fix: align org chart hierarchy and typography weights
This commit is contained in:
1 parent
72d427fcd2
commit
d42466f5eb
33 files changed
+358
-85
No files matched your search
@@ -1,6 +1,8 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fixture from '../../../../examples/org-chart/data-expanded-large.json';
|
||||
import small from '../../../../examples/org-chart/data-expanded-small.json';
|
||||
import medium from '../../../../examples/org-chart/data-expanded-medium.json';
|
||||
import { companyColorPresets, type CompanyId } from '../company-color-presets.js';
|
||||
import {
|
||||
calculateSummary, createOrgChartExampleDataset, JsonOrgChartDataSource,
|
||||
@@ -20,17 +22,34 @@ function assertContract(dataset: OrgChartDataset) {
|
||||
assert.equal(new Set(dataset.affiliations.map(affiliation => affiliation.id)).size, dataset.affiliations.length);
|
||||
const summary = calculateSummary(dataset).raw;
|
||||
assert.equal(summary.total, dataset.employees.length, 'leaders count once as employees');
|
||||
const pending = normalizeOrgChartDataset(dataset).roots.map(node => ({ node, depth: 1 }));
|
||||
const pending = normalizeOrgChartDataset(dataset).roots.map(node => ({ node, depth: 1, underCell: false }));
|
||||
let maximumDepth = 0;
|
||||
while (pending.length) {
|
||||
const { node, depth } = pending.pop()!;
|
||||
const { node, depth, underCell } = pending.pop()!;
|
||||
assert.ok(!(underCell && node.organization.type === 'team'), `team ${node.organization.id} must not descend from a cell`);
|
||||
maximumDepth = Math.max(maximumDepth, depth);
|
||||
pending.push(...node.children.map(child => ({ node: child, depth: depth + 1 })));
|
||||
pending.push(...node.children.map(child => ({ node: child, depth: depth + 1, underCell: underCell || node.organization.type === 'cell' })));
|
||||
}
|
||||
assert.ok(maximumDepth >= 3);
|
||||
assert.ok(new Set(Object.values(summary.byOrganization).map(value => value.direct)).size > 1, 'unequal organization membership');
|
||||
}
|
||||
|
||||
test('generated small/medium/large fixtures follow the hierarchy, retaining team -> cell examples', () => {
|
||||
for (const dataset of [small, medium, fixture] as OrgChartDataset[]) assertContract(dataset);
|
||||
const byId = new Map(base.organizations.map(org => [org.id, org]));
|
||||
const cells = base.organizations.filter(org => org.type === 'cell');
|
||||
assert.equal(cells.length, companies.length * 2);
|
||||
for (const cell of cells) assert.equal(byId.get(cell.parentId!)!.type, 'team');
|
||||
});
|
||||
|
||||
test('hierarchy regression check rejects a team below an indirect cell ancestor', () => {
|
||||
const invalid = structuredClone(base);
|
||||
const office = invalid.organizations.find(org => org.id === 'hanmac-office-sibling')!;
|
||||
office.parentId = 'hanmac-cell-0';
|
||||
invalid.organizations.find(org => org.id === 'hanmac-team-sibling')!.parentId = office.id;
|
||||
assert.throws(() => assertContract(invalid), /must not descend from a cell/);
|
||||
});
|
||||
|
||||
for (const employeeCount of sizes) {
|
||||
test(`total ${employeeCount} contains exactly that many unique employees across all seven preset companies`, () => {
|
||||
const dataset = createOrgChartExampleDataset(base, { scope: 'total', employeeCount });
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
.hm-orgchart-employee:is([data-card-asset], [data-card-layout="compact"]) .hm-orgchart-person-name {
|
||||
color: var(--hm-orgchart-card-color, #071D3A);
|
||||
font-size: var(--hm-orgchart-person-name-size);
|
||||
font-weight: 600;
|
||||
font-weight: 700;
|
||||
line-height: var(--hm-orgchart-person-name-line-height);
|
||||
letter-spacing: var(--hm-orgchart-person-name-letter-spacing);
|
||||
overflow: hidden;
|
||||
@@ -264,7 +264,7 @@
|
||||
.hm-orgchart-employee:is([data-card-asset], [data-card-layout="compact"])[data-card-asset-size="representative"] .hm-orgchart-person-attributes { left: 4px; width: 36px; }
|
||||
.hm-orgchart-employee:is([data-card-asset], [data-card-layout="compact"]) .hm-orgchart-job-title { max-width: 100%; padding: 0 2px; font-size: 8px; line-height: 12px; letter-spacing: -0.2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.hm-orgchart-employee:is([data-card-asset], [data-card-layout="compact"])[data-card-asset-size="leader"] .hm-orgchart-job-title { font-size: 9px; font-weight: 700; }
|
||||
.hm-orgchart-employee:is([data-card-asset], [data-card-layout="compact"]):is([data-card-asset-size="employee"], [data-card-layout="compact"]) .hm-orgchart-job-title { font-size: 8.5px; font-weight: 600; }
|
||||
.hm-orgchart-employee:is([data-card-asset], [data-card-layout="compact"]):is([data-card-asset-size="employee"], [data-card-layout="compact"]) .hm-orgchart-job-title { font-size: 8.5px; font-weight: 500; }
|
||||
/* Workdesk source: index.css .rank-position/.role-rank and .bg-*.
|
||||
Preserve the approved SVG geometry and position/name typography. The photo
|
||||
slot uses the existing reserved width because the approved cards are smaller
|
||||
@@ -326,7 +326,7 @@
|
||||
.hm-orgchart-employee:is([data-card-asset], [data-card-layout="compact"]):is([data-card-asset-size="employee"], [data-card-layout="compact"]) .hm-orgchart-job-title {
|
||||
padding: 0 2px;
|
||||
font-size: 8.5px;
|
||||
font-weight: 600;
|
||||
font-weight: 500;
|
||||
}
|
||||
/* Status is retained for assistive reading; the specified two-line card
|
||||
composition has no third status row. Supplementary status cards are intact. */
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
}
|
||||
/* Workdesk .hw/.hr labels share compact typography; .sw/.ux retain 20px/700. */
|
||||
.hm-orgchart-composition[data-display-mode="readOnly"] .hm-orgchart-engine.orgchart .node[data-header-role="group"][data-organization-id^="business-planning-"] .hm-orgchart-organization-name,
|
||||
.hm-orgchart-composition[data-display-mode="readOnly"] .hm-orgchart-engine.orgchart .node[data-header-role="group"][data-organization-id^="talent-growth-"] .hm-orgchart-organization-name { font-size: 18px; font-weight: 600; line-height: 16.9px; }
|
||||
.hm-orgchart-composition[data-display-mode="readOnly"] .hm-orgchart-engine.orgchart .node[data-header-role="group"][data-organization-id^="talent-growth-"] .hm-orgchart-organization-name { font-size: 18px; font-weight: 700; line-height: 16.9px; }
|
||||
/* Stacked cells: the vertical spine follows the 16px node gap. */
|
||||
.hm-orgchart-composition[data-display-mode="readOnly"] .hm-orgchart-engine.orgchart .hierarchy:has(> .node[data-depth]) > .nodes > .hierarchy::before { top: -16px; height: 16px; }
|
||||
.hm-orgchart-composition[data-display-mode="readOnly"] .hm-orgchart-engine.orgchart .node[data-depth] .hm-orgchart-leader { margin: 8px 0 0; }
|
||||
@@ -182,7 +182,7 @@
|
||||
gap: 8px;
|
||||
}
|
||||
.hm-orgchart-hub-icon { width: 20px; height: 20px; flex: 0 0 20px; stroke: #f8fcff; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 0 8px rgba(0, 0, 0, 0.38)); }
|
||||
.hm-orgchart-hub-label { position: relative; font-size: 21px; font-weight: 750; line-height: 24px; letter-spacing: normal; background: linear-gradient(180deg, #dbeeff, #f8fcff 15.38%, #fff 48.08%, #f4faff 79.33%, #dbeeff); background-clip: text; -webkit-text-fill-color: transparent; filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.5)); }
|
||||
.hm-orgchart-hub-label { position: relative; font-size: 21px; font-weight: 700; line-height: 24px; letter-spacing: normal; background: linear-gradient(180deg, #dbeeff, #f8fcff 15.38%, #fff 48.08%, #f4faff 79.33%, #dbeeff); background-clip: text; -webkit-text-fill-color: transparent; filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.5)); }
|
||||
.hm-orgchart-composition[data-display-mode="readOnly"] .hm-orgchart-stage[data-workdesk-artwork] .hm-orgchart-axis::before,
|
||||
.hm-orgchart-composition[data-display-mode="readOnly"] .hm-orgchart-stage[data-workdesk-artwork] .hm-orgchart-hub::after,
|
||||
.hm-orgchart-composition[data-display-mode="readOnly"] .hm-orgchart-stage[data-workdesk-artwork] .hm-orgchart-forest::before,
|
||||
|
||||
Reference in new issue
Block a user