@@ -58,7 +58,114 @@ Custom rendering of a More actions button that displays a context menu for each
58
58
const termSetId = " 36d21c3f-b83b-4acc-a223-4df6fa8e946d" ;
59
59
const [clickedActionTerm, setClickedActionTerm] = React .useState <ITermInfo >();
60
60
61
- const addChildTerm = (parentTermId , updateTaxonomyTreeViewCallback ): void => {
61
+ private addTermSwitch = async (index : number , term : ITermInfo , updateTaxonomyTreeViewCallback : any , isParent : boolean ) => {
62
+ if (isParent ) {
63
+ this .addTerm (index , term , updateTaxonomyTreeViewCallback );
64
+ } else {
65
+ this .addChildTerm (index , term , updateTaxonomyTreeViewCallback );
66
+ }
67
+ }
68
+
69
+ // Below methods are using graphClient to create terms
70
+ private addTerm = async (index : number , term : ITermInfo , updateTaxonomyTreeViewCallback : any ) => {
71
+ try {
72
+ if (termSetId ) {
73
+ this .props .context ?.msGraphClientFactory ?.getClient (" 3" ).then ((client ) => {
74
+ client
75
+ .api (` /sites/${this .props .context ?.pageContext .site .id }/termStore/sets/${termSetId }/terms/${term .id } ` )
76
+ .post ({
77
+ labels: [
78
+ {
79
+ languageTag: " en-US" ,
80
+ name: " TestTerm" ,
81
+ isDefault: true ,
82
+ },
83
+ ],
84
+ })
85
+ .then ((response ) => {
86
+ const { " @odata.context" : _, ... filteredResponse } = response ;
87
+ filteredResponse .isAvailableForTagging = [
88
+ {
89
+ " setId" : termSetId ,
90
+ " isAvailable" : true
91
+ }
92
+ ];
93
+ // Pass the filtered response to updateTaxonomyTreeViewCallback
94
+ updateTaxonomyTreeViewCallback ([filteredResponse ] as ITermInfo [], [term ] as ITermInfo [], null , null );
95
+ })
96
+ .catch ((error ) => {
97
+ console .error (" Error adding child term" , error );
98
+ });
99
+ });
100
+ } else {
101
+ console .error (" termSetId is undefined" );
102
+ }
103
+ } catch (error ) {
104
+ console .error (" Error adding child term" , error );
105
+ }
106
+ }
107
+
108
+ private addChildTerm = async (index : number , term : ITermInfo , updateTaxonomyTreeViewCallback : any ) => {
109
+ try {
110
+ if (termSetId ) {
111
+ this .props .context ?.msGraphClientFactory ?.getClient (" 3" ).then ((client ) => {
112
+ client
113
+ .api (` /sites/${this .props .context ?.pageContext .site .id }/termStore/sets/${termSetId }/terms/${term .id }/children ` )
114
+ .post ({
115
+ labels: [
116
+ {
117
+ languageTag: " en-US" ,
118
+ name: " TestChild" ,
119
+ isDefault: true ,
120
+ },
121
+ ],
122
+ })
123
+ .then ((response ) => {
124
+ // Exclude @odata.context from the response
125
+ const { " @odata.context" : _, ... filteredResponse } = response ;
126
+ filteredResponse .isAvailableForTagging = [
127
+ {
128
+ " setId" : termSetId ,
129
+ " isAvailable" : true
130
+ }
131
+ ];
132
+ // Pass the filtered response to updateTaxonomyTreeViewCallback
133
+ updateTaxonomyTreeViewCallback ([filteredResponse ] as ITermInfo [], [term ] as ITermInfo [], null , null );
134
+ })
135
+ .catch ((error ) => {
136
+ console .error (" Error adding child term" , error );
137
+ });
138
+ });
139
+ } else {
140
+ console .error (" termSetId is undefined" );
141
+ }
142
+ } catch (error ) {
143
+ console .error (" Error adding child term" , error );
144
+ }
145
+ }
146
+
147
+
148
+ private deleteTerm = (_ : number , term : ITermInfo ,updateTaxonomyTreeViewCallback : any ) => {
149
+ if (termSetId ) {
150
+ this .props .context ?.msGraphClientFactory ?.getClient (" 3" ).then ((client ) => {
151
+ client
152
+ .api (` /sites/${this .props .context ?.pageContext .site .id }/termStore/sets/${termSetId }/terms/${term .id } ` )
153
+ .delete ()
154
+ .then (() => {
155
+ console .log (" Term deleted" );
156
+ updateTaxonomyTreeViewCallback (null ,null ,[term ] as ITermInfo []);
157
+ })
158
+ .catch ((error ) => {
159
+ console .error (" Error deleting term" , error );
160
+ });
161
+ });
162
+ } else {
163
+ console .error (" termSetId is undefined" );
164
+ }
165
+ }
166
+
167
+ // Another example in how to create term
168
+ const addChildTerm = (parentTermId , updateTaxonomyTreeViewCallback ): void => {
62
169
spPost (sp .termStore .sets .getById (termSetId ).terms .getById (parentTermId ).children , {
63
170
body: JSON .stringify ({
64
171
" labels" : [
@@ -76,58 +183,53 @@ const addChildTerm = (parentTermId, updateTaxonomyTreeViewCallback): void => {
76
183
.then (term => {
77
184
updateTaxonomyTreeViewCallback ([term ], null , null );
78
185
});
79
- }
80
-
81
- ...
186
+ }
82
187
188
+ // Usage
83
189
< ModernTaxonomyPicker
84
- allowMultipleSelections = {true }
85
- termSetId = {termSetId }
86
- panelTitle = " Panel title"
87
- label = {" Field title" }
88
- context = {this.props.context }
89
- required = {false }
90
- initialValues = {[{labels: [{name: " Subprocess A1" , isDefault: true , languageTag: " en-US" }], id: " 29eced8f-cf08-454b-bd9e-6443bc0a0f5e" }]}
91
- onChange={this.onTaxPickerChange}
92
- disabled={false}
93
- customPanelWidth={700}
94
- isLightDismiss={false}
95
- isBlocking={false}
96
- onRenderActionButton={(
97
- termStoreInfo: ITermStoreInfo ,
98
- termSetInfo: ITermSetInfo ,
99
- termInfo: ITermInfo
100
- updateTaxonomyTreeViewCallback ?: (newTermItems ? : ITermInfo [], updatedTermItems ? : ITermInfo [], deletedTermItems ? : ITermInfo []) => void
190
+ allowMultipleSelections = {true }
191
+ termSetId = {' 8ed8c9ea-7052-4c1d-a4d7-b9c10bffea6f' }
192
+ panelTitle = ' Select Term'
193
+ label = {' Modern Taxonomy Picker' }
194
+ context = {this.props.context }
195
+ required = {false }
196
+ disabled = {false }
197
+ onRenderActionButton = {(
198
+ termStoreInfo: any ,
199
+ termSetInfo: any ,
200
+ termInfo: ITermInfo ,
201
+ updateTaxonomyTreeViewCallback?: (newTermItems ? : ITermInfo [], parentTerm ? : ITermInfo [], updatedTermItems ? : ITermInfo [], deletedTermItems ? : ITermInfo []) => void
101
202
): JSX .Element => {
102
- const menuIcon: IIconProps = { iconName: ' MoreVertical' , " aria-label" : " More actions " , style: { fontSize: " medium" } };
203
+ const menuIcon: IIconProps = { iconName: ' MoreVertical' , ' aria-label' : ' Add or delete terms ' , style: { fontSize: ' medium' } };
103
204
if (termInfo ) {
104
205
const menuProps: IContextualMenuProps = {
105
206
items: [
106
207
{
107
208
key: ' addTerm' ,
108
209
text: ' Add Term' ,
109
210
iconProps: { iconName: ' Tag' },
110
- onClick : () => addChildTerm ( termInfo . id , updateTaxonomyTreeViewCallback )
211
+ onClick : () => { ( async () => await this . addTermSwitch ( 0 , termInfo , updateTaxonomyTreeViewCallback , false ))(); }
111
212
},
112
213
{
113
214
key: ' deleteTerm' ,
114
215
text: ' Delete term' ,
115
216
iconProps: { iconName: ' Untag' },
116
- onClick : () => deleteTerm (termInfo . id , updateTaxonomyTreeViewCallback )
217
+ onClick : () => this . deleteTerm (0 , termInfo , updateTaxonomyTreeViewCallback )
117
218
},
118
219
],
119
220
};
120
-
121
221
return (
122
- < IconButton
222
+ <>
223
+ < IconButton
123
224
menuProps = {menuProps }
124
225
menuIconProps = {menuIcon }
125
- style = {clickedActionTerm && clickedActionTerm.id === termInfo .id ? {opacity: 1 } : null }
126
- onMenuClick = {(ev?: React .MouseEvent < HTMLElement , MouseEvent> | React.KeyboardEvent<HTMLElement>, button?: IButtonProps ) => {
127
- setClickedActionTerm (termInfo ));
226
+ style = {{opacity : 1 }}
227
+ onMenuClick = {(_: React .MouseEvent < HTMLElement , MouseEvent> | React.KeyboardEvent<HTMLElement>, __?: IButtonProps ) => {
228
+ console .log (' IconButton clicked' );
229
+ this .setClickedActionTerm (termInfo );
128
230
}}
129
- onAfterMenuDismiss = {() => setClickedActionTerm(null )}
130
231
/ >
232
+ < / >
131
233
);
132
234
}
133
235
else {
@@ -137,7 +239,7 @@ const addChildTerm = (parentTermId, updateTaxonomyTreeViewCallback): void => {
137
239
key: ' addTerm' ,
138
240
text: ' Add term' ,
139
241
iconProps: { iconName: ' Tag' },
140
- onClick : () => addTerm ( termInfo . id , updateTaxonomyTreeViewCallback )
242
+ onClick : () => { ( async () => await this . addTermSwitch ( 0 , termInfo , updateTaxonomyTreeViewCallback , true ))(); }
141
243
},
142
244
],
143
245
};
@@ -175,7 +277,7 @@ The ModernTaxonomyPicker control can be configured with the following properties
175
277
| themeVariant | IReadonlyTheme | no | The current loaded SharePoint theme/section background (More info: [ Supporting section backgrounds] ( https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/guidance/supporting-section-backgrounds ) ). |
176
278
| isLightDismiss | boolean | no | Whether the panel can be light dismissed. |
177
279
| isBlocking | boolean | no | Whether the panel uses a modal overlay or not. |
178
- | onRenderActionButton | function | no | Optional custom renderer for adding e.g. a button with additional actions to the terms in the tree view. |
280
+ | onRenderActionButton | function | no | Optional custom renderer for adding e.g. a button with additional actions to the terms in the tree view. See advanced example section |
179
281
| isPathRendered | boolean | no | Whether the terms will be rendered with the term label or the full path up to the root. |
180
282
| allowSelectingChildren | boolean | no | Whether child terms can be selected. Default value is true. |
181
283
0 commit comments