Files
HMDesign/packages/org-chart/src/data/normalize.ts
T

28 lines
1.7 KiB
TypeScript

import type { Employee, NormalizedOrgChartDataset, OrganizationTreeNode, OrgChartDataset } from './types.js';
/** Pure derivation for validated datasets. Multiple roots remain a forest. */
export function normalizeOrgChartDataset(data: OrgChartDataset): NormalizedOrgChartDataset {
const organizationsById = new Map(data.organizations.map(org => [org.id, org]));
const employeesByOrganization = new Map<string, Employee[]>(data.organizations.map(org => [org.id, []]));
for (const employee of data.employees) employeesByOrganization.get(employee.organizationId)?.push(employee);
const nodes = new Map<string, OrganizationTreeNode>(data.organizations.map(org => [org.id, { organization: org, children: [] }]));
const roots: OrganizationTreeNode[] = [];
for (const node of nodes.values()) {
if (node.organization.parentId === null) roots.push(node);
else nodes.get(node.organization.parentId)?.children.push(node);
}
const order = new Map((data.presentation?.organizationOrder ?? []).map((id, index) => [id, index]));
const compare = (a: OrganizationTreeNode, b: OrganizationTreeNode) => {
const aOrder = order.get(a.organization.id) ?? Infinity;
const bOrder = order.get(b.organization.id) ?? Infinity;
if (aOrder !== bOrder) return aOrder < bOrder ? -1 : 1;
const difference = a.organization.displayOrder - b.organization.displayOrder;
if (difference) return difference;
// Code-unit order is deterministic across environments and independent of locale.
return a.organization.id < b.organization.id ? -1 : a.organization.id > b.organization.id ? 1 : 0;
};
roots.sort(compare);
for (const node of nodes.values()) node.children.sort(compare);
return { roots, organizationsById, employeesByOrganization };
}