box-ui-elements
Version:
Box UI Elements
98 lines (87 loc) • 3.83 kB
text/typescript
import { TreeQueryInput, TreeOptionType, FetcherResponse } from '@box/combobox-with-api';
import type API from '../../../api';
import type { MetadataOptionEntry } from '../../../common/types/metadata';
export const metadataTaxonomyFetcher = async (
api: API,
fileId: string,
scope: string,
templateKey: string,
fieldKey: string,
level: number,
options: TreeQueryInput,
): Promise<FetcherResponse<TreeOptionType>> => {
const metadataOptions = await api
.getMetadataAPI(false)
.getMetadataOptions(fileId, scope, templateKey, fieldKey, level, options);
const { marker = null } = options;
return {
options: metadataOptions.entries.map((metadataOption: MetadataOptionEntry) => ({
value: metadataOption.id,
displayValue: metadataOption.display_name || metadataOption.displayName,
level: metadataOption.level,
parentId: metadataOption.parentId,
nodePath: metadataOption.nodePath,
deprecated: metadataOption.deprecated,
ancestors: metadataOption.ancestors?.map(({display_name, displayName, ...rest}) => ({...rest, displayName: display_name || displayName })),
selectable: metadataOption.selectable,
})),
marker,
...(metadataOptions.total_result_count !== undefined && { totalResultCount: metadataOptions.total_result_count }),
...(metadataOptions.limit !== undefined && { limit: metadataOptions.limit }),
} as FetcherResponse<TreeOptionType>;
};
type HydratedMetadataTaxonomyLevel = {
level: number;
levelName: string;
description: string;
levelValue: string;
id: string;
};
export const metadataTaxonomyNodeAncestorsFetcher = async (
api: API,
fileID: string,
scope: string,
taxonomyKey: string,
nodeID: string,
): Promise<HydratedMetadataTaxonomyLevel[]> => {
const [metadataTaxonomy, metadataTaxonomyNode] = await Promise.all([
api.getMetadataAPI(false).getMetadataTaxonomy(fileID, scope, taxonomyKey),
api.getMetadataAPI(false).getMetadataTaxonomyNode(fileID, scope, taxonomyKey, nodeID, true),
]);
if (!metadataTaxonomy?.levels) {
return [];
}
// Create a hashmap of levels to easily hydrate with data from metadataTaxonomyNode
const levelsMap = new Map();
for (const item of metadataTaxonomy.levels) {
const levelData = {
level: item.level,
levelName: item.displayName || item.display_name,
description: item.description,
};
// If the level matches the metadataTaxonomyNode level, hydrate the level with the node data
if (metadataTaxonomyNode.level === item.level) {
levelsMap.set(item.level, {
...levelData,
id: metadataTaxonomyNode.id,
levelValue: metadataTaxonomyNode.displayName || metadataTaxonomyNode.display_name,
});
// If the level is not the metadataTaxonomyNode level, just add the level data
} else {
levelsMap.set(item.level, levelData);
}
}
// Hydrate the levels with the ancestors data from the metadataTaxonomyNode
if (metadataTaxonomyNode.ancestors?.length) {
for (const ancestor of metadataTaxonomyNode.ancestors) {
const levelData = levelsMap.get(ancestor.level);
if (levelData) {
levelsMap.set(ancestor.level, { ...levelData, levelValue: ancestor.displayName || ancestor.display_name, id: ancestor.id });
}
}
}
// Filter out levels that were not hydrated by metadataTaxonomyNode
const hydratedLevels = Array.from(levelsMap.values()).filter(level => !!level.id);
// Return the hydrated levels as an array
return hydratedLevels;
};