@fmsim/board 2.0.0-beta.99 → 2.0.1

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.
Files changed (62) hide show
  1. package/custom-elements.json +3377 -2770
  2. package/dist/src/board-i18n.d.ts +37 -0
  3. package/dist/src/board-i18n.js +121 -0
  4. package/dist/src/board-i18n.js.map +1 -0
  5. package/dist/src/config/flow-replay.d.ts +14 -0
  6. package/dist/src/config/flow-replay.js +20 -0
  7. package/dist/src/config/flow-replay.js.map +1 -0
  8. package/dist/src/index.d.ts +2 -0
  9. package/dist/src/index.js +2 -0
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/layers/mcs-mouse-event-handler.js +21 -4
  12. package/dist/src/layers/mcs-mouse-event-handler.js.map +1 -1
  13. package/dist/src/layers/movement-layer.d.ts +5 -2
  14. package/dist/src/layers/movement-layer.js +19 -2
  15. package/dist/src/layers/movement-layer.js.map +1 -1
  16. package/dist/src/modeller/bulk-create-dialog.d.ts +12 -1
  17. package/dist/src/modeller/bulk-create-dialog.js +67 -3
  18. package/dist/src/modeller/bulk-create-dialog.js.map +1 -1
  19. package/dist/src/modeller/bulk-create.d.ts +6 -0
  20. package/dist/src/modeller/bulk-create.js +3 -1
  21. package/dist/src/modeller/bulk-create.js.map +1 -1
  22. package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +6 -0
  23. package/dist/src/modeller/component-toolbar/component-toolbar.js +18 -2
  24. package/dist/src/modeller/component-toolbar/component-toolbar.js.map +1 -1
  25. package/dist/src/modeller/edit-toolbar.js +10 -1
  26. package/dist/src/modeller/edit-toolbar.js.map +1 -1
  27. package/dist/src/modeller/property-sidebar/effects/effects.js +3 -2
  28. package/dist/src/modeller/property-sidebar/effects/effects.js.map +1 -1
  29. package/dist/src/modeller/property-sidebar/inspector/inspector-controller.d.ts +9 -1
  30. package/dist/src/modeller/property-sidebar/inspector/inspector-controller.js +34 -4
  31. package/dist/src/modeller/property-sidebar/inspector/inspector-controller.js.map +1 -1
  32. package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.d.ts +2 -0
  33. package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.js +23 -4
  34. package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.js.map +1 -1
  35. package/dist/src/modeller/property-sidebar/inspector/inspector.js +28 -5
  36. package/dist/src/modeller/property-sidebar/inspector/inspector.js.map +1 -1
  37. package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js +12 -3
  38. package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js.map +1 -1
  39. package/dist/src/modeller/property-sidebar/shapes/shapes.js +40 -24
  40. package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -1
  41. package/dist/src/modeller/property-sidebar/specifics/parent-object.d.ts +29 -0
  42. package/dist/src/modeller/property-sidebar/specifics/parent-object.js +74 -0
  43. package/dist/src/modeller/property-sidebar/specifics/parent-object.js.map +1 -0
  44. package/dist/src/modeller/property-sidebar/specifics/specifics.d.ts +4 -2
  45. package/dist/src/modeller/property-sidebar/specifics/specifics.js +13 -31
  46. package/dist/src/modeller/property-sidebar/specifics/specifics.js.map +1 -1
  47. package/dist/src/ox-board-modeller.js +9 -2
  48. package/dist/src/ox-board-modeller.js.map +1 -1
  49. package/dist/src/ox-board-viewer.js +16 -6
  50. package/dist/src/ox-board-viewer.js.map +1 -1
  51. package/dist/src/ox-editor-board-selector.js +4 -2
  52. package/dist/src/ox-editor-board-selector.js.map +1 -1
  53. package/dist/src/ox-playback-controls.d.ts +9 -0
  54. package/dist/src/ox-playback-controls.js +24 -0
  55. package/dist/src/ox-playback-controls.js.map +1 -1
  56. package/dist/src/scene-monitor-renderer.d.ts +10 -0
  57. package/dist/src/scene-monitor-renderer.js +226 -0
  58. package/dist/src/scene-monitor-renderer.js.map +1 -0
  59. package/dist/src/selector/ox-board-selector.js +2 -1
  60. package/dist/src/selector/ox-board-selector.js.map +1 -1
  61. package/dist/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +15 -15
