sp-react-formfields
Version:
Collection of React controls used for rendering SharePoint fields in custom forms. Support new/edit/display rendering modes.
187 lines (171 loc) • 6.21 kB
text/typescript
import * as Taxonomy from '@pnp/sp-taxonomy';
import { IPickerTerms, IPickerTerm, IPickerTermSet } from './interfaces';
import { IFieldProps } from '../../interfaces';
import { registerDefaultFontFaces } from '@uifabric/styling/lib';
export default class SPTermStorePickerService {
constructor(private props: IFieldProps) {
// this.clientServiceUrl = this.context.pageContext.web.absoluteUrl + '/_vti_bin/client.svc/ProcessQuery';
}
public async getAllTerms(termsetId: string): Promise<IPickerTermSet> {
let termSet: Taxonomy.ITermSetData & Taxonomy.ITermSet =
await Taxonomy.taxonomy.getDefaultSiteCollectionTermStore().getTermSetById(termsetId)
.usingCaching()
.get();
let result: IPickerTermSet = null;
if (termSet) {
result = {
Id: termsetId,
Name: termSet.Name,
Description: termSet.Description,
CustomSortOrder: termSet.CustomSortOrder
};
let retrievedTerms: any[] =
await Taxonomy.taxonomy.getDefaultSiteCollectionTermStore().getTermSetById(termsetId)
.terms
.select('Id', 'Name', 'PathOfTerm', 'IsDeprecated', 'Parent', 'CustomSortOrder')
.usingCaching()
.get();
if (retrievedTerms) {
// console.log(retrievedTerms);
result.Terms = retrievedTerms.map(rt => {
return {
key: this.cleanGuid(rt.Id),
parentId: rt.Parent ? this.cleanGuid(rt.Parent.Id) : null,
customSortOrder: rt.CustomSortOrder ? rt.CustomSortOrder : null,
name: rt.Name,
path: rt.PathOfTerm,
pathDepth: rt.PathOfTerm ? rt.PathOfTerm.split(';').length : 1,
termSet: termsetId,
termSetName: result.Name,
isDeprecated: rt.IsDeprecated
} as IPickerTerm;
});
// result.Terms = result.Terms.sort(this.sortTerms);
// console.log(result.Terms);
}
}
return this.sortTermsInTermSetByHierarchy(result);
}
/**
* Retrieve all terms that starts with the searchText
* @param searchText
*/
public searchTermsByName(searchText: string): Promise<IPickerTerm[]> {
return this.searchTermsByTermSet(searchText, this.props.TaxonomyTermSetId);
}
/**
* Clean the Guid from the Web Service response
* @param guid
*/
public cleanGuid(guid: string): string {
if (guid !== undefined) {
return guid.replace('/Guid(', '').replace('/', '').replace(')', '');
} else {
return '';
}
}
/**
* Get the term set ID by its name
* @param termstore
* @param termset
*/
// private getTermSetId(termstore: TermService.ITermStore[], termsetName: string): TermService.ITermSet {
// if (termstore && termstore.length > 0 && termsetName) {
// // Get the first term store
// const ts = termstore[0];
// // 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_) {
// for (const termSet of group.TermSets._Child_Items_) {
// // Check if the term set is found
// if (termSet.Name === termsetName) {
// return termSet;
// }
// }
// }
// }
// }
// }
// return null;
// }
/**
* Searches terms for the given term set
* @param searchText
* @param termsetId
*/
private searchTermsByTermSet(searchText: string, termSetId: string, termLimit: number = 10): Promise<IPickerTerm[]> {
return new Promise<IPickerTerm[]>(async resolve => {
let allTerms = await this.getAllTerms(termSetId);
let filteredTerms = allTerms.Terms.filter(t => t.name.match(new RegExp(searchText, 'gi')));
if (filteredTerms.length > termLimit) {
filteredTerms = filteredTerms.slice(0, termLimit - 1);
}
resolve(filteredTerms);
});
}
private isGuid(strGuid: string): boolean {
return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(strGuid);
}
/**
* Sort the terms by their path
* @param a term 2
* @param b term 2
*/
// private sortTerms(a: IPickerTerm, b: IPickerTerm) {
// if (a.pathDepth < b.pathDepth) {
// return -1;
// }
// if (a.pathDepth > b.pathDepth) {
// return 1;
// }
// return 0;
// }
private sortTermsInTermSetByHierarchy(termSet: IPickerTermSet): IPickerTermSet {
if (!termSet) {
return termSet;
}
let mockRootLevelTerm: IPickerTerm = {
key: null,
name: '',
customSortOrder: termSet.CustomSortOrder,
isDeprecated: false,
parentId: null,
path: '',
pathDepth: 0,
termSet: ''
};
// debugger;
let sortedTerms: IPickerTerm[] = [];
let toProcess = this.getSortedTermsForAParent(termSet.Terms, mockRootLevelTerm);
while (toProcess.length > 0) {
let item = toProcess[0];
sortedTerms.push(item);
let currentItemChildren = this.getSortedTermsForAParent(termSet.Terms, item);
if (currentItemChildren.length > 0) {
toProcess.splice(0, 1, ...currentItemChildren);
} else {
toProcess.splice(0, 1);
}
}
termSet.Terms = sortedTerms;
return termSet;
}
private getSortedTermsForAParent(allUnsortedTerms: IPickerTerm[], parentPickerTerm: IPickerTerm): IPickerTerm[] {
let results = allUnsortedTerms.filter(f => f.parentId === parentPickerTerm.key);
if (parentPickerTerm.customSortOrder) {
const orderedTermIds = parentPickerTerm.customSortOrder.split(':');
let sortedResults = [];
for (let id of orderedTermIds) {
const res = results.filter(r => r.key === id);
if (res.length > 0) {
sortedResults.push(res[0]);
}
}
return sortedResults;
} else {
return results;
}
}
}