feat(orgchart): integrate chart-only viewport and scoped guard fixes

Add initial fit and direct wheel zoom with preserved default presentation. Integrate five scoped GuardFix findings and AI generation preselection policy. Exclude Cell experiments and retain five historical guard failures.
This commit is contained in:
shkim4 committed 2026-10-13 18:41:14 +09:00
1 parent 0a8daf7ee7
commit d56d587fd2
28 files changed
+1170 -77

No files matched your search

@@ -3,6 +3,7 @@ import { createHeading, type RenderContext } from './render.js';
import type { RenderEngineNode } from './engine.js';
import { getCompanyColorPreset } from '../company-color-presets.js';
import { alignExpandedLevels } from './expanded-layout.js';
import type { OrgChartWheelZoom } from './types.js';
/** Auto-only presenter. The source and popup identity remain unchanged. */
export function decorateExpandedNode(node: HTMLElement, value: RenderEngineNode, context: RenderContext, signal: AbortSignal): void {
@@ -27,7 +28,6 @@ export function decorateExpandedNode(node: HTMLElement, value: RenderEngineNode,
node.dataset.verticalLayout = String(vertical);
const layoutDirection = context.autoLayout?.type === 'lr' || vertical ? 'left' : 'top';
node.style.setProperty('--hm-orgchart-expanded-primary', preset.primary);
node.style.setProperty('--hm-orgchart-expanded-title-ink', ['saman', 'jangheon-industry'].includes(companyId) ? 'var(--hm-orgchart-resolved-fg-primary)' : 'var(--hm-orgchart-resolved-on-action-primary)');
preset.secondary.forEach((color, index) => node.style.setProperty(`--hm-orgchart-expanded-secondary-${index + 1}`, color));
for (const edge of node.querySelectorAll('.edge')) edge.setAttribute('aria-hidden', 'true');
const leaderId = top?.employeeId === undefined ? organization.leaderId : top.employeeId;
@@ -90,11 +90,13 @@ export function decorateExpandedNode(node: HTMLElement, value: RenderEngineNode,
}
}
export function createExpandedOrgChartContent(document: Document, context: RenderContext, tree: HTMLElement, signal: AbortSignal, layoutReady: () => void): HTMLElement {
export function createExpandedOrgChartContent(document: Document, context: RenderContext, tree: HTMLElement, signal: AbortSignal, layoutReady: () => void,
presentation: { chartOnly?: boolean; wheelZoom?: OrgChartWheelZoom } = {}): HTMLElement {
const content = document.createElement('div');
content.className = 'hm-orgchart-expanded';
content.dataset.component = 'ExpandedOrgChartContent';
content.dataset.layoutMode = 'auto';
if (presentation.chartOnly) content.dataset.presentationMode = 'chart-only';
content.dataset.autoLayout = context.autoLayout?.type ?? 'tb';
content.dataset.hybridStartDepth = String(context.autoLayout?.hybridStartDepth ?? 3);
content.dataset.initialVisibleDepth = String(context.autoLayout?.initialVisibleDepth ?? 'all');
@@ -105,8 +107,10 @@ export function createExpandedOrgChartContent(document: Document, context: Rende
const preset = getCompanyColorPreset(company);
if (preset) content.style.setProperty(`--hm-orgchart-company-${company}`, preset.primary);
}
tree.setAttribute('aria-label', '확장형 조직 계층도 · Ctrl 또는 Command + 휠로 확대 · 드래그로 이동');
content.append(createHeading(document, context), tree);
tree.setAttribute('aria-label', `확장형 조직 계층도 · ${presentation.wheelZoom === 'direct' ? '휠로 확대·축소' : 'Ctrl 또는 Command + 휠로 확대'} · 드래그로 이동`);
// Chart Only: titles inside organization nodes remain; the outer heading does not.
if (presentation.chartOnly) content.append(tree);
else content.append(createHeading(document, context), tree);
alignExpandedLevels(tree, signal, layoutReady, context.autoLayout);
return content;
}