@bscotch/bravo
Advanced tools
Comparing version 0.6.0 to 0.7.0
@@ -95,4 +95,8 @@ /// <reference types="node" /> | ||
setCustomRating(...args: Parameters<BravoCardUpdateBuilder['setCustomRating']>): Promise<this>; | ||
setCustomMulipleSelect(...args: Parameters<BravoCardUpdateBuilder['setCustomMulipleSelect']>): Promise<this>; | ||
setCustomMulipleSelectByName(...args: Parameters<BravoCardUpdateBuilder['setCustomMulipleSelectByName']>): Promise<this>; | ||
setCustomMulipleSelect(...args: Parameters<BravoCardUpdateBuilder['setCustomMultipleSelect']>): Promise<this>; | ||
setCustomMulipleSelectByName(...args: Parameters<BravoCardUpdateBuilder['setCustomMultipleSelectByName']>): Promise<this>; | ||
addCustomMembers(...args: Parameters<BravoCardUpdateBuilder['addCustomMembers']>): Promise<this>; | ||
removeCustomMembers(...args: Parameters<BravoCardUpdateBuilder['removeCustomMembers']>): Promise<this>; | ||
completeCustomMembers(...args: Parameters<BravoCardUpdateBuilder['completeCustomMembers']>): Promise<this>; | ||
uncompleteCustomMembers(...args: Parameters<BravoCardUpdateBuilder['uncompleteCustomMembers']>): Promise<this>; | ||
/** | ||
@@ -99,0 +103,0 @@ * Get the custom field definitions and values associated with |
@@ -209,7 +209,19 @@ "use strict"; | ||
async setCustomMulipleSelect(...args) { | ||
return await this.updateField('setCustomMulipleSelect', ...args); | ||
return await this.updateField('setCustomMultipleSelect', ...args); | ||
} | ||
async setCustomMulipleSelectByName(...args) { | ||
return await this.updateField('setCustomMulipleSelectByName', ...args); | ||
return await this.updateField('setCustomMultipleSelectByName', ...args); | ||
} | ||
async addCustomMembers(...args) { | ||
return await this.updateField('addCustomMembers', ...args); | ||
} | ||
async removeCustomMembers(...args) { | ||
return await this.updateField('removeCustomMembers', ...args); | ||
} | ||
async completeCustomMembers(...args) { | ||
return await this.updateField('completeCustomMembers', ...args); | ||
} | ||
async uncompleteCustomMembers(...args) { | ||
return await this.updateField('uncompleteCustomMembers', ...args); | ||
} | ||
//#endregion | ||
@@ -216,0 +228,0 @@ /** |
@@ -50,7 +50,12 @@ import { DataFavroCardFavroAttachment, DataFavroCustomFieldType, DataFavroRating } from '../../types/FavroCardTypes.js'; | ||
setCustomRating(customFieldId: CustomFieldOrId<'Rating'>, rating: DataFavroRating): this; | ||
setCustomMulipleSelect(customFieldOrId: CustomFieldOrId<'Multiple select'>, optionOrIds: (string | { | ||
setCustomMultipleSelect(customFieldOrId: CustomFieldOrId<'Multiple select'>, optionOrIds: (string | { | ||
customFieldItemId: string; | ||
name: string; | ||
})[]): this; | ||
setCustomMulipleSelectByName(customFieldId: CustomFieldOrId<'Multiple select'>, optionNames: (string | RegExp)[], fieldDefinition: DataFavroCustomFieldDefinition | BravoCustomFieldDefinition<'Multiple select'> | BravoCustomField<'Multiple select'>): this; | ||
setCustomMultipleSelectByName(customFieldOrId: CustomFieldOrId<'Multiple select'>, optionNames: (string | RegExp)[], fieldDefinition: DataFavroCustomFieldDefinition | BravoCustomFieldDefinition<'Multiple select'> | BravoCustomField<'Multiple select'>): this; | ||
private updateCustomMembers; | ||
addCustomMembers(customFieldOrId: CustomFieldOrId<'Members'>, users: (string | BravoUser)[]): this; | ||
removeCustomMembers(customFieldOrId: CustomFieldOrId<'Members'>, users: (string | BravoUser)[]): this; | ||
completeCustomMembers(customFieldOrId: CustomFieldOrId<'Members'>, users: (string | BravoUser)[]): this; | ||
uncompleteCustomMembers(customFieldOrId: CustomFieldOrId<'Members'>, users: (string | BravoUser)[]): this; | ||
/** | ||
@@ -94,3 +99,3 @@ * Get a plain update object that can be directly used | ||
archive?: boolean | undefined; | ||
customFields: import("../../types/FavroCardUpdateTypes.js").FavroApiParamsCardUpdateCustomField[]; | ||
customFields: any[]; | ||
}; | ||
@@ -97,0 +102,0 @@ private setAssignmentCompletion; |
@@ -143,3 +143,3 @@ "use strict"; | ||
} | ||
setCustomMulipleSelect(customFieldOrId, optionOrIds) { | ||
setCustomMultipleSelect(customFieldOrId, optionOrIds) { | ||
return this.setCustomFieldUniquely(customFieldOrId, { | ||
@@ -149,9 +149,52 @@ value: optionOrIds.map((o) => typeof o == 'string' ? o : o.customFieldItemId), | ||
} | ||
setCustomMulipleSelectByName(customFieldId, optionNames, fieldDefinition) { | ||
setCustomMultipleSelectByName(customFieldOrId, optionNames, fieldDefinition) { | ||
(0, errors_js_1.assertBravoClaim)(optionNames.length > 0, 'No option names provided'); | ||
const matchingOptions = fieldDefinition.customFieldItems.filter((item) => optionNames.some((name) => (0, utility_js_1.isMatch)(item.name, name))); | ||
(0, errors_js_1.assertBravoClaim)(matchingOptions.length === optionNames.length, `Expected to find ${optionNames.length} matching options, but found ${matchingOptions.length}.`); | ||
return this.setCustomMulipleSelect(customFieldId, matchingOptions.map((o) => o.customFieldItemId)); | ||
return this.setCustomMultipleSelect(customFieldOrId, matchingOptions.map((o) => o.customFieldItemId)); | ||
} | ||
// TODO: Map these onto Card methods & test | ||
updateCustomMembers(customFieldOrId, members, action) { | ||
const userIds = (0, utility_js_1.stringsOrObjectsToStrings)(members, 'userId'); | ||
const customFieldId = typeof customFieldOrId == 'string' | ||
? customFieldOrId | ||
: customFieldOrId.customFieldId; | ||
let update = this.update.customFields.find((f) => f.customFieldId == customFieldId); | ||
if (!update) { | ||
update = { | ||
customFieldId, | ||
members: { | ||
addUserIds: [], | ||
removeUserIds: [], | ||
completeUsers: [], | ||
}, | ||
}; | ||
this.update.customFields.push(update); | ||
} | ||
if (action == 'add') { | ||
update.members.addUserIds = userIds; | ||
} | ||
else if (action == 'remove') { | ||
update.members.removeUserIds = userIds; | ||
} | ||
else if (action == 'complete') { | ||
(0, utility_js_1.addToUniqueArrayBy)(update.members.completeUsers, 'userId', userIds.map((u) => ({ userId: u, completed: true }))); | ||
} | ||
else if (action == 'uncomplete') { | ||
(0, utility_js_1.addToUniqueArrayBy)(update.members.completeUsers, 'userId', userIds.map((u) => ({ userId: u, completed: false }))); | ||
} | ||
return this; | ||
} | ||
addCustomMembers(customFieldOrId, users) { | ||
return this.updateCustomMembers(customFieldOrId, users, 'add'); | ||
} | ||
removeCustomMembers(customFieldOrId, users) { | ||
return this.updateCustomMembers(customFieldOrId, users, 'remove'); | ||
} | ||
completeCustomMembers(customFieldOrId, users) { | ||
return this.updateCustomMembers(customFieldOrId, users, 'complete'); | ||
} | ||
uncompleteCustomMembers(customFieldOrId, users) { | ||
return this.updateCustomMembers(customFieldOrId, users, 'uncomplete'); | ||
} | ||
/** | ||
@@ -183,6 +226,4 @@ * Get a plain update object that can be directly used | ||
(_a = this.update)[updateField] || (_a[updateField] = []); | ||
// @ts-expect-error | ||
(0, utility_js_1.ensureArrayExistsAndAddUnique)(this.update[updateField], values); | ||
if (opposingField) { | ||
// @ts-expect-error | ||
(0, utility_js_1.removeFromArray)(this.update[opposingField], values); | ||
@@ -189,0 +230,0 @@ } |
@@ -88,2 +88,3 @@ import { DataFavroCustomFieldsValues, DataFavroCustomFieldType, DataFavroRating } from '../../types/FavroCardTypes.js'; | ||
}[] : never; | ||
get assignedTo(): TypeName extends 'Members' ? string[] : never; | ||
get humanFriendlyValue(): BravoHumanFriendlyFieldValues[TypeName] | undefined; | ||
@@ -90,0 +91,0 @@ } |
@@ -105,2 +105,9 @@ "use strict"; | ||
} | ||
get assignedTo() { | ||
var _a; | ||
const { type: fieldType } = this; | ||
(0, errors_js_1.assertBravoClaim)(fieldType === 'Members', `Fields of type ${fieldType} do not have members assigned to them.`); | ||
// @ts-expect-error | ||
return ((_a = this.value) === null || _a === void 0 ? void 0 : _a.value) || []; | ||
} | ||
get humanFriendlyValue() { | ||
@@ -148,3 +155,3 @@ const type = this.type; | ||
// @ts-expect-error | ||
return value.value; | ||
return this.assignedTo; | ||
case 'Tags': | ||
@@ -151,0 +158,0 @@ // @ts-expect-error |
@@ -1,20 +0,27 @@ | ||
import type { DataFavroCardFieldNumber, DataFavroCardFieldText, DataFavroCardFieldSingleSelect, DataFavroCardFieldMultipleSelect, DataFavroCardFieldCheckbox, DataFavroCardFieldDate, DataFavroCardFieldLink, DataFavroCardFieldRating, DataFavroCardFieldTimeline, DataFavroCardFavroAttachment, DataFavroCardFieldTimeUserReport } from './FavroCardTypes'; | ||
import type { DataFavroCardFieldNumber, DataFavroCardFieldText, DataFavroCardFieldSingleSelect, DataFavroCardFieldMultipleSelect, DataFavroCardFieldCheckbox, DataFavroCardFieldDate, DataFavroCardFieldLink, DataFavroCardFieldRating, DataFavroCardFieldTimeline, DataFavroCardFavroAttachment, DataFavroCardFieldTimeUserReport, DataFavroCustomFieldType } from './FavroCardTypes'; | ||
import { ExtractKeysByValue } from './Utility.js'; | ||
interface DataFavroCardFieldMembersUpdate { | ||
/** The list of members, that will be added to the card custom field (array of userIds).*/ | ||
addUserIds: string[]; | ||
/** The list of members, that will be removed from card custom field (array of userIds).*/ | ||
removeUserIds: string[]; | ||
/** The list of card assignment, that will update their statuses on the custom field accordingly.*/ | ||
completeUsers: string[]; | ||
export interface DataFavroCardFieldMembersUpdate { | ||
members: { | ||
/** The list of members, that will be added to the card custom field (array of userIds).*/ | ||
addUserIds: string[]; | ||
/** The list of members, that will be removed from card custom field (array of userIds).*/ | ||
removeUserIds: string[]; | ||
/** The list of card assignment, that will update their statuses on the custom field accordingly.*/ | ||
completeUsers: { | ||
userId: string; | ||
completed: boolean; | ||
}[]; | ||
}; | ||
} | ||
interface DataFavroCardFieldTagsUpdate { | ||
/** The list of tag names or card tags that will be added to this card custom field. If the tag does not exist in the organization it will be created.*/ | ||
addTags: string[]; | ||
/** A list of tagIds that will be added to this card custom field.*/ | ||
addTagIds: string[]; | ||
/** The list of tag names, that will be removed from this card custom field.*/ | ||
removeTags: string[]; | ||
/** The list of tag IDs, that will be removed from this card custom field.*/ | ||
removeTagIds: string[]; | ||
tags: { | ||
/** The list of tag names or card tags that will be added to this card custom field. If the tag does not exist in the organization it will be created.*/ | ||
addTags: string[]; | ||
/** A list of tagIds that will be added to this card custom field.*/ | ||
addTagIds: string[]; | ||
/** The list of tag names, that will be removed from this card custom field.*/ | ||
removeTags: string[]; | ||
/** The list of tag IDs, that will be removed from this card custom field.*/ | ||
removeTagIds: string[]; | ||
}; | ||
} | ||
@@ -29,3 +36,3 @@ interface DataFavroCardFieldTimeUpdate { | ||
} | ||
interface DataFavroCardFieldVoteUpdate { | ||
interface DataFavroCardFieldVotingUpdate { | ||
/** | ||
@@ -45,7 +52,31 @@ * The value to determine the field should be either voted or unvoted. | ||
*/ | ||
export declare type FavroApiParamsCardUpdateCustomField = { | ||
export declare type FavroApiParamsCardUpdateCustomField<FieldType extends DataFavroCustomFieldType = any> = { | ||
customFieldId: string; | ||
} & FavroApiParamsCardCustomField; | ||
export declare type FavroApiParamsCardCustomField = DataFavroCardFieldCheckbox | DataFavroCardFieldDate | DataFavroCardFieldLink | DataFavroCardFieldMultipleSelect | DataFavroCardFieldNumber | DataFavroCardFieldRating | DataFavroCardFieldSingleSelect | DataFavroCardFieldText | DataFavroCardFieldTimeline | DataFavroCardFieldMembersUpdate | DataFavroCardFieldTagsUpdate | DataFavroCardFieldTimeUpdate | DataFavroCardFieldVoteUpdate; | ||
} & FavroApiParamsCardCustomField<FieldType>; | ||
export declare type FavroApiParamsCardCustomField<FieldType extends DataFavroCustomFieldType = any> = FavroApiParamsCardCustomFields[FieldType]; | ||
/** | ||
* Map of Custom Field Types to their respective | ||
* update object shapes. | ||
*/ | ||
declare type FavroApiParamsCardCustomFields = { | ||
Checkbox: DataFavroCardFieldCheckbox; | ||
Date: DataFavroCardFieldDate; | ||
Link: DataFavroCardFieldLink; | ||
'Multiple select': DataFavroCardFieldMultipleSelect; | ||
Number: DataFavroCardFieldNumber; | ||
Rating: DataFavroCardFieldRating; | ||
'Single select': DataFavroCardFieldSingleSelect; | ||
Text: DataFavroCardFieldText; | ||
Timeline: DataFavroCardFieldTimeline; | ||
Members: DataFavroCardFieldMembersUpdate; | ||
Tags: DataFavroCardFieldTagsUpdate; | ||
Time: DataFavroCardFieldTimeUpdate; | ||
Voting: DataFavroCardFieldVotingUpdate; | ||
}; | ||
export declare type FavroApiParamsCardUpdateField = keyof FavroApiParamsCardUpdate; | ||
/** | ||
* Fields for a Card update request whose values are arrays. | ||
* | ||
* Useful for generic methods that act on arrays. | ||
*/ | ||
export declare type FavroApiParamsCardUpdateArrayField = ExtractKeysByValue<Required<FavroApiParamsCardUpdate>, any[]>; | ||
@@ -52,0 +83,0 @@ /** |
@@ -0,1 +1,10 @@ | ||
# [0.7.0](https://github.com/bscotch/favro-sdk/compare/v0.6.0...v0.7.0) (2021-08-28) | ||
### Features | ||
* Add methods for setting Custom Members fields. ([24af17d](https://github.com/bscotch/favro-sdk/commit/24af17d1d1c1d27ce82b97365194d3c453b4f2ec)) | ||
# [0.6.0](https://github.com/bscotch/favro-sdk/compare/v0.5.0...v0.6.0) (2021-08-27) | ||
@@ -2,0 +11,0 @@ |
@@ -14,3 +14,3 @@ { | ||
], | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"engines": { | ||
@@ -17,0 +17,0 @@ "node": ">=14" |
@@ -77,7 +77,8 @@ <p align="center"><i><a href="https://www.bscotch.net">Butterscotch Shenanigans</a> Presents:</i></p> | ||
2. [Searching](#searching) | ||
3. [Limited Markdown](#limited-markdown) | ||
4. [Identifiers](#identifiers) | ||
3. [Member fields & "completion"](#member-fields--completion) | ||
4. [Limited Markdown](#limited-markdown) | ||
5. [Identifiers](#identifiers) | ||
1. [Card Sequential IDs](#card-sequential-ids) | ||
2. [Widget-specific `cardId`s](#widget-specific-cardids) | ||
5. [Creating Boards](#creating-boards) | ||
6. [Creating Boards](#creating-boards) | ||
@@ -350,2 +351,16 @@ ## Authentication | ||
### Member fields & "completion" | ||
Cards have a default Members field, and also allows for Custom Members fields. You'll notice that, via the Favro webapp, if you click the "Mark as complete" button you'll get a checkmark next to your avatar *in every Members-type field*. (And all will be unchecked if you then mark as incomplete.) But via the API, you mark a user "complete" via the built-in *or* via the Custom Members field. | ||
So what happens when you mark a user as complete via the API, given the combinations of ways a user can be assigned to any subset of the default and any Custom Members fields? | ||
- All Member field "completion" statuses are **completely independent** via the API. | ||
- The Favro webapp will show checkmarks correctly by field -- if you used the API to mark the default field "complete" but not a Custom Field, you'll see the checkmark in the default Members assignment but not the Custom one. | ||
- The Favro webapp will only show the Card as "complete" if *all* Member fields are complete. | ||
- The Favro webapp couples completion state between all fields when you use the "Mark as (in)complete" button. | ||
- If you use the context menu for an individual Member field in the Favro webapp, you can separately manage completion state between fields via the app. | ||
- The Favro API *does not* provide a way for you to obtain a user's "complete" status for a Custom Members field via the API. You can *set* the state but not *get* the state! ([Upvote the feature request!](https://favro.canny.io/feature-requests/p/favro-api-return-complete-state-for-custom-members-fields)) | ||
### Limited Markdown | ||
@@ -352,0 +367,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
317122
4155
407