feat(org-chart): separate fixed and auto layout previews
This commit is contained in:
1 parent
80583eb4ca
commit
a92913d6bc
18 files changed
+1211
-7
No files matched your search
@@ -5,6 +5,9 @@ import type { EngineAdapter, EngineConstructor } from './engine.js';
|
||||
import { decorateNode, engineTree } from './render.js';
|
||||
import { createOrgChartTree } from './org-chart-tree.js';
|
||||
import { createOrgChartContent } from './org-chart-content.js';
|
||||
import { createExpandedOrgChartContent } from './expanded-content.js';
|
||||
import { expandedPreviewRoots } from './expanded-layout.js';
|
||||
import { getCompanyColorPreset } from '../company-color-presets.js';
|
||||
import { createPositionSummary } from './position-summary.js';
|
||||
import { createAffiliationSummary } from './affiliation-summary.js';
|
||||
import { createStatusSummary } from './status-summary.js';
|
||||
@@ -13,7 +16,7 @@ import type { EmployeeInfoDialog } from './employee-info-dialog.js';
|
||||
import type { RenderContext } from './render.js';
|
||||
import type { OrgChartEmployeeClickContext, OrgChartHandle, OrgChartOptions, OrgChartState } from './types.js';
|
||||
|
||||
export type { OrgChartEmployeeClickContext, OrgChartHandle, OrgChartOptions, OrgChartOrganizationLinks, OrgChartState } from './types.js';
|
||||
export type { OrgChartLayoutMode, OrgChartEmployeeClickContext, OrgChartHandle, OrgChartOptions, OrgChartOrganizationLinks, OrgChartState } from './types.js';
|
||||
|
||||
const owners = new WeakMap<HTMLElement, symbol>();
|
||||
let instanceSequence = 0;
|
||||
@@ -47,6 +50,11 @@ export function createOrgChartView(options: OrgChartOptions, view: CoreView): Or
|
||||
if (!options.stylesheetUrls?.core || (needsEngine && !options.stylesheetUrls.engine)) throw new TypeError('Provide the required OrgChart stylesheet URLs');
|
||||
const stylesheetUrls = { ...options.stylesheetUrls };
|
||||
if (options.displayMode !== undefined && options.displayMode !== 'interactive' && options.displayMode !== 'readOnly') throw new TypeError('displayMode must be "interactive" or "readOnly"');
|
||||
if (options.layoutMode !== undefined && options.layoutMode !== 'fixed' && options.layoutMode !== 'auto') throw new TypeError('layoutMode must be "fixed" or "auto"');
|
||||
const layoutMode = options.layoutMode ?? 'fixed';
|
||||
const expanded = view === 'composition' && layoutMode === 'auto';
|
||||
const expandedCompanyPreset = expanded ? getCompanyColorPreset(options.companyId ?? 'hanmac') : undefined;
|
||||
if (expanded && !expandedCompanyPreset) throw new TypeError('companyId must be a registered company preset in Auto mode');
|
||||
const readOnly = view === 'composition' && options.displayMode === 'readOnly';
|
||||
const organizationLinks: Record<string, string> = Object.create(null);
|
||||
if (options.onEmployeeClick !== undefined && typeof options.onEmployeeClick !== 'function') throw new TypeError('onEmployeeClick must be a function');
|
||||
@@ -200,14 +208,16 @@ export function createOrgChartView(options: OrgChartOptions, view: CoreView): Or
|
||||
const normalized = normalizeOrgChartDataset(data);
|
||||
const summary = freeze(calculateSummary(data, policy));
|
||||
const topLeaderIds = new Set(view === 'composition' ? normalized.roots.filter(node => node.organization.type === 'root' && node.organization.leaderId).map(node => node.organization.leaderId!) : []);
|
||||
const nextContext: RenderContext = { data, summary, orderedOrganizations: [], employeesByOrganization: normalized.employeesByOrganization, topLeaderIds, readOnly, organizationLinks };
|
||||
const nextContext: RenderContext = { data, summary, orderedOrganizations: [], employeesByOrganization: normalized.employeesByOrganization, topLeaderIds, readOnly: readOnly || expanded, organizationLinks, expandedCompanyPreset };
|
||||
// Composition shows the root leader as the standalone top card, so the root's direct
|
||||
// organizations become the horizontal engine roots (data and parentId stay untouched).
|
||||
// A root with other direct employees keeps its node so those employees stay visible.
|
||||
const flattenRoot = (node: typeof normalized.roots[number]) => view === 'composition' && node.organization.type === 'root' && !!node.organization.leaderId
|
||||
&& (normalized.employeesByOrganization.get(node.organization.id) ?? []).every(employee => employee.id === node.organization.leaderId);
|
||||
const flattened = normalized.roots.some(flattenRoot);
|
||||
const tree = engineTree(flattened ? normalized.roots.flatMap(node => flattenRoot(node) ? node.children : [node]) : normalized.roots, prefix, nextContext, flattened ? 1 : 0);
|
||||
const roots = expanded ? expandedPreviewRoots(normalized.roots)
|
||||
: flattened ? normalized.roots.flatMap(node => flattenRoot(node) ? node.children : [node]) : normalized.roots;
|
||||
const tree = engineTree(roots, prefix, nextContext, expanded || flattened ? 1 : 0);
|
||||
const styleIssues = await styleReady;
|
||||
if (!active(version)) return;
|
||||
if (styleIssues) { fail(version, styleIssues); return; }
|
||||
@@ -233,7 +243,9 @@ export function createOrgChartView(options: OrgChartOptions, view: CoreView): Or
|
||||
});
|
||||
}
|
||||
// If regeneration removed keyboard focus, offer the stable viewport next.
|
||||
const nextContent = view === 'composition' ? createOrgChartContent(document, nextContext, viewport!, contentGeneration.signal)
|
||||
const nextContent = view === 'composition' ? expanded
|
||||
? createExpandedOrgChartContent(document, nextContext, viewport!, contentGeneration.signal)
|
||||
: createOrgChartContent(document, nextContext, viewport!, contentGeneration.signal)
|
||||
: view === 'tree' ? viewport!
|
||||
: view === 'positionSummary' ? createPositionSummary(document, nextContext)
|
||||
: view === 'affiliationSummary' ? createAffiliationSummary(document, nextContext)
|
||||
@@ -306,6 +318,7 @@ export function createOrgChartView(options: OrgChartOptions, view: CoreView): Or
|
||||
cancelStyles = () => { for (const dispose of styleDisposers) dispose(); };
|
||||
shell = document.createElement('section');
|
||||
shell.className = 'hm-orgchart-shell';
|
||||
shell.dataset.layoutMode = view === 'composition' ? layoutMode : 'fixed';
|
||||
// The Core's Korean labels must shape identically in ko HTML and en Storybook hosts.
|
||||
shell.lang = 'ko';
|
||||
shell.tabIndex = -1;
|
||||
|
||||
Reference in new issue
Block a user