@things-factory/figure-ui 10.1.6 → 10.1.8

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 (51) hide show
  1. package/client/graphql/index.ts +25 -0
  2. package/client/modeller/figure-animations.ts +769 -0
  3. package/client/modeller/figure-ask.ts +6 -1
  4. package/client/modeller/figure-history-panel.ts +52 -1
  5. package/client/modeller/figure-inspector.ts +520 -120
  6. package/client/modeller/figure-side.ts +65 -17
  7. package/client/modeller/proposal-session.ts +92 -0
  8. package/client/pages/figure-list-page.ts +56 -4
  9. package/client/pages/figure-modeller-page.ts +204 -179
  10. package/client/types.ts +39 -0
  11. package/client/viewparts/figure-thumb.ts +78 -0
  12. package/dist-client/graphql/index.d.ts +3 -1
  13. package/dist-client/graphql/index.js +22 -0
  14. package/dist-client/graphql/index.js.map +1 -1
  15. package/dist-client/modeller/figure-animations.d.ts +96 -0
  16. package/dist-client/modeller/figure-animations.js +708 -0
  17. package/dist-client/modeller/figure-animations.js.map +1 -0
  18. package/dist-client/modeller/figure-ask.d.ts +3 -0
  19. package/dist-client/modeller/figure-ask.js +9 -0
  20. package/dist-client/modeller/figure-ask.js.map +1 -1
  21. package/dist-client/modeller/figure-history-panel.d.ts +7 -0
  22. package/dist-client/modeller/figure-history-panel.js +50 -0
  23. package/dist-client/modeller/figure-history-panel.js.map +1 -1
  24. package/dist-client/modeller/figure-inspector.d.ts +17 -0
  25. package/dist-client/modeller/figure-inspector.js +506 -107
  26. package/dist-client/modeller/figure-inspector.js.map +1 -1
  27. package/dist-client/modeller/figure-side.d.ts +23 -0
  28. package/dist-client/modeller/figure-side.js +68 -16
  29. package/dist-client/modeller/figure-side.js.map +1 -1
  30. package/dist-client/modeller/proposal-session.d.ts +23 -0
  31. package/dist-client/modeller/proposal-session.js +65 -0
  32. package/dist-client/modeller/proposal-session.js.map +1 -0
  33. package/dist-client/pages/figure-list-page.d.ts +10 -0
  34. package/dist-client/pages/figure-list-page.js +55 -4
  35. package/dist-client/pages/figure-list-page.js.map +1 -1
  36. package/dist-client/pages/figure-modeller-page.d.ts +50 -28
  37. package/dist-client/pages/figure-modeller-page.js +197 -176
  38. package/dist-client/pages/figure-modeller-page.js.map +1 -1
  39. package/dist-client/tsconfig.tsbuildinfo +1 -1
  40. package/dist-client/types.d.ts +44 -0
  41. package/dist-client/types.js.map +1 -1
  42. package/dist-client/viewparts/figure-thumb.js +74 -0
  43. package/dist-client/viewparts/figure-thumb.js.map +1 -1
  44. package/package.json +4 -5
  45. package/test/ai-proposal-contract.test.ts +169 -0
  46. package/test/i18n-prefix-guard.test.ts +42 -0
  47. package/translations/en.json +82 -6
  48. package/translations/ja.json +34 -1
  49. package/translations/ko.json +92 -6
  50. package/translations/ms.json +34 -1
  51. package/translations/zh.json +34 -1
@@ -8,7 +8,7 @@ import type { FigureSource } from '@hatiolab/figure-model'
8
8
  import { activePalette } from '@hatiolab/things-scene'
9
9
 
10
10
  import { proposeFigure } from '../graphql/index.js'
11
- import type { FigureProposal } from '../types.js'
11
+ import type { FigureProposal, ProposalFeedback } from '../types.js'
12
12
 
13
13
  /**
14
14
  * 말로 시키는 줄.
@@ -175,6 +175,8 @@ export class FigureAsk extends localize(i18next)(LitElement) {
175
175
  @property({ type: Object }) source?: FigureSource
176
176
  /** 새로 만들 때 쓸 타입 이름. */
177
177
  @property({ type: String }) type = ''
178
+ /** 이 모델러 세션에서 사람이 명시적으로 남긴 이전 후보 반응. */
179
+ @property({ type: Array }) feedback: ProposalFeedback[] = []
178
180
 
179
181
  @state() private asking = false
180
182
  @state() private failure = ''
