@things-factory/figure-library 10.1.178 → 10.1.181
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/pages/figure-library-page.d.ts +2 -3
- package/dist-client/pages/figure-library-page.js +11 -61
- package/dist-client/pages/figure-library-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/figure-package-import.d.ts +24 -0
- package/dist-client/viewparts/figure-package-import.js +117 -0
- package/dist-client/viewparts/figure-package-import.js.map +1 -0
- package/package.json +8 -7
- package/translations/en.json +1 -0
- package/translations/es.json +1 -0
- package/translations/ja.json +1 -0
- package/translations/ko.json +1 -0
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
|
@@ -2,6 +2,7 @@ import '@operato/data-grist';
|
|
|
2
2
|
import '@operato/data-grist/ox-card-thumb.js';
|
|
3
3
|
import '@things-factory/figure-viewer/dist-client/figure-thumb-mark.js';
|
|
4
4
|
import '../viewparts/figure-releases-popup.js';
|
|
5
|
+
import '../viewparts/figure-package-import.js';
|
|
5
6
|
import { PageView } from '@operato/shell';
|
|
6
7
|
declare const FigureLibraryPage_base: (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
|
|
7
8
|
export declare class FigureLibraryPage extends FigureLibraryPage_base {
|
|
@@ -33,8 +34,6 @@ export declare class FigureLibraryPage extends FigureLibraryPage_base {
|
|
|
33
34
|
/** The line under the name: the full name and the version it draws with, as a board card's 「v1 · 3일 전」. */
|
|
34
35
|
private metaOf;
|
|
35
36
|
private openReleases;
|
|
36
|
-
private
|
|
37
|
-
private importFile;
|
|
38
|
-
private renderImported;
|
|
37
|
+
private openImport;
|
|
39
38
|
}
|
|
40
39
|
export {};
|
|
@@ -3,9 +3,10 @@ import '@operato/data-grist';
|
|
|
3
3
|
import '@operato/data-grist/ox-card-thumb.js';
|
|
4
4
|
import '@things-factory/figure-viewer/dist-client/figure-thumb-mark.js';
|
|
5
5
|
import '../viewparts/figure-releases-popup.js';
|
|
6
|
+
import '../viewparts/figure-package-import.js';
|
|
6
7
|
import { versionText } from '../viewparts/figure-version.js';
|
|
7
8
|
import gql from 'graphql-tag';
|
|
8
|
-
import { css, html
|
|
9
|
+
import { css, html } from 'lit';
|
|
9
10
|
import { customElement, query, state } from 'lit/decorators.js';
|
|
10
11
|
import { DataGrist } from '@operato/data-grist';
|
|
11
12
|
import { client } from '@operato/graphql';
|
|
@@ -22,7 +23,7 @@ import { getPathInfo } from '@operato/utils';
|
|
|
22
23
|
*
|
|
23
24
|
* The library is expected to grow to many figures, so the list pages from the server and the filters (category,
|
|
24
25
|
* capability) are drop-down lists in the filter bar beside the name search. Upload, the screen's one primary action, is
|
|
25
|
-
* the FAB;
|
|
26
|
+
* the FAB; it opens a popup whose drop box takes the package and says what it came to.
|
|
26
27
|
*/
|
|
27
28
|
const FIGURES = gql `
|
|
28
29
|
query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
|
|
@@ -63,22 +64,6 @@ const FACETS = gql `
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
`;
|
|
66
|
-
const IMPORT = gql `
|
|
67
|
-
mutation ($file: Upload!) {
|
|
68
|
-
importFigurePackage(file: $file) {
|
|
69
|
-
problems {
|
|
70
|
-
code
|
|
71
|
-
path
|
|
72
|
-
}
|
|
73
|
-
outcomes {
|
|
74
|
-
ref
|
|
75
|
-
outcome
|
|
76
|
-
code
|
|
77
|
-
differs
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
`;
|
|
82
67
|
/** The filter value for a figure with no category, or one that declares no capability. */
|
|
83
68
|
const NONE = '-';
|
|
84
69
|
let FigureLibraryPage = class FigureLibraryPage extends localize(i18next)(PageView) {
|
|
@@ -98,28 +83,6 @@ let FigureLibraryPage = class FigureLibraryPage extends localize(i18next)(PageVi
|
|
|
98
83
|
});
|
|
99
84
|
return { total: response.data.responses.total || 0, records: response.data.responses.items || [] };
|
|
100
85
|
};
|
|
101
|
-
this.importFile = async (event) => {
|
|
102
|
-
const input = event.target;
|
|
103
|
-
const file = input.files?.[0];
|
|
104
|
-
if (!file)
|
|
105
|
-
return;
|
|
106
|
-
let result;
|
|
107
|
-
try {
|
|
108
|
-
const response = await client.mutate({ mutation: IMPORT, variables: { file }, context: { hasUpload: true } });
|
|
109
|
-
if (response.errors?.length)
|
|
110
|
-
throw new Error(response.errors[0].message);
|
|
111
|
-
result = response.data.importFigurePackage;
|
|
112
|
-
}
|
|
113
|
-
catch (e) {
|
|
114
|
-
result = { problems: [{ code: e?.message ?? 'error' }], outcomes: [] };
|
|
115
|
-
}
|
|
116
|
-
finally {
|
|
117
|
-
input.value = '';
|
|
118
|
-
}
|
|
119
|
-
await this.configure();
|
|
120
|
-
this.grist.fetch();
|
|
121
|
-
openPopup(this.renderImported(result), { backdrop: true, size: 'small', closable: true, title: i18next.t('figure-library.title.import-result') });
|
|
122
|
-
};
|
|
123
86
|
}
|
|
124
87
|
static { this.styles = [
|
|
125
88
|
WorkSurfacePageStyles,
|
|
@@ -148,14 +111,13 @@ let FigureLibraryPage = class FigureLibraryPage extends localize(i18next)(PageVi
|
|
|
148
111
|
}
|
|
149
112
|
render() {
|
|
150
113
|
return html `
|
|
151
|
-
<input id="file" type="file" accept=".figpkg,.zip" hidden @change=${this.importFile} />
|
|
152
114
|
<ox-grist class="page-fill" mode="CARD" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler}>
|
|
153
115
|
<div slot="headroom">
|
|
154
116
|
<ox-filters-form autofocus without-search></ox-filters-form>
|
|
155
117
|
</div>
|
|
156
118
|
</ox-grist>
|
|
157
119
|
|
|
158
|
-
<button fab @click=${() => this.
|
|
120
|
+
<button fab @click=${() => this.openImport()}>
|
|
159
121
|
<md-icon>upload_file</md-icon>${i18next.t('figure-library.button.upload')}
|
|
160
122
|
</button>
|
|
161
123
|
`;
|
|
@@ -280,25 +242,13 @@ let FigureLibraryPage = class FigureLibraryPage extends localize(i18next)(PageVi
|
|
|
280
242
|
title: i18next.t('figure-library.title.releases-of', { name: (record.release ?? record.latest).name, count: record.releaseCount })
|
|
281
243
|
});
|
|
282
244
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
${result.problems.length
|
|
291
|
-
? html `<p style="margin: 0; color: var(--ui-crit, var(--md-sys-color-error));" role="alert">
|
|
292
|
-
${i18next.t('figure-library.text.package-refused', { code: result.problems.map(p => p.code).join(', ') })}
|
|
293
|
-
</p>`
|
|
294
|
-
: result.outcomes.map(o => html `<div>
|
|
295
|
-
<span style="font-family: var(--ui-mono, monospace);">${o.ref}</span> ·
|
|
296
|
-
<strong style=${o.outcome === 'refused' ? 'color: var(--ui-crit, var(--md-sys-color-error))' : ''}>${i18next.t(`figure-library.outcome.${o.outcome}`)}</strong>
|
|
297
|
-
${o.differs?.length ? html `<div>${i18next.t('figure-library.text.differs', { fields: o.differs.join(', ') })}</div>` : nothing}
|
|
298
|
-
${o.outcome === 'refused' && o.code ? html `<div>${o.code}</div>` : nothing}
|
|
299
|
-
</div>`)}
|
|
300
|
-
</div>
|
|
301
|
-
`;
|
|
245
|
+
openImport() {
|
|
246
|
+
openPopup(html `<figure-package-import
|
|
247
|
+
@imported=${async () => {
|
|
248
|
+
await this.configure();
|
|
249
|
+
this.grist.fetch();
|
|
250
|
+
}}
|
|
251
|
+
></figure-package-import>`, { backdrop: true, size: 'small', closable: true, title: i18next.t('figure-library.button.upload') });
|
|
302
252
|
}
|
|
303
253
|
};
|
|
304
254
|
__decorate([
|
|
@@ -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 '@operato/data-grist/ox-card-thumb.js'\nimport '@things-factory/figure-viewer/dist-client/figure-thumb-mark.js'\nimport '../viewparts/figure-releases-popup.js'\nimport { versionText } from '../viewparts/figure-version.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 { CardCatalogStyles, 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 with the board catalog's card: the\n * thumbnail, the name, and one line - the full name and the version it draws with. The one thing to know before opening\n * a card is its corner marker: cannot be read here, not drawing the latest, or deprecated. Clicking a card opens its\n * 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 screen's one primary action, is\n * the FAB; 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 /* The card, its picture cell and the upload FAB: every card catalog's (ADR-0117 amendment 2026-10-13). */\n CardCatalogStyles,\n css`\n ox-filters-form {\n flex: 1;\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) => this.metaOf(record) }\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 /** The picture cell every catalog card draws, with the one marker this figure needs. */\n private thumbnailOf(record: any) {\n const hash = (record?.release ?? record?.latest)?.dependencies?.find((d: any) => d.role === 'thumbnail')?.hash\n const { contextPath } = getPathInfo(location.pathname)\n const [badge, tone] = this.markerOf(record)\n return html`<ox-card-thumb\n src=${hash ? `${contextPath}/figure-library-file/${hash}` : ''}\n alt=${(record?.release ?? record?.latest)?.name ?? ''}\n badge=${badge}\n tone=${tone}\n >\n <figure-thumb-mark slot=\"empty\" .label=${i18next.t('figure-library.text.no-thumbnail')}></figure-thumb-mark>\n </ox-card-thumb>`\n }\n\n /**\n * The one thing a card says before it is opened, the gravest first: nothing here can draw it, it does not draw its\n * latest release, or the release it draws is deprecated. A figure drawing its latest says nothing.\n */\n private markerOf(record: any): [string, 'plain' | 'warn' | 'crit'] {\n const release = record?.release\n if (!release) return [i18next.t('figure-library.text.format-unsupported'), 'crit']\n if (release.version !== record.latestVersion) return [i18next.t('figure-library.text.not-latest'), 'warn']\n if (release.deprecated) return [i18next.t('figure-library.text.deprecated'), 'plain']\n return ['', 'plain']\n }\n\n /** The line under the name: the full name and the version it draws with, as a board card's 「v1 · 3일 전」. */\n private metaOf(record: any): string {\n return record?.release ? `${record.name} · ${versionText(record.release.version)}` : record?.name ?? ''\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 '@operato/data-grist/ox-card-thumb.js'\nimport '@things-factory/figure-viewer/dist-client/figure-thumb-mark.js'\nimport '../viewparts/figure-releases-popup.js'\nimport '../viewparts/figure-package-import.js'\nimport { versionText } from '../viewparts/figure-version.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 { CardCatalogStyles, 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 with the board catalog's card: the\n * thumbnail, the name, and one line - the full name and the version it draws with. The one thing to know before opening\n * a card is its corner marker: cannot be read here, not drawing the latest, or deprecated. Clicking a card opens its\n * 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 screen's one primary action, is\n * the FAB; it opens a popup whose drop box takes the package and says what it came to.\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\n/** The filter value for a figure with no category, or one that declares no capability. */\nconst NONE = '-'\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 /* The card, its picture cell and the upload FAB: every card catalog's (ADR-0117 amendment 2026-10-13). */\n CardCatalogStyles,\n css`\n ox-filters-form {\n flex: 1;\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 <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.openImport()}>\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) => this.metaOf(record) }\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 /** The picture cell every catalog card draws, with the one marker this figure needs. */\n private thumbnailOf(record: any) {\n const hash = (record?.release ?? record?.latest)?.dependencies?.find((d: any) => d.role === 'thumbnail')?.hash\n const { contextPath } = getPathInfo(location.pathname)\n const [badge, tone] = this.markerOf(record)\n return html`<ox-card-thumb\n src=${hash ? `${contextPath}/figure-library-file/${hash}` : ''}\n alt=${(record?.release ?? record?.latest)?.name ?? ''}\n badge=${badge}\n tone=${tone}\n >\n <figure-thumb-mark slot=\"empty\" .label=${i18next.t('figure-library.text.no-thumbnail')}></figure-thumb-mark>\n </ox-card-thumb>`\n }\n\n /**\n * The one thing a card says before it is opened, the gravest first: nothing here can draw it, it does not draw its\n * latest release, or the release it draws is deprecated. A figure drawing its latest says nothing.\n */\n private markerOf(record: any): [string, 'plain' | 'warn' | 'crit'] {\n const release = record?.release\n if (!release) return [i18next.t('figure-library.text.format-unsupported'), 'crit']\n if (release.version !== record.latestVersion) return [i18next.t('figure-library.text.not-latest'), 'warn']\n if (release.deprecated) return [i18next.t('figure-library.text.deprecated'), 'plain']\n return ['', 'plain']\n }\n\n /** The line under the name: the full name and the version it draws with, as a board card's 「v1 · 3일 전」. */\n private metaOf(record: any): string {\n return record?.release ? `${record.name} · ${versionText(record.release.version)}` : record?.name ?? ''\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 openImport() {\n openPopup(\n html`<figure-package-import\n @imported=${async () => {\n await this.configure()\n this.grist.fetch()\n }}\n ></figure-package-import>`,\n { backdrop: true, size: 'small', closable: true, title: i18next.t('figure-library.button.upload') }\n )\n }\n}\n"]}
|