92 lines
3.9 KiB
TypeScript
92 lines
3.9 KiB
TypeScript
import { StrictMode } from 'react';
|
|
import { createRoot } from 'react-dom/client';
|
|
import { OrgChart, type OrgChartProps } from '@hm-design/org-chart-react';
|
|
import { JsonOrgChartDataSource, type OrgChartDataSource, type OrgChartState } from '@hm-design/org-chart';
|
|
import engineUrl from '@hm-design/org-chart/engine.css?url';
|
|
import coreUrl from '@hm-design/org-chart/style.css?url';
|
|
import v1 from '../org-chart/data-v1.json';
|
|
import v2 from '../org-chart/data-v2.json';
|
|
import './index.css';
|
|
|
|
// An independent production-built consumer of public package entries. This
|
|
// inspection seam exercises React Props only; it never reaches into the engine.
|
|
const events: { instance: string; callback: number; state: OrgChartState }[] = [];
|
|
const lifecycleErrors: string[] = [];
|
|
const requests: Record<string, { loads: number; aborts: number }> = {};
|
|
function track(name: string, source: OrgChartDataSource): OrgChartDataSource {
|
|
requests[name] = { loads: 0, aborts: 0 };
|
|
return {
|
|
load(options) {
|
|
requests[name].loads++;
|
|
options?.signal?.addEventListener('abort', () => { requests[name].aborts++; }, { once: true });
|
|
return source.load(options);
|
|
},
|
|
};
|
|
}
|
|
const noEmployees = structuredClone(v1);
|
|
noEmployees.employees = [];
|
|
for (const organization of noEmployees.organizations) organization.leaderId = null;
|
|
const noOrganizations = structuredClone(v1);
|
|
noOrganizations.organizations = [];
|
|
const sources = {
|
|
v1: track('v1', new JsonOrgChartDataSource(v1)),
|
|
v2: track('v2', new JsonOrgChartDataSource(v2)),
|
|
zeroEmployees: track('zeroEmployees', new JsonOrgChartDataSource(noEmployees)),
|
|
zeroOrganizations: track('zeroOrganizations', new JsonOrgChartDataSource(noOrganizations)),
|
|
error: track('error', { async load() { throw new Error('Fictitious source failure'); } }),
|
|
};
|
|
let releaseSlow: (() => void) | undefined;
|
|
const slowSource = track('slow', {
|
|
load() { return new Promise(resolve => { releaseSlow = () => resolve(structuredClone(v1)); }); },
|
|
});
|
|
type Configuration = {
|
|
sourceA: OrgChartDataSource;
|
|
sourceB: OrgChartDataSource;
|
|
mountedA: boolean;
|
|
mountedB: boolean;
|
|
callback: number;
|
|
aggregationPolicy: OrgChartProps['aggregationPolicy'];
|
|
stylesheetUrls: OrgChartProps['stylesheetUrls'];
|
|
className: string;
|
|
};
|
|
let configuration: Configuration = {
|
|
sourceA: sources.v1, sourceB: sources.v2, mountedA: true, mountedB: false,
|
|
callback: 1, aggregationPolicy: undefined,
|
|
stylesheetUrls: { engine: engineUrl, core: coreUrl }, className: 'consumer-chart',
|
|
};
|
|
const root = createRoot(document.getElementById('root')!);
|
|
function render(patch: Partial<Configuration> = {}) {
|
|
configuration = { ...configuration, ...patch };
|
|
const callback = configuration.callback;
|
|
const chart = (instance: 'A' | 'B', source: OrgChartDataSource) => (
|
|
<section key={instance} aria-label={`OrgChart ${instance}`} data-instance={instance}>
|
|
<OrgChart
|
|
dataSource={source}
|
|
aggregationPolicy={configuration.aggregationPolicy}
|
|
stylesheetUrls={configuration.stylesheetUrls}
|
|
className={configuration.className}
|
|
onStateChange={state => { events.push({ instance, callback, state }); }}
|
|
onLifecycleError={error => { lifecycleErrors.push(error instanceof Error ? error.message : String(error)); }}
|
|
/>
|
|
</section>
|
|
);
|
|
root.render(
|
|
<StrictMode>
|
|
<p className="consumer-note">가상 JSON 데이터 · React Strict Mode · 공개 OrgChart 패키지 사용</p>
|
|
<div className="consumer-charts">
|
|
{configuration.mountedA && chart('A', configuration.sourceA)}
|
|
{configuration.mountedB && chart('B', configuration.sourceB)}
|
|
</div>
|
|
</StrictMode>,
|
|
);
|
|
}
|
|
const demo = {
|
|
render, sources, slowSource, events, lifecycleErrors, requests,
|
|
releaseSlow: () => releaseSlow?.(),
|
|
get configuration() { return configuration; },
|
|
destroy: () => root.unmount(),
|
|
};
|
|
declare global { interface Window { OrgChartReactDemo: typeof demo } }
|
|
window.OrgChartReactDemo = demo;
|
|
render();
|