@@ -239,6 +241,9 @@ export class FigureAsk extends localize(i18next)(LitElement) {
239
241
  type: this.source ? undefined : this.type,
240
242
  // 그리는 쪽이 풀 수 있는 토큰만 보낸다. 서버는 이 목록 밖의 색을 거절한다.
241
243
  palette: Object.keys(activePalette() as Record<string, string>),
244
+ // 구조적으로는 맞지만 품질 근거가 남으면 한 번 더 개선 후보를 시킨다.
245
+ refine: true,
246
+ feedback: this.feedback,
242
247
  image: this.picture
243
248
  })
244
249
 
@@ -7,7 +7,7 @@ import { i18next, localize } from '@operato/i18n'
7
7
  import { ScrollbarStyles } from '@operato/styles'
8
8
 
9
9
  import { fetchFigureVersions, inspectFigure, releaseFigure, revertFigureVersion } from '../graphql/index.js'
10
- import type { FigureGateFinding, FigureInspection, FigureVersion } from '../types.js'
10
+ import type { FigureGateFinding, FigureGateFix, FigureInspection, FigureVersion } from '../types.js'
11
11
 
12
12
  /**
13
13
  * 이력 — **발행하는 자리이자, 발행된 판들을 보는 자리.**
@@ -253,6 +253,33 @@ export class FigureHistoryPanel extends localize(i18next)(LitElement) {
253
253
  margin-top: 1px;
254
254
  }
255
255
 
256
+ /* 설명으로 끝내지 않는다. 이 단추는 원본을 바꾸지 않고 모델러에 후보만 연다. */
257
+ li[finding] button[preview-fix] {
258
+ margin-top: 3px;
259
+ padding: 4px 7px;
260
+ font-weight: 700;
261
+ color: var(--md-sys-color-on-primary-container, var(--md-sys-color-on-surface));
262
+ background-color: var(--md-sys-color-primary-container, transparent);
263
+ border: 0;
264
+ border-radius: 5px;
265
+ cursor: pointer;
266
+ }
267
+
268
+ li[finding] button[preview-fix]:hover {
269
+ filter: brightness(1.08);
270
+ }
271
+
272
+ li[finding] button[apply-fix] {
273
+ margin-top: 3px;
274
+ padding: 4px 7px;
275
+ font-weight: 700;
276
+ color: var(--ui-on-accent, #fff);
277
+ background-color: var(--md-sys-color-primary);
278
+ border: 0;
279
+ border-radius: 5px;
280
+ cursor: pointer;
281
+ }
282
+
256
283
  p[quiet] {
257
284
  margin: 0;
258
285
  line-height: 1.6;
@@ -408,10 +435,34 @@ export class FigureHistoryPanel extends localize(i18next)(LitElement) {
408
435
  ${finding.at ? html`<code where>${finding.at}</code>` : nothing}
409
436
  ${finding.why ? html`<span why-line>${finding.why}</span>` : nothing}
410
437
  ${finding.how ? html`<span how-line><md-icon>build</md-icon>${finding.how}</span>` : nothing}
438
+ ${(finding.fixes ?? []).map(fix => html`
439
+ ${fix.safe ? html`
440
+ <button apply-fix @click=${() => this.applyFix(fix)}>
441
+ 안전하게 수정 적용 · ${fix.part}.anchor.${fix.axis}: ${fix.from ?? 'auto'} → ${fix.to}
442
+ </button>
443
+ ` : nothing}
444
+ <button preview-fix @click=${() => this.previewFix(fix)}>
445
+ 수정안 미리보기 · ${fix.part}.anchor.${fix.axis}: ${fix.from ?? 'auto'} → ${fix.to}
446
+ </button>
447
+ `)}
411
448
  </li>
412
449
  `
413
450
  }
414
451
 
452
+ /**
453
+ * 게이트는 수정을 저장하지 않는다. 부모 모델러가 현재 정본과 이 한 수정안을 나란히 렌더하고,
454
+ * 저작자가 '변경 받기'를 눌렀을 때에만 자기 작업 사본에 적용한다.
455
+ */
456
+ private previewFix(fix: FigureGateFix) {
457
+ this.dispatchEvent(new CustomEvent('preview-sizing-fix', { detail: fix, bubbles: true, composed: true }))
458
+ }
459
+
460
+ /** 서버가 전수 재검사해 모든 차단 split이 사라진 후보만 작업 사본에 원클릭 적용한다. 저장은 하지 않는다. */
461
+ private applyFix(fix: FigureGateFix) {
462
+ if (!fix.safe) return
463
+ this.dispatchEvent(new CustomEvent('apply-sizing-fix', { detail: fix, bubbles: true, composed: true }))
464
+ }
465
+
415
466
  private renderVersion(version: FigureVersion) {
416
467
  return html`
417
468
  <li>