@things-factory/figure-library 10.1.256 → 10.1.257
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-client/item-types/ox-item-types-input.d.ts +4 -5
- package/dist-client/item-types/ox-item-types-input.js +17 -24
- package/dist-client/item-types/ox-item-types-input.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/figure-releases-popup.d.ts +13 -8
- package/dist-client/viewparts/figure-releases-popup.js +35 -60
- package/dist-client/viewparts/figure-releases-popup.js.map +1 -1
- package/package.json +9 -9
|
@@ -19,16 +19,21 @@ export declare class FigureReleasesPopup extends FigureReleasesPopup_base {
|
|
|
19
19
|
archived: boolean;
|
|
20
20
|
/** The id of the release it draws with now; '' when nothing is in use. */
|
|
21
21
|
drawing: string;
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
private releasesOf;
|
|
23
|
+
private saves;
|
|
24
|
+
/** The release each column shows, by id, once one was switched; until then the default pair. */
|
|
25
|
+
private columns?;
|
|
25
26
|
private picked;
|
|
26
|
-
|
|
27
|
-
private
|
|
27
|
+
/** The save sent last: its refusal is the one said. */
|
|
28
|
+
private sent?;
|
|
28
29
|
/** The tab both columns show: choosing one in a column turns the other to it, so both are compared on one view. */
|
|
29
30
|
private tab;
|
|
30
31
|
private assets;
|
|
31
|
-
connectedCallback():
|
|
32
|
+
connectedCallback(): void;
|
|
33
|
+
private get releases();
|
|
34
|
+
private get shown();
|
|
35
|
+
private get saving();
|
|
36
|
+
private get failure();
|
|
32
37
|
render(): import("lit-html").TemplateResult<1>;
|
|
33
38
|
private assetOf;
|
|
34
39
|
private renderColumn;
|
|
@@ -36,8 +41,8 @@ export declare class FigureReleasesPopup extends FigureReleasesPopup_base {
|
|
|
36
41
|
private show;
|
|
37
42
|
private archive;
|
|
38
43
|
private unarchive;
|
|
39
|
-
/** Archives or unarchives the name; a refusal (a board still uses it) is said at the top and the popup stays. */
|
|
40
|
-
private change;
|
|
41
44
|
private save;
|
|
45
|
+
/** Once the library took it, the catalogue is told and the popup closes. */
|
|
46
|
+
private run;
|
|
42
47
|
}
|
|
43
48
|
export {};
|
|
@@ -6,7 +6,7 @@ import '@things-factory/figure-viewer/dist-client/figure-facts-list.js';
|
|
|
6
6
|
import gql from 'graphql-tag';
|
|
7
7
|
import { css, html, LitElement, nothing } from 'lit';
|
|
8
8
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
9
|
-
import {
|
|
9
|
+
import { MutationController, QueryController } from '@operato/graphql';
|
|
10
10
|
import { i18next, localize } from '@operato/i18n';
|
|
11
11
|
import { closePopup } from '@operato/popup';
|
|
12
12
|
import { ButtonStyles, CommonPopupStyles, FormFieldStyles, ScrollbarStyles } from '@operato/styles';
|
|
@@ -92,34 +92,21 @@ let FigureReleasesPopup = class FigureReleasesPopup extends localize(i18next)(Li
|
|
|
92
92
|
this.archived = false;
|
|
93
93
|
/** The id of the release it draws with now; '' when nothing is in use. */
|
|
94
94
|
this.drawing = '';
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
/* The name's releases, newest first (ADR-0190). */
|
|
96
|
+
this.releasesOf = new QueryController(this, RELEASES_OF, { variables: () => (this.name ? { name: this.name } : undefined) });
|
|
97
|
+
/* A refusal (a board still uses it) is said at the top and the popup stays. */
|
|
98
|
+
this.saves = {
|
|
99
|
+
archive: new MutationController(this, ARCHIVE, { showsError: true }),
|
|
100
|
+
unarchive: new MutationController(this, UNARCHIVE, { showsError: true }),
|
|
101
|
+
choose: new MutationController(this, CHOOSE, { showsError: true })
|
|
102
|
+
};
|
|
98
103
|
this.picked = '';
|
|
99
|
-
this.saving = false;
|
|
100
|
-
this.failure = '';
|
|
101
104
|
/** The tab both columns show: choosing one in a column turns the other to it, so both are compared on one view. */
|
|
102
105
|
this.tab = 'info';
|
|
103
106
|
this.assets = new Map();
|
|
104
|
-
this.archive = () => this.
|
|
105
|
-
this.unarchive = () => this.
|
|
106
|
-
this.save =
|
|
107
|
-
this.saving = true;
|
|
108
|
-
try {
|
|
109
|
-
const response = await client.mutate({ mutation: CHOOSE, variables: { name: this.name, releaseId: this.picked } });
|
|
110
|
-
if (response.errors?.length)
|
|
111
|
-
throw new Error(response.errors[0].message);
|
|
112
|
-
announceLibraryChanged();
|
|
113
|
-
this.dispatchEvent(new CustomEvent('saved', { bubbles: true, composed: true }));
|
|
114
|
-
closePopup(this);
|
|
115
|
-
}
|
|
116
|
-
catch (e) {
|
|
117
|
-
this.failure = e?.message ?? '';
|
|
118
|
-
}
|
|
119
|
-
finally {
|
|
120
|
-
this.saving = false;
|
|
121
|
-
}
|
|
122
|
-
};
|
|
107
|
+
this.archive = () => this.run(this.saves.archive, { name: this.name });
|
|
108
|
+
this.unarchive = () => this.run(this.saves.unarchive, { name: this.name });
|
|
109
|
+
this.save = () => this.run(this.saves.choose, { name: this.name, releaseId: this.picked });
|
|
123
110
|
}
|
|
124
111
|
static { this.styles = [
|
|
125
112
|
CommonPopupStyles,
|
|
@@ -298,12 +285,21 @@ let FigureReleasesPopup = class FigureReleasesPopup extends localize(i18next)(Li
|
|
|
298
285
|
}
|
|
299
286
|
`
|
|
300
287
|
]; }
|
|
301
|
-
|
|
288
|
+
connectedCallback() {
|
|
302
289
|
super.connectedCallback();
|
|
303
290
|
this.picked = this.drawing;
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
this.
|
|
291
|
+
}
|
|
292
|
+
get releases() {
|
|
293
|
+
return this.releasesOf.data?.figureLibraryReleasesOf ?? [];
|
|
294
|
+
}
|
|
295
|
+
get shown() {
|
|
296
|
+
return this.columns ?? defaultPair(this.releases, this.drawing);
|
|
297
|
+
}
|
|
298
|
+
get saving() {
|
|
299
|
+
return Object.values(this.saves).some(save => save.pending);
|
|
300
|
+
}
|
|
301
|
+
get failure() {
|
|
302
|
+
return this.sent?.error?.message ?? '';
|
|
307
303
|
}
|
|
308
304
|
render() {
|
|
309
305
|
const changed = !!this.picked && this.picked !== this.drawing;
|
|
@@ -404,25 +400,16 @@ let FigureReleasesPopup = class FigureReleasesPopup extends localize(i18next)(Li
|
|
|
404
400
|
show(column, id) {
|
|
405
401
|
const next = [...this.shown];
|
|
406
402
|
next[column] = id;
|
|
407
|
-
this.
|
|
403
|
+
this.columns = next;
|
|
408
404
|
}
|
|
409
|
-
/**
|
|
410
|
-
async
|
|
411
|
-
this.
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
this.dispatchEvent(new CustomEvent('saved', { bubbles: true, composed: true }));
|
|
418
|
-
closePopup(this);
|
|
419
|
-
}
|
|
420
|
-
catch (e) {
|
|
421
|
-
this.failure = e?.message ?? '';
|
|
422
|
-
}
|
|
423
|
-
finally {
|
|
424
|
-
this.saving = false;
|
|
425
|
-
}
|
|
405
|
+
/** Once the library took it, the catalogue is told and the popup closes. */
|
|
406
|
+
async run(save, variables) {
|
|
407
|
+
this.sent = save;
|
|
408
|
+
if (!(await save.run(variables)))
|
|
409
|
+
return;
|
|
410
|
+
announceLibraryChanged();
|
|
411
|
+
this.dispatchEvent(new CustomEvent('saved', { bubbles: true, composed: true }));
|
|
412
|
+
closePopup(this);
|
|
426
413
|
}
|
|
427
414
|
};
|
|
428
415
|
__decorate([
|
|
@@ -440,23 +427,11 @@ __decorate([
|
|
|
440
427
|
__decorate([
|
|
441
428
|
state(),
|
|
442
429
|
__metadata("design:type", Array)
|
|
443
|
-
], FigureReleasesPopup.prototype, "
|
|
444
|
-
__decorate([
|
|
445
|
-
state(),
|
|
446
|
-
__metadata("design:type", Array)
|
|
447
|
-
], FigureReleasesPopup.prototype, "shown", void 0);
|
|
430
|
+
], FigureReleasesPopup.prototype, "columns", void 0);
|
|
448
431
|
__decorate([
|
|
449
432
|
state(),
|
|
450
433
|
__metadata("design:type", Object)
|
|
451
434
|
], FigureReleasesPopup.prototype, "picked", void 0);
|
|
452
|
-
__decorate([
|
|
453
|
-
state(),
|
|
454
|
-
__metadata("design:type", Object)
|
|
455
|
-
], FigureReleasesPopup.prototype, "saving", void 0);
|
|
456
|
-
__decorate([
|
|
457
|
-
state(),
|
|
458
|
-
__metadata("design:type", Object)
|
|
459
|
-
], FigureReleasesPopup.prototype, "failure", void 0);
|
|
460
435
|
__decorate([
|
|
461
436
|
state(),
|
|
462
437
|
__metadata("design:type", Object)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figure-releases-popup.js","sourceRoot":"","sources":["../../client/viewparts/figure-releases-popup.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/button/text-button.js'\nimport '@operato/popup/ox-popup-actions.js'\nimport '@things-factory/figure-viewer/dist-client/figure-asset-viewer.js'\nimport '@things-factory/figure-viewer/dist-client/figure-facts-list.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport type { FigureAsset } from '@hatiolab/figure-model'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { ButtonStyles, CommonPopupStyles, FormFieldStyles, ScrollbarStyles } from '@operato/styles'\n\nimport { announceLibraryChanged } from '../figure-library-changed.js'\nimport { versionText } from './figure-version.js'\nimport { defaultPair, SIDE_BY_SIDE } from './release-pair.js'\n\nconst RELEASES_OF = gql`\n query ($name: String!) {\n figureLibraryReleasesOf(name: $name) {\n id\n name\n ref\n version\n category\n source\n formatSupported\n assetFormat\n kernelVersion\n changes\n deprecated\n supersededBy\n comment\n sourceUrl\n releasedAt\n createdAt\n }\n }\n`\n\n/* Archiving is how a figure leaves the library; its releases stay (ADR-0114 결정 18 · 20). */\nconst ARCHIVE = gql`\n mutation ($name: String!) {\n archiveFigure(name: $name) {\n name\n }\n }\n`\n\nconst UNARCHIVE = gql`\n mutation ($name: String!) {\n unarchiveFigure(name: $name) {\n name\n }\n }\n`\n\nconst CHOOSE = gql`\n mutation ($name: String!, $releaseId: String!) {\n chooseFigureRelease(name: $name, releaseId: $releaseId) {\n name\n }\n }\n`\n\ntype Change = { code?: string; values?: Record<string, unknown>; detail?: string; blocking?: boolean }\n\n/** A time in the reader's language (a bare toLocaleString follows the browser, not the app). */\nconst when = (value?: string | null) => (value ? new Date(value).toLocaleString(i18next.language) : '')\n\n/**\n * A contract change in words. figure-model gives a code and values; `detail` is English for logs and is\n * the sentence only when this module has no words for a new code (open question P8 in figure-library.md).\n */\nconst changeText = (change: Change) =>\n change.code\n ? i18next.t(`figure-library.contract.${change.code}`, { ...(change.values ?? {}), defaultValue: change.detail ?? change.code })\n : change.detail ?? ''\n\n/** The contract changes a release carries against its previous release, as the authoring server measured them. */\nconst changesOf = (release: any): Change[] => {\n try {\n const parsed = release.changes ? JSON.parse(release.changes) : []\n return Array.isArray(parsed) ? parsed : []\n } catch {\n return []\n }\n}\n\n/**\n * Two releases of one figure on live canvases, side by side (ADR-0114, amended 2026-10-12): each drawn as a board draws\n * it, sized within its ranges, posed and played, with what it is and its places beside it -- operato-figure's preview\n * (@things-factory/figure-viewer), not a second one. With more releases, each column picks the release it shows; the\n * one in use and the latest stand first. The operator picks the release the figure draws with and saves; save stays\n * off until the pick differs. A release this server cannot read shows why instead of a canvas and cannot be picked.\n */\n@customElement('figure-releases-popup')\nexport class FigureReleasesPopup extends localize(i18next)(LitElement) {\n static styles = [\n CommonPopupStyles,\n ScrollbarStyles,\n ButtonStyles,\n FormFieldStyles,\n css`\n /*\n The popup takes the overlay's width (a share of the window, all of it on a narrow one) and never more: the two\n columns sit side by side when they have room and stack when they do not, and the actions stay in view.\n */\n :host {\n min-height: 0;\n width: 100%;\n --popup-min-width: 0;\n }\n\n /*\n Each column is as tall as the body, so its canvas stays in view while only its tab's body scrolls (user\n 2026-10-15: a clip played at the bottom of a scrolled column moved a figure no longer seen). Stacked, the body\n scrolls from one column to the next.\n */\n .body {\n flex: 1;\n overflow: auto;\n container-type: size;\n }\n\n .columns {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));\n gap: var(--spacing-large, 12px);\n align-items: start;\n }\n\n section.column {\n display: flex;\n flex-direction: column;\n min-width: 0;\n height: 100cqh;\n box-sizing: border-box;\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: var(--ui-r, 10px);\n background: var(--ui-panel, var(--md-sys-color-surface-container-lowest));\n }\n\n section.column > * {\n flex: none;\n }\n\n /*\n The canvas and what a release is share the column: the canvas takes at most half of it, so its facts, size and\n motion always have the other half however wide the column is (user 2026-10-22: a 4:3 canvas across a wide\n column left the facts below the fold, or out of sight).\n */\n section.column > figure-asset-viewer {\n flex: 1;\n min-height: 0;\n --figure-asset-viewer-canvas-max: 50%;\n }\n\n section.column[picked] {\n border-color: var(--ui-accent, var(--md-sys-color-primary));\n box-shadow: inset 0 0 0 1px var(--ui-accent, var(--md-sys-color-primary));\n }\n\n /*\n Side by side, which release a column is stays in view while its facts scroll by. Stacked, each column's canvas\n stands right under its own header and the header leaves with its column (below two columns' width).\n */\n .head {\n position: sticky;\n top: 0;\n z-index: 1;\n border-radius: var(--ui-r, 10px) var(--ui-r, 10px) 0 0;\n background: var(--ui-panel, var(--md-sys-color-surface-container-lowest));\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n padding: var(--spacing-medium, 8px) 16px;\n border-bottom: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n }\n\n @container (max-width: 771px) {\n .head {\n position: static;\n }\n }\n\n .head label {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-small, 4px);\n font-weight: 600;\n }\n\n .head select {\n height: var(--form-element-height-small, 26px);\n min-width: 72px;\n font-size: var(--ui-t-body, 13px);\n }\n\n .head strong {\n font-size: var(--ui-t-title, 15px);\n }\n\n .marks {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-small, 4px);\n }\n\n .mark {\n padding: 0 var(--spacing-medium, 8px);\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: 999px;\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n font-size: var(--ui-t-small, 11.5px);\n white-space: nowrap;\n }\n\n .mark.on {\n border-color: var(--ui-accent, var(--md-sys-color-primary));\n color: var(--ui-accent, var(--md-sys-color-primary));\n font-weight: 600;\n }\n\n .mark.crit {\n color: var(--ui-crit, var(--md-sys-color-error));\n }\n\n .reason {\n margin: 0;\n padding: var(--spacing-huge, 24px) 16px;\n color: var(--ui-crit, var(--md-sys-color-error));\n }\n\n /* The release's own facts (note, dates, source, format, contract change) under the figure's. */\n dl.release {\n display: grid;\n grid-template-columns: 96px minmax(0, 1fr);\n gap: 3px 12px;\n margin: 0;\n padding: 10px 16px;\n line-height: 1.45;\n }\n\n dl.release dt {\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n\n dl.release dd {\n margin: 0;\n overflow-wrap: anywhere;\n }\n\n dl.release dd small {\n display: block;\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n\n ul {\n margin: 0;\n padding-left: 1.2em;\n }\n\n li.breaking {\n color: var(--ui-crit, var(--md-sys-color-error));\n }\n\n .finding {\n margin: 0 0 var(--spacing-large, 12px);\n padding-left: var(--spacing-large, 12px);\n border-left: 2px solid var(--ui-crit, var(--md-sys-color-error));\n }\n `\n ]\n\n /** The full figure name. */\n @property() name = ''\n /** Whether the name is archived: the action row offers to unarchive it instead of archiving it. */\n @property({ type: Boolean }) archived = false\n /** The id of the release it draws with now; '' when nothing is in use. */\n @property() drawing = ''\n\n @state() private releases: any[] = []\n /** The release each column shows, by id. */\n @state() private shown: string[] = []\n @state() private picked = ''\n @state() private saving = false\n @state() private failure = ''\n /** The tab both columns show: choosing one in a column turns the other to it, so both are compared on one view. */\n @state() private tab = 'info'\n\n private assets = new Map<string, FigureAsset | null>()\n\n async connectedCallback() {\n super.connectedCallback()\n this.picked = this.drawing\n const response = await client.query({ query: RELEASES_OF, variables: { name: this.name }, fetchPolicy: 'network-only' })\n this.releases = response.data?.figureLibraryReleasesOf ?? []\n this.shown = defaultPair(this.releases, this.drawing)\n }\n\n render() {\n const changed = !!this.picked && this.picked !== this.drawing\n const byId = new Map(this.releases.map(release => [release.id, release]))\n\n return html`\n <div class=\"body\">\n ${this.failure ? html`<p class=\"finding\" role=\"alert\">${this.failure}</p>` : nothing}\n <div class=\"columns\">\n ${this.shown.map((id, column) => (byId.get(id) ? this.renderColumn(byId.get(id), column) : nothing))}\n </div>\n </div>\n <ox-popup-actions>\n <md-text-button slot=\"start\" ?disabled=${this.saving} @click=${this.archived ? this.unarchive : this.archive}>\n ${i18next.t(this.archived ? 'figure-library.button.unarchive' : 'figure-library.button.archive')}\n </md-text-button>\n <button slot=\"cancel\" @click=${() => closePopup(this)}>${i18next.t('figure-library.button.cancel')}</button>\n <button slot=\"confirm\" raised ?disabled=${!changed || this.saving} @click=${this.save}>${i18next.t('figure-library.button.save')}</button>\n </ox-popup-actions>\n `\n }\n\n private assetOf(release: any): FigureAsset | null {\n if (!this.assets.has(release.id)) {\n let asset: FigureAsset | null = null\n try {\n asset = release.formatSupported ? (JSON.parse(release.source) as FigureAsset) : null\n } catch {\n asset = null\n }\n this.assets.set(release.id, asset)\n }\n return this.assets.get(release.id)!\n }\n\n private renderColumn(release: any, column: number) {\n const picked = release.id === this.picked\n /* A release this server cannot read is never used: it is shown, not picked (ADR-0114, amended 2026-10-12). */\n const asset = this.assetOf(release)\n const unusable = !asset\n const latest = release.id === this.releases[0]?.id\n const choosable = this.releases.length > SIDE_BY_SIDE\n\n return html`\n <section class=\"column\" ?picked=${picked}>\n <div class=\"head\">\n <label>\n <input type=\"radio\" name=\"release\" .checked=${picked} ?disabled=${unusable} @change=${() => (this.picked = release.id)} />\n ${choosable\n ? html`<select aria-label=${i18next.t('figure-library.label.release-shown')} @change=${(e: Event) => this.show(column, (e.target as HTMLSelectElement).value)}>\n ${this.releases.map(\n other => html`<option value=${other.id} ?selected=${other.id === release.id}>${versionText(other.version)}</option>`\n )}\n </select>`\n : html`<strong>${versionText(release.version)}</strong>`}\n </label>\n <span class=\"marks\">\n ${release.id === this.drawing ? html`<span class=\"mark on\">${i18next.t('figure-library.text.in-use')}</span>` : nothing}\n ${latest ? html`<span class=\"mark\">${i18next.t('figure-library.text.latest')}</span>` : nothing}\n ${unusable ? html`<span class=\"mark crit\">${i18next.t('figure-library.text.format-unsupported')}</span>` : nothing}\n ${release.deprecated ? html`<span class=\"mark\">${i18next.t('figure-library.text.deprecated')}</span>` : nothing}\n </span>\n </div>\n ${asset\n ? html`<figure-asset-viewer .asset=${asset} .tab=${this.tab} @tab-change=${(e: CustomEvent<{ tab: string }>) => (this.tab = e.detail.tab)}>\n <figure-facts-list slot=\"facts\" .asset=${asset} .row=${{ category: release.category }}></figure-facts-list>\n ${this.renderReleaseFacts(release, 'facts')}\n </figure-asset-viewer>`\n : html`<p class=\"reason\" role=\"note\">${i18next.t('figure-library.text.cannot-use-format', { format: release.assetFormat })}</p>\n ${this.renderReleaseFacts(release)}`}\n </section>\n `\n }\n\n private renderReleaseFacts(release: any, slot?: string) {\n const changes = changesOf(release)\n\n return html`<dl class=\"release\" slot=${slot ?? nothing}>\n ${release.comment ? html`<dt>${i18next.t('figure-library.label.release-note')}</dt><dd>${release.comment}</dd>` : nothing}\n ${release.version > 1\n ? html`<dt>${i18next.t('figure-library.text.contract-since', { version: versionText(release.version - 1) })}</dt>\n <dd>\n ${changes.length\n ? html`<ul>\n ${changes.map(\n change => html`<li class=${change.blocking ? 'breaking' : ''}>\n ${changeText(change)}${change.blocking ? html` · ${i18next.t('figure-library.text.breaking')}` : nothing}\n </li>`\n )}\n </ul>`\n : i18next.t('figure-library.text.no-contract-change')}\n </dd>`\n : nothing}\n <dt>${i18next.t('figure-library.label.format')}</dt>\n <dd>\n ${release.assetFormat}\n ${release.kernelVersion ? html`<small>${i18next.t('figure-library.text.kernel', { version: release.kernelVersion })}</small>` : nothing}\n </dd>\n <dt>${i18next.t('figure-library.label.released-at')}</dt>\n <dd>${when(release.releasedAt)}</dd>\n <dt>${i18next.t('figure-library.label.imported-at')}</dt>\n <dd>${when(release.createdAt)}</dd>\n <dt>${i18next.t('figure-library.label.source')}</dt>\n <dd>${release.sourceUrl ?? ''}</dd>\n </dl>`\n }\n\n private show(column: number, id: string) {\n const next = [...this.shown]\n next[column] = id\n this.shown = next\n }\n\n private archive = () => this.change(ARCHIVE)\n\n private unarchive = () => this.change(UNARCHIVE)\n\n /** Archives or unarchives the name; a refusal (a board still uses it) is said at the top and the popup stays. */\n private async change(mutation: typeof ARCHIVE) {\n this.saving = true\n try {\n const response = await client.mutate({ mutation, variables: { name: this.name } })\n if (response.errors?.length) throw new Error(response.errors[0].message)\n announceLibraryChanged()\n this.dispatchEvent(new CustomEvent('saved', { bubbles: true, composed: true }))\n closePopup(this)\n } catch (e: any) {\n this.failure = e?.message ?? ''\n } finally {\n this.saving = false\n }\n }\n\n private save = async () => {\n this.saving = true\n try {\n const response = await client.mutate({ mutation: CHOOSE, variables: { name: this.name, releaseId: this.picked } })\n if (response.errors?.length) throw new Error(response.errors[0].message)\n announceLibraryChanged()\n this.dispatchEvent(new CustomEvent('saved', { bubbles: true, composed: true }))\n closePopup(this)\n } catch (e: any) {\n this.failure = e?.message ?? ''\n } finally {\n this.saving = false\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"figure-releases-popup.js","sourceRoot":"","sources":["../../client/viewparts/figure-releases-popup.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/button/text-button.js'\nimport '@operato/popup/ox-popup-actions.js'\nimport '@things-factory/figure-viewer/dist-client/figure-asset-viewer.js'\nimport '@things-factory/figure-viewer/dist-client/figure-facts-list.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport type { FigureAsset } from '@hatiolab/figure-model'\nimport { MutationController, QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { ButtonStyles, CommonPopupStyles, FormFieldStyles, ScrollbarStyles } from '@operato/styles'\n\nimport { announceLibraryChanged } from '../figure-library-changed.js'\nimport { versionText } from './figure-version.js'\nimport { defaultPair, SIDE_BY_SIDE } from './release-pair.js'\n\nconst RELEASES_OF = gql`\n query ($name: String!) {\n figureLibraryReleasesOf(name: $name) {\n id\n name\n ref\n version\n category\n source\n formatSupported\n assetFormat\n kernelVersion\n changes\n deprecated\n supersededBy\n comment\n sourceUrl\n releasedAt\n createdAt\n }\n }\n`\n\n/* Archiving is how a figure leaves the library; its releases stay (ADR-0114 결정 18 · 20). */\nconst ARCHIVE = gql`\n mutation ($name: String!) {\n archiveFigure(name: $name) {\n name\n }\n }\n`\n\nconst UNARCHIVE = gql`\n mutation ($name: String!) {\n unarchiveFigure(name: $name) {\n name\n }\n }\n`\n\nconst CHOOSE = gql`\n mutation ($name: String!, $releaseId: String!) {\n chooseFigureRelease(name: $name, releaseId: $releaseId) {\n name\n }\n }\n`\n\ntype Change = { code?: string; values?: Record<string, unknown>; detail?: string; blocking?: boolean }\n\n/** A time in the reader's language (a bare toLocaleString follows the browser, not the app). */\nconst when = (value?: string | null) => (value ? new Date(value).toLocaleString(i18next.language) : '')\n\n/**\n * A contract change in words. figure-model gives a code and values; `detail` is English for logs and is\n * the sentence only when this module has no words for a new code (open question P8 in figure-library.md).\n */\nconst changeText = (change: Change) =>\n change.code\n ? i18next.t(`figure-library.contract.${change.code}`, { ...(change.values ?? {}), defaultValue: change.detail ?? change.code })\n : change.detail ?? ''\n\n/** The contract changes a release carries against its previous release, as the authoring server measured them. */\nconst changesOf = (release: any): Change[] => {\n try {\n const parsed = release.changes ? JSON.parse(release.changes) : []\n return Array.isArray(parsed) ? parsed : []\n } catch {\n return []\n }\n}\n\n/**\n * Two releases of one figure on live canvases, side by side (ADR-0114, amended 2026-10-12): each drawn as a board draws\n * it, sized within its ranges, posed and played, with what it is and its places beside it -- operato-figure's preview\n * (@things-factory/figure-viewer), not a second one. With more releases, each column picks the release it shows; the\n * one in use and the latest stand first. The operator picks the release the figure draws with and saves; save stays\n * off until the pick differs. A release this server cannot read shows why instead of a canvas and cannot be picked.\n */\n@customElement('figure-releases-popup')\nexport class FigureReleasesPopup extends localize(i18next)(LitElement) {\n static styles = [\n CommonPopupStyles,\n ScrollbarStyles,\n ButtonStyles,\n FormFieldStyles,\n css`\n /*\n The popup takes the overlay's width (a share of the window, all of it on a narrow one) and never more: the two\n columns sit side by side when they have room and stack when they do not, and the actions stay in view.\n */\n :host {\n min-height: 0;\n width: 100%;\n --popup-min-width: 0;\n }\n\n /*\n Each column is as tall as the body, so its canvas stays in view while only its tab's body scrolls (user\n 2026-10-15: a clip played at the bottom of a scrolled column moved a figure no longer seen). Stacked, the body\n scrolls from one column to the next.\n */\n .body {\n flex: 1;\n overflow: auto;\n container-type: size;\n }\n\n .columns {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));\n gap: var(--spacing-large, 12px);\n align-items: start;\n }\n\n section.column {\n display: flex;\n flex-direction: column;\n min-width: 0;\n height: 100cqh;\n box-sizing: border-box;\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: var(--ui-r, 10px);\n background: var(--ui-panel, var(--md-sys-color-surface-container-lowest));\n }\n\n section.column > * {\n flex: none;\n }\n\n /*\n The canvas and what a release is share the column: the canvas takes at most half of it, so its facts, size and\n motion always have the other half however wide the column is (user 2026-10-22: a 4:3 canvas across a wide\n column left the facts below the fold, or out of sight).\n */\n section.column > figure-asset-viewer {\n flex: 1;\n min-height: 0;\n --figure-asset-viewer-canvas-max: 50%;\n }\n\n section.column[picked] {\n border-color: var(--ui-accent, var(--md-sys-color-primary));\n box-shadow: inset 0 0 0 1px var(--ui-accent, var(--md-sys-color-primary));\n }\n\n /*\n Side by side, which release a column is stays in view while its facts scroll by. Stacked, each column's canvas\n stands right under its own header and the header leaves with its column (below two columns' width).\n */\n .head {\n position: sticky;\n top: 0;\n z-index: 1;\n border-radius: var(--ui-r, 10px) var(--ui-r, 10px) 0 0;\n background: var(--ui-panel, var(--md-sys-color-surface-container-lowest));\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n padding: var(--spacing-medium, 8px) 16px;\n border-bottom: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n }\n\n @container (max-width: 771px) {\n .head {\n position: static;\n }\n }\n\n .head label {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-small, 4px);\n font-weight: 600;\n }\n\n .head select {\n height: var(--form-element-height-small, 26px);\n min-width: 72px;\n font-size: var(--ui-t-body, 13px);\n }\n\n .head strong {\n font-size: var(--ui-t-title, 15px);\n }\n\n .marks {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-small, 4px);\n }\n\n .mark {\n padding: 0 var(--spacing-medium, 8px);\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: 999px;\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n font-size: var(--ui-t-small, 11.5px);\n white-space: nowrap;\n }\n\n .mark.on {\n border-color: var(--ui-accent, var(--md-sys-color-primary));\n color: var(--ui-accent, var(--md-sys-color-primary));\n font-weight: 600;\n }\n\n .mark.crit {\n color: var(--ui-crit, var(--md-sys-color-error));\n }\n\n .reason {\n margin: 0;\n padding: var(--spacing-huge, 24px) 16px;\n color: var(--ui-crit, var(--md-sys-color-error));\n }\n\n /* The release's own facts (note, dates, source, format, contract change) under the figure's. */\n dl.release {\n display: grid;\n grid-template-columns: 96px minmax(0, 1fr);\n gap: 3px 12px;\n margin: 0;\n padding: 10px 16px;\n line-height: 1.45;\n }\n\n dl.release dt {\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n\n dl.release dd {\n margin: 0;\n overflow-wrap: anywhere;\n }\n\n dl.release dd small {\n display: block;\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n\n ul {\n margin: 0;\n padding-left: 1.2em;\n }\n\n li.breaking {\n color: var(--ui-crit, var(--md-sys-color-error));\n }\n\n .finding {\n margin: 0 0 var(--spacing-large, 12px);\n padding-left: var(--spacing-large, 12px);\n border-left: 2px solid var(--ui-crit, var(--md-sys-color-error));\n }\n `\n ]\n\n /** The full figure name. */\n @property() name = ''\n /** Whether the name is archived: the action row offers to unarchive it instead of archiving it. */\n @property({ type: Boolean }) archived = false\n /** The id of the release it draws with now; '' when nothing is in use. */\n @property() drawing = ''\n\n /* The name's releases, newest first (ADR-0190). */\n private releasesOf = new QueryController(this, RELEASES_OF, { variables: () => (this.name ? { name: this.name } : undefined) })\n /* A refusal (a board still uses it) is said at the top and the popup stays. */\n private saves = {\n archive: new MutationController(this, ARCHIVE, { showsError: true }),\n unarchive: new MutationController(this, UNARCHIVE, { showsError: true }),\n choose: new MutationController(this, CHOOSE, { showsError: true })\n }\n /** The release each column shows, by id, once one was switched; until then the default pair. */\n @state() private columns?: string[]\n @state() private picked = ''\n /** The save sent last: its refusal is the one said. */\n private sent?: MutationController\n /** The tab both columns show: choosing one in a column turns the other to it, so both are compared on one view. */\n @state() private tab = 'info'\n\n private assets = new Map<string, FigureAsset | null>()\n\n connectedCallback() {\n super.connectedCallback()\n this.picked = this.drawing\n }\n\n private get releases(): any[] {\n return this.releasesOf.data?.figureLibraryReleasesOf ?? []\n }\n\n private get shown(): string[] {\n return this.columns ?? defaultPair(this.releases, this.drawing)\n }\n\n private get saving() {\n return Object.values(this.saves).some(save => save.pending)\n }\n\n private get failure(): string {\n return (this.sent?.error as Error | undefined)?.message ?? ''\n }\n\n render() {\n const changed = !!this.picked && this.picked !== this.drawing\n const byId = new Map(this.releases.map(release => [release.id, release]))\n\n return html`\n <div class=\"body\">\n ${this.failure ? html`<p class=\"finding\" role=\"alert\">${this.failure}</p>` : nothing}\n <div class=\"columns\">\n ${this.shown.map((id, column) => (byId.get(id) ? this.renderColumn(byId.get(id), column) : nothing))}\n </div>\n </div>\n <ox-popup-actions>\n <md-text-button slot=\"start\" ?disabled=${this.saving} @click=${this.archived ? this.unarchive : this.archive}>\n ${i18next.t(this.archived ? 'figure-library.button.unarchive' : 'figure-library.button.archive')}\n </md-text-button>\n <button slot=\"cancel\" @click=${() => closePopup(this)}>${i18next.t('figure-library.button.cancel')}</button>\n <button slot=\"confirm\" raised ?disabled=${!changed || this.saving} @click=${this.save}>${i18next.t('figure-library.button.save')}</button>\n </ox-popup-actions>\n `\n }\n\n private assetOf(release: any): FigureAsset | null {\n if (!this.assets.has(release.id)) {\n let asset: FigureAsset | null = null\n try {\n asset = release.formatSupported ? (JSON.parse(release.source) as FigureAsset) : null\n } catch {\n asset = null\n }\n this.assets.set(release.id, asset)\n }\n return this.assets.get(release.id)!\n }\n\n private renderColumn(release: any, column: number) {\n const picked = release.id === this.picked\n /* A release this server cannot read is never used: it is shown, not picked (ADR-0114, amended 2026-10-12). */\n const asset = this.assetOf(release)\n const unusable = !asset\n const latest = release.id === this.releases[0]?.id\n const choosable = this.releases.length > SIDE_BY_SIDE\n\n return html`\n <section class=\"column\" ?picked=${picked}>\n <div class=\"head\">\n <label>\n <input type=\"radio\" name=\"release\" .checked=${picked} ?disabled=${unusable} @change=${() => (this.picked = release.id)} />\n ${choosable\n ? html`<select aria-label=${i18next.t('figure-library.label.release-shown')} @change=${(e: Event) => this.show(column, (e.target as HTMLSelectElement).value)}>\n ${this.releases.map(\n other => html`<option value=${other.id} ?selected=${other.id === release.id}>${versionText(other.version)}</option>`\n )}\n </select>`\n : html`<strong>${versionText(release.version)}</strong>`}\n </label>\n <span class=\"marks\">\n ${release.id === this.drawing ? html`<span class=\"mark on\">${i18next.t('figure-library.text.in-use')}</span>` : nothing}\n ${latest ? html`<span class=\"mark\">${i18next.t('figure-library.text.latest')}</span>` : nothing}\n ${unusable ? html`<span class=\"mark crit\">${i18next.t('figure-library.text.format-unsupported')}</span>` : nothing}\n ${release.deprecated ? html`<span class=\"mark\">${i18next.t('figure-library.text.deprecated')}</span>` : nothing}\n </span>\n </div>\n ${asset\n ? html`<figure-asset-viewer .asset=${asset} .tab=${this.tab} @tab-change=${(e: CustomEvent<{ tab: string }>) => (this.tab = e.detail.tab)}>\n <figure-facts-list slot=\"facts\" .asset=${asset} .row=${{ category: release.category }}></figure-facts-list>\n ${this.renderReleaseFacts(release, 'facts')}\n </figure-asset-viewer>`\n : html`<p class=\"reason\" role=\"note\">${i18next.t('figure-library.text.cannot-use-format', { format: release.assetFormat })}</p>\n ${this.renderReleaseFacts(release)}`}\n </section>\n `\n }\n\n private renderReleaseFacts(release: any, slot?: string) {\n const changes = changesOf(release)\n\n return html`<dl class=\"release\" slot=${slot ?? nothing}>\n ${release.comment ? html`<dt>${i18next.t('figure-library.label.release-note')}</dt><dd>${release.comment}</dd>` : nothing}\n ${release.version > 1\n ? html`<dt>${i18next.t('figure-library.text.contract-since', { version: versionText(release.version - 1) })}</dt>\n <dd>\n ${changes.length\n ? html`<ul>\n ${changes.map(\n change => html`<li class=${change.blocking ? 'breaking' : ''}>\n ${changeText(change)}${change.blocking ? html` · ${i18next.t('figure-library.text.breaking')}` : nothing}\n </li>`\n )}\n </ul>`\n : i18next.t('figure-library.text.no-contract-change')}\n </dd>`\n : nothing}\n <dt>${i18next.t('figure-library.label.format')}</dt>\n <dd>\n ${release.assetFormat}\n ${release.kernelVersion ? html`<small>${i18next.t('figure-library.text.kernel', { version: release.kernelVersion })}</small>` : nothing}\n </dd>\n <dt>${i18next.t('figure-library.label.released-at')}</dt>\n <dd>${when(release.releasedAt)}</dd>\n <dt>${i18next.t('figure-library.label.imported-at')}</dt>\n <dd>${when(release.createdAt)}</dd>\n <dt>${i18next.t('figure-library.label.source')}</dt>\n <dd>${release.sourceUrl ?? ''}</dd>\n </dl>`\n }\n\n private show(column: number, id: string) {\n const next = [...this.shown]\n next[column] = id\n this.columns = next\n }\n\n private archive = () => this.run(this.saves.archive, { name: this.name })\n\n private unarchive = () => this.run(this.saves.unarchive, { name: this.name })\n\n private save = () => this.run(this.saves.choose, { name: this.name, releaseId: this.picked })\n\n /** Once the library took it, the catalogue is told and the popup closes. */\n private async run(save: MutationController, variables: Record<string, string>) {\n this.sent = save\n if (!(await save.run(variables))) return\n announceLibraryChanged()\n this.dispatchEvent(new CustomEvent('saved', { bubbles: true, composed: true }))\n closePopup(this)\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/figure-library",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.257",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "dist-client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -30,19 +30,19 @@
|
|
|
30
30
|
"@hatiolab/figure-model": "^0.12.3",
|
|
31
31
|
"@hatiolab/things-scene": "^10.1.110",
|
|
32
32
|
"@material/web": "^2.0.0",
|
|
33
|
-
"@operato/data-grist": "^10.
|
|
34
|
-
"@operato/graphql": "^10.29.
|
|
33
|
+
"@operato/data-grist": "^10.29.69",
|
|
34
|
+
"@operato/graphql": "^10.29.69",
|
|
35
35
|
"@operato/i18n": "^10.0.0",
|
|
36
36
|
"@operato/input": "^10.29.37",
|
|
37
37
|
"@operato/popup": "^10.29.25",
|
|
38
|
-
"@operato/property-editor": "^10.29.
|
|
39
|
-
"@operato/shell": "^10.
|
|
38
|
+
"@operato/property-editor": "^10.29.69",
|
|
39
|
+
"@operato/shell": "^10.29.69",
|
|
40
40
|
"@operato/slot-layout-editor": "^10.29.58",
|
|
41
41
|
"@operato/styles": "^10.29.23",
|
|
42
42
|
"@operato/utils": "^10.0.0",
|
|
43
|
-
"@things-factory/attachment-base": "^10.1.
|
|
44
|
-
"@things-factory/auth-base": "^10.1.
|
|
45
|
-
"@things-factory/board-service": "^10.1.
|
|
43
|
+
"@things-factory/attachment-base": "^10.1.257",
|
|
44
|
+
"@things-factory/auth-base": "^10.1.257",
|
|
45
|
+
"@things-factory/board-service": "^10.1.257",
|
|
46
46
|
"@things-factory/env": "^10.1.149",
|
|
47
47
|
"@things-factory/figure-viewer": "^10.1.253",
|
|
48
48
|
"@things-factory/shell": "^10.1.254",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"koa-router": "^7.4.0",
|
|
54
54
|
"lit": "^3.1.2"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "885b594299601ca4936f4f39701d6713273bbf1e"
|
|
57
57
|
}
|