@things-factory/figure-ui 10.1.170 → 10.1.172
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/client/modeller/editor.ts +11 -5
- package/client/modeller/figure-preview.ts +9 -3
- package/dist-client/modeller/editor.js +11 -5
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/figure-links.d.ts +1 -1
- package/dist-client/modeller/figure-material-panel.d.ts +1 -1
- package/dist-client/modeller/figure-preview.js +9 -3
- package/dist-client/modeller/figure-preview.js.map +1 -1
- package/dist-client/modeller/figure-section-panel.d.ts +1 -1
- package/dist-client/modeller/group-menu.d.ts +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/test/browser/modeller.check.mjs +3 -1
- package/test/browser/screen-page.js +2 -1
- package/test/browser/screen.check.mjs +26 -1
|
@@ -1358,7 +1358,7 @@ export class FigureEditor extends LitElement {
|
|
|
1358
1358
|
return version > 0 ? i18next.t('figure.text.release-state-draft-over', { version: String(version) }) : i18next.t('figure.text.release-state-draft-new')
|
|
1359
1359
|
}
|
|
1360
1360
|
/** The findings that block release, under the bar beside 「발행」, each with the way out the verdict tab offers for it. */
|
|
1361
|
-
private renderReleaseBlockers(asset: FigureAsset | undefined, unavailable: boolean) {
|
|
1361
|
+
private renderReleaseBlockers(blockers: FigureGateFinding[], asset: FigureAsset | undefined, unavailable: boolean) {
|
|
1362
1362
|
const parts = (asset?.appearance ?? []).map(look => look.target)
|
|
1363
1363
|
const way = (code: string) =>
|
|
1364
1364
|
(code === 'occupancy-undeclared' || code === 'part-outside-occupancy') && asset && parts.length
|
|
@@ -1369,7 +1369,7 @@ export class FigureEditor extends LitElement {
|
|
|
1369
1369
|
return html`<div release-blockers role="dialog" aria-label=${i18next.t('figure.text.must-fix-to-release')} @keydown=${(e: KeyboardEvent) => e.key === 'Escape' && (this.blockersOpen = false)}>
|
|
1370
1370
|
<ul gate>
|
|
1371
1371
|
<li head>${i18next.t('figure.text.must-fix-to-release')}</li>
|
|
1372
|
-
${
|
|
1372
|
+
${blockers.map(finding => renderGateFinding(finding, true, way(finding.code), parts))}
|
|
1373
1373
|
</ul>
|
|
1374
1374
|
</div>`
|
|
1375
1375
|
}
|
|
@@ -1659,6 +1659,12 @@ export class FigureEditor extends LitElement {
|
|
|
1659
1659
|
: view.dirty || !view.id
|
|
1660
1660
|
? 'figure.text.unsaved-changes'
|
|
1661
1661
|
: 'figure.text.saved'
|
|
1662
|
+
/*
|
|
1663
|
+
A figure with no parts yet is not one that failed: what blocks its release is said once it has something to
|
|
1664
|
+
release (first 15 minutes, 2026-10-16 evening -- red from the first click read as a failure). The verdict tab
|
|
1665
|
+
still says it.
|
|
1666
|
+
*/
|
|
1667
|
+
const blockers = view.geometry.length ? this.releaseBlockers : []
|
|
1662
1668
|
const tab = this.tab
|
|
1663
1669
|
const live = this.liveParts(shown)
|
|
1664
1670
|
return html`<ox-canvas-bar
|
|
@@ -1683,15 +1689,15 @@ export class FigureEditor extends LitElement {
|
|
|
1683
1689
|
<span slot="status" class="status" role="status" ?dirty=${status === 'figure.text.unsaved-changes'}>${i18next.t(status)}</span>
|
|
1684
1690
|
<span slot="status" release-state>${this.releaseWords(view)}</span>
|
|
1685
1691
|
${this.renderOverlayButton('history', 'history', 'figure.label.history', 'commit')}
|
|
1686
|
-
${
|
|
1692
|
+
${blockers.length
|
|
1687
1693
|
? html`<button slot="commit" release-blocked aria-expanded=${String(this.blockersOpen)} @click=${() => (this.blockersOpen = !this.blockersOpen)}>
|
|
1688
|
-
<md-icon>error</md-icon>${i18next.t('figure.button.release-blocked', { count:
|
|
1694
|
+
<md-icon>error</md-icon>${i18next.t('figure.button.release-blocked', { count: blockers.length })}
|
|
1689
1695
|
</button>`
|
|
1690
1696
|
: nothing}
|
|
1691
1697
|
<button slot="commit" publish ?disabled=${!view.id} title=${view.id ? '' : i18next.t('figure.text.save-the-figure-before-releasing')} @click=${this.goRelease}>${i18next.t('figure.button.release')}</button>
|
|
1692
1698
|
<button slot="commit" save ?disabled=${unavailable || (!view.dirty && !!view.id)} @click=${this.save}>${i18next.t('figure.button.save')}</button>
|
|
1693
1699
|
</ox-canvas-bar>
|
|
1694
|
-
${this.blockersOpen &&
|
|
1700
|
+
${this.blockersOpen && blockers.length ? this.renderReleaseBlockers(blockers, asset, unavailable) : nothing}
|
|
1695
1701
|
${this.catalogOpen
|
|
1696
1702
|
? html`<figure-recipe-catalog
|
|
1697
1703
|
.templates=${this.templates}
|
|
@@ -10,7 +10,7 @@ import { DEFAULT_VIEW, previewBoardDepth, sceneLook, WORKBENCH, type ViewSetting
|
|
|
10
10
|
import { dialShape } from './angle-dial.js'
|
|
11
11
|
import { domainOf, motionWrittenByData, typedValueOf, valueRowsOf } from './data-interface.js'
|
|
12
12
|
import { derivedOf, type FigureRevision } from './revision.js'
|
|
13
|
-
import { authoredSizeOf, PREVIEW_FACTOR, PREVIEW_WAYS, previewClampsOf, previewInstances, previewOneInstance, previewTypeOf, setupPartOf, sizeRangeOf, sizeWithinRange } from '@things-factory/figure-viewer/dist-client/preview-model.js'
|
|
13
|
+
import { authoredSizeOf, occupancyAtSize, PREVIEW_FACTOR, PREVIEW_WAYS, previewClampsOf, previewInstances, previewOneInstance, previewTypeOf, setupPartOf, sizeRangeOf, sizeWithinRange } from '@things-factory/figure-viewer/dist-client/preview-model.js'
|
|
14
14
|
import { previewSizeWordsOf } from './preview-size.js'
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -353,6 +353,8 @@ export class FigurePreview extends localize(i18next)(LitElement) {
|
|
|
353
353
|
if (way === this.way) return
|
|
354
354
|
this.way = way
|
|
355
355
|
this.standUp()
|
|
356
|
+
/* The content is made again inside the scene standing, which keeps the camera: from one figure to eight it stood inside them. */
|
|
357
|
+
requestAnimationFrame(() => this.fitView())
|
|
356
358
|
}
|
|
357
359
|
|
|
358
360
|
/** The one figure at another size on an axis, held to what the figure declares, its centre kept on the board's. */
|
|
@@ -362,7 +364,9 @@ export class FigurePreview extends localize(i18next)(LitElement) {
|
|
|
362
364
|
if (used === undefined || !this.trying) return
|
|
363
365
|
this.trying = { ...this.trying, [axis]: used }
|
|
364
366
|
const instance = this.scene?.root?.components?.[0] as { model?: { width?: number; height?: number }; set(props: Record<string, unknown>): void } | undefined
|
|
365
|
-
|
|
367
|
+
/* The instance's box is the space the figure takes at the sizes tried, not the sizes (occupancyAtSize). */
|
|
368
|
+
const box = occupancyAtSize(asset!, this.trying) ?? this.trying
|
|
369
|
+
instance?.set({ width: box.x, depth: box.y, height: box.z })
|
|
366
370
|
const { width = 0, height = 0 } = instance?.model ?? {}
|
|
367
371
|
instance?.set({ left: this.board.width / 2 - width / 2, top: this.board.height / 2 - height / 2 })
|
|
368
372
|
}
|
|
@@ -596,7 +600,9 @@ export class FigurePreview extends localize(i18next)(LitElement) {
|
|
|
596
600
|
this.valuing = {}
|
|
597
601
|
registerFigure(type, asset)
|
|
598
602
|
this.registered = type
|
|
599
|
-
|
|
603
|
+
/* Each instance stands in the space the figure takes at the size it is asked (occupancyAtSize), as a board reads it. */
|
|
604
|
+
const boxOf = (asked: { x: number; y: number; z: number }) => occupancyAtSize(asset, asked) ?? asked
|
|
605
|
+
const { components, board } = this.way === 'one' ? previewOneInstance(type, boxOf(size)) : previewInstances(type, size, boxOf)
|
|
600
606
|
this.board = board
|
|
601
607
|
this.trying = this.way === 'one' ? { ...size } : undefined
|
|
602
608
|
const model = {
|
|
@@ -1369,7 +1369,7 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1369
1369
|
return version > 0 ? i18next.t('figure.text.release-state-draft-over', { version: String(version) }) : i18next.t('figure.text.release-state-draft-new');
|
|
1370
1370
|
}
|
|
1371
1371
|
/** The findings that block release, under the bar beside 「발행」, each with the way out the verdict tab offers for it. */
|
|
1372
|
-
renderReleaseBlockers(asset, unavailable) {
|
|
1372
|
+
renderReleaseBlockers(blockers, asset, unavailable) {
|
|
1373
1373
|
const parts = (asset?.appearance ?? []).map(look => look.target);
|
|
1374
1374
|
const way = (code) => (code === 'occupancy-undeclared' || code === 'part-outside-occupancy') && asset && parts.length
|
|
1375
1375
|
? html `<button act ?disabled=${unavailable} @click=${() => this.linkCommand(occupancyFromParts(asset))}>
|
|
@@ -1379,7 +1379,7 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1379
1379
|
return html `<div release-blockers role="dialog" aria-label=${i18next.t('figure.text.must-fix-to-release')} @keydown=${(e) => e.key === 'Escape' && (this.blockersOpen = false)}>
|
|
1380
1380
|
<ul gate>
|
|
1381
1381
|
<li head>${i18next.t('figure.text.must-fix-to-release')}</li>
|
|
1382
|
-
${
|
|
1382
|
+
${blockers.map(finding => renderGateFinding(finding, true, way(finding.code), parts))}
|
|
1383
1383
|
</ul>
|
|
1384
1384
|
</div>`;
|
|
1385
1385
|
}
|
|
@@ -1679,6 +1679,12 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1679
1679
|
: view.dirty || !view.id
|
|
1680
1680
|
? 'figure.text.unsaved-changes'
|
|
1681
1681
|
: 'figure.text.saved';
|
|
1682
|
+
/*
|
|
1683
|
+
A figure with no parts yet is not one that failed: what blocks its release is said once it has something to
|
|
1684
|
+
release (first 15 minutes, 2026-10-16 evening -- red from the first click read as a failure). The verdict tab
|
|
1685
|
+
still says it.
|
|
1686
|
+
*/
|
|
1687
|
+
const blockers = view.geometry.length ? this.releaseBlockers : [];
|
|
1682
1688
|
const tab = this.tab;
|
|
1683
1689
|
const live = this.liveParts(shown);
|
|
1684
1690
|
return html `<ox-canvas-bar
|
|
@@ -1701,15 +1707,15 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1701
1707
|
<span slot="status" class="status" role="status" ?dirty=${status === 'figure.text.unsaved-changes'}>${i18next.t(status)}</span>
|
|
1702
1708
|
<span slot="status" release-state>${this.releaseWords(view)}</span>
|
|
1703
1709
|
${this.renderOverlayButton('history', 'history', 'figure.label.history', 'commit')}
|
|
1704
|
-
${
|
|
1710
|
+
${blockers.length
|
|
1705
1711
|
? html `<button slot="commit" release-blocked aria-expanded=${String(this.blockersOpen)} @click=${() => (this.blockersOpen = !this.blockersOpen)}>
|
|
1706
|
-
<md-icon>error</md-icon>${i18next.t('figure.button.release-blocked', { count:
|
|
1712
|
+
<md-icon>error</md-icon>${i18next.t('figure.button.release-blocked', { count: blockers.length })}
|
|
1707
1713
|
</button>`
|
|
1708
1714
|
: nothing}
|
|
1709
1715
|
<button slot="commit" publish ?disabled=${!view.id} title=${view.id ? '' : i18next.t('figure.text.save-the-figure-before-releasing')} @click=${this.goRelease}>${i18next.t('figure.button.release')}</button>
|
|
1710
1716
|
<button slot="commit" save ?disabled=${unavailable || (!view.dirty && !!view.id)} @click=${this.save}>${i18next.t('figure.button.save')}</button>
|
|
1711
1717
|
</ox-canvas-bar>
|
|
1712
|
-
${this.blockersOpen &&
|
|
1718
|
+
${this.blockersOpen && blockers.length ? this.renderReleaseBlockers(blockers, asset, unavailable) : nothing}
|
|
1713
1719
|
${this.catalogOpen
|
|
1714
1720
|
? html `<figure-recipe-catalog
|
|
1715
1721
|
.templates=${this.templates}
|