@pnp/spfx-property-controls
Version:
Reusable property pane controls for SharePoint Framework solutions
335 lines • 22.8 kB
JavaScript
/**
* DISCLAIMER
*
* As there is not yet an OData end-point for managed metadata, this service makes use of the ProcessQuery end-points.
* The service will get updated once the APIs are in place for managing managed metadata.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { SPHttpClient } from '@microsoft/sp-http';
import { TermStorePickerServiceHelper } from './ISPTermStorePickerService';
/**
* Service implementation to manage term stores in SharePoint
*/
export default class SPTermStorePickerService {
/**
* Service constructor
*/
constructor(props, context) {
this.props = props;
this.context = context;
this.clientServiceUrl = this.context.pageContext.web.absoluteUrl + '/_vti_bin/client.svc/ProcessQuery';
}
/**
* Gets the collection of term stores in the current SharePoint env
*/
getTermStores() {
// Retrieve the term store name, groups, and term sets
const data = '<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName=".NET Library" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="2" ObjectPathId="1" /><ObjectIdentityQuery Id="3" ObjectPathId="1" /><ObjectPath Id="5" ObjectPathId="4" /><ObjectIdentityQuery Id="6" ObjectPathId="4" /><Query Id="7" ObjectPathId="4"><Query SelectAllProperties="false"><Properties><Property Name="Id" ScalarProperty="true" /><Property Name="Name" ScalarProperty="true" /><Property Name="Groups"><Query SelectAllProperties="false"><Properties /></Query><ChildItemQuery SelectAllProperties="false"><Properties><Property Name="Name" ScalarProperty="true" /><Property Name="Id" ScalarProperty="true" /><Property Name="IsSystemGroup" ScalarProperty="true" /><Property Name="TermSets"><Query SelectAllProperties="false"><Properties /></Query><ChildItemQuery SelectAllProperties="false"><Properties><Property Name="Name" ScalarProperty="true" /><Property Name="Id" ScalarProperty="true" /><Property Name="Description" ScalarProperty="true" /><Property Name="Names" ScalarProperty="true" /></Properties></ChildItemQuery></Property></Properties></ChildItemQuery></Property></Properties></Query></Query></Actions><ObjectPaths><StaticMethod Id="1" Name="GetTaxonomySession" TypeId="{981cbc68-9edc-4f8d-872f-71146fcbb84f}" /><Method Id="4" ParentId="1" Name="GetDefaultSiteCollectionTermStore" /></ObjectPaths></Request>';
const reqHeaders = new Headers();
reqHeaders.append("accept", "application/json");
reqHeaders.append("content-type", "application/xml");
const httpPostOptions = {
headers: reqHeaders,
body: data
};
return this.context.spHttpClient.post(this.clientServiceUrl, SPHttpClient.configurations.v1, httpPostOptions).then((serviceResponse) => {
return serviceResponse.json().then((serviceJSONResponse) => {
// Construct results
const termStoreResult = serviceJSONResponse.filter(r => r['_ObjectType_'] === 'SP.Taxonomy.TermStore');
// Check if term store was retrieved
if (termStoreResult.length > 0) {
// Check if the termstore needs to be filtered or limited
if (this.props.limitByGroupNameOrID || this.props.limitByTermsetNameOrID || this.props.excludeSystemGroup) {
return termStoreResult.map(termstore => {
let termGroups = termstore.Groups._Child_Items_;
// Check if the groups have to be limited to a specific group name or ID
if (this.props.limitByGroupNameOrID) {
const groupNameOrId = this.props.limitByGroupNameOrID;
termGroups = termGroups.filter((group) => group.Name === groupNameOrId || group.Id.toLowerCase() === groupNameOrId.toLowerCase());
}
// Check if the groups have to be limited to a specific term set
if (this.props.limitByTermsetNameOrID) {
const termsetNameOrId = this.props.limitByTermsetNameOrID;
termGroups = termGroups.map((group) => {
group.TermSets._Child_Items_ = group.TermSets._Child_Items_.filter((termSet) => termSet.Name === termsetNameOrId || TermStorePickerServiceHelper.cleanGuid(termSet.Id).toLowerCase() === TermStorePickerServiceHelper.cleanGuid(termsetNameOrId).toLowerCase());
return group;
});
}
// Filter out all systen groups
if (this.props.excludeSystemGroup) {
termGroups = termGroups.filter(group => !group.IsSystemGroup);
}
// Filter out empty groups
termGroups = termGroups.filter((group) => group.TermSets._Child_Items_.length > 0);
// Map the new groups
termstore.Groups._Child_Items_ = termGroups;
return termstore;
});
}
// Return the term store results
return termStoreResult;
}
return [];
});
});
}
/**
* Gets the current term set
*/
getTermSets() {
return __awaiter(this, void 0, void 0, function* () {
const termStore = yield this.getTermStores();
return this.getAllTermSets(termStore, this.props.limitByTermsetNameOrID);
});
}
/**
* Get the term set ID by its name
* @param termstore
* @param termset
*/
getAllTermSets(termstore, termsetNameOrId) {
if (termstore && termstore.length > 0) {
// Get the first term store
const ts = termstore[0];
let termSets = [];
// Check if the term store contains groups
if (ts.Groups && ts.Groups._Child_Items_) {
for (const group of ts.Groups._Child_Items_) {
// Check if the group contains term sets
if (group.TermSets && group.TermSets._Child_Items_) {
if (termsetNameOrId) {
for (const termSet of group.TermSets._Child_Items_) {
// Check if the term set is found
if (termSet.Name === termsetNameOrId || termSet.Id.indexOf(termsetNameOrId) !== -1) {
termSets = [...termSets, termSet];
}
}
}
else {
termSets = [...termSets, ...group.TermSets._Child_Items_];
}
}
}
}
return termSets;
}
return null;
}
/**
* Retrieve all terms for the given term set
* @param termsetId
*/
getAllTerms(termSet) {
return __awaiter(this, void 0, void 0, function* () {
// Request body to retrieve all terms for the given term set
const data = `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName=".NET Library" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="30" ObjectPathId="29" /><Query Id="31" ObjectPathId="29"><Query SelectAllProperties="false"><Properties /></Query><ChildItemQuery SelectAllProperties="false"><Properties><Property Name="Name" ScalarProperty="true" /><Property Name="Id" ScalarProperty="true" /><Property Name="Description" ScalarProperty="true" /><Property Name="IsDeprecated" ScalarProperty="true" /><Property Name="IsAvailableForTagging" ScalarProperty="true" /><Property Name="IsRoot" ScalarProperty="true" /><Property Name="PathOfTerm" ScalarProperty="true" /><Property Name="TermSet" SelectAll="true" /><Property Name="Parent" SelectAll="true"><Query SelectAllProperties="false"><Properties /></Query></Property><Property Name="TermSet"><Query SelectAllProperties="false"><Properties><Property Name="Id" ScalarProperty="true" /></Properties></Query></Property></Properties></ChildItemQuery></Query></Actions><ObjectPaths><Method Id="29" ParentId="18" Name="GetAllTerms" /><Identity Id="18" Name="${termSet._ObjectIdentity_}"
/></ObjectPaths></Request>`;
const reqHeaders = new Headers();
reqHeaders.append("accept", "application/json");
reqHeaders.append("content-type", "application/xml");
const httpPostOptions = {
headers: reqHeaders,
body: data
};
return this.context.spHttpClient.post(this.clientServiceUrl, SPHttpClient.configurations.v1, httpPostOptions).then((serviceResponse) => {
return serviceResponse.json().then((serviceJSONResponse) => {
// Retrieve the term collection results
const termStoreResult = serviceJSONResponse.filter(r => r['_ObjectType_'] === 'SP.Taxonomy.TermCollection');
if (termStoreResult.length > 0) {
// Retrieve all terms
let terms = termStoreResult[0]._Child_Items_;
// Clean the term ID and specify the path depth
terms = terms.map(term => {
term.Id = TermStorePickerServiceHelper.cleanGuid(term.Id);
term.PathDepth = term.PathOfTerm.split(';').length;
return term;
});
// Check if the term set was not empty
if (terms.length > 0) {
// Sort the terms by PathOfTerm and their depth
return TermStorePickerServiceHelper.sortTerms(terms);
}
}
return null;
});
});
});
}
/**
* Retrieve all terms that starts with the searchText
* @param searchText
*/
searchTermsByName(searchText) {
if (this.props.limitByTermsetNameOrID) {
return this.searchTermsByTermSet(searchText, this.props.limitByTermsetNameOrID);
}
else if (this.props.limitByGroupNameOrID) {
return this.searchTermsByGroup(searchText);
}
else {
return this.searchAllTerms(searchText);
}
}
getGroupTermSets(group) {
return __awaiter(this, void 0, void 0, function* () {
return group.TermSets;
});
}
/**
* Searches terms for the given term set
* @param searchText
* @param termsetId
*/
searchTermsByTermSet(searchText, termSet) {
return new Promise(resolve => {
this.getTermStores().then(termStore => {
let TermSetId = termSet;
if (!TermStorePickerServiceHelper.isGuid(termSet)) {
TermSetId = TermStorePickerServiceHelper.cleanGuid(termStore[0].Groups._Child_Items_[0].TermSets._Child_Items_[0].Id);
}
const group = this.getTermGroupByTermSetId(TermSetId, termStore);
const data = `<Request xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="Javascript Library"><Actions><ObjectPath Id="456" ObjectPathId="455" /><ObjectIdentityQuery Id="457" ObjectPathId="455" /><ObjectPath Id="459" ObjectPathId="458" /><ObjectIdentityQuery Id="460" ObjectPathId="458" /><ObjectPath Id="462" ObjectPathId="461" /><ObjectIdentityQuery Id="463" ObjectPathId="461" /><ObjectPath Id="465" ObjectPathId="464" /><SetProperty Id="466" ObjectPathId="464" Name="TermLabel"><Parameter Type="String">${searchText}</Parameter></SetProperty><SetProperty Id="467" ObjectPathId="464" Name="DefaultLabelOnly"><Parameter Type="Boolean">true</Parameter></SetProperty><SetProperty Id="468" ObjectPathId="464" Name="StringMatchOption"><Parameter Type="Number">0</Parameter></SetProperty><SetProperty Id="469" ObjectPathId="464" Name="ResultCollectionSize"><Parameter Type="Number">10</Parameter></SetProperty><SetProperty Id="470" ObjectPathId="464" Name="TrimUnavailable"><Parameter Type="Boolean">true</Parameter></SetProperty><ObjectPath Id="472" ObjectPathId="471" /><Query Id="473" ObjectPathId="471"><Query SelectAllProperties="false"><Properties /></Query><ChildItemQuery SelectAllProperties="false"><Properties><Property Name="IsRoot" SelectAll="true" /><Property Name="Id" SelectAll="true" /><Property Name="Name" SelectAll="true" /><Property Name="PathOfTerm" SelectAll="true" /><Property Name="TermSet" SelectAll="true" /></Properties></ChildItemQuery></Query></Actions><ObjectPaths><StaticMethod Id="455" Name="GetTaxonomySession" TypeId="{981cbc68-9edc-4f8d-872f-71146fcbb84f}" /><Method Id="458" ParentId="455" Name="GetDefaultKeywordsTermStore" /><Method Id="461" ParentId="458" Name="GetTermSet"><Parameters><Parameter Type="Guid">${TermSetId}</Parameter></Parameters></Method><Constructor Id="464" TypeId="{61a1d689-2744-4ea3-a88b-c95bee9803aa}" /><Method Id="471" ParentId="461" Name="GetTerms"><Parameters><Parameter ObjectPathId="464" /></Parameters></Method></ObjectPaths></Request>`;
const reqHeaders = new Headers();
reqHeaders.append("accept", "application/json");
reqHeaders.append("content-type", "application/xml");
const httpPostOptions = {
headers: reqHeaders,
body: data
};
return this.context.spHttpClient.post(this.clientServiceUrl, SPHttpClient.configurations.v1, httpPostOptions).then((serviceResponse) => {
return serviceResponse.json().then((serviceJSONResponse) => {
// Retrieve the term collection results
const termStoreResult = serviceJSONResponse.filter(r => r['_ObjectType_'] === 'SP.Taxonomy.TermCollection');
if (termStoreResult.length > 0) {
// Retrieve all terms
const terms = termStoreResult[0]._Child_Items_;
const returnTerms = [];
terms.forEach(term => {
if (term.Name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1) {
returnTerms.push({
key: TermStorePickerServiceHelper.cleanGuid(term.Id),
name: term.Name,
path: term.PathOfTerm,
termSet: term.TermSet.Id,
termSetName: term.TermSet.Name,
termGroup: group ? TermStorePickerServiceHelper.cleanGuid(group.Id) : ''
});
}
});
resolve(returnTerms);
}
return null;
});
});
})
.catch(() => {
// no-op;
});
});
}
/**
* Searches terms for a group
* @param searchText
*/
searchTermsByGroup(searchText) {
return new Promise(resolve => {
this.getTermStores().then(termStore => {
const termSetTerms = [];
termStore[0].Groups._Child_Items_[0].TermSets._Child_Items_.forEach(ts => {
termSetTerms.push(this.getAllTerms(ts));
});
Promise.all(termSetTerms).then(results => {
const returnTerms = [];
results.forEach(terms => {
if (terms) {
terms.forEach(term => {
if (term.Name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1) {
returnTerms.push({
key: TermStorePickerServiceHelper.cleanGuid(term.Id),
name: term.Name,
path: term.PathOfTerm,
termSet: term.TermSet.Id,
termSetName: term.TermSet.Name,
termGroup: TermStorePickerServiceHelper.cleanGuid(termStore[0].Groups._Child_Items_[0].Id) // ??? I don't know why we always work with the 1st group
});
}
});
}
});
resolve(returnTerms);
})
.catch(() => {
// no-op;
});
})
.catch(() => {
// no-op;
});
});
}
/**
* Searches terms in termstore
* @param searchText
*/
searchAllTerms(searchText) {
return new Promise(resolve => {
const data = `<Request xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="Javascript Library"><Actions><ObjectPath Id="775" ObjectPathId="774" /><ObjectIdentityQuery Id="776" ObjectPathId="774" /><ObjectPath Id="778" ObjectPathId="777" /><ObjectIdentityQuery Id="779" ObjectPathId="777" /><ObjectPath Id="781" ObjectPathId="780" /><SetProperty Id="782" ObjectPathId="780" Name="TermLabel"><Parameter Type="String">${searchText}</Parameter></SetProperty><SetProperty Id="783" ObjectPathId="780" Name="DefaultLabelOnly"><Parameter Type="Boolean">true</Parameter></SetProperty><SetProperty Id="784" ObjectPathId="780" Name="StringMatchOption"><Parameter Type="Number">0</Parameter></SetProperty><SetProperty Id="785" ObjectPathId="780" Name="ResultCollectionSize"><Parameter Type="Number">10</Parameter></SetProperty><SetProperty Id="786" ObjectPathId="780" Name="TrimUnavailable"><Parameter Type="Boolean">true</Parameter></SetProperty><ObjectPath Id="788" ObjectPathId="787" /><Query Id="789" ObjectPathId="787"><Query SelectAllProperties="false"><Properties /></Query><ChildItemQuery SelectAllProperties="false"><Properties><Property Name="IsRoot" SelectAll="true" /><Property Name="Id" SelectAll="true" /><Property Name="Name" SelectAll="true" /><Property Name="PathOfTerm" SelectAll="true" /><Property Name="TermSet" SelectAll="true" /></Properties></ChildItemQuery></Query></Actions><ObjectPaths><StaticMethod Id="774" Name="GetTaxonomySession" TypeId="{981cbc68-9edc-4f8d-872f-71146fcbb84f}" /><Method Id="777" ParentId="774" Name="GetDefaultKeywordsTermStore" /><Constructor Id="780" TypeId="{61a1d689-2744-4ea3-a88b-c95bee9803aa}" /><Method Id="787" ParentId="777" Name="GetTerms"><Parameters><Parameter ObjectPathId="780" /></Parameters></Method></ObjectPaths></Request>`;
const reqHeaders = new Headers();
reqHeaders.append("accept", "application/json");
reqHeaders.append("content-type", "application/xml");
const httpPostOptions = {
headers: reqHeaders,
body: data
};
return this.context.spHttpClient.post(this.clientServiceUrl, SPHttpClient.configurations.v1, httpPostOptions).then((serviceResponse) => {
return serviceResponse.json().then((serviceJSONResponse) => {
// Retrieve the term collection results
const termStoreResult = serviceJSONResponse.filter(r => r['_ObjectType_'] === 'SP.Taxonomy.TermCollection');
if (termStoreResult.length > 0) {
// Retrieve all terms
const terms = termStoreResult[0]._Child_Items_;
const returnTerms = [];
terms.forEach(term => {
if (term.Name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1) {
returnTerms.push({
key: TermStorePickerServiceHelper.cleanGuid(term.Id),
name: term.Name,
path: term.PathOfTerm,
termSet: term.TermSet.Id,
termSetName: term.TermSet.Name,
termGroup: '' // didn't find a way to simply get Group in that situation. It won't affect functionality. Only switch between TermStorePicker and EnterpriseTermStorePicker
});
}
});
resolve(returnTerms);
}
return null;
})
.catch(() => {
// no-op;
});
});
});
}
getTermGroupByTermSetId(termSetId, termStores) {
for (let i = 0, len = termStores.length; i < len; i++) {
const termStore = termStores[i];
for (let groupIdx = 0, groupsLen = termStore.Groups._Child_Items_.length; groupIdx < groupsLen; groupIdx++) {
const group = termStore.Groups._Child_Items_[groupIdx];
if (group.TermSets._Child_Items_.filter(ts => TermStorePickerServiceHelper.cleanGuid(ts.Id) === termSetId).length) {
return group;
}
}
}
return null;
}
}
//# sourceMappingURL=SPTermStorePickerService.js.map