@@ -0,0 +1,74 @@
1
+ /**
2
+ * parentObject 후보 수집 — 속성창(단일 선택)과 bulk-paste 다이얼로그가 공유하는 로직.
3
+ *
4
+ * parentObjectId 는 ParentObjectMixin(capability `parentObjectTypes`) 컴포넌트에서만 의미가
5
+ * 있고, 후보 리스트는 컴포넌트 타입별로 다르다 (parentObjectTypes 로 씬을 훑어 수집).
6
+ * 이 함수들을 (types, root) 로 매개변수화해 두 소비처가 한 구현을 재사용한다.
7
+ */
8
+ import { Component } from '@hatiolab/things-scene';
9
+ /** 대상이 ParentObjectMixin(= parentObjectTypes capability) 을 가졌는지. */
10
+ export function hasParentObject(target) {
11
+ return !!target && 'parentObjectTypes' in target;
12
+ }
13
+ /**
14
+ * template(모델)의 타입으로부터 parentObject 지원 여부 + 후보 리스트 계산 (bulk-paste 용).
15
+ * template 은 라이브 컴포넌트가 아니라 클립보드 모델이므로, 타입 클래스의 임시 인스턴스로
16
+ * parentObjectTypes(클래스 상수 capability)를 읽은 뒤 씬(root)에서 후보를 수집한다.
17
+ */
18
+ export function parentObjectForTemplate(template, root) {
19
+ var _a;
20
+ const type = template === null || template === void 0 ? void 0 : template.type;
21
+ const Clazz = type && Component.register(type);
22
+ if (!Clazz)
23
+ return { has: false, items: [] };
24
+ let tmp;
25
+ try {
26
+ tmp = new Clazz({ type });
27
+ }
28
+ catch (_b) {
29
+ return { has: false, items: [] };
30
+ }
31
+ const has = hasParentObject(tmp);
32
+ const items = has ? collectParentObjectItems(tmp.parentObjectTypes, root) : [];
33
+ try {
34
+ (_a = tmp.dispose) === null || _a === void 0 ? void 0 : _a.call(tmp);
35
+ }
36
+ catch (_c) {
37
+ /* temp 인스턴스 정리 실패는 무시 */
38
+ }
39
+ return { has, items };
40
+ }
41
+ /**
42
+ * parentObject 후보 id 리스트.
43
+ * @param parentObjectTypes 대상 컴포넌트가 부모로 삼을 수 있는 타입들 (빈 배열이면 isMcsMachine 폴백).
44
+ * @param root 씬 루트 (여기서부터 재귀 수집).
45
+ * @param opts.exclude 후보에서 제외할 컴포넌트 (자기 자신 등).
46
+ * @param opts.knownParentId 이미 아는 부모 id — 있으면 후보 맨 앞으로.
47
+ */
48
+ export function collectParentObjectItems(parentObjectTypes, root, opts) {
49
+ if (!root)
50
+ return [];
51
+ const types = Array.isArray(parentObjectTypes) ? parentObjectTypes : [];
52
+ const exclude = opts === null || opts === void 0 ? void 0 : opts.exclude;
53
+ const out = [];
54
+ const visit = (node) => {
55
+ var _a, _b;
56
+ for (const c of (node === null || node === void 0 ? void 0 : node.components) || []) {
57
+ const match = types.length ? types.includes((_a = c.state) === null || _a === void 0 ? void 0 : _a.type) : !!c.isMcsMachine;
58
+ if (match && c !== exclude) {
59
+ const id = (_b = c.state) === null || _b === void 0 ? void 0 : _b.id;
60
+ if (id)
61
+ out.push(String(id));
62
+ }
63
+ visit(c);
64
+ }
65
+ };
66
+ visit(root);
67
+ let ids = [...new Set(out)];
68
+ const knownPid = opts === null || opts === void 0 ? void 0 : opts.knownParentId;
69
+ if (knownPid) {
70
+ ids = [knownPid, ...ids.filter(id => id !== knownPid)];
71
+ }
72
+ return ids;
73
+ }
74
+ //# sourceMappingURL=parent-object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-object.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/specifics/parent-object.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * parentObject 후보 수집 — 속성창(단일 선택)과 bulk-paste 다이얼로그가 공유하는 로직.\n *\n * parentObjectId 는 ParentObjectMixin(capability `parentObjectTypes`) 컴포넌트에서만 의미가\n * 있고, 후보 리스트는 컴포넌트 타입별로 다르다 (parentObjectTypes 로 씬을 훑어 수집).\n * 이 함수들을 (types, root) 로 매개변수화해 두 소비처가 한 구현을 재사용한다.\n */\n\nimport { Component } from '@hatiolab/things-scene'\n\n/** 대상이 ParentObjectMixin(= parentObjectTypes capability) 을 가졌는지. */\nexport function hasParentObject(target: any): boolean {\n return !!target && 'parentObjectTypes' in target\n}\n\n/**\n * template(모델)의 타입으로부터 parentObject 지원 여부 + 후보 리스트 계산 (bulk-paste 용).\n * template 은 라이브 컴포넌트가 아니라 클립보드 모델이므로, 타입 클래스의 임시 인스턴스로\n * parentObjectTypes(클래스 상수 capability)를 읽은 뒤 씬(root)에서 후보를 수집한다.\n */\nexport function parentObjectForTemplate(template: any, root: any): { has: boolean; items: string[] } {\n const type = template?.type\n const Clazz: any = type && (Component as any).register(type)\n if (!Clazz) return { has: false, items: [] }\n\n let tmp: any\n try {\n tmp = new Clazz({ type })\n } catch {\n return { has: false, items: [] }\n }\n\n const has = hasParentObject(tmp)\n const items = has ? collectParentObjectItems(tmp.parentObjectTypes, root) : []\n try {\n tmp.dispose?.()\n } catch {\n /* temp 인스턴스 정리 실패는 무시 */\n }\n return { has, items }\n}\n\n/**\n * parentObject 후보 id 리스트.\n * @param parentObjectTypes 대상 컴포넌트가 부모로 삼을 수 있는 타입들 (빈 배열이면 isMcsMachine 폴백).\n * @param root 씬 루트 (여기서부터 재귀 수집).\n * @param opts.exclude 후보에서 제외할 컴포넌트 (자기 자신 등).\n * @param opts.knownParentId 이미 아는 부모 id — 있으면 후보 맨 앞으로.\n */\nexport function collectParentObjectItems(\n parentObjectTypes: string[] | undefined,\n root: any,\n opts?: { exclude?: any; knownParentId?: string }\n): string[] {\n if (!root) return []\n const types: string[] = Array.isArray(parentObjectTypes) ? parentObjectTypes : []\n const exclude = opts?.exclude\n const out: string[] = []\n const visit = (node: any) => {\n for (const c of node?.components || []) {\n const match = types.length ? types.includes(c.state?.type) : !!c.isMcsMachine\n if (match && c !== exclude) {\n const id = c.state?.id\n if (id) out.push(String(id))\n }\n visit(c)\n }\n }\n visit(root)\n\n let ids = [...new Set(out)]\n const knownPid = opts?.knownParentId\n if (knownPid) {\n ids = [knownPid, ...ids.filter(id => id !== knownPid)]\n }\n return ids\n}\n"]}
@@ -13,6 +13,8 @@ export declare class PropertySpecific extends PropertySpecific_base {
13
13
  selected: Component[];
14
14
  props: any[];
15
15
  propertyEditor: any[];
16
+ /** 3D 비활성 시 requires3d 태그 속성(조명 프리셋 등)을 뺀 목록. */
17
+ private get _visibleProps();
16
18
  private boundINeedSelected;
17
19
  connectedCallback(): void;
18
20
  disconnectedCallback(): void;
@@ -42,8 +44,8 @@ export declare class PropertySpecific extends PropertySpecific_base {
42
44
  /** 선택 컴포넌트가 ParentObjectMixin(= parentObject/parentObjectTypes capability) 인지. */
43
45
  _hasParentObject(selected: Component[]): boolean;
44
46
  /**
45
- * parentObject 후보 — 모델(씬)에서 컴포넌트 타입 기준 수집. 컴포넌트의 parentObjectTypes
46
- * (예: AGV→['AGVLine'], PortFlow→['Port']) 타입만, 빈 배열이면 모든 머신(isMcsMachine). 자기 자신 제외.
47
+ * parentObject 후보 — 씬에서 컴포넌트 타입 기준 수집 (공유 헬퍼 재사용).
48
+ * 실제 부모 컨테이너가 id 를 가지면 그 부모를 후보 맨 위로.
47
49
  */
48
50
  _parentObjectItems(selected: Component[]): string[];
49
51
  _onINeedSelected(e: CustomEvent): void;
@@ -4,11 +4,13 @@
4
4
  import { __decorate } from "tslib";
5
5
  import { css, html } from 'lit';
6
6
  import { property } from 'lit/decorators.js';
7
+ import { isThreedEnabled } from '@hatiolab/things-scene';
7
8
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
8
9
  import { PropertySharedStyle } from '../property-shared-style';
9
10
  import { SpecificPropertiesBuilder } from './specific-properties-builder.js';
10
11
  import { AbstractProperty } from '../abstract-property';
11
12
  import { OxInputEntityId } from '../shapes/ox-input-entity-id';
13
+ import { hasParentObject, collectParentObjectItems } from './parent-object.js';
12
14
  export class PropertySpecific extends ScopedElementsMixin(AbstractProperty) {
13
15
  constructor() {
14
16
  super(...arguments);
@@ -18,6 +20,10 @@ export class PropertySpecific extends ScopedElementsMixin(AbstractProperty) {
18
20
  this.propertyEditor = [];
19
21
  this.boundINeedSelected = this._onINeedSelected.bind(this);
20
22
  }
23
+ /** 3D 비활성 시 requires3d 태그 속성(조명 프리셋 등)을 뺀 목록. */
24
+ get _visibleProps() {
25
+ return isThreedEnabled() ? this.props : (this.props || []).filter(p => !p.requires3d);
26
+ }
21
27
  connectedCallback() {
22
28
  super.connectedCallback();
23
29
  this.addEventListener('i-need-selected', this.boundINeedSelected);
@@ -93,7 +99,7 @@ export class PropertySpecific extends ScopedElementsMixin(AbstractProperty) {
93
99
  </div>
94
100
  </fieldset>
95
101
 
96
- <specific-properties-builder .value=${value} .props=${this.props} .propertyEditor=${this.propertyEditor}>
102
+ <specific-properties-builder .value=${value} .props=${this._visibleProps} .propertyEditor=${this.propertyEditor}>
97
103
  </specific-properties-builder>
98
104
  `;
99
105
  }
@@ -160,42 +166,18 @@ export class PropertySpecific extends ScopedElementsMixin(AbstractProperty) {
160
166
  }
161
167
  /** 선택 컴포넌트가 ParentObjectMixin(= parentObject/parentObjectTypes capability) 인지. */
162
168
  _hasParentObject(selected) {
163
- return (selected === null || selected === void 0 ? void 0 : selected.length) === 1 && 'parentObjectTypes' in selected[0];
169
+ return (selected === null || selected === void 0 ? void 0 : selected.length) === 1 && hasParentObject(selected[0]);
164
170
  }
165
171
  /**
166
- * parentObject 후보 — 모델(씬)에서 컴포넌트 타입 기준 수집. 컴포넌트의 parentObjectTypes
167
- * (예: AGV→['AGVLine'], PortFlow→['Port']) 타입만, 빈 배열이면 모든 머신(isMcsMachine). 자기 자신 제외.
172
+ * parentObject 후보 — 씬에서 컴포넌트 타입 기준 수집 (공유 헬퍼 재사용).
173
+ * 실제 부모 컨테이너가 id 를 가지면 그 부모를 후보 맨 위로.
168
174
  */
169
175
  _parentObjectItems(selected) {
170
176
  var _a, _b;
171
177
  const target = selected === null || selected === void 0 ? void 0 : selected[0];
172
- const root = target === null || target === void 0 ? void 0 : target.root;
173
- if (!root)
174
- return [];
175
- const types = Array.isArray(target.parentObjectTypes) ? target.parentObjectTypes : [];
176
- const out = [];
177
- const visit = (node) => {
178
- var _a, _b;
179
- for (const c of (node === null || node === void 0 ? void 0 : node.components) || []) {
180
- const match = types.length ? types.includes((_a = c.state) === null || _a === void 0 ? void 0 : _a.type) : !!c.isMcsMachine;
181
- if (match && c !== target) {
182
- const id = (_b = c.state) === null || _b === void 0 ? void 0 : _b.id;
183
- if (id)
184
- out.push(String(id));
185
- }
186
- visit(c);
187
- }
188
- };
189
- visit(root);
190
- let ids = [...new Set(out)];
191
- // 실제 부모 컨테이너(루트/레이어 제외)가 id 를 가지면 = parentObject 를 이미 아는 경우.
192
- // 명시 설정 없이도 그 부모를 후보 맨 위로 올려 바로 고를 수 있게 한다.
193
- const parent = target.parent;
194
- const knownPid = parent && !((_a = parent.isRootModel) === null || _a === void 0 ? void 0 : _a.call(parent)) && !(parent.isLayer && parent.isLayer()) ? String(((_b = parent.state) === null || _b === void 0 ? void 0 : _b.id) || '') : '';
195
- if (knownPid) {
196
- ids = [knownPid, ...ids.filter(id => id !== knownPid)];
197
- }
198
- return ids;
178
+ const parent = target === null || target === void 0 ? void 0 : target.parent;
179
+ const knownParentId = parent && !((_a = parent.isRootModel) === null || _a === void 0 ? void 0 : _a.call(parent)) && !(parent.isLayer && parent.isLayer()) ? String(((_b = parent.state) === null || _b === void 0 ? void 0 : _b.id) || '') : '';
180
+ return collectParentObjectItems(target === null || target === void 0 ? void 0 : target.parentObjectTypes, target === null || target === void 0 ? void 0 : target.root, { exclude: target, knownParentId });
199
181
  }
200
182
  _onINeedSelected(e) {
201
183
  e.stopPropagation();
@@ -1 +1 @@
1
- {"version":3,"file":"specifics.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/specifics/specifics.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { PropertySharedStyle } from '../property-shared-style'\nimport { SpecificPropertiesBuilder } from './specific-properties-builder.js'\nimport { AbstractProperty } from '../abstract-property'\nimport { OxInputEntityId } from '../shapes/ox-input-entity-id'\n\nexport class PropertySpecific extends ScopedElementsMixin(AbstractProperty) {\n static styles = [\n PropertySharedStyle,\n css`\n label[component-type] {\n display: block;\n margin: 10px;\n\n text-align: right;\n font: bold 14px var(--theme-font);\n color: var(--primary-color);\n text-transform: capitalize;\n }\n `\n ]\n\n @property({ type: Object }) value: any\n @property({ type: Object }) scene: Scene | null = null\n @property({ type: Array }) selected: Component[] = []\n @property({ type: Array }) props: any[] = []\n @property({ type: Array }) propertyEditor: any[] = []\n\n private boundINeedSelected: any = this._onINeedSelected.bind(this)\n\n connectedCallback() {\n super.connectedCallback()\n\n this.addEventListener('i-need-selected', this.boundINeedSelected)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.removeEventListener('i-need-selected', this.boundINeedSelected)\n }\n\n static get scopedElements() {\n return {\n 'specific-properties-builder': SpecificPropertiesBuilder,\n 'ox-input-entity-id': OxInputEntityId\n }\n }\n\n private _isGroupSelected(): boolean {\n return this.selected?.length > 0 && (this.selected[0] as any).isGroup?.()\n }\n\n render() {\n const selected = this.selected && this.selected[0]\n const value = this.value || {}\n\n if (this._isGroupSelected()) {\n return html`<label component-type>${value.type}</label>`\n }\n\n return html`\n <label component-type>${value.type}</label>\n <fieldset>\n <div class=\"property-grid\">\n ${this._isIdentifiable(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.id\">ID</ox-i18n> </label>\n ${this._idLookupType(this.selected)\n ? html`\n <ox-input-entity-id\n custom-editor\n value-key=\"id\"\n .value=${value.id || ''}\n .entityType=${this._idLookupType(this.selected)}\n .machine=${this._parentMachineId(this.selected)}\n .requireMachine=${!!(this.selected[0] as any).idLookupRequiresMachine}\n ></ox-input-entity-id>\n `\n : html`<input value-key=\"id\" .value=${value.id || ''} />`}\n `\n : html``}\n ${this._hasParentObject(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.parent-object-id\">parent object</ox-i18n> </label>\n <ox-input-entity-id\n custom-editor\n value-key=\"parentObjectId\"\n .value=${value.parentObjectId || ''}\n .localItems=${this._parentObjectItems(this.selected)}\n ></ox-input-entity-id>\n `\n : html``}\n ${this._hasTextProperty(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.text\">Text</ox-i18n> </label>\n <input value-key=\"text\" .value=${value.text || ''} />\n <label> <ox-i18n msgid=\"label.text-format\">Text Format</ox-i18n> </label>\n <input value-key=\"textFormat\" .value=${value.textFormat || ''} list=\"format-list\" />\n <datalist id=\"format-list\">\n <option value=\"#,###.\"></option>\n <option value=\"#,###.#\"></option>\n <option value=\"#,###.0\"></option>\n <option value=\"#,##0.#\"></option>\n <option value=\"#,##0.0\"></option>\n <option value=\"#,##0.0%\"></option>\n </datalist>\n `\n : html``}\n </div>\n </fieldset>\n\n <specific-properties-builder .value=${value} .props=${this.props} .propertyEditor=${this.propertyEditor}>\n </specific-properties-builder>\n `\n }\n\n _onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this._getValueFromEventTarget(element)\n\n this._onAfterValueChange(key, value)\n }\n\n _isIdentifiable(selected: Component[]) {\n if (!selected || selected.length == 0 || selected.length > 1 || (selected[0].isLayer && selected[0].isLayer()))\n return false\n if ((selected[0] as any).isGroup?.())\n return false\n\n return true\n }\n\n /**\n * 단일 선택 컴포넌트의 부모 machine id (unit 의 ID 검색 시 조회조건으로 전달).\n * 부모가 루트 모델/레이어가 아니고 id 를 가지면 그 id 를 반환. 그 외엔 빈 문자열.\n * (shape 탭 PropertyShapes 와 동일한 규칙.)\n */\n _parentMachineId(selected: Component[]): string {\n const target = selected?.length === 1 ? (selected[0] as any) : null\n if (!target) return ''\n // 명시적 parentObjectId(= 부모 머신 id) 우선 — 모델러에 실제 없는 id 라도 그대로 조회조건으로 사용.\n const pid = target.state?.parentObjectId\n if (pid) return String(pid)\n const parent = target.parent\n if (!parent || parent.isRootModel?.() || (parent.isLayer && parent.isLayer())) return ''\n return parent.state?.id || ''\n }\n\n /**\n * 선택 컴포넌트의 id 조회용 타입명 (capability `idLookupType`). 값이 있으면 그 타입으로\n * 검색 에디터, 없으면 plain input — 불필요한 id 리스트 요청을 막는다. 기본은 자기 타입,\n * 특수 케이스는 override. (shape 탭 PropertyShapes 와 동일 규칙.)\n */\n _idLookupType(selected: Component[]): string | undefined {\n if (selected?.length !== 1) return undefined\n if (!this._idLookupEnabled(selected)) return undefined\n return (selected[0] as any).idLookupType\n }\n\n /** Board 루트 속성 state.idLookup 으로 id 룩업 전체 ON/OFF (기본 ON). */\n _idLookupEnabled(selected: Component[]): boolean {\n const root = (selected?.[0] as any)?.root\n return root?.state?.idLookup !== false\n }\n\n _hasTextProperty(selected: Component[]) {\n for (let i = 0; i < selected.length; i++) {\n if (!selected[i].hasTextProperty) return false\n }\n\n return true\n }\n\n /** 선택 컴포넌트가 ParentObjectMixin(= parentObject/parentObjectTypes capability) 인지. */\n _hasParentObject(selected: Component[]): boolean {\n return selected?.length === 1 && 'parentObjectTypes' in (selected[0] as any)\n }\n\n /**\n * parentObject 후보 — 모델(씬)에서 컴포넌트 타입 기준 수집. 컴포넌트의 parentObjectTypes\n * (예: AGV→['AGVLine'], PortFlow→['Port']) 타입만, 빈 배열이면 모든 머신(isMcsMachine). 자기 자신 제외.\n */\n _parentObjectItems(selected: Component[]): string[] {\n const target = selected?.[0] as any\n const root = target?.root\n if (!root) return []\n const types: string[] = Array.isArray(target.parentObjectTypes) ? target.parentObjectTypes : []\n const out: string[] = []\n const visit = (node: any) => {\n for (const c of node?.components || []) {\n const match = types.length ? types.includes(c.state?.type) : !!c.isMcsMachine\n if (match && c !== target) {\n const id = c.state?.id\n if (id) out.push(String(id))\n }\n visit(c)\n }\n }\n visit(root)\n\n let ids = [...new Set(out)]\n\n // 실제 부모 컨테이너(루트/레이어 제외)가 id 를 가지면 = parentObject 를 이미 아는 경우.\n // 명시 설정 없이도 그 부모를 후보 맨 위로 올려 바로 고를 수 있게 한다.\n const parent = target.parent\n const knownPid =\n parent && !parent.isRootModel?.() && !(parent.isLayer && parent.isLayer()) ? String(parent.state?.id || '') : ''\n if (knownPid) {\n ids = [knownPid, ...ids.filter(id => id !== knownPid)]\n }\n\n return ids\n }\n\n _onINeedSelected(e: CustomEvent) {\n e.stopPropagation()\n\n var { callback } = e.detail\n\n this.scene!.undoableChange(() => {\n callback.call(null, this.selected)\n })\n }\n}\n"]}
1
+ {"version":3,"file":"specifics.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/specifics/specifics.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component, Scene, isThreedEnabled } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { PropertySharedStyle } from '../property-shared-style'\nimport { SpecificPropertiesBuilder } from './specific-properties-builder.js'\nimport { AbstractProperty } from '../abstract-property'\nimport { OxInputEntityId } from '../shapes/ox-input-entity-id'\nimport { hasParentObject, collectParentObjectItems } from './parent-object.js'\n\nexport class PropertySpecific extends ScopedElementsMixin(AbstractProperty) {\n static styles = [\n PropertySharedStyle,\n css`\n label[component-type] {\n display: block;\n margin: 10px;\n\n text-align: right;\n font: bold 14px var(--theme-font);\n color: var(--primary-color);\n text-transform: capitalize;\n }\n `\n ]\n\n @property({ type: Object }) value: any\n @property({ type: Object }) scene: Scene | null = null\n @property({ type: Array }) selected: Component[] = []\n @property({ type: Array }) props: any[] = []\n @property({ type: Array }) propertyEditor: any[] = []\n /** 3D 비활성 시 requires3d 태그 속성(조명 프리셋 등)을 뺀 목록. */\n private get _visibleProps(): any[] {\n return isThreedEnabled() ? this.props : (this.props || []).filter(p => !p.requires3d)\n }\n\n private boundINeedSelected: any = this._onINeedSelected.bind(this)\n\n connectedCallback() {\n super.connectedCallback()\n\n this.addEventListener('i-need-selected', this.boundINeedSelected)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.removeEventListener('i-need-selected', this.boundINeedSelected)\n }\n\n static get scopedElements() {\n return {\n 'specific-properties-builder': SpecificPropertiesBuilder,\n 'ox-input-entity-id': OxInputEntityId\n }\n }\n\n private _isGroupSelected(): boolean {\n return this.selected?.length > 0 && (this.selected[0] as any).isGroup?.()\n }\n\n render() {\n const selected = this.selected && this.selected[0]\n const value = this.value || {}\n\n if (this._isGroupSelected()) {\n return html`<label component-type>${value.type}</label>`\n }\n\n return html`\n <label component-type>${value.type}</label>\n <fieldset>\n <div class=\"property-grid\">\n ${this._isIdentifiable(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.id\">ID</ox-i18n> </label>\n ${this._idLookupType(this.selected)\n ? html`\n <ox-input-entity-id\n custom-editor\n value-key=\"id\"\n .value=${value.id || ''}\n .entityType=${this._idLookupType(this.selected)}\n .machine=${this._parentMachineId(this.selected)}\n .requireMachine=${!!(this.selected[0] as any).idLookupRequiresMachine}\n ></ox-input-entity-id>\n `\n : html`<input value-key=\"id\" .value=${value.id || ''} />`}\n `\n : html``}\n ${this._hasParentObject(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.parent-object-id\">parent object</ox-i18n> </label>\n <ox-input-entity-id\n custom-editor\n value-key=\"parentObjectId\"\n .value=${value.parentObjectId || ''}\n .localItems=${this._parentObjectItems(this.selected)}\n ></ox-input-entity-id>\n `\n : html``}\n ${this._hasTextProperty(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.text\">Text</ox-i18n> </label>\n <input value-key=\"text\" .value=${value.text || ''} />\n <label> <ox-i18n msgid=\"label.text-format\">Text Format</ox-i18n> </label>\n <input value-key=\"textFormat\" .value=${value.textFormat || ''} list=\"format-list\" />\n <datalist id=\"format-list\">\n <option value=\"#,###.\"></option>\n <option value=\"#,###.#\"></option>\n <option value=\"#,###.0\"></option>\n <option value=\"#,##0.#\"></option>\n <option value=\"#,##0.0\"></option>\n <option value=\"#,##0.0%\"></option>\n </datalist>\n `\n : html``}\n </div>\n </fieldset>\n\n <specific-properties-builder .value=${value} .props=${this._visibleProps} .propertyEditor=${this.propertyEditor}>\n </specific-properties-builder>\n `\n }\n\n _onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this._getValueFromEventTarget(element)\n\n this._onAfterValueChange(key, value)\n }\n\n _isIdentifiable(selected: Component[]) {\n if (!selected || selected.length == 0 || selected.length > 1 || (selected[0].isLayer && selected[0].isLayer()))\n return false\n if ((selected[0] as any).isGroup?.())\n return false\n\n return true\n }\n\n /**\n * 단일 선택 컴포넌트의 부모 machine id (unit 의 ID 검색 시 조회조건으로 전달).\n * 부모가 루트 모델/레이어가 아니고 id 를 가지면 그 id 를 반환. 그 외엔 빈 문자열.\n * (shape 탭 PropertyShapes 와 동일한 규칙.)\n */\n _parentMachineId(selected: Component[]): string {\n const target = selected?.length === 1 ? (selected[0] as any) : null\n if (!target) return ''\n // 명시적 parentObjectId(= 부모 머신 id) 우선 — 모델러에 실제 없는 id 라도 그대로 조회조건으로 사용.\n const pid = target.state?.parentObjectId\n if (pid) return String(pid)\n const parent = target.parent\n if (!parent || parent.isRootModel?.() || (parent.isLayer && parent.isLayer())) return ''\n return parent.state?.id || ''\n }\n\n /**\n * 선택 컴포넌트의 id 조회용 타입명 (capability `idLookupType`). 값이 있으면 그 타입으로\n * 검색 에디터, 없으면 plain input — 불필요한 id 리스트 요청을 막는다. 기본은 자기 타입,\n * 특수 케이스는 override. (shape 탭 PropertyShapes 와 동일 규칙.)\n */\n _idLookupType(selected: Component[]): string | undefined {\n if (selected?.length !== 1) return undefined\n if (!this._idLookupEnabled(selected)) return undefined\n return (selected[0] as any).idLookupType\n }\n\n /** Board 루트 속성 state.idLookup 으로 id 룩업 전체 ON/OFF (기본 ON). */\n _idLookupEnabled(selected: Component[]): boolean {\n const root = (selected?.[0] as any)?.root\n return root?.state?.idLookup !== false\n }\n\n _hasTextProperty(selected: Component[]) {\n for (let i = 0; i < selected.length; i++) {\n if (!selected[i].hasTextProperty) return false\n }\n\n return true\n }\n\n /** 선택 컴포넌트가 ParentObjectMixin(= parentObject/parentObjectTypes capability) 인지. */\n _hasParentObject(selected: Component[]): boolean {\n return selected?.length === 1 && hasParentObject(selected[0])\n }\n\n /**\n * parentObject 후보 — 씬에서 컴포넌트 타입 기준 수집 (공유 헬퍼 재사용).\n * 실제 부모 컨테이너가 id 를 가지면 그 부모를 후보 맨 위로.\n */\n _parentObjectItems(selected: Component[]): string[] {\n const target = selected?.[0] as any\n const parent = target?.parent\n const knownParentId =\n parent && !parent.isRootModel?.() && !(parent.isLayer && parent.isLayer()) ? String(parent.state?.id || '') : ''\n return collectParentObjectItems(target?.parentObjectTypes, target?.root, { exclude: target, knownParentId })\n }\n\n _onINeedSelected(e: CustomEvent) {\n e.stopPropagation()\n\n var { callback } = e.detail\n\n this.scene!.undoableChange(() => {\n callback.call(null, this.selected)\n })\n }\n}\n"]}
@@ -10,12 +10,13 @@ import './ox-board-viewer';
10
10
  import { saveAs } from 'file-saver';
11
11
  import { css, html, LitElement } from 'lit';
12
12
  import { customElement, property, query } from 'lit/decorators.js';
13
- import { LoadingOverlay, SCENE_MODE } from '@hatiolab/things-scene';
13
+ import { LoadingOverlay, SCENE_MODE, dataLagTracker } from '@hatiolab/things-scene';
14
14
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
15
15
  import { OxPopup } from '@operato/popup';
16
16
  import { isMacOS, togglefullscreen } from '@operato/utils';
17
17
  import { navigate } from '@operato/shell';
18
18
  import { ComponentToolbar } from './modeller/component-toolbar/component-toolbar';
19
+ import { SceneMonitorRenderer } from './scene-monitor-renderer';
19
20
  import { EditToolbar } from './modeller/edit-toolbar';
20
21
  import { PropertySidebar } from './modeller/property-sidebar/property-sidebar';
21
22
  const MACOS = isMacOS();
@@ -108,11 +109,17 @@ let BoardModeller = class BoardModeller extends ScopedElementsMixin(LitElement)
108
109
  };
109
110
  }
110
111
  updated(changes) {
112
+ var _a;
111
113
  if (changes.has('loadTracker') && this.loadTracker) {
112
114
  if (!this._loadingOverlay) {
113
115
  this._loadingOverlay = new LoadingOverlay();
116
+ this._loadingOverlay.renderer = new SceneMonitorRenderer();
114
117
  }
115
- this._loadingOverlay.attach(this.renderRoot, this.loadTracker);
118
+ this._loadingOverlay.attach(this.renderRoot, this.loadTracker, dataLagTracker);
119
+ }
120
+ // M키 로딩 오버레이(scene 내장)에 fmsim Scene Monitor 렌더러 주입.
121
+ if (changes.has('scene') && ((_a = this.scene) === null || _a === void 0 ? void 0 : _a.loadingOverlay)) {
122
+ this.scene.loadingOverlay.renderer = new SceneMonitorRenderer();
116
123
  }
117
124
  }
118
125
  render() {
@@ -1 +1 @@
1
- {"version":3,"file":"ox-board-modeller.js","sourceRoot":"","sources":["../../src/ox-board-modeller.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/fab/fab.js'\nimport '@material/web/icon/icon.js'\n\nimport '@hatiolab/things-scene'\nimport './modeller/scene-viewer/ox-scene-handler.js'\nimport './modeller/scene-viewer/ox-scene-layer.js'\nimport './modeller/scene-viewer/ox-scene-property.js'\nimport './modeller/scene-viewer/ox-scene-viewer.js'\nimport './ox-board-viewer'\n\nimport { saveAs } from 'file-saver'\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { LoadTracker, LoadingOverlay, Scene, SCENE_MODE, SceneMode } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { OxPopup } from '@operato/popup'\nimport { isMacOS, togglefullscreen } from '@operato/utils'\nimport { navigate } from '@operato/shell'\n\nimport { ComponentToolbar } from './modeller/component-toolbar/component-toolbar'\nimport { EditToolbar } from './modeller/edit-toolbar'\nimport { PropertySidebar } from './modeller/property-sidebar/property-sidebar'\nimport { ComponentGroup, ComponentTemplate } from './types'\n\nconst MACOS = isMacOS()\n\nconst ICON_PROPERTIES = new URL('../../icons/icon-properties.png', import.meta.url).href\nconst ICON_PROPERTIES_LINE_TYPE = new URL('../../icons/icon-properties-line-type.png', import.meta.url).href\nconst ICON_PROPERTIES_ARROW_TYPE = new URL('../../icons/icon-properties-arrow-type.png', import.meta.url).href\nconst ICON_PROPERTIES_LABEL = new URL('../../icons/icon-properties-label.png', import.meta.url).href\nconst ICON_PROPERTIES_PADDING = new URL('../../icons/icon-properties-padding.png', import.meta.url).href\n\nconst ICON_HTOOLBAR = new URL('../../icons/icon-htoolbar.png', import.meta.url).href\nconst ICON_FULLSCREEN = new URL('../../icons/icon-fullscreen.png', import.meta.url).href\nconst ICON_COLLAPSE = new URL('../../icons/icon-collapse.png', import.meta.url).href\nconst ICON_COLLAPSE_ACTIVE = new URL('../../icons/icon-collapse-active.png', import.meta.url).href\n\nconst ICON_SHELL_INSPECTOR = new URL('../../icons/icon-shell-inspector.png', import.meta.url).href\n\nvar Registry: ComponentGroup[] = []\n\n@customElement('ox-board-modeller')\nexport class BoardModeller extends ScopedElementsMixin(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n height: 100%;\n overflow: hidden;\n\n font-family: 'Pretendard', 'Segoe UI', sans-serif;\n }\n\n edit-toolbar {\n flex: 45px;\n max-height: 45px;\n overflow: hidden;\n }\n\n div[content] {\n flex: 1;\n max-height: calc(100% - 45px);\n\n display: flex;\n flex-direction: row;\n }\n\n component-toolbar {\n max-height: 100%;\n }\n\n property-sidebar {\n overflow: hidden;\n }\n\n #scene-wrap {\n position: relative;\n\n flex: 1;\n display: flex;\n flex-direction: row;\n }\n\n ox-scene-viewer {\n flex: 1;\n width: 100%;\n height: 100%;\n }\n\n md-fab {\n position: absolute;\n right: 15px;\n bottom: 15px;\n z-index: 1000;\n }\n\n\n [brand] {\n display: flex;\n white-space: nowrap;\n flex-direction: row;\n align-items: center;\n gap: 3px;\n }\n `\n ]\n\n static registerGroup(group: ComponentGroup) {\n var found = Registry.find(inRegisterGroup => inRegisterGroup.name == group.name)\n\n if (found) {\n found = {\n ...found,\n ...group\n }\n } else {\n Registry.push(group)\n }\n }\n\n static registerTemplate(templates: ComponentTemplate[]): void {\n templates &&\n templates.forEach(template => {\n var groups: string[] = typeof template.group == 'string' ? [template.group] : template.group\n\n Registry.filter(group => groups.includes(group.name)).forEach(group => {\n if (!group.templates.find(inGroupTemplate => inGroupTemplate.type == template.type)) {\n group.templates.push(template)\n }\n })\n })\n }\n\n static get groups(): ComponentGroup[] {\n return Registry\n }\n\n static getGroup(name: string) {\n return Registry.find(group => group.name === name)\n }\n\n @property({ type: String }) boardName: string = ''\n @property({ type: Object }) model: any = null\n @property({ type: String }) baseUrl: string = ''\n @property({ type: Array }) selected: any[] = []\n @property({ type: Number }) mode: SceneMode = SCENE_MODE.EDIT\n @property({ type: Object }) provider: any = null\n @property({ type: Boolean }) hideProperty: boolean = false\n @property({ type: String }) overlay: string = ''\n @property({ type: Object }) scene?: Scene\n @property({ type: Object }) loadTracker?: LoadTracker\n @property({ type: Array }) componentGroupList: any[] = []\n @property({ type: Array }) fonts: any[] = []\n @property({ type: Object }) themes: any = null\n @property({ type: Array }) propertyEditor: any[] = []\n\n @query('edit-toolbar') private editToolbar!: EditToolbar\n\n private group: string = ''\n private shortcutHandler?: (e: KeyboardEvent) => void\n private _loadingOverlay?: LoadingOverlay\n\n constructor() {\n super()\n\n document.addEventListener('get-all-scene-component-ids', (e: Event) => {\n var { component, callback } = (e as CustomEvent).detail\n\n if (!this.scene) return\n\n var ids\n if (component) {\n ids = this.scene.findAll(component).map((c: any) => c.model.id)\n } else {\n ids = this.scene.ids.map(({ key }: { key: string }) => key)\n }\n\n ids = ids.filter(Boolean).sort()\n callback(ids)\n })\n\n this.style.setProperty('--url-icon-properties', `url(${ICON_PROPERTIES})`)\n this.style.setProperty('--url-icon-properties-label', `url(${ICON_PROPERTIES_LABEL})`)\n this.style.setProperty('--url-icon-properties-padding', `url(${ICON_PROPERTIES_PADDING})`)\n this.style.setProperty('--url-icon-properties-line-type', `url(${ICON_PROPERTIES_LINE_TYPE})`)\n this.style.setProperty('--url-icon-properties-arrow-type', `url(${ICON_PROPERTIES_ARROW_TYPE})`)\n\n this.style.setProperty('--url-icon-htoolbar', `url(${ICON_HTOOLBAR})`)\n this.style.setProperty('--url-icon-fullscreen', `url(${ICON_FULLSCREEN})`)\n this.style.setProperty('--url-icon-collapse', `url(${ICON_COLLAPSE})`)\n this.style.setProperty('--url-icon-collapse-active', `url(${ICON_COLLAPSE_ACTIVE})`)\n\n this.style.setProperty('--url-icon-shell-inspector', `url(${ICON_SHELL_INSPECTOR})`)\n }\n\n static get scopedElements() {\n return {\n 'edit-toolbar': EditToolbar,\n 'property-sidebar': PropertySidebar,\n 'component-toolbar': ComponentToolbar\n }\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('loadTracker') && this.loadTracker) {\n if (!this._loadingOverlay) {\n this._loadingOverlay = new LoadingOverlay()\n }\n this._loadingOverlay.attach(this.renderRoot as HTMLElement, this.loadTracker)\n }\n }\n\n render() {\n return html`\n <edit-toolbar\n .scene=${this.scene}\n .selected=${this.selected}\n @hide-property-changed=${(e: CustomEvent) => (this.hideProperty = e.detail.value)}\n @open-preview=${() => this.preview()}\n @download-model=${() => this.downloadModel()}\n @modeller-fullscreen=${() => togglefullscreen(this)}\n >\n ${this.renderBrandingZone()}\n </edit-toolbar>\n\n <div content>\n <component-toolbar\n .scene=${this.scene}\n .mode=${this.mode}\n @mode-changed=${(e: CustomEvent) => {\n this.mode = e.detail.value\n }}\n .componentGroupList=${this.componentGroupList}\n .group=${this.group}\n >\n </component-toolbar>\n\n <div id=\"scene-wrap\">\n <ox-scene-viewer\n id=\"scene\"\n .scene=${this.scene}\n .loadTracker=${this.loadTracker}\n @scene-changed=${(e: CustomEvent) => {\n this.scene = e.detail.value\n }}\n .model=${this.model}\n .themes=${this.themes}\n .selected=${this.selected}\n @selected-changed=${(e: CustomEvent) => {\n this.selected = e.detail.value\n }}\n .mode=${this.mode}\n @mode-changed=${(e: CustomEvent) => {\n this.mode = e.detail.value\n }}\n fit=\"ratio\"\n .baseUrl=${this.baseUrl}\n @contextmenu=${() => this.onContextMenu()}\n .provider=${this.provider}\n name=\"modeller\"\n >\n <ox-scene-layer type=\"snap-guide-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"selection-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"modeling-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"add-layer\"> </ox-scene-layer>\n <ox-scene-layer type=\"shift-layer\">\n <ox-scene-property name=\"text\" value=\"${this.overlay}\"></ox-scene-property>\n <ox-scene-property name=\"alpha\" value=\"0.3\"></ox-scene-property>\n <ox-scene-property name=\"fontFamily\" value=\"arial\"></ox-scene-property>\n <ox-scene-property name=\"fontSize\" value=\"30\" type=\"number\"></ox-scene-property>\n <ox-scene-property name=\"fontColor\" value=\"navy\"></ox-scene-property>\n <ox-scene-property name=\"textBaseline\" value=\"top\"></ox-scene-property>\n <ox-scene-property name=\"textAlign\" value=\"left\"></ox-scene-property>\n <ox-scene-property name=\"paddingTop\" value=\"50\" type=\"number\"></ox-scene-property>\n <ox-scene-property name=\"paddingLeft\" value=\"50\" type=\"number\"></ox-scene-property>\n </ox-scene-layer>\n <ox-scene-handler type=\"text-editor\"></ox-scene-handler>\n <ox-scene-handler type=\"move-handler\"></ox-scene-handler>\n </ox-scene-viewer>\n\n <md-fab @click=${() => this.onTapSave()} title=\"save\"><md-icon slot=\"icon\">save</md-icon></md-fab>\n </div>\n\n <property-sidebar\n .scene=${this.scene}\n .selected=${this.selected}\n .collapsed=${this.hideProperty}\n .fonts=${this.fonts}\n .propertyEditor=${this.propertyEditor}\n >\n </property-sidebar>\n </div>\n `\n }\n\n connectedCallback(): void {\n super.connectedCallback()\n this.bindShortcutEvent()\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback()\n this.unbindShortcutEvent()\n }\n\n close() {\n this.model = null\n this.requestUpdate()\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n switch (e.code) {\n case 'KeyS':\n if (ctrlKey) {\n this.onTapSave()\n e.preventDefault()\n }\n break\n }\n }\n\n preview() {\n const board = {\n id: 'preview',\n model: this.scene?.model ? JSON.parse(JSON.stringify(this.scene.model)) : null,\n style: this.scene?.rootContainer.style\n }\n\n OxPopup.open({\n template: html`\n <ox-board-viewer\n style=\"width:100%;height:100%;background:white;\"\n .provider=${this.provider}\n .board=${board}\n ></ox-board-viewer>\n `,\n style: 'width:90vw;height:90vh;',\n backdrop: true,\n preventCloseOnBlur: true\n })\n\n requestAnimationFrame(() => {\n dispatchEvent(new Event('resize'))\n })\n }\n\n downloadModel() {\n if (!this.scene) return\n\n var model = JSON.stringify(this.model, null, 2)\n var filename = (this.boardName || 'NONAME') + '-' + Date.now() + '.json'\n saveAs(new Blob([model], { type: 'application/octet-stream' }), filename)\n }\n\n renderBrandingZone() {\n return html`\n <div brand>\n <md-icon\n @click=${() => {\n navigate('board-list')\n return false\n }}\n >home</md-icon\n >\n <div board_name>${this.boardName}</div>\n </div>\n `\n }\n\n onTapSave() {\n this.dispatchEvent(new CustomEvent('save-model', { bubbles: true, composed: true, detail: { model: this.model } }))\n }\n\n bindShortcutEvent() {\n // TODO: Global Hotkey에 대한 정의를 edit-toolbar에서 가져올 수 있도록 수정해야 함.\n const GLOBAL_HOTKEYS = ['Digit1', 'Digit2', 'F11', 'KeyD', 'KeyP', 'KeyS']\n\n this.shortcutHandler = (e: KeyboardEvent) => {\n const target = e.composedPath()[0] as HTMLElement\n var tagName = target.tagName\n var isInput = target.isContentEditable || tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA'\n var isGlobalHotkey = GLOBAL_HOTKEYS.includes(e.code)\n\n if (!isGlobalHotkey && isInput) return\n if (!this.editToolbar.onShortcut(e)) this.onShortcut(e)\n }\n\n document.addEventListener('keydown', this.shortcutHandler)\n }\n\n unbindShortcutEvent() {\n if (this.shortcutHandler) {\n document.removeEventListener('keydown', this.shortcutHandler)\n delete this.shortcutHandler\n }\n }\n\n onContextMenu() {}\n}\n"]}
1
+ {"version":3,"file":"ox-board-modeller.js","sourceRoot":"","sources":["../../src/ox-board-modeller.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/fab/fab.js'\nimport '@material/web/icon/icon.js'\n\nimport '@hatiolab/things-scene'\nimport './modeller/scene-viewer/ox-scene-handler.js'\nimport './modeller/scene-viewer/ox-scene-layer.js'\nimport './modeller/scene-viewer/ox-scene-property.js'\nimport './modeller/scene-viewer/ox-scene-viewer.js'\nimport './ox-board-viewer'\n\nimport { saveAs } from 'file-saver'\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { LoadTracker, LoadingOverlay, Scene, SCENE_MODE, SceneMode, dataLagTracker } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { OxPopup } from '@operato/popup'\nimport { isMacOS, togglefullscreen } from '@operato/utils'\nimport { navigate } from '@operato/shell'\n\nimport { ComponentToolbar } from './modeller/component-toolbar/component-toolbar'\nimport { SceneMonitorRenderer } from './scene-monitor-renderer'\nimport { EditToolbar } from './modeller/edit-toolbar'\nimport { PropertySidebar } from './modeller/property-sidebar/property-sidebar'\nimport { ComponentGroup, ComponentTemplate } from './types'\n\nconst MACOS = isMacOS()\n\nconst ICON_PROPERTIES = new URL('../../icons/icon-properties.png', import.meta.url).href\nconst ICON_PROPERTIES_LINE_TYPE = new URL('../../icons/icon-properties-line-type.png', import.meta.url).href\nconst ICON_PROPERTIES_ARROW_TYPE = new URL('../../icons/icon-properties-arrow-type.png', import.meta.url).href\nconst ICON_PROPERTIES_LABEL = new URL('../../icons/icon-properties-label.png', import.meta.url).href\nconst ICON_PROPERTIES_PADDING = new URL('../../icons/icon-properties-padding.png', import.meta.url).href\n\nconst ICON_HTOOLBAR = new URL('../../icons/icon-htoolbar.png', import.meta.url).href\nconst ICON_FULLSCREEN = new URL('../../icons/icon-fullscreen.png', import.meta.url).href\nconst ICON_COLLAPSE = new URL('../../icons/icon-collapse.png', import.meta.url).href\nconst ICON_COLLAPSE_ACTIVE = new URL('../../icons/icon-collapse-active.png', import.meta.url).href\n\nconst ICON_SHELL_INSPECTOR = new URL('../../icons/icon-shell-inspector.png', import.meta.url).href\n\nvar Registry: ComponentGroup[] = []\n\n@customElement('ox-board-modeller')\nexport class BoardModeller extends ScopedElementsMixin(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n height: 100%;\n overflow: hidden;\n\n font-family: 'Pretendard', 'Segoe UI', sans-serif;\n }\n\n edit-toolbar {\n flex: 45px;\n max-height: 45px;\n overflow: hidden;\n }\n\n div[content] {\n flex: 1;\n max-height: calc(100% - 45px);\n\n display: flex;\n flex-direction: row;\n }\n\n component-toolbar {\n max-height: 100%;\n }\n\n property-sidebar {\n overflow: hidden;\n }\n\n #scene-wrap {\n position: relative;\n\n flex: 1;\n display: flex;\n flex-direction: row;\n }\n\n ox-scene-viewer {\n flex: 1;\n width: 100%;\n height: 100%;\n }\n\n md-fab {\n position: absolute;\n right: 15px;\n bottom: 15px;\n z-index: 1000;\n }\n\n\n [brand] {\n display: flex;\n white-space: nowrap;\n flex-direction: row;\n align-items: center;\n gap: 3px;\n }\n `\n ]\n\n static registerGroup(group: ComponentGroup) {\n var found = Registry.find(inRegisterGroup => inRegisterGroup.name == group.name)\n\n if (found) {\n found = {\n ...found,\n ...group\n }\n } else {\n Registry.push(group)\n }\n }\n\n static registerTemplate(templates: ComponentTemplate[]): void {\n templates &&\n templates.forEach(template => {\n var groups: string[] = typeof template.group == 'string' ? [template.group] : template.group\n\n Registry.filter(group => groups.includes(group.name)).forEach(group => {\n if (!group.templates.find(inGroupTemplate => inGroupTemplate.type == template.type)) {\n group.templates.push(template)\n }\n })\n })\n }\n\n static get groups(): ComponentGroup[] {\n return Registry\n }\n\n static getGroup(name: string) {\n return Registry.find(group => group.name === name)\n }\n\n @property({ type: String }) boardName: string = ''\n @property({ type: Object }) model: any = null\n @property({ type: String }) baseUrl: string = ''\n @property({ type: Array }) selected: any[] = []\n @property({ type: Number }) mode: SceneMode = SCENE_MODE.EDIT\n @property({ type: Object }) provider: any = null\n @property({ type: Boolean }) hideProperty: boolean = false\n @property({ type: String }) overlay: string = ''\n @property({ type: Object }) scene?: Scene\n @property({ type: Object }) loadTracker?: LoadTracker\n @property({ type: Array }) componentGroupList: any[] = []\n @property({ type: Array }) fonts: any[] = []\n @property({ type: Object }) themes: any = null\n @property({ type: Array }) propertyEditor: any[] = []\n\n @query('edit-toolbar') private editToolbar!: EditToolbar\n\n private group: string = ''\n private shortcutHandler?: (e: KeyboardEvent) => void\n private _loadingOverlay?: LoadingOverlay\n\n constructor() {\n super()\n\n document.addEventListener('get-all-scene-component-ids', (e: Event) => {\n var { component, callback } = (e as CustomEvent).detail\n\n if (!this.scene) return\n\n var ids\n if (component) {\n ids = this.scene.findAll(component).map((c: any) => c.model.id)\n } else {\n ids = this.scene.ids.map(({ key }: { key: string }) => key)\n }\n\n ids = ids.filter(Boolean).sort()\n callback(ids)\n })\n\n this.style.setProperty('--url-icon-properties', `url(${ICON_PROPERTIES})`)\n this.style.setProperty('--url-icon-properties-label', `url(${ICON_PROPERTIES_LABEL})`)\n this.style.setProperty('--url-icon-properties-padding', `url(${ICON_PROPERTIES_PADDING})`)\n this.style.setProperty('--url-icon-properties-line-type', `url(${ICON_PROPERTIES_LINE_TYPE})`)\n this.style.setProperty('--url-icon-properties-arrow-type', `url(${ICON_PROPERTIES_ARROW_TYPE})`)\n\n this.style.setProperty('--url-icon-htoolbar', `url(${ICON_HTOOLBAR})`)\n this.style.setProperty('--url-icon-fullscreen', `url(${ICON_FULLSCREEN})`)\n this.style.setProperty('--url-icon-collapse', `url(${ICON_COLLAPSE})`)\n this.style.setProperty('--url-icon-collapse-active', `url(${ICON_COLLAPSE_ACTIVE})`)\n\n this.style.setProperty('--url-icon-shell-inspector', `url(${ICON_SHELL_INSPECTOR})`)\n }\n\n static get scopedElements() {\n return {\n 'edit-toolbar': EditToolbar,\n 'property-sidebar': PropertySidebar,\n 'component-toolbar': ComponentToolbar\n }\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('loadTracker') && this.loadTracker) {\n if (!this._loadingOverlay) {\n this._loadingOverlay = new LoadingOverlay()\n this._loadingOverlay.renderer = new SceneMonitorRenderer()\n }\n this._loadingOverlay.attach(this.renderRoot as HTMLElement, this.loadTracker, dataLagTracker)\n }\n // M키 로딩 오버레이(scene 내장)에 fmsim Scene Monitor 렌더러 주입.\n if (changes.has('scene') && this.scene?.loadingOverlay) {\n this.scene.loadingOverlay.renderer = new SceneMonitorRenderer()\n }\n }\n\n render() {\n return html`\n <edit-toolbar\n .scene=${this.scene}\n .selected=${this.selected}\n @hide-property-changed=${(e: CustomEvent) => (this.hideProperty = e.detail.value)}\n @open-preview=${() => this.preview()}\n @download-model=${() => this.downloadModel()}\n @modeller-fullscreen=${() => togglefullscreen(this)}\n >\n ${this.renderBrandingZone()}\n </edit-toolbar>\n\n <div content>\n <component-toolbar\n .scene=${this.scene}\n .mode=${this.mode}\n @mode-changed=${(e: CustomEvent) => {\n this.mode = e.detail.value\n }}\n .componentGroupList=${this.componentGroupList}\n .group=${this.group}\n >\n </component-toolbar>\n\n <div id=\"scene-wrap\">\n <ox-scene-viewer\n id=\"scene\"\n .scene=${this.scene}\n .loadTracker=${this.loadTracker}\n @scene-changed=${(e: CustomEvent) => {\n this.scene = e.detail.value\n }}\n .model=${this.model}\n .themes=${this.themes}\n .selected=${this.selected}\n @selected-changed=${(e: CustomEvent) => {\n this.selected = e.detail.value\n }}\n .mode=${this.mode}\n @mode-changed=${(e: CustomEvent) => {\n this.mode = e.detail.value\n }}\n fit=\"ratio\"\n .baseUrl=${this.baseUrl}\n @contextmenu=${() => this.onContextMenu()}\n .provider=${this.provider}\n name=\"modeller\"\n >\n <ox-scene-layer type=\"snap-guide-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"selection-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"modeling-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"add-layer\"> </ox-scene-layer>\n <ox-scene-layer type=\"shift-layer\">\n <ox-scene-property name=\"text\" value=\"${this.overlay}\"></ox-scene-property>\n <ox-scene-property name=\"alpha\" value=\"0.3\"></ox-scene-property>\n <ox-scene-property name=\"fontFamily\" value=\"arial\"></ox-scene-property>\n <ox-scene-property name=\"fontSize\" value=\"30\" type=\"number\"></ox-scene-property>\n <ox-scene-property name=\"fontColor\" value=\"navy\"></ox-scene-property>\n <ox-scene-property name=\"textBaseline\" value=\"top\"></ox-scene-property>\n <ox-scene-property name=\"textAlign\" value=\"left\"></ox-scene-property>\n <ox-scene-property name=\"paddingTop\" value=\"50\" type=\"number\"></ox-scene-property>\n <ox-scene-property name=\"paddingLeft\" value=\"50\" type=\"number\"></ox-scene-property>\n </ox-scene-layer>\n <ox-scene-handler type=\"text-editor\"></ox-scene-handler>\n <ox-scene-handler type=\"move-handler\"></ox-scene-handler>\n </ox-scene-viewer>\n\n <md-fab @click=${() => this.onTapSave()} title=\"save\"><md-icon slot=\"icon\">save</md-icon></md-fab>\n </div>\n\n <property-sidebar\n .scene=${this.scene}\n .selected=${this.selected}\n .collapsed=${this.hideProperty}\n .fonts=${this.fonts}\n .propertyEditor=${this.propertyEditor}\n >\n </property-sidebar>\n </div>\n `\n }\n\n connectedCallback(): void {\n super.connectedCallback()\n this.bindShortcutEvent()\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback()\n this.unbindShortcutEvent()\n }\n\n close() {\n this.model = null\n this.requestUpdate()\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n switch (e.code) {\n case 'KeyS':\n if (ctrlKey) {\n this.onTapSave()\n e.preventDefault()\n }\n break\n }\n }\n\n preview() {\n const board = {\n id: 'preview',\n model: this.scene?.model ? JSON.parse(JSON.stringify(this.scene.model)) : null,\n style: this.scene?.rootContainer.style\n }\n\n OxPopup.open({\n template: html`\n <ox-board-viewer\n style=\"width:100%;height:100%;background:white;\"\n .provider=${this.provider}\n .board=${board}\n ></ox-board-viewer>\n `,\n style: 'width:90vw;height:90vh;',\n backdrop: true,\n preventCloseOnBlur: true\n })\n\n requestAnimationFrame(() => {\n dispatchEvent(new Event('resize'))\n })\n }\n\n downloadModel() {\n if (!this.scene) return\n\n var model = JSON.stringify(this.model, null, 2)\n var filename = (this.boardName || 'NONAME') + '-' + Date.now() + '.json'\n saveAs(new Blob([model], { type: 'application/octet-stream' }), filename)\n }\n\n renderBrandingZone() {\n return html`\n <div brand>\n <md-icon\n @click=${() => {\n navigate('board-list')\n return false\n }}\n >home</md-icon\n >\n <div board_name>${this.boardName}</div>\n </div>\n `\n }\n\n onTapSave() {\n this.dispatchEvent(new CustomEvent('save-model', { bubbles: true, composed: true, detail: { model: this.model } }))\n }\n\n bindShortcutEvent() {\n // TODO: Global Hotkey에 대한 정의를 edit-toolbar에서 가져올 수 있도록 수정해야 함.\n const GLOBAL_HOTKEYS = ['Digit1', 'Digit2', 'F11', 'KeyD', 'KeyP', 'KeyS']\n\n this.shortcutHandler = (e: KeyboardEvent) => {\n const target = e.composedPath()[0] as HTMLElement\n var tagName = target.tagName\n var isInput = target.isContentEditable || tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA'\n var isGlobalHotkey = GLOBAL_HOTKEYS.includes(e.code)\n\n if (!isGlobalHotkey && isInput) return\n if (!this.editToolbar.onShortcut(e)) this.onShortcut(e)\n }\n\n document.addEventListener('keydown', this.shortcutHandler)\n }\n\n unbindShortcutEvent() {\n if (this.shortcutHandler) {\n document.removeEventListener('keydown', this.shortcutHandler)\n delete this.shortcutHandler\n }\n }\n\n onContextMenu() {}\n}\n"]}
@@ -9,12 +9,14 @@ import './ox-playback-controls.js';
9
9
  import { css, html, LitElement, nothing } from 'lit';
10
10
  import { customElement, property, query, state } from 'lit/decorators.js';
11
11
  import { PlaybackEngine } from './playback/playback-engine.js';
12
+ import { isFlowReplayEnabled } from './config/flow-replay.js';
12
13
  import { CarrierTrackingStore } from './playback/carrier-tracking-store.js';
13
- import { create, LoadTracker, LoadingOverlay, SCENE_MODE } from '@hatiolab/things-scene';
14
+ import { create, LoadTracker, LoadingOverlay, SCENE_MODE, dataLagTracker, isThreedEnabled } from '@hatiolab/things-scene';
14
15
  import { isIOS, fullscreen, exitfullscreen, togglefullscreen } from '@operato/utils';
15
16
  import { ScrollbarStyles } from '@operato/styles';
16
17
  import { DataStorage } from './data-storage/data-storage.js';
17
18
  import { runScenario, startScenario, DataSubscriptionProviderImpl, isRestfulAvailable } from '@fmsim/api';
19
+ import { SceneMonitorRenderer } from './scene-monitor-renderer.js';
18
20
  // FAB 아이콘 — packages/board/icons/fab/ 의 외부 SVG asset 로 분리.
19
21
  // 기존엔 inline SVG 였으나 (a) 가독성 향상, (b) 디자이너 단독 수정, (c) 캐시 활용 목적.
20
22
  const ICON_FAB_PLAYBACK_PLAY = new URL('../../icons/fab/playback-play.svg', import.meta.url).href;
@@ -269,7 +271,7 @@ let BoardViewer = BoardViewer_1 = class BoardViewer extends LitElement {
269
271
  title="fullscreen"
270
272
  ><md-icon slot="icon">${document.fullscreenElement ? 'fullscreen_exit' : 'fullscreen'}</md-icon></md-fab>`}
271
273
 
272
- <md-fab
274
+ ${isFlowReplayEnabled() ? html `<md-fab
273
275
  class="sub-fab"
274
276
  @click=${() => { this._fabExpanded = false; this.onTapPlayback(); }}
275
277
  title=${this._playbackActive ? 'stop playback' : 'start playback'}
@@ -277,9 +279,9 @@ let BoardViewer = BoardViewer_1 = class BoardViewer extends LitElement {
277
279
  class="fab-icon"
278
280
  src=${this._playbackActive ? ICON_FAB_PLAYBACK_STOP : ICON_FAB_PLAYBACK_PLAY}
279
281
  alt=${this._playbackActive ? 'stop playback' : 'start playback'}
280
- /></span></md-fab>
282
+ /></span></md-fab>` : nothing}
281
283
 
282
- <md-fab
284
+ ${isThreedEnabled() ? html `<md-fab
283
285
  class="sub-fab"
284
286
  @click=${() => { this._fabExpanded = false; this.onTapToggle3D(); }}
285
287
  title=${this._is3dMode ? '2D mode' : '3D mode'}
@@ -287,7 +289,7 @@ let BoardViewer = BoardViewer_1 = class BoardViewer extends LitElement {
287
289
  class="fab-icon"
288
290
  src=${this._is3dMode ? ICON_FAB_MODE_2D : ICON_FAB_MODE_3D}
289
291
  alt=${this._is3dMode ? '2D mode' : '3D mode'}
290
- /></span></md-fab>
292
+ /></span></md-fab>` : nothing}
291
293
  </div>
292
294
  `;
293
295
  var prev = !this.hideNavigation
@@ -470,8 +472,9 @@ let BoardViewer = BoardViewer_1 = class BoardViewer extends LitElement {
470
472
  _ensureOverlay(tracker) {
471
473
  if (!this._loadingOverlay) {
472
474
  this._loadingOverlay = new LoadingOverlay();
475
+ this._loadingOverlay.renderer = new SceneMonitorRenderer();
473
476
  }
474
- this._loadingOverlay.attach(this.renderRoot, tracker);
477
+ this._loadingOverlay.attach(this.renderRoot, tracker, dataLagTracker);
475
478
  }
476
479
  closeScene() {
477
480
  var _a, _b;
@@ -501,6 +504,10 @@ let BoardViewer = BoardViewer_1 = class BoardViewer extends LitElement {
501
504
  this._onPlaybackStop();
502
505
  }
503
506
  this._scene = scene;
507
+ // M키 로딩 오버레이(scene 내장)에 fmsim Scene Monitor 렌더러 주입 — 카테고리별 표현.
508
+ if (scene === null || scene === void 0 ? void 0 : scene.loadingOverlay) {
509
+ scene.loadingOverlay.renderer = new SceneMonitorRenderer();
510
+ }
504
511
  const backgroundColor = (_a = this._scene) === null || _a === void 0 ? void 0 : _a.root.state.fillStyle;
505
512
  if (typeof backgroundColor === 'string') {
506
513
  this.style.backgroundColor = backgroundColor;
@@ -853,6 +860,9 @@ let BoardViewer = BoardViewer_1 = class BoardViewer extends LitElement {
853
860
  }
854
861
  onTapPlayback() {
855
862
  var _a, _b;
863
+ // Flow-Replay 비활성 시 시작 경로 차단 (FAB 은 이미 숨겨지지만 방어적 가드).
864
+ if (!isFlowReplayEnabled() && !this._playbackActive)
865
+ return;
856
866
  if (this._playbackActive) {
857
867
  this._onPlaybackStop();
858
868
  }