Skip to content

Commit ebc2d88

Browse files
author
Piotr Siatka
committed
Implement term actions functionality. Refactor. Fix bugs. Documentation.
1 parent 1f446b1 commit ebc2d88

File tree

13 files changed

+79
-45
lines changed

13 files changed

+79
-45
lines changed

docs/documentation/docs/controls/TaxonomyPicker.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/Taxon
4242
context={this.props.context}
4343
onChange={this.onTaxPickerChange}
4444
isTermSetSelectable={false}
45+
termActions={termActions}
4546
/>
4647
```
4748

@@ -71,6 +72,7 @@ The TaxonomyPicker control can be configured with the following properties:
7172
| disabledTermIds | string[] | no | Specify which terms should be disabled in the term set so that they cannot be selected. |
7273
| disableChildrenOfDisabledParents | boolean | no | Specify if you want to disable the child terms when their parent is disabled. |
7374
| anchorId | string | no | Set the anchorid to a child term in the TermSet to be able to select terms from that level and below. |
75+
| termActions | ITermActions | no | Allows to execute custom action on the term like e.g. get other term labelsITermActions. |
7476

7577
Interface `IPickerTerm`
7678

@@ -86,4 +88,18 @@ Interface `IPickerTerms`
8688

8789
An Array of IPickerTerm
8890

91+
Interface `ITermActions`
92+
| Property | Type | Required | Description |
93+
| ---- | ---- | ---- | ---- |
94+
| actions | ITermAction[] | yes | The array of supported actions |
95+
| termActionsDisplayStyle | TermActionsDisplayStyle | no | Defines how to display term action button, available options: text (default), icon, text and icon |
96+
| termActionsDisplayMode | TermActionsDisplayMode | no | Defines how to display term actions, as buttons (default) or dropdown |
97+
98+
Interface `ITermAction`
99+
| Property | Type | Required | Description |
100+
| ---- | ---- | ---- | ---- |
101+
| id | string | yes | Unique id of the term action |
102+
| displayText | string | no | Name of the action |
103+
| iconName | string | no | Name of the icon to be used to display action |
104+
89105
![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/Placeholder)

src/controls/taxonomyPicker/ITaxonomyPicker.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ export interface ITaxonomyPickerState {
9393
openPanel?: boolean;
9494
loaded?: boolean;
9595
activeNodes?: IPickerTerms;
96-
termActions?: ITermActions;
9796
}
9897

9998
export interface ITermChanges {
@@ -112,6 +111,7 @@ export interface ITermParentProps extends ITermChanges {
112111

113112
termActions?: ITermActions;
114113
autoExpand: () => void;
114+
updateTaxonomyTree: () => void;
115115
termSetSelectedChange?: (termSet: ITermSet, isChecked: boolean) => void;
116116
}
117117

@@ -127,6 +127,8 @@ export interface ITermProps extends ITermChanges {
127127
multiSelection: boolean;
128128
disabled: boolean;
129129
termActions?: ITermActions;
130+
131+
updateTaxonomyTree: () => void;
130132
}
131133

132134
export interface ITermState {

src/controls/taxonomyPicker/TaxonomyPicker.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
5555
this.onSave = this.onSave.bind(this);
5656
this.termsChanged = this.termsChanged.bind(this);
5757
this.termsFromPickerChanged = this.termsFromPickerChanged.bind(this);
58-
this.prepareTermActions = this.prepareTermActions.bind(this);
5958
}
6059

6160
/**
@@ -79,32 +78,36 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
7978
}
8079
}
8180

82-
private prepareTermActions = (): ITermActions => {
83-
let termActions = this.props.termActions ? cloneDeep(this.props.termActions) : null;
84-
// Add default available actions
85-
if (termActions && termActions.addDefaultActions) {
86-
termActions.concreateActions.unshift(new TermLabelAction(this.termsService));
87-
}
88-
return termActions;
89-
}
90-
9181
/**
9282
* Loads the list from SharePoint current web site
9383
*/
9484
private loadTermStores(): void {
9585
this.termsService = new SPTermStorePickerService(this.props, this.props.context);
96-
let termActions = this.prepareTermActions();
86+
87+
if (this.props.termActions) {
88+
this.props.termActions.actions.map(x => {
89+
x.initialize(this.termsService);
90+
});
91+
}
9792
this.termsService.getAllTerms(this.props.termsetNameOrID).then((response: ITermSet) => {
9893
// Check if a response was retrieved
9994
let termSetAndTerms = response ? response : null;
10095
this.setState({
10196
termSetAndTerms,
102-
loaded: true,
103-
termActions
97+
loaded: true
10498
});
10599
});
106100
}
107101

102+
/**
103+
* Force update of the taxonomy tree - required by term action in case the term has been added, deleted or moved.
104+
*/
105+
private updateTaxonomyTree(): void {
106+
this.setState({
107+
termSetAndTerms: this.state.termSetAndTerms
108+
});
109+
}
110+
108111
/**
109112
* Open the right Panel
110113
*/
@@ -314,7 +317,8 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
314317
changedCallback={this.termsChanged}
315318
multiSelection={this.props.allowMultipleSelections}
316319

317-
termActions={this.state.termActions}
320+
updateTaxonomyTree={this.updateTaxonomyTree}
321+
termActions={this.props.termActions}
318322
/>
319323
</div>
320324
)

src/controls/taxonomyPicker/Term.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ export default class Term extends React.Component<ITermProps, ITermState> {
7676
this.props.term.Name = updateAction.value;
7777
this.setState({
7878
termLabel: updateAction.value
79-
})
79+
});
80+
}
81+
else {
82+
this.props.updateTaxonomyTree();
8083
}
8184
}
8285

@@ -89,7 +92,7 @@ export default class Term extends React.Component<ITermProps, ITermState> {
8992
};
9093
const checkBoxStyle: React.CSSProperties = {
9194
display: "inline-flex"
92-
}
95+
};
9396

9497
return (
9598
<div>

src/controls/taxonomyPicker/TermParent.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP
108108
disabled = parentPath && parentPath.length > 0;
109109
}
110110

111-
return <Term key={term.Id} term={term} termset={this.props.termset.Id} activeNodes={this.props.activeNodes} changedCallback={this.props.changedCallback} multiSelection={this.props.multiSelection} disabled={disabled} termActions={this.props.termActions} />;
111+
return <Term key={term.Id} term={term} termset={this.props.termset.Id}
112+
activeNodes={this.props.activeNodes} changedCallback={this.props.changedCallback}
113+
multiSelection={this.props.multiSelection} disabled={disabled}
114+
termActions={this.props.termActions} updateTaxonomyTree={this.props.updateTaxonomyTree}/>;
112115
})
113116
}
114117
</div>

src/controls/taxonomyPicker/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
export * from './ITaxonomyPicker';
22
export * from './TaxonomyPicker';
3-
export * from './ITermPicker';
3+
export * from './ITermPicker';
4+
export * from "./termActions/ITermsActions";
5+
export * from './termActions/TermActionsControl';

src/controls/taxonomyPicker/termActions/ButtonTermAction.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default class ButtonTermAction extends React.Component<IConreteTermAction
2323
style={this._getTermActionActionButtonStyle()}
2424
/>
2525
</div>
26-
)
26+
);
2727
})
2828
}
2929
</div>
@@ -50,7 +50,7 @@ export default class ButtonTermAction extends React.Component<IConreteTermAction
5050
backgroundColor: "transparent",
5151
width: "32px",
5252
height: "32px"
53-
}
53+
};
5454

5555
return result;
5656
}

src/controls/taxonomyPicker/termActions/DropdownTermAction.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@ export class DropdownTermAction extends React.Component<IConreteTermActionProps>
3838
useTargetWidth = false;
3939
}
4040
if (displayStyle && (displayStyle === TermActionsDisplayStyle.icon || displayStyle === TermActionsDisplayStyle.textAndIcon)) {
41-
termActionMenuItem.iconProps = { iconName: termAction.iconName }
41+
termActionMenuItem.iconProps = { iconName: termAction.iconName };
4242
}
4343

4444
items.push(termActionMenuItem);
45-
})
45+
});
4646

4747
const contextualMenuProps: IContextualMenuProps = {
4848
items,
4949
useTargetWidth
50-
}
50+
};
5151
return contextualMenuProps;
5252
}
5353

@@ -60,7 +60,7 @@ export class DropdownTermAction extends React.Component<IConreteTermActionProps>
6060
width: "14px",
6161
display: "inline-flex",
6262
padding: "0px"
63-
}
63+
};
6464

6565
return result;
6666
}

src/controls/taxonomyPicker/termActions/ITermsActions.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ITerm } from '../../../services/ISPTermStorePickerService';
2+
import SPTermStorePickerService from '../../../services/SPTermStorePickerService';
23

34
export interface ITermActionsControlProps {
45
/**
@@ -70,8 +71,7 @@ export interface UpdateAction {
7071
}
7172

7273
export interface ITermActions {
73-
addDefaultActions: boolean;
74-
concreateActions: ITermAction[];
74+
actions: ITermAction[];
7575
termActionsDisplayStyle?: TermActionsDisplayStyle;
7676
termActionsDisplayMode?: TermActionsDisplayMode;
7777
}
@@ -89,17 +89,18 @@ export interface ITermAction {
8989
*/
9090
iconName?: string;
9191

92-
/**
93-
* Specifies it the waiting dialog should be displayed when executing the action.
94-
*/
95-
isBlocking?: boolean;
96-
/**
97-
* Method that verifies if the action can be applied to the term. If false, action won't be avaialable.
98-
* @param currentTerm
99-
*/
100-
applyToTerm(currentTerm: ITerm): boolean;
92+
/**
93+
* Method checks if the current term is supported.
94+
* @param currentTerm
95+
*/
96+
applyToTerm(currentTerm: ITerm): Promise<boolean> | boolean;
10197
/**
10298
* Method to be executed when action is fired.
10399
*/
104100
actionCallback: (currentTerm: ITerm) => Promise<UpdateAction>;
101+
102+
/**
103+
* Initializes the term action with the taxonomy servie.
104+
*/
105+
initialize: (spTermService: SPTermStorePickerService) => Promise<void>;
105106
}

src/controls/taxonomyPicker/termActions/DefaultTermActions.ts renamed to src/controls/taxonomyPicker/termActions/TermActions.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,22 @@ import { findIndex } from "@microsoft/sp-lodash-subset";
99
*/
1010
export class TermLabelAction implements ITermAction {
1111
public iconName: string = "LocaleLanguage";
12-
public displayText: string = "Get Labels"
12+
public displayText: string = "Get Labels";
1313
public id: string = "TermLabelActionId";
1414

1515
private _spTermsService: SPTermStorePickerService;
1616
private _labels: string[];
1717
private _processedTerms: ITerm[];
1818

19-
constructor(spTermService: SPTermStorePickerService) {
20-
this._spTermsService = spTermService;
19+
constructor() {
2120
this._processedTerms = [];
2221
}
2322

23+
public initialize = (spTermService: SPTermStorePickerService): Promise<void> => {
24+
this._spTermsService = spTermService;
25+
return Promise.resolve();
26+
}
27+
2428
public applyToTerm = (currentTerm: ITerm): boolean => {
2529
const termIndex = findIndex(this._processedTerms, term => term.Id == currentTerm.Id);
2630
if (termIndex >= 0) {
@@ -32,7 +36,7 @@ export class TermLabelAction implements ITermAction {
3236
public actionCallback = async (currentTerm: ITerm): Promise<UpdateAction> => {
3337
try {
3438
// Set pointer to loading
35-
let updateAction : UpdateAction = null;
39+
let updateAction: UpdateAction = null;
3640
this._labels = await this._spTermsService.getTermLabels(currentTerm.Id);
3741

3842
if (this._labels) {

0 commit comments

Comments
 (0)