@things-factory/figure-ui 10.1.34 → 10.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/client/graphql/index.ts +13 -0
  2. package/client/graphql/v3-store.ts +30 -0
  3. package/client/modeller/figure-history-panel.ts +29 -2
  4. package/client/modeller/v3-canvas.ts +145 -0
  5. package/client/modeller/v3-editor.ts +317 -0
  6. package/client/modeller/v3-product-session.ts +141 -0
  7. package/client/modeller/v3-renderer.ts +61 -0
  8. package/client/pages/figure-modeller-page.ts +50 -3
  9. package/client/pages/figure-v3-modeller-page.ts +117 -0
  10. package/client/types.ts +8 -0
  11. package/dist-client/graphql/index.js +13 -0
  12. package/dist-client/graphql/index.js.map +1 -1
  13. package/dist-client/graphql/v3-store.d.ts +3 -0
  14. package/dist-client/graphql/v3-store.js +32 -0
  15. package/dist-client/graphql/v3-store.js.map +1 -0
  16. package/dist-client/modeller/figure-history-panel.d.ts +2 -0
  17. package/dist-client/modeller/figure-history-panel.js +28 -1
  18. package/dist-client/modeller/figure-history-panel.js.map +1 -1
  19. package/dist-client/modeller/v3-canvas.d.ts +28 -0
  20. package/dist-client/modeller/v3-canvas.js +157 -0
  21. package/dist-client/modeller/v3-canvas.js.map +1 -0
  22. package/dist-client/modeller/v3-editor.d.ts +19 -0
  23. package/dist-client/modeller/v3-editor.js +332 -0
  24. package/dist-client/modeller/v3-editor.js.map +1 -0
  25. package/dist-client/modeller/v3-product-session.d.ts +366 -0
  26. package/dist-client/modeller/v3-product-session.js +130 -0
  27. package/dist-client/modeller/v3-product-session.js.map +1 -0
  28. package/dist-client/modeller/v3-renderer.d.ts +31 -0
  29. package/dist-client/modeller/v3-renderer.js +81 -0
  30. package/dist-client/modeller/v3-renderer.js.map +1 -0
  31. package/dist-client/pages/figure-modeller-page.d.ts +7 -0
  32. package/dist-client/pages/figure-modeller-page.js +55 -2
  33. package/dist-client/pages/figure-modeller-page.js.map +1 -1
  34. package/dist-client/pages/figure-v3-modeller-page.d.ts +26 -0
  35. package/dist-client/pages/figure-v3-modeller-page.js +140 -0
  36. package/dist-client/pages/figure-v3-modeller-page.js.map +1 -0
  37. package/dist-client/tsconfig.tsbuildinfo +1 -1
  38. package/dist-client/types.d.ts +7 -0
  39. package/dist-client/types.js.map +1 -1
  40. package/docs/v3-product-cutover.md +35 -0
  41. package/package.json +4 -4
  42. package/test/v3-product-session.test.ts +133 -0
  43. package/test/v3-product-write.test.ts +48 -0
  44. package/test/v3-renderer.test.ts +24 -0
  45. package/translations/en.json +3 -0
  46. package/translations/ja.json +3 -0
  47. package/translations/ko.json +3 -0
  48. package/translations/ms.json +3 -0
  49. package/translations/zh.json +3 -0
@@ -143,6 +143,7 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
143
143
  * 미저장 표시(`dirty`)는 그대로 남으므로 데이터를 잃지는 않았다. 잃은 것은 **사유**다.
144
144
  */
145
145
  this.saveFailure = '';
146
+ this.sourceLoadFailure = '';
146
147
  this.showSaveModal = false;
147
148
  this.saveModalType = '';
148
149
  this.saveModalName = '';
@@ -837,6 +838,11 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
837
838
  };
838
839
  }
