@fmsim/board 2.0.0-beta.11 → 2.0.0-beta.111
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 +6502 -2308
- package/demo/index-modeller.html +1 -1
- package/demo/index-player.html +2 -2
- package/demo/index-viewer.html +2 -2
- package/demo/index.html +2 -2
- package/dist/src/board-i18n.d.ts +37 -0
- package/dist/src/board-i18n.js +121 -0
- package/dist/src/board-i18n.js.map +1 -0
- package/dist/src/component/etc.js +36 -0
- package/dist/src/component/etc.js.map +1 -1
- package/dist/src/component/index.d.ts +1 -0
- package/dist/src/component/index.js +1 -0
- package/dist/src/component/index.js.map +1 -1
- package/dist/src/component/restful-property-editor-backdrop-faces.d.ts +50 -0
- package/dist/src/component/restful-property-editor-backdrop-faces.js +524 -0
- package/dist/src/component/restful-property-editor-backdrop-faces.js.map +1 -0
- package/dist/src/config/flow-replay.d.ts +14 -0
- package/dist/src/config/flow-replay.js +20 -0
- package/dist/src/config/flow-replay.js.map +1 -0
- package/dist/src/data-storage/board-model-cache.d.ts +13 -0
- package/dist/src/data-storage/board-model-cache.js +66 -0
- package/dist/src/data-storage/board-model-cache.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/layers/mcs-mouse-event-handler.js +28 -3
- package/dist/src/layers/mcs-mouse-event-handler.js.map +1 -1
- package/dist/src/layers/movement-layer.d.ts +9 -6
- package/dist/src/layers/movement-layer.js +35 -10
- package/dist/src/layers/movement-layer.js.map +1 -1
- package/dist/src/modeller/bulk-create-dialog.d.ts +62 -0
- package/dist/src/modeller/bulk-create-dialog.js +595 -0
- package/dist/src/modeller/bulk-create-dialog.js.map +1 -0
- package/dist/src/modeller/bulk-create.d.ts +107 -0
- package/dist/src/modeller/bulk-create.js +201 -0
- package/dist/src/modeller/bulk-create.js.map +1 -0
- package/dist/src/modeller/component-toolbar/component-menu.d.ts +1 -1
- package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +7 -1
- package/dist/src/modeller/component-toolbar/component-toolbar.js +18 -2
- package/dist/src/modeller/component-toolbar/component-toolbar.js.map +1 -1
- package/dist/src/modeller/edit-toolbar.d.ts +13 -0
- package/dist/src/modeller/edit-toolbar.js +177 -7
- package/dist/src/modeller/edit-toolbar.js.map +1 -1
- package/dist/src/modeller/property-sidebar/abstract-property.js +10 -2
- package/dist/src/modeller/property-sidebar/abstract-property.js.map +1 -1
- package/dist/src/modeller/property-sidebar/data-binding/data-binding.d.ts +1 -1
- package/dist/src/modeller/property-sidebar/effects/effects.d.ts +10 -1
- package/dist/src/modeller/property-sidebar/effects/effects.js +67 -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 +13 -3
- 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/modeller/property-sidebar/inspector/inspector-controller.d.ts +66 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-controller.js +288 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-controller.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.d.ts +15 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.js +67 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-group-view.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-highlight.d.ts +7 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-highlight.js +25 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-highlight.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-model.d.ts +44 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-model.js +72 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-model.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-tree-view.d.ts +18 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-tree-view.js +61 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector-tree-view.js.map +1 -0
- package/dist/src/modeller/property-sidebar/inspector/inspector.d.ts +17 -12
- package/dist/src/modeller/property-sidebar/inspector/inspector.js +287 -151
- package/dist/src/modeller/property-sidebar/inspector/inspector.js.map +1 -1
- package/dist/src/modeller/property-sidebar/property-sidebar.d.ts +1 -1
- package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.d.ts +75 -0
- package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js +355 -0
- package/dist/src/modeller/property-sidebar/shapes/ox-input-entity-id.js.map +1 -0
- package/dist/src/modeller/property-sidebar/shapes/shapes.d.ts +22 -1
- package/dist/src/modeller/property-sidebar/shapes/shapes.js +110 -2
- package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -1
- package/dist/src/modeller/property-sidebar/specifics/parent-object.d.ts +29 -0
- package/dist/src/modeller/property-sidebar/specifics/parent-object.js +74 -0
- package/dist/src/modeller/property-sidebar/specifics/parent-object.js.map +1 -0
- package/dist/src/modeller/property-sidebar/specifics/specifics.d.ts +27 -1
- package/dist/src/modeller/property-sidebar/specifics/specifics.js +95 -3
- package/dist/src/modeller/property-sidebar/specifics/specifics.js.map +1 -1
- package/dist/src/modeller/property-sidebar/styles/styles.d.ts +1 -1
- package/dist/src/modeller/scene-viewer/ox-scene-layer.d.ts +4 -3
- package/dist/src/modeller/scene-viewer/ox-scene-layer.js +2 -1
- package/dist/src/modeller/scene-viewer/ox-scene-layer.js.map +1 -1
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +2 -1
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +5 -1
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -1
- package/dist/src/ox-board-component-info.d.ts +1 -0
- package/dist/src/ox-board-component-info.js +42 -2
- package/dist/src/ox-board-component-info.js.map +1 -1
- package/dist/src/ox-board-modeller.d.ts +6 -3
- package/dist/src/ox-board-modeller.js +21 -1
- package/dist/src/ox-board-modeller.js.map +1 -1
- package/dist/src/ox-board-viewer.d.ts +117 -13
- package/dist/src/ox-board-viewer.js +688 -102
- package/dist/src/ox-board-viewer.js.map +1 -1
- package/dist/src/ox-editor-board-selector.d.ts +3 -0
- package/dist/src/ox-editor-board-selector.js +40 -9
- package/dist/src/ox-editor-board-selector.js.map +1 -1
- package/dist/src/ox-playback-controls.d.ts +115 -18
- package/dist/src/ox-playback-controls.js +744 -167
- package/dist/src/ox-playback-controls.js.map +1 -1
- package/dist/src/playback/carrier-tracking-store.d.ts +51 -0
- package/dist/src/playback/carrier-tracking-store.js +115 -0
- package/dist/src/playback/carrier-tracking-store.js.map +1 -0
- package/dist/src/playback/playback-engine.d.ts +106 -0
- package/dist/src/playback/playback-engine.js +395 -0
- package/dist/src/playback/playback-engine.js.map +1 -0
- package/dist/src/scene-monitor-renderer.d.ts +10 -0
- package/dist/src/scene-monitor-renderer.js +226 -0
- package/dist/src/scene-monitor-renderer.js.map +1 -0
- package/dist/src/selector/ox-board-selector.js +14 -2
- package/dist/src/selector/ox-board-selector.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/icons/components/text.png +0 -0
- package/icons/fab/mode-2d.svg +25 -0
- package/icons/fab/mode-3d.svg +25 -0
- package/icons/fab/playback-play.svg +49 -0
- package/icons/fab/playback-stop.svg +50 -0
- package/package.json +8 -4
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import '@operato/i18n/ox-i18n.js';
|
|
5
|
+
import { LitElement, PropertyValues } from 'lit';
|
|
6
|
+
/**
|
|
7
|
+
* 컴포넌트 ID 입력기 — 자유 입력 + 타입별 백엔드(MCS) 검색 선택을 함께 제공.
|
|
8
|
+
*
|
|
9
|
+
* - 기존처럼 자유롭게 텍스트로 ID 를 입력할 수 있다 (commit = blur/Enter).
|
|
10
|
+
* - input 에 *포커스가 가면* 아래로 검색 드롭다운이 펼쳐진다. `entityType`
|
|
11
|
+
* (컴포넌트 타입) 으로 MCS 에 정의된 ID 후보를 조회한다.
|
|
12
|
+
* - machine 타입 → 머신 id 가 1레벨 평면으로 (선택 가능)
|
|
13
|
+
* - unit 타입 → machine 이 그룹 헤더, 그 아래 unit id 가 자식 (선택 가능).
|
|
14
|
+
* 컴포넌트가 부모 machine 을 알면(`machine` prop) 그 머신으로 좁혀 조회.
|
|
15
|
+
*
|
|
16
|
+
* value-key="id" 와 함께 property-grid 안에 두면, 이 host 가 `change`(bubbles+
|
|
17
|
+
* composed) 를 발행하므로 AbstractProperty 제너릭 핸들러가 `element.value` 를
|
|
18
|
+
* 읽어 property-change 로 전파한다.
|
|
19
|
+
*
|
|
20
|
+
* 등록: 패널 자식 커스텀 엘리먼트 컨벤션에 따라 전역 `@customElement` 가 아니라
|
|
21
|
+
* 부모 패널(PropertyShapes)의 `scopedElements` 로 등록한다 (@open-wc/scoped-elements).
|
|
22
|
+
*/
|
|
23
|
+
export declare class OxInputEntityId extends LitElement {
|
|
24
|
+
static styles: import("lit").CSSResult[];
|
|
25
|
+
/** 현재 ID 값. */
|
|
26
|
+
value: string;
|
|
27
|
+
/** 검색 조건 — 선택된 컴포넌트 타입 (예: 'STOCKER', 'AGV', 'Port'). */
|
|
28
|
+
entityType: string;
|
|
29
|
+
/** 검색 조건 — 부모 machine id (unit 컴포넌트가 소속 machine 을 알 때). */
|
|
30
|
+
machine: string;
|
|
31
|
+
/** machine 필수 타입(예: Port) — machine 없으면 조회하지 않는다 (후보 과다 방지). */
|
|
32
|
+
requireMachine: boolean;
|
|
33
|
+
/** 백엔드 조회 대신 사용할 로컬 후보 리스트 (예: parentObject — 씬의 머신들). null 이면 백엔드 조회. */
|
|
34
|
+
localItems: string[] | null;
|
|
35
|
+
placeholder: string;
|
|
36
|
+
private _open;
|
|
37
|
+
/** 서버에서 받은 전체 후보 리스트 (포커스 시 1회 조회, 키워드 미적용). */
|
|
38
|
+
private _all;
|
|
39
|
+
private _loading;
|
|
40
|
+
/** machine 필수인데 machine 미지정이라 조회를 보류한 상태. */
|
|
41
|
+
private _needMachine;
|
|
42
|
+
/** 선택 가능 항목 기준 active index. */
|
|
43
|
+
private _activeIndex;
|
|
44
|
+
private _input;
|
|
45
|
+
private _blurTimer?;
|
|
46
|
+
private _loadSeq;
|
|
47
|
+
/** 마지막으로 발행한 값 — 같은 값 재발행(undo 중복) 방지. */
|
|
48
|
+
private _lastEmitted?;
|
|
49
|
+
disconnectedCallback(): void;
|
|
50
|
+
updated(changed: PropertyValues): void;
|
|
51
|
+
/**
|
|
52
|
+
* 드롭다운 표시 항목 — 입력값(초기값 포함)으로 풀텍스트 로컬 필터.
|
|
53
|
+
* 단, 매치가 0이면 전체 후보로 fallback (막다른 "결과 없음" 방지 — 예: committed
|
|
54
|
+
* id 가 후보 형식과 달라 안 맞는 경우). 서버 재조회 없음.
|
|
55
|
+
*/
|
|
56
|
+
private get _items();
|
|
57
|
+
/** 드롭다운에서 선택 가능한 id 들 (표시 순서). */
|
|
58
|
+
private get _selectableIds();
|
|
59
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
60
|
+
private _renderDropdown;
|
|
61
|
+
private _onFocus;
|
|
62
|
+
private _onBlur;
|
|
63
|
+
private _onInput;
|
|
64
|
+
/** 자유 입력 commit (blur/Enter 의 native change) — 기존 free-text 동작 보존. */
|
|
65
|
+
private _onInputCommit;
|
|
66
|
+
private _onKeydown;
|
|
67
|
+
private _select;
|
|
68
|
+
private _commitValue;
|
|
69
|
+
private _emitChange;
|
|
70
|
+
/**
|
|
71
|
+
* 후보 전체를 1회 조회 (포커스 시). keyword 는 보내지 않으며, 표시 필터는 _items
|
|
72
|
+
* 게터가 로컬에서 처리한다. entityType(+unit 이면 machine) 만 서버로 보낸다.
|
|
73
|
+
*/
|
|
74
|
+
private _load;
|
|
75
|
+
}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { __decorate } from "tslib";
|
|
5
|
+
import '@operato/i18n/ox-i18n.js';
|
|
6
|
+
import { css, html, LitElement } from 'lit';
|
|
7
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
8
|
+
import { ScrollbarStyles } from '@operato/styles';
|
|
9
|
+
import { searchFigureIds, filterFigureIds } from '@fmsim/api';
|
|
10
|
+
/**
|
|
11
|
+
* 컴포넌트 ID 입력기 — 자유 입력 + 타입별 백엔드(MCS) 검색 선택을 함께 제공.
|
|
12
|
+
*
|
|
13
|
+
* - 기존처럼 자유롭게 텍스트로 ID 를 입력할 수 있다 (commit = blur/Enter).
|
|
14
|
+
* - input 에 *포커스가 가면* 아래로 검색 드롭다운이 펼쳐진다. `entityType`
|
|
15
|
+
* (컴포넌트 타입) 으로 MCS 에 정의된 ID 후보를 조회한다.
|
|
16
|
+
* - machine 타입 → 머신 id 가 1레벨 평면으로 (선택 가능)
|
|
17
|
+
* - unit 타입 → machine 이 그룹 헤더, 그 아래 unit id 가 자식 (선택 가능).
|
|
18
|
+
* 컴포넌트가 부모 machine 을 알면(`machine` prop) 그 머신으로 좁혀 조회.
|
|
19
|
+
*
|
|
20
|
+
* value-key="id" 와 함께 property-grid 안에 두면, 이 host 가 `change`(bubbles+
|
|
21
|
+
* composed) 를 발행하므로 AbstractProperty 제너릭 핸들러가 `element.value` 를
|
|
22
|
+
* 읽어 property-change 로 전파한다.
|
|
23
|
+
*
|
|
24
|
+
* 등록: 패널 자식 커스텀 엘리먼트 컨벤션에 따라 전역 `@customElement` 가 아니라
|
|
25
|
+
* 부모 패널(PropertyShapes)의 `scopedElements` 로 등록한다 (@open-wc/scoped-elements).
|
|
26
|
+
*/
|
|
27
|
+
export class OxInputEntityId extends LitElement {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
/** 현재 ID 값. */
|
|
31
|
+
this.value = '';
|
|
32
|
+
/** 검색 조건 — 선택된 컴포넌트 타입 (예: 'STOCKER', 'AGV', 'Port'). */
|
|
33
|
+
this.entityType = '';
|
|
34
|
+
/** 검색 조건 — 부모 machine id (unit 컴포넌트가 소속 machine 을 알 때). */
|
|
35
|
+
this.machine = '';
|
|
36
|
+
/** machine 필수 타입(예: Port) — machine 없으면 조회하지 않는다 (후보 과다 방지). */
|
|
37
|
+
this.requireMachine = false;
|
|
38
|
+
/** 백엔드 조회 대신 사용할 로컬 후보 리스트 (예: parentObject — 씬의 머신들). null 이면 백엔드 조회. */
|
|
39
|
+
this.localItems = null;
|
|
40
|
+
this.placeholder = '';
|
|
41
|
+
this._open = false;
|
|
42
|
+
/** 서버에서 받은 전체 후보 리스트 (포커스 시 1회 조회, 키워드 미적용). */
|
|
43
|
+
this._all = [];
|
|
44
|
+
this._loading = false;
|
|
45
|
+
/** machine 필수인데 machine 미지정이라 조회를 보류한 상태. */
|
|
46
|
+
this._needMachine = false;
|
|
47
|
+
/** 선택 가능 항목 기준 active index. */
|
|
48
|
+
this._activeIndex = -1;
|
|
49
|
+
this._loadSeq = 0;
|
|
50
|
+
}
|
|
51
|
+
disconnectedCallback() {
|
|
52
|
+
super.disconnectedCallback();
|
|
53
|
+
clearTimeout(this._blurTimer);
|
|
54
|
+
}
|
|
55
|
+
updated(changed) {
|
|
56
|
+
// 열린 상태에서 조회 조건(타입/부모 머신)이 바뀌면 재조회 (예: 부모 머신을 방금 지정).
|
|
57
|
+
if (this._open && (changed.has('entityType') || changed.has('machine') || changed.has('localItems'))) {
|
|
58
|
+
this._load();
|
|
59
|
+
}
|
|
60
|
+
// 화살표 키로 active 항목 이동 시 항상 보이도록 드롭다운을 스크롤.
|
|
61
|
+
if (changed.has('_activeIndex') && this._open && this._activeIndex >= 0) {
|
|
62
|
+
const el = this.renderRoot.querySelector('.item.active');
|
|
63
|
+
el === null || el === void 0 ? void 0 : el.scrollIntoView({ block: 'nearest' });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 드롭다운 표시 항목 — 입력값(초기값 포함)으로 풀텍스트 로컬 필터.
|
|
68
|
+
* 단, 매치가 0이면 전체 후보로 fallback (막다른 "결과 없음" 방지 — 예: committed
|
|
69
|
+
* id 가 후보 형식과 달라 안 맞는 경우). 서버 재조회 없음.
|
|
70
|
+
*/
|
|
71
|
+
get _items() {
|
|
72
|
+
if (!this._all.length)
|
|
73
|
+
return [];
|
|
74
|
+
const filtered = filterFigureIds(this._all, this.value || '');
|
|
75
|
+
return filtered.length ? filtered : this._all;
|
|
76
|
+
}
|
|
77
|
+
/** 드롭다운에서 선택 가능한 id 들 (표시 순서). */
|
|
78
|
+
get _selectableIds() {
|
|
79
|
+
return this._items;
|
|
80
|
+
}
|
|
81
|
+
render() {
|
|
82
|
+
return html `
|
|
83
|
+
<input
|
|
84
|
+
part="input"
|
|
85
|
+
.value=${this.value || ''}
|
|
86
|
+
placeholder=${this.placeholder}
|
|
87
|
+
autocomplete="off"
|
|
88
|
+
@focus=${this._onFocus}
|
|
89
|
+
@blur=${this._onBlur}
|
|
90
|
+
@input=${this._onInput}
|
|
91
|
+
@change=${this._onInputCommit}
|
|
92
|
+
@keydown=${this._onKeydown}
|
|
93
|
+
/>
|
|
94
|
+
${this._open ? this._renderDropdown() : ''}
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
_renderDropdown() {
|
|
98
|
+
if (this._needMachine) {
|
|
99
|
+
return html `<div class="dropdown">
|
|
100
|
+
<div class="hint"><ox-i18n msgid="text.need-parent-machine">상위 머신을 먼저 지정하세요</ox-i18n></div>
|
|
101
|
+
</div>`;
|
|
102
|
+
}
|
|
103
|
+
if (this._loading) {
|
|
104
|
+
return html `<div class="dropdown"><div class="hint"><ox-i18n msgid="text.searching">searching…</ox-i18n></div></div>`;
|
|
105
|
+
}
|
|
106
|
+
if (!this._items.length) {
|
|
107
|
+
return html `<div class="dropdown"><div class="hint"><ox-i18n msgid="text.no-results">no results</ox-i18n></div></div>`;
|
|
108
|
+
}
|
|
109
|
+
return html `
|
|
110
|
+
<div class="dropdown">
|
|
111
|
+
${this._items.map((id, idx) => html `
|
|
112
|
+
<div
|
|
113
|
+
class="item ${idx === this._activeIndex ? 'active' : ''}"
|
|
114
|
+
@mousedown=${(e) => this._select(id, e)}
|
|
115
|
+
>
|
|
116
|
+
${id}
|
|
117
|
+
</div>
|
|
118
|
+
`)}
|
|
119
|
+
</div>
|
|
120
|
+
`;
|
|
121
|
+
}
|
|
122
|
+
_onFocus() {
|
|
123
|
+
clearTimeout(this._blurTimer);
|
|
124
|
+
this._open = true;
|
|
125
|
+
this._activeIndex = -1;
|
|
126
|
+
this._load();
|
|
127
|
+
}
|
|
128
|
+
_onBlur() {
|
|
129
|
+
// 드롭다운 항목 mousedown 이 먼저 처리되도록 약간 지연 후 닫기
|
|
130
|
+
this._blurTimer = setTimeout(() => {
|
|
131
|
+
this._open = false;
|
|
132
|
+
this._activeIndex = -1;
|
|
133
|
+
}, 150);
|
|
134
|
+
}
|
|
135
|
+
_onInput(e) {
|
|
136
|
+
this.value = e.target.value;
|
|
137
|
+
this._open = true;
|
|
138
|
+
this._activeIndex = -1;
|
|
139
|
+
}
|
|
140
|
+
/** 자유 입력 commit (blur/Enter 의 native change) — 기존 free-text 동작 보존. */
|
|
141
|
+
_onInputCommit(e) {
|
|
142
|
+
this.value = e.target.value;
|
|
143
|
+
this._emitChange();
|
|
144
|
+
}
|
|
145
|
+
_onKeydown(e) {
|
|
146
|
+
const ids = this._selectableIds;
|
|
147
|
+
if (!this._open || !ids.length) {
|
|
148
|
+
if (e.key === 'Escape')
|
|
149
|
+
this._open = false;
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// 드롭다운이 열린 상태에서 처리하는 키는 부모(다이얼로그 confirm/cancel 등)로
|
|
153
|
+
// 전파되지 않도록 stopPropagation 한다. (Enter 로 항목 선택 시 다이얼로그가 닫히던 버그.)
|
|
154
|
+
if (e.key === 'ArrowDown') {
|
|
155
|
+
e.preventDefault();
|
|
156
|
+
e.stopPropagation();
|
|
157
|
+
this._activeIndex = (this._activeIndex + 1) % ids.length;
|
|
158
|
+
}
|
|
159
|
+
else if (e.key === 'ArrowUp') {
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
e.stopPropagation();
|
|
162
|
+
this._activeIndex = (this._activeIndex - 1 + ids.length) % ids.length;
|
|
163
|
+
}
|
|
164
|
+
else if (e.key === 'Enter') {
|
|
165
|
+
e.preventDefault();
|
|
166
|
+
e.stopPropagation();
|
|
167
|
+
if (this._activeIndex >= 0) {
|
|
168
|
+
this._commitValue(ids[this._activeIndex]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (e.key === 'Escape') {
|
|
172
|
+
e.stopPropagation();
|
|
173
|
+
this._open = false;
|
|
174
|
+
this._activeIndex = -1;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
_select(id, e) {
|
|
178
|
+
// mousedown 기본동작(blur) 막아 흐름 제어
|
|
179
|
+
e.preventDefault();
|
|
180
|
+
this._commitValue(id);
|
|
181
|
+
}
|
|
182
|
+
_commitValue(id) {
|
|
183
|
+
this.value = id;
|
|
184
|
+
this._open = false;
|
|
185
|
+
this._activeIndex = -1;
|
|
186
|
+
if (this._input)
|
|
187
|
+
this._input.value = id;
|
|
188
|
+
this._emitChange();
|
|
189
|
+
// NOTE: blur() 하지 않는다. null 로 blur 하면 relatedTarget=null 이 되어, 팝업 안에서
|
|
190
|
+
// 쓰일 때 OxPopup 의 focusout(밖으로 나감) 판정에 걸려 팝업이 통째로 닫혔다.
|
|
191
|
+
// 드롭다운은 _open=false 로 이미 닫히므로 blur 는 불필요하고, 선택 후 입력창에
|
|
192
|
+
// 포커스가 남는 편이 자연스럽다.
|
|
193
|
+
}
|
|
194
|
+
_emitChange() {
|
|
195
|
+
// 같은 값 재발행 skip (예: 드롭다운 선택 직후 blur 의 native change 중복)
|
|
196
|
+
if (this.value === this._lastEmitted)
|
|
197
|
+
return;
|
|
198
|
+
this._lastEmitted = this.value;
|
|
199
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* 후보 전체를 1회 조회 (포커스 시). keyword 는 보내지 않으며, 표시 필터는 _items
|
|
203
|
+
* 게터가 로컬에서 처리한다. entityType(+unit 이면 machine) 만 서버로 보낸다.
|
|
204
|
+
*/
|
|
205
|
+
async _load() {
|
|
206
|
+
// 로컬 리스트 모드(예: parentObject) — 백엔드 조회 없이 주어진 리스트 사용.
|
|
207
|
+
if (this.localItems != null) {
|
|
208
|
+
this._needMachine = false;
|
|
209
|
+
this._loading = false;
|
|
210
|
+
this._all = this.localItems;
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (!this.entityType) {
|
|
214
|
+
this._all = [];
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
// machine 필수 타입(Port 등)인데 부모 머신 미지정 → 조회 보류 (후보 과다 방지).
|
|
218
|
+
if (this.requireMachine && !this.machine) {
|
|
219
|
+
this._all = [];
|
|
220
|
+
this._needMachine = true;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this._needMachine = false;
|
|
224
|
+
const seq = ++this._loadSeq;
|
|
225
|
+
this._loading = true;
|
|
226
|
+
try {
|
|
227
|
+
const ids = await searchFigureIds(this.entityType, '', this.machine ? { machine: this.machine } : {});
|
|
228
|
+
if (seq !== this._loadSeq)
|
|
229
|
+
return; // 더 최신 조회가 있으면 폐기
|
|
230
|
+
this._all = ids;
|
|
231
|
+
}
|
|
232
|
+
catch (_a) {
|
|
233
|
+
if (seq === this._loadSeq)
|
|
234
|
+
this._all = [];
|
|
235
|
+
}
|
|
236
|
+
finally {
|
|
237
|
+
if (seq === this._loadSeq)
|
|
238
|
+
this._loading = false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
OxInputEntityId.styles = [
|
|
243
|
+
ScrollbarStyles,
|
|
244
|
+
css `
|
|
245
|
+
:host {
|
|
246
|
+
position: relative;
|
|
247
|
+
display: flex;
|
|
248
|
+
align-items: stretch;
|
|
249
|
+
width: 100%;
|
|
250
|
+
height: 100%;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
input {
|
|
254
|
+
flex: 1 1 auto;
|
|
255
|
+
width: 100%;
|
|
256
|
+
height: 100%;
|
|
257
|
+
box-sizing: border-box;
|
|
258
|
+
margin: 0;
|
|
259
|
+
padding: var(--input-padding, 2px 4px);
|
|
260
|
+
font: inherit;
|
|
261
|
+
border: var(--property-sidebar-fieldset-border, 1px solid #ccc);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.dropdown {
|
|
265
|
+
position: absolute;
|
|
266
|
+
top: 100%;
|
|
267
|
+
left: 0;
|
|
268
|
+
right: 0;
|
|
269
|
+
z-index: 100;
|
|
270
|
+
|
|
271
|
+
max-height: 220px;
|
|
272
|
+
overflow-y: auto;
|
|
273
|
+
|
|
274
|
+
margin-top: 2px;
|
|
275
|
+
background: var(--md-sys-color-surface, #fff);
|
|
276
|
+
border: 1px solid var(--md-sys-color-outline-variant, #c4c7c5);
|
|
277
|
+
border-radius: 4px;
|
|
278
|
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.group-header {
|
|
282
|
+
padding: 3px 8px;
|
|
283
|
+
font-size: 10px;
|
|
284
|
+
font-weight: 600;
|
|
285
|
+
text-transform: uppercase;
|
|
286
|
+
letter-spacing: 0.04em;
|
|
287
|
+
color: var(--md-sys-color-on-surface-variant, #777);
|
|
288
|
+
background: var(--md-sys-color-surface-variant, #eef0f3);
|
|
289
|
+
position: sticky;
|
|
290
|
+
top: 0;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.item {
|
|
294
|
+
padding: 4px 8px;
|
|
295
|
+
cursor: pointer;
|
|
296
|
+
white-space: nowrap;
|
|
297
|
+
overflow: hidden;
|
|
298
|
+
text-overflow: ellipsis;
|
|
299
|
+
font: var(--property-sidebar-fieldset-label, 12px sans-serif);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* unit 항목 (그룹 자식) 은 살짝 들여쓰기 */
|
|
303
|
+
.item.child {
|
|
304
|
+
padding-left: 18px;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.item:hover,
|
|
308
|
+
.item.active {
|
|
309
|
+
background: var(--md-sys-color-secondary-container, #d7e3ff);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.hint {
|
|
313
|
+
padding: 6px 8px;
|
|
314
|
+
color: var(--md-sys-color-on-surface-variant, #888);
|
|
315
|
+
font-size: 11px;
|
|
316
|
+
}
|
|
317
|
+
`
|
|
318
|
+
];
|
|
319
|
+
__decorate([
|
|
320
|
+
property({ type: String })
|
|
321
|
+
], OxInputEntityId.prototype, "value", void 0);
|
|
322
|
+
__decorate([
|
|
323
|
+
property({ type: String })
|
|
324
|
+
], OxInputEntityId.prototype, "entityType", void 0);
|
|
325
|
+
__decorate([
|
|
326
|
+
property({ type: String })
|
|
327
|
+
], OxInputEntityId.prototype, "machine", void 0);
|
|
328
|
+
__decorate([
|
|
329
|
+
property({ type: Boolean })
|
|
330
|
+
], OxInputEntityId.prototype, "requireMachine", void 0);
|
|
331
|
+
__decorate([
|
|
332
|
+
property({ type: Array })
|
|
333
|
+
], OxInputEntityId.prototype, "localItems", void 0);
|
|
334
|
+
__decorate([
|
|
335
|
+
property({ type: String })
|
|
336
|
+
], OxInputEntityId.prototype, "placeholder", void 0);
|
|
337
|
+
__decorate([
|
|
338
|
+
state()
|
|
339
|
+
], OxInputEntityId.prototype, "_open", void 0);
|
|
340
|
+
__decorate([
|
|
341
|
+
state()
|
|
342
|
+
], OxInputEntityId.prototype, "_all", void 0);
|
|
343
|
+
__decorate([
|
|
344
|
+
state()
|
|
345
|
+
], OxInputEntityId.prototype, "_loading", void 0);
|
|
346
|
+
__decorate([
|
|
347
|
+
state()
|
|
348
|
+
], OxInputEntityId.prototype, "_needMachine", void 0);
|
|
349
|
+
__decorate([
|
|
350
|
+
state()
|
|
351
|
+
], OxInputEntityId.prototype, "_activeIndex", void 0);
|
|
352
|
+
__decorate([
|
|
353
|
+
query('input')
|
|
354
|
+
], OxInputEntityId.prototype, "_input", void 0);
|
|
355
|
+
//# sourceMappingURL=ox-input-entity-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ox-input-entity-id.js","sourceRoot":"","sources":["../../../../../src/modeller/property-sidebar/shapes/ox-input-entity-id.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { searchFigureIds, filterFigureIds } from '@fmsim/api'\n\n/**\n * 컴포넌트 ID 입력기 — 자유 입력 + 타입별 백엔드(MCS) 검색 선택을 함께 제공.\n *\n * - 기존처럼 자유롭게 텍스트로 ID 를 입력할 수 있다 (commit = blur/Enter).\n * - input 에 *포커스가 가면* 아래로 검색 드롭다운이 펼쳐진다. `entityType`\n * (컴포넌트 타입) 으로 MCS 에 정의된 ID 후보를 조회한다.\n * - machine 타입 → 머신 id 가 1레벨 평면으로 (선택 가능)\n * - unit 타입 → machine 이 그룹 헤더, 그 아래 unit id 가 자식 (선택 가능).\n * 컴포넌트가 부모 machine 을 알면(`machine` prop) 그 머신으로 좁혀 조회.\n *\n * value-key=\"id\" 와 함께 property-grid 안에 두면, 이 host 가 `change`(bubbles+\n * composed) 를 발행하므로 AbstractProperty 제너릭 핸들러가 `element.value` 를\n * 읽어 property-change 로 전파한다.\n *\n * 등록: 패널 자식 커스텀 엘리먼트 컨벤션에 따라 전역 `@customElement` 가 아니라\n * 부모 패널(PropertyShapes)의 `scopedElements` 로 등록한다 (@open-wc/scoped-elements).\n */\nexport class OxInputEntityId extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n position: relative;\n display: flex;\n align-items: stretch;\n width: 100%;\n height: 100%;\n }\n\n input {\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n margin: 0;\n padding: var(--input-padding, 2px 4px);\n font: inherit;\n border: var(--property-sidebar-fieldset-border, 1px solid #ccc);\n }\n\n .dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 100;\n\n max-height: 220px;\n overflow-y: auto;\n\n margin-top: 2px;\n background: var(--md-sys-color-surface, #fff);\n border: 1px solid var(--md-sys-color-outline-variant, #c4c7c5);\n border-radius: 4px;\n box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);\n }\n\n .group-header {\n padding: 3px 8px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--md-sys-color-on-surface-variant, #777);\n background: var(--md-sys-color-surface-variant, #eef0f3);\n position: sticky;\n top: 0;\n }\n\n .item {\n padding: 4px 8px;\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font: var(--property-sidebar-fieldset-label, 12px sans-serif);\n }\n\n /* unit 항목 (그룹 자식) 은 살짝 들여쓰기 */\n .item.child {\n padding-left: 18px;\n }\n\n .item:hover,\n .item.active {\n background: var(--md-sys-color-secondary-container, #d7e3ff);\n }\n\n .hint {\n padding: 6px 8px;\n color: var(--md-sys-color-on-surface-variant, #888);\n font-size: 11px;\n }\n `\n ]\n\n /** 현재 ID 값. */\n @property({ type: String }) value = ''\n /** 검색 조건 — 선택된 컴포넌트 타입 (예: 'STOCKER', 'AGV', 'Port'). */\n @property({ type: String }) entityType = ''\n /** 검색 조건 — 부모 machine id (unit 컴포넌트가 소속 machine 을 알 때). */\n @property({ type: String }) machine = ''\n /** machine 필수 타입(예: Port) — machine 없으면 조회하지 않는다 (후보 과다 방지). */\n @property({ type: Boolean }) requireMachine = false\n /** 백엔드 조회 대신 사용할 로컬 후보 리스트 (예: parentObject — 씬의 머신들). null 이면 백엔드 조회. */\n @property({ type: Array }) localItems: string[] | null = null\n @property({ type: String }) placeholder = ''\n\n @state() private _open = false\n /** 서버에서 받은 전체 후보 리스트 (포커스 시 1회 조회, 키워드 미적용). */\n @state() private _all: string[] = []\n @state() private _loading = false\n /** machine 필수인데 machine 미지정이라 조회를 보류한 상태. */\n @state() private _needMachine = false\n /** 선택 가능 항목 기준 active index. */\n @state() private _activeIndex = -1\n\n @query('input') private _input!: HTMLInputElement\n\n private _blurTimer?: ReturnType<typeof setTimeout>\n private _loadSeq = 0\n /** 마지막으로 발행한 값 — 같은 값 재발행(undo 중복) 방지. */\n private _lastEmitted?: string\n\n disconnectedCallback() {\n super.disconnectedCallback()\n clearTimeout(this._blurTimer)\n }\n\n updated(changed: PropertyValues) {\n // 열린 상태에서 조회 조건(타입/부모 머신)이 바뀌면 재조회 (예: 부모 머신을 방금 지정).\n if (this._open && (changed.has('entityType') || changed.has('machine') || changed.has('localItems'))) {\n this._load()\n }\n // 화살표 키로 active 항목 이동 시 항상 보이도록 드롭다운을 스크롤.\n if (changed.has('_activeIndex') && this._open && this._activeIndex >= 0) {\n const el = this.renderRoot.querySelector('.item.active') as HTMLElement | null\n el?.scrollIntoView({ block: 'nearest' })\n }\n }\n\n /**\n * 드롭다운 표시 항목 — 입력값(초기값 포함)으로 풀텍스트 로컬 필터.\n * 단, 매치가 0이면 전체 후보로 fallback (막다른 \"결과 없음\" 방지 — 예: committed\n * id 가 후보 형식과 달라 안 맞는 경우). 서버 재조회 없음.\n */\n private get _items(): string[] {\n if (!this._all.length) return []\n const filtered = filterFigureIds(this._all, this.value || '')\n return filtered.length ? filtered : this._all\n }\n\n /** 드롭다운에서 선택 가능한 id 들 (표시 순서). */\n private get _selectableIds(): string[] {\n return this._items\n }\n\n render() {\n return html`\n <input\n part=\"input\"\n .value=${this.value || ''}\n placeholder=${this.placeholder}\n autocomplete=\"off\"\n @focus=${this._onFocus}\n @blur=${this._onBlur}\n @input=${this._onInput}\n @change=${this._onInputCommit}\n @keydown=${this._onKeydown}\n />\n ${this._open ? this._renderDropdown() : ''}\n `\n }\n\n private _renderDropdown() {\n if (this._needMachine) {\n return html`<div class=\"dropdown\">\n <div class=\"hint\"><ox-i18n msgid=\"text.need-parent-machine\">상위 머신을 먼저 지정하세요</ox-i18n></div>\n </div>`\n }\n if (this._loading) {\n return html`<div class=\"dropdown\"><div class=\"hint\"><ox-i18n msgid=\"text.searching\">searching…</ox-i18n></div></div>`\n }\n if (!this._items.length) {\n return html`<div class=\"dropdown\"><div class=\"hint\"><ox-i18n msgid=\"text.no-results\">no results</ox-i18n></div></div>`\n }\n\n return html`\n <div class=\"dropdown\">\n ${this._items.map(\n (id, idx) => html`\n <div\n class=\"item ${idx === this._activeIndex ? 'active' : ''}\"\n @mousedown=${(e: MouseEvent) => this._select(id, e)}\n >\n ${id}\n </div>\n `\n )}\n </div>\n `\n }\n\n private _onFocus() {\n clearTimeout(this._blurTimer)\n this._open = true\n this._activeIndex = -1\n this._load()\n }\n\n private _onBlur() {\n // 드롭다운 항목 mousedown 이 먼저 처리되도록 약간 지연 후 닫기\n this._blurTimer = setTimeout(() => {\n this._open = false\n this._activeIndex = -1\n }, 150)\n }\n\n private _onInput(e: Event) {\n this.value = (e.target as HTMLInputElement).value\n this._open = true\n this._activeIndex = -1\n }\n\n /** 자유 입력 commit (blur/Enter 의 native change) — 기존 free-text 동작 보존. */\n private _onInputCommit(e: Event) {\n this.value = (e.target as HTMLInputElement).value\n this._emitChange()\n }\n\n private _onKeydown(e: KeyboardEvent) {\n const ids = this._selectableIds\n if (!this._open || !ids.length) {\n if (e.key === 'Escape') this._open = false\n return\n }\n // 드롭다운이 열린 상태에서 처리하는 키는 부모(다이얼로그 confirm/cancel 등)로\n // 전파되지 않도록 stopPropagation 한다. (Enter 로 항목 선택 시 다이얼로그가 닫히던 버그.)\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n e.stopPropagation()\n this._activeIndex = (this._activeIndex + 1) % ids.length\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n e.stopPropagation()\n this._activeIndex = (this._activeIndex - 1 + ids.length) % ids.length\n } else if (e.key === 'Enter') {\n e.preventDefault()\n e.stopPropagation()\n if (this._activeIndex >= 0) {\n this._commitValue(ids[this._activeIndex])\n }\n } else if (e.key === 'Escape') {\n e.stopPropagation()\n this._open = false\n this._activeIndex = -1\n }\n }\n\n private _select(id: string, e: MouseEvent) {\n // mousedown 기본동작(blur) 막아 흐름 제어\n e.preventDefault()\n this._commitValue(id)\n }\n\n private _commitValue(id: string) {\n this.value = id\n this._open = false\n this._activeIndex = -1\n if (this._input) this._input.value = id\n this._emitChange()\n // NOTE: blur() 하지 않는다. null 로 blur 하면 relatedTarget=null 이 되어, 팝업 안에서\n // 쓰일 때 OxPopup 의 focusout(밖으로 나감) 판정에 걸려 팝업이 통째로 닫혔다.\n // 드롭다운은 _open=false 로 이미 닫히므로 blur 는 불필요하고, 선택 후 입력창에\n // 포커스가 남는 편이 자연스럽다.\n }\n\n private _emitChange() {\n // 같은 값 재발행 skip (예: 드롭다운 선택 직후 blur 의 native change 중복)\n if (this.value === this._lastEmitted) return\n this._lastEmitted = this.value\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n }\n\n /**\n * 후보 전체를 1회 조회 (포커스 시). keyword 는 보내지 않으며, 표시 필터는 _items\n * 게터가 로컬에서 처리한다. entityType(+unit 이면 machine) 만 서버로 보낸다.\n */\n private async _load() {\n // 로컬 리스트 모드(예: parentObject) — 백엔드 조회 없이 주어진 리스트 사용.\n if (this.localItems != null) {\n this._needMachine = false\n this._loading = false\n this._all = this.localItems\n return\n }\n if (!this.entityType) {\n this._all = []\n return\n }\n // machine 필수 타입(Port 등)인데 부모 머신 미지정 → 조회 보류 (후보 과다 방지).\n if (this.requireMachine && !this.machine) {\n this._all = []\n this._needMachine = true\n return\n }\n this._needMachine = false\n const seq = ++this._loadSeq\n this._loading = true\n try {\n const ids = await searchFigureIds(this.entityType, '', this.machine ? { machine: this.machine } : {})\n if (seq !== this._loadSeq) return // 더 최신 조회가 있으면 폐기\n this._all = ids\n } catch {\n if (seq === this._loadSeq) this._all = []\n } finally {\n if (seq === this._loadSeq) this._loading = false\n }\n }\n}\n"]}
|
|
@@ -7,7 +7,12 @@ import '@material/web/icon/icon.js';
|
|
|
7
7
|
import '@operato/i18n/ox-i18n.js';
|
|
8
8
|
import { BOUNDS, Component, Properties } from '@hatiolab/things-scene';
|
|
9
9
|
import { AbstractProperty } from '../abstract-property';
|
|
10
|
-
|
|
10
|
+
import { OxInputEntityId } from './ox-input-entity-id';
|
|
11
|
+
declare const PropertyShapes_base: typeof AbstractProperty & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
|
|
12
|
+
export declare class PropertyShapes extends PropertyShapes_base {
|
|
13
|
+
static get scopedElements(): {
|
|
14
|
+
'ox-input-entity-id': typeof OxInputEntityId;
|
|
15
|
+
};
|
|
11
16
|
static styles: import("lit").CSSResult[];
|
|
12
17
|
value?: Properties;
|
|
13
18
|
bounds: BOUNDS | null;
|
|
@@ -18,7 +23,23 @@ export declare class PropertyShapes extends AbstractProperty {
|
|
|
18
23
|
_hasTextProperty(selected: Component[]): boolean;
|
|
19
24
|
_hasProperties(selected: Component[]): boolean;
|
|
20
25
|
_isIdentifiable(selected: Component[]): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* 단일 선택 컴포넌트의 부모 machine id (unit 의 ID 검색 시 조회조건으로 전달).
|
|
28
|
+
* 부모가 루트 모델/레이어가 아니고 id 를 가지면 그 id 를 반환 — unit 이 자신의
|
|
29
|
+
* 소속 machine 을 특정할 수 있는 경우에 해당. 그 외엔 빈 문자열.
|
|
30
|
+
*/
|
|
31
|
+
_parentMachineId(selected: Component[]): string;
|
|
32
|
+
/**
|
|
33
|
+
* 선택 컴포넌트의 id 조회용 타입명 (capability `idLookupType`). 값이 있으면 그 타입으로
|
|
34
|
+
* 검색 에디터를 띄우고, 없으면(일반 도형·Carrier 등) plain input 으로 두어 불필요한 id
|
|
35
|
+
* 리스트 요청을 보내지 않는다. 기본은 자기 타입이며 컴포넌트가 다른 타입으로 override 가능.
|
|
36
|
+
* (머신/유닛 + Node 가 opt-in. isLVComponent 은 Carrier 포함·Node 제외라 부적합.)
|
|
37
|
+
*/
|
|
38
|
+
_idLookupType(selected: Component[]): string | undefined;
|
|
39
|
+
/** Board 루트 속성 state.idLookup 으로 id 룩업 전체 ON/OFF (기본 ON). */
|
|
40
|
+
_idLookupEnabled(selected: Component[]): boolean;
|
|
21
41
|
_isClassIdentifiable(selected: Component[]): boolean;
|
|
22
42
|
_isLine(selected: Component[]): boolean;
|
|
23
43
|
_is3dish(selected: Component[]): boolean;
|
|
24
44
|
}
|
|
45
|
+
export {};
|
|
@@ -9,19 +9,28 @@ import '@operato/i18n/ox-i18n.js';
|
|
|
9
9
|
import { css, html } from 'lit';
|
|
10
10
|
import { property } from 'lit/decorators.js';
|
|
11
11
|
import { keyed } from 'lit/directives/keyed.js';
|
|
12
|
+
import { isThreedEnabled } from '@hatiolab/things-scene';
|
|
13
|
+
import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|
12
14
|
import { AbstractProperty } from '../abstract-property';
|
|
13
15
|
import { PropertySharedStyle } from '../property-shared-style';
|
|
14
16
|
import { BoxPaddingEditorStyles } from './box-padding-editor-styles';
|
|
15
|
-
|
|
17
|
+
import { OxInputEntityId } from './ox-input-entity-id';
|
|
18
|
+
export class PropertyShapes extends ScopedElementsMixin(AbstractProperty) {
|
|
16
19
|
constructor() {
|
|
17
20
|
super(...arguments);
|
|
18
21
|
this.bounds = null;
|
|
19
22
|
this.selected = [];
|
|
20
23
|
}
|
|
24
|
+
static get scopedElements() {
|
|
25
|
+
return {
|
|
26
|
+
'ox-input-entity-id': OxInputEntityId
|
|
27
|
+
};
|
|
28
|
+
}
|
|
21
29
|
firstUpdated() {
|
|
22
30
|
this.renderRoot.addEventListener('change', this._onValueChange.bind(this));
|
|
23
31
|
}
|
|
24
32
|
render() {
|
|
33
|
+
var _a, _b;
|
|
25
34
|
const value = this.value || {};
|
|
26
35
|
const { width, height } = this.bounds || {};
|
|
27
36
|
return html `
|
|
@@ -30,7 +39,18 @@ export class PropertyShapes extends AbstractProperty {
|
|
|
30
39
|
${this._isIdentifiable(this.selected)
|
|
31
40
|
? html `
|
|
32
41
|
<label> <ox-i18n msgid="label.id">ID</ox-i18n> </label>
|
|
33
|
-
|
|
42
|
+
${this._idLookupType(this.selected)
|
|
43
|
+
? html `
|
|
44
|
+
<ox-input-entity-id
|
|
45
|
+
custom-editor
|
|
46
|
+
value-key="id"
|
|
47
|
+
.value=${value.id || ''}
|
|
48
|
+
.entityType=${this._idLookupType(this.selected)}
|
|
49
|
+
.machine=${this._parentMachineId(this.selected)}
|
|
50
|
+
.requireMachine=${!!this.selected[0].idLookupRequiresMachine}
|
|
51
|
+
></ox-input-entity-id>
|
|
52
|
+
`
|
|
53
|
+
: html `<input value-key="id" .value=${value.id || ''} />`}
|
|
34
54
|
`
|
|
35
55
|
: html ``}
|
|
36
56
|
${this._isClassIdentifiable(this.selected)
|
|
@@ -85,6 +105,26 @@ export class PropertyShapes extends AbstractProperty {
|
|
|
85
105
|
${this.selected.length && this.selected[0].isRootModel()
|
|
86
106
|
? html ``
|
|
87
107
|
: html `
|
|
108
|
+
${isThreedEnabled()
|
|
109
|
+
? html `
|
|
110
|
+
<label class="depth"> <ox-i18n msgid="label.depth">depth</ox-i18n> </label>
|
|
111
|
+
<input
|
|
112
|
+
type="number"
|
|
113
|
+
value-key="depth"
|
|
114
|
+
.value=${String((_a = value.depth) !== null && _a !== void 0 ? _a : '')}
|
|
115
|
+
placeholder="auto"
|
|
116
|
+
/>
|
|
117
|
+
|
|
118
|
+
<label class="zPos"> <ox-i18n msgid="label.zPos">zPos</ox-i18n> </label>
|
|
119
|
+
<input
|
|
120
|
+
type="number"
|
|
121
|
+
value-key="zPos"
|
|
122
|
+
.value=${String((_b = value.zPos) !== null && _b !== void 0 ? _b : '')}
|
|
123
|
+
placeholder="auto"
|
|
124
|
+
/>
|
|
125
|
+
`
|
|
126
|
+
: html ``}
|
|
127
|
+
|
|
88
128
|
<label class="rotate"> <ox-i18n msgid="label.rotate">rotate</ox-i18n> </label>
|
|
89
129
|
<ox-input-angle value-key="rotation" .value=${value.rotation}> </ox-input-angle>
|
|
90
130
|
`}
|
|
@@ -176,6 +216,32 @@ export class PropertyShapes extends AbstractProperty {
|
|
|
176
216
|
<option value="width">width</option>
|
|
177
217
|
<option value="height">height</option>
|
|
178
218
|
</select>
|
|
219
|
+
|
|
220
|
+
${isThreedEnabled()
|
|
221
|
+
? html `
|
|
222
|
+
<div class="checkbox-row">
|
|
223
|
+
<input id="cb-threed" type="checkbox" value-key="threed" .checked=${!!value.threed} />
|
|
224
|
+
<label for="cb-threed"><ox-i18n msgid="label.start-in-3d">Start in 3D</ox-i18n></label>
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
<div class="checkbox-row">
|
|
228
|
+
<input
|
|
229
|
+
id="cb-floor-constraint"
|
|
230
|
+
type="checkbox"
|
|
231
|
+
value-key="cameraFloorConstraint"
|
|
232
|
+
.checked=${!!value.cameraFloorConstraint}
|
|
233
|
+
/>
|
|
234
|
+
<label for="cb-floor-constraint">
|
|
235
|
+
<ox-i18n msgid="label.keep-above-ground">Keep Above Ground</ox-i18n>
|
|
236
|
+
</label>
|
|
237
|
+
</div>
|
|
238
|
+
`
|
|
239
|
+
: html ``}
|
|
240
|
+
|
|
241
|
+
<div class="checkbox-row">
|
|
242
|
+
<input id="cb-id-lookup" type="checkbox" value-key="idLookup" .checked=${value.idLookup !== false} />
|
|
243
|
+
<label for="cb-id-lookup"><ox-i18n msgid="label.id-lookup">ID Lookup</ox-i18n></label>
|
|
244
|
+
</div>
|
|
179
245
|
</div>
|
|
180
246
|
</fieldset>
|
|
181
247
|
`
|
|
@@ -225,6 +291,44 @@ export class PropertyShapes extends AbstractProperty {
|
|
|
225
291
|
return false;
|
|
226
292
|
return true;
|
|
227
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* 단일 선택 컴포넌트의 부모 machine id (unit 의 ID 검색 시 조회조건으로 전달).
|
|
296
|
+
* 부모가 루트 모델/레이어가 아니고 id 를 가지면 그 id 를 반환 — unit 이 자신의
|
|
297
|
+
* 소속 machine 을 특정할 수 있는 경우에 해당. 그 외엔 빈 문자열.
|
|
298
|
+
*/
|
|
299
|
+
_parentMachineId(selected) {
|
|
300
|
+
var _a, _b, _c;
|
|
301
|
+
const target = (selected === null || selected === void 0 ? void 0 : selected.length) === 1 ? selected[0] : null;
|
|
302
|
+
if (!target)
|
|
303
|
+
return '';
|
|
304
|
+
// 명시적 parentObjectId(= 부모 머신 id) 우선, 없으면 실제 scene 부모의 id.
|
|
305
|
+
const pid = (_a = target.state) === null || _a === void 0 ? void 0 : _a.parentObjectId;
|
|
306
|
+
if (pid)
|
|
307
|
+
return String(pid);
|
|
308
|
+
const parent = target.parent;
|
|
309
|
+
if (!parent || ((_b = parent.isRootModel) === null || _b === void 0 ? void 0 : _b.call(parent)) || (parent.isLayer && parent.isLayer()))
|
|
310
|
+
return '';
|
|
311
|
+
return ((_c = parent.state) === null || _c === void 0 ? void 0 : _c.id) || '';
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* 선택 컴포넌트의 id 조회용 타입명 (capability `idLookupType`). 값이 있으면 그 타입으로
|
|
315
|
+
* 검색 에디터를 띄우고, 없으면(일반 도형·Carrier 등) plain input 으로 두어 불필요한 id
|
|
316
|
+
* 리스트 요청을 보내지 않는다. 기본은 자기 타입이며 컴포넌트가 다른 타입으로 override 가능.
|
|
317
|
+
* (머신/유닛 + Node 가 opt-in. isLVComponent 은 Carrier 포함·Node 제외라 부적합.)
|
|
318
|
+
*/
|
|
319
|
+
_idLookupType(selected) {
|
|
320
|
+
if ((selected === null || selected === void 0 ? void 0 : selected.length) !== 1)
|
|
321
|
+
return undefined;
|
|
322
|
+
if (!this._idLookupEnabled(selected))
|
|
323
|
+
return undefined;
|
|
324
|
+
return selected[0].idLookupType;
|
|
325
|
+
}
|
|
326
|
+
/** Board 루트 속성 state.idLookup 으로 id 룩업 전체 ON/OFF (기본 ON). */
|
|
327
|
+
_idLookupEnabled(selected) {
|
|
328
|
+
var _a, _b;
|
|
329
|
+
const root = (_a = selected === null || selected === void 0 ? void 0 : selected[0]) === null || _a === void 0 ? void 0 : _a.root;
|
|
330
|
+
return ((_b = root === null || root === void 0 ? void 0 : root.state) === null || _b === void 0 ? void 0 : _b.idLookup) !== false;
|
|
331
|
+
}
|
|
228
332
|
_isClassIdentifiable(selected) {
|
|
229
333
|
if (!selected || (selected[0] && selected[0].isLayer()))
|
|
230
334
|
return false;
|
|
@@ -266,6 +370,10 @@ PropertyShapes.styles = [
|
|
|
266
370
|
background: var(--url-icon-properties-label) 7px -900px no-repeat;
|
|
267
371
|
}
|
|
268
372
|
|
|
373
|
+
.icon-label .checkbox-row label {
|
|
374
|
+
background: none;
|
|
375
|
+
}
|
|
376
|
+
|
|
269
377
|
.icon-label label.width {
|
|
270
378
|
background-position: 7px -96px;
|
|
271
379
|
}
|