@operato/scene-visualizer 10.0.0-beta.8 → 10.0.0-beta.9
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/dist/editors/index.d.ts +1 -0
- package/dist/editors/index.js +5 -0
- package/dist/editors/index.js.map +1 -1
- package/dist/editors/property-editor-stocker-location.d.ts +13 -0
- package/dist/editors/property-editor-stocker-location.js +151 -0
- package/dist/editors/property-editor-stocker-location.js.map +1 -0
- package/dist/editors/property-editor-stocker-ports.d.ts +8 -0
- package/dist/editors/property-editor-stocker-ports.js +112 -0
- package/dist/editors/property-editor-stocker-ports.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/stocker-3d.d.ts +23 -0
- package/dist/stocker-3d.js +352 -0
- package/dist/stocker-3d.js.map +1 -0
- package/dist/stocker-port-3d.d.ts +14 -0
- package/dist/stocker-port-3d.js +80 -0
- package/dist/stocker-port-3d.js.map +1 -0
- package/dist/stocker-port.d.ts +254 -0
- package/dist/stocker-port.js +123 -0
- package/dist/stocker-port.js.map +1 -0
- package/dist/stocker.d.ts +340 -0
- package/dist/stocker.js +370 -0
- package/dist/stocker.js.map +1 -0
- package/dist/templates/index.d.ts +40 -0
- package/dist/templates/index.js +5 -1
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/stocker-port.d.ts +17 -0
- package/dist/templates/stocker-port.js +17 -0
- package/dist/templates/stocker-port.js.map +1 -0
- package/dist/templates/stocker.d.ts +27 -0
- package/dist/templates/stocker.js +38 -0
- package/dist/templates/stocker.js.map +1 -0
- package/package.json +2 -2
package/dist/editors/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import './property-editor-location-increase-pattern.js';
|
|
|
2
2
|
import './property-editor-gltf-info.js';
|
|
3
3
|
import './property-editor-gltf-fill-targets.js';
|
|
4
4
|
import './property-editor-gltf-play-targets.js';
|
|
5
|
+
import './property-editor-stocker-location.js';
|
|
5
6
|
declare const _default: {
|
|
6
7
|
type: string;
|
|
7
8
|
element: string;
|
package/dist/editors/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import './property-editor-location-increase-pattern.js';
|
|
|
2
2
|
import './property-editor-gltf-info.js';
|
|
3
3
|
import './property-editor-gltf-fill-targets.js';
|
|
4
4
|
import './property-editor-gltf-play-targets.js';
|
|
5
|
+
import './property-editor-stocker-location.js';
|
|
5
6
|
export default [
|
|
6
7
|
{
|
|
7
8
|
type: 'location-increase-pattern',
|
|
@@ -18,6 +19,10 @@ export default [
|
|
|
18
19
|
{
|
|
19
20
|
type: 'gltf-play-targets',
|
|
20
21
|
element: 'property-editor-gltf-play-targets'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'stocker-location',
|
|
25
|
+
element: 'property-editor-stocker-location'
|
|
21
26
|
}
|
|
22
27
|
];
|
|
23
28
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/editors/index.ts"],"names":[],"mappings":"AAAA,OAAO,gDAAgD,CAAA;AACvD,OAAO,gCAAgC,CAAA;AACvC,OAAO,wCAAwC,CAAA;AAC/C,OAAO,wCAAwC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/editors/index.ts"],"names":[],"mappings":"AAAA,OAAO,gDAAgD,CAAA;AACvD,OAAO,gCAAgC,CAAA;AACvC,OAAO,wCAAwC,CAAA;AAC/C,OAAO,wCAAwC,CAAA;AAC/C,OAAO,uCAAuC,CAAA;AAE9C,eAAe;IACb;QACE,IAAI,EAAE,2BAA2B;QACjC,OAAO,EAAE,2CAA2C;KACrD;IACD;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,2BAA2B;KACrC;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,mCAAmC;KAC7C;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,mCAAmC;KAC7C;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,kCAAkC;KAC5C;CACF,CAAA","sourcesContent":["import './property-editor-location-increase-pattern.js'\nimport './property-editor-gltf-info.js'\nimport './property-editor-gltf-fill-targets.js'\nimport './property-editor-gltf-play-targets.js'\nimport './property-editor-stocker-location.js'\n\nexport default [\n {\n type: 'location-increase-pattern',\n element: 'property-editor-location-increase-pattern'\n },\n {\n type: 'gltf-info',\n element: 'property-editor-gltf-info'\n },\n {\n type: 'gltf-fill-targets',\n element: 'property-editor-gltf-fill-targets'\n },\n {\n type: 'gltf-play-targets',\n element: 'property-editor-gltf-play-targets'\n },\n {\n type: 'stocker-location',\n element: 'property-editor-stocker-location'\n }\n]\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TemplateResult } from 'lit';
|
|
2
|
+
import { OxPropertyEditor, PropertySpec } from '@operato/property-editor';
|
|
3
|
+
export default class StockerLocationEditor extends OxPropertyEditor {
|
|
4
|
+
static styles: import("lit").CSSResult[];
|
|
5
|
+
private _rule;
|
|
6
|
+
private _lastExternalValue;
|
|
7
|
+
constructor();
|
|
8
|
+
private _parseValue;
|
|
9
|
+
editorTemplate(value: any, _spec: PropertySpec): TemplateResult;
|
|
10
|
+
private _set;
|
|
11
|
+
private _setSideLabel;
|
|
12
|
+
private _apply;
|
|
13
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Stocker Location Rule Editor
|
|
5
|
+
*/
|
|
6
|
+
import { __decorate } from "tslib";
|
|
7
|
+
import { css, html } from 'lit';
|
|
8
|
+
import { customElement, state } from 'lit/decorators.js';
|
|
9
|
+
import { OxPropertyEditor } from '@operato/property-editor';
|
|
10
|
+
import { DEFAULT_LOCATION_RULE, buildLocationId } from '../stocker.js';
|
|
11
|
+
let StockerLocationEditor = class StockerLocationEditor extends OxPropertyEditor {
|
|
12
|
+
static styles = [
|
|
13
|
+
...OxPropertyEditor.styles,
|
|
14
|
+
css `
|
|
15
|
+
.loc-grid { display: grid; grid-template-columns: 80px 1fr; gap: 3px 6px; font-size: 11px; align-items: center; }
|
|
16
|
+
.loc-grid label { color: #555; font-weight: 500; font-size: 10px; }
|
|
17
|
+
.loc-grid input, .loc-grid select {
|
|
18
|
+
width: 100%; box-sizing: border-box; font-size: 11px; padding: 3px 4px;
|
|
19
|
+
border: 1px solid rgba(0,0,0,0.15); border-radius: 4px; background: #fff; color: #1c1b1f;
|
|
20
|
+
}
|
|
21
|
+
.loc-grid input[type="number"] { width: 50px; }
|
|
22
|
+
.side-labels { display: flex; gap: 4px; align-items: center; font-size: 10px; }
|
|
23
|
+
.side-labels input { width: 30px; text-align: center; }
|
|
24
|
+
.section-title { grid-column: 1 / -1; font-weight: 600; font-size: 10px; color: #6750a4; margin-top: 6px; padding-bottom: 2px; border-bottom: 1px solid rgba(0,0,0,0.08); }
|
|
25
|
+
.preview { grid-column: 1 / -1; margin-top: 6px; padding: 6px 8px; background: #f3edf7; border-radius: 6px; font-family: monospace; font-size: 11px; }
|
|
26
|
+
.preview-title { font-size: 9px; font-weight: 600; color: #555; margin-bottom: 3px; }
|
|
27
|
+
.preview-samples { display: flex; flex-wrap: wrap; gap: 4px; }
|
|
28
|
+
.preview-sample { padding: 1px 5px; background: #fff; border-radius: 3px; font-size: 10px; }
|
|
29
|
+
`
|
|
30
|
+
];
|
|
31
|
+
_lastExternalValue = undefined;
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
this._rule = { ...DEFAULT_LOCATION_RULE };
|
|
35
|
+
}
|
|
36
|
+
_parseValue(value) {
|
|
37
|
+
if (!value)
|
|
38
|
+
return { ...DEFAULT_LOCATION_RULE };
|
|
39
|
+
if (typeof value === 'string') {
|
|
40
|
+
try {
|
|
41
|
+
return { ...DEFAULT_LOCATION_RULE, ...JSON.parse(value) };
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return { ...DEFAULT_LOCATION_RULE };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { ...DEFAULT_LOCATION_RULE, ...value };
|
|
48
|
+
}
|
|
49
|
+
editorTemplate(value, _spec) {
|
|
50
|
+
const serialized = typeof value === 'string' ? value : JSON.stringify(value);
|
|
51
|
+
if (serialized !== this._lastExternalValue) {
|
|
52
|
+
this._lastExternalValue = serialized;
|
|
53
|
+
this._rule = this._parseValue(value);
|
|
54
|
+
}
|
|
55
|
+
const r = this._rule;
|
|
56
|
+
const rackConfig = { bays: 10, levels: 5, depthCount: 1 };
|
|
57
|
+
const samples = [
|
|
58
|
+
buildLocationId(r, 'L', 1, 1, 1, rackConfig),
|
|
59
|
+
buildLocationId(r, 'L', 5, 3, 1, rackConfig),
|
|
60
|
+
buildLocationId(r, 'R', 10, 5, 1, rackConfig)
|
|
61
|
+
];
|
|
62
|
+
return html `
|
|
63
|
+
<fieldset fullwidth>
|
|
64
|
+
<div class="loc-grid">
|
|
65
|
+
<div class="section-title">Pattern</div>
|
|
66
|
+
<label>Format</label>
|
|
67
|
+
<input type="text" .value=${r.pattern} placeholder="{side}{bay}-{level}-{depth}"
|
|
68
|
+
@change=${(e) => { e.stopPropagation(); this._set('pattern', e.target.value); }} />
|
|
69
|
+
|
|
70
|
+
<label>Side labels</label>
|
|
71
|
+
<div class="side-labels">
|
|
72
|
+
L=<input type="text" .value=${r.sideLabels.L}
|
|
73
|
+
@change=${(e) => { e.stopPropagation(); this._setSideLabel('L', e.target.value); }} />
|
|
74
|
+
R=<input type="text" .value=${r.sideLabels.R}
|
|
75
|
+
@change=${(e) => { e.stopPropagation(); this._setSideLabel('R', e.target.value); }} />
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div class="section-title">Direction</div>
|
|
79
|
+
<label>Bay</label>
|
|
80
|
+
<select .value=${r.bayDir}
|
|
81
|
+
@change=${(e) => { e.stopPropagation(); this._set('bayDir', e.target.value); }}>
|
|
82
|
+
<option value="ltr">Left → Right</option>
|
|
83
|
+
<option value="rtl">Right → Left</option>
|
|
84
|
+
</select>
|
|
85
|
+
|
|
86
|
+
<label>Level</label>
|
|
87
|
+
<select .value=${r.levelDir}
|
|
88
|
+
@change=${(e) => { e.stopPropagation(); this._set('levelDir', e.target.value); }}>
|
|
89
|
+
<option value="btt">Bottom → Top</option>
|
|
90
|
+
<option value="ttb">Top → Bottom</option>
|
|
91
|
+
</select>
|
|
92
|
+
|
|
93
|
+
<div class="section-title">Start number</div>
|
|
94
|
+
<label>Bay start</label>
|
|
95
|
+
<input type="number" .value=${String(r.bayStart)} min="0" step="1"
|
|
96
|
+
@change=${(e) => { e.stopPropagation(); this._set('bayStart', Number(e.target.value)); }} />
|
|
97
|
+
<label>Level start</label>
|
|
98
|
+
<input type="number" .value=${String(r.levelStart)} min="0" step="1"
|
|
99
|
+
@change=${(e) => { e.stopPropagation(); this._set('levelStart', Number(e.target.value)); }} />
|
|
100
|
+
<label>Depth start</label>
|
|
101
|
+
<input type="number" .value=${String(r.depthStart)} min="0" step="1"
|
|
102
|
+
@change=${(e) => { e.stopPropagation(); this._set('depthStart', Number(e.target.value)); }} />
|
|
103
|
+
|
|
104
|
+
<div class="section-title">Digit padding</div>
|
|
105
|
+
<label>Bay digits</label>
|
|
106
|
+
<input type="number" .value=${String(r.bayDigits)} min="0" max="4" step="1"
|
|
107
|
+
@change=${(e) => { e.stopPropagation(); this._set('bayDigits', Number(e.target.value)); }} />
|
|
108
|
+
<label>Level digits</label>
|
|
109
|
+
<input type="number" .value=${String(r.levelDigits)} min="0" max="4" step="1"
|
|
110
|
+
@change=${(e) => { e.stopPropagation(); this._set('levelDigits', Number(e.target.value)); }} />
|
|
111
|
+
<label>Depth digits</label>
|
|
112
|
+
<input type="number" .value=${String(r.depthDigits)} min="0" max="4" step="1"
|
|
113
|
+
@change=${(e) => { e.stopPropagation(); this._set('depthDigits', Number(e.target.value)); }} />
|
|
114
|
+
|
|
115
|
+
<div class="preview">
|
|
116
|
+
<div class="preview-title">Preview (10 bays, 5 levels)</div>
|
|
117
|
+
<div class="preview-samples">
|
|
118
|
+
${samples.map(s => html `<span class="preview-sample">${s}</span>`)}
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</fieldset>
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
_set(field, value) {
|
|
126
|
+
this._rule = { ...this._rule, [field]: value };
|
|
127
|
+
this._apply();
|
|
128
|
+
}
|
|
129
|
+
_setSideLabel(side, value) {
|
|
130
|
+
this._rule = { ...this._rule, sideLabels: { ...this._rule.sideLabels, [side]: value || side } };
|
|
131
|
+
this._apply();
|
|
132
|
+
}
|
|
133
|
+
_apply() {
|
|
134
|
+
const jsonValue = JSON.stringify(this._rule);
|
|
135
|
+
this.value = jsonValue;
|
|
136
|
+
this._lastExternalValue = jsonValue;
|
|
137
|
+
this.requestUpdate();
|
|
138
|
+
this.dispatchEvent(new CustomEvent('i-need-selected', {
|
|
139
|
+
bubbles: true, composed: true,
|
|
140
|
+
detail: { callback: (selected) => { selected[0]?.set('locationRule', jsonValue); } }
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
__decorate([
|
|
145
|
+
state()
|
|
146
|
+
], StockerLocationEditor.prototype, "_rule", void 0);
|
|
147
|
+
StockerLocationEditor = __decorate([
|
|
148
|
+
customElement('property-editor-stocker-location')
|
|
149
|
+
], StockerLocationEditor);
|
|
150
|
+
export default StockerLocationEditor;
|
|
151
|
+
//# sourceMappingURL=property-editor-stocker-location.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property-editor-stocker-location.js","sourceRoot":"","sources":["../../src/editors/property-editor-stocker-location.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Stocker Location Rule Editor\n */\n\nimport { css, html, TemplateResult } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { OxPropertyEditor, PropertySpec } from '@operato/property-editor'\nimport type { LocationRule } from '../stocker.js'\nimport { DEFAULT_LOCATION_RULE, buildLocationId } from '../stocker.js'\n\n@customElement('property-editor-stocker-location')\nexport default class StockerLocationEditor extends OxPropertyEditor {\n static styles = [\n ...OxPropertyEditor.styles,\n css`\n .loc-grid { display: grid; grid-template-columns: 80px 1fr; gap: 3px 6px; font-size: 11px; align-items: center; }\n .loc-grid label { color: #555; font-weight: 500; font-size: 10px; }\n .loc-grid input, .loc-grid select {\n width: 100%; box-sizing: border-box; font-size: 11px; padding: 3px 4px;\n border: 1px solid rgba(0,0,0,0.15); border-radius: 4px; background: #fff; color: #1c1b1f;\n }\n .loc-grid input[type=\"number\"] { width: 50px; }\n .side-labels { display: flex; gap: 4px; align-items: center; font-size: 10px; }\n .side-labels input { width: 30px; text-align: center; }\n .section-title { grid-column: 1 / -1; font-weight: 600; font-size: 10px; color: #6750a4; margin-top: 6px; padding-bottom: 2px; border-bottom: 1px solid rgba(0,0,0,0.08); }\n .preview { grid-column: 1 / -1; margin-top: 6px; padding: 6px 8px; background: #f3edf7; border-radius: 6px; font-family: monospace; font-size: 11px; }\n .preview-title { font-size: 9px; font-weight: 600; color: #555; margin-bottom: 3px; }\n .preview-samples { display: flex; flex-wrap: wrap; gap: 4px; }\n .preview-sample { padding: 1px 5px; background: #fff; border-radius: 3px; font-size: 10px; }\n `\n ]\n\n @state() private declare _rule: LocationRule\n private _lastExternalValue: any = undefined\n\n constructor() {\n super()\n this._rule = { ...DEFAULT_LOCATION_RULE }\n }\n\n private _parseValue(value: any): LocationRule {\n if (!value) return { ...DEFAULT_LOCATION_RULE }\n if (typeof value === 'string') {\n try { return { ...DEFAULT_LOCATION_RULE, ...JSON.parse(value) } } catch { return { ...DEFAULT_LOCATION_RULE } }\n }\n return { ...DEFAULT_LOCATION_RULE, ...value }\n }\n\n editorTemplate(value: any, _spec: PropertySpec): TemplateResult {\n const serialized = typeof value === 'string' ? value : JSON.stringify(value)\n if (serialized !== this._lastExternalValue) {\n this._lastExternalValue = serialized\n this._rule = this._parseValue(value)\n }\n\n const r = this._rule\n const rackConfig = { bays: 10, levels: 5, depthCount: 1 }\n const samples = [\n buildLocationId(r, 'L', 1, 1, 1, rackConfig),\n buildLocationId(r, 'L', 5, 3, 1, rackConfig),\n buildLocationId(r, 'R', 10, 5, 1, rackConfig)\n ]\n\n return html`\n <fieldset fullwidth>\n <div class=\"loc-grid\">\n <div class=\"section-title\">Pattern</div>\n <label>Format</label>\n <input type=\"text\" .value=${r.pattern} placeholder=\"{side}{bay}-{level}-{depth}\"\n @change=${(e: Event) => { e.stopPropagation(); this._set('pattern', (e.target as HTMLInputElement).value) }} />\n\n <label>Side labels</label>\n <div class=\"side-labels\">\n L=<input type=\"text\" .value=${r.sideLabels.L}\n @change=${(e: Event) => { e.stopPropagation(); this._setSideLabel('L', (e.target as HTMLInputElement).value) }} />\n R=<input type=\"text\" .value=${r.sideLabels.R}\n @change=${(e: Event) => { e.stopPropagation(); this._setSideLabel('R', (e.target as HTMLInputElement).value) }} />\n </div>\n\n <div class=\"section-title\">Direction</div>\n <label>Bay</label>\n <select .value=${r.bayDir}\n @change=${(e: Event) => { e.stopPropagation(); this._set('bayDir', (e.target as HTMLSelectElement).value) }}>\n <option value=\"ltr\">Left → Right</option>\n <option value=\"rtl\">Right → Left</option>\n </select>\n\n <label>Level</label>\n <select .value=${r.levelDir}\n @change=${(e: Event) => { e.stopPropagation(); this._set('levelDir', (e.target as HTMLSelectElement).value) }}>\n <option value=\"btt\">Bottom → Top</option>\n <option value=\"ttb\">Top → Bottom</option>\n </select>\n\n <div class=\"section-title\">Start number</div>\n <label>Bay start</label>\n <input type=\"number\" .value=${String(r.bayStart)} min=\"0\" step=\"1\"\n @change=${(e: Event) => { e.stopPropagation(); this._set('bayStart', Number((e.target as HTMLInputElement).value)) }} />\n <label>Level start</label>\n <input type=\"number\" .value=${String(r.levelStart)} min=\"0\" step=\"1\"\n @change=${(e: Event) => { e.stopPropagation(); this._set('levelStart', Number((e.target as HTMLInputElement).value)) }} />\n <label>Depth start</label>\n <input type=\"number\" .value=${String(r.depthStart)} min=\"0\" step=\"1\"\n @change=${(e: Event) => { e.stopPropagation(); this._set('depthStart', Number((e.target as HTMLInputElement).value)) }} />\n\n <div class=\"section-title\">Digit padding</div>\n <label>Bay digits</label>\n <input type=\"number\" .value=${String(r.bayDigits)} min=\"0\" max=\"4\" step=\"1\"\n @change=${(e: Event) => { e.stopPropagation(); this._set('bayDigits', Number((e.target as HTMLInputElement).value)) }} />\n <label>Level digits</label>\n <input type=\"number\" .value=${String(r.levelDigits)} min=\"0\" max=\"4\" step=\"1\"\n @change=${(e: Event) => { e.stopPropagation(); this._set('levelDigits', Number((e.target as HTMLInputElement).value)) }} />\n <label>Depth digits</label>\n <input type=\"number\" .value=${String(r.depthDigits)} min=\"0\" max=\"4\" step=\"1\"\n @change=${(e: Event) => { e.stopPropagation(); this._set('depthDigits', Number((e.target as HTMLInputElement).value)) }} />\n\n <div class=\"preview\">\n <div class=\"preview-title\">Preview (10 bays, 5 levels)</div>\n <div class=\"preview-samples\">\n ${samples.map(s => html`<span class=\"preview-sample\">${s}</span>`)}\n </div>\n </div>\n </div>\n </fieldset>\n `\n }\n\n private _set(field: string, value: any) {\n this._rule = { ...this._rule, [field]: value }\n this._apply()\n }\n\n private _setSideLabel(side: 'L' | 'R', value: string) {\n this._rule = { ...this._rule, sideLabels: { ...this._rule.sideLabels, [side]: value || side } }\n this._apply()\n }\n\n private _apply() {\n const jsonValue = JSON.stringify(this._rule)\n this.value = jsonValue\n this._lastExternalValue = jsonValue\n this.requestUpdate()\n\n this.dispatchEvent(new CustomEvent('i-need-selected', {\n bubbles: true, composed: true,\n detail: { callback: (selected: any[]) => { selected[0]?.set('locationRule', jsonValue) } }\n }))\n }\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TemplateResult } from 'lit';
|
|
2
|
+
import { OxPropertyEditor, PropertySpec } from '@operato/property-editor';
|
|
3
|
+
export default class StockerPortsEditor extends OxPropertyEditor {
|
|
4
|
+
static styles: import("lit").CSSResult[];
|
|
5
|
+
editorTemplate(value: any, _spec: PropertySpec): TemplateResult;
|
|
6
|
+
private _set;
|
|
7
|
+
private _applyPorts;
|
|
8
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Stocker Port Configuration Editor
|
|
5
|
+
*
|
|
6
|
+
* 주의: OxPropertyEditor base class가 모든 change 이벤트를 잡아서
|
|
7
|
+
* this.value를 덮어쓰므로, 내부 input/select의 change 이벤트 버블링을 차단해야 함.
|
|
8
|
+
*/
|
|
9
|
+
import { __decorate } from "tslib";
|
|
10
|
+
import { css, html } from 'lit';
|
|
11
|
+
import { customElement } from 'lit/decorators.js';
|
|
12
|
+
import { OxPropertyEditor } from '@operato/property-editor';
|
|
13
|
+
function parsePorts(value) {
|
|
14
|
+
if (!value)
|
|
15
|
+
return [];
|
|
16
|
+
if (Array.isArray(value))
|
|
17
|
+
return value;
|
|
18
|
+
if (typeof value === 'string') {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = JSON.parse(value);
|
|
21
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
let StockerPortsEditor = class StockerPortsEditor extends OxPropertyEditor {
|
|
30
|
+
static styles = [
|
|
31
|
+
...OxPropertyEditor.styles,
|
|
32
|
+
css `
|
|
33
|
+
.port-table { width: 100%; font-size: 11px; border-collapse: collapse; }
|
|
34
|
+
.port-table th { text-align: left; padding: 3px 4px; font-weight: 600; color: #555; border-bottom: 1px solid rgba(0,0,0,0.12); font-size: 10px; }
|
|
35
|
+
.port-table td { padding: 2px 3px; vertical-align: middle; }
|
|
36
|
+
.port-table select, .port-table input {
|
|
37
|
+
width: 100%; box-sizing: border-box; font-size: 11px; padding: 3px 4px;
|
|
38
|
+
border: 1px solid rgba(0,0,0,0.15); border-radius: 4px; background: #fff; color: #1c1b1f;
|
|
39
|
+
}
|
|
40
|
+
.port-table input[type="number"] { width: 50px; }
|
|
41
|
+
.port-table input[type="text"] { width: 60px; }
|
|
42
|
+
.btn-row { display: flex; gap: 4px; margin-top: 4px; }
|
|
43
|
+
.btn {
|
|
44
|
+
padding: 3px 8px; font-size: 10px; cursor: pointer;
|
|
45
|
+
border: 1px solid rgba(0,0,0,0.15); border-radius: 4px; background: #f3edf7; color: #1c1b1f;
|
|
46
|
+
}
|
|
47
|
+
.btn:hover { background: #ece6f0; }
|
|
48
|
+
.btn-remove { color: #b3261e; cursor: pointer; font-size: 14px; padding: 0 4px; background: none; border: none; }
|
|
49
|
+
`
|
|
50
|
+
];
|
|
51
|
+
editorTemplate(value, _spec) {
|
|
52
|
+
const ports = Array.isArray(this.value) ? this.value : parsePorts(value);
|
|
53
|
+
return html `
|
|
54
|
+
<fieldset fullwidth>
|
|
55
|
+
${ports.length > 0 ? html `
|
|
56
|
+
<table class="port-table">
|
|
57
|
+
<thead><tr><th>Type</th><th>Side</th><th>Pos</th><th>Label</th><th></th></tr></thead>
|
|
58
|
+
<tbody>
|
|
59
|
+
${ports.map((port, i) => html `
|
|
60
|
+
<tr>
|
|
61
|
+
<td><select @change=${(e) => { e.stopPropagation(); this._set(ports, i, 'type', e.target.value); }}>
|
|
62
|
+
<option value="in" ?selected=${port.type === 'in'}>IN</option>
|
|
63
|
+
<option value="out" ?selected=${port.type === 'out'}>OUT</option>
|
|
64
|
+
</select></td>
|
|
65
|
+
<td><select @change=${(e) => { e.stopPropagation(); this._set(ports, i, 'side', e.target.value); }}>
|
|
66
|
+
<option value="front" ?selected=${port.side === 'front'}>Front</option>
|
|
67
|
+
<option value="back" ?selected=${port.side === 'back'}>Back</option>
|
|
68
|
+
</select></td>
|
|
69
|
+
<td><input type="number" .value=${String(port.position)} min="1" step="1"
|
|
70
|
+
@change=${(e) => { e.stopPropagation(); this._set(ports, i, 'position', Number(e.target.value)); }} /></td>
|
|
71
|
+
<td><input type="text" .value=${port.label || ''} placeholder="auto"
|
|
72
|
+
@change=${(e) => { e.stopPropagation(); this._set(ports, i, 'label', e.target.value || undefined); }} /></td>
|
|
73
|
+
<td><button class="btn-remove" @click=${() => this._applyPorts(ports.filter((_, j) => j !== i))}>×</button></td>
|
|
74
|
+
</tr>
|
|
75
|
+
`)}
|
|
76
|
+
</tbody>
|
|
77
|
+
</table>
|
|
78
|
+
` : html `<div style="font-size:11px;color:#888;padding:4px">No ports</div>`}
|
|
79
|
+
<div class="btn-row">
|
|
80
|
+
<button class="btn" @click=${() => {
|
|
81
|
+
const maxPos = ports.length > 0 ? Math.max(...ports.map(p => p.position)) : 0;
|
|
82
|
+
this._applyPorts([...ports, { type: 'in', side: 'front', position: maxPos + 1 }]);
|
|
83
|
+
}}>+ IN</button>
|
|
84
|
+
<button class="btn" @click=${() => {
|
|
85
|
+
const maxPos = ports.length > 0 ? Math.max(...ports.map(p => p.position)) : 0;
|
|
86
|
+
this._applyPorts([...ports, { type: 'out', side: 'front', position: maxPos + 1 }]);
|
|
87
|
+
}}>+ OUT</button>
|
|
88
|
+
</div>
|
|
89
|
+
</fieldset>
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
_set(ports, index, field, val) {
|
|
93
|
+
this._applyPorts(ports.map((p, i) => i === index ? { ...p, [field]: val } : p));
|
|
94
|
+
}
|
|
95
|
+
_applyPorts(ports) {
|
|
96
|
+
this.value = ports;
|
|
97
|
+
this.requestUpdate();
|
|
98
|
+
this.dispatchEvent(new CustomEvent('i-need-selected', {
|
|
99
|
+
bubbles: true, composed: true,
|
|
100
|
+
detail: {
|
|
101
|
+
callback: (selected) => {
|
|
102
|
+
selected[0]?.set('ports', JSON.stringify(ports));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
StockerPortsEditor = __decorate([
|
|
109
|
+
customElement('property-editor-stocker-ports')
|
|
110
|
+
], StockerPortsEditor);
|
|
111
|
+
export default StockerPortsEditor;
|
|
112
|
+
//# sourceMappingURL=property-editor-stocker-ports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property-editor-stocker-ports.js","sourceRoot":"","sources":["../../src/editors/property-editor-stocker-ports.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAgB,MAAM,0BAA0B,CAAA;AASzE,SAAS,UAAU,CAAC,KAAU;IAC5B,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAA;IACrB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAChC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5C,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,EAAE,CAAA;QAAC,CAAC;IACvB,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAGc,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,gBAAgB;IAC9D,MAAM,CAAC,MAAM,GAAG;QACd,GAAG,gBAAgB,CAAC,MAAM;QAC1B,GAAG,CAAA;;;;;;;;;;;;;;;;;KAiBF;KACF,CAAA;IAED,cAAc,CAAC,KAAU,EAAE,KAAmB;QAC5C,MAAM,KAAK,GAAgB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QAErF,OAAO,IAAI,CAAA;;UAEL,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;;;;gBAIjB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAA;;wCAEH,CAAC,CAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAK,CAAC,CAAA,CAAC,CAAC;mDAC9F,IAAI,CAAC,IAAI,KAAK,IAAI;oDACjB,IAAI,CAAC,IAAI,KAAK,KAAK;;wCAE/B,CAAC,CAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAK,CAAC,CAAA,CAAC,CAAC;sDAC3F,IAAI,CAAC,IAAI,KAAK,OAAO;qDACtB,IAAI,CAAC,IAAI,KAAK,MAAM;;oDAErB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;8BAC3C,CAAC,CAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,CAAE,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC,CAAC,CAAA,CAAC,CAAC;kDAChG,IAAI,CAAC,KAAK,IAAI,EAAE;8BACpC,CAAC,CAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAG,CAAC,CAAC,MAA2B,CAAC,KAAK,IAAI,SAAS,CAAC,CAAA,CAAC,CAAC;0DAC1F,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;;eAElG,CAAC;;;SAGP,CAAC,CAAC,CAAC,IAAI,CAAA,mEAAmE;;uCAE5C,GAAG,EAAE;YAChC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC7E,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,KAAK,EAAE,EAAE,IAAI,EAAE,IAAa,EAAE,IAAI,EAAE,OAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QACrG,CAAC;uCAC4B,GAAG,EAAE;YAChC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC7E,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,KAAK,EAAE,EAAE,IAAI,EAAE,KAAc,EAAE,IAAI,EAAE,OAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QACtG,CAAC;;;KAGN,CAAA;IACH,CAAC;IAEO,IAAI,CAAC,KAAkB,EAAE,KAAa,EAAE,KAAa,EAAE,GAAQ;QACrE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACjF,CAAC;IAEO,WAAW,CAAC,KAAkB;QACpC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,aAAa,EAAE,CAAA;QAEpB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,iBAAiB,EAAE;YACpD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI;YAC7B,MAAM,EAAE;gBACN,QAAQ,EAAE,CAAC,QAAe,EAAE,EAAE;oBAC5B,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;gBAClD,CAAC;aACF;SACF,CAAC,CAAC,CAAA;IACL,CAAC;;AAlFkB,kBAAkB;IADtC,aAAa,CAAC,+BAA+B,CAAC;GAC1B,kBAAkB,CAmFtC;eAnFoB,kBAAkB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Stocker Port Configuration Editor\n *\n * 주의: OxPropertyEditor base class가 모든 change 이벤트를 잡아서\n * this.value를 덮어쓰므로, 내부 input/select의 change 이벤트 버블링을 차단해야 함.\n */\n\nimport { css, html, TemplateResult } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { OxPropertyEditor, PropertySpec } from '@operato/property-editor'\n\ninterface PortEntry {\n type: 'in' | 'out'\n side: 'front' | 'back'\n position: number\n label?: string\n}\n\nfunction parsePorts(value: any): PortEntry[] {\n if (!value) return []\n if (Array.isArray(value)) return value\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value)\n return Array.isArray(parsed) ? parsed : []\n } catch { return [] }\n }\n return []\n}\n\n@customElement('property-editor-stocker-ports')\nexport default class StockerPortsEditor extends OxPropertyEditor {\n static styles = [\n ...OxPropertyEditor.styles,\n css`\n .port-table { width: 100%; font-size: 11px; border-collapse: collapse; }\n .port-table th { text-align: left; padding: 3px 4px; font-weight: 600; color: #555; border-bottom: 1px solid rgba(0,0,0,0.12); font-size: 10px; }\n .port-table td { padding: 2px 3px; vertical-align: middle; }\n .port-table select, .port-table input {\n width: 100%; box-sizing: border-box; font-size: 11px; padding: 3px 4px;\n border: 1px solid rgba(0,0,0,0.15); border-radius: 4px; background: #fff; color: #1c1b1f;\n }\n .port-table input[type=\"number\"] { width: 50px; }\n .port-table input[type=\"text\"] { width: 60px; }\n .btn-row { display: flex; gap: 4px; margin-top: 4px; }\n .btn {\n padding: 3px 8px; font-size: 10px; cursor: pointer;\n border: 1px solid rgba(0,0,0,0.15); border-radius: 4px; background: #f3edf7; color: #1c1b1f;\n }\n .btn:hover { background: #ece6f0; }\n .btn-remove { color: #b3261e; cursor: pointer; font-size: 14px; padding: 0 4px; background: none; border: none; }\n `\n ]\n\n editorTemplate(value: any, _spec: PropertySpec): TemplateResult {\n const ports: PortEntry[] = Array.isArray(this.value) ? this.value : parsePorts(value)\n\n return html`\n <fieldset fullwidth>\n ${ports.length > 0 ? html`\n <table class=\"port-table\">\n <thead><tr><th>Type</th><th>Side</th><th>Pos</th><th>Label</th><th></th></tr></thead>\n <tbody>\n ${ports.map((port, i) => html`\n <tr>\n <td><select @change=${(e: Event) => { e.stopPropagation(); this._set(ports, i, 'type', (e.target as HTMLSelectElement).value) }}>\n <option value=\"in\" ?selected=${port.type === 'in'}>IN</option>\n <option value=\"out\" ?selected=${port.type === 'out'}>OUT</option>\n </select></td>\n <td><select @change=${(e: Event) => { e.stopPropagation(); this._set(ports, i, 'side', (e.target as HTMLSelectElement).value) }}>\n <option value=\"front\" ?selected=${port.side === 'front'}>Front</option>\n <option value=\"back\" ?selected=${port.side === 'back'}>Back</option>\n </select></td>\n <td><input type=\"number\" .value=${String(port.position)} min=\"1\" step=\"1\"\n @change=${(e: Event) => { e.stopPropagation(); this._set(ports, i, 'position', Number((e.target as HTMLInputElement).value)) }} /></td>\n <td><input type=\"text\" .value=${port.label || ''} placeholder=\"auto\"\n @change=${(e: Event) => { e.stopPropagation(); this._set(ports, i, 'label', (e.target as HTMLInputElement).value || undefined) }} /></td>\n <td><button class=\"btn-remove\" @click=${() => this._applyPorts(ports.filter((_, j) => j !== i))}>×</button></td>\n </tr>\n `)}\n </tbody>\n </table>\n ` : html`<div style=\"font-size:11px;color:#888;padding:4px\">No ports</div>`}\n <div class=\"btn-row\">\n <button class=\"btn\" @click=${() => {\n const maxPos = ports.length > 0 ? Math.max(...ports.map(p => p.position)) : 0\n this._applyPorts([...ports, { type: 'in' as const, side: 'front' as const, position: maxPos + 1 }])\n }}>+ IN</button>\n <button class=\"btn\" @click=${() => {\n const maxPos = ports.length > 0 ? Math.max(...ports.map(p => p.position)) : 0\n this._applyPorts([...ports, { type: 'out' as const, side: 'front' as const, position: maxPos + 1 }])\n }}>+ OUT</button>\n </div>\n </fieldset>\n `\n }\n\n private _set(ports: PortEntry[], index: number, field: string, val: any) {\n this._applyPorts(ports.map((p, i) => i === index ? { ...p, [field]: val } : p))\n }\n\n private _applyPorts(ports: PortEntry[]) {\n this.value = ports\n this.requestUpdate()\n\n this.dispatchEvent(new CustomEvent('i-need-selected', {\n bubbles: true, composed: true,\n detail: {\n callback: (selected: any[]) => {\n selected[0]?.set('ports', JSON.stringify(ports))\n }\n }\n }))\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6CAA6C;AAC7C,2BAA2B;AAE3B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\n// threed 인프라 + 범용 3D 컴포넌트는 things-scene에서 제공\n// 여기서는 도메인 특화 컴포넌트만 export\n\nexport * from './desk.js'\nexport * from './rack.js'\nexport * from './rack-table.js'\nexport * from './rack-table-cell.js'\nexport * from './visualizer.js'\nexport * from './stock.js'\nexport * from './signal-tower.js'\nexport * from './stock-hub.js'\nexport * from './tank.js'\nexport * from './vehicle.js'\nexport * from './carrier.js'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6CAA6C;AAC7C,2BAA2B;AAE3B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\n// threed 인프라 + 범용 3D 컴포넌트는 things-scene에서 제공\n// 여기서는 도메인 특화 컴포넌트만 export\n\nexport * from './desk.js'\nexport * from './rack.js'\nexport * from './rack-table.js'\nexport * from './rack-table-cell.js'\nexport * from './visualizer.js'\nexport * from './stock.js'\nexport * from './signal-tower.js'\nexport * from './stock-hub.js'\nexport * from './tank.js'\nexport * from './vehicle.js'\nexport * from './carrier.js'\nexport * from './stocker.js'\nexport * from './stocker-port.js'\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RealObjectGroup } from '@hatiolab/things-scene';
|
|
2
|
+
import type { Stocker } from './stocker.js';
|
|
3
|
+
export declare class Stocker3d extends RealObjectGroup {
|
|
4
|
+
private _cranes;
|
|
5
|
+
private _cellMeshes;
|
|
6
|
+
private _animRaf;
|
|
7
|
+
get stocker(): Stocker;
|
|
8
|
+
get position(): {
|
|
9
|
+
x: number;
|
|
10
|
+
y: any;
|
|
11
|
+
z: number;
|
|
12
|
+
};
|
|
13
|
+
build(): void;
|
|
14
|
+
private _buildRackSide;
|
|
15
|
+
private _buildEnclosure;
|
|
16
|
+
private _buildCranes;
|
|
17
|
+
updateCraneTargets(): void;
|
|
18
|
+
private _startCraneAnim;
|
|
19
|
+
onchange(after: Record<string, unknown>, before: Record<string, unknown>): void;
|
|
20
|
+
dispose(): void;
|
|
21
|
+
updateDimension(): void;
|
|
22
|
+
updateAlpha(): void;
|
|
23
|
+
}
|