import { themesColorMap, themesAnimationMap } from '@fmsim/api' import MCSUnit from './mcs-unit.js' import { parseIfJsonString } from './utils/data-value' /** * Holder.data 변경 감지 시 carrierManager 에 전달할 4 키 묶음 + multiCarriers 배열. * 비교 결과 단 하나라도 다르면 carrierManager.update 호출. * (데이터 키는 모두 대문자 전제 — 케이스 정규화 없이 직접 읽는다) */ const CARRIER_DATA_KEYS = ['CARRIERNAME', 'CARRIERTYPE', 'EMPTYTYPE', 'CARRIERSTATUS'] as const function multiCarriersChanged(a: any, b: any): boolean { // MULTICARRIERS 값이 JSON 문자열로 올 수 있어 파싱 후 비교. shallow JSON 비교로 충분 — // 각 항목이 4 키 primitive 만 가짐. 빈/누락은 같은 '[]' 직렬화로 동치 취급. return ( JSON.stringify(parseIfJsonString(a?.MULTICARRIERS) ?? []) !== JSON.stringify(parseIfJsonString(b?.MULTICARRIERS) ?? []) ) } export default class MCSCarrierHolder extends MCSUnit { static get properties(): any { return [ ...MCSUnit.properties, { type: 'select', label: 'carrier-legend-name', name: 'carrierLegendName', property: { options: themesColorMap } }, { type: 'select', label: 'carrier-animation-name', name: 'carrierAnimationName', property: { options: themesAnimationMap } }, { type: 'boolean', label: 'show-carrier-text', name: 'showCarrierText' } // 적층 두께는 carrier 측 (Carrier.added) 에서 자기 default depth 를 결정. // holder 측에는 별도 carrierDepth 속성을 두지 않는다. ] } get showOverflow() { return true } get hierarchy() { return { ...super.hierarchy, components: [] } } dispose(): void { ;(this.root as any)?.carrierManager?.update(this, {}, this.data) super.dispose() } async ready() { super.ready() if (this._hasCarrierData(this.data)) { ;(this.root as any).carrierManager.update(this, this.data || {}, undefined) } } onchangeData(after: Record, before: Record): void { const afterData = after.data || {} const beforeData = before.data || {} let changed = false for (const k of CARRIER_DATA_KEYS) { if (afterData[k] !== beforeData[k]) { changed = true break } } if (!changed) { changed = multiCarriersChanged(afterData, beforeData) } if (changed) { ;(this.root as any).carrierManager.update(this, afterData, beforeData) } super.onchangeData(after, before) } /** data 안에 carrier 정보 (대표 또는 multiCarriers) 가 하나라도 있는지. */ private _hasCarrierData(data: any): boolean { if (!data) return false if (data.CARRIERNAME) return true const list = parseIfJsonString(data.MULTICARRIERS) if (Array.isArray(list) && list.some((a: any) => a?.CARRIERNAME)) return true return false } }