76 lines
2.1 KiB
JavaScript
76 lines
2.1 KiB
JavaScript
export const TreeUtilsMixin = (superClass) => class TreeUtilsMixin extends superClass {
|
|
_normalizeKeyPath(path) {
|
|
if (Array.isArray(path)) return path.map((s) => String(s)).filter(Boolean);
|
|
if (typeof path !== 'string') return [];
|
|
return path.split('/').map((s) => s.trim()).filter(Boolean);
|
|
}
|
|
|
|
_resolveIcon(icon) {
|
|
if (!icon) return null;
|
|
if (typeof icon === 'string') {
|
|
return this.constructor?.defaultIcons?.[icon] ?? null;
|
|
}
|
|
return icon;
|
|
}
|
|
|
|
_normalizeActions(actions) {
|
|
if (!actions) return [];
|
|
if (Array.isArray(actions)) return actions;
|
|
if (typeof actions === 'object') return Object.values(actions);
|
|
return [];
|
|
}
|
|
|
|
_mergeActions(defaults = [], nodeActions = []) {
|
|
const map = new Map();
|
|
const add = (list) => {
|
|
list?.forEach((a) => {
|
|
if (a && a.action) {
|
|
map.set(a.action, a);
|
|
}
|
|
});
|
|
};
|
|
add(defaults);
|
|
add(nodeActions);
|
|
return Array.from(map.values());
|
|
}
|
|
|
|
_walkNodes(nodes, path, visitor) {
|
|
if (!Array.isArray(nodes)) return;
|
|
nodes.forEach((node, index) => {
|
|
const slug = node?.slug ?? `${index}`;
|
|
const nextPath = [...path, slug];
|
|
visitor(node, nextPath);
|
|
if (Array.isArray(node?.children) && node.children.length) {
|
|
this._walkNodes(node.children, nextPath, visitor);
|
|
}
|
|
});
|
|
}
|
|
|
|
_mapTree(nodes, mapper, path = []) {
|
|
if (!Array.isArray(nodes)) return { nodes: [], changed: false };
|
|
let changed = false;
|
|
const mapped = nodes.map((node, index) => {
|
|
const slug = node?.slug ?? `${index}`;
|
|
const nextPath = [...path, slug];
|
|
const mappedNode = mapper(node, nextPath) ?? node;
|
|
|
|
const { nodes: childNodes, changed: childChanged } = this._mapTree(
|
|
mappedNode?.children,
|
|
mapper,
|
|
nextPath
|
|
);
|
|
|
|
const children = childChanged ? childNodes : mappedNode?.children;
|
|
const nodeChanged = mappedNode !== node || childChanged;
|
|
|
|
if (nodeChanged) {
|
|
changed = true;
|
|
return { ...mappedNode, children };
|
|
}
|
|
|
|
return mappedNode;
|
|
});
|
|
return { nodes: mapped, changed };
|
|
}
|
|
};
|