UNPKG

@pnp/spfx-property-controls

Version:

Reusable property pane controls for SharePoint Framework solutions

367 lines 16.4 kB
import { __awaiter } from "tslib"; import { TermStorePickerServiceHelper } from "./ISPTermStorePickerService"; import { SPHttpClient } from "@microsoft/sp-http"; /** * Term Store Picker Service implementation that uses SharePoint REST API for taxonomy * This replaces the old @pnp/sp-taxonomy which is no longer available in PnPjs v4 */ export default class PnPTermStorePickerService { constructor(props, context) { this.props = props; this._termSetCollectionObjectType = 'SP.Taxonomy.TermSetCollection'; this._termGroupCollectionObjectType = 'SP.Taxonomy.TermGroupCollection'; this._groups = {}; // No initialization needed - we use SPHttpClient from context this.context = context; } /** * Makes a request to the taxonomy REST API * @param endpoint - The endpoint path after /v2.1/_api/ */ _taxonomyRequest(endpoint) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.context.pageContext.web.absoluteUrl}/_api/v2.1/${endpoint}`; const response = yield this.context.spHttpClient.get(url, SPHttpClient.configurations.v1); if (!response.ok) { throw new Error(`Taxonomy API request failed: ${response.statusText}`); } return response.json(); }); } /** * Gets term stores from the taxonomy service */ getTermStores() { return __awaiter(this, void 0, void 0, function* () { yield this._ensureTermStores(); return this._termStores; }); } /** * Searches terms by provided text * @param searchText text to search */ searchTermsByName(searchText) { return __awaiter(this, void 0, void 0, function* () { if (this.props.limitByTermsetNameOrID) { return this._searchTermsByTermSet(searchText); } else if (this.props.limitByGroupNameOrID) { return this._searchTermsByGroup(searchText); } else { return this._searchAllTerms(searchText); } }); } /** * Gets term sets from the stores */ getTermSets() { return __awaiter(this, void 0, void 0, function* () { yield this._ensureTermStores(); let termSets = []; for (const termStore of this._termStores) { const groups = this._groups[termStore.Id]; for (const group of groups) { if (this.props.limitByTermsetNameOrID) { // Filter to specific term set const filteredTermSets = group.TermSets._Child_Items_.filter(ts => ts.Name === this.props.limitByTermsetNameOrID || ts.Id.toLowerCase() === this.props.limitByTermsetNameOrID.toLowerCase()); termSets = [...termSets, ...filteredTermSets]; } else { termSets = [...termSets, ...group.TermSets._Child_Items_]; } } } return termSets; }); } /** * Gets all terms from the specified term set * @param termSet Term Set to get terms from */ getAllTerms(termSet) { return __awaiter(this, void 0, void 0, function* () { yield this._ensureTermStores(); try { // Use the new taxonomy REST API to get terms const response = yield this._taxonomyRequest(`termStore/sets/${termSet.Id}/terms?$expand=children`); const resultTerms = []; // Recursively process terms to build flat list with paths const processTerms = (terms, parentPath = '', depth = 1) => { for (const taxonomyTerm of terms) { const termName = this._getDefaultLabel(taxonomyTerm); const pathOfTerm = parentPath ? `${parentPath};${termName}` : termName; const term = { _ObjectType_: 'SP.Taxonomy.Term', _ObjectIdentity_: taxonomyTerm.id, Id: taxonomyTerm.id, Name: termName, Description: this._getDescription(taxonomyTerm), IsDeprecated: taxonomyTerm.isDeprecated || false, IsAvailableForTagging: taxonomyTerm.isAvailableForTagging !== false, IsRoot: depth === 1, PathOfTerm: pathOfTerm, PathDepth: depth, TermSet: { _ObjectType_: 'SP.Taxonomy.TermSet', _ObjectIdentity_: termSet.Id, Id: termSet.Id, Name: termSet.Name } }; if (this.props.includeLabels) { term.Labels = taxonomyTerm.labels.map(l => l.name); } resultTerms.push(term); // Process children recursively if (taxonomyTerm.children && taxonomyTerm.children.length > 0) { processTerms(taxonomyTerm.children, pathOfTerm, depth + 1); } } }; processTerms(response.value); return TermStorePickerServiceHelper.sortTerms(resultTerms); } catch (error) { console.error('Error loading terms', error); return []; } }); } /** * Get term sets from the specified group * @param group Term Group */ getGroupTermSets(group) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; yield this._ensureTermStores(); 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); if (!groupData) { return { _ObjectType_: this._termSetCollectionObjectType, _Child_Items_: [] }; } let termSets = groupData.TermSets._Child_Items_; if (this.props.limitByTermsetNameOrID) { termSets = termSets.filter(ts => ts.Name === this.props.limitByTermsetNameOrID || ts.Id.toLowerCase() === this.props.limitByTermsetNameOrID.toLowerCase()); } return { _ObjectType_: this._termSetCollectionObjectType, _Child_Items_: termSets }; }); } /** * Searches terms by provided text in the term sets specified by limitByTermsetNameOrID */ _searchTermsByTermSet(searchText) { return __awaiter(this, void 0, void 0, function* () { yield this._ensureTermStores(); const returnTerms = []; const termSets = yield this.getTermSets(); for (const termSet of termSets) { const terms = yield this.getAllTerms(termSet); const filtered = this._filterTermsBySearch(terms, searchText); for (const term of filtered) { returnTerms.push(this._termToPickerTerm(term, termSet)); } } return returnTerms; }); } /** * Searches terms by provided text in the group specified by limitByGroupNameOrID */ _searchTermsByGroup(searchText) { return __awaiter(this, void 0, void 0, function* () { yield this._ensureTermStores(); const returnTerms = []; for (const termStore of this._termStores) { const groups = this._groups[termStore.Id]; const targetGroup = groups.find(g => g.Name === this.props.limitByGroupNameOrID || g.Id.toLowerCase() === this.props.limitByGroupNameOrID.toLowerCase()); if (targetGroup) { for (const termSet of targetGroup.TermSets._Child_Items_) { const terms = yield this.getAllTerms(termSet); const filtered = this._filterTermsBySearch(terms, searchText); for (const term of filtered) { const pickerTerm = this._termToPickerTerm(term, termSet); pickerTerm.termGroup = targetGroup.Id; returnTerms.push(pickerTerm); } } } } return returnTerms; }); } /** * Searches for terms across all term stores */ _searchAllTerms(searchText) { return __awaiter(this, void 0, void 0, function* () { yield this._ensureTermStores(); const returnTerms = []; for (const termStore of this._termStores) { const groups = this._groups[termStore.Id]; for (const group of groups) { for (const termSet of group.TermSets._Child_Items_) { const terms = yield this.getAllTerms(termSet); const filtered = this._filterTermsBySearch(terms, searchText); for (const term of filtered) { const pickerTerm = this._termToPickerTerm(term, termSet); pickerTerm.termGroup = group.Id; returnTerms.push(pickerTerm); } } } } return returnTerms; }); } /** * Filters terms by search text (starts with, case-insensitive) */ _filterTermsBySearch(terms, searchText) { const lowerSearch = searchText.toLowerCase(); return terms.filter(t => t.Name.toLowerCase().startsWith(lowerSearch)).slice(0, 30); } /** * Converts an ITerm to an IPickerTerm */ _termToPickerTerm(term, termSet) { const pickerTerm = { key: term.Id, name: term.Name, path: term.PathOfTerm, termSet: termSet.Id, termSetName: termSet.Name, termGroup: '' }; if (term.Labels) { pickerTerm.labels = term.Labels; } return pickerTerm; } /** * Ensures term stores and groups are loaded */ _ensureTermStores() { return __awaiter(this, void 0, void 0, function* () { if (this._termStores) { return; } try { // Get the default term store const termStoreInfo = yield this._taxonomyRequest('termStore'); this._termStoreId = termStoreInfo.id; // Get all groups in the term store const groupsResponse = yield this._taxonomyRequest('termStore/groups'); let groups = groupsResponse.value; // Filter by group if specified if (this.props.limitByGroupNameOrID) { groups = groups.filter(g => g.name === this.props.limitByGroupNameOrID || g.id.toLowerCase() === this.props.limitByGroupNameOrID.toLowerCase()); } // Exclude system groups if specified if (this.props.excludeSystemGroup) { groups = groups.filter(g => g.type !== 'systemGroup'); } // Build the groups with their term sets const processedGroups = []; for (const taxonomyGroup of groups) { // Get term sets for this group const termSetsResponse = yield this._taxonomyRequest(`termStore/groups/${taxonomyGroup.id}/sets`); let termSets = termSetsResponse.value; // Filter by term set if specified if (this.props.limitByTermsetNameOrID) { termSets = termSets.filter(ts => { var _a, _b; 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); return name === this.props.limitByTermsetNameOrID || ts.id.toLowerCase() === this.props.limitByTermsetNameOrID.toLowerCase(); }); } const group = { _ObjectType_: 'SP.Taxonomy.TermGroup', _ObjectIdentity_: taxonomyGroup.id, Id: taxonomyGroup.id, Name: taxonomyGroup.name, IsSystemGroup: taxonomyGroup.type === 'systemGroup', TermStore: { Id: termStoreInfo.id, Name: termStoreInfo.name }, TermSets: { _ObjectType_: this._termSetCollectionObjectType, _Child_Items_: termSets.map(ts => this._convertTermSet(ts, termStoreInfo.defaultLanguageTag, taxonomyGroup.id)) } }; // Only add groups that have term sets (after filtering) if (group.TermSets._Child_Items_.length > 0 || !this.props.limitByTermsetNameOrID) { processedGroups.push(group); } } this._groups[termStoreInfo.id] = processedGroups; // Build the term store result this._termStores = [{ _ObjectType_: 'SP.Taxonomy.TermStore', _ObjectIdentity_: termStoreInfo.id, Id: termStoreInfo.id, Name: termStoreInfo.name, Groups: { _ObjectType_: this._termGroupCollectionObjectType, _Child_Items_: processedGroups } }]; } catch (error) { console.error('Error loading term stores', error); this._termStores = []; } }); } /** * Converts a taxonomy API term set to the internal ITermSet format */ _convertTermSet(taxonomyTermSet, defaultLanguage, groupId) { var _a, _b; const defaultName = ((_a = taxonomyTermSet.localizedNames.find(n => n.languageTag === defaultLanguage)) === null || _a === void 0 ? void 0 : _a.name) || ((_b = taxonomyTermSet.localizedNames[0]) === null || _b === void 0 ? void 0 : _b.name) || ''; const names = {}; taxonomyTermSet.localizedNames.forEach(n => { names[n.languageTag] = n.name; }); return { _ObjectType_: 'SP.Taxonomy.TermSet', _ObjectIdentity_: taxonomyTermSet.id, Id: taxonomyTermSet.id, Name: defaultName, Description: taxonomyTermSet.description || '', Names: names, Group: groupId }; } /** * Gets the default label from a taxonomy term */ _getDefaultLabel(taxonomyTerm) { var _a; const defaultLabel = taxonomyTerm.labels.find(l => l.isDefault); return (defaultLabel === null || defaultLabel === void 0 ? void 0 : defaultLabel.name) || ((_a = taxonomyTerm.labels[0]) === null || _a === void 0 ? void 0 : _a.name) || ''; } /** * Gets the description from a taxonomy term */ _getDescription(taxonomyTerm) { var _a, _b; return ((_b = (_a = taxonomyTerm.descriptions) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.description) || ''; } } //# sourceMappingURL=PnPTermStorePickerService.js.map