839
840
  render() {
841
+ if (this.sourceLoadFailure)
842
+ return html `<section role="alert" style="padding:24px">
843
+ <h2>Figure를 열지 못했습니다</h2><p>${this.sourceLoadFailure}</p>
844
+ <button @click=${() => navigate('figure-list')}>Figure 목록으로</button>
845
+ </section>`;
840
846
  const source = this.folded;
841
847
  return html `
842
848
  <div
@@ -850,6 +856,7 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
850
856
  @figure-reverted=${() => this.figure?.id && this.load(this.figure.id)}
851
857
  @preview-sizing-fix=${(e) => this.previewSizingFix(e.detail)}
852
858
  @apply-sizing-fix=${(e) => this.applySizingFix(e.detail)}
859
+ @apply-sizing-fix-plan=${(e) => this.applySizingFixPlan(e.detail)}
853
860
  @restore-released-footprint=${(e) => this.restoreReleasedFootprint(e.detail)}
854
861
  @fit-base-to-parts=${() => this.fitBaseToParts()}
855
862
  @settle-parts-on-floor=${() => this.settlePartsOnFloor()}
@@ -1198,6 +1205,37 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
1198
1205
  return;
1199
1206
  this.take();
1200
1207
  }
1208
+ /**
1209
+ * The release gate may need several anchors to keep a connected assembly together. It has already
1210
+ * measured the complete set. Apply it directly to this unsaved work copy instead of making the
1211
+ * author accept a sequence of opaque mini-proposals.
1212
+ */
1213
+ applySizingFixPlan(plan) {
1214
+ if (!plan.safe || !this.folded || plan.fixes.length === 0)
1215
+ return;
1216
+ const fixes = new Map(plan.fixes.map(fix => [`${fix.part}:${fix.axis}`, fix]));
1217
+ const next = {
1218
+ ...this.folded,
1219
+ parts: this.folded.parts.map(part => {
1220
+ const anchor = { ...(part.anchor ?? {}) };
1221
+ let changed = false;
1222
+ for (const axis of ['x', 'y', 'z']) {
1223
+ const fix = fixes.get(`${part.name}:${axis}`);
1224
+ if (!fix)
1225
+ continue;
1226
+ anchor[axis] = fix.to;
1227
+ changed = true;
1228
+ }
1229
+ return changed ? { ...part, anchor } : part;
1230
+ })
1231
+ };
1232
+ this.recordHistory();
1233
+ const { draft, parts } = fromFigureSource(next);
1234
+ this.draft = draft;
1235
+ this.parts = parts;
1236
+ this.selected = parts.length ? 0 : -1;
1237
+ this.dirty = true;
1238
+ }
1201
1239
  /**
1202
1240
  * 고른 변경을 받아들인다.
1203
1241
  *
@@ -1333,6 +1371,17 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
1333
1371
  const figure = await fetchFigure(id);
1334
1372
  if (generation !== this.loadGeneration || !this.active)
1335
1373
  return;
1374
+ // Decode before assigning the target ID or generating a thumbnail. On failure the previous
1375
+ // editor snapshot remains internal, but is hidden and cannot be saved under the requested ID.
1376
+ let model;
1377
+ try {
1378
+ model = figure.source ? fromFigureSource(JSON.parse(figure.source)) : undefined;
1379
+ }
1380
+ catch (error) {
1381
+ this.sourceLoadFailure = error instanceof Error ? error.message : String(error);
1382
+ return;
1383
+ }
1384
+ this.sourceLoadFailure = '';
1336
1385
  this.proposalSession = undefined;
1337
1386
  this.proposalBaseSource = undefined;
1338
1387
  this.figure = figure;
@@ -1348,7 +1397,6 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
1348
1397
  }
1349
1398
  // 서버가 준 것을 그대로 쓴다. 읽지 못하면 오류보고없이 빈 상태로 바꾸지 않는다.
1350
1399
  // 그러면 사용자가 저장을 선택해 원본을 덮어쓴다.
1351
- const model = figure.source ? fromFigureSource(JSON.parse(figure.source)) : undefined;
1352
1400
  this.draft = model?.draft;
1353
1401
  this.parts = model?.parts ?? [];
1354
1402
  /*
@@ -1390,6 +1438,7 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
1390
1438
  }
1391
1439
  }
1392
1440
  startNew() {
1441
+ this.sourceLoadFailure = '';
1393
1442
  ++this.loadGeneration;
1394
1443
  this.proposalSession = undefined;
1395
1444
  this.proposalBaseSource = undefined;
@@ -1747,7 +1796,7 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
1747
1796
  }
1748
1797
  }
1749
1798
  save() {
1750
- if (!this.canSave || !this.folded || !this.figure) {
1799
+ if (this.sourceLoadFailure || !this.canSave || !this.folded || !this.figure) {
1751
1800
  return;
1752
1801
  }
1753
1802
  if (!this.figure.id) {
@@ -1943,6 +1992,10 @@ __decorate([
1943
1992
  state(),
1944
1993
  __metadata("design:type", Object)
1945
1994
  ], FigureModellerPage.prototype, "saveFailure", void 0);
1995
+ __decorate([
1996
+ state(),
1997
+ __metadata("design:type", Object)
1998
+ ], FigureModellerPage.prototype, "sourceLoadFailure", void 0);
1946
1999
  __decorate([
1947
2000
  state(),
1948
2001
  __metadata("design:type", Object)