@things-factory/figure-library 10.1.156 → 10.1.157
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.
|
@@ -15,14 +15,6 @@ export declare class FigureLibraryPage extends FigureLibraryPage_base {
|
|
|
15
15
|
handler: (search: string) => void;
|
|
16
16
|
value: string;
|
|
17
17
|
};
|
|
18
|
-
actions: {
|
|
19
|
-
title: string;
|
|
20
|
-
icon: string;
|
|
21
|
-
action: () => void;
|
|
22
|
-
emphasis: {
|
|
23
|
-
raised: boolean;
|
|
24
|
-
};
|
|
25
|
-
}[];
|
|
26
18
|
};
|
|
27
19
|
render(): import("lit-html").TemplateResult<1>;
|
|
28
20
|
pageInitialized(): Promise<void>;
|
|
@@ -11,7 +11,7 @@ import { client } from '@operato/graphql';
|
|
|
11
11
|
import { i18next, localize } from '@operato/i18n';
|
|
12
12
|
import { openPopup } from '@operato/popup';
|
|
13
13
|
import { PageView } from '@operato/shell';
|
|
14
|
-
import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
|
|
14
|
+
import { CommonGristStyles, CommonHeaderStyles, FabStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
|
|
15
15
|
import { getPathInfo } from '@operato/utils';
|
|
16
16
|
/*
|
|
17
17
|
* The board server's figures (ADR-0114, amended 2026-10-12), as a card catalogue: one card per imported figure, its
|
|
@@ -124,6 +124,7 @@ let FigureLibraryPage = class FigureLibraryPage extends localize(i18next)(PageVi
|
|
|
124
124
|
ScrollbarStyles,
|
|
125
125
|
CommonGristStyles,
|
|
126
126
|
CommonHeaderStyles,
|
|
127
|
+
FabStyles,
|
|
127
128
|
css `
|
|
128
129
|
ox-filters-form {
|
|
129
130
|
flex: 1;
|
|
@@ -147,15 +148,7 @@ let FigureLibraryPage = class FigureLibraryPage extends localize(i18next)(PageVi
|
|
|
147
148
|
this.grist.searchText = search;
|
|
148
149
|
},
|
|
149
150
|
value: this.grist?.searchText || ''
|
|
150
|
-
}
|
|
151
|
-
actions: [
|
|
152
|
-
{
|
|
153
|
-
title: i18next.t('figure-library.button.upload'),
|
|
154
|
-
icon: 'upload_file',
|
|
155
|
-
action: () => this.chooseFile(),
|
|
156
|
-
emphasis: { raised: true }
|
|
157
|
-
}
|
|
158
|
-
]
|
|
151
|
+
}
|
|
159
152
|
};
|
|
160
153
|
}
|
|
161
154
|
render() {
|
|
@@ -166,6 +159,10 @@ let FigureLibraryPage = class FigureLibraryPage extends localize(i18next)(PageVi
|
|
|
166
159
|
<ox-filters-form autofocus without-search></ox-filters-form>
|
|
167
160
|
</div>
|
|
168
161
|
</ox-grist>
|
|
162
|
+
|
|
163
|
+
<button fab @click=${() => this.chooseFile()}>
|
|
164
|
+
<md-icon>upload_file</md-icon>${i18next.t('figure-library.button.upload')}
|
|
165
|
+
</button>
|
|
169
166
|
`;
|
|
170
167
|
}
|
|
171
168
|
async pageInitialized() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figure-library-page.js","sourceRoot":"","sources":["../../client/pages/figure-library-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '../viewparts/figure-card-meta.js'\nimport '@things-factory/figure-viewer/dist-client/figure-thumb-mark.js'\nimport '../viewparts/figure-releases-popup.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/popup'\nimport { PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { getPathInfo } from '@operato/utils'\n\n/*\n * The board server's figures (ADR-0114, amended 2026-10-12), as a card catalogue: one card per imported figure, its\n * thumbnail first, the release it draws with and the latest imported. A card whose figure does not draw with its latest\n * says so. Clicking a card opens its releases side by side to compare them and choose the one it draws with.\n *\n * The library is expected to grow to many figures, so the list pages from the server and the filters (category,\n * capability) are drop-down lists in the filter bar beside the name search. Upload, the decision of the screen, sits in\n * the shell's action bar; what it did opens in a popup.\n */\n\nconst FIGURES = gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: figureLibraryFigures(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n name\n latestVersion\n releaseCount\n release {\n id\n name\n version\n category\n capabilities\n formatSupported\n deprecated\n dependencies\n }\n latest {\n id\n name\n version\n formatSupported\n dependencies\n }\n }\n total\n }\n }\n`\n\nconst FACETS = gql`\n query {\n figureLibraryFacets {\n categories\n uncategorized\n capabilities\n incapable\n }\n }\n`\n\nconst IMPORT = gql`\n mutation ($file: Upload!) {\n importFigurePackage(file: $file) {\n problems {\n code\n path\n }\n outcomes {\n ref\n outcome\n code\n differs\n }\n }\n }\n`\n\n/** The filter value for a figure with no category, or one that declares no capability. */\nconst NONE = '-'\n\ntype ImportResult = { problems: { code: string; path?: string }[]; outcomes: { ref: string; outcome: string; code?: string; differs?: string[] }[] }\n\n@customElement('figure-library-page')\nexport class FigureLibraryPage extends localize(i18next)(PageView) {\n static styles = [\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n css`\n ox-filters-form {\n flex: 1;\n }\n\n ox-grist {\n /* Cards of a row stand at one height; a card with an extra fact row does not stick out below the others. */\n --data-card-record-card-height: auto;\n --data-card-thumbnail-aspect: 4 / 3;\n --data-card-thumbnail-background: var(--md-sys-color-surface-container-lowest);\n }\n\n `\n ]\n\n @state() private gristConfig: any\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('figure-library.title'),\n search: {\n placeholder: i18next.t('figure-library.text.search'),\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n actions: [\n {\n title: i18next.t('figure-library.button.upload'),\n icon: 'upload_file',\n action: () => this.chooseFile(),\n emphasis: { raised: true }\n }\n ]\n }\n }\n\n render() {\n return html`\n <input id=\"file\" type=\"file\" accept=\".figpkg,.zip\" hidden @change=${this.importFile} />\n <ox-grist class=\"page-fill\" mode=\"CARD\" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler}>\n <div slot=\"headroom\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n </div>\n </ox-grist>\n `\n }\n\n async pageInitialized() {\n await this.configure()\n }\n\n /*\n * The filter options are read once here (and again after an import), never per render: an async options function\n * runs on every render of the filter bar and replaces the open list's options under the pointer.\n */\n private async configure() {\n const { categories, capabilities } = await this.facets()\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n fields: ['title', 'meta'],\n details: []\n },\n columns: [\n {\n type: 'image',\n name: 'thumbnail',\n record: { editable: false, renderEmpty: true, renderer: (_value, _column, record) => this.thumbnailOf(record) }\n },\n {\n type: 'string',\n name: 'title',\n record: {\n editable: false,\n renderer: (_value, _column, record) => (record.release ?? record.latest).name\n }\n },\n {\n type: 'string',\n name: 'meta',\n record: { editable: false, renderer: (_value, _column, record) => html`<figure-card-meta .figure=${record}></figure-card-meta>` }\n },\n { type: 'string', name: 'name', hidden: true, record: { editable: false }, filter: 'search' },\n {\n type: 'select',\n name: 'category',\n header: i18next.t('figure-library.label.category'),\n hidden: true,\n record: { editable: false },\n filter: { operator: 'eq', options: categories }\n },\n {\n type: 'select',\n name: 'capability',\n header: i18next.t('figure-library.label.capability'),\n hidden: true,\n record: { editable: false },\n filter: { operator: 'eq', options: capabilities }\n }\n ],\n rows: {\n selectable: false,\n appendable: false,\n handlers: {\n click: (_columns, _data, _column, record) => record && this.openReleases(record)\n }\n },\n pagination: { pages: [24, 48, 96] }\n }\n }\n\n async pageUpdated() {\n if (this.active) this.grist?.fetch()\n }\n\n private fetchHandler = async ({ page = 1, limit = 24, filters = [] }: FetchOption) => {\n const response = await client.query({\n query: FIGURES,\n variables: {\n /* The name search arrives as %text%; the server matches parts itself. */\n filters: filters\n .filter(filter => filter.value !== undefined && filter.value !== '' && !(Array.isArray(filter.value) && !filter.value.length))\n .map(filter => ({ ...filter, value: typeof filter.value === 'string' ? filter.value.replace(/^%|%$/g, '') : filter.value })),\n pagination: { page, limit }\n },\n fetchPolicy: 'network-only'\n })\n return { total: response.data.responses.total || 0, records: response.data.responses.items || [] }\n }\n\n /** The filter options, from what the figures that draw carry. */\n private async facets() {\n const response = await client.query({ query: FACETS, fetchPolicy: 'network-only' })\n const facets = response.data?.figureLibraryFacets ?? { categories: [], capabilities: [] }\n return {\n categories: [\n ...facets.categories.map((value: string) => ({ display: value, value })),\n ...(facets.uncategorized ? [{ display: i18next.t('figure-library.text.no-category'), value: NONE }] : [])\n ],\n capabilities: [\n ...facets.capabilities.map((value: string) => ({ display: i18next.t(`figure.label.role-${value}`, { defaultValue: value }), value })),\n ...(facets.incapable ? [{ display: i18next.t('figure-library.text.no-capability'), value: NONE }] : [])\n ]\n }\n }\n\n private thumbnailOf(record: any) {\n const hash = (record?.release ?? record?.latest)?.dependencies?.find((d: any) => d.role === 'thumbnail')?.hash\n if (!hash) return html`<figure-thumb-mark .label=${i18next.t('figure-library.text.no-thumbnail')}></figure-thumb-mark>`\n const { contextPath } = getPathInfo(location.pathname)\n return html`<img alt=\"\" src=${`${contextPath}/figure-library-file/${hash}`} />`\n }\n\n private openReleases(record: any) {\n openPopup(\n html`<figure-releases-popup .name=${record.name} .drawing=${record.release?.id ?? ''} @saved=${() => this.grist.fetch()}></figure-releases-popup>`,\n {\n backdrop: true,\n size: 'large',\n title: i18next.t('figure-library.title.releases-of', { name: (record.release ?? record.latest).name, count: record.releaseCount })\n }\n )\n }\n\n private chooseFile() {\n ;(this.renderRoot.querySelector('#file') as HTMLInputElement | null)?.click()\n }\n\n private importFile = async (event: Event) => {\n const input = event.target as HTMLInputElement\n const file = input.files?.[0]\n if (!file) return\n let result: ImportResult\n try {\n const response = await client.mutate({ mutation: IMPORT, variables: { file }, context: { hasUpload: true } })\n if (response.errors?.length) throw new Error(response.errors[0].message)\n result = response.data.importFigurePackage\n } catch (e: any) {\n result = { problems: [{ code: e?.message ?? 'error' }], outcomes: [] }\n } finally {\n input.value = ''\n }\n await this.configure()\n this.grist.fetch()\n openPopup(this.renderImported(result), { backdrop: true, size: 'small', closable: true, title: i18next.t('figure-library.title.import-result') })\n }\n\n private renderImported(result: ImportResult) {\n return html`\n <div style=\"padding: 16px; display: flex; flex-direction: column; gap: 8px; font-size: var(--ui-t-body, 13px);\">\n ${result.problems.length\n ? html`<p style=\"margin: 0; color: var(--ui-crit, var(--md-sys-color-error));\" role=\"alert\">\n ${i18next.t('figure-library.text.package-refused', { code: result.problems.map(p => p.code).join(', ') })}\n </p>`\n : result.outcomes.map(\n o => html`<div>\n <span style=\"font-family: var(--ui-mono, monospace);\">${o.ref}</span> ·\n <strong style=${o.outcome === 'refused' ? 'color: var(--ui-crit, var(--md-sys-color-error))' : ''}>${i18next.t(`figure-library.outcome.${o.outcome}`)}</strong>\n ${o.differs?.length ? html`<div>${i18next.t('figure-library.text.differs', { fields: o.differs.join(', ') })}</div>` : nothing}\n ${o.outcome === 'refused' && o.code ? html`<div>${o.code}</div>` : nothing}\n </div>`\n )}\n </div>\n `\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"figure-library-page.js","sourceRoot":"","sources":["../../client/pages/figure-library-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '../viewparts/figure-card-meta.js'\nimport '@things-factory/figure-viewer/dist-client/figure-thumb-mark.js'\nimport '../viewparts/figure-releases-popup.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/popup'\nimport { PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, FabStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { getPathInfo } from '@operato/utils'\n\n/*\n * The board server's figures (ADR-0114, amended 2026-10-12), as a card catalogue: one card per imported figure, its\n * thumbnail first, the release it draws with and the latest imported. A card whose figure does not draw with its latest\n * says so. Clicking a card opens its releases side by side to compare them and choose the one it draws with.\n *\n * The library is expected to grow to many figures, so the list pages from the server and the filters (category,\n * capability) are drop-down lists in the filter bar beside the name search. Upload, the decision of the screen, sits in\n * the shell's action bar; what it did opens in a popup.\n */\n\nconst FIGURES = gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: figureLibraryFigures(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n name\n latestVersion\n releaseCount\n release {\n id\n name\n version\n category\n capabilities\n formatSupported\n deprecated\n dependencies\n }\n latest {\n id\n name\n version\n formatSupported\n dependencies\n }\n }\n total\n }\n }\n`\n\nconst FACETS = gql`\n query {\n figureLibraryFacets {\n categories\n uncategorized\n capabilities\n incapable\n }\n }\n`\n\nconst IMPORT = gql`\n mutation ($file: Upload!) {\n importFigurePackage(file: $file) {\n problems {\n code\n path\n }\n outcomes {\n ref\n outcome\n code\n differs\n }\n }\n }\n`\n\n/** The filter value for a figure with no category, or one that declares no capability. */\nconst NONE = '-'\n\ntype ImportResult = { problems: { code: string; path?: string }[]; outcomes: { ref: string; outcome: string; code?: string; differs?: string[] }[] }\n\n@customElement('figure-library-page')\nexport class FigureLibraryPage extends localize(i18next)(PageView) {\n static styles = [\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n FabStyles,\n css`\n ox-filters-form {\n flex: 1;\n }\n\n ox-grist {\n /* Cards of a row stand at one height; a card with an extra fact row does not stick out below the others. */\n --data-card-record-card-height: auto;\n --data-card-thumbnail-aspect: 4 / 3;\n --data-card-thumbnail-background: var(--md-sys-color-surface-container-lowest);\n }\n\n `\n ]\n\n @state() private gristConfig: any\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('figure-library.title'),\n search: {\n placeholder: i18next.t('figure-library.text.search'),\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n }\n }\n }\n\n render() {\n return html`\n <input id=\"file\" type=\"file\" accept=\".figpkg,.zip\" hidden @change=${this.importFile} />\n <ox-grist class=\"page-fill\" mode=\"CARD\" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler}>\n <div slot=\"headroom\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n </div>\n </ox-grist>\n\n <button fab @click=${() => this.chooseFile()}>\n <md-icon>upload_file</md-icon>${i18next.t('figure-library.button.upload')}\n </button>\n `\n }\n\n async pageInitialized() {\n await this.configure()\n }\n\n /*\n * The filter options are read once here (and again after an import), never per render: an async options function\n * runs on every render of the filter bar and replaces the open list's options under the pointer.\n */\n private async configure() {\n const { categories, capabilities } = await this.facets()\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n fields: ['title', 'meta'],\n details: []\n },\n columns: [\n {\n type: 'image',\n name: 'thumbnail',\n record: { editable: false, renderEmpty: true, renderer: (_value, _column, record) => this.thumbnailOf(record) }\n },\n {\n type: 'string',\n name: 'title',\n record: {\n editable: false,\n renderer: (_value, _column, record) => (record.release ?? record.latest).name\n }\n },\n {\n type: 'string',\n name: 'meta',\n record: { editable: false, renderer: (_value, _column, record) => html`<figure-card-meta .figure=${record}></figure-card-meta>` }\n },\n { type: 'string', name: 'name', hidden: true, record: { editable: false }, filter: 'search' },\n {\n type: 'select',\n name: 'category',\n header: i18next.t('figure-library.label.category'),\n hidden: true,\n record: { editable: false },\n filter: { operator: 'eq', options: categories }\n },\n {\n type: 'select',\n name: 'capability',\n header: i18next.t('figure-library.label.capability'),\n hidden: true,\n record: { editable: false },\n filter: { operator: 'eq', options: capabilities }\n }\n ],\n rows: {\n selectable: false,\n appendable: false,\n handlers: {\n click: (_columns, _data, _column, record) => record && this.openReleases(record)\n }\n },\n pagination: { pages: [24, 48, 96] }\n }\n }\n\n async pageUpdated() {\n if (this.active) this.grist?.fetch()\n }\n\n private fetchHandler = async ({ page = 1, limit = 24, filters = [] }: FetchOption) => {\n const response = await client.query({\n query: FIGURES,\n variables: {\n /* The name search arrives as %text%; the server matches parts itself. */\n filters: filters\n .filter(filter => filter.value !== undefined && filter.value !== '' && !(Array.isArray(filter.value) && !filter.value.length))\n .map(filter => ({ ...filter, value: typeof filter.value === 'string' ? filter.value.replace(/^%|%$/g, '') : filter.value })),\n pagination: { page, limit }\n },\n fetchPolicy: 'network-only'\n })\n return { total: response.data.responses.total || 0, records: response.data.responses.items || [] }\n }\n\n /** The filter options, from what the figures that draw carry. */\n private async facets() {\n const response = await client.query({ query: FACETS, fetchPolicy: 'network-only' })\n const facets = response.data?.figureLibraryFacets ?? { categories: [], capabilities: [] }\n return {\n categories: [\n ...facets.categories.map((value: string) => ({ display: value, value })),\n ...(facets.uncategorized ? [{ display: i18next.t('figure-library.text.no-category'), value: NONE }] : [])\n ],\n capabilities: [\n ...facets.capabilities.map((value: string) => ({ display: i18next.t(`figure.label.role-${value}`, { defaultValue: value }), value })),\n ...(facets.incapable ? [{ display: i18next.t('figure-library.text.no-capability'), value: NONE }] : [])\n ]\n }\n }\n\n private thumbnailOf(record: any) {\n const hash = (record?.release ?? record?.latest)?.dependencies?.find((d: any) => d.role === 'thumbnail')?.hash\n if (!hash) return html`<figure-thumb-mark .label=${i18next.t('figure-library.text.no-thumbnail')}></figure-thumb-mark>`\n const { contextPath } = getPathInfo(location.pathname)\n return html`<img alt=\"\" src=${`${contextPath}/figure-library-file/${hash}`} />`\n }\n\n private openReleases(record: any) {\n openPopup(\n html`<figure-releases-popup .name=${record.name} .drawing=${record.release?.id ?? ''} @saved=${() => this.grist.fetch()}></figure-releases-popup>`,\n {\n backdrop: true,\n size: 'large',\n title: i18next.t('figure-library.title.releases-of', { name: (record.release ?? record.latest).name, count: record.releaseCount })\n }\n )\n }\n\n private chooseFile() {\n ;(this.renderRoot.querySelector('#file') as HTMLInputElement | null)?.click()\n }\n\n private importFile = async (event: Event) => {\n const input = event.target as HTMLInputElement\n const file = input.files?.[0]\n if (!file) return\n let result: ImportResult\n try {\n const response = await client.mutate({ mutation: IMPORT, variables: { file }, context: { hasUpload: true } })\n if (response.errors?.length) throw new Error(response.errors[0].message)\n result = response.data.importFigurePackage\n } catch (e: any) {\n result = { problems: [{ code: e?.message ?? 'error' }], outcomes: [] }\n } finally {\n input.value = ''\n }\n await this.configure()\n this.grist.fetch()\n openPopup(this.renderImported(result), { backdrop: true, size: 'small', closable: true, title: i18next.t('figure-library.title.import-result') })\n }\n\n private renderImported(result: ImportResult) {\n return html`\n <div style=\"padding: 16px; display: flex; flex-direction: column; gap: 8px; font-size: var(--ui-t-body, 13px);\">\n ${result.problems.length\n ? html`<p style=\"margin: 0; color: var(--ui-crit, var(--md-sys-color-error));\" role=\"alert\">\n ${i18next.t('figure-library.text.package-refused', { code: result.problems.map(p => p.code).join(', ') })}\n </p>`\n : result.outcomes.map(\n o => html`<div>\n <span style=\"font-family: var(--ui-mono, monospace);\">${o.ref}</span> ·\n <strong style=${o.outcome === 'refused' ? 'color: var(--ui-crit, var(--md-sys-color-error))' : ''}>${i18next.t(`figure-library.outcome.${o.outcome}`)}</strong>\n ${o.differs?.length ? html`<div>${i18next.t('figure-library.text.differs', { fields: o.differs.join(', ') })}</div>` : nothing}\n ${o.outcome === 'refused' && o.code ? html`<div>${o.code}</div>` : nothing}\n </div>`\n )}\n </div>\n `\n }\n}\n"]}
|