@operato/property-panel 10.0.0-beta.46 → 10.0.0-beta.48
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/CHANGELOG.md +25 -0
- package/dist/src/property-panel/effects/property-event-tap.js +21 -1
- package/dist/src/property-panel/effects/property-event-tap.js.map +1 -1
- package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.d.ts +20 -0
- package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.js +125 -0
- package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.js.map +1 -0
- package/dist/src/property-panel/shapes/placeholder-convert.d.ts +34 -0
- package/dist/src/property-panel/shapes/placeholder-convert.js +117 -0
- package/dist/src/property-panel/shapes/placeholder-convert.js.map +1 -0
- package/dist/src/property-panel/shapes/shapes.js +8 -2
- package/dist/src/property-panel/shapes/shapes.js.map +1 -1
- package/dist/src/property-panel/specifics/specifics.d.ts +1 -0
- package/dist/src/property-panel/specifics/specifics.js +1 -0
- package/dist/src/property-panel/specifics/specifics.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/translations/en.json +14 -1
- package/translations/ja.json +14 -1
- package/translations/ko.json +14 -1
- package/translations/ms.json +14 -1
- package/translations/zh.json +14 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,31 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [10.0.0-beta.48](https://github.com/hatiolab/operato/compare/v10.0.0-beta.47...v10.0.0-beta.48) (2026-05-05)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
* **property-panel:** generic-object 타입 변환 UI를 specifics 탭 전용 에디터로 이동 ([4b90f57](https://github.com/hatiolab/operato/commit/4b90f574c29f1677eb0dacc73b05e9fd10c9d2b2))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### :house: Code Refactoring
|
|
15
|
+
|
|
16
|
+
* **property-panel:** placeholder-convert 아키텍처 정리 ([ec7c805](https://github.com/hatiolab/operato/commit/ec7c80550148fe2a13704999aafb940b26558729))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## [10.0.0-beta.47](https://github.com/hatiolab/operato/compare/v10.0.0-beta.46...v10.0.0-beta.47) (2026-05-03)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### :rocket: New Features
|
|
24
|
+
|
|
25
|
+
* **i18n:** popup-container + tooltip-3d component names + new property labels ([2e15e2b](https://github.com/hatiolab/operato/commit/2e15e2baad9d8f09a651f6f253015f8d7a8e5e32))
|
|
26
|
+
* **modeller:** popup-container palette + inline-popup tap actions ([737b081](https://github.com/hatiolab/operato/commit/737b0819c287d7703f404db266e79b12281070d3))
|
|
27
|
+
* **property-panel:** popup position option + inline-popup target list ([19778c5](https://github.com/hatiolab/operato/commit/19778c515ca38678bfd88b895639f1aa95032682))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
6
31
|
## [10.0.0-beta.46](https://github.com/hatiolab/operato/compare/v10.0.0-beta.45...v10.0.0-beta.46) (2026-05-01)
|
|
7
32
|
|
|
8
33
|
**Note:** Version bump only for package @operato/property-panel
|
|
@@ -55,6 +55,8 @@ export class PropertyEventTap extends LitElement {
|
|
|
55
55
|
<option value="route-page">route to page</option>
|
|
56
56
|
<option value="popup">popup target board</option>
|
|
57
57
|
<option value="modal-popup">modal popup target board</option>
|
|
58
|
+
<option value="inline-popup">inline popup (target = popup component)</option>
|
|
59
|
+
<option value="inline-modal-popup">inline modal popup (target = popup component)</option>
|
|
58
60
|
<option value="close-scene">close current board</option>
|
|
59
61
|
<option value="infoWindow">open infowindow</option>
|
|
60
62
|
<option value="toggle-info-window">toggle infowindow</option>
|
|
@@ -73,7 +75,7 @@ export class PropertyEventTap extends LitElement {
|
|
|
73
75
|
|
|
74
76
|
<label> <ox-i18n msgid="label.target">target</ox-i18n> </label>
|
|
75
77
|
|
|
76
|
-
${action === 'goto' ||
|
|
78
|
+
${action === 'goto' || action === 'popup' || action === 'modal-popup'
|
|
77
79
|
? html `
|
|
78
80
|
<ox-editor-board-selector
|
|
79
81
|
class="custom-editor"
|
|
@@ -176,6 +178,24 @@ export class PropertyEventTap extends LitElement {
|
|
|
176
178
|
return { value: `#${id}`, description: (_a = this.scene.findById(id)) === null || _a === void 0 ? void 0 : _a.get('type') };
|
|
177
179
|
})) ||
|
|
178
180
|
[]);
|
|
181
|
+
case 'inline-popup':
|
|
182
|
+
case 'inline-modal-popup':
|
|
183
|
+
/* target = 같은 보드의 popup-container (또는 state.position='popup' 인 일반 Container) id.
|
|
184
|
+
* 모든 보드 내 popup template 후보를 select 으로 노출. 액션 핸들러는 그 컨테이너를
|
|
185
|
+
* 템플릿으로 fresh 인스턴스 생성하여 popup 으로 표시. */
|
|
186
|
+
return ((this.scene &&
|
|
187
|
+
this.scene.ids
|
|
188
|
+
.filter((i) => {
|
|
189
|
+
var _a;
|
|
190
|
+
const c = this.scene.findById(i.key);
|
|
191
|
+
return c.get('type') === 'popup-container' || ((_a = c.getState) === null || _a === void 0 ? void 0 : _a.call(c, 'position')) === 'popup';
|
|
192
|
+
})
|
|
193
|
+
.map((i) => {
|
|
194
|
+
var _a;
|
|
195
|
+
const id = i.key;
|
|
196
|
+
return { value: `#${id}`, description: (_a = this.scene.findById(id)) === null || _a === void 0 ? void 0 : _a.get('type') };
|
|
197
|
+
})) ||
|
|
198
|
+
[]);
|
|
179
199
|
case 'start-scenario':
|
|
180
200
|
case 'run-scenario':
|
|
181
201
|
return this.scenarios;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"property-event-tap.js","sourceRoot":"","sources":["../../../../src/property-panel/effects/property-event-tap.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/input/ox-input-data.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { property, state } from 'lit/decorators.js'\n\nimport { Properties, Scene } from '@hatiolab/things-scene'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\n\nimport { scenarios } from '../../graphql/scenario.js'\nimport { playlists } from '../../graphql/play-group.js'\nimport { convert } from './value-converter.js'\n\nconst SETS_ACTION = ['data-set', 'partial-data-set', 'value-set', 'partial-value-set', 'start-scenario', 'run-scenario']\n\nexport class PropertyEventTap extends LitElement {\n static styles = [\n PropertyGridStyles,\n css`\n :host {\n display: flex;\n }\n `\n ]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n\n @state() scenarios: { value: string; description: string }[] = []\n @state() playlists: { value: string; description: string }[] = []\n @state() targetList: { value: string; description: string }[] = []\n\n async firstUpdated() {\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n }\n\n render() {\n var { action, value = '', target = '', pressed, options } = this.value || {}\n var { input = '(self)', output = true } = options || {}\n\n return html`\n <div class=\"property-grid\">\n <input id=\"checkbox-pressed\" type=\"checkbox\" value-key=\"pressed\" .checked=${pressed} />\n <label for=\"checkbox-pressed\" class=\"checkbox-label\"> <ox-i18n msgid=\"label.pressed\">pressed</ox-i18n> </label>\n\n <label> <ox-i18n msgid=\"label.tap-action\">tap action</ox-i18n> </label>\n <select\n id=\"tap-select\"\n value-key=\"action\"\n .value=${action || ''}\n @change=${async (e: Event) => {\n if ((e.target as HTMLSelectElement).value.includes('scenario')) {\n this.scenarios = (await scenarios()).map(({ name, description }) => {\n return { value: name, description }\n })\n } else if ((e.target as HTMLSelectElement).value == 'goto-playlist') {\n this.playlists = (await playlists()).map(({ name, description }) => {\n return { value: name, description }\n })\n }\n }}\n >\n <option value=\"\"></option>\n <option value=\"goto\">go to target board</option>\n <option value=\"goto-playlist\">go to target playlist</option>\n <option value=\"link-open\">open new window for target link</option>\n <option value=\"link-move\">move to target link</option>\n <option value=\"route-page\">route to page</option>\n <option value=\"popup\">popup target board</option>\n <option value=\"modal-popup\">modal popup target board</option>\n <option value=\"close-scene\">close current board</option>\n <option value=\"infoWindow\">open infowindow</option>\n <option value=\"toggle-info-window\">toggle infowindow</option>\n <option value=\"data-toggle\">toggle(true/false) target component data</option>\n <option value=\"data-tristate\">tristate(0/1/2) target component data</option>\n <option value=\"data-spreading\">forcely execute data spreading of target component</option>\n <option value=\"data-set\">set value to target component data</option>\n <option value=\"partial-data-set\">set partial value to target component data</option>\n <option value=\"value-set\">set value to target component value</option>\n <option value=\"partial-value-set\">set partial value to target component value</option>\n <option value=\"start-scenario\">start the given scenario</option>\n <option value=\"run-scenario\">run the given scenario</option>\n <option value=\"export-data\">export data</option>\n <option value=\"import-data\">import data</option>\n </select>\n\n <label> <ox-i18n msgid=\"label.target\">target</ox-i18n> </label>\n\n ${action === 'goto' || action?.includes('popup')\n ? html`\n <ox-editor-board-selector\n class=\"custom-editor\"\n value-key=\"target\"\n .value=${target}\n ></ox-editor-board-selector>\n `\n : html`\n <input\n value-key=\"target\"\n .value=${target}\n list=\"target-list\"\n .placeholder=${this._getPlaceHoder(action)}\n @focusin=${() => {\n this.targetList = this._getTargetList(action)\n }}\n />\n\n <datalist id=\"target-list\">\n ${this.targetList.map(\n ({ value, description }) => html` <option .value=${value}>${description}</option> `\n )}\n </datalist>\n `}\n ${action === 'goto' || action === 'goto-playlist' || action?.includes('popup')\n ? html`\n <label for=\"input\"> <ox-i18n msgid=\"label.input-data\">input</ox-i18n> </label>\n <input\n id=\"input\"\n value-key=\"input\"\n .value=${input}\n list=\"input-list\"\n @focusin=${() => {\n this.targetList = this._getInputList(action)\n }}\n />\n <datalist id=\"input-list\">\n ${this.targetList.map(\n ({ value, description }) => html` <option .value=${value}>${description}</option> `\n )}\n </datalist>\n ${\n /* currently 'goto' does not support returning result */\n action?.includes('popup')\n ? html` <input id=\"checkbox-output\" type=\"checkbox\" value-key=\"output\" .checked=${output} />\n <label for=\"checkbox-output\" class=\"checkbox-label\">\n <ox-i18n msgid=\"label.will-get-return\">will-get-return</ox-i18n>\n </label>`\n : html``\n }\n `\n : SETS_ACTION.indexOf(action) != -1\n ? html`\n <label> <ox-i18n msgid=\"label.value\">value</ox-i18n> </label>\n <ox-input-data\n class=\"custom-editor fullwidth\"\n value-key=\"value\"\n .value=${value}\n fullwidth\n ></ox-input-data>\n `\n : html``}\n </div>\n `\n }\n\n _getPlaceHoder(action: string) {\n switch (action) {\n case 'link-open':\n case 'link-move':\n return 'http://www.hatiolab.com/'\n case 'export-data':\n return 'abc.xlsx'\n default:\n return ''\n }\n }\n\n _getTargetList(action: string): { value: string; description: string }[] {\n switch (action) {\n case 'data-toggle':\n case 'data-tristate':\n case 'data-set':\n case 'value-set':\n case 'popup':\n case 'modal-popup':\n case 'data-spreading':\n let ids =\n (this.scene &&\n this.scene.ids.map((i: any) => {\n const id = i.key\n return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }\n })) ||\n []\n ids.unshift({ value: '(self)', description: 'self component' })\n return ids\n case 'infoWindow':\n case 'toggle-info-window':\n return (\n (this.scene &&\n this.scene.ids\n .filter((i: any) => {\n return this.scene!.findById(i.key).get('type') == 'info-window'\n })\n .map((i: any) => {\n const id = i.key\n return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }\n })) ||\n []\n )\n case 'start-scenario':\n case 'run-scenario':\n return this.scenarios\n case 'goto-playlist':\n return this.playlists\n case 'export-data':\n default:\n return []\n }\n }\n\n _getInputList(action: string): { value: string; description: string }[] {\n switch (action) {\n case 'popup':\n case 'modal-popup':\n case 'data-spreading':\n case 'goto':\n case 'goto-playlist':\n let ids =\n (this.scene &&\n this.scene.ids.map((i: any) => {\n const id = i.key\n return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }\n })) ||\n []\n ids.unshift({ value: '(self)', description: 'self component' })\n return ids\n default:\n return []\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 if (key === 'input' || key === 'output') {\n var { options = {} } = this.value || {}\n\n this.value = {\n ...this.value,\n options: {\n ...options,\n [key]: convert(element)\n }\n }\n } else {\n this.value = {\n ...this.value,\n [key]: convert(element)\n }\n }\n\n var { action } = this.value\n if (action !== 'goto' && action !== 'goto-playlist' && !action?.includes('popup')) {\n /* clear unused options */\n delete this.value.options\n }\n\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"property-event-tap.js","sourceRoot":"","sources":["../../../../src/property-panel/effects/property-event-tap.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/input/ox-input-data.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { property, state } from 'lit/decorators.js'\n\nimport { Properties, Scene } from '@hatiolab/things-scene'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\n\nimport { scenarios } from '../../graphql/scenario.js'\nimport { playlists } from '../../graphql/play-group.js'\nimport { convert } from './value-converter.js'\n\nconst SETS_ACTION = ['data-set', 'partial-data-set', 'value-set', 'partial-value-set', 'start-scenario', 'run-scenario']\n\nexport class PropertyEventTap extends LitElement {\n static styles = [\n PropertyGridStyles,\n css`\n :host {\n display: flex;\n }\n `\n ]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n\n @state() scenarios: { value: string; description: string }[] = []\n @state() playlists: { value: string; description: string }[] = []\n @state() targetList: { value: string; description: string }[] = []\n\n async firstUpdated() {\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n }\n\n render() {\n var { action, value = '', target = '', pressed, options } = this.value || {}\n var { input = '(self)', output = true } = options || {}\n\n return html`\n <div class=\"property-grid\">\n <input id=\"checkbox-pressed\" type=\"checkbox\" value-key=\"pressed\" .checked=${pressed} />\n <label for=\"checkbox-pressed\" class=\"checkbox-label\"> <ox-i18n msgid=\"label.pressed\">pressed</ox-i18n> </label>\n\n <label> <ox-i18n msgid=\"label.tap-action\">tap action</ox-i18n> </label>\n <select\n id=\"tap-select\"\n value-key=\"action\"\n .value=${action || ''}\n @change=${async (e: Event) => {\n if ((e.target as HTMLSelectElement).value.includes('scenario')) {\n this.scenarios = (await scenarios()).map(({ name, description }) => {\n return { value: name, description }\n })\n } else if ((e.target as HTMLSelectElement).value == 'goto-playlist') {\n this.playlists = (await playlists()).map(({ name, description }) => {\n return { value: name, description }\n })\n }\n }}\n >\n <option value=\"\"></option>\n <option value=\"goto\">go to target board</option>\n <option value=\"goto-playlist\">go to target playlist</option>\n <option value=\"link-open\">open new window for target link</option>\n <option value=\"link-move\">move to target link</option>\n <option value=\"route-page\">route to page</option>\n <option value=\"popup\">popup target board</option>\n <option value=\"modal-popup\">modal popup target board</option>\n <option value=\"inline-popup\">inline popup (target = popup component)</option>\n <option value=\"inline-modal-popup\">inline modal popup (target = popup component)</option>\n <option value=\"close-scene\">close current board</option>\n <option value=\"infoWindow\">open infowindow</option>\n <option value=\"toggle-info-window\">toggle infowindow</option>\n <option value=\"data-toggle\">toggle(true/false) target component data</option>\n <option value=\"data-tristate\">tristate(0/1/2) target component data</option>\n <option value=\"data-spreading\">forcely execute data spreading of target component</option>\n <option value=\"data-set\">set value to target component data</option>\n <option value=\"partial-data-set\">set partial value to target component data</option>\n <option value=\"value-set\">set value to target component value</option>\n <option value=\"partial-value-set\">set partial value to target component value</option>\n <option value=\"start-scenario\">start the given scenario</option>\n <option value=\"run-scenario\">run the given scenario</option>\n <option value=\"export-data\">export data</option>\n <option value=\"import-data\">import data</option>\n </select>\n\n <label> <ox-i18n msgid=\"label.target\">target</ox-i18n> </label>\n\n ${action === 'goto' || action === 'popup' || action === 'modal-popup'\n ? html`\n <ox-editor-board-selector\n class=\"custom-editor\"\n value-key=\"target\"\n .value=${target}\n ></ox-editor-board-selector>\n `\n : html`\n <input\n value-key=\"target\"\n .value=${target}\n list=\"target-list\"\n .placeholder=${this._getPlaceHoder(action)}\n @focusin=${() => {\n this.targetList = this._getTargetList(action)\n }}\n />\n\n <datalist id=\"target-list\">\n ${this.targetList.map(\n ({ value, description }) => html` <option .value=${value}>${description}</option> `\n )}\n </datalist>\n `}\n ${action === 'goto' || action === 'goto-playlist' || action?.includes('popup')\n ? html`\n <label for=\"input\"> <ox-i18n msgid=\"label.input-data\">input</ox-i18n> </label>\n <input\n id=\"input\"\n value-key=\"input\"\n .value=${input}\n list=\"input-list\"\n @focusin=${() => {\n this.targetList = this._getInputList(action)\n }}\n />\n <datalist id=\"input-list\">\n ${this.targetList.map(\n ({ value, description }) => html` <option .value=${value}>${description}</option> `\n )}\n </datalist>\n ${\n /* currently 'goto' does not support returning result */\n action?.includes('popup')\n ? html` <input id=\"checkbox-output\" type=\"checkbox\" value-key=\"output\" .checked=${output} />\n <label for=\"checkbox-output\" class=\"checkbox-label\">\n <ox-i18n msgid=\"label.will-get-return\">will-get-return</ox-i18n>\n </label>`\n : html``\n }\n `\n : SETS_ACTION.indexOf(action) != -1\n ? html`\n <label> <ox-i18n msgid=\"label.value\">value</ox-i18n> </label>\n <ox-input-data\n class=\"custom-editor fullwidth\"\n value-key=\"value\"\n .value=${value}\n fullwidth\n ></ox-input-data>\n `\n : html``}\n </div>\n `\n }\n\n _getPlaceHoder(action: string) {\n switch (action) {\n case 'link-open':\n case 'link-move':\n return 'http://www.hatiolab.com/'\n case 'export-data':\n return 'abc.xlsx'\n default:\n return ''\n }\n }\n\n _getTargetList(action: string): { value: string; description: string }[] {\n switch (action) {\n case 'data-toggle':\n case 'data-tristate':\n case 'data-set':\n case 'value-set':\n case 'popup':\n case 'modal-popup':\n case 'data-spreading':\n let ids =\n (this.scene &&\n this.scene.ids.map((i: any) => {\n const id = i.key\n return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }\n })) ||\n []\n ids.unshift({ value: '(self)', description: 'self component' })\n return ids\n case 'infoWindow':\n case 'toggle-info-window':\n return (\n (this.scene &&\n this.scene.ids\n .filter((i: any) => {\n return this.scene!.findById(i.key).get('type') == 'info-window'\n })\n .map((i: any) => {\n const id = i.key\n return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }\n })) ||\n []\n )\n case 'inline-popup':\n case 'inline-modal-popup':\n /* target = 같은 보드의 popup-container (또는 state.position='popup' 인 일반 Container) id.\n * 모든 보드 내 popup template 후보를 select 으로 노출. 액션 핸들러는 그 컨테이너를\n * 템플릿으로 fresh 인스턴스 생성하여 popup 으로 표시. */\n return (\n (this.scene &&\n this.scene.ids\n .filter((i: any) => {\n const c = this.scene!.findById(i.key)\n return c.get('type') === 'popup-container' || c.getState?.('position') === 'popup'\n })\n .map((i: any) => {\n const id = i.key\n return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }\n })) ||\n []\n )\n case 'start-scenario':\n case 'run-scenario':\n return this.scenarios\n case 'goto-playlist':\n return this.playlists\n case 'export-data':\n default:\n return []\n }\n }\n\n _getInputList(action: string): { value: string; description: string }[] {\n switch (action) {\n case 'popup':\n case 'modal-popup':\n case 'data-spreading':\n case 'goto':\n case 'goto-playlist':\n let ids =\n (this.scene &&\n this.scene.ids.map((i: any) => {\n const id = i.key\n return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }\n })) ||\n []\n ids.unshift({ value: '(self)', description: 'self component' })\n return ids\n default:\n return []\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 if (key === 'input' || key === 'output') {\n var { options = {} } = this.value || {}\n\n this.value = {\n ...this.value,\n options: {\n ...options,\n [key]: convert(element)\n }\n }\n } else {\n this.value = {\n ...this.value,\n [key]: convert(element)\n }\n }\n\n var { action } = this.value\n if (action !== 'goto' && action !== 'goto-playlist' && !action?.includes('popup')) {\n /* clear unused options */\n delete this.value.options\n }\n\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n }\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* placeholder → 도메인 type 변환 property editor.
|
|
5
|
+
*
|
|
6
|
+
* GenericObject.nature.properties 에 `{ type: 'placeholder-convert', name: '_convert' }` 로
|
|
7
|
+
* 선언되어 specific 탭에서 자동 렌더링. 별도 사용처 없음 — nature 선언으로 충분.
|
|
8
|
+
*
|
|
9
|
+
* 변환 흐름:
|
|
10
|
+
* 타입 버튼 클릭 → i-need-selected → specifics.ts undoableChange → convertComponentType
|
|
11
|
+
*/
|
|
12
|
+
import { TemplateResult } from 'lit';
|
|
13
|
+
import { OxPropertyEditor } from '@operato/property-editor';
|
|
14
|
+
import type { PropertySpec } from '@operato/property-editor';
|
|
15
|
+
export declare class OxPlaceholderConvertEditor extends OxPropertyEditor {
|
|
16
|
+
static styles: import("lit").CSSResult[];
|
|
17
|
+
private _search;
|
|
18
|
+
editorTemplate(_value: any, _spec: PropertySpec): TemplateResult;
|
|
19
|
+
private _onConvert;
|
|
20
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* placeholder → 도메인 type 변환 property editor.
|
|
5
|
+
*
|
|
6
|
+
* GenericObject.nature.properties 에 `{ type: 'placeholder-convert', name: '_convert' }` 로
|
|
7
|
+
* 선언되어 specific 탭에서 자동 렌더링. 별도 사용처 없음 — nature 선언으로 충분.
|
|
8
|
+
*
|
|
9
|
+
* 변환 흐름:
|
|
10
|
+
* 타입 버튼 클릭 → i-need-selected → specifics.ts undoableChange → convertComponentType
|
|
11
|
+
*/
|
|
12
|
+
import { __decorate } from "tslib";
|
|
13
|
+
import { css, html } from 'lit';
|
|
14
|
+
import { customElement, state } from 'lit/decorators.js';
|
|
15
|
+
import { OxPropertyEditor } from '@operato/property-editor';
|
|
16
|
+
import { convertComponentType, getConvertibleTypes } from './placeholder-convert.js';
|
|
17
|
+
OxPropertyEditor.register({ 'placeholder-convert': 'ox-placeholder-convert-editor' });
|
|
18
|
+
let OxPlaceholderConvertEditor = class OxPlaceholderConvertEditor extends OxPropertyEditor {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this._search = '';
|
|
22
|
+
}
|
|
23
|
+
editorTemplate(_value, _spec) {
|
|
24
|
+
const all = getConvertibleTypes();
|
|
25
|
+
const q = this._search.trim().toLowerCase();
|
|
26
|
+
const candidates = q ? all.filter(t => t.toLowerCase().includes(q)) : all;
|
|
27
|
+
return html `
|
|
28
|
+
<div class="convert-wrap fullwidth">
|
|
29
|
+
<input
|
|
30
|
+
type="search"
|
|
31
|
+
class="convert-search"
|
|
32
|
+
placeholder="search type to convert to..."
|
|
33
|
+
.value=${this._search}
|
|
34
|
+
@input=${(e) => {
|
|
35
|
+
this._search = e.target.value;
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
38
|
+
<div class="convert-list">
|
|
39
|
+
${candidates.length === 0
|
|
40
|
+
? html `<div class="empty">no matching type</div>`
|
|
41
|
+
: candidates.map(type => html `
|
|
42
|
+
<button class="convert-item" @click=${() => this._onConvert(type)} title=${`convert to ${type}`}>
|
|
43
|
+
${type}
|
|
44
|
+
</button>
|
|
45
|
+
`)}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
50
|
+
_onConvert(newType) {
|
|
51
|
+
this.dispatchEvent(new CustomEvent('i-need-selected', {
|
|
52
|
+
bubbles: true,
|
|
53
|
+
composed: true,
|
|
54
|
+
detail: {
|
|
55
|
+
callback: (selected) => {
|
|
56
|
+
if (selected[0])
|
|
57
|
+
convertComponentType(selected[0], newType);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
this._search = '';
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
OxPlaceholderConvertEditor.styles = [
|
|
65
|
+
...OxPropertyEditor.styles,
|
|
66
|
+
css `
|
|
67
|
+
.convert-wrap {
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
gap: 4px;
|
|
71
|
+
padding: 4px 0;
|
|
72
|
+
}
|
|
73
|
+
.convert-search {
|
|
74
|
+
font-size: 12px;
|
|
75
|
+
padding: 4px 8px;
|
|
76
|
+
border: 1px solid var(--md-sys-color-outline-variant, #d0d7de);
|
|
77
|
+
border-radius: 4px;
|
|
78
|
+
background: var(--md-sys-color-surface, #fff);
|
|
79
|
+
color: var(--md-sys-color-on-surface, #000);
|
|
80
|
+
outline: none;
|
|
81
|
+
}
|
|
82
|
+
.convert-search:focus {
|
|
83
|
+
border-color: var(--md-sys-color-primary, #2a64d8);
|
|
84
|
+
}
|
|
85
|
+
.convert-list {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
gap: 2px;
|
|
89
|
+
max-height: 200px;
|
|
90
|
+
overflow-y: auto;
|
|
91
|
+
background: var(--md-sys-color-surface, #fff);
|
|
92
|
+
border-radius: 4px;
|
|
93
|
+
padding: 2px;
|
|
94
|
+
}
|
|
95
|
+
.convert-list .empty {
|
|
96
|
+
text-align: center;
|
|
97
|
+
font-size: 11px;
|
|
98
|
+
padding: 8px;
|
|
99
|
+
color: var(--md-sys-color-on-secondary-container, #777);
|
|
100
|
+
}
|
|
101
|
+
.convert-item {
|
|
102
|
+
text-align: left;
|
|
103
|
+
font-size: 12px;
|
|
104
|
+
font-family: monospace;
|
|
105
|
+
padding: 4px 8px;
|
|
106
|
+
background: transparent;
|
|
107
|
+
border: 1px solid transparent;
|
|
108
|
+
border-radius: 3px;
|
|
109
|
+
cursor: pointer;
|
|
110
|
+
color: var(--md-sys-color-on-surface, #000);
|
|
111
|
+
}
|
|
112
|
+
.convert-item:hover {
|
|
113
|
+
background: var(--md-sys-color-primary-container, #eaf2ff);
|
|
114
|
+
border-color: var(--md-sys-color-primary, #2a64d8);
|
|
115
|
+
}
|
|
116
|
+
`
|
|
117
|
+
];
|
|
118
|
+
__decorate([
|
|
119
|
+
state()
|
|
120
|
+
], OxPlaceholderConvertEditor.prototype, "_search", void 0);
|
|
121
|
+
OxPlaceholderConvertEditor = __decorate([
|
|
122
|
+
customElement('ox-placeholder-convert-editor')
|
|
123
|
+
], OxPlaceholderConvertEditor);
|
|
124
|
+
export { OxPlaceholderConvertEditor };
|
|
125
|
+
//# sourceMappingURL=ox-placeholder-convert-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ox-placeholder-convert-editor.js","sourceRoot":"","sources":["../../../../src/property-panel/shapes/ox-placeholder-convert-editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAG3D,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEpF,gBAAgB,CAAC,QAAQ,CAAC,EAAE,qBAAqB,EAAE,+BAA+B,EAAE,CAAC,CAAA;AAG9E,IAAM,0BAA0B,GAAhC,MAAM,0BAA2B,SAAQ,gBAAgB;IAAzD;;QAwDY,YAAO,GAAG,EAAE,CAAA;IA+C/B,CAAC;IA7CC,cAAc,CAAC,MAAW,EAAE,KAAmB;QAC7C,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAA;QACjC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC3C,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QAEzE,OAAO,IAAI,CAAA;;;;;;mBAMI,IAAI,CAAC,OAAO;mBACZ,CAAC,CAAQ,EAAE,EAAE;YACpB,IAAI,CAAC,OAAO,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAA;QACrD,CAAC;;;YAGC,UAAU,CAAC,MAAM,KAAK,CAAC;YACvB,CAAC,CAAC,IAAI,CAAA,2CAA2C;YACjD,CAAC,CAAC,UAAU,CAAC,GAAG,CACZ,IAAI,CAAC,EAAE,CAAC,IAAI,CAAA;wDAC4B,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,cAAc,IAAI,EAAE;sBAC3F,IAAI;;iBAET,CACF;;;KAGV,CAAA;IACH,CAAC;IAEO,UAAU,CAAC,OAAe;QAChC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;YACjC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,QAAQ,EAAE,CAAC,QAAqB,EAAE,EAAE;oBAClC,IAAI,QAAQ,CAAC,CAAC,CAAC;wBAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;gBAC7D,CAAC;aACF;SACF,CAAC,CACH,CAAA;QACD,IAAI,CAAC,OAAO,GAAG,EAAE,CAAA;IACnB,CAAC;;AArGM,iCAAM,GAAG;IACd,GAAG,gBAAgB,CAAC,MAAM;IAC1B,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkDF;CACF,AArDY,CAqDZ;AAEgB;IAAhB,KAAK,EAAE;2DAAqB;AAxDlB,0BAA0B;IADtC,aAAa,CAAC,+BAA+B,CAAC;GAClC,0BAA0B,CAuGtC","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * placeholder → 도메인 type 변환 property editor.\n *\n * GenericObject.nature.properties 에 `{ type: 'placeholder-convert', name: '_convert' }` 로\n * 선언되어 specific 탭에서 자동 렌더링. 별도 사용처 없음 — nature 선언으로 충분.\n *\n * 변환 흐름:\n * 타입 버튼 클릭 → i-need-selected → specifics.ts undoableChange → convertComponentType\n */\n\nimport { css, html, TemplateResult } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\nimport type { Component } from '@hatiolab/things-scene'\nimport { OxPropertyEditor } from '@operato/property-editor'\nimport type { PropertySpec } from '@operato/property-editor'\n\nimport { convertComponentType, getConvertibleTypes } from './placeholder-convert.js'\n\nOxPropertyEditor.register({ 'placeholder-convert': 'ox-placeholder-convert-editor' })\n\n@customElement('ox-placeholder-convert-editor')\nexport class OxPlaceholderConvertEditor extends OxPropertyEditor {\n static styles = [\n ...OxPropertyEditor.styles,\n css`\n .convert-wrap {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 4px 0;\n }\n .convert-search {\n font-size: 12px;\n padding: 4px 8px;\n border: 1px solid var(--md-sys-color-outline-variant, #d0d7de);\n border-radius: 4px;\n background: var(--md-sys-color-surface, #fff);\n color: var(--md-sys-color-on-surface, #000);\n outline: none;\n }\n .convert-search:focus {\n border-color: var(--md-sys-color-primary, #2a64d8);\n }\n .convert-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 200px;\n overflow-y: auto;\n background: var(--md-sys-color-surface, #fff);\n border-radius: 4px;\n padding: 2px;\n }\n .convert-list .empty {\n text-align: center;\n font-size: 11px;\n padding: 8px;\n color: var(--md-sys-color-on-secondary-container, #777);\n }\n .convert-item {\n text-align: left;\n font-size: 12px;\n font-family: monospace;\n padding: 4px 8px;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 3px;\n cursor: pointer;\n color: var(--md-sys-color-on-surface, #000);\n }\n .convert-item:hover {\n background: var(--md-sys-color-primary-container, #eaf2ff);\n border-color: var(--md-sys-color-primary, #2a64d8);\n }\n `\n ]\n\n @state() private _search = ''\n\n editorTemplate(_value: any, _spec: PropertySpec): TemplateResult {\n const all = getConvertibleTypes()\n const q = this._search.trim().toLowerCase()\n const candidates = q ? all.filter(t => t.toLowerCase().includes(q)) : all\n\n return html`\n <div class=\"convert-wrap fullwidth\">\n <input\n type=\"search\"\n class=\"convert-search\"\n placeholder=\"search type to convert to...\"\n .value=${this._search}\n @input=${(e: Event) => {\n this._search = (e.target as HTMLInputElement).value\n }}\n />\n <div class=\"convert-list\">\n ${candidates.length === 0\n ? html`<div class=\"empty\">no matching type</div>`\n : candidates.map(\n type => html`\n <button class=\"convert-item\" @click=${() => this._onConvert(type)} title=${`convert to ${type}`}>\n ${type}\n </button>\n `\n )}\n </div>\n </div>\n `\n }\n\n private _onConvert(newType: string) {\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: (selected: Component[]) => {\n if (selected[0]) convertComponentType(selected[0], newType)\n }\n }\n })\n )\n this._search = ''\n }\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Placeholder → 도메인 type 변환 helper.
|
|
5
|
+
*
|
|
6
|
+
* 대상: board-import 가 떨어뜨린 generic-* placeholder 컴포넌트 — 사용자가 모델러에서
|
|
7
|
+
* 구체 type 으로 변환하는 액션. property-panel 의 shapes 섹션이 호출.
|
|
8
|
+
*
|
|
9
|
+
* 정책:
|
|
10
|
+
* - **placeholder type 한정** — 일반 컴포넌트 (Stocker, Forklift 등) 는 대상 X. 안전.
|
|
11
|
+
* - things-scene 의 `Scene.undoableChange` 로 감싸 undo/redo 자연스럽게 통합.
|
|
12
|
+
* - 좌표/크기/회전/id 보존. 새 type 의 default state 는 클래스 생성자가 처리.
|
|
13
|
+
*
|
|
14
|
+
* things-scene 의 컴포넌트 type 변경은 클래스 자체 교체가 필요 (메서드 binding 이라).
|
|
15
|
+
* 단순 `state.type` 갱신으론 부족 → 기존 컴포넌트 제거 + 새 type 으로 compile + 같은 위치에 추가.
|
|
16
|
+
*/
|
|
17
|
+
import { Component } from '@hatiolab/things-scene';
|
|
18
|
+
/**
|
|
19
|
+
* 변환 대상 placeholder 인지 판정. property-panel 의 conditional 렌더 가드.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isPlaceholderComponent(component: Component | undefined | null): boolean;
|
|
22
|
+
export declare function getConvertibleTypes(): string[];
|
|
23
|
+
/**
|
|
24
|
+
* placeholder 를 새 type 으로 변환. 좌표/크기/회전/id 보존.
|
|
25
|
+
*
|
|
26
|
+
* 동작:
|
|
27
|
+
* 1) component.hierarchy 로 모델 snapshot
|
|
28
|
+
* 2) 새 모델 = snapshot + { type: newType }
|
|
29
|
+
* 3) Scene.undoableChange 안에서: removeSelf → compile(newModel) → parent.insertComponentAt 같은 index
|
|
30
|
+
* 4) snapshot-commander 가 자동으로 undoable snapshot 캡처
|
|
31
|
+
*
|
|
32
|
+
* 실패 (newType 미등록 / 컴포넌트 placeholder 아님 등) 시 throw.
|
|
33
|
+
*/
|
|
34
|
+
export declare function convertComponentType(component: Component, newType: string): void;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Placeholder → 도메인 type 변환 helper.
|
|
5
|
+
*
|
|
6
|
+
* 대상: board-import 가 떨어뜨린 generic-* placeholder 컴포넌트 — 사용자가 모델러에서
|
|
7
|
+
* 구체 type 으로 변환하는 액션. property-panel 의 shapes 섹션이 호출.
|
|
8
|
+
*
|
|
9
|
+
* 정책:
|
|
10
|
+
* - **placeholder type 한정** — 일반 컴포넌트 (Stocker, Forklift 등) 는 대상 X. 안전.
|
|
11
|
+
* - things-scene 의 `Scene.undoableChange` 로 감싸 undo/redo 자연스럽게 통합.
|
|
12
|
+
* - 좌표/크기/회전/id 보존. 새 type 의 default state 는 클래스 생성자가 처리.
|
|
13
|
+
*
|
|
14
|
+
* things-scene 의 컴포넌트 type 변경은 클래스 자체 교체가 필요 (메서드 binding 이라).
|
|
15
|
+
* 단순 `state.type` 갱신으론 부족 → 기존 컴포넌트 제거 + 새 type 으로 compile + 같은 위치에 추가.
|
|
16
|
+
*/
|
|
17
|
+
import { Component, Model } from '@hatiolab/things-scene';
|
|
18
|
+
/** 변환 가능한 placeholder type 모음. board-import 의 CORE_PLACEHOLDER_TYPES 와 동기화.
|
|
19
|
+
* 도메인 generic 추상 (GenericTransport, GenericFacility 등) 은 GLB 바디 교체 전용 —
|
|
20
|
+
* 여기에 포함하지 않는다 (변환 아닌 GLB attach 가 별도 UI).
|
|
21
|
+
*/
|
|
22
|
+
const PLACEHOLDER_TYPES = new Set([
|
|
23
|
+
'placeholder',
|
|
24
|
+
'GenericObject' // 구버전 PascalCase 호환
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* 변환 대상 placeholder 인지 판정. property-panel 의 conditional 렌더 가드.
|
|
28
|
+
*/
|
|
29
|
+
export function isPlaceholderComponent(component) {
|
|
30
|
+
var _a;
|
|
31
|
+
if (!component)
|
|
32
|
+
return false;
|
|
33
|
+
return PLACEHOLDER_TYPES.has((_a = component.state) === null || _a === void 0 ? void 0 : _a.type);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 변환 후보 type 목록 — 등록된 모든 component type 중 placeholder 자기 자신 + 시스템 type
|
|
37
|
+
* (root container, layer 등) 제외. property-panel dropdown 후보에 사용.
|
|
38
|
+
*/
|
|
39
|
+
const SYSTEM_TYPES = new Set([
|
|
40
|
+
'root',
|
|
41
|
+
'root-container',
|
|
42
|
+
'group',
|
|
43
|
+
'layer',
|
|
44
|
+
'model-layer',
|
|
45
|
+
'tool-layer',
|
|
46
|
+
'modeler-layer'
|
|
47
|
+
]);
|
|
48
|
+
export function getConvertibleTypes() {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
const all = (_b = (_a = Component).types) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
51
|
+
if (!all)
|
|
52
|
+
return [];
|
|
53
|
+
return all
|
|
54
|
+
.filter(t => !PLACEHOLDER_TYPES.has(t))
|
|
55
|
+
.filter(t => !SYSTEM_TYPES.has(t))
|
|
56
|
+
.sort();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* placeholder 를 새 type 으로 변환. 좌표/크기/회전/id 보존.
|
|
60
|
+
*
|
|
61
|
+
* 동작:
|
|
62
|
+
* 1) component.hierarchy 로 모델 snapshot
|
|
63
|
+
* 2) 새 모델 = snapshot + { type: newType }
|
|
64
|
+
* 3) Scene.undoableChange 안에서: removeSelf → compile(newModel) → parent.insertComponentAt 같은 index
|
|
65
|
+
* 4) snapshot-commander 가 자동으로 undoable snapshot 캡처
|
|
66
|
+
*
|
|
67
|
+
* 실패 (newType 미등록 / 컴포넌트 placeholder 아님 등) 시 throw.
|
|
68
|
+
*/
|
|
69
|
+
export function convertComponentType(component, newType) {
|
|
70
|
+
if (!isPlaceholderComponent(component)) {
|
|
71
|
+
throw new Error(`Component (type=${component.state.type}) is not a placeholder — convert restricted to placeholders only.`);
|
|
72
|
+
}
|
|
73
|
+
const clazz = Component.register(newType);
|
|
74
|
+
if (!clazz) {
|
|
75
|
+
throw new Error(`Unknown component type: ${newType}`);
|
|
76
|
+
}
|
|
77
|
+
if (PLACEHOLDER_TYPES.has(newType)) {
|
|
78
|
+
throw new Error(`Cannot convert to another placeholder type: ${newType}`);
|
|
79
|
+
}
|
|
80
|
+
const app = component.app;
|
|
81
|
+
if (!(app === null || app === void 0 ? void 0 : app.commander))
|
|
82
|
+
throw new Error('Component is not attached to an app/scene.');
|
|
83
|
+
const oldHierarchy = JSON.parse(JSON.stringify(component.hierarchy));
|
|
84
|
+
const newModel = {
|
|
85
|
+
...oldHierarchy,
|
|
86
|
+
type: newType
|
|
87
|
+
};
|
|
88
|
+
performTypeSwap(component, newModel);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 공통 swap 로직 — Scene.undoableChange 안에서 component 를 새 모델로 교체.
|
|
92
|
+
* snapshot-commander 가 자동으로 undoable 처리.
|
|
93
|
+
*/
|
|
94
|
+
function performTypeSwap(component, newModel) {
|
|
95
|
+
var _a, _b, _c, _d;
|
|
96
|
+
const app = component.app;
|
|
97
|
+
const parent = component.parent;
|
|
98
|
+
if (!parent)
|
|
99
|
+
throw new Error('Component has no parent — cannot swap.');
|
|
100
|
+
// children 인덱스 (insertComponentAt 으로 같은 위치 보존)
|
|
101
|
+
const siblings = parent.components;
|
|
102
|
+
const index = siblings ? siblings.indexOf(component) : -1;
|
|
103
|
+
(_b = (_a = component).removeSelf) === null || _b === void 0 ? void 0 : _b.call(_a, false);
|
|
104
|
+
const newComp = Model.compile(newModel, app);
|
|
105
|
+
if (!newComp) {
|
|
106
|
+
throw new Error(`Failed to compile new component type: ${newModel.type}`);
|
|
107
|
+
}
|
|
108
|
+
if (index >= 0 && parent.insertComponentAt) {
|
|
109
|
+
;
|
|
110
|
+
parent.insertComponentAt(newComp, index);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
;
|
|
114
|
+
(_d = (_c = parent).addComponent) === null || _d === void 0 ? void 0 : _d.call(_c, newComp);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=placeholder-convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeholder-convert.js","sourceRoot":"","sources":["../../../../src/property-panel/shapes/placeholder-convert.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAEzD;;;GAGG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,aAAa;IACb,eAAe,CAAC,oBAAoB;CACrC,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAuC;;IAC5E,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAA;IAC5B,OAAO,iBAAiB,CAAC,GAAG,CAAC,MAAA,SAAS,CAAC,KAAK,0CAAE,IAAc,CAAC,CAAA;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,MAAM;IACN,gBAAgB;IAChB,OAAO;IACP,OAAO;IACP,aAAa;IACb,YAAY;IACZ,eAAe;CAChB,CAAC,CAAA;AAEF,MAAM,UAAU,mBAAmB;;IACjC,MAAM,GAAG,GAAG,MAAA,MAAC,SAAiB,EAAC,KAAK,kDAA4B,CAAA;IAChE,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAA;IACnB,OAAO,GAAG;SACP,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACjC,IAAI,EAAE,CAAA;AACX,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAoB,EAAE,OAAe;IACxE,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,mBAAmB,SAAS,CAAC,KAAK,CAAC,IAAI,mEAAmE,CAC3G,CAAA;IACH,CAAC;IACD,MAAM,KAAK,GAAI,SAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAClD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAA;IACvD,CAAC;IACD,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,+CAA+C,OAAO,EAAE,CAAC,CAAA;IAC3E,CAAC;IAED,MAAM,GAAG,GAAI,SAAiB,CAAC,GAAG,CAAA;IAClC,IAAI,CAAC,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,SAAS,CAAA;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;IAElF,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAE,SAAiB,CAAC,SAAS,CAAC,CAAC,CAAA;IAC7E,MAAM,QAAQ,GAAwB;QACpC,GAAG,YAAY;QACf,IAAI,EAAE,OAAO;KACd,CAAA;IAED,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;AACtC,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,SAAoB,EAAE,QAA6B;;IAC1E,MAAM,GAAG,GAAI,SAAiB,CAAC,GAAG,CAAA;IAClC,MAAM,MAAM,GAAI,SAAiB,CAAC,MAAM,CAAA;IACxC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;IAEtE,+CAA+C;IAC/C,MAAM,QAAQ,GAAI,MAAc,CAAC,UAAqC,CAAA;IACtE,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAGxD;IAAA,MAAA,MAAC,SAAiB,EAAC,UAAU,mDAAG,KAAK,CAAC,CAAA;IACvC,MAAM,OAAO,GAAI,KAAa,CAAC,OAAO,CAAC,QAAe,EAAE,GAAG,CAAC,CAAA;IAC5D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,yCAAyC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAC3E,CAAC;IACD,IAAI,KAAK,IAAI,CAAC,IAAK,MAAc,CAAC,iBAAiB,EAAE,CAAC;QACpD,CAAC;QAAC,MAAc,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACpD,CAAC;SAAM,CAAC;QACN,CAAC;QAAA,MAAA,MAAC,MAAc,EAAC,YAAY,mDAAG,OAAO,CAAC,CAAA;IAC1C,CAAC;AACH,CAAC","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * Placeholder → 도메인 type 변환 helper.\n *\n * 대상: board-import 가 떨어뜨린 generic-* placeholder 컴포넌트 — 사용자가 모델러에서\n * 구체 type 으로 변환하는 액션. property-panel 의 shapes 섹션이 호출.\n *\n * 정책:\n * - **placeholder type 한정** — 일반 컴포넌트 (Stocker, Forklift 등) 는 대상 X. 안전.\n * - things-scene 의 `Scene.undoableChange` 로 감싸 undo/redo 자연스럽게 통합.\n * - 좌표/크기/회전/id 보존. 새 type 의 default state 는 클래스 생성자가 처리.\n *\n * things-scene 의 컴포넌트 type 변경은 클래스 자체 교체가 필요 (메서드 binding 이라).\n * 단순 `state.type` 갱신으론 부족 → 기존 컴포넌트 제거 + 새 type 으로 compile + 같은 위치에 추가.\n */\n\nimport { Component, Model } from '@hatiolab/things-scene'\n\n/** 변환 가능한 placeholder type 모음. board-import 의 CORE_PLACEHOLDER_TYPES 와 동기화.\n * 도메인 generic 추상 (GenericTransport, GenericFacility 등) 은 GLB 바디 교체 전용 —\n * 여기에 포함하지 않는다 (변환 아닌 GLB attach 가 별도 UI).\n */\nconst PLACEHOLDER_TYPES = new Set([\n 'placeholder',\n 'GenericObject' // 구버전 PascalCase 호환\n])\n\n/**\n * 변환 대상 placeholder 인지 판정. property-panel 의 conditional 렌더 가드.\n */\nexport function isPlaceholderComponent(component: Component | undefined | null): boolean {\n if (!component) return false\n return PLACEHOLDER_TYPES.has(component.state?.type as string)\n}\n\n/**\n * 변환 후보 type 목록 — 등록된 모든 component type 중 placeholder 자기 자신 + 시스템 type\n * (root container, layer 등) 제외. property-panel dropdown 후보에 사용.\n */\nconst SYSTEM_TYPES = new Set([\n 'root',\n 'root-container',\n 'group',\n 'layer',\n 'model-layer',\n 'tool-layer',\n 'modeler-layer'\n])\n\nexport function getConvertibleTypes(): string[] {\n const all = (Component as any).types?.() as string[] | undefined\n if (!all) return []\n return all\n .filter(t => !PLACEHOLDER_TYPES.has(t))\n .filter(t => !SYSTEM_TYPES.has(t))\n .sort()\n}\n\n/**\n * placeholder 를 새 type 으로 변환. 좌표/크기/회전/id 보존.\n *\n * 동작:\n * 1) component.hierarchy 로 모델 snapshot\n * 2) 새 모델 = snapshot + { type: newType }\n * 3) Scene.undoableChange 안에서: removeSelf → compile(newModel) → parent.insertComponentAt 같은 index\n * 4) snapshot-commander 가 자동으로 undoable snapshot 캡처\n *\n * 실패 (newType 미등록 / 컴포넌트 placeholder 아님 등) 시 throw.\n */\nexport function convertComponentType(component: Component, newType: string): void {\n if (!isPlaceholderComponent(component)) {\n throw new Error(\n `Component (type=${component.state.type}) is not a placeholder — convert restricted to placeholders only.`\n )\n }\n const clazz = (Component as any).register(newType)\n if (!clazz) {\n throw new Error(`Unknown component type: ${newType}`)\n }\n if (PLACEHOLDER_TYPES.has(newType)) {\n throw new Error(`Cannot convert to another placeholder type: ${newType}`)\n }\n\n const app = (component as any).app\n if (!app?.commander) throw new Error('Component is not attached to an app/scene.')\n\n const oldHierarchy = JSON.parse(JSON.stringify((component as any).hierarchy))\n const newModel: Record<string, any> = {\n ...oldHierarchy,\n type: newType\n }\n\n performTypeSwap(component, newModel)\n}\n\n/**\n * 공통 swap 로직 — Scene.undoableChange 안에서 component 를 새 모델로 교체.\n * snapshot-commander 가 자동으로 undoable 처리.\n */\nfunction performTypeSwap(component: Component, newModel: Record<string, any>): void {\n const app = (component as any).app\n const parent = (component as any).parent\n if (!parent) throw new Error('Component has no parent — cannot swap.')\n\n // children 인덱스 (insertComponentAt 으로 같은 위치 보존)\n const siblings = (parent as any).components as Component[] | undefined\n const index = siblings ? siblings.indexOf(component) : -1\n\n // 호출자(specifics.ts의 i-need-selected → undoableChange)가 이미 감싸므로 직접 실행.\n ;(component as any).removeSelf?.(false)\n const newComp = (Model as any).compile(newModel as any, app)\n if (!newComp) {\n throw new Error(`Failed to compile new component type: ${newModel.type}`)\n }\n if (index >= 0 && (parent as any).insertComponentAt) {\n ;(parent as any).insertComponentAt(newComp, index)\n } else {\n ;(parent as any).addComponent?.(newComp)\n }\n}\n"]}
|
|
@@ -7,7 +7,7 @@ import '@operato/input/ox-buttons-radio.js';
|
|
|
7
7
|
import '@material/web/icon/icon.js';
|
|
8
8
|
import '@operato/i18n/ox-i18n.js';
|
|
9
9
|
import '@operato/help/ox-title-with-help.js';
|
|
10
|
-
import { html } from 'lit';
|
|
10
|
+
import { css, html } from 'lit';
|
|
11
11
|
import { property, state } from 'lit/decorators.js';
|
|
12
12
|
import { keyed } from 'lit/directives/keyed.js';
|
|
13
13
|
import { PropertyGridStyles } from '@operato/styles/property-grid-styles.js';
|
|
@@ -118,6 +118,7 @@ export class PropertyShapes extends AbstractProperty {
|
|
|
118
118
|
<option value="absolute">absolute</option>
|
|
119
119
|
<option value="fixed">fixed</option>
|
|
120
120
|
<option value="sticky">sticky</option>
|
|
121
|
+
<option value="popup">popup (template)</option>
|
|
121
122
|
</select>
|
|
122
123
|
|
|
123
124
|
<label>Origin</label>
|
|
@@ -315,7 +316,12 @@ export class PropertyShapes extends AbstractProperty {
|
|
|
315
316
|
return true;
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
|
-
PropertyShapes.styles = [
|
|
319
|
+
PropertyShapes.styles = [
|
|
320
|
+
PropertyGridStyles,
|
|
321
|
+
BoxPaddingEditorStyles,
|
|
322
|
+
css `
|
|
323
|
+
`
|
|
324
|
+
];
|
|
319
325
|
__decorate([
|
|
320
326
|
property({ type: Object })
|
|
321
327
|
], PropertyShapes.prototype, "value", void 0);
|