@operato/slot-layout-editor 10.29.14 → 10.29.16
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 +18 -0
- package/dist/src/draft.d.ts +21 -10
- package/dist/src/draft.js +48 -21
- package/dist/src/draft.js.map +1 -1
- package/dist/src/issue-text.d.ts +4 -1
- package/dist/src/issue-text.js +16 -3
- package/dist/src/issue-text.js.map +1 -1
- package/dist/src/ox-slot-layout-editor.d.ts +21 -6
- package/dist/src/ox-slot-layout-editor.js +94 -31
- package/dist/src/ox-slot-layout-editor.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/translations/en.json +17 -6
- package/translations/ja.json +17 -6
- package/translations/ko.json +23 -12
- package/translations/ms.json +17 -6
- package/translations/zh.json +17 -6
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
3
|
*
|
|
4
|
-
* 자리 레이아웃 편집기. 홀더의
|
|
4
|
+
* 자리 레이아웃 편집기. 홀더의 Tier·Slot 구성을 고치고, 검증하고, 미리 보고, [적용]으로 알린다.
|
|
5
|
+
* Tier 는 홀더가 주는 Anchor 하나에 서고, 그 Anchor 기준 위치·회전과 적재 방식(mount)을 갖는다.
|
|
5
6
|
*
|
|
6
7
|
* 컴포넌트 상태를 직접 바꾸지 않는다. 호스트에 두 가지만 알린다:
|
|
7
8
|
* change — 적용한 레이아웃 (this.value)
|
|
@@ -12,9 +13,9 @@ import { __decorate } from "tslib";
|
|
|
12
13
|
import { css, html, nothing, LitElement, svg } from 'lit';
|
|
13
14
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
14
15
|
import { i18next, localize } from '@operato/i18n';
|
|
15
|
-
import { persistenceIssues, validateSlotLayout } from '@hatiolab/things-scene';
|
|
16
|
-
import { addCustomSlot, applyPreset, copyTier, previewTier, removeCustomSlot, removeTier, setTierPattern, updatePattern, updateSlotSpec, updateTier } from './draft.js';
|
|
17
|
-
import { issueText as defaultIssueText, t } from './issue-text.js';
|
|
16
|
+
import { persistenceIssues, slotSpaceWarnings, validateSlotLayout } from '@hatiolab/things-scene';
|
|
17
|
+
import { addCustomSlot, addressImpact, applyPreset, copyTier, previewTier, removeCustomSlot, removeTier, setTierPattern, updatePattern, updateSlotSpec, updateTier } from './draft.js';
|
|
18
|
+
import { issueText as defaultIssueText, spaceWarningText, t } from './issue-text.js';
|
|
18
19
|
const num = (e) => {
|
|
19
20
|
const n = e.target.valueAsNumber;
|
|
20
21
|
return Number.isFinite(n) ? n : NaN;
|
|
@@ -28,7 +29,6 @@ let OxSlotLayoutEditor = class OxSlotLayoutEditor extends localize(i18next)(LitE
|
|
|
28
29
|
this.presetKey = '';
|
|
29
30
|
this.presetSize = {};
|
|
30
31
|
this.presetParams = {};
|
|
31
|
-
this.copyElevation = NaN;
|
|
32
32
|
}
|
|
33
33
|
willUpdate(changed) {
|
|
34
34
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -41,23 +41,37 @@ let OxSlotLayoutEditor = class OxSlotLayoutEditor extends localize(i18next)(LitE
|
|
|
41
41
|
}
|
|
42
42
|
/** 편집 중인 값을 버리고 개별 설정(없으면 호스트 기본값)에서 다시 시작한다 */
|
|
43
43
|
reset() {
|
|
44
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
44
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
45
45
|
const start = (_a = this.value) !== null && _a !== void 0 ? _a : (_b = this.options) === null || _b === void 0 ? void 0 : _b.effective;
|
|
46
46
|
this.draft = start ? structuredClone(start) : undefined;
|
|
47
|
-
this.tier = 1;
|
|
47
|
+
this.tier = (_f = (_e = (_d = (_c = this.draft) === null || _c === void 0 ? void 0 : _c.tiers) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.tierNo) !== null && _f !== void 0 ? _f : 1;
|
|
48
48
|
this.dirty = false;
|
|
49
|
-
this.presetSize = { ...((
|
|
50
|
-
if (!((
|
|
51
|
-
this.presetKey = (
|
|
49
|
+
this.presetSize = { ...((_h = (_g = this.options) === null || _g === void 0 ? void 0 : _g.presetSize) !== null && _h !== void 0 ? _h : {}) };
|
|
50
|
+
if (!((_k = (_j = this.options) === null || _j === void 0 ? void 0 : _j.presets) === null || _k === void 0 ? void 0 : _k.some(p => p.key === this.presetKey)))
|
|
51
|
+
this.presetKey = (_p = (_o = (_m = (_l = this.options) === null || _l === void 0 ? void 0 : _l.presets) === null || _m === void 0 ? void 0 : _m[0]) === null || _o === void 0 ? void 0 : _o.key) !== null && _p !== void 0 ? _p : '';
|
|
52
52
|
}
|
|
53
53
|
get issues() {
|
|
54
|
-
var _a, _b, _c;
|
|
54
|
+
var _a, _b, _c, _d, _e;
|
|
55
55
|
if (!this.draft)
|
|
56
56
|
return [];
|
|
57
|
-
const
|
|
57
|
+
const anchors = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.anchors) === null || _b === void 0 ? void 0 : _b.map(a => a.id);
|
|
58
|
+
const invalid = [...validateSlotLayout(this.draft, { anchors }), ...((_e = (_d = (_c = this.options) === null || _c === void 0 ? void 0 : _c.validate) === null || _d === void 0 ? void 0 : _d.call(_c, this.draft)) !== null && _e !== void 0 ? _e : [])];
|
|
58
59
|
// 저장 불가 검사는 검증을 통과한 값에만 보인다 (같은 문제를 두 번 적지 않는다)
|
|
59
60
|
return invalid.length ? invalid : persistenceIssues(this.draft);
|
|
60
61
|
}
|
|
62
|
+
/** 자리끼리 겹치거나 면 밖으로 나가는 설정 경고. 적용을 막지 않는다. 적재면 크기를 주지 않은 호스트에는 확인 불가를 보이지 않는다 */
|
|
63
|
+
get warnings() {
|
|
64
|
+
var _a;
|
|
65
|
+
if (!this.draft || this.issues.length)
|
|
66
|
+
return [];
|
|
67
|
+
const faces = (_a = this.options) === null || _a === void 0 ? void 0 : _a.anchorFaces;
|
|
68
|
+
return slotSpaceWarnings(this.draft, { anchorFaces: faces }).filter(w => faces || w.code !== 'ANCHOR_SPACE_UNKNOWN');
|
|
69
|
+
}
|
|
70
|
+
/** 적용하면 뜻이 바뀌는 주소 (지금 적용된 값 기준) */
|
|
71
|
+
get impact() {
|
|
72
|
+
var _a, _b;
|
|
73
|
+
return this.dirty && !this.issues.length ? addressImpact((_a = this.value) !== null && _a !== void 0 ? _a : (_b = this.options) === null || _b === void 0 ? void 0 : _b.effective, this.draft) : { moved: [], gone: [] };
|
|
74
|
+
}
|
|
61
75
|
_text(issue) {
|
|
62
76
|
var _a, _b, _c;
|
|
63
77
|
return (_c = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.issueText) === null || _b === void 0 ? void 0 : _b.call(_a, issue)) !== null && _c !== void 0 ? _c : defaultIssueText(issue);
|
|
@@ -86,7 +100,7 @@ let OxSlotLayoutEditor = class OxSlotLayoutEditor extends localize(i18next)(LitE
|
|
|
86
100
|
${this.options.notes.map(n => html `<div class=${n.level === 'error' ? 'error' : 'note'}>${n.text}</div>`)}
|
|
87
101
|
</div>`
|
|
88
102
|
: nothing}
|
|
89
|
-
${this._renderPreset()} ${this.draft ? this._renderDraft(issues) : nothing}
|
|
103
|
+
${this._renderPreset()} ${this.draft ? this._renderDraft(issues) : nothing} ${this._renderImpact()}
|
|
90
104
|
<div class="actions">
|
|
91
105
|
${canUseDefault ? html `<button data-action="use-default" @click=${this._useDefault}>${t('use-default', 'Use default')}</button>` : nothing}
|
|
92
106
|
<button data-action="discard" ?disabled=${!this.dirty} @click=${() => this.reset()}>${t('discard', 'Discard')}</button>
|
|
@@ -127,17 +141,33 @@ let OxSlotLayoutEditor = class OxSlotLayoutEditor extends localize(i18next)(LitE
|
|
|
127
141
|
</div>
|
|
128
142
|
`;
|
|
129
143
|
}
|
|
130
|
-
/**
|
|
144
|
+
/** 적용 전에 뜻이 바뀌는 주소를 보인다. 놓인 Carrier 는 주소로 다시 읽혀 다른 자리에 그려지거나 예외가 된다 */
|
|
145
|
+
_renderImpact() {
|
|
146
|
+
const { moved, gone } = this.impact;
|
|
147
|
+
if (!moved.length && !gone.length)
|
|
148
|
+
return nothing;
|
|
149
|
+
const list = (ids) => (ids.length > 12 ? `${ids.slice(0, 12).join(', ')} … (${ids.length})` : ids.join(', '));
|
|
150
|
+
return html `<div class="notes" data-impact>
|
|
151
|
+
${moved.length ? html `<div class="note">${t('impact-moved', 'Moves: {ids}', { ids: list(moved) })}</div>` : nothing}
|
|
152
|
+
${gone.length ? html `<div class="error">${t('impact-gone', 'Removed: {ids}', { ids: list(gone) })}</div>` : nothing}
|
|
153
|
+
</div>`;
|
|
154
|
+
}
|
|
155
|
+
/** 프리셋으로 다시 시작한다. 지금 값에 덧붙은 호스트 키(Tier 밖의 키)는 가져온다 */
|
|
131
156
|
_startFrom(layout) {
|
|
132
157
|
var _a;
|
|
133
|
-
const {
|
|
158
|
+
const { tiers: _t, ...extra } = ((_a = this.draft) !== null && _a !== void 0 ? _a : {});
|
|
134
159
|
this._edit({ ...extra, ...structuredClone(layout) });
|
|
135
160
|
}
|
|
136
161
|
_renderDraft(issues) {
|
|
137
162
|
var _a, _b, _c, _d, _e, _f;
|
|
138
163
|
const draft = this.draft;
|
|
139
164
|
const tier = (_b = (_a = draft.tiers) === null || _a === void 0 ? void 0 : _a.find(x => x.tierNo === this.tier)) !== null && _b !== void 0 ? _b : (_c = draft.tiers) === null || _c === void 0 ? void 0 : _c[0];
|
|
140
|
-
const
|
|
165
|
+
const warnings = this.warnings;
|
|
166
|
+
const issueList = issues.length
|
|
167
|
+
? html `<div class="error" data-issues>${issues.map(i => html `<div>· ${this._text(i)}</div>`)}</div>`
|
|
168
|
+
: warnings.length
|
|
169
|
+
? html `<div class="note" data-warnings>${warnings.map(w => html `<div>· ${spaceWarningText(w)}</div>`)}</div>`
|
|
170
|
+
: nothing;
|
|
141
171
|
// 층이 없는 값(잘못된 저장값)은 편집할 층이 없으므로 문제만 보인다. 프리셋으로 다시 시작한다
|
|
142
172
|
if (!tier)
|
|
143
173
|
return issueList;
|
|
@@ -146,21 +176,21 @@ let OxSlotLayoutEditor = class OxSlotLayoutEditor extends localize(i18next)(LitE
|
|
|
146
176
|
<div class="chips">
|
|
147
177
|
${draft.tiers.map(x => html `<button data-tier=${x.tierNo} ?active=${x.tierNo === tier.tierNo} @click=${() => (this.tier = x.tierNo)}>${t('tier-n', 'Tier {n}', { n: x.tierNo })}</button>`)}
|
|
148
178
|
</div>
|
|
149
|
-
<div class="row">
|
|
150
|
-
<label>${t('copy-elevation', 'New tier elevation')}</label>
|
|
151
|
-
<input type="number" data-field="copy-elevation" .value=${Number.isFinite(this.copyElevation) ? String(this.copyElevation) : ''} @change=${(e) => (this.copyElevation = num(e))} />
|
|
152
|
-
</div>
|
|
153
179
|
<div class="actions">
|
|
154
|
-
<button data-action="copy-tier"
|
|
155
|
-
${t('copy-tier', 'Copy tier')}
|
|
156
|
-
</button>
|
|
180
|
+
<button data-action="copy-tier" @click=${() => this._copyTier(draft, tier.tierNo)}>${t('copy-tier', 'Copy tier')}</button>
|
|
157
181
|
<button data-action="remove-tier" ?disabled=${draft.tiers.length <= 1} @click=${() => this._edit(removeTier(draft, tier.tierNo))}>${t('remove-tier', 'Remove tier')}</button>
|
|
158
182
|
</div>
|
|
159
183
|
${this._renderTier(draft, tier.tierNo)} ${(_f = (_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.renderExtra) === null || _e === void 0 ? void 0 : _e.call(_d, draft, next => this._edit(next))) !== null && _f !== void 0 ? _f : nothing}
|
|
160
|
-
<h4>${t('preview', 'Preview (top view, tier {n})', { n: tier.tierNo })}</h4>
|
|
184
|
+
<h4>${t('preview', 'Preview (top view, tier {n}, in the tier)', { n: tier.tierNo })}</h4>
|
|
161
185
|
${this._renderPreview(draft, tier.tierNo)} ${issueList}
|
|
162
186
|
`;
|
|
163
187
|
}
|
|
188
|
+
/** 복사한 Tier 를 골라 둔다. 같은 자리에 겹쳐 생기므로 바로 이어서 배치를 고친다 */
|
|
189
|
+
_copyTier(draft, tierNo) {
|
|
190
|
+
const next = copyTier(draft, tierNo);
|
|
191
|
+
this._edit(next);
|
|
192
|
+
this.tier = next.tiers[next.tiers.length - 1].tierNo;
|
|
193
|
+
}
|
|
164
194
|
_renderTier(draft, tierNo) {
|
|
165
195
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
166
196
|
const tier = draft.tiers.find(x => x.tierNo === tierNo);
|
|
@@ -180,10 +210,7 @@ let OxSlotLayoutEditor = class OxSlotLayoutEditor extends localize(i18next)(LitE
|
|
|
180
210
|
</div>
|
|
181
211
|
`;
|
|
182
212
|
return html `
|
|
183
|
-
|
|
184
|
-
<label>${t('elevation', 'Elevation')}</label>
|
|
185
|
-
<input type="number" data-field="elevation" .value=${String(tier.elevation)} @change=${(e) => this._edit(updateTier(draft, tierNo, { elevation: num(e) }))} />
|
|
186
|
-
</div>
|
|
213
|
+
${this._renderPlacement(draft, tierNo)}
|
|
187
214
|
${select('pattern', t('pattern', 'Pattern'), l.pattern, ['SINGLE', 'ROW', 'GRID', 'CUSTOM'], v => this._edit(setTierPattern(draft, tierNo, v)))}
|
|
188
215
|
${l.pattern === 'ROW'
|
|
189
216
|
? html `
|
|
@@ -205,6 +232,45 @@ let OxSlotLayoutEditor = class OxSlotLayoutEditor extends localize(i18next)(LitE
|
|
|
205
232
|
${l.pattern === 'CUSTOM' ? this._renderCustom(draft, tierNo) : this._renderSpec(draft, tierNo, l.slot)}
|
|
206
233
|
`;
|
|
207
234
|
}
|
|
235
|
+
/** Tier 가 선 Anchor, 적재 방식, Anchor 기준 위치·회전 */
|
|
236
|
+
_renderPlacement(draft, tierNo) {
|
|
237
|
+
var _a, _b, _c, _d, _e, _f;
|
|
238
|
+
const tier = draft.tiers.find(x => x.tierNo === tierNo);
|
|
239
|
+
const anchors = (_a = this.options) === null || _a === void 0 ? void 0 : _a.anchors;
|
|
240
|
+
const edit = (patch) => this._edit(updateTier(draft, tierNo, patch));
|
|
241
|
+
const position = (_b = tier.position) !== null && _b !== void 0 ? _b : { x: 0, y: 0, z: 0 };
|
|
242
|
+
const axis = (k, label) => {
|
|
243
|
+
var _a;
|
|
244
|
+
return html `
|
|
245
|
+
<div class="row">
|
|
246
|
+
<label>${label}</label>
|
|
247
|
+
<input type="number" data-field=${`position-${k}`} .value=${String((_a = position[k]) !== null && _a !== void 0 ? _a : '')} @change=${(e) => edit({ position: { ...position, [k]: num(e) } })} />
|
|
248
|
+
</div>
|
|
249
|
+
`;
|
|
250
|
+
};
|
|
251
|
+
return html `
|
|
252
|
+
<div class="row">
|
|
253
|
+
<label>${t('anchor', 'Anchor')}</label>
|
|
254
|
+
${(anchors === null || anchors === void 0 ? void 0 : anchors.length)
|
|
255
|
+
? html `<select data-field="anchor" @change=${(e) => edit({ anchorId: e.target.value })}>
|
|
256
|
+
${anchors.some(a => a.id === tier.anchorId) ? nothing : html `<option value=${(_c = tier.anchorId) !== null && _c !== void 0 ? _c : ''} selected>${(_d = tier.anchorId) !== null && _d !== void 0 ? _d : ''}</option>`}
|
|
257
|
+
${anchors.map(a => { var _a; return html `<option value=${a.id} ?selected=${a.id === tier.anchorId}>${(_a = a.label) !== null && _a !== void 0 ? _a : a.id}</option>`; })}
|
|
258
|
+
</select>`
|
|
259
|
+
: html `<input data-field="anchor" .value=${(_e = tier.anchorId) !== null && _e !== void 0 ? _e : ''} @change=${(e) => edit({ anchorId: e.target.value.trim() })} />`}
|
|
260
|
+
</div>
|
|
261
|
+
<div class="row">
|
|
262
|
+
<label>${t('mount', 'Mount')}</label>
|
|
263
|
+
<select data-field="mount" @change=${(e) => edit({ mount: e.target.value })}>
|
|
264
|
+
${['ON', 'IN', 'HANG'].map(m => html `<option value=${m} ?selected=${m === tier.mount}>${m}</option>`)}
|
|
265
|
+
</select>
|
|
266
|
+
</div>
|
|
267
|
+
${axis('x', t('position-x', 'Position X'))} ${axis('y', t('position-y', 'Position Y (height)'))} ${axis('z', t('position-z', 'Position Z'))}
|
|
268
|
+
<div class="row">
|
|
269
|
+
<label>${t('tier-rotation', 'Tier rotation (deg)')}</label>
|
|
270
|
+
<input type="number" data-field="tier-rotation" .value=${String((_f = tier.rotation) !== null && _f !== void 0 ? _f : '')} @change=${(e) => edit({ rotation: num(e) })} />
|
|
271
|
+
</div>
|
|
272
|
+
`;
|
|
273
|
+
}
|
|
208
274
|
/** 받는 타입: 모든 타입(accepts 생략) / 지정 타입만(빈 목록이면 아무것도 받지 않음) */
|
|
209
275
|
_acceptsEditor(spec, onChange) {
|
|
210
276
|
var _a;
|
|
@@ -426,9 +492,6 @@ __decorate([
|
|
|
426
492
|
__decorate([
|
|
427
493
|
state()
|
|
428
494
|
], OxSlotLayoutEditor.prototype, "presetParams", void 0);
|
|
429
|
-
__decorate([
|
|
430
|
-
state()
|
|
431
|
-
], OxSlotLayoutEditor.prototype, "copyElevation", void 0);
|
|
432
495
|
OxSlotLayoutEditor = __decorate([
|
|
433
496
|
customElement('ox-slot-layout-editor')
|
|
434
497
|
], OxSlotLayoutEditor);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-slot-layout-editor.js","sourceRoot":"","sources":["../../src/ox-slot-layout-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * 자리 레이아웃 편집기. 홀더의 층·자리 구성을 고치고, 검증하고, 미리 보고, [적용]으로 알린다.\n *\n * 컴포넌트 상태를 직접 바꾸지 않는다. 호스트에 두 가지만 알린다:\n * change — 적용한 레이아웃 (this.value)\n * slot-layout-use-default — 개별 설정을 지우고 기본값을 쓰겠다는 의도 (값을 비우는 편집과 다르다)\n * 기본값을 쓰게 된 뒤 보일 값은 호스트가 options.effective 로 다시 준다.\n */\n\nimport { css, html, nothing, LitElement, svg } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { i18next, localize } from '@operato/i18n'\nimport { persistenceIssues, validateSlotLayout, type GridOrder, type SlotLayout, type SlotMount, type SlotPattern, type SlotSpec } from '@hatiolab/things-scene'\n\nimport {\n addCustomSlot,\n applyPreset,\n copyTier,\n previewTier,\n removeCustomSlot,\n removeTier,\n setTierPattern,\n updatePattern,\n updateSlotSpec,\n updateTier,\n type PresetSize,\n type SlotLayoutPreset\n} from './draft.js'\nimport { issueText as defaultIssueText, t, type EditorIssue } from './issue-text.js'\n\nexport interface SlotLayoutEditorNote {\n text: string\n level?: 'info' | 'error'\n}\n\nexport interface SlotLayoutEditorOptions<L extends SlotLayout = SlotLayout> {\n /** 개별 설정이 없을 때 보이는 값 (호스트가 고른 기본값). 편집 시작점이 된다 */\n effective?: L\n /** [기본값 사용]을 보일지. 기본은 개별 설정(value)이 있을 때 */\n canUseDefault?: boolean\n /** 호스트가 주는 프리셋 */\n presets?: SlotLayoutPreset<L>[]\n /** 프리셋 크기 초기값 */\n presetSize?: Partial<PresetSize>\n /** 상태 문구 (값의 출처, 단위 상태 등) */\n notes?: SlotLayoutEditorNote[]\n /** 프리셋 없이 새로 시작할 때의 mount. 기본 ON */\n mount?: SlotMount\n /** 호스트 고유 검증 (경로는 레이아웃 기준) */\n validate?: (layout: L) => EditorIssue[]\n /** 문제 문구. undefined 를 돌려주면 기본 문구 */\n issueText?: (issue: EditorIssue) => string | undefined\n /** 레이아웃에 덧붙인 호스트 키를 고치는 구역 (예: 실시간 주소 읽기). edit 로 새 레이아웃을 넘긴다 */\n renderExtra?: (draft: L, edit: (next: L) => void) => unknown\n}\n\nconst num = (e: Event) => {\n const n = (e.target as HTMLInputElement).valueAsNumber\n return Number.isFinite(n) ? n : NaN\n}\n\n@customElement('ox-slot-layout-editor')\nexport class OxSlotLayoutEditor extends localize(i18next)(LitElement) {\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n }\n .row {\n display: grid;\n grid-template-columns: 40% 1fr;\n align-items: center;\n gap: 4px;\n }\n .notes {\n padding: 4px 6px;\n border-radius: 4px;\n background: rgba(0, 0, 0, 0.04);\n }\n .error {\n color: #c62828;\n }\n .note {\n color: rgba(0, 0, 0, 0.55);\n }\n .chips {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n .chips button[active] {\n border-color: var(--md-sys-color-primary, #1976d2);\n color: var(--md-sys-color-primary, #1976d2);\n font-weight: bold;\n }\n button {\n font-size: 12px;\n padding: 2px 8px;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n background: #fff;\n cursor: pointer;\n }\n button[disabled] {\n opacity: 0.4;\n cursor: default;\n }\n input,\n select {\n font-size: 12px;\n min-width: 0;\n }\n table {\n border-collapse: collapse;\n width: 100%;\n }\n td,\n th {\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n padding: 1px;\n }\n td input {\n width: 100%;\n box-sizing: border-box;\n }\n h4 {\n margin: 6px 0 2px;\n font-size: 12px;\n }\n svg {\n width: 100%;\n height: 160px;\n background: rgba(0, 0, 0, 0.02);\n border: 1px solid rgba(0, 0, 0, 0.08);\n }\n .actions {\n display: flex;\n gap: 4px;\n justify-content: flex-end;\n }\n `\n\n /** 개별 설정. 없으면 undefined */\n @property({ attribute: false }) value: SlotLayout | undefined\n @property({ attribute: false }) options: SlotLayoutEditorOptions = {}\n\n @state() draft: SlotLayout | undefined\n @state() tier = 1\n @state() dirty = false\n @state() presetKey = ''\n @state() presetSize: Partial<PresetSize> = {}\n @state() presetParams: Record<string, number> = {}\n @state() copyElevation = NaN\n\n willUpdate(changed: Map<string, unknown>) {\n // 호스트가 렌더마다 새 options 를 넘겨도 편집 중인 값을 잃지 않도록, 값이나 호스트 기본값이 바뀔 때만 다시 시작한다\n const before = changed.get('options') as SlotLayoutEditorOptions | undefined\n if (changed.has('value') || (changed.has('options') && before?.effective !== this.options?.effective)) this.reset()\n else if (changed.has('options') && !this.options?.presets?.some(p => p.key === this.presetKey))\n this.presetKey = this.options?.presets?.[0]?.key ?? ''\n }\n\n /** 편집 중인 값을 버리고 개별 설정(없으면 호스트 기본값)에서 다시 시작한다 */\n reset() {\n const start = this.value ?? this.options?.effective\n this.draft = start ? structuredClone(start) : undefined\n this.tier = 1\n this.dirty = false\n this.presetSize = { ...(this.options?.presetSize ?? {}) }\n if (!this.options?.presets?.some(p => p.key === this.presetKey)) this.presetKey = this.options?.presets?.[0]?.key ?? ''\n }\n\n get issues(): EditorIssue[] {\n if (!this.draft) return []\n const invalid: EditorIssue[] = [...validateSlotLayout(this.draft), ...(this.options?.validate?.(this.draft) ?? [])]\n // 저장 불가 검사는 검증을 통과한 값에만 보인다 (같은 문제를 두 번 적지 않는다)\n return invalid.length ? invalid : persistenceIssues(this.draft)\n }\n\n private _text(issue: EditorIssue) {\n return this.options?.issueText?.(issue) ?? defaultIssueText(issue)\n }\n\n private _edit(next: SlotLayout) {\n this.draft = next\n this.dirty = true\n if (!next.tiers.some(x => x.tierNo === this.tier)) this.tier = next.tiers[next.tiers.length - 1]?.tierNo ?? 1\n }\n\n private _apply() {\n this.value = structuredClone(this.draft)\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private _useDefault() {\n this.dispatchEvent(new CustomEvent('slot-layout-use-default', { bubbles: true, composed: true }))\n }\n\n render() {\n const issues = this.issues\n const canUseDefault = this.options?.canUseDefault ?? this.value !== undefined\n return html`\n ${this.options?.notes?.length\n ? html`<div class=\"notes\">\n ${this.options.notes.map(n => html`<div class=${n.level === 'error' ? 'error' : 'note'}>${n.text}</div>`)}\n </div>`\n : nothing}\n ${this._renderPreset()} ${this.draft ? this._renderDraft(issues) : nothing}\n <div class=\"actions\">\n ${canUseDefault ? html`<button data-action=\"use-default\" @click=${this._useDefault}>${t('use-default', 'Use default')}</button>` : nothing}\n <button data-action=\"discard\" ?disabled=${!this.dirty} @click=${() => this.reset()}>${t('discard', 'Discard')}</button>\n <button data-action=\"apply\" ?disabled=${!this.dirty || !this.draft || issues.length > 0} @click=${this._apply}>${t('apply', 'Apply')}</button>\n </div>\n `\n }\n\n private _renderPreset() {\n const presets = this.options?.presets ?? []\n if (!presets.length) return nothing\n const preset = presets.find(p => p.key === this.presetKey) ?? presets[0]\n const built = applyPreset(preset, this.presetSize, this.presetParams)\n const numberRow = (label: string, value: unknown, onChange: (n: number) => void, key: string) => html`\n <div class=\"row\">\n <label>${label}</label>\n <input type=\"number\" data-preset=${key} .value=${value === undefined || Number.isNaN(value) ? '' : String(value)} @change=${(e: Event) => onChange(num(e))} />\n </div>\n `\n return html`\n <h4>${t('preset', 'Preset')}</h4>\n <div class=\"row\">\n <label>${t('preset-kind', 'Kind')}</label>\n <select data-preset=\"kind\" @change=${(e: Event) => (this.presetKey = (e.target as HTMLSelectElement).value)}>\n ${presets.map(p => html`<option value=${p.key} ?selected=${p.key === preset.key}>${p.label}</option>`)}\n </select>\n </div>\n ${numberRow(t('width', 'Width (X)'), this.presetSize.width, n => (this.presetSize = { ...this.presetSize, width: n }), 'width')}\n ${numberRow(t('depth', 'Depth (Z)'), this.presetSize.depth, n => (this.presetSize = { ...this.presetSize, depth: n }), 'depth')}\n ${numberRow(t('slot-height', 'Slot height'), this.presetSize.slotHeight, n => (this.presetSize = { ...this.presetSize, slotHeight: n }), 'slotHeight')}\n ${(preset.params ?? []).map(p =>\n numberRow(p.label, this.presetParams[p.key], n => (this.presetParams = { ...this.presetParams, [p.key]: n }), p.key)\n )}\n <div class=\"note\">${t('preset-note', 'Pitch and slot size are split evenly as starting values. Confirm them against the real equipment.')}</div>\n <div class=\"actions\">\n <button data-action=\"start-preset\" ?disabled=${!built.layout} @click=${() => built.layout && this._startFrom(built.layout)}>\n ${t('start-from-preset', 'Start from preset')}\n </button>\n </div>\n `\n }\n\n /** 프리셋으로 다시 시작한다. 지금 값에 덧붙은 호스트 키(층·자리 밖의 키)는 가져온다 */\n private _startFrom(layout: SlotLayout) {\n const { mount: _m, tiers: _t, ...extra } = (this.draft ?? {}) as Record<string, unknown>\n this._edit({ ...extra, ...structuredClone(layout) } as SlotLayout)\n }\n\n private _renderDraft(issues: EditorIssue[]) {\n const draft = this.draft!\n const tier = draft.tiers?.find(x => x.tierNo === this.tier) ?? draft.tiers?.[0]\n const issueList = issues.length ? html`<div class=\"error\" data-issues>${issues.map(i => html`<div>· ${this._text(i)}</div>`)}</div>` : nothing\n // 층이 없는 값(잘못된 저장값)은 편집할 층이 없으므로 문제만 보인다. 프리셋으로 다시 시작한다\n if (!tier) return issueList\n return html`\n <h4>${t('tiers', 'Tiers')}</h4>\n <div class=\"chips\">\n ${draft.tiers.map(\n x => html`<button data-tier=${x.tierNo} ?active=${x.tierNo === tier.tierNo} @click=${() => (this.tier = x.tierNo)}>${t('tier-n', 'Tier {n}', { n: x.tierNo })}</button>`\n )}\n </div>\n <div class=\"row\">\n <label>${t('copy-elevation', 'New tier elevation')}</label>\n <input type=\"number\" data-field=\"copy-elevation\" .value=${Number.isFinite(this.copyElevation) ? String(this.copyElevation) : ''} @change=${(e: Event) => (this.copyElevation = num(e))} />\n </div>\n <div class=\"actions\">\n <button data-action=\"copy-tier\" ?disabled=${!Number.isFinite(this.copyElevation)} @click=${() => this._edit(copyTier(draft, tier.tierNo, this.copyElevation))}>\n ${t('copy-tier', 'Copy tier')}\n </button>\n <button data-action=\"remove-tier\" ?disabled=${draft.tiers.length <= 1} @click=${() => this._edit(removeTier(draft, tier.tierNo))}>${t('remove-tier', 'Remove tier')}</button>\n </div>\n ${this._renderTier(draft, tier.tierNo)} ${this.options?.renderExtra?.(draft, next => this._edit(next)) ?? nothing}\n <h4>${t('preview', 'Preview (top view, tier {n})', { n: tier.tierNo })}</h4>\n ${this._renderPreview(draft, tier.tierNo)} ${issueList}\n `\n }\n\n private _renderTier(draft: SlotLayout, tierNo: number) {\n const tier = draft.tiers.find(x => x.tierNo === tierNo)!\n const l = tier.layout as SlotPattern & Record<string, any>\n const patternInput = (k: string, label: string, value: unknown, parse: (e: Event) => unknown = num) => html`\n <div class=\"row\">\n <label>${label}</label>\n <input type=\"number\" data-field=${k} .value=${value === undefined || Number.isNaN(value) ? '' : String(value)} @change=${(e: Event) => this._edit(updatePattern(draft, tierNo, { [k]: parse(e) }))} />\n </div>\n `\n const select = (field: string, label: string, value: string, options: string[], onChange: (v: string) => void) => html`\n <div class=\"row\">\n <label>${label}</label>\n <select data-field=${field} @change=${(e: Event) => onChange((e.target as HTMLSelectElement).value)}>\n ${options.map(o => html`<option value=${o} ?selected=${o === value}>${o}</option>`)}\n </select>\n </div>\n `\n return html`\n <div class=\"row\">\n <label>${t('elevation', 'Elevation')}</label>\n <input type=\"number\" data-field=\"elevation\" .value=${String(tier.elevation)} @change=${(e: Event) => this._edit(updateTier(draft, tierNo, { elevation: num(e) }))} />\n </div>\n ${select('pattern', t('pattern', 'Pattern'), l.pattern, ['SINGLE', 'ROW', 'GRID', 'CUSTOM'], v => this._edit(setTierPattern(draft, tierNo, v as SlotPattern['pattern'])))}\n ${l.pattern === 'ROW'\n ? html`\n ${patternInput('count', t('count', 'Slots'), l.count)} ${patternInput('pitch', t('pitch', 'Pitch'), l.pitch)}\n ${select('axis', t('axis', 'Axis'), l.axis, ['X', 'Z'], v => this._edit(updatePattern(draft, tierNo, { axis: v as 'X' | 'Z' })))}\n ${select('origin', t('origin', 'Slot 1 at'), l.origin ?? 'MIN', ['MIN', 'MAX'], v => this._edit(updatePattern(draft, tierNo, { origin: v as 'MIN' | 'MAX' })))}\n `\n : nothing}\n ${l.pattern === 'GRID'\n ? html`\n ${patternInput('rows', t('rows', 'Rows (Z)'), l.rows)} ${patternInput('cols', t('cols', 'Columns (X)'), l.cols)}\n ${patternInput('pitch', t('pitch-x', 'Pitch X'), l.pitch?.x, e => ({ ...l.pitch, x: num(e) }))}\n ${patternInput('pitch', t('pitch-z', 'Pitch Z'), l.pitch?.z, e => ({ ...l.pitch, z: num(e) }))}\n ${select('order', t('order', 'Numbering'), l.order ?? 'ROW_MAJOR', ['ROW_MAJOR', 'COL_MAJOR', 'SERPENTINE_ROW', 'SERPENTINE_COL'], v =>\n this._edit(updatePattern(draft, tierNo, { order: v as GridOrder }))\n )}\n ${select('origin-x', t('origin-x', 'Slot 1 at X'), l.origin?.x ?? 'MIN', ['MIN', 'MAX'], v =>\n this._edit(updatePattern(draft, tierNo, { origin: { z: 'MIN', ...l.origin, x: v as 'MIN' | 'MAX' } }))\n )}\n ${select('origin-z', t('origin-z', 'Slot 1 at Z'), l.origin?.z ?? 'MIN', ['MIN', 'MAX'], v =>\n this._edit(updatePattern(draft, tierNo, { origin: { x: 'MIN', ...l.origin, z: v as 'MIN' | 'MAX' } }))\n )}\n `\n : nothing}\n ${l.pattern === 'CUSTOM' ? this._renderCustom(draft, tierNo) : this._renderSpec(draft, tierNo, l.slot)}\n `\n }\n\n /** 받는 타입: 모든 타입(accepts 생략) / 지정 타입만(빈 목록이면 아무것도 받지 않음) */\n private _acceptsEditor(spec: SlotSpec, onChange: (accepts: string[] | undefined) => void) {\n const restricted = Array.isArray(spec.accepts)\n return html`\n <div class=\"row\">\n <label>${t('accepts', 'Accepts')}</label>\n <select data-field=\"accepts-mode\" @change=${(e: Event) => onChange((e.target as HTMLSelectElement).value === 'ALL' ? undefined : spec.accepts ?? [])}>\n <option value=\"ALL\" ?selected=${!restricted}>${t('accepts-all', 'Any type')}</option>\n <option value=\"LIST\" ?selected=${restricted}>${t('accepts-list', 'Listed types only')}</option>\n </select>\n </div>\n ${restricted\n ? html`<div class=\"row\">\n <label>${t('accepts-types', 'Types (comma)')}</label>\n <input\n data-field=\"accepts\"\n .value=${(spec.accepts ?? []).join(', ')}\n placeholder=${t('accepts-none', 'Empty = accepts nothing')}\n @change=${(e: Event) =>\n onChange(\n (e.target as HTMLInputElement).value\n .split(',')\n .map(s => s.trim())\n .filter(Boolean)\n )}\n />\n </div>`\n : nothing}\n `\n }\n\n private _renderSpec(draft: SlotLayout, tierNo: number, spec: SlotSpec) {\n const edit = (patch: Partial<SlotSpec>) => this._edit(updateSlotSpec(draft, tierNo, patch))\n const allowed = (k: 'width' | 'depth' | 'height', label: string) => html`\n <div class=\"row\">\n <label>${label}</label>\n <input type=\"number\" data-field=${`allowed-${k}`} .value=${String(spec.allowed?.[k] ?? '')} @change=${(e: Event) => edit({ allowed: { ...spec.allowed, [k]: num(e) } })} />\n </div>\n `\n return html`\n <h4>${t('slot-spec', 'Slot (same for every slot in this tier)')}</h4>\n ${allowed('width', t('allowed-width', 'Allowed width'))} ${allowed('depth', t('allowed-depth', 'Allowed depth'))}\n ${allowed('height', t('allowed-height', 'Allowed height'))}\n <div class=\"row\">\n <label>${t('stack-limit', 'Stack limit')}</label>\n <input type=\"number\" data-field=\"stack-limit\" min=\"1\" step=\"1\" .value=${String(spec.stackLimit ?? 1)} @change=${(e: Event) => edit({ stackLimit: num(e) })} />\n </div>\n <div class=\"row\">\n <label>${t('rotation', 'Rotation (deg)')}</label>\n <input type=\"number\" data-field=\"rotation\" .value=${String(spec.rotation ?? 0)} @change=${(e: Event) => edit({ rotation: num(e) || undefined })} />\n </div>\n ${this._acceptsEditor(spec, accepts => edit({ accepts }))}\n `\n }\n\n private _renderCustom(draft: SlotLayout, tierNo: number) {\n const tier = draft.tiers.find(x => x.tierNo === tierNo)!\n const slots = [...(tier.layout as Extract<SlotPattern, { pattern: 'CUSTOM' }>).slots].sort((a, b) => a.slotNo - b.slotNo)\n const cell = (slotNo: number, value: unknown, patch: (e: Event) => Record<string, unknown>) =>\n html`<td><input type=\"number\" .value=${String(value ?? '')} @change=${(e: Event) => this._edit(updateSlotSpec(draft, tierNo, patch(e), slotNo))} /></td>`\n return html`\n <h4>${t('custom-slots', 'Slots')}</h4>\n <table>\n <tr>\n <th>#</th>\n <th>X</th>\n <th>Z</th>\n <th>${t('w', 'W')}</th>\n <th>${t('d', 'D')}</th>\n <th>${t('h', 'H')}</th>\n <th>${t('stack', 'Stack')}</th>\n <th>${t('rot', 'Rot')}</th>\n <th></th>\n </tr>\n ${slots.map(\n s => html`\n <tr>\n <td>${s.slotNo}</td>\n ${cell(s.slotNo, s.offset?.x, e => ({ offset: { ...s.offset, x: num(e) } }))}\n ${cell(s.slotNo, s.offset?.z, e => ({ offset: { ...s.offset, z: num(e) } }))}\n ${cell(s.slotNo, s.allowed?.width, e => ({ allowed: { ...s.allowed, width: num(e) } }))}\n ${cell(s.slotNo, s.allowed?.depth, e => ({ allowed: { ...s.allowed, depth: num(e) } }))}\n ${cell(s.slotNo, s.allowed?.height, e => ({ allowed: { ...s.allowed, height: num(e) } }))}\n ${cell(s.slotNo, s.stackLimit ?? 1, e => ({ stackLimit: num(e) }))} ${cell(s.slotNo, s.rotation ?? 0, e => ({ rotation: num(e) || undefined }))}\n <td><button ?disabled=${slots.length <= 1} @click=${() => this._edit(removeCustomSlot(draft, tierNo, s.slotNo))}>−</button></td>\n </tr>\n `\n )}\n </table>\n <div class=\"actions\"><button data-action=\"add-slot\" @click=${() => this._edit(addCustomSlot(draft, tierNo))}>${t('add-slot', 'Add slot')}</button></div>\n `\n }\n\n /** 위에서 본 자리 배치. 오른쪽이 +X, 위쪽이 −Z */\n private _renderPreview(draft: SlotLayout, tierNo: number) {\n const slots = previewTier(draft, tierNo)\n if (!slots.length) return html`<div class=\"note\" data-preview=\"none\">${t('preview-none', 'No slots to show with the current values.')}</div>`\n const minX = Math.min(...slots.map(s => s.x - s.width / 2))\n const maxX = Math.max(...slots.map(s => s.x + s.width / 2))\n const minZ = Math.min(...slots.map(s => s.z - s.depth / 2))\n const maxZ = Math.max(...slots.map(s => s.z + s.depth / 2))\n const w = Math.max(maxX - minX, 1)\n const h = Math.max(maxZ - minZ, 1)\n const pad = Math.max(w, h) * 0.08\n const font = Math.max(w, h) * 0.07\n return html`\n <svg data-preview viewBox=\"${minX - pad} ${minZ - pad} ${w + pad * 2} ${h + pad * 2}\" preserveAspectRatio=\"xMidYMid meet\">\n ${slots.map(\n s => svg`\n <rect data-slot=${s.slotNo} x=${s.x - s.width / 2} y=${s.z - s.depth / 2} width=${s.width} height=${s.depth}\n fill=\"rgba(25,118,210,0.08)\" stroke=\"rgba(25,118,210,0.8)\" stroke-width=${Math.max(w, h) * 0.006} />\n <text x=${s.x} y=${s.z} font-size=${font} text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"#0d47a1\">${s.slotNo}</text>\n `\n )}\n </svg>\n <div class=\"note\">${t('preview-axes', 'Right = +X, up = −Z')}</div>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ox-slot-layout-editor': OxSlotLayoutEditor\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ox-slot-layout-editor.js","sourceRoot":"","sources":["../../src/ox-slot-layout-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * 자리 레이아웃 편집기. 홀더의 Tier·Slot 구성을 고치고, 검증하고, 미리 보고, [적용]으로 알린다.\n * Tier 는 홀더가 주는 Anchor 하나에 서고, 그 Anchor 기준 위치·회전과 적재 방식(mount)을 갖는다.\n *\n * 컴포넌트 상태를 직접 바꾸지 않는다. 호스트에 두 가지만 알린다:\n * change — 적용한 레이아웃 (this.value)\n * slot-layout-use-default — 개별 설정을 지우고 기본값을 쓰겠다는 의도 (값을 비우는 편집과 다르다)\n * 기본값을 쓰게 된 뒤 보일 값은 호스트가 options.effective 로 다시 준다.\n */\n\nimport { css, html, nothing, LitElement, svg } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { i18next, localize } from '@operato/i18n'\nimport {\n persistenceIssues,\n slotSpaceWarnings,\n validateSlotLayout,\n type GridOrder,\n type SlotLayout,\n type SlotMount,\n type SlotPattern,\n type SlotSpec,\n type SlotSpaceOptions\n} from '@hatiolab/things-scene'\n\nimport {\n addCustomSlot,\n addressImpact,\n applyPreset,\n copyTier,\n previewTier,\n removeCustomSlot,\n removeTier,\n setTierPattern,\n updatePattern,\n updateSlotSpec,\n updateTier,\n type PresetSize,\n type SlotLayoutPreset\n} from './draft.js'\nimport { issueText as defaultIssueText, spaceWarningText, t, type EditorIssue } from './issue-text.js'\n\nexport interface SlotLayoutEditorNote {\n text: string\n level?: 'info' | 'error'\n}\n\nexport interface SlotLayoutEditorOptions<L extends SlotLayout = SlotLayout> {\n /** 개별 설정이 없을 때 보이는 값 (호스트가 고른 기본값). 편집 시작점이 된다 */\n effective?: L\n /** [기본값 사용]을 보일지. 기본은 개별 설정(value)이 있을 때 */\n canUseDefault?: boolean\n /** 호스트가 주는 프리셋 */\n presets?: SlotLayoutPreset<L>[]\n /** 프리셋 크기 초기값 */\n presetSize?: Partial<PresetSize>\n /** 상태 문구 (값의 출처, 단위 상태 등) */\n notes?: SlotLayoutEditorNote[]\n /** 홀더가 주는 Anchor. 주면 Tier 는 이 중 하나를 고르고, 없는 Anchor 는 문제로 보인다 */\n anchors?: { id: string; label?: string }[]\n /** Anchor 가 주는 적재면 크기 (Anchor 기준 X·Z). 주면 자리가 면 밖으로 나가는지와 확인 불가를 알린다 */\n anchorFaces?: SlotSpaceOptions['anchorFaces']\n /** 호스트 고유 검증 (경로는 레이아웃 기준) */\n validate?: (layout: L) => EditorIssue[]\n /** 문제 문구. undefined 를 돌려주면 기본 문구 */\n issueText?: (issue: EditorIssue) => string | undefined\n /** 레이아웃에 덧붙인 호스트 키를 고치는 구역 (예: 실시간 주소 읽기). edit 로 새 레이아웃을 넘긴다 */\n renderExtra?: (draft: L, edit: (next: L) => void) => unknown\n}\n\nconst num = (e: Event) => {\n const n = (e.target as HTMLInputElement).valueAsNumber\n return Number.isFinite(n) ? n : NaN\n}\n\n@customElement('ox-slot-layout-editor')\nexport class OxSlotLayoutEditor extends localize(i18next)(LitElement) {\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n }\n .row {\n display: grid;\n grid-template-columns: 40% 1fr;\n align-items: center;\n gap: 4px;\n }\n .notes {\n padding: 4px 6px;\n border-radius: 4px;\n background: rgba(0, 0, 0, 0.04);\n }\n .error {\n color: #c62828;\n }\n .note {\n color: rgba(0, 0, 0, 0.55);\n }\n .chips {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n .chips button[active] {\n border-color: var(--md-sys-color-primary, #1976d2);\n color: var(--md-sys-color-primary, #1976d2);\n font-weight: bold;\n }\n button {\n font-size: 12px;\n padding: 2px 8px;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n background: #fff;\n cursor: pointer;\n }\n button[disabled] {\n opacity: 0.4;\n cursor: default;\n }\n input,\n select {\n font-size: 12px;\n min-width: 0;\n }\n table {\n border-collapse: collapse;\n width: 100%;\n }\n td,\n th {\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n padding: 1px;\n }\n td input {\n width: 100%;\n box-sizing: border-box;\n }\n h4 {\n margin: 6px 0 2px;\n font-size: 12px;\n }\n svg {\n width: 100%;\n height: 160px;\n background: rgba(0, 0, 0, 0.02);\n border: 1px solid rgba(0, 0, 0, 0.08);\n }\n .actions {\n display: flex;\n gap: 4px;\n justify-content: flex-end;\n }\n `\n\n /** 개별 설정. 없으면 undefined */\n @property({ attribute: false }) value: SlotLayout | undefined\n @property({ attribute: false }) options: SlotLayoutEditorOptions = {}\n\n @state() draft: SlotLayout | undefined\n @state() tier = 1\n @state() dirty = false\n @state() presetKey = ''\n @state() presetSize: Partial<PresetSize> = {}\n @state() presetParams: Record<string, number> = {}\n\n willUpdate(changed: Map<string, unknown>) {\n // 호스트가 렌더마다 새 options 를 넘겨도 편집 중인 값을 잃지 않도록, 값이나 호스트 기본값이 바뀔 때만 다시 시작한다\n const before = changed.get('options') as SlotLayoutEditorOptions | undefined\n if (changed.has('value') || (changed.has('options') && before?.effective !== this.options?.effective)) this.reset()\n else if (changed.has('options') && !this.options?.presets?.some(p => p.key === this.presetKey))\n this.presetKey = this.options?.presets?.[0]?.key ?? ''\n }\n\n /** 편집 중인 값을 버리고 개별 설정(없으면 호스트 기본값)에서 다시 시작한다 */\n reset() {\n const start = this.value ?? this.options?.effective\n this.draft = start ? structuredClone(start) : undefined\n this.tier = this.draft?.tiers?.[0]?.tierNo ?? 1\n this.dirty = false\n this.presetSize = { ...(this.options?.presetSize ?? {}) }\n if (!this.options?.presets?.some(p => p.key === this.presetKey)) this.presetKey = this.options?.presets?.[0]?.key ?? ''\n }\n\n get issues(): EditorIssue[] {\n if (!this.draft) return []\n const anchors = this.options?.anchors?.map(a => a.id)\n const invalid: EditorIssue[] = [...validateSlotLayout(this.draft, { anchors }), ...(this.options?.validate?.(this.draft) ?? [])]\n // 저장 불가 검사는 검증을 통과한 값에만 보인다 (같은 문제를 두 번 적지 않는다)\n return invalid.length ? invalid : persistenceIssues(this.draft)\n }\n\n /** 자리끼리 겹치거나 면 밖으로 나가는 설정 경고. 적용을 막지 않는다. 적재면 크기를 주지 않은 호스트에는 확인 불가를 보이지 않는다 */\n get warnings(): EditorIssue[] {\n if (!this.draft || this.issues.length) return []\n const faces = this.options?.anchorFaces\n return slotSpaceWarnings(this.draft, { anchorFaces: faces }).filter(w => faces || w.code !== 'ANCHOR_SPACE_UNKNOWN')\n }\n\n /** 적용하면 뜻이 바뀌는 주소 (지금 적용된 값 기준) */\n get impact() {\n return this.dirty && !this.issues.length ? addressImpact(this.value ?? this.options?.effective, this.draft) : { moved: [], gone: [] }\n }\n\n private _text(issue: EditorIssue) {\n return this.options?.issueText?.(issue) ?? defaultIssueText(issue)\n }\n\n private _edit(next: SlotLayout) {\n this.draft = next\n this.dirty = true\n if (!next.tiers.some(x => x.tierNo === this.tier)) this.tier = next.tiers[next.tiers.length - 1]?.tierNo ?? 1\n }\n\n private _apply() {\n this.value = structuredClone(this.draft)\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private _useDefault() {\n this.dispatchEvent(new CustomEvent('slot-layout-use-default', { bubbles: true, composed: true }))\n }\n\n render() {\n const issues = this.issues\n const canUseDefault = this.options?.canUseDefault ?? this.value !== undefined\n return html`\n ${this.options?.notes?.length\n ? html`<div class=\"notes\">\n ${this.options.notes.map(n => html`<div class=${n.level === 'error' ? 'error' : 'note'}>${n.text}</div>`)}\n </div>`\n : nothing}\n ${this._renderPreset()} ${this.draft ? this._renderDraft(issues) : nothing} ${this._renderImpact()}\n <div class=\"actions\">\n ${canUseDefault ? html`<button data-action=\"use-default\" @click=${this._useDefault}>${t('use-default', 'Use default')}</button>` : nothing}\n <button data-action=\"discard\" ?disabled=${!this.dirty} @click=${() => this.reset()}>${t('discard', 'Discard')}</button>\n <button data-action=\"apply\" ?disabled=${!this.dirty || !this.draft || issues.length > 0} @click=${this._apply}>${t('apply', 'Apply')}</button>\n </div>\n `\n }\n\n private _renderPreset() {\n const presets = this.options?.presets ?? []\n if (!presets.length) return nothing\n const preset = presets.find(p => p.key === this.presetKey) ?? presets[0]\n const built = applyPreset(preset, this.presetSize, this.presetParams)\n const numberRow = (label: string, value: unknown, onChange: (n: number) => void, key: string) => html`\n <div class=\"row\">\n <label>${label}</label>\n <input type=\"number\" data-preset=${key} .value=${value === undefined || Number.isNaN(value) ? '' : String(value)} @change=${(e: Event) => onChange(num(e))} />\n </div>\n `\n return html`\n <h4>${t('preset', 'Preset')}</h4>\n <div class=\"row\">\n <label>${t('preset-kind', 'Kind')}</label>\n <select data-preset=\"kind\" @change=${(e: Event) => (this.presetKey = (e.target as HTMLSelectElement).value)}>\n ${presets.map(p => html`<option value=${p.key} ?selected=${p.key === preset.key}>${p.label}</option>`)}\n </select>\n </div>\n ${numberRow(t('width', 'Width (X)'), this.presetSize.width, n => (this.presetSize = { ...this.presetSize, width: n }), 'width')}\n ${numberRow(t('depth', 'Depth (Z)'), this.presetSize.depth, n => (this.presetSize = { ...this.presetSize, depth: n }), 'depth')}\n ${numberRow(t('slot-height', 'Slot height'), this.presetSize.slotHeight, n => (this.presetSize = { ...this.presetSize, slotHeight: n }), 'slotHeight')}\n ${(preset.params ?? []).map(p =>\n numberRow(p.label, this.presetParams[p.key], n => (this.presetParams = { ...this.presetParams, [p.key]: n }), p.key)\n )}\n <div class=\"note\">${t('preset-note', 'Pitch and slot size are split evenly as starting values. Confirm them against the real equipment.')}</div>\n <div class=\"actions\">\n <button data-action=\"start-preset\" ?disabled=${!built.layout} @click=${() => built.layout && this._startFrom(built.layout)}>\n ${t('start-from-preset', 'Start from preset')}\n </button>\n </div>\n `\n }\n\n /** 적용 전에 뜻이 바뀌는 주소를 보인다. 놓인 Carrier 는 주소로 다시 읽혀 다른 자리에 그려지거나 예외가 된다 */\n private _renderImpact() {\n const { moved, gone } = this.impact\n if (!moved.length && !gone.length) return nothing\n const list = (ids: string[]) => (ids.length > 12 ? `${ids.slice(0, 12).join(', ')} … (${ids.length})` : ids.join(', '))\n return html`<div class=\"notes\" data-impact>\n ${moved.length ? html`<div class=\"note\">${t('impact-moved', 'Moves: {ids}', { ids: list(moved) })}</div>` : nothing}\n ${gone.length ? html`<div class=\"error\">${t('impact-gone', 'Removed: {ids}', { ids: list(gone) })}</div>` : nothing}\n </div>`\n }\n\n /** 프리셋으로 다시 시작한다. 지금 값에 덧붙은 호스트 키(Tier 밖의 키)는 가져온다 */\n private _startFrom(layout: SlotLayout) {\n const { tiers: _t, ...extra } = (this.draft ?? {}) as Record<string, unknown>\n this._edit({ ...extra, ...structuredClone(layout) } as SlotLayout)\n }\n\n private _renderDraft(issues: EditorIssue[]) {\n const draft = this.draft!\n const tier = draft.tiers?.find(x => x.tierNo === this.tier) ?? draft.tiers?.[0]\n const warnings = this.warnings\n const issueList = issues.length\n ? html`<div class=\"error\" data-issues>${issues.map(i => html`<div>· ${this._text(i)}</div>`)}</div>`\n : warnings.length\n ? html`<div class=\"note\" data-warnings>${warnings.map(w => html`<div>· ${spaceWarningText(w)}</div>`)}</div>`\n : nothing\n // 층이 없는 값(잘못된 저장값)은 편집할 층이 없으므로 문제만 보인다. 프리셋으로 다시 시작한다\n if (!tier) return issueList\n return html`\n <h4>${t('tiers', 'Tiers')}</h4>\n <div class=\"chips\">\n ${draft.tiers.map(\n x => html`<button data-tier=${x.tierNo} ?active=${x.tierNo === tier.tierNo} @click=${() => (this.tier = x.tierNo)}>${t('tier-n', 'Tier {n}', { n: x.tierNo })}</button>`\n )}\n </div>\n <div class=\"actions\">\n <button data-action=\"copy-tier\" @click=${() => this._copyTier(draft, tier.tierNo)}>${t('copy-tier', 'Copy tier')}</button>\n <button data-action=\"remove-tier\" ?disabled=${draft.tiers.length <= 1} @click=${() => this._edit(removeTier(draft, tier.tierNo))}>${t('remove-tier', 'Remove tier')}</button>\n </div>\n ${this._renderTier(draft, tier.tierNo)} ${this.options?.renderExtra?.(draft, next => this._edit(next)) ?? nothing}\n <h4>${t('preview', 'Preview (top view, tier {n}, in the tier)', { n: tier.tierNo })}</h4>\n ${this._renderPreview(draft, tier.tierNo)} ${issueList}\n `\n }\n\n /** 복사한 Tier 를 골라 둔다. 같은 자리에 겹쳐 생기므로 바로 이어서 배치를 고친다 */\n private _copyTier(draft: SlotLayout, tierNo: number) {\n const next = copyTier(draft, tierNo)\n this._edit(next)\n this.tier = next.tiers[next.tiers.length - 1].tierNo\n }\n\n private _renderTier(draft: SlotLayout, tierNo: number) {\n const tier = draft.tiers.find(x => x.tierNo === tierNo)!\n const l = tier.layout as SlotPattern & Record<string, any>\n const patternInput = (k: string, label: string, value: unknown, parse: (e: Event) => unknown = num) => html`\n <div class=\"row\">\n <label>${label}</label>\n <input type=\"number\" data-field=${k} .value=${value === undefined || Number.isNaN(value) ? '' : String(value)} @change=${(e: Event) => this._edit(updatePattern(draft, tierNo, { [k]: parse(e) }))} />\n </div>\n `\n const select = (field: string, label: string, value: string, options: string[], onChange: (v: string) => void) => html`\n <div class=\"row\">\n <label>${label}</label>\n <select data-field=${field} @change=${(e: Event) => onChange((e.target as HTMLSelectElement).value)}>\n ${options.map(o => html`<option value=${o} ?selected=${o === value}>${o}</option>`)}\n </select>\n </div>\n `\n return html`\n ${this._renderPlacement(draft, tierNo)}\n ${select('pattern', t('pattern', 'Pattern'), l.pattern, ['SINGLE', 'ROW', 'GRID', 'CUSTOM'], v => this._edit(setTierPattern(draft, tierNo, v as SlotPattern['pattern'])))}\n ${l.pattern === 'ROW'\n ? html`\n ${patternInput('count', t('count', 'Slots'), l.count)} ${patternInput('pitch', t('pitch', 'Pitch'), l.pitch)}\n ${select('axis', t('axis', 'Axis'), l.axis, ['X', 'Z'], v => this._edit(updatePattern(draft, tierNo, { axis: v as 'X' | 'Z' })))}\n ${select('origin', t('origin', 'Slot 1 at'), l.origin ?? 'MIN', ['MIN', 'MAX'], v => this._edit(updatePattern(draft, tierNo, { origin: v as 'MIN' | 'MAX' })))}\n `\n : nothing}\n ${l.pattern === 'GRID'\n ? html`\n ${patternInput('rows', t('rows', 'Rows (Z)'), l.rows)} ${patternInput('cols', t('cols', 'Columns (X)'), l.cols)}\n ${patternInput('pitch', t('pitch-x', 'Pitch X'), l.pitch?.x, e => ({ ...l.pitch, x: num(e) }))}\n ${patternInput('pitch', t('pitch-z', 'Pitch Z'), l.pitch?.z, e => ({ ...l.pitch, z: num(e) }))}\n ${select('order', t('order', 'Numbering'), l.order ?? 'ROW_MAJOR', ['ROW_MAJOR', 'COL_MAJOR', 'SERPENTINE_ROW', 'SERPENTINE_COL'], v =>\n this._edit(updatePattern(draft, tierNo, { order: v as GridOrder }))\n )}\n ${select('origin-x', t('origin-x', 'Slot 1 at X'), l.origin?.x ?? 'MIN', ['MIN', 'MAX'], v =>\n this._edit(updatePattern(draft, tierNo, { origin: { z: 'MIN', ...l.origin, x: v as 'MIN' | 'MAX' } }))\n )}\n ${select('origin-z', t('origin-z', 'Slot 1 at Z'), l.origin?.z ?? 'MIN', ['MIN', 'MAX'], v =>\n this._edit(updatePattern(draft, tierNo, { origin: { x: 'MIN', ...l.origin, z: v as 'MIN' | 'MAX' } }))\n )}\n `\n : nothing}\n ${l.pattern === 'CUSTOM' ? this._renderCustom(draft, tierNo) : this._renderSpec(draft, tierNo, l.slot)}\n `\n }\n\n /** Tier 가 선 Anchor, 적재 방식, Anchor 기준 위치·회전 */\n private _renderPlacement(draft: SlotLayout, tierNo: number) {\n const tier = draft.tiers.find(x => x.tierNo === tierNo)!\n const anchors = this.options?.anchors\n const edit = (patch: Parameters<typeof updateTier>[2]) => this._edit(updateTier(draft, tierNo, patch))\n const position = tier.position ?? { x: 0, y: 0, z: 0 }\n const axis = (k: 'x' | 'y' | 'z', label: string) => html`\n <div class=\"row\">\n <label>${label}</label>\n <input type=\"number\" data-field=${`position-${k}`} .value=${String(position[k] ?? '')} @change=${(e: Event) => edit({ position: { ...position, [k]: num(e) } })} />\n </div>\n `\n return html`\n <div class=\"row\">\n <label>${t('anchor', 'Anchor')}</label>\n ${anchors?.length\n ? html`<select data-field=\"anchor\" @change=${(e: Event) => edit({ anchorId: (e.target as HTMLSelectElement).value })}>\n ${anchors.some(a => a.id === tier.anchorId) ? nothing : html`<option value=${tier.anchorId ?? ''} selected>${tier.anchorId ?? ''}</option>`}\n ${anchors.map(a => html`<option value=${a.id} ?selected=${a.id === tier.anchorId}>${a.label ?? a.id}</option>`)}\n </select>`\n : html`<input data-field=\"anchor\" .value=${tier.anchorId ?? ''} @change=${(e: Event) => edit({ anchorId: (e.target as HTMLInputElement).value.trim() })} />`}\n </div>\n <div class=\"row\">\n <label>${t('mount', 'Mount')}</label>\n <select data-field=\"mount\" @change=${(e: Event) => edit({ mount: (e.target as HTMLSelectElement).value as SlotMount })}>\n ${(['ON', 'IN', 'HANG'] as const).map(m => html`<option value=${m} ?selected=${m === tier.mount}>${m}</option>`)}\n </select>\n </div>\n ${axis('x', t('position-x', 'Position X'))} ${axis('y', t('position-y', 'Position Y (height)'))} ${axis('z', t('position-z', 'Position Z'))}\n <div class=\"row\">\n <label>${t('tier-rotation', 'Tier rotation (deg)')}</label>\n <input type=\"number\" data-field=\"tier-rotation\" .value=${String(tier.rotation ?? '')} @change=${(e: Event) => edit({ rotation: num(e) })} />\n </div>\n `\n }\n\n /** 받는 타입: 모든 타입(accepts 생략) / 지정 타입만(빈 목록이면 아무것도 받지 않음) */\n private _acceptsEditor(spec: SlotSpec, onChange: (accepts: string[] | undefined) => void) {\n const restricted = Array.isArray(spec.accepts)\n return html`\n <div class=\"row\">\n <label>${t('accepts', 'Accepts')}</label>\n <select data-field=\"accepts-mode\" @change=${(e: Event) => onChange((e.target as HTMLSelectElement).value === 'ALL' ? undefined : spec.accepts ?? [])}>\n <option value=\"ALL\" ?selected=${!restricted}>${t('accepts-all', 'Any type')}</option>\n <option value=\"LIST\" ?selected=${restricted}>${t('accepts-list', 'Listed types only')}</option>\n </select>\n </div>\n ${restricted\n ? html`<div class=\"row\">\n <label>${t('accepts-types', 'Types (comma)')}</label>\n <input\n data-field=\"accepts\"\n .value=${(spec.accepts ?? []).join(', ')}\n placeholder=${t('accepts-none', 'Empty = accepts nothing')}\n @change=${(e: Event) =>\n onChange(\n (e.target as HTMLInputElement).value\n .split(',')\n .map(s => s.trim())\n .filter(Boolean)\n )}\n />\n </div>`\n : nothing}\n `\n }\n\n private _renderSpec(draft: SlotLayout, tierNo: number, spec: SlotSpec) {\n const edit = (patch: Partial<SlotSpec>) => this._edit(updateSlotSpec(draft, tierNo, patch))\n const allowed = (k: 'width' | 'depth' | 'height', label: string) => html`\n <div class=\"row\">\n <label>${label}</label>\n <input type=\"number\" data-field=${`allowed-${k}`} .value=${String(spec.allowed?.[k] ?? '')} @change=${(e: Event) => edit({ allowed: { ...spec.allowed, [k]: num(e) } })} />\n </div>\n `\n return html`\n <h4>${t('slot-spec', 'Slot (same for every slot in this tier)')}</h4>\n ${allowed('width', t('allowed-width', 'Allowed width'))} ${allowed('depth', t('allowed-depth', 'Allowed depth'))}\n ${allowed('height', t('allowed-height', 'Allowed height'))}\n <div class=\"row\">\n <label>${t('stack-limit', 'Stack limit')}</label>\n <input type=\"number\" data-field=\"stack-limit\" min=\"1\" step=\"1\" .value=${String(spec.stackLimit ?? 1)} @change=${(e: Event) => edit({ stackLimit: num(e) })} />\n </div>\n <div class=\"row\">\n <label>${t('rotation', 'Rotation (deg)')}</label>\n <input type=\"number\" data-field=\"rotation\" .value=${String(spec.rotation ?? 0)} @change=${(e: Event) => edit({ rotation: num(e) || undefined })} />\n </div>\n ${this._acceptsEditor(spec, accepts => edit({ accepts }))}\n `\n }\n\n private _renderCustom(draft: SlotLayout, tierNo: number) {\n const tier = draft.tiers.find(x => x.tierNo === tierNo)!\n const slots = [...(tier.layout as Extract<SlotPattern, { pattern: 'CUSTOM' }>).slots].sort((a, b) => a.slotNo - b.slotNo)\n const cell = (slotNo: number, value: unknown, patch: (e: Event) => Record<string, unknown>) =>\n html`<td><input type=\"number\" .value=${String(value ?? '')} @change=${(e: Event) => this._edit(updateSlotSpec(draft, tierNo, patch(e), slotNo))} /></td>`\n return html`\n <h4>${t('custom-slots', 'Slots')}</h4>\n <table>\n <tr>\n <th>#</th>\n <th>X</th>\n <th>Z</th>\n <th>${t('w', 'W')}</th>\n <th>${t('d', 'D')}</th>\n <th>${t('h', 'H')}</th>\n <th>${t('stack', 'Stack')}</th>\n <th>${t('rot', 'Rot')}</th>\n <th></th>\n </tr>\n ${slots.map(\n s => html`\n <tr>\n <td>${s.slotNo}</td>\n ${cell(s.slotNo, s.offset?.x, e => ({ offset: { ...s.offset, x: num(e) } }))}\n ${cell(s.slotNo, s.offset?.z, e => ({ offset: { ...s.offset, z: num(e) } }))}\n ${cell(s.slotNo, s.allowed?.width, e => ({ allowed: { ...s.allowed, width: num(e) } }))}\n ${cell(s.slotNo, s.allowed?.depth, e => ({ allowed: { ...s.allowed, depth: num(e) } }))}\n ${cell(s.slotNo, s.allowed?.height, e => ({ allowed: { ...s.allowed, height: num(e) } }))}\n ${cell(s.slotNo, s.stackLimit ?? 1, e => ({ stackLimit: num(e) }))} ${cell(s.slotNo, s.rotation ?? 0, e => ({ rotation: num(e) || undefined }))}\n <td><button ?disabled=${slots.length <= 1} @click=${() => this._edit(removeCustomSlot(draft, tierNo, s.slotNo))}>−</button></td>\n </tr>\n `\n )}\n </table>\n <div class=\"actions\"><button data-action=\"add-slot\" @click=${() => this._edit(addCustomSlot(draft, tierNo))}>${t('add-slot', 'Add slot')}</button></div>\n `\n }\n\n /** 위에서 본 자리 배치. 오른쪽이 +X, 위쪽이 −Z */\n private _renderPreview(draft: SlotLayout, tierNo: number) {\n const slots = previewTier(draft, tierNo)\n if (!slots.length) return html`<div class=\"note\" data-preview=\"none\">${t('preview-none', 'No slots to show with the current values.')}</div>`\n const minX = Math.min(...slots.map(s => s.x - s.width / 2))\n const maxX = Math.max(...slots.map(s => s.x + s.width / 2))\n const minZ = Math.min(...slots.map(s => s.z - s.depth / 2))\n const maxZ = Math.max(...slots.map(s => s.z + s.depth / 2))\n const w = Math.max(maxX - minX, 1)\n const h = Math.max(maxZ - minZ, 1)\n const pad = Math.max(w, h) * 0.08\n const font = Math.max(w, h) * 0.07\n return html`\n <svg data-preview viewBox=\"${minX - pad} ${minZ - pad} ${w + pad * 2} ${h + pad * 2}\" preserveAspectRatio=\"xMidYMid meet\">\n ${slots.map(\n s => svg`\n <rect data-slot=${s.slotNo} x=${s.x - s.width / 2} y=${s.z - s.depth / 2} width=${s.width} height=${s.depth}\n fill=\"rgba(25,118,210,0.08)\" stroke=\"rgba(25,118,210,0.8)\" stroke-width=${Math.max(w, h) * 0.006} />\n <text x=${s.x} y=${s.z} font-size=${font} text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"#0d47a1\">${s.slotNo}</text>\n `\n )}\n </svg>\n <div class=\"note\">${t('preview-axes', 'Right = +X, up = −Z')}</div>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ox-slot-layout-editor': OxSlotLayoutEditor\n }\n}\n"]}
|