Aktualisiere Version auf 1.1.2, füge Unterstützung für die Auflösung interner WSS-IDs über die TaxonomyHiddenList hinzu und verbessere die Handhabung von Kategoriewerten im Accordion-WebPart
This commit is contained in:
@@ -32,7 +32,7 @@ function categoryEntryValues(entry: any, splitPlainSemicolon: boolean): string[]
|
||||
const semicolonParts: string[] = candidate.split(';');
|
||||
const allTaxonomyValues: boolean = semicolonParts.every((part: string): boolean =>
|
||||
/\|[0-9a-f]{8}-[0-9a-f-]{27}$/i.test(part.trim()));
|
||||
if (allTaxonomyValues || splitPlainSemicolon) { parts = semicolonParts; }
|
||||
if (allTaxonomyValues || splitPlainSemicolon) { parts = semicolonParts; }
|
||||
}
|
||||
|
||||
const values: string[] = [];
|
||||
@@ -44,3 +44,20 @@ function categoryEntryValues(entry: any, splitPlainSemicolon: boolean): string[]
|
||||
}
|
||||
return values.filter((text: string): boolean => !!text);
|
||||
}
|
||||
|
||||
export function replaceAccordionCategoryIds(
|
||||
values: string[],
|
||||
labelsByWssId: { [wssId: string]: string }
|
||||
): string[] {
|
||||
const result: string[] = [];
|
||||
const keys: { [key: string]: boolean } = {};
|
||||
for (let i: number = 0; i < values.length; i++) {
|
||||
const value: string = values[i];
|
||||
const label: string = /^\d+$/.test(value) && labelsByWssId[value]
|
||||
? labelsByWssId[value]
|
||||
: value;
|
||||
const key: string = '$' + label.toLocaleLowerCase();
|
||||
if (label && !keys[key]) { keys[key] = true; result.push(label); }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';
|
||||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { getAccordionCategoryValues } from './AccordionCategoryValues';
|
||||
import { getAccordionCategoryValues, replaceAccordionCategoryIds } from './AccordionCategoryValues';
|
||||
import { IAccordionFieldOption, IAccordionItem, IAccordionListOption } from './AccordionTypes';
|
||||
|
||||
export class AccordionDataService {
|
||||
private taxonomyLabelsByWssId: { [wssId: string]: string } = {};
|
||||
private missingTaxonomyWssIds: { [wssId: string]: boolean } = {};
|
||||
|
||||
public constructor(private context: WebPartContext) { }
|
||||
|
||||
public getLists(): Promise<IAccordionListOption[]> {
|
||||
@@ -55,20 +58,24 @@ export class AccordionDataService {
|
||||
'&$orderby=' + orderField + (sortAscending ? ' asc' : ' desc') + '&$top=5000';
|
||||
return this.context.spHttpClient.get(url, SPHttpClient.configurations.v1, { headers: this.headers })
|
||||
.then((response: SPHttpClientResponse): Promise<any> => this.ensureJson(response)) // tslint:disable-line:no-any
|
||||
.then((payload: any): IAccordionItem[] => this.results(payload) // tslint:disable-line:no-any
|
||||
.filter((item: any): boolean => !categoryValue || // tslint:disable-line:no-any
|
||||
this.itemCategoryValues(item, categoryField, taxonomyCategory).indexOf(categoryValue) >= 0)
|
||||
.map((item: any): IAccordionItem => { // tslint:disable-line:no-any
|
||||
const categories: string[] = categoryField
|
||||
? this.itemCategoryValues(item, categoryField, taxonomyCategory)
|
||||
: [];
|
||||
return {
|
||||
id: Number(item.Id),
|
||||
title: this.toText(item[titleField]),
|
||||
content: this.toText(item[contentField]),
|
||||
categories: categories
|
||||
};
|
||||
}));
|
||||
.then((payload: any): Promise<IAccordionItem[]> => { // tslint:disable-line:no-any
|
||||
const items: any[] = this.results(payload); // tslint:disable-line:no-any
|
||||
return this.resolveItemCategoryValues(items, categoryField, taxonomyCategory)
|
||||
.then((categoriesByItem: string[][]): IAccordionItem[] => {
|
||||
const result: IAccordionItem[] = [];
|
||||
for (let i: number = 0; i < items.length; i++) {
|
||||
const categories: string[] = categoriesByItem[i];
|
||||
if (categoryValue && categories.indexOf(categoryValue) < 0) { continue; }
|
||||
result.push({
|
||||
id: Number(items[i].Id),
|
||||
title: this.toText(items[i][titleField]),
|
||||
content: this.toText(items[i][contentField]),
|
||||
categories: categories
|
||||
});
|
||||
}
|
||||
return result;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public getCategoryValues(listId: string, categoryField: string, categoryFieldType: string): Promise<string[]> {
|
||||
@@ -80,18 +87,21 @@ export class AccordionDataService {
|
||||
'?$select=' + categoryField + formattedSelect + formattedExpand + '&$top=5000';
|
||||
return this.context.spHttpClient.get(url, SPHttpClient.configurations.v1, { headers: this.headers })
|
||||
.then((response: SPHttpClientResponse): Promise<any> => this.ensureJson(response)) // tslint:disable-line:no-any
|
||||
.then((payload: any): string[] => { // tslint:disable-line:no-any
|
||||
const values: string[] = [];
|
||||
const keys: { [key: string]: boolean } = {};
|
||||
.then((payload: any): Promise<string[]> => { // tslint:disable-line:no-any
|
||||
const items: any[] = this.results(payload); // tslint:disable-line:no-any
|
||||
for (let i: number = 0; i < items.length; i++) {
|
||||
const current: string[] = this.itemCategoryValues(items[i], categoryField, taxonomyCategory);
|
||||
for (let valueIndex: number = 0; valueIndex < current.length; valueIndex++) {
|
||||
const key: string = '$' + current[valueIndex].toLocaleLowerCase();
|
||||
if (!keys[key]) { keys[key] = true; values.push(current[valueIndex]); }
|
||||
}
|
||||
}
|
||||
return values.sort((left: string, right: string): number => left.localeCompare(right));
|
||||
return this.resolveItemCategoryValues(items, categoryField, taxonomyCategory)
|
||||
.then((categoriesByItem: string[][]): string[] => {
|
||||
const values: string[] = [];
|
||||
const keys: { [key: string]: boolean } = {};
|
||||
for (let i: number = 0; i < categoriesByItem.length; i++) {
|
||||
const current: string[] = categoriesByItem[i];
|
||||
for (let valueIndex: number = 0; valueIndex < current.length; valueIndex++) {
|
||||
const key: string = '$' + current[valueIndex].toLocaleLowerCase();
|
||||
if (!keys[key]) { keys[key] = true; values.push(current[valueIndex]); }
|
||||
}
|
||||
}
|
||||
return values.sort((left: string, right: string): number => left.localeCompare(right));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -129,6 +139,61 @@ export class AccordionDataService {
|
||||
return getAccordionCategoryValues(item ? item[categoryField] : undefined);
|
||||
}
|
||||
|
||||
private resolveItemCategoryValues(
|
||||
items: any[], // tslint:disable-line:no-any
|
||||
categoryField: string,
|
||||
taxonomyCategory: boolean
|
||||
): Promise<string[][]> {
|
||||
const categoriesByItem: string[][] = items.map((item: any): string[] => // tslint:disable-line:no-any
|
||||
categoryField ? this.itemCategoryValues(item, categoryField, taxonomyCategory) : []);
|
||||
if (!taxonomyCategory) { return Promise.resolve(categoriesByItem); }
|
||||
|
||||
const wssIds: string[] = [];
|
||||
const seen: { [wssId: string]: boolean } = {};
|
||||
for (let itemIndex: number = 0; itemIndex < categoriesByItem.length; itemIndex++) {
|
||||
for (let valueIndex: number = 0; valueIndex < categoriesByItem[itemIndex].length; valueIndex++) {
|
||||
const value: string = categoriesByItem[itemIndex][valueIndex];
|
||||
if (/^\d+$/.test(value) && !seen[value]) { seen[value] = true; wssIds.push(value); }
|
||||
}
|
||||
}
|
||||
if (!wssIds.length) { return Promise.resolve(categoriesByItem); }
|
||||
|
||||
return this.loadTaxonomyLabels(wssIds).then((labelsByWssId: { [wssId: string]: string }): string[][] =>
|
||||
categoriesByItem.map((values: string[]): string[] => replaceAccordionCategoryIds(values, labelsByWssId)));
|
||||
}
|
||||
|
||||
private loadTaxonomyLabels(wssIds: string[]): Promise<{ [wssId: string]: string }> {
|
||||
const missingIds: string[] = wssIds.filter((wssId: string): boolean =>
|
||||
!this.taxonomyLabelsByWssId[wssId] && !this.missingTaxonomyWssIds[wssId]);
|
||||
if (!missingIds.length) { return Promise.resolve(this.taxonomyLabelsByWssId); }
|
||||
|
||||
const requests: Array<Promise<any[]>> = []; // tslint:disable-line:no-any
|
||||
for (let offset: number = 0; offset < missingIds.length; offset += 40) {
|
||||
const chunk: string[] = missingIds.slice(offset, offset + 40);
|
||||
const filter: string = chunk.map((wssId: string): string => 'Id eq ' + wssId).join(' or ');
|
||||
const url: string = this.webUrl + "/_api/site/rootweb/lists/getbytitle('TaxonomyHiddenList')/items" +
|
||||
'?$select=Id,Term&$filter=' + filter + '&$top=40';
|
||||
requests.push(this.context.spHttpClient.get(url, SPHttpClient.configurations.v1, { headers: this.headers })
|
||||
.then((response: SPHttpClientResponse): Promise<any> => this.ensureJson(response)) // tslint:disable-line:no-any
|
||||
.then((payload: any): any[] => this.results(payload))); // tslint:disable-line:no-any
|
||||
}
|
||||
|
||||
return Promise.all(requests).then((resultSets: any[][]): { [wssId: string]: string } => { // tslint:disable-line:no-any
|
||||
for (let resultIndex: number = 0; resultIndex < resultSets.length; resultIndex++) {
|
||||
const items: any[] = resultSets[resultIndex]; // tslint:disable-line:no-any
|
||||
for (let itemIndex: number = 0; itemIndex < items.length; itemIndex++) {
|
||||
const id: string = String(items[itemIndex].Id || items[itemIndex].ID || '');
|
||||
const term: string = String(items[itemIndex].Term || '').trim();
|
||||
if (id && term) { this.taxonomyLabelsByWssId[id] = term; }
|
||||
}
|
||||
}
|
||||
for (let i: number = 0; i < missingIds.length; i++) {
|
||||
if (!this.taxonomyLabelsByWssId[missingIds[i]]) { this.missingTaxonomyWssIds[missingIds[i]] = true; }
|
||||
}
|
||||
return this.taxonomyLabelsByWssId;
|
||||
});
|
||||
}
|
||||
|
||||
private toText(value: any): string { // tslint:disable-line:no-any
|
||||
if (value === undefined || value === null) { return ''; }
|
||||
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { return String(value); }
|
||||
|
||||
Reference in New Issue
Block a user