@fmsim/board 2.0.0-beta.84 → 2.0.0-beta.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +1005 -939
- package/dist/src/modeller/property-sidebar/effects/effects.js +8 -1
- package/dist/src/modeller/property-sidebar/effects/effects.js.map +1 -1
- package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.d.ts +44 -0
- package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.js +70 -0
- package/dist/src/modeller/property-sidebar/effects/event-handler-adapter.js.map +1 -0
- package/dist/src/modeller/property-sidebar/effects/property-event.d.ts +12 -2
- package/dist/src/modeller/property-sidebar/effects/property-event.js +20 -11
- package/dist/src/modeller/property-sidebar/effects/property-event.js.map +1 -1
- package/dist/src/ox-board-component-info.js +30 -1
- package/dist/src/ox-board-component-info.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -36,7 +36,14 @@ export class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {
|
|
|
36
36
|
</fieldset>
|
|
37
37
|
|
|
38
38
|
${this.selected.length == 1
|
|
39
|
-
? html `
|
|
39
|
+
? html `
|
|
40
|
+
<property-event
|
|
41
|
+
value-key="eventHandlers"
|
|
42
|
+
.scene=${this.scene}
|
|
43
|
+
.value=${value.eventHandlers || []}
|
|
44
|
+
>
|
|
45
|
+
</property-event>
|
|
46
|
+
`
|
|
40
47
|
: nothing}
|
|
41
48
|
`;
|
|
42
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effects.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/effects/effects.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,0BAA0B,CAAA;AAEjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,OAAO,eAAgB,SAAQ,mBAAmB,CAAC,gBAAgB,CAAC;IAA1E;;QAK6B,aAAQ,GAAgB,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"effects.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/effects/effects.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,0BAA0B,CAAA;AAEjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,OAAO,eAAgB,SAAQ,mBAAmB,CAAC,gBAAgB,CAAC;IAA1E;;QAK6B,aAAQ,GAAgB,EAAE,CAAA;IAqCvD,CAAC;IAnCC,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,iBAAiB,EAAE,cAAc;YACjC,gBAAgB,EAAE,aAAa;SAChC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,OAAO,IAAI,CAAA;;;;;;qDAMsC,KAAK,CAAC,MAAM,IAAI,EAAE;;;QAG/D,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC;YACzB,CAAC,CAAC,IAAI,CAAA;;;uBAGS,IAAI,CAAC,KAAK;uBACV,KAAK,CAAC,aAAa,IAAI,EAAE;;;WAGrC;YACH,CAAC,CAAC,OAAO;KACZ,CAAA;IACH,CAAC;;AAxCM,sBAAM,GAAG,CAAC,mBAAmB,CAAC,AAAxB,CAAwB;AAET;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAmB;AAClB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAc;AACd;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;iDAA2B","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/i18n/ox-i18n.js'\n\nimport { html, nothing } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component, Properties, Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { AbstractProperty } from '../abstract-property.js'\nimport { PropertySharedStyle } from '../property-shared-style.js'\nimport { PropertyEvent } from './property-event.js'\nimport { PropertyShadow } from './property-shadow.js'\n\nexport class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {\n static styles = [PropertySharedStyle]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) selected: Component[] = []\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n static get scopedElements() {\n return {\n 'property-shadow': PropertyShadow,\n 'property-event': PropertyEvent\n }\n }\n\n render() {\n const value = this.value || {}\n\n return html`\n <fieldset>\n <legend>\n <ox-i18n topic=\"board-modeller/effects/shadow\" msgid=\"label.shadow\">shadow</ox-i18n>\n </legend>\n\n <property-shadow value-key=\"shadow\" .value=${value.shadow || {}}> </property-shadow>\n </fieldset>\n\n ${this.selected.length == 1\n ? html`\n <property-event\n value-key=\"eventHandlers\"\n .scene=${this.scene}\n .value=${value.eventHandlers || []}\n >\n </property-event>\n `\n : nothing}\n `\n }\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* 기존 PropertyEvent UI 는 legacy `state.event = { tap: {...} }` 단일 객체
|
|
5
|
+
* 모델 위에 만들어졌으나, things-scene v10 의 신규 모델은
|
|
6
|
+
* `state.eventHandlers: EventHandler[]` 다중 핸들러 배열. dispatcher 가
|
|
7
|
+
* legacy fallback 도 지원하지만, UI 가 신규 모델로 직접 read/write 하도록
|
|
8
|
+
* 정합화한다.
|
|
9
|
+
*
|
|
10
|
+
* 정책 — 사용자 의도에 따른 *최소 호환*:
|
|
11
|
+
* - 신규 모델의 multi-trigger / multi-handler 는 미지원
|
|
12
|
+
* - 기존 UI 그대로 — tap (click) 단일 핸들러만
|
|
13
|
+
* - 다른 trigger 의 핸들러가 이미 배열에 있으면 *건드리지 않는다*
|
|
14
|
+
* (UI 가 모르는 항목은 보존)
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* EventHandler — things-scene v10 의 신규 모델 spec 미러.
|
|
18
|
+
* things-scene root export 에 아직 포함되지 않아 inline 정의.
|
|
19
|
+
* (참조: things-scene/src/interfaces/event-handler.ts:29)
|
|
20
|
+
*/
|
|
21
|
+
export interface EventHandler {
|
|
22
|
+
trigger: string;
|
|
23
|
+
action?: string;
|
|
24
|
+
code?: string;
|
|
25
|
+
target?: string;
|
|
26
|
+
value?: any;
|
|
27
|
+
options?: Record<string, any>;
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** legacy tap 객체 형태 — PropertyEventTap UI 가 다루는 모양. */
|
|
31
|
+
export interface LegacyTap {
|
|
32
|
+
action?: string;
|
|
33
|
+
target?: string;
|
|
34
|
+
value?: any;
|
|
35
|
+
pressed?: boolean;
|
|
36
|
+
options?: Record<string, any>;
|
|
37
|
+
}
|
|
38
|
+
/** trigger 가 click/tap 인 첫 핸들러를 legacy tap 객체로 변환. */
|
|
39
|
+
export declare function eventHandlersToLegacyTap(handlers: EventHandler[] | undefined): LegacyTap;
|
|
40
|
+
/**
|
|
41
|
+
* 기존 배열에서 click/tap 항목을 새 값으로 교체 (또는 push, 또는 제거).
|
|
42
|
+
* 다른 trigger 항목은 그대로 보존.
|
|
43
|
+
*/
|
|
44
|
+
export declare function applyLegacyTapToHandlers(handlers: EventHandler[] | undefined, newTap: LegacyTap | undefined): EventHandler[];
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** trigger 가 click/tap 인 첫 핸들러를 legacy tap 객체로 변환. */
|
|
2
|
+
export function eventHandlersToLegacyTap(handlers) {
|
|
3
|
+
var _a, _b;
|
|
4
|
+
if (!Array.isArray(handlers))
|
|
5
|
+
return {};
|
|
6
|
+
const h = handlers.find(h => h.trigger === 'click' || h.trigger === 'tap');
|
|
7
|
+
if (!h)
|
|
8
|
+
return {};
|
|
9
|
+
// action='script' 인 경우 code 를 value 자리로 노출 — legacy UI 가 value
|
|
10
|
+
// 텍스트 영역에 script 를 넣어 쓰던 관습 보존.
|
|
11
|
+
if (h.action === 'script') {
|
|
12
|
+
return { action: 'script', target: h.target, value: (_a = h.code) !== null && _a !== void 0 ? _a : '' };
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
action: h.action,
|
|
16
|
+
target: h.target,
|
|
17
|
+
value: h.value,
|
|
18
|
+
pressed: (_b = h.options) === null || _b === void 0 ? void 0 : _b.pressed,
|
|
19
|
+
options: h.options
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** legacy tap 객체 → EventHandler. action 없으면 null (= 삭제 의미). */
|
|
23
|
+
function legacyTapToEventHandler(tap) {
|
|
24
|
+
var _a;
|
|
25
|
+
if (!tap)
|
|
26
|
+
return null;
|
|
27
|
+
// action 이 비어있고 target/value 도 없으면 의미 있는 데이터 없음 → 제거
|
|
28
|
+
const hasContent = !!(tap.action || tap.target || tap.value);
|
|
29
|
+
if (!hasContent)
|
|
30
|
+
return null;
|
|
31
|
+
if (tap.action === 'script') {
|
|
32
|
+
return {
|
|
33
|
+
trigger: 'click',
|
|
34
|
+
action: 'script',
|
|
35
|
+
code: typeof tap.value === 'string' ? tap.value : '',
|
|
36
|
+
target: tap.target
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// pressed 는 legacy 의 *최상위 키* 였지만 신규 모델에선 options 의 일부.
|
|
40
|
+
const options = { ...((_a = tap.options) !== null && _a !== void 0 ? _a : {}) };
|
|
41
|
+
if (tap.pressed !== undefined)
|
|
42
|
+
options.pressed = tap.pressed;
|
|
43
|
+
return {
|
|
44
|
+
trigger: 'click',
|
|
45
|
+
action: tap.action,
|
|
46
|
+
target: tap.target,
|
|
47
|
+
value: tap.value,
|
|
48
|
+
...(Object.keys(options).length > 0 ? { options } : {})
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 기존 배열에서 click/tap 항목을 새 값으로 교체 (또는 push, 또는 제거).
|
|
53
|
+
* 다른 trigger 항목은 그대로 보존.
|
|
54
|
+
*/
|
|
55
|
+
export function applyLegacyTapToHandlers(handlers, newTap) {
|
|
56
|
+
const out = Array.isArray(handlers) ? [...handlers] : [];
|
|
57
|
+
const idx = out.findIndex(h => h.trigger === 'click' || h.trigger === 'tap');
|
|
58
|
+
const newHandler = legacyTapToEventHandler(newTap);
|
|
59
|
+
if (newHandler) {
|
|
60
|
+
if (idx >= 0)
|
|
61
|
+
out[idx] = newHandler;
|
|
62
|
+
else
|
|
63
|
+
out.push(newHandler);
|
|
64
|
+
}
|
|
65
|
+
else if (idx >= 0) {
|
|
66
|
+
out.splice(idx, 1);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=event-handler-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-handler-adapter.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/effects/event-handler-adapter.ts"],"names":[],"mappings":"AAuCA,sDAAsD;AACtD,MAAM,UAAU,wBAAwB,CAAC,QAAoC;;IAC3E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAA;IACvC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAA;IAC1E,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAA;IAEjB,+DAA+D;IAC/D,gCAAgC;IAChC,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAA,CAAC,CAAC,IAAI,mCAAI,EAAE,EAAE,CAAA;IACpE,CAAC;IAED,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,MAAA,CAAC,CAAC,OAAO,0CAAE,OAAO;QAC3B,OAAO,EAAE,CAAC,CAAC,OAAO;KACnB,CAAA;AACH,CAAC;AAED,+DAA+D;AAC/D,SAAS,uBAAuB,CAAC,GAA0B;;IACzD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,qDAAqD;IACrD,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;IAC5D,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAA;IAE5B,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO;YACL,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YACpD,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAA;IACH,CAAC;IAED,uDAAuD;IACvD,MAAM,OAAO,GAAwB,EAAE,GAAG,CAAC,MAAA,GAAG,CAAC,OAAO,mCAAI,EAAE,CAAC,EAAE,CAAA;IAC/D,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAA;IAE5D,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAAoC,EACpC,MAA6B;IAE7B,MAAM,GAAG,GAAmB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACxE,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAA;IAC5E,MAAM,UAAU,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAA;IAElD,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,GAAG,IAAI,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,UAAU,CAAA;;YAC9B,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC3B,CAAC;SAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IACpB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * 기존 PropertyEvent UI 는 legacy `state.event = { tap: {...} }` 단일 객체\n * 모델 위에 만들어졌으나, things-scene v10 의 신규 모델은\n * `state.eventHandlers: EventHandler[]` 다중 핸들러 배열. dispatcher 가\n * legacy fallback 도 지원하지만, UI 가 신규 모델로 직접 read/write 하도록\n * 정합화한다.\n *\n * 정책 — 사용자 의도에 따른 *최소 호환*:\n * - 신규 모델의 multi-trigger / multi-handler 는 미지원\n * - 기존 UI 그대로 — tap (click) 단일 핸들러만\n * - 다른 trigger 의 핸들러가 이미 배열에 있으면 *건드리지 않는다*\n * (UI 가 모르는 항목은 보존)\n */\n/**\n * EventHandler — things-scene v10 의 신규 모델 spec 미러.\n * things-scene root export 에 아직 포함되지 않아 inline 정의.\n * (참조: things-scene/src/interfaces/event-handler.ts:29)\n */\nexport interface EventHandler {\n trigger: string\n action?: string\n code?: string\n target?: string\n value?: any\n options?: Record<string, any>\n disabled?: boolean\n}\n\n/** legacy tap 객체 형태 — PropertyEventTap UI 가 다루는 모양. */\nexport interface LegacyTap {\n action?: string\n target?: string\n value?: any\n pressed?: boolean\n options?: Record<string, any>\n}\n\n/** trigger 가 click/tap 인 첫 핸들러를 legacy tap 객체로 변환. */\nexport function eventHandlersToLegacyTap(handlers: EventHandler[] | undefined): LegacyTap {\n if (!Array.isArray(handlers)) return {}\n const h = handlers.find(h => h.trigger === 'click' || h.trigger === 'tap')\n if (!h) return {}\n\n // action='script' 인 경우 code 를 value 자리로 노출 — legacy UI 가 value\n // 텍스트 영역에 script 를 넣어 쓰던 관습 보존.\n if (h.action === 'script') {\n return { action: 'script', target: h.target, value: h.code ?? '' }\n }\n\n return {\n action: h.action,\n target: h.target,\n value: h.value,\n pressed: h.options?.pressed,\n options: h.options\n }\n}\n\n/** legacy tap 객체 → EventHandler. action 없으면 null (= 삭제 의미). */\nfunction legacyTapToEventHandler(tap: LegacyTap | undefined): EventHandler | null {\n if (!tap) return null\n // action 이 비어있고 target/value 도 없으면 의미 있는 데이터 없음 → 제거\n const hasContent = !!(tap.action || tap.target || tap.value)\n if (!hasContent) return null\n\n if (tap.action === 'script') {\n return {\n trigger: 'click',\n action: 'script',\n code: typeof tap.value === 'string' ? tap.value : '',\n target: tap.target\n }\n }\n\n // pressed 는 legacy 의 *최상위 키* 였지만 신규 모델에선 options 의 일부.\n const options: Record<string, any> = { ...(tap.options ?? {}) }\n if (tap.pressed !== undefined) options.pressed = tap.pressed\n\n return {\n trigger: 'click',\n action: tap.action,\n target: tap.target,\n value: tap.value,\n ...(Object.keys(options).length > 0 ? { options } : {})\n }\n}\n\n/**\n * 기존 배열에서 click/tap 항목을 새 값으로 교체 (또는 push, 또는 제거).\n * 다른 trigger 항목은 그대로 보존.\n */\nexport function applyLegacyTapToHandlers(\n handlers: EventHandler[] | undefined,\n newTap: LegacyTap | undefined\n): EventHandler[] {\n const out: EventHandler[] = Array.isArray(handlers) ? [...handlers] : []\n const idx = out.findIndex(h => h.trigger === 'click' || h.trigger === 'tap')\n const newHandler = legacyTapToEventHandler(newTap)\n\n if (newHandler) {\n if (idx >= 0) out[idx] = newHandler\n else out.push(newHandler)\n } else if (idx >= 0) {\n out.splice(idx, 1)\n }\n return out\n}\n"]}
|
|
@@ -2,12 +2,22 @@
|
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import { LitElement } from 'lit';
|
|
5
|
-
import {
|
|
5
|
+
import { Scene } from '@hatiolab/things-scene';
|
|
6
6
|
import { PropertyEventTap } from './property-event-tap';
|
|
7
|
+
import { EventHandler } from './event-handler-adapter.js';
|
|
7
8
|
declare const PropertyEvent_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
|
|
9
|
+
/**
|
|
10
|
+
* things-scene v10 의 신규 모델 (`state.eventHandlers: EventHandler[]`) 위에서
|
|
11
|
+
* 기존 단일-tap UI 를 그대로 동작시키는 어댑터.
|
|
12
|
+
*
|
|
13
|
+
* read : eventHandlers 배열에서 trigger='click'/'tap' 인 첫 항목 → legacy tap
|
|
14
|
+
* 객체로 변환 후 PropertyEventTap 에 전달.
|
|
15
|
+
* write: PropertyEventTap 이 emit 한 legacy tap 변경 → click 항목을 update/push
|
|
16
|
+
* 한 새 배열로 외부에 emit. 다른 trigger 의 핸들러는 보존.
|
|
17
|
+
*/
|
|
8
18
|
export declare class PropertyEvent extends PropertyEvent_base {
|
|
9
19
|
static styles: import("lit").CSSResult[];
|
|
10
|
-
value?:
|
|
20
|
+
value?: EventHandler[];
|
|
11
21
|
scene?: Scene;
|
|
12
22
|
firstUpdated(): void;
|
|
13
23
|
static get scopedElements(): {
|
|
@@ -8,6 +8,16 @@ import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|
|
8
8
|
import { PropertySharedStyle } from '../property-shared-style';
|
|
9
9
|
import { PropertyEventTap } from './property-event-tap';
|
|
10
10
|
import { convert } from './value-converter';
|
|
11
|
+
import { applyLegacyTapToHandlers, eventHandlersToLegacyTap } from './event-handler-adapter.js';
|
|
12
|
+
/**
|
|
13
|
+
* things-scene v10 의 신규 모델 (`state.eventHandlers: EventHandler[]`) 위에서
|
|
14
|
+
* 기존 단일-tap UI 를 그대로 동작시키는 어댑터.
|
|
15
|
+
*
|
|
16
|
+
* read : eventHandlers 배열에서 trigger='click'/'tap' 인 첫 항목 → legacy tap
|
|
17
|
+
* 객체로 변환 후 PropertyEventTap 에 전달.
|
|
18
|
+
* write: PropertyEventTap 이 emit 한 legacy tap 변경 → click 항목을 update/push
|
|
19
|
+
* 한 새 배열로 외부에 emit. 다른 trigger 의 핸들러는 보존.
|
|
20
|
+
*/
|
|
11
21
|
export class PropertyEvent extends ScopedElementsMixin(LitElement) {
|
|
12
22
|
firstUpdated() {
|
|
13
23
|
this.renderRoot.addEventListener('change', this._onValueChange.bind(this));
|
|
@@ -18,33 +28,32 @@ export class PropertyEvent extends ScopedElementsMixin(LitElement) {
|
|
|
18
28
|
};
|
|
19
29
|
}
|
|
20
30
|
render() {
|
|
21
|
-
const
|
|
31
|
+
const tap = eventHandlersToLegacyTap(this.value);
|
|
22
32
|
return html `
|
|
23
33
|
<fieldset>
|
|
24
34
|
<legend>
|
|
25
35
|
<ox-i18n msgid="label.tap-event" topic="board-modeller/effects/tap-event"></ox-i18n>
|
|
26
36
|
</legend>
|
|
27
37
|
|
|
28
|
-
<property-event-tap value-key="tap" .scene=${this.scene} .value=${
|
|
38
|
+
<property-event-tap value-key="tap" .scene=${this.scene} .value=${tap}> </property-event-tap>
|
|
29
39
|
</fieldset>
|
|
30
40
|
`;
|
|
31
41
|
}
|
|
32
42
|
_onValueChange(e) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
const element = e.target;
|
|
44
|
+
const key = element.getAttribute('value-key');
|
|
45
|
+
// 어댑터는 tap 트리거 하나만 처리. PropertyEventTap host 가 retarget 된
|
|
46
|
+
// change 의 value-key 만 받아들이고, 자식 input 의 raw change 는 무시.
|
|
47
|
+
if (key !== 'tap')
|
|
36
48
|
return;
|
|
37
|
-
|
|
38
|
-
this.value =
|
|
39
|
-
...this.value,
|
|
40
|
-
[key]: convert(element)
|
|
41
|
-
};
|
|
49
|
+
const newTap = convert(element);
|
|
50
|
+
this.value = applyLegacyTapToHandlers(this.value, newTap);
|
|
42
51
|
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
|
43
52
|
}
|
|
44
53
|
}
|
|
45
54
|
PropertyEvent.styles = [PropertySharedStyle];
|
|
46
55
|
__decorate([
|
|
47
|
-
property({ type:
|
|
56
|
+
property({ type: Array })
|
|
48
57
|
], PropertyEvent.prototype, "value", void 0);
|
|
49
58
|
__decorate([
|
|
50
59
|
property({ type: Object })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"property-event.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/effects/property-event.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"property-event.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/effects/property-event.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EAGzB,MAAM,4BAA4B,CAAA;AAEnC;;;;;;;;GAQG;AACH,MAAM,OAAO,aAAc,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAMhE,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,oBAAoB,EAAE,gBAAgB;SACvC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,MAAM,GAAG,GAAG,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAEhD,OAAO,IAAI,CAAA;;;;;;qDAMsC,IAAI,CAAC,KAAK,WAAW,GAAG;;KAExE,CAAA;IACH,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,MAAM,OAAO,GAAG,CAAC,CAAC,MAAqB,CAAA;QACvC,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAE7C,0DAA0D;QAC1D,0DAA0D;QAC1D,IAAI,GAAG,KAAK,KAAK;YAAE,OAAM;QAEzB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAc,CAAA;QAC5C,IAAI,CAAC,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAEzD,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAClF,CAAC;;AAzCM,oBAAM,GAAG,CAAC,mBAAmB,CAAC,CAAA;AAEV;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;4CAAuB;AACrB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CAAc","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { PropertySharedStyle } from '../property-shared-style'\nimport { PropertyEventTap } from './property-event-tap'\nimport { convert } from './value-converter'\nimport {\n applyLegacyTapToHandlers,\n eventHandlersToLegacyTap,\n EventHandler,\n LegacyTap\n} from './event-handler-adapter.js'\n\n/**\n * things-scene v10 의 신규 모델 (`state.eventHandlers: EventHandler[]`) 위에서\n * 기존 단일-tap UI 를 그대로 동작시키는 어댑터.\n *\n * read : eventHandlers 배열에서 trigger='click'/'tap' 인 첫 항목 → legacy tap\n * 객체로 변환 후 PropertyEventTap 에 전달.\n * write: PropertyEventTap 이 emit 한 legacy tap 변경 → click 항목을 update/push\n * 한 새 배열로 외부에 emit. 다른 trigger 의 핸들러는 보존.\n */\nexport class PropertyEvent extends ScopedElementsMixin(LitElement) {\n static styles = [PropertySharedStyle]\n\n @property({ type: Array }) value?: EventHandler[]\n @property({ type: Object }) scene?: Scene\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this._onValueChange.bind(this))\n }\n\n static get scopedElements() {\n return {\n 'property-event-tap': PropertyEventTap\n }\n }\n\n render() {\n const tap = eventHandlersToLegacyTap(this.value)\n\n return html`\n <fieldset>\n <legend>\n <ox-i18n msgid=\"label.tap-event\" topic=\"board-modeller/effects/tap-event\"></ox-i18n>\n </legend>\n\n <property-event-tap value-key=\"tap\" .scene=${this.scene} .value=${tap}> </property-event-tap>\n </fieldset>\n `\n }\n\n _onValueChange(e: Event) {\n const element = e.target as HTMLElement\n const key = element.getAttribute('value-key')\n\n // 어댑터는 tap 트리거 하나만 처리. PropertyEventTap host 가 retarget 된\n // change 의 value-key 만 받아들이고, 자식 input 의 raw change 는 무시.\n if (key !== 'tap') return\n\n const newTap = convert(element) as LegacyTap\n this.value = applyLegacyTapToHandlers(this.value, newTap)\n\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n }\n}\n"]}
|
|
@@ -7,6 +7,35 @@ import { css, html, LitElement, nothing } from 'lit';
|
|
|
7
7
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
8
8
|
import { ScrollbarStyles } from '@operato/styles';
|
|
9
9
|
import { i18next } from '@operato/i18n';
|
|
10
|
+
/**
|
|
11
|
+
* info panel 의 *value 셀* 렌더링. 1차 표시는 plain string 인데, ADDITIONS
|
|
12
|
+
* 같이 *object array* 가 들어오면 `[object Object]` 로 뭉개진다.
|
|
13
|
+
*
|
|
14
|
+
* - ADDITIONS: array of carrier info object → 각 항목을 한 줄씩
|
|
15
|
+
* "CARRIERNAME (CARRIERTYPE / EMPTYTYPE)" 형식으로
|
|
16
|
+
* - 그 외 object/array → JSON 한 줄
|
|
17
|
+
* - primitive → 그대로
|
|
18
|
+
*/
|
|
19
|
+
function formatCarrierItem(item) {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
if (!item || typeof item !== 'object')
|
|
22
|
+
return String(item);
|
|
23
|
+
const name = (_b = (_a = item.CARRIERNAME) !== null && _a !== void 0 ? _a : item.CARRIERID) !== null && _b !== void 0 ? _b : '';
|
|
24
|
+
const meta = [item.CARRIERTYPE, item.EMPTYTYPE].filter(Boolean).join(' / ');
|
|
25
|
+
return meta ? `${name} (${meta})` : name;
|
|
26
|
+
}
|
|
27
|
+
function renderInfoValue(key, value) {
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
if (key === 'ADDITIONS') {
|
|
30
|
+
return html `${value.map(item => html `<div>${formatCarrierItem(item)}</div>`)}`;
|
|
31
|
+
}
|
|
32
|
+
return html `${value.map((v, i) => html `<div>${i}: ${typeof v === 'object' ? JSON.stringify(v) : String(v)}</div>`)}`;
|
|
33
|
+
}
|
|
34
|
+
if (value !== null && typeof value === 'object') {
|
|
35
|
+
return JSON.stringify(value);
|
|
36
|
+
}
|
|
37
|
+
return value === null || value === undefined ? '' : String(value);
|
|
38
|
+
}
|
|
10
39
|
let BoardComponentInfo = class BoardComponentInfo extends LitElement {
|
|
11
40
|
constructor() {
|
|
12
41
|
super(...arguments);
|
|
@@ -104,7 +133,7 @@ let BoardComponentInfo = class BoardComponentInfo extends LitElement {
|
|
|
104
133
|
${infos.map(([key, value]) => html `
|
|
105
134
|
<tr>
|
|
106
135
|
<td subTh>${key}</td>
|
|
107
|
-
<td>${value}</td>
|
|
136
|
+
<td>${renderInfoValue(key, value)}</td>
|
|
108
137
|
</tr>
|
|
109
138
|
`)}
|
|
110
139
|
`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-board-component-info.js","sourceRoot":"","sources":["../../src/ox-board-component-info.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/progress/linear-progress.js'\nimport '@operato/property-editor/ox-properties-dynamic-view.js'\nimport '@operato/markdown'\n\nimport { css, html, LitElement, PropertyValues, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { ScrollbarStyles } from '@operato/styles'\nimport { i18next } from '@operato/i18n'\n\n@customElement('ox-board-component-info')\nexport class BoardComponentInfo extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n background-color: white;\n font-size: 12px;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n border: 2px solid var(--primary-color);\n border-radius: 3px;\n\n --md-icon-size: 12px;\n }\n\n [header] {\n background-color: var(--primary-color);\n user-select: none;\n align-items: center;\n color: #eee;\n padding: 0 2px;\n\n display: flex;\n }\n\n md-icon {\n --md-icon-size: 14px;\n\n color: #555;\n align-self: center;\n padding: 0 2px;\n }\n\n [header] md-icon[close] {\n margin-left: auto;\n }\n\n [content] {\n overflow: auto;\n }\n\n table {\n border-collapse: collapse;\n background-color: #fff;\n width: 100%;\n margin: auto;\n }\n\n tr {\n border-bottom: var(--border-dark-color);\n }\n\n td {\n padding: var(--padding-narrow);\n border-right: var(--border-dark-color);\n font-size: 0.8em;\n }\n\n [subTh] {\n text-align: center !important;\n font-weight: bold;\n width: 60px;\n text-transform: capitalize;\n background-color: rgba(0, 0, 0, 0.05);\n }\n\n [split] {\n height: 10px;\n color: #eee;\n background-color: var(--primary-color);\n font-size: 0.8em;\n padding: 0;\n text-align: center;\n }\n\n [location] {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n }\n\n md-linear-progress {\n --md-linear-progress-active-indicator-color: red;\n --md-linear-progress-track-color: #ed788d;\n }\n `\n ]\n\n @property({ type: Object }) component?: any\n @property({ type: Boolean }) playbackMode: boolean = false\n\n @state() detailInfo?: any\n @state() collapsed: boolean = false\n @state() loading: boolean = false\n\n private dragStart?: { x: number; y: number }\n\n private dragEndHandler = this.onDragEnd.bind(this) as EventListener\n private dragMoveHandler = this.onDragMove.bind(this) as EventListener\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.collapsed = sessionStorage.getItem('ox-board-component-info-collapsed') == 'true'\n\n document.addEventListener('mouseup', this.dragEndHandler)\n document.addEventListener('mousemove', this.dragMoveHandler)\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback()\n\n document.removeEventListener('mouseup', this.dragEndHandler)\n document.removeEventListener('mousemove', this.dragMoveHandler)\n }\n\n render() {\n const { state, data } = this.component || {}\n const { id, type } = state || {}\n const details = this.detailInfo || data\n const infos: [key: string, value: string][] =\n details && Object.entries(details).filter(([key, value]) => key != 'ID')\n const identifiable = this.component?.isIdentifiable() || false\n\n return html`\n <div header @mousedown=${this.onDragStart.bind(this)} draggable=\"false\">\n <md-icon @click=${() => (this.collapsed = !this.collapsed)} collapsed\n >${this.collapsed ? 'expand_more' : 'expand_less'}</md-icon\n >\n Object Information\n <md-icon @click=${(e: MouseEvent) => this.dispatchEvent(new CustomEvent('close'))} close>close</md-icon>\n </div>\n ${this.loading\n ? html`<div>\n <md-linear-progress indeterminate></md-linear-progress>\n </div>`\n : nothing}\n\n <div content @wheel=${(e: WheelEvent) => this.onWheel(e)}>\n <table>\n ${identifiable\n ? html`\n <tr>\n <td subTh>\n <div\n location\n @click=${(e: MouseEvent) => {\n this.component.trigger('deco-border', { distance: 8, lineWidth: 4, color: '#f007' })\n this.component.rootModel?.centerTo(this.component, true /* animated */)\n\n return false\n }}\n >\n ${i18next.t('label.id')} <md-icon style=\"color:red;\">location_on</md-icon>\n </div>\n </td>\n <td>${id}</td>\n </tr>\n <tr>\n <td subTh>\n ${i18next.t('label.type')}${!identifiable\n ? html` <md-icon style=\"color:red;\">location_on</md-icon>`\n : html``}\n </td>\n <td>${type}</td>\n </tr>\n `\n : html`\n <tr>\n <td subTh>\n <div\n location\n @click=${(e: MouseEvent) => {\n this.component.trigger('deco-border', { distance: 8, lineWidth: 4, color: '#f007' })\n this.component.rootModel?.centerTo(this.component, true /* animated */)\n\n return false\n }}\n >\n ${i18next.t('label.type')}${!identifiable ? html` <md-icon>location_on</md-icon>` : html``}\n </div>\n </td>\n <td>${type}</td>\n </tr>\n `}\n ${!this.collapsed && infos && !this.loading\n ? html`\n <tr>\n <td split colspan=\"2\">Details</td>\n </tr>\n\n ${infos.map(\n ([key, value]) => html`\n <tr>\n <td subTh>${key}</td>\n <td>${value}</td>\n </tr>\n `\n )}\n `\n : nothing}\n </table>\n </div>\n `\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('component')) {\n this.detailInfo = null\n\n if (!this.playbackMode && 'detailInfo' in this.component) {\n try {\n this.loading = true\n this.detailInfo = await this.component.detailInfo()\n } catch (e) {\n console.error('failed to get detail information')\n } finally {\n this.loading = false\n }\n }\n }\n\n if (changes.has('collapsed')) {\n sessionStorage.setItem('ox-board-component-info-collapsed', this.collapsed ? 'true' : 'false')\n }\n }\n\n onWheel(e: WheelEvent) {\n const scrollableDiv = e.currentTarget! as HTMLElement\n const contentDiv = scrollableDiv.querySelector('table')!\n\n // 컨텐츠의 높이와 div의 높이를 비교하여 수평 스크롤을 동작시키거나 수직 스크롤을 동작시킴\n if (contentDiv.offsetHeight > scrollableDiv.offsetHeight) {\n // 수직 스크롤 가능한 경우\n scrollableDiv.scrollTop += e.deltaY\n } else {\n // 수직 스크롤이 없는 경우\n scrollableDiv.scrollLeft += e.deltaY\n }\n }\n\n onDragStart(e: MouseEvent) {\n e.stopPropagation()\n\n if (e.button == 0) {\n this.dragStart = {\n x: e.clientX,\n y: e.clientY\n }\n }\n\n return false\n }\n\n onDragMove(e: Event) {\n if (!this.dragStart) {\n return false\n }\n\n e.stopPropagation()\n e.preventDefault()\n\n var x = (e as MouseEvent).clientX,\n y = (e as MouseEvent).clientY\n\n const dragStart = { x, y }\n\n x -= this.dragStart.x\n y -= this.dragStart.y\n\n this.dragStart = dragStart\n\n this.style.left =\n Math.min(this.parentElement!.offsetWidth - this.offsetWidth, Math.max(0, this.offsetLeft + x)) + 'px'\n this.style.top =\n Math.min(this.parentElement!.offsetHeight - this.offsetHeight, Math.max(0, this.offsetTop + y)) + 'px'\n\n return false\n }\n\n onDragEnd(e: Event) {\n if (this.dragStart) {\n e.stopPropagation()\n e.preventDefault()\n\n delete this.dragStart\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ox-board-component-info.js","sourceRoot":"","sources":["../../src/ox-board-component-info.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/progress/linear-progress.js'\nimport '@operato/property-editor/ox-properties-dynamic-view.js'\nimport '@operato/markdown'\n\nimport { css, html, LitElement, PropertyValues, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { ScrollbarStyles } from '@operato/styles'\nimport { i18next } from '@operato/i18n'\n\n/**\n * info panel 의 *value 셀* 렌더링. 1차 표시는 plain string 인데, ADDITIONS\n * 같이 *object array* 가 들어오면 `[object Object]` 로 뭉개진다.\n *\n * - ADDITIONS: array of carrier info object → 각 항목을 한 줄씩\n * \"CARRIERNAME (CARRIERTYPE / EMPTYTYPE)\" 형식으로\n * - 그 외 object/array → JSON 한 줄\n * - primitive → 그대로\n */\nfunction formatCarrierItem(item: any): string {\n if (!item || typeof item !== 'object') return String(item)\n const name = item.CARRIERNAME ?? item.CARRIERID ?? ''\n const meta = [item.CARRIERTYPE, item.EMPTYTYPE].filter(Boolean).join(' / ')\n return meta ? `${name} (${meta})` : name\n}\n\nfunction renderInfoValue(key: string, value: any) {\n if (Array.isArray(value)) {\n if (key === 'ADDITIONS') {\n return html`${value.map(item => html`<div>${formatCarrierItem(item)}</div>`)}`\n }\n return html`${value.map((v, i) => html`<div>${i}: ${typeof v === 'object' ? JSON.stringify(v) : String(v)}</div>`)}`\n }\n if (value !== null && typeof value === 'object') {\n return JSON.stringify(value)\n }\n return value === null || value === undefined ? '' : String(value)\n}\n\n@customElement('ox-board-component-info')\nexport class BoardComponentInfo extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n background-color: white;\n font-size: 12px;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n border: 2px solid var(--primary-color);\n border-radius: 3px;\n\n --md-icon-size: 12px;\n }\n\n [header] {\n background-color: var(--primary-color);\n user-select: none;\n align-items: center;\n color: #eee;\n padding: 0 2px;\n\n display: flex;\n }\n\n md-icon {\n --md-icon-size: 14px;\n\n color: #555;\n align-self: center;\n padding: 0 2px;\n }\n\n [header] md-icon[close] {\n margin-left: auto;\n }\n\n [content] {\n overflow: auto;\n }\n\n table {\n border-collapse: collapse;\n background-color: #fff;\n width: 100%;\n margin: auto;\n }\n\n tr {\n border-bottom: var(--border-dark-color);\n }\n\n td {\n padding: var(--padding-narrow);\n border-right: var(--border-dark-color);\n font-size: 0.8em;\n }\n\n [subTh] {\n text-align: center !important;\n font-weight: bold;\n width: 60px;\n text-transform: capitalize;\n background-color: rgba(0, 0, 0, 0.05);\n }\n\n [split] {\n height: 10px;\n color: #eee;\n background-color: var(--primary-color);\n font-size: 0.8em;\n padding: 0;\n text-align: center;\n }\n\n [location] {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n }\n\n md-linear-progress {\n --md-linear-progress-active-indicator-color: red;\n --md-linear-progress-track-color: #ed788d;\n }\n `\n ]\n\n @property({ type: Object }) component?: any\n @property({ type: Boolean }) playbackMode: boolean = false\n\n @state() detailInfo?: any\n @state() collapsed: boolean = false\n @state() loading: boolean = false\n\n private dragStart?: { x: number; y: number }\n\n private dragEndHandler = this.onDragEnd.bind(this) as EventListener\n private dragMoveHandler = this.onDragMove.bind(this) as EventListener\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.collapsed = sessionStorage.getItem('ox-board-component-info-collapsed') == 'true'\n\n document.addEventListener('mouseup', this.dragEndHandler)\n document.addEventListener('mousemove', this.dragMoveHandler)\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback()\n\n document.removeEventListener('mouseup', this.dragEndHandler)\n document.removeEventListener('mousemove', this.dragMoveHandler)\n }\n\n render() {\n const { state, data } = this.component || {}\n const { id, type } = state || {}\n const details = this.detailInfo || data\n const infos: [key: string, value: string][] =\n details && Object.entries(details).filter(([key, value]) => key != 'ID')\n const identifiable = this.component?.isIdentifiable() || false\n\n return html`\n <div header @mousedown=${this.onDragStart.bind(this)} draggable=\"false\">\n <md-icon @click=${() => (this.collapsed = !this.collapsed)} collapsed\n >${this.collapsed ? 'expand_more' : 'expand_less'}</md-icon\n >\n Object Information\n <md-icon @click=${(e: MouseEvent) => this.dispatchEvent(new CustomEvent('close'))} close>close</md-icon>\n </div>\n ${this.loading\n ? html`<div>\n <md-linear-progress indeterminate></md-linear-progress>\n </div>`\n : nothing}\n\n <div content @wheel=${(e: WheelEvent) => this.onWheel(e)}>\n <table>\n ${identifiable\n ? html`\n <tr>\n <td subTh>\n <div\n location\n @click=${(e: MouseEvent) => {\n this.component.trigger('deco-border', { distance: 8, lineWidth: 4, color: '#f007' })\n this.component.rootModel?.centerTo(this.component, true /* animated */)\n\n return false\n }}\n >\n ${i18next.t('label.id')} <md-icon style=\"color:red;\">location_on</md-icon>\n </div>\n </td>\n <td>${id}</td>\n </tr>\n <tr>\n <td subTh>\n ${i18next.t('label.type')}${!identifiable\n ? html` <md-icon style=\"color:red;\">location_on</md-icon>`\n : html``}\n </td>\n <td>${type}</td>\n </tr>\n `\n : html`\n <tr>\n <td subTh>\n <div\n location\n @click=${(e: MouseEvent) => {\n this.component.trigger('deco-border', { distance: 8, lineWidth: 4, color: '#f007' })\n this.component.rootModel?.centerTo(this.component, true /* animated */)\n\n return false\n }}\n >\n ${i18next.t('label.type')}${!identifiable ? html` <md-icon>location_on</md-icon>` : html``}\n </div>\n </td>\n <td>${type}</td>\n </tr>\n `}\n ${!this.collapsed && infos && !this.loading\n ? html`\n <tr>\n <td split colspan=\"2\">Details</td>\n </tr>\n\n ${infos.map(\n ([key, value]) => html`\n <tr>\n <td subTh>${key}</td>\n <td>${renderInfoValue(key, value)}</td>\n </tr>\n `\n )}\n `\n : nothing}\n </table>\n </div>\n `\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('component')) {\n this.detailInfo = null\n\n if (!this.playbackMode && 'detailInfo' in this.component) {\n try {\n this.loading = true\n this.detailInfo = await this.component.detailInfo()\n } catch (e) {\n console.error('failed to get detail information')\n } finally {\n this.loading = false\n }\n }\n }\n\n if (changes.has('collapsed')) {\n sessionStorage.setItem('ox-board-component-info-collapsed', this.collapsed ? 'true' : 'false')\n }\n }\n\n onWheel(e: WheelEvent) {\n const scrollableDiv = e.currentTarget! as HTMLElement\n const contentDiv = scrollableDiv.querySelector('table')!\n\n // 컨텐츠의 높이와 div의 높이를 비교하여 수평 스크롤을 동작시키거나 수직 스크롤을 동작시킴\n if (contentDiv.offsetHeight > scrollableDiv.offsetHeight) {\n // 수직 스크롤 가능한 경우\n scrollableDiv.scrollTop += e.deltaY\n } else {\n // 수직 스크롤이 없는 경우\n scrollableDiv.scrollLeft += e.deltaY\n }\n }\n\n onDragStart(e: MouseEvent) {\n e.stopPropagation()\n\n if (e.button == 0) {\n this.dragStart = {\n x: e.clientX,\n y: e.clientY\n }\n }\n\n return false\n }\n\n onDragMove(e: Event) {\n if (!this.dragStart) {\n return false\n }\n\n e.stopPropagation()\n e.preventDefault()\n\n var x = (e as MouseEvent).clientX,\n y = (e as MouseEvent).clientY\n\n const dragStart = { x, y }\n\n x -= this.dragStart.x\n y -= this.dragStart.y\n\n this.dragStart = dragStart\n\n this.style.left =\n Math.min(this.parentElement!.offsetWidth - this.offsetWidth, Math.max(0, this.offsetLeft + x)) + 'px'\n this.style.top =\n Math.min(this.parentElement!.offsetHeight - this.offsetHeight, Math.max(0, this.offsetTop + y)) + 'px'\n\n return false\n }\n\n onDragEnd(e: Event) {\n if (this.dragStart) {\n e.stopPropagation()\n e.preventDefault()\n\n delete this.dragStart\n }\n }\n}\n"]}
|