Skip to content

Commit af3e665

Browse files
committed
#235 - documentation updates + code refactoring
1 parent 7ff35e1 commit af3e665

File tree

13 files changed

+198
-89
lines changed

13 files changed

+198
-89
lines changed
21.9 KB
Loading

docs/documentation/docs/controls/TaxonomyPicker.md

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,13 @@ import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/Taxon
3434
- Use the `TaxonomyPicker` control in your code as follows:
3535

3636
```TypeScript
37-
<TaxonomyPicker
38-
allowMultipleSelections={true}
39-
termsetNameOrID="Countries"
40-
panelTitle="Select Term"
41-
label="Taxonomy Picker"
42-
context={this.props.context}
43-
onChange={this.onTaxPickerChange}
44-
isTermSetSelectable={false}
45-
termActions={termActions}
46-
/>
37+
<TaxonomyPicker allowMultipleSelections={true}
38+
termsetNameOrID="Countries"
39+
panelTitle="Select Term"
40+
label="Taxonomy Picker"
41+
context={this.props.context}
42+
onChange={this.onTaxPickerChange}
43+
isTermSetSelectable={false} />
4744
```
4845

4946
- With the `onChange` property you can capture the event of when the terms in the picker has changed:
@@ -54,6 +51,51 @@ private onTaxPickerChange(terms : IPickerTerms) {
5451
}
5552
```
5653

54+
## Term actions
55+
56+
Since version `1.12.0`, you can apply term actions to all terms or specific ones. Term actions could for instance be used to retrieve the labels of the term, or retrieve other information. These term actions can be implemented as follows:
57+
58+
```typescript
59+
<TaxonomyPicker allowMultipleSelections={true}
60+
termsetNameOrID="Countries"
61+
panelTitle="Select Term"
62+
label="Taxonomy Picker"
63+
context={this.props.context}
64+
onChange={this.onServicePickerChange}
65+
isTermSetSelectable={false}
66+
termActions={{
67+
actions: [{
68+
title: "Update term label",
69+
iconName: "LocaleLanguage",
70+
id: "UpdateTermLabel",
71+
actionCallback: async (taxService: SPTermStorePickerService, term: ITerm) => {
72+
return {
73+
updateActionType: UpdateType.updateTermLabel,
74+
value: `${term.Name} (updated)`
75+
};
76+
},
77+
applyToTerm: (term: ITerm) => (true) // Applying the action to all terms
78+
}]
79+
}} />
80+
```
81+
82+
![Term action sample](../assets/term-action.png)
83+
84+
We also provided a default term action which you can use to retrieve the term its labels and will update the term text in the TaxonomyPicker hierarchy.
85+
86+
```typescript
87+
<TaxonomyPicker allowMultipleSelections={true}
88+
termsetNameOrID="Countries"
89+
panelTitle="Select Term"
90+
label="Taxonomy Picker"
91+
context={this.props.context}
92+
onChange={this.onServicePickerChange}
93+
isTermSetSelectable={false}
94+
termActions={{
95+
actions: [new TermLabelAction("Get Labels")]
96+
}} />
97+
```
98+
5799
## Implementation
58100

59101
The TaxonomyPicker control can be configured with the following properties:
@@ -89,17 +131,38 @@ Interface `IPickerTerms`
89131
An Array of IPickerTerm
90132

91133
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 |
134+
135+
| Property | Type | Required | Description | Default |
136+
| ---- | ---- | ---- | ---- | ---- |
137+
| actions | ITermAction[] | yes | The array of supported actions | |
138+
| termActionsDisplayStyle | TermActionsDisplayStyle | no | Defines how to display term action button, available options: text, icon, text and icon | text |
139+
| termActionsDisplayMode | TermActionsDisplayMode | no | Defines how to display term actions, as buttons or dropdown | buttons |
140+
| initialize | (spTermService: SPTermStorePickerService) => Promise\<void\> | no | Initializes the term action with the taxonomy service |
97141

98142
Interface `ITermAction`
143+
99144
| Property | Type | Required | Description |
100145
| ---- | ---- | ---- | ---- |
101146
| id | string | yes | Unique id of the term action |
102-
| displayText | string | no | Name of the action |
147+
| title | string | yes | Action title |
103148
| iconName | string | no | Name of the icon to be used to display action |
149+
| applyToTerm | (currentTerm: ITerm) => Promise\<boolean\> \| boolean | yes | Method checks if the current term is supported |
150+
| actionCallback | (spTermService: SPTermStorePickerService, currentTerm: ITerm) => Promise\<UpdateAction\> | yes | Method to be executed when action is fired |
151+
| initialize | (spTermService: SPTermStorePickerService) => Promise\<void\> | no | Initializes the term action with the taxonomy service |
152+
153+
154+
Interface `UpdateAction`
155+
156+
| Property | Type | Required | Description |
157+
| ---- | ---- | ---- | ---- |
158+
| updateActionType | UpdateType | yes | Defines the type of update you want to perform |
159+
| value | string | no | New term label value to update. Only required when you want to update the term |
160+
161+
Enum `UpdateType`
162+
163+
| Value |
164+
| ---- |
165+
| updateTermLabel |
166+
| updateTermsTree |
104167

105168
![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/Placeholder)

src/controls/taxonomyPicker/ITaxonomyPicker.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { IPickerTerms } from './ITermPicker';
33
import { ITermSet, ITerm } from '../../services/ISPTermStorePickerService';
44
import { IWebPartContext } from '@microsoft/sp-webpart-base';
55
import { ITermActions } from './termActions/ITermsActions';
6+
import SPTermStorePickerService from '../../services/SPTermStorePickerService';
67

78
/**
89
* PropertyFieldTermPickerHost properties interface
@@ -108,8 +109,9 @@ export interface ITermParentProps extends ITermChanges {
108109
multiSelection: boolean;
109110
anchorId? : string;
110111
isTermSetSelectable?: boolean;
111-
112112
termActions?: ITermActions;
113+
spTermService: SPTermStorePickerService;
114+
113115
autoExpand: () => void;
114116
updateTaxonomyTree: () => void;
115117
termSetSelectedChange?: (termSet: ITermSet, isChecked: boolean) => void;
@@ -127,6 +129,7 @@ export interface ITermProps extends ITermChanges {
127129
multiSelection: boolean;
128130
disabled: boolean;
129131
termActions?: ITermActions;
132+
spTermService: SPTermStorePickerService;
130133

131134
updateTaxonomyTree: () => void;
132135
}

src/controls/taxonomyPicker/TaxonomyPicker.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { IPickerTerms, IPickerTerm } from './ITermPicker';
88
import { ITaxonomyPickerProps, ITaxonomyPickerState } from './ITaxonomyPicker';
99
import SPTermStorePickerService from './../../services/SPTermStorePickerService';
1010
import { ITermSet, ITerm } from './../../services/ISPTermStorePickerService';
11-
import { TermLabelAction, ITermActions } from './termActions';
1211

1312
import styles from './TaxonomyPicker.module.scss';
1413
import { sortBy, uniqBy, cloneDeep, isEqual } from '@microsoft/sp-lodash-subset';
@@ -84,11 +83,13 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
8483
private loadTermStores(): void {
8584
this.termsService = new SPTermStorePickerService(this.props, this.props.context);
8685

87-
if (this.props.termActions) {
88-
this.props.termActions.actions.map(x => {
89-
x.initialize(this.termsService);
90-
});
86+
if (this.props.termActions && this.props.termActions.initialize) {
87+
this.props.termActions.initialize(this.termsService);
88+
// this.props.termActions.actions.forEach(x => {
89+
// x.initialize(this.termsService);
90+
// });
9191
}
92+
9293
this.termsService.getAllTerms(this.props.termsetNameOrID).then((response: ITermSet) => {
9394
// Check if a response was retrieved
9495
let termSetAndTerms = response ? response : null;
@@ -316,6 +317,7 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
316317
disableChildrenOfDisabledParents={this.props.disableChildrenOfDisabledParents}
317318
changedCallback={this.termsChanged}
318319
multiSelection={this.props.allowMultipleSelections}
320+
spTermService={this.termsService}
319321

320322
updateTaxonomyTree={this.updateTaxonomyTree}
321323
termActions={this.props.termActions}

src/controls/taxonomyPicker/Term.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { Checkbox, ICheckboxStyles } from 'office-ui-fabric-react/lib/Checkbox';
2+
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
33
import { ITermProps, ITermState } from './ITaxonomyPicker';
44

55
import styles from './TaxonomyPicker.module.scss';
@@ -12,6 +12,7 @@ import { UpdateAction, UpdateType } from './termActions';
1212
* Renders a selectable term
1313
*/
1414
export default class Term extends React.Component<ITermProps, ITermState> {
15+
1516
constructor(props: ITermProps) {
1617
super(props);
1718

@@ -108,7 +109,10 @@ export default class Term extends React.Component<ITermProps, ITermState> {
108109
</div>
109110
{
110111
this.props.termActions &&
111-
<TermActionsControl term={this.props.term} termActions={this.props.termActions} termActionCallback={this.termActionCallback} />
112+
<TermActionsControl term={this.props.term}
113+
termActions={this.props.termActions}
114+
termActionCallback={this.termActionCallback}
115+
spTermService={this.props.spTermService} />
112116
}
113117
</div>
114118
</div>

src/controls/taxonomyPicker/TermParent.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,16 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP
106106
disabled = parentPath && parentPath.length > 0;
107107
}
108108

109-
return <Term key={term.Id} term={term} termset={this.props.termset.Id}
110-
activeNodes={this.props.activeNodes} changedCallback={this.props.changedCallback}
111-
multiSelection={this.props.multiSelection} disabled={disabled}
112-
termActions={this.props.termActions} updateTaxonomyTree={this.props.updateTaxonomyTree}/>;
109+
return <Term key={term.Id}
110+
term={term}
111+
termset={this.props.termset.Id}
112+
activeNodes={this.props.activeNodes}
113+
changedCallback={this.props.changedCallback}
114+
multiSelection={this.props.multiSelection}
115+
disabled={disabled}
116+
termActions={this.props.termActions}
117+
updateTaxonomyTree={this.props.updateTaxonomyTree}
118+
spTermService={this.props.spTermService} />;
113119
})
114120
}
115121
</div>
Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
import * as React from 'react';
22
import { CommandBarButton } from 'office-ui-fabric-react/lib/Button';
3-
import { ITermAction, TermActionsDisplayStyle, IConreteTermActionProps } from './ITermsActions';
3+
import { ITermAction, TermActionsDisplayStyle, IConcreteTermActionProps } from './ITermsActions';
44

5-
export default class ButtonTermAction extends React.Component<IConreteTermActionProps> {
6-
public render(): React.ReactElement<IConreteTermActionProps> {
5+
export default class ButtonTermAction extends React.Component<IConcreteTermActionProps> {
6+
public render(): React.ReactElement<IConcreteTermActionProps> {
77
const { term, termActions } = this.props;
88

99
return (
1010
<div style={{ display: 'flex', alignItems: 'stretch', height: '32px' }}>
1111
{
1212
termActions &&
1313
termActions.map(termAction => {
14-
const { name, text, iconName } = this._prepareCommandBarButton(termAction);
14+
const { name, text, iconName, btnTitle } = this._prepareCommandBarButton(termAction);
1515
return (
1616
<div>
1717
<CommandBarButton split={true}
18-
onClick={() => { this._onActionExecute(termAction); }}
19-
iconProps={{ iconName: iconName }}
20-
text={text}
21-
name={name}
22-
key={term.Id}
23-
style={this._getTermActionActionButtonStyle()}
18+
onClick={() => { this._onActionExecute(termAction); }}
19+
iconProps={{
20+
iconName: iconName || null,
21+
style: { display: iconName ? null : "none"}
22+
}}
23+
text={text}
24+
title={btnTitle}
25+
name={name}
26+
key={term.Id}
27+
style={this._getTermActionActionButtonStyle()}
2428
/>
2529
</div>
2630
);
@@ -31,32 +35,37 @@ export default class ButtonTermAction extends React.Component<IConreteTermAction
3135
}
3236

3337

34-
private _prepareCommandBarButton = (termAction: ITermAction): { name: string, text: string, iconName: string } => {
35-
let name, text, iconName = "";
38+
private _prepareCommandBarButton = (termAction: ITermAction): { name: string, text: string, iconName: string, btnTitle: string } => {
39+
let name: string = "";
40+
let text: string = "";
41+
let iconName: string = "";
42+
let btnTitle: string = "";
3643

37-
if (this.props.displayStyle && (this.props.displayStyle === TermActionsDisplayStyle.text || this.props.displayStyle === TermActionsDisplayStyle.textAndIcon)) {
38-
name = termAction.displayText;
39-
text = termAction.displayText;
44+
if ((this.props.displayStyle && (this.props.displayStyle === TermActionsDisplayStyle.text || this.props.displayStyle === TermActionsDisplayStyle.textAndIcon))) {
45+
name = termAction.title;
46+
text = termAction.title;
4047
}
4148
if (this.props.displayStyle && (this.props.displayStyle === TermActionsDisplayStyle.icon || this.props.displayStyle === TermActionsDisplayStyle.textAndIcon)) {
4249
iconName = termAction.iconName;
4350
}
4451

45-
return { name, text, iconName };
52+
btnTitle = termAction.title;
53+
54+
return { name, text, iconName, btnTitle };
4655
}
4756

4857
private _getTermActionActionButtonStyle = (): React.CSSProperties => {
4958
let result: React.CSSProperties = {
5059
backgroundColor: "transparent",
51-
width: "32px",
60+
width: this.props.displayStyle === TermActionsDisplayStyle.icon ? "32px" : null,
5261
height: "32px"
5362
};
5463

5564
return result;
5665
}
5766

5867
private _onActionExecute = async (termAction: ITermAction) => {
59-
const updateAction = await termAction.actionCallback(this.props.term);
68+
const updateAction = await termAction.actionCallback(this.props.spTermService, this.props.term);
6069
this.props.termActionCallback(updateAction);
6170
}
6271
}

src/controls/taxonomyPicker/termActions/DropdownTermAction.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as React from 'react';
22
import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
33
import { ITerm } from '../../../services/ISPTermStorePickerService';
4-
import { ITermAction, TermActionsDisplayStyle, UpdateAction, IConreteTermActionProps } from './ITermsActions';
4+
import { ITermAction, TermActionsDisplayStyle, IConcreteTermActionProps } from './ITermsActions';
55
import { IContextualMenuItem, IContextualMenuProps } from 'office-ui-fabric-react/lib/ContextualMenu';
66

7-
export class DropdownTermAction extends React.Component<IConreteTermActionProps> {
8-
public render(): React.ReactElement<IConreteTermActionProps> {
7+
export class DropdownTermAction extends React.Component<IConcreteTermActionProps> {
8+
public render(): React.ReactElement<IConcreteTermActionProps> {
99
const { term, termActions } = this.props;
1010

1111
const termActionButtonStyle = this._getTermActionActionButtonStyle();
@@ -33,8 +33,8 @@ export class DropdownTermAction extends React.Component<IConreteTermActionProps>
3333
};
3434

3535
if (displayStyle && (displayStyle === TermActionsDisplayStyle.text || displayStyle === TermActionsDisplayStyle.textAndIcon)) {
36-
termActionMenuItem.text = termAction.displayText;
37-
termActionMenuItem.name = termAction.displayText;
36+
termActionMenuItem.text = termAction.title;
37+
termActionMenuItem.name = termAction.title;
3838
useTargetWidth = false;
3939
}
4040
if (displayStyle && (displayStyle === TermActionsDisplayStyle.icon || displayStyle === TermActionsDisplayStyle.textAndIcon)) {
@@ -69,7 +69,7 @@ export class DropdownTermAction extends React.Component<IConreteTermActionProps>
6969
* Handler to execute selected action.
7070
*/
7171
private _onActionExecute = async (termAction: ITermAction) => {
72-
const updateAction = await termAction.actionCallback(this.props.term);
72+
const updateAction = await termAction.actionCallback(this.props.spTermService, this.props.term);
7373
this.props.termActionCallback(updateAction);
7474
}
7575
}

0 commit comments

Comments
 (0)