@pnp/spfx-property-controls 3.22.0 → 3.23.0-beta.2200135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/CHANGELOG.json +9 -0
  2. package/CHANGELOG.md +2 -0
  3. package/lib/common/telemetry/version.d.ts.map +1 -1
  4. package/lib/common/telemetry/version.js +1 -1
  5. package/lib/common/telemetry/version.js.map +1 -1
  6. package/lib/propertyFields/folderPicker/PropertyFieldFolderPickerHost.d.ts.map +1 -1
  7. package/lib/propertyFields/folderPicker/PropertyFieldFolderPickerHost.js +5 -2
  8. package/lib/propertyFields/folderPicker/PropertyFieldFolderPickerHost.js.map +1 -1
  9. package/lib/propertyFields/folderPicker/controls/FolderExplorer/FolderExplorer.d.ts.map +1 -1
  10. package/lib/propertyFields/folderPicker/controls/FolderExplorer/FolderExplorer.js +9 -4
  11. package/lib/propertyFields/folderPicker/controls/FolderExplorer/FolderExplorer.js.map +1 -1
  12. package/lib/propertyFields/folderPicker/controls/NewFolder/NewFolder.js +1 -1
  13. package/lib/propertyFields/folderPicker/controls/NewFolder/NewFolder.js.map +1 -1
  14. package/lib/propertyFields/termPicker/TermPicker.d.ts.map +1 -1
  15. package/lib/propertyFields/termPicker/TermPicker.js +2 -1
  16. package/lib/propertyFields/termPicker/TermPicker.js.map +1 -1
  17. package/lib/services/FolderExplorerService.d.ts +5 -24
  18. package/lib/services/FolderExplorerService.d.ts.map +1 -1
  19. package/lib/services/FolderExplorerService.js +33 -52
  20. package/lib/services/FolderExplorerService.js.map +1 -1
  21. package/lib/services/PnPTermStorePickerService.d.ts +26 -46
  22. package/lib/services/PnPTermStorePickerService.d.ts.map +1 -1
  23. package/lib/services/PnPTermStorePickerService.js +229 -364
  24. package/lib/services/PnPTermStorePickerService.js.map +1 -1
  25. package/package.json +2 -8
  26. package/release/manifests/bd19c378-ab07-4eaa-9bb6-0e329932d8bf.manifest.json +1 -6
@@ -8,20 +8,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { TermStorePickerServiceHelper } from "./ISPTermStorePickerService";
11
- import { taxonomy, StringMatchOption } from "@pnp/sp-taxonomy";
11
+ import { SPHttpClient } from "@microsoft/sp-http";
12
12
  /**
13
- * Term Store Picker Service implementation that uses @pnp/sp-taxonomy to work with taxonomy service
13
+ * Term Store Picker Service implementation that uses SharePoint REST API for taxonomy
14
+ * This replaces the old @pnp/sp-taxonomy which is no longer available in PnPjs v4
14
15
  */
15
16
  export default class PnPTermStorePickerService {
16
17
  constructor(props, context) {
17
18
  this.props = props;
18
- this.context = context;
19
19
  this._termSetCollectionObjectType = 'SP.Taxonomy.TermSetCollection';
20
20
  this._termGroupCollectionObjectType = 'SP.Taxonomy.TermGroupCollection';
21
- this._pnpGroups = {};
22
- taxonomy.setup({
23
- spfxContext: context
24
- //globalCacheDisable: true // uncomment this one for debugging with no cache
21
+ this._groups = {};
22
+ // No initialization needed - we use SPHttpClient from context
23
+ this.context = context;
24
+ }
25
+ /**
26
+ * Makes a request to the taxonomy REST API
27
+ * @param endpoint - The endpoint path after /v2.1/_api/
28
+ */
29
+ _taxonomyRequest(endpoint) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ const url = `${this.context.pageContext.web.absoluteUrl}/_api/v2.1/${endpoint}`;
32
+ const response = yield this.context.spHttpClient.get(url, SPHttpClient.configurations.v1);
33
+ if (!response.ok) {
34
+ throw new Error(`Taxonomy API request failed: ${response.statusText}`);
35
+ }
36
+ return response.json();
25
37
  });
26
38
  }
27
39
  /**
@@ -30,22 +42,7 @@ export default class PnPTermStorePickerService {
30
42
  getTermStores() {
31
43
  return __awaiter(this, void 0, void 0, function* () {
32
44
  yield this._ensureTermStores();
33
- const result = [];
34
- this._pnpTermStores.forEach(pnpTermStore => {
35
- result.push({
36
- _ObjectType_: 'SP.Taxonomy.TermStore',
37
- _ObjectIdentity_: pnpTermStore._ObjectIdentity_, // eslint-disable-line @typescript-eslint/no-explicit-any
38
- Id: pnpTermStore.Id,
39
- Name: pnpTermStore.Name,
40
- Groups: {
41
- _ObjectType_: this._termGroupCollectionObjectType,
42
- _Child_Items_: this._pnpGroups[pnpTermStore.Id].map(g => {
43
- return this._pnpTermGroup2TermGroup(g, pnpTermStore);
44
- })
45
- }
46
- });
47
- });
48
- return result;
45
+ return this._termStores;
49
46
  });
50
47
  }
51
48
  /**
@@ -54,13 +51,13 @@ export default class PnPTermStorePickerService {
54
51
  */
