feat(org-chart): add P5-0 company color presets

This commit is contained in:
shkim4 committed 2026-10-12 17:59:20 +09:00
1 parent 61c6f8d1f1
commit 80583eb4ca
3 files changed
+103

No files matched your search

@@ -0,0 +1,44 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { companyColorPresets, getCompanyColorPreset } from './index.js';
import type { CompanyColorPreset, CompanyId } from './index.js';
// Independent acceptance values from the P5-0 request, including the secondary order.
const expected: ReadonlyArray<CompanyColorPreset & { readonly companyId: CompanyId }> = [
{ companyId: 'hanmac', companyName: '한맥기술', primary: '#CB2E28', secondary: ['#1D4289'] },
{ companyId: 'saman', companyName: '삼안', primary: '#F08300', secondary: ['#6D6C6C'] },
{ companyId: 'jangheon-industry', companyName: '장헌산업', primary: '#4580A6', secondary: ['#92BED4'] },
{ companyId: 'jangheon', companyName: '장헌', primary: '#1D418D', secondary: ['#AE232A'] },
{ companyId: 'ptc', companyName: '피티씨', primary: '#84338E', secondary: ['#F7AF00', '#0066B5'] },
{ companyId: 'halla', companyName: '한라산업개발', primary: '#0068B7', secondary: ['#231815'] },
{ companyId: 'baron', companyName: '바론컨설턴트', primary: '#0C367F', secondary: [] },
];
test('the public registry contains exactly the seven existing company IDs', () => {
assert.deepEqual(Object.keys(companyColorPresets).sort(), expected.map(preset => preset.companyId).sort());
});
for (const preset of expected) {
test(`${preset.companyName}: public lookup preserves the approved ID, name and exact colors`, () => {
assert.deepEqual(getCompanyColorPreset(preset.companyId), preset);
assert.equal(getCompanyColorPreset(preset.companyId), companyColorPresets[preset.companyId]);
});
}
test('unknown IDs and inherited property names never select a company or fallback color', () => {
for (const id of ['', 'unknown', 'hanmaek', 'HANMAC', '__proto__', 'constructor', 'toString']) {
assert.equal(getCompanyColorPreset(id), undefined);
}
});
test('shared preset values cannot be mutated by HTML or React consumers', () => {
assert.ok(Object.isFrozen(companyColorPresets));
for (const { companyId } of expected) {
const preset = getCompanyColorPreset(companyId);
assert.ok(Object.isFrozen(preset));
assert.ok(Object.isFrozen(preset.secondary));
assert.equal(Reflect.set(preset, 'primary', '#000000'), false);
assert.equal(Reflect.set(preset.secondary, '0', '#000000'), false);
assert.deepEqual(getCompanyColorPreset(companyId), expected.find(item => item.companyId === companyId));
}
});
@@ -0,0 +1,57 @@
/** Company colors reserved for the future Auto Layout view.
* The fixed Workdesk composition continues to use core/style-presets.ts.
* These values do not apply CSS, change rendering or depend on HM Theme. */
export interface CompanyColorPreset {
readonly companyId: string;
readonly companyName: string;
readonly primary: string;
readonly secondary: readonly string[];
}
function freezePreset(preset: CompanyColorPreset): CompanyColorPreset {
return Object.freeze({ ...preset, secondary: Object.freeze([...preset.secondary]) });
}
/** IDs match the existing affiliation IDs. Only user-approved colors belong here. */
export const companyColorPresets = Object.freeze({
hanmac: freezePreset({
companyId: 'hanmac', companyName: '한맥기술',
primary: '#CB2E28', secondary: ['#1D4289'],
}),
saman: freezePreset({
companyId: 'saman', companyName: '삼안',
primary: '#F08300', secondary: ['#6D6C6C'],
}),
'jangheon-industry': freezePreset({
companyId: 'jangheon-industry', companyName: '장헌산업',
primary: '#4580A6', secondary: ['#92BED4'],
}),
jangheon: freezePreset({
companyId: 'jangheon', companyName: '장헌',
primary: '#1D418D', secondary: ['#AE232A'],
}),
ptc: freezePreset({
companyId: 'ptc', companyName: '피티씨',
primary: '#84338E', secondary: ['#F7AF00', '#0066B5'],
}),
halla: freezePreset({
companyId: 'halla', companyName: '한라산업개발',
primary: '#0068B7', secondary: ['#231815'],
}),
baron: freezePreset({
companyId: 'baron', companyName: '바론컨설턴트',
primary: '#0C367F', secondary: [],
}),
});
export type CompanyId = keyof typeof companyColorPresets;
/** HTML/React share this lookup. Unknown IDs return undefined without a fallback.
* @example const { primary, secondary } = getCompanyColorPreset('hanmac'); */
export function getCompanyColorPreset(companyId: CompanyId): CompanyColorPreset;
export function getCompanyColorPreset(companyId: string): CompanyColorPreset | undefined;
export function getCompanyColorPreset(companyId: string): CompanyColorPreset | undefined {
return Object.hasOwn(companyColorPresets, companyId)
? companyColorPresets[companyId as CompanyId]
: undefined;
}
+2
View File
@@ -1,4 +1,6 @@
export * from './data/index.js';
export { companyColorPresets, getCompanyColorPreset } from './company-color-presets.js';
export type { CompanyColorPreset, CompanyId } from './company-color-presets.js';
export { createOrgChart } from './core/index.js';
export type { OrgChartDisplayMode, OrgChartEmployeeClickContext, OrgChartHandle, OrgChartOptions, OrgChartOrganizationLinks, OrgChartState } from './core/types.js';
export { createOrgChartTree, createPositionSummary, createAffiliationSummary, createStatusSummary } from './components.js';