55
52
  searchTermsByName(searchText) {
56
53
  return __awaiter(this, void 0, void 0, function* () {
57
- if (this.props.limitByTermsetNameOrID) { // search in specific term(s)
54
+ if (this.props.limitByTermsetNameOrID) {
58
55
  return this._searchTermsByTermSet(searchText);
59
56
  }
60
- else if (this.props.limitByGroupNameOrID) { // search in specific group
57
+ else if (this.props.limitByGroupNameOrID) {
61
58
  return this._searchTermsByGroup(searchText);
62
59
  }
63
- else { // search everywhere
60
+ else {
64
61
  return this._searchAllTerms(searchText);
65
62
  }
66
63
  });
@@ -70,44 +67,20 @@ export default class PnPTermStorePickerService {
70
67
  */
71
68
  getTermSets() {
72
69
  return __awaiter(this, void 0, void 0, function* () {
73
- let termSets = [];
74
70
  yield this._ensureTermStores();
75
- for (let i = 0, len = this._pnpTermStores.length; i < len; i++) {
76
- const pnpTermStore = this._pnpTermStores[i];
77
- if (this.props.limitByTermsetNameOrID) {
78
- const pnpTermSets = yield this._getPnPTermSetsByNameOrId(pnpTermStore, this.props.limitByTermsetNameOrID);
79
- const groupsBatch = taxonomy.createBatch();
80
- for (let termSetIdx = 0, termSetLen = pnpTermSets.length; termSetIdx < termSetLen; termSetIdx++) {
81
- const pnpTermSet = pnpTermSets[termSetIdx];
82
- const termSet = this._pnpTermSet2TermSet(pnpTermSet, '');
83
- termSets.push(termSet);
84
- pnpTermSet.group.inBatch(groupsBatch).usingCaching().get().then(pnpTermGroup => {
85
- termSet.Group = TermStorePickerServiceHelper.cleanGuid(pnpTermGroup.Id);
86
- }).catch(() => { });
87
- }
88
- yield groupsBatch.execute();
89
- }
90
- else {
91
- let pnpGroups;
92
- if (this.props.limitByGroupNameOrID) {
93
- const pnpGroup = this._getPnPTermGroupsByNameOrId(pnpTermStore.Id, this.props.limitByGroupNameOrID);
94
- pnpGroups = [];
95
- if (pnpGroup) {
96
- pnpGroups.push(pnpGroup);
97
- }
71
+ let termSets = [];
72
+ for (const termStore of this._termStores) {
73
+ const groups = this._groups[termStore.Id];
74
+ for (const group of groups) {
75
+ if (this.props.limitByTermsetNameOrID) {
76
+ // Filter to specific term set
77
+ const filteredTermSets = group.TermSets._Child_Items_.filter(ts => ts.Name === this.props.limitByTermsetNameOrID ||
78
+ ts.Id.toLowerCase() === this.props.limitByTermsetNameOrID.toLowerCase());
79
+ termSets = [...termSets, ...filteredTermSets];
98
80
  }
99
81
  else {
100
- pnpGroups = this._pnpGroups[pnpTermStore.Id];
82
+ termSets = [...termSets, ...group.TermSets._Child_Items_];
101
83
  }
102
- const batch = taxonomy.createBatch();
103
- pnpGroups.forEach(pnpGroup => {
104
- pnpGroup.termSets.inBatch(batch).usingCaching().get().then(pnpTermSets => {
105
- termSets = [...termSets, ...pnpTermSets.map(pnpTermSet => {
106
- return this._pnpTermSet2TermSet(pnpTermSet, TermStorePickerServiceHelper.cleanGuid(pnpGroup.Id));
107
- })];
108
- }).catch(() => { });
109
- });
110
- yield batch.execute();
111
84
  }
112
85
  }
113
86
  return termSets;
@@ -120,33 +93,50 @@ export default class PnPTermStorePickerService {
120
93
  getAllTerms(termSet) {
121
94
  return __awaiter(this, void 0, void 0, function* () {
122
95
  yield this._ensureTermStores();
123
- const pnpTermStores = this._pnpTermStores;
124
- for (const pnpTermStore of pnpTermStores) {
125
- const termsResult = yield this._tryGetAllTerms(pnpTermStore, termSet).catch((error) => { }); // .catch part is needed to proceed if there was a rejected promise
126
- if (!termsResult) { // terms variable will be undefined if the Promise has been rejected. Otherwise it will contain an array
127
- continue;
128
- }
129
- const pnpTerms = termsResult;
96
+ try {
97
+ // Use the new taxonomy REST API to get terms
98
+ const response = yield this._taxonomyRequest(`termStore/sets/${termSet.Id}/terms?$expand=children`);
130
99
  const resultTerms = [];
131
- const labelsBatch = taxonomy.createBatch();
132
- for (let termIdx = 0, termsLen = pnpTerms.length; termIdx < termsLen; termIdx++) {
133
- const pnpTerm = pnpTerms[termIdx];
134
- const term = pnpTerm;
135
- term.Id = TermStorePickerServiceHelper.cleanGuid(term.Id);
136
- term.PathDepth = term.PathOfTerm.split(';').length;
137
- term.TermSet = termSet;
138
- resultTerms.push(term);
139
- if (this.props.includeLabels) {
140
- pnpTerm.labels.inBatch(labelsBatch).usingCaching().get().then(labels => {
141
- term.Labels = labels.map(label => label.Value);
142
- }).catch(() => { });
100
+ // Recursively process terms to build flat list with paths
101
+ const processTerms = (terms, parentPath = '', depth = 1) => {
102
+ for (const taxonomyTerm of terms) {
103
+ const termName = this._getDefaultLabel(taxonomyTerm);
104
+ const pathOfTerm = parentPath ? `${parentPath};${termName}` : termName;
105
+ const term = {
106
+ _ObjectType_: 'SP.Taxonomy.Term',
107
+ _ObjectIdentity_: taxonomyTerm.id,
108
+ Id: taxonomyTerm.id,
109
+ Name: termName,
110
+ Description: this._getDescription(taxonomyTerm),
111
+ IsDeprecated: taxonomyTerm.isDeprecated || false,
112
+ IsAvailableForTagging: taxonomyTerm.isAvailableForTagging !== false,
113
+ IsRoot: depth === 1,
114
+ PathOfTerm: pathOfTerm,
115
+ PathDepth: depth,
116
+ TermSet: {
117
+ _ObjectType_: 'SP.Taxonomy.TermSet',
118
+ _ObjectIdentity_: termSet.Id,
119
+ Id: termSet.Id,
120
+ Name: termSet.Name
121
+ }
122
+ };
123
+ if (this.props.includeLabels) {
124
+ term.Labels = taxonomyTerm.labels.map(l => l.name);
125
+ }
126
+ resultTerms.push(term);
127
+ // Process children recursively
128
+ if (taxonomyTerm.children && taxonomyTerm.children.length > 0) {
129
+ processTerms(taxonomyTerm.children, pathOfTerm, depth + 1);
130
+ }
143
131
  }
144
- }
145
- if (this.props.includeLabels) {
146
- yield labelsBatch.execute();
147
- }
132
+ };
133
+ processTerms(response.value);
148
134
  return TermStorePickerServiceHelper.sortTerms(resultTerms);
149
135
  }
136
+ catch (error) {
137
+ console.error('Error loading terms', error);
138
+ return [];
139
+ }
150
140
  });
151
141
  }
152
142
  /**
@@ -154,357 +144,232 @@ export default class PnPTermStorePickerService {
154
144
  * @param group Term Group
155
145
  */
156
146
  getGroupTermSets(group) {
147
+ var _a, _b;
157
148
  return __awaiter(this, void 0, void 0, function* () {
158
149
  yield this._ensureTermStores();
159
- const pnpTermStore = this._pnpTermStores.filter(ts => TermStorePickerServiceHelper.cleanGuid(ts.Id) === group.TermStore.Id)[0];
160
- const pnpGroups = this._pnpGroups[pnpTermStore.Id].filter(gr => TermStorePickerServiceHelper.cleanGuid(gr.Id) === group.Id); //await pnpTermStore.getTermGroupById(group.Id).usingCaching().get();
161
- if (!pnpGroups || !pnpGroups.length) {
150
+ const groupData = (_b = this._groups[((_a = group.TermStore) === null || _a === void 0 ? void 0 : _a.Id) || this._termStoreId]) === null || _b === void 0 ? void 0 : _b.find(g => g.Id === group.Id);
151
+ if (!groupData) {
162
152
  return {
163
153
  _ObjectType_: this._termSetCollectionObjectType,
164
154
  _Child_Items_: []
165
155
  };
166
156
  }
167
- const pnpGroup = pnpGroups[0];
168
- let pnpTermSets;
157
+ let termSets = groupData.TermSets._Child_Items_;
169
158
  if (this.props.limitByTermsetNameOrID) {
170
- const isGuid = TermStorePickerServiceHelper.isGuid(this.props.limitByTermsetNameOrID);
171
- if (isGuid) {
172
- pnpTermSets = [yield pnpGroup.termSets.getById(this.props.limitByTermsetNameOrID).usingCaching().get()];
173
- }
174
- else {
175
- pnpTermSets = [yield pnpGroup.termSets.getByName(this.props.limitByTermsetNameOrID).usingCaching().get()];
176
- }
177
- }
178
- else {
179
- pnpTermSets = yield pnpGroup.termSets.usingCaching().get();
159
+ termSets = termSets.filter(ts => ts.Name === this.props.limitByTermsetNameOrID ||
160
+ ts.Id.toLowerCase() === this.props.limitByTermsetNameOrID.toLowerCase());
180
161
  }
181
- const result = {
162
+ return {
182
163
  _ObjectType_: this._termSetCollectionObjectType,
183
- _Child_Items_: pnpTermSets.map(pnpTermSet => {
184
- return this._pnpTermSet2TermSet(pnpTermSet, TermStorePickerServiceHelper.cleanGuid(pnpGroup.Id));
185
- })
164
+ _Child_Items_: termSets
186
165
  };
187
- return result;
188
- });
189
- }
190
- /**
191
- * Tries to get terms from the specified Term Set.
192
- * @param pnpTermStore Term Store to work with
193
- * @param termSet Term set to get terms from
194
- */
195
- _tryGetAllTerms(pnpTermStore, termSet) {
196
- return new Promise((resolve, reject) => {
197
- pnpTermStore.getTermSetById(termSet.Id).terms.usingCaching().get().then((pnpTerms) => {
198
- resolve(pnpTerms);
199
- }, (error) => {
200
- reject(error);
201
- });
202
166
  });
203
167
  }
204
168
  /**
205
- * Searches terms by provided text in the term sets specified by the this.props.limitByTermSetNameOrId
206
- * @param searchText text to search
169
+ * Searches terms by provided text in the term sets specified by limitByTermsetNameOrID
207
170
  */
208
171
  _searchTermsByTermSet(searchText) {
209
172
  return __awaiter(this, void 0, void 0, function* () {
210
173
  yield this._ensureTermStores();
211
174
  const returnTerms = [];
212
- const pnpTermStores = this._pnpTermStores;
213
- //
214
- // iterating through term stores
215
- //
216
- for (let i = 0, len = pnpTermStores.length; i < len; i++) {
217
- const pnpTermStore = pnpTermStores[i];
218
- const pnpTermSets = yield this._getPnPTermSetsByNameOrId(pnpTermStore, this.props.limitByTermsetNameOrID);
219
- // getting filtered terms from term sets
220
- returnTerms.push(...yield this._searchTermsInTermSets(pnpTermStore, pnpTermSets, searchText));
175
+ const termSets = yield this.getTermSets();
176
+ for (const termSet of termSets) {
177
+ const terms = yield this.getAllTerms(termSet);
178
+ const filtered = this._filterTermsBySearch(terms, searchText);
179
+ for (const term of filtered) {
180
+ returnTerms.push(this._termToPickerTerm(term, termSet));
181
+ }
221
182
  }
222
183
  return returnTerms;
223
184
  });
224
185
  }
225
186
  /**
226
- * Searches terms by provided text in the term sets specified by the this.props.limitByGroupNameOrId
227
- * @param searchText text to search
187
+ * Searches terms by provided text in the group specified by limitByGroupNameOrID
228
188
  */
229
189
  _searchTermsByGroup(searchText) {
230
190
  return __awaiter(this, void 0, void 0, function* () {
231
191
  yield this._ensureTermStores();
232
- const groupNameOrID = this.props.limitByGroupNameOrID;
233
192
  const returnTerms = [];
234
- const pnpTermStores = this._pnpTermStores;
235
- //
236
- // iterating through term stores
237
- //
238
- for (let i = 0, len = pnpTermStores.length; i < len; i++) {
239
- const pnpTermStore = pnpTermStores[i];
240
- const pnpGroup = this._getPnPTermGroupsByNameOrId(pnpTermStore.Id, groupNameOrID);
241
- if (!pnpGroup) {
242
- continue;
193
+ for (const termStore of this._termStores) {
194
+ const groups = this._groups[termStore.Id];
195
+ const targetGroup = groups.find(g => g.Name === this.props.limitByGroupNameOrID ||
196
+ g.Id.toLowerCase() === this.props.limitByGroupNameOrID.toLowerCase());
197
+ if (targetGroup) {
198
+ for (const termSet of targetGroup.TermSets._Child_Items_) {
199
+ const terms = yield this.getAllTerms(termSet);
200
+ const filtered = this._filterTermsBySearch(terms, searchText);
201
+ for (const term of filtered) {
202
+ const pickerTerm = this._termToPickerTerm(term, termSet);
203
+ pickerTerm.termGroup = targetGroup.Id;
204
+ returnTerms.push(pickerTerm);
205
+ }
206
+ }
243
207
  }
244
- // getting term sets from term group
245
- const pnpTermSets = yield pnpGroup.termSets.usingCaching().get();
246
- // getting filtered terms from term sets
247
- returnTerms.push(...yield this._searchTermsInTermSets(pnpTermStore, pnpTermSets, searchText, pnpGroup.Id));
248
208
  }
249
209
  return returnTerms;
250
210
  });
251
211
  }
252
212
  /**
253
- * Searches for terms in the term store
254
- * @param searchText text to search
213
+ * Searches for terms across all term stores
255
214
  */
256
215
  _searchAllTerms(searchText) {
257
216
  return __awaiter(this, void 0, void 0, function* () {
258
217
  yield this._ensureTermStores();
259
- const pnpTermStores = this._pnpTermStores;
260
218
  const returnTerms = [];
261
- //
262
- // iterating through term stores
263
- //
264
- for (let i = 0, len = pnpTermStores.length; i < len; i++) {
265
- const pnpTermStore = pnpTermStores[i];
266
- // searching for terms that starts with provided string
267
- const pnpTerms = yield pnpTermStore.getTerms({
268
- TermLabel: searchText,
269
- StringMatchOption: StringMatchOption.StartsWith,
270
- DefaultLabelOnly: true,
271
- TrimUnavailable: true,
272
- ResultCollectionSize: 30
273
- }).usingCaching().get();
274
- const batch = taxonomy.createBatch();
275
- //
276
- // processing each term to get termSet info and labels
277
- //
278
- pnpTerms.forEach(pnpTerm => {
279
- const pickerTerm = {
280
- key: TermStorePickerServiceHelper.cleanGuid(pnpTerm.Id),
281
- name: pnpTerm.Name,
282
- path: pnpTerm.PathOfTerm,
283
- termSet: '',
284
- termGroup: ''
285
- };
286
- returnTerms.push(pickerTerm);
287
- pnpTerm.termSet.group.inBatch(batch).usingCaching().get().then(pnpTermGroup => {
288
- pickerTerm.termGroup = TermStorePickerServiceHelper.cleanGuid(pnpTermGroup.Id);
289
- }).catch(() => { });
290
- pnpTerm.termSet.inBatch(batch).usingCaching().get().then(pnpTermSet => {
291
- pickerTerm.termSet = TermStorePickerServiceHelper.cleanGuid(pnpTermSet.Id);
292
- pickerTerm.termSetName = pnpTermSet.Name;
293
- }).catch(() => { });
294
- if (this.props.includeLabels) {
295
- pnpTerm.labels.inBatch(batch).usingCaching().get().then(labels => {
296
- pickerTerm.labels = labels.map(label => label.Value);
297
- }).catch(() => { });
219
+ for (const termStore of this._termStores) {
220
+ const groups = this._groups[termStore.Id];
221
+ for (const group of groups) {
222
+ for (const termSet of group.TermSets._Child_Items_) {
223
+ const terms = yield this.getAllTerms(termSet);
224
+ const filtered = this._filterTermsBySearch(terms, searchText);
225
+ for (const term of filtered) {
226
+ const pickerTerm = this._termToPickerTerm(term, termSet);
227
+ pickerTerm.termGroup = group.Id;
228
+ returnTerms.push(pickerTerm);
229
+ }
298
230
  }
299
- });
300
- yield batch.execute();
231
+ }
301
232
  }
302
233
  return returnTerms;
303
234
  });
304
235
  }
305
236
  /**
306
- * Searches for terms by provided text in specified term sets
307
- * @param pnpTermStore Term Store
308
- * @param pnpTermSets term sets where the terms should be searched for
309
- * @param searchText text to search
310
- * @param termGroupId Id of the group that contains the term sets
237
+ * Filters terms by search text (starts with, case-insensitive)
311
238
  */
312
- _searchTermsInTermSets(pnpTermStore, pnpTermSets, searchText, termGroupId) {
313
- return __awaiter(this, void 0, void 0, function* () {
314
- const returnTerms = [];
315
- const termSetGroups = {};
316
- const termsBatch = taxonomy.createBatch();
317
- const labelsBatch = taxonomy.createBatch();
318
- const lowerCasedSearchText = searchText.toLowerCase();
319
- for (let termSetIdx = 0, termSetLen = pnpTermSets.length; termSetIdx < termSetLen; termSetIdx++) {
320
- const pnpTermSet = pnpTermSets[termSetIdx];
321
- const pnpTermSetGuid = TermStorePickerServiceHelper.cleanGuid(pnpTermSet.Id);
322
- if (!termGroupId) { // if no group id provided we need to load it from store
323
- pnpTermSet.group.inBatch(termsBatch).usingCaching().get().then(pnpTermGroup => {
324
- termSetGroups[pnpTermSet.Id] = pnpTermGroup.Id;
325
- const loadedTerms = returnTerms.filter(t => t.termSet === pnpTermSetGuid);
326
- loadedTerms.forEach(t => {
327
- t.termGroup = TermStorePickerServiceHelper.cleanGuid(pnpTermGroup.Id);
328
- });
329
- }).catch(() => { });
330
- }
331
- // getting terms for term set in batch
332
- pnpTermSet.terms.inBatch(termsBatch).usingCaching().get().then(pnpTerms => {
333
- for (let termIdx = 0, termLen = pnpTerms.length; termIdx < termLen; termIdx++) {
334
- const pnpTerm = pnpTerms[termIdx];
335
- if (pnpTerm.Name.toLowerCase().indexOf(lowerCasedSearchText) === 0) {
336
- const pickerTerm = {
337
- key: TermStorePickerServiceHelper.cleanGuid(pnpTerm.Id),
338
- name: pnpTerm.Name,
339
- path: pnpTerm.PathOfTerm,
340
- termSet: TermStorePickerServiceHelper.cleanGuid(pnpTermSetGuid),
341
- termSetName: pnpTermSet.Name,
342
- termGroup: termGroupId || TermStorePickerServiceHelper.cleanGuid(termSetGroups[pnpTermSet.Id])
343
- };
344
- returnTerms.push(pickerTerm);
345
- // getting labels for each term in a separate batch
346
- if (this.props.includeLabels) {
347
- pnpTerm.labels.inBatch(labelsBatch).usingCaching().get().then(pnpLabels => {
348
- pickerTerm.labels = pnpLabels.map(l => l.Value);
349
- }).catch(() => { });
350
- }
351
- }
352
- }
353
- }).catch(() => { });
354
- }
355
- //
356
- // executing batches
357
- //
358
- yield termsBatch.execute();
359
- if (this.props.includeLabels) {
360
- yield labelsBatch.execute();
361
- }
362
- return returnTerms;
363
- });
239
+ _filterTermsBySearch(terms, searchText) {
240
+ const lowerSearch = searchText.toLowerCase();
241
+ return terms.filter(t => t.Name.toLowerCase().startsWith(lowerSearch)).slice(0, 30);
242
+ }
243
+ /**
244
+ * Converts an ITerm to an IPickerTerm
245
+ */
246
+ _termToPickerTerm(term, termSet) {
247
+ const pickerTerm = {
248
+ key: term.Id,
249
+ name: term.Name,
250
+ path: term.PathOfTerm,
251
+ termSet: termSet.Id,
252
+ termSetName: termSet.Name,
253
+ termGroup: ''
254
+ };
255
+ if (term.Labels) {
256
+ pickerTerm.labels = term.Labels;
257
+ }
258
+ return pickerTerm;
364
259
  }
365
260
  /**
366
- * Ensures (loads if needed) term stores and term groups from taxonomy service
261
+ * Ensures term stores and groups are loaded
367
262
  */
368
263
  _ensureTermStores() {
369
264
  return __awaiter(this, void 0, void 0, function* () {
370
- if (!this._pnpTermStores) {
371
- this._pnpTermStores = yield taxonomy.termStores.usingCaching().get();
372
- // TODO: limit by group or termset
373
- for (let i = 0, len = this._pnpTermStores.length; i < len; i++) {
374
- const pnpTermStore = this._pnpTermStores[i];
375
- let pnpGroups;
376
- if (this.props.limitByGroupNameOrID) {
377
- const group = yield this._requestPnPTermGroupByNameOrId(pnpTermStore, this.props.limitByGroupNameOrID);
378
- pnpGroups = [];
379
- if (group) {
380
- pnpGroups.push(group);
381
- }
382
- }
383
- else if (this.props.limitByTermsetNameOrID) {
384
- const pnpTermSets = yield this._getPnPTermSetsByNameOrId(pnpTermStore, this.props.limitByTermsetNameOrID);
385
- pnpGroups = [];
386
- const groupsBatch = taxonomy.createBatch();
387
- pnpTermSets.forEach(pnpTermSet => {
388
- pnpTermSet.group.inBatch(groupsBatch).usingCaching().get().then(pnpGroup => {
389
- if (!pnpGroups.filter(gr => gr.Id === pnpGroup.Id).length) {
390
- pnpGroups.push(pnpGroup);
391
- }
392
- }).catch(() => { });
265
+ if (this._termStores) {
266
+ return;
267
+ }
268
+ try {
269
+ // Get the default term store
270
+ const termStoreInfo = yield this._taxonomyRequest('termStore');
271
+ this._termStoreId = termStoreInfo.id;
272
+ // Get all groups in the term store
273
+ const groupsResponse = yield this._taxonomyRequest('termStore/groups');
274
+ let groups = groupsResponse.value;
275
+ // Filter by group if specified
276
+ if (this.props.limitByGroupNameOrID) {
277
+ groups = groups.filter(g => g.name === this.props.limitByGroupNameOrID ||
278
+ g.id.toLowerCase() === this.props.limitByGroupNameOrID.toLowerCase());
279
+ }
280
+ // Exclude system groups if specified
281
+ if (this.props.excludeSystemGroup) {
282
+ groups = groups.filter(g => g.type !== 'systemGroup');
283
+ }
284
+ // Build the groups with their term sets
285
+ const processedGroups = [];
286
+ for (const taxonomyGroup of groups) {
287
+ // Get term sets for this group
288
+ const termSetsResponse = yield this._taxonomyRequest(`termStore/groups/${taxonomyGroup.id}/sets`);
289
+ let termSets = termSetsResponse.value;
290
+ // Filter by term set if specified
291
+ if (this.props.limitByTermsetNameOrID) {
292
+ termSets = termSets.filter(ts => {
293
+ var _a, _b;
294
+ const name = ((_a = ts.localizedNames.find(n => n.languageTag === termStoreInfo.defaultLanguageTag)) === null || _a === void 0 ? void 0 : _a.name) || ((_b = ts.localizedNames[0]) === null || _b === void 0 ? void 0 : _b.name);
295
+ return name === this.props.limitByTermsetNameOrID ||
296
+ ts.id.toLowerCase() === this.props.limitByTermsetNameOrID.toLowerCase();
393
297
  });
394
- yield groupsBatch.execute();
395
298
  }
396
- else {
397
- pnpGroups = yield pnpTermStore.groups.usingCaching().get();
299
+ const group = {
300
+ _ObjectType_: 'SP.Taxonomy.TermGroup',
301
+ _ObjectIdentity_: taxonomyGroup.id,
302
+ Id: taxonomyGroup.id,
303
+ Name: taxonomyGroup.name,
304
+ IsSystemGroup: taxonomyGroup.type === 'systemGroup',
305
+ TermStore: {
306
+ Id: termStoreInfo.id,
307
+ Name: termStoreInfo.name
308
+ },
309
+ TermSets: {
310
+ _ObjectType_: this._termSetCollectionObjectType,
311
+ _Child_Items_: termSets.map(ts => this._convertTermSet(ts, termStoreInfo.defaultLanguageTag, taxonomyGroup.id))
312
+ }
313
+ };
314
+ // Only add groups that have term sets (after filtering)
315
+ if (group.TermSets._Child_Items_.length > 0 || !this.props.limitByTermsetNameOrID) {
316
+ processedGroups.push(group);
398
317
  }
399
- this._pnpGroups[pnpTermStore.Id] = pnpGroups;
400
318
  }
319
+ this._groups[termStoreInfo.id] = processedGroups;
320
+ // Build the term store result
321
+ this._termStores = [{
322
+ _ObjectType_: 'SP.Taxonomy.TermStore',
323
+ _ObjectIdentity_: termStoreInfo.id,
324
+ Id: termStoreInfo.id,
325
+ Name: termStoreInfo.name,
326
+ Groups: {
327
+ _ObjectType_: this._termGroupCollectionObjectType,
328
+ _Child_Items_: processedGroups
329
+ }
330
+ }];
331
+ }
332
+ catch (error) {
333
+ console.error('Error loading term stores', error);
334
+ this._termStores = [];
401
335
  }
402
336
  });
403
337
  }
404
338
  /**
405
- * Converts @pnp/sp-taxonomy Term Set instance into internal ITermSet object
406
- * @param pnpTermSet @pnp/sp-taxonomy Term Set instance
407
- * @param groupId Id of the group that contains the term set
339
+ * Converts a taxonomy API term set to the internal ITermSet format
408
340
  */
409
- _pnpTermSet2TermSet(pnpTermSet, groupId) {
410
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
411
- const anyPnPTermSet = pnpTermSet; // we need this one to reference _ObjectType_ and _ObjectIdentity_
341
+ _convertTermSet(taxonomyTermSet, defaultLanguage, groupId) {
342
+ var _a, _b;
343
+ const defaultName = ((_a = taxonomyTermSet.localizedNames.find(n => n.languageTag === defaultLanguage)) === null || _a === void 0 ? void 0 : _a.name) ||
344
+ ((_b = taxonomyTermSet.localizedNames[0]) === null || _b === void 0 ? void 0 : _b.name) || '';
345
+ const names = {};
346
+ taxonomyTermSet.localizedNames.forEach(n => {
347
+ names[n.languageTag] = n.name;
348
+ });
412
349
  return {
413
- _ObjectType_: anyPnPTermSet._ObjectType_,
414
- _ObjectIdentity_: anyPnPTermSet._ObjectIdentity_,
415
- Id: TermStorePickerServiceHelper.cleanGuid(pnpTermSet.Id),
416
- Name: pnpTermSet.Name,
417
- Description: pnpTermSet.Description,
418
- Names: pnpTermSet.Names,
350
+ _ObjectType_: 'SP.Taxonomy.TermSet',
351
+ _ObjectIdentity_: taxonomyTermSet.id,
352
+ Id: taxonomyTermSet.id,
353
+ Name: defaultName,
354
+ Description: taxonomyTermSet.description || '',
355
+ Names: names,
419
356
  Group: groupId
420
357
  };
421
358
  }
422
359
  /**
423
- * Converts @pnp/sp-taxonomy Term Group instance into internal IGroup object
424
- * @param pnpTermGroup @pnp/sp-taxonomy Term Group instance
425
- * @param pnpTermStore @pnp/sp-taxonumy term store to work with
360
+ * Gets the default label from a taxonomy term
426
361
  */
427
- _pnpTermGroup2TermGroup(pnpTermGroup, pnpTermStore) {
428
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
429
- const anyPnPTermGroup = pnpTermGroup; // we need this one to reference _ObjectType_ and _ObjectIdentity_
430
- return {
431
- _ObjectType_: anyPnPTermGroup._ObjectType_,
432
- _ObjectIdentity_: anyPnPTermGroup._ObjectIdentity_,
433
- Id: TermStorePickerServiceHelper.cleanGuid(pnpTermGroup.Id),
434
- Name: pnpTermGroup.Name,
435
- IsSystemGroup: pnpTermGroup.IsSystemGroup,
436
- TermStore: {
437
- Id: TermStorePickerServiceHelper.cleanGuid(pnpTermStore.Id),
438
- Name: pnpTermStore.Name
439
- },
440
- TermSets: {
441
- _ObjectType_: this._termSetCollectionObjectType,
442
- _Child_Items_: null
443
- }
444
- };
445
- }
446
- /**
447
- * Gets term set(s) from taxonomy service by name or id
448
- * @param pnpTermStore @pnp/sp-taxonumy term store to work with
449
- * @param termSetNameOrID term set name or id
450
- */
451
- _getPnPTermSetsByNameOrId(pnpTermStore, termSetNameOrID) {
452
- return __awaiter(this, void 0, void 0, function* () {
453
- let pnpTermSets;
454
- const isGuid = TermStorePickerServiceHelper.isGuid(termSetNameOrID);
455
- //
456
- // getting term sets by filter
457
- //
458
- if (isGuid) {
459
- pnpTermSets = [];
460
- const pnpTermSet = yield pnpTermStore.getTermSetById(termSetNameOrID).usingCaching().get();
461
- if (pnpTermSet.Id) {
462
- pnpTermSets.push(pnpTermSet);
463
- }
464
- }
465
- else {
466
- pnpTermSets = yield pnpTermStore.getTermSetsByName(termSetNameOrID, pnpTermStore.DefaultLanguage).usingCaching().get();
467
- }
468
- return pnpTermSets;
469
- });
362
+ _getDefaultLabel(taxonomyTerm) {
363
+ var _a;
364
+ const defaultLabel = taxonomyTerm.labels.find(l => l.isDefault);
365
+ return (defaultLabel === null || defaultLabel === void 0 ? void 0 : defaultLabel.name) || ((_a = taxonomyTerm.labels[0]) === null || _a === void 0 ? void 0 : _a.name) || '';
470
366
  }
471
367
  /**
472
- * Gets group from cached (previously loaded) list of groups by name or id
473
- * @param termStoreId term store id
474
- * @param groupNameOrID group name or id
368
+ * Gets the description from a taxonomy term
475
369
  */
476
- _getPnPTermGroupsByNameOrId(termStoreId, groupNameOrID) {
477
- const isGuid = TermStorePickerServiceHelper.isGuid(groupNameOrID);
478
- const pnpTermStoreGroups = this._pnpGroups[termStoreId];
479
- if (pnpTermStoreGroups) {
480
- const groups = pnpTermStoreGroups.filter(pnpGroup => isGuid ? TermStorePickerServiceHelper.cleanGuid(pnpGroup.Id) === groupNameOrID
481
- : pnpGroup.Name === groupNameOrID);
482
- if (groups && groups.length) {
483
- return groups[0];
484
- }
485
- }
486
- return null;
487
- }
488
- /**
489
- * Gets group from taxonomy service by name or id
490
- * @param pnpTermStore @pnp/sp-taxonomy term store to work with
491
- * @param groupNameOrID group name or id
492
- */
493
- _requestPnPTermGroupByNameOrId(pnpTermStore, groupNameOrID) {
494
- return __awaiter(this, void 0, void 0, function* () {
495
- const isGuid = TermStorePickerServiceHelper.isGuid(groupNameOrID);
496
- let group;
497
- if (isGuid) {
498
- group = yield pnpTermStore.getTermGroupById(groupNameOrID).usingCaching().get();
499
- }
500
- else {
501
- group = yield pnpTermStore.groups.getByName(groupNameOrID).usingCaching().get();
502
- }
503
- if (group.Id) {
504
- return group;
505
- }
506
- return null;
507
- });
370
+ _getDescription(taxonomyTerm) {
371
+ var _a, _b;
372
+ return ((_b = (_a = taxonomyTerm.descriptions) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.description) || '';
508
373
  }
509
374
  }
510
375
  //# sourceMappingURL=PnPTermStorePickerService.js.map