@things-factory/figure-library 10.1.154 → 10.1.155
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 +20 -58
- package/dist-client/pages/figure-library-page.js +189 -672
- package/dist-client/pages/figure-library-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/figure-card-meta.d.ts +19 -0
- package/dist-client/viewparts/figure-card-meta.js +122 -0
- package/dist-client/viewparts/figure-card-meta.js.map +1 -0
- package/dist-client/viewparts/figure-releases-popup.d.ts +34 -0
- package/dist-client/viewparts/figure-releases-popup.js +400 -0
- package/dist-client/viewparts/figure-releases-popup.js.map +1 -0
- package/dist-client/viewparts/release-pair.d.ts +9 -0
- package/dist-client/viewparts/release-pair.js +15 -0
- package/dist-client/viewparts/release-pair.js.map +1 -0
- package/dist-server/service/figure-library-release/figure-library-release.d.ts +5 -3
- package/dist-server/service/figure-library-release/figure-library-release.js +13 -3
- package/dist-server/service/figure-library-release/figure-library-release.js.map +1 -1
- package/dist-server/service/figure-library-resolver.d.ts +9 -9
- package/dist-server/service/figure-library-resolver.js +66 -69
- package/dist-server/service/figure-library-resolver.js.map +1 -1
- package/dist-server/service/figure-library-types.d.ts +17 -4
- package/dist-server/service/figure-library-types.js +63 -15
- package/dist-server/service/figure-library-types.js.map +1 -1
- package/dist-server/service/figure-type-map/figure-type-map-entry.d.ts +5 -4
- package/dist-server/service/figure-type-map/figure-type-map-entry.js +8 -14
- package/dist-server/service/figure-type-map/figure-type-map-entry.js.map +1 -1
- package/dist-server/service/index.d.ts +2 -3
- package/dist-server/service/index.js +2 -3
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/library/blueprints.d.ts +3 -8
- package/dist-server/service/library/blueprints.js +5 -6
- package/dist-server/service/library/blueprints.js.map +1 -1
- package/dist-server/service/library/carriers.d.ts +8 -11
- package/dist-server/service/library/carriers.js +8 -14
- package/dist-server/service/library/carriers.js.map +1 -1
- package/dist-server/service/library/derived.d.ts +5 -3
- package/dist-server/service/library/derived.js +4 -3
- package/dist-server/service/library/derived.js.map +1 -1
- package/dist-server/service/library/figures.d.ts +46 -0
- package/dist-server/service/library/figures.js +91 -0
- package/dist-server/service/library/figures.js.map +1 -0
- package/dist-server/service/library/import.d.ts +1 -1
- package/dist-server/service/library/import.js +5 -3
- package/dist-server/service/library/import.js.map +1 -1
- package/dist-server/service/library/inspection.d.ts +1 -48
- package/dist-server/service/library/inspection.js +3 -80
- package/dist-server/service/library/inspection.js.map +1 -1
- package/dist-server/service/library/type-map.d.ts +10 -22
- package/dist-server/service/library/type-map.js +44 -108
- package/dist-server/service/library/type-map.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -10
- package/translations/en.json +26 -47
- package/translations/es.json +26 -47
- package/translations/ja.json +26 -47
- package/translations/ko.json +26 -47
- package/translations/ms.json +26 -47
- package/translations/zh.json +26 -47
- package/dist-server/service/figure-type-map/figure-type-map.d.ts +0 -34
- package/dist-server/service/figure-type-map/figure-type-map.js +0 -120
- package/dist-server/service/figure-type-map/figure-type-map.js.map +0 -1
|
@@ -1,72 +1,66 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import '@operato/
|
|
3
|
-
import '
|
|
2
|
+
import '@operato/data-grist';
|
|
3
|
+
import '../viewparts/figure-card-meta.js';
|
|
4
|
+
import '@things-factory/figure-viewer/dist-client/figure-thumb-mark.js';
|
|
5
|
+
import '../viewparts/figure-releases-popup.js';
|
|
4
6
|
import gql from 'graphql-tag';
|
|
5
7
|
import { css, html, nothing } from 'lit';
|
|
6
|
-
import { customElement, state } from 'lit/decorators.js';
|
|
8
|
+
import { customElement, query, state } from 'lit/decorators.js';
|
|
9
|
+
import { DataGrist } from '@operato/data-grist';
|
|
7
10
|
import { client } from '@operato/graphql';
|
|
8
11
|
import { i18next, localize } from '@operato/i18n';
|
|
12
|
+
import { openPopup } from '@operato/popup';
|
|
9
13
|
import { PageView } from '@operato/shell';
|
|
10
|
-
import {
|
|
14
|
+
import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
|
|
11
15
|
import { getPathInfo } from '@operato/utils';
|
|
12
16
|
/*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* stays off until the candidate has been checked, and the button says so.
|
|
17
|
+
* The board server's figures (ADR-0114, amended 2026-10-12), as a card catalogue: one card per imported figure, its
|
|
18
|
+
* thumbnail first, the release it draws with and the latest imported. A card whose figure does not draw with its latest
|
|
19
|
+
* says so. Clicking a card opens its releases side by side to compare them and choose the one it draws with.
|
|
17
20
|
*
|
|
18
|
-
* The
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
+
* The library is expected to grow to many figures, so the list pages from the server and the filters (category,
|
|
22
|
+
* capability) are drop-down lists in the filter bar beside the name search. Upload, the decision of the screen, sits in
|
|
23
|
+
* the shell's action bar; what it did opens in a popup.
|
|
21
24
|
*/
|
|
22
|
-
const
|
|
23
|
-
query {
|
|
24
|
-
|
|
25
|
+
const FIGURES = gql `
|
|
26
|
+
query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
|
|
27
|
+
responses: figureLibraryFigures(filters: $filters, pagination: $pagination, sortings: $sortings) {
|
|
25
28
|
items {
|
|
26
|
-
id
|
|
27
29
|
name
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
latestVersion
|
|
31
|
+
releaseCount
|
|
32
|
+
release {
|
|
33
|
+
id
|
|
34
|
+
name
|
|
35
|
+
version
|
|
36
|
+
category
|
|
37
|
+
capabilities
|
|
38
|
+
formatSupported
|
|
39
|
+
deprecated
|
|
40
|
+
dependencies
|
|
41
|
+
}
|
|
42
|
+
latest {
|
|
43
|
+
id
|
|
44
|
+
name
|
|
45
|
+
version
|
|
46
|
+
formatSupported
|
|
47
|
+
dependencies
|
|
48
|
+
}
|
|
38
49
|
}
|
|
39
50
|
total
|
|
40
51
|
}
|
|
41
52
|
}
|
|
42
53
|
`;
|
|
43
|
-
const
|
|
54
|
+
const FACETS = gql `
|
|
44
55
|
query {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
activatedAt
|
|
56
|
+
figureLibraryFacets {
|
|
57
|
+
categories
|
|
58
|
+
uncategorized
|
|
59
|
+
capabilities
|
|
60
|
+
incapable
|
|
51
61
|
}
|
|
52
62
|
}
|
|
53
63
|
`;
|
|
54
|
-
const LINES = gql `
|
|
55
|
-
query ($version: Int!) {
|
|
56
|
-
figureTypeMapEntries(version: $version) {
|
|
57
|
-
name
|
|
58
|
-
release {
|
|
59
|
-
id
|
|
60
|
-
ref
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
`;
|
|
65
|
-
const CHECK = gql `
|
|
66
|
-
query {
|
|
67
|
-
figureTypeMapCheck
|
|
68
|
-
}
|
|
69
|
-
`;
|
|
70
64
|
const IMPORT = gql `
|
|
71
65
|
mutation ($file: Upload!) {
|
|
72
66
|
importFigurePackage(file: $file) {
|
|
@@ -83,698 +77,221 @@ const IMPORT = gql `
|
|
|
83
77
|
}
|
|
84
78
|
}
|
|
85
79
|
`;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
saveFigureTypeMapCandidate(lines: $lines) {
|
|
89
|
-
version
|
|
90
|
-
revision
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
`;
|
|
94
|
-
const ACTIVATE = gql `
|
|
95
|
-
mutation ($version: Int!) {
|
|
96
|
-
activateFigureTypeMap(version: $version) {
|
|
97
|
-
version
|
|
98
|
-
state
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
`;
|
|
102
|
-
const fullName = (release) => `${release.namespace}/${release.type}`;
|
|
103
|
-
/** A time in the reader's language (a bare toLocaleString follows the browser, not the app). */
|
|
104
|
-
const when = (value) => (value ? new Date(value).toLocaleString(i18next.language) : '');
|
|
105
|
-
/**
|
|
106
|
-
* A contract change in words. figure-model gives a code and values; `detail` is English for logs and is
|
|
107
|
-
* the sentence only when this module has no words for a new code (open question P8 in figure-library.md).
|
|
108
|
-
*/
|
|
109
|
-
const changeText = (change) => change.code
|
|
110
|
-
? i18next.t(`figure-library.contract.${change.code}`, { ...(change.values ?? {}), defaultValue: change.detail ?? change.code })
|
|
111
|
-
: change.detail ?? '';
|
|
80
|
+
/** The filter value for a figure with no category, or one that declares no capability. */
|
|
81
|
+
const NONE = '-';
|
|
112
82
|
let FigureLibraryPage = class FigureLibraryPage extends localize(i18next)(PageView) {
|
|
113
83
|
constructor() {
|
|
114
84
|
super(...arguments);
|
|
115
|
-
this.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
85
|
+
this.fetchHandler = async ({ page = 1, limit = 24, filters = [] }) => {
|
|
86
|
+
const response = await client.query({
|
|
87
|
+
query: FIGURES,
|
|
88
|
+
variables: {
|
|
89
|
+
/* The name search arrives as %text%; the server matches parts itself. */
|
|
90
|
+
filters: filters
|
|
91
|
+
.filter(filter => filter.value !== undefined && filter.value !== '' && !(Array.isArray(filter.value) && !filter.value.length))
|
|
92
|
+
.map(filter => ({ ...filter, value: typeof filter.value === 'string' ? filter.value.replace(/^%|%$/g, '') : filter.value })),
|
|
93
|
+
pagination: { page, limit }
|
|
94
|
+
},
|
|
95
|
+
fetchPolicy: 'network-only'
|
|
96
|
+
});
|
|
97
|
+
return { total: response.data.responses.total || 0, records: response.data.responses.items || [] };
|
|
98
|
+
};
|
|
127
99
|
this.importFile = async (event) => {
|
|
128
100
|
const input = event.target;
|
|
129
101
|
const file = input.files?.[0];
|
|
130
102
|
if (!file)
|
|
131
103
|
return;
|
|
132
|
-
|
|
104
|
+
let result;
|
|
133
105
|
try {
|
|
134
106
|
const response = await client.mutate({ mutation: IMPORT, variables: { file }, context: { hasUpload: true } });
|
|
135
|
-
this.imported = response.data.importFigurePackage;
|
|
136
|
-
await this.refresh();
|
|
137
|
-
}
|
|
138
|
-
catch (e) {
|
|
139
|
-
this.imported = { problems: [{ code: e?.message ?? 'error' }], outcomes: [] };
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
this.busy = false;
|
|
143
|
-
input.value = '';
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
/* A window of its own draws the candidate: its figures never mix with the active map of this one (ADR-0114 결정 12). */
|
|
147
|
-
this.preview = () => {
|
|
148
|
-
const { contextPath } = getPathInfo(location.pathname);
|
|
149
|
-
window.open(`${contextPath}/board-list?figure-map=candidate`, '_blank', 'noopener');
|
|
150
|
-
};
|
|
151
|
-
this.saveCandidate = async () => {
|
|
152
|
-
this.busy = true;
|
|
153
|
-
try {
|
|
154
|
-
const lines = [...this.candidate].map(([name, releaseId]) => ({ name, releaseId }));
|
|
155
|
-
await client.mutate({ mutation: SAVE, variables: { lines } });
|
|
156
|
-
this.report = undefined;
|
|
157
|
-
await this.refresh();
|
|
158
|
-
}
|
|
159
|
-
catch (e) {
|
|
160
|
-
this.failure = e?.message ?? '';
|
|
161
|
-
}
|
|
162
|
-
finally {
|
|
163
|
-
this.busy = false;
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
this.check = async () => {
|
|
167
|
-
this.busy = true;
|
|
168
|
-
try {
|
|
169
|
-
const response = await client.query({ query: CHECK, fetchPolicy: 'network-only' });
|
|
170
107
|
if (response.errors?.length)
|
|
171
108
|
throw new Error(response.errors[0].message);
|
|
172
|
-
|
|
173
|
-
this.failure = '';
|
|
109
|
+
result = response.data.importFigurePackage;
|
|
174
110
|
}
|
|
175
111
|
catch (e) {
|
|
176
|
-
|
|
112
|
+
result = { problems: [{ code: e?.message ?? 'error' }], outcomes: [] };
|
|
177
113
|
}
|
|
178
114
|
finally {
|
|
179
|
-
|
|
115
|
+
input.value = '';
|
|
180
116
|
}
|
|
117
|
+
await this.configure();
|
|
118
|
+
this.grist.fetch();
|
|
119
|
+
openPopup(this.renderImported(result), { backdrop: true, size: 'small', closable: true, title: i18next.t('figure-library.title.import-result') });
|
|
181
120
|
};
|
|
182
121
|
}
|
|
183
122
|
static { this.styles = [
|
|
123
|
+
WorkSurfacePageStyles,
|
|
184
124
|
ScrollbarStyles,
|
|
185
|
-
|
|
186
|
-
|
|
125
|
+
CommonGristStyles,
|
|
126
|
+
CommonHeaderStyles,
|
|
187
127
|
css `
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
font-size: var(--ui-t-body, 13px);
|
|
191
|
-
line-height: 1.5;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/* 표 — 격자와 같은 모양(머리글 · 줄 여백 · 경계선이 --grid-* 토큰). */
|
|
195
|
-
table {
|
|
196
|
-
width: 100%;
|
|
197
|
-
border-collapse: collapse;
|
|
198
|
-
font-size: var(--grid-record-fontsize, 14px);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
th {
|
|
202
|
-
padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);
|
|
203
|
-
border-top: var(--grid-header-top-border, 2px solid var(--md-sys-color-primary));
|
|
204
|
-
border-bottom: var(--grid-header-bottom-border, 1px solid var(--md-sys-color-outline-variant));
|
|
205
|
-
background: var(--grid-header-background-color, var(--md-sys-color-surface-container-low));
|
|
206
|
-
font: var(--grid-header-font, 500 14px inherit);
|
|
207
|
-
color: var(--grid-header-color, var(--md-sys-color-primary));
|
|
208
|
-
text-align: left;
|
|
209
|
-
white-space: nowrap;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
td {
|
|
213
|
-
padding: var(--grid-record-padding, 4px 8px);
|
|
214
|
-
border-bottom: var(--grid-record-border-bottom, 1px solid var(--md-sys-color-outline-variant));
|
|
215
|
-
vertical-align: middle;
|
|
216
|
-
word-break: keep-all;
|
|
217
|
-
overflow-wrap: anywhere;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
td.thumb {
|
|
221
|
-
width: 64px;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
img[thumb] {
|
|
225
|
-
display: block;
|
|
226
|
-
width: 48px;
|
|
227
|
-
height: 36px;
|
|
228
|
-
object-fit: contain;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/* 식별자(정식 이름 · 발행본 참조)는 고정폭 숫자, 줄을 바꾸지 않는다. */
|
|
232
|
-
.ref {
|
|
233
|
-
font-family: var(--ui-mono, ui-monospace, Menlo, monospace);
|
|
234
|
-
font-size: var(--ui-t-small, 11.5px);
|
|
235
|
-
white-space: nowrap;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
.sub {
|
|
239
|
-
display: block;
|
|
240
|
-
color: var(--ui-muted, var(--md-sys-color-on-surface-variant));
|
|
241
|
-
font-size: var(--ui-t-small, 11.5px);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
.when {
|
|
245
|
-
font-variant-numeric: tabular-nums;
|
|
246
|
-
white-space: nowrap;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/* 상태 표 — 같은 줄에 둘 이상 붙을 수 있다(형식 미지원 · 퇴역). */
|
|
250
|
-
.marks {
|
|
251
|
-
display: flex;
|
|
252
|
-
flex-wrap: wrap;
|
|
253
|
-
gap: var(--spacing-small, 4px);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
.mark {
|
|
257
|
-
padding: 1px var(--spacing-medium, 8px);
|
|
258
|
-
border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));
|
|
259
|
-
border-radius: 999px;
|
|
260
|
-
color: var(--ui-muted, var(--md-sys-color-on-surface-variant));
|
|
261
|
-
font-size: var(--ui-t-small, 11.5px);
|
|
262
|
-
white-space: nowrap;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.mark.crit {
|
|
266
|
-
border-color: color-mix(in srgb, var(--ui-crit, var(--md-sys-color-error)) 40%, transparent);
|
|
267
|
-
color: var(--ui-crit, var(--md-sys-color-error));
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
.mark.on {
|
|
271
|
-
border-color: var(--ui-accent, var(--md-sys-color-primary));
|
|
272
|
-
color: var(--ui-accent, var(--md-sys-color-primary));
|
|
273
|
-
font-weight: 600;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/* 찾아낸 것 · 거부 — 왼쪽 선 하나. */
|
|
277
|
-
.finding {
|
|
278
|
-
margin: 0;
|
|
279
|
-
padding: var(--spacing-medium, 8px) 0 var(--spacing-medium, 8px) var(--spacing-large, 12px);
|
|
280
|
-
border-left: 2px solid var(--ui-crit, var(--md-sys-color-error));
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
.outcomes,
|
|
284
|
-
.report-list {
|
|
285
|
-
margin: 0;
|
|
286
|
-
padding: 0;
|
|
287
|
-
list-style: none;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
.outcomes > li,
|
|
291
|
-
.report-list > li {
|
|
292
|
-
display: flex;
|
|
293
|
-
flex-wrap: wrap;
|
|
294
|
-
align-items: baseline;
|
|
295
|
-
gap: var(--spacing-small, 4px) var(--spacing-large, 12px);
|
|
296
|
-
padding: var(--spacing-medium, 8px) 0;
|
|
297
|
-
border-top: 1px solid var(--ui-line-soft, var(--md-sys-color-surface-container-high));
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
.outcomes > li:first-child,
|
|
301
|
-
.report-list > li:first-child {
|
|
302
|
-
padding-top: 0;
|
|
303
|
-
border-top: none;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
.outcome-refused {
|
|
307
|
-
color: var(--ui-crit, var(--md-sys-color-error));
|
|
308
|
-
font-weight: 600;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
.changes {
|
|
312
|
-
flex-basis: 100%;
|
|
313
|
-
margin: 0;
|
|
314
|
-
padding-left: 1.2em;
|
|
315
|
-
color: var(--ui-muted, var(--md-sys-color-on-surface-variant));
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
.changes .breaking {
|
|
319
|
-
color: var(--ui-crit, var(--md-sys-color-error));
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
.report-group + .report-group {
|
|
323
|
-
margin-top: var(--spacing-huge, 24px);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
.report-group h4 {
|
|
327
|
-
margin: 0 0 var(--spacing-medium, 8px);
|
|
328
|
-
font-size: var(--ui-t-body, 13px);
|
|
329
|
-
font-weight: 600;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
select {
|
|
333
|
-
height: var(--form-element-height-medium, 30px);
|
|
334
|
-
min-width: 240px;
|
|
335
|
-
font-size: var(--ui-t-body, 13px);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
.empty {
|
|
339
|
-
margin: 0;
|
|
340
|
-
padding: var(--spacing-huge, 24px);
|
|
341
|
-
border: 1px dashed var(--ui-line, var(--md-sys-color-outline-variant));
|
|
342
|
-
border-radius: var(--ui-r, 10px);
|
|
343
|
-
color: var(--ui-muted, var(--md-sys-color-on-surface-variant));
|
|
344
|
-
text-align: center;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/* Row buttons take the action-bar look until @operato/styles ButtonStyles is installed (ADR-0117). */
|
|
348
|
-
td button {
|
|
349
|
-
box-sizing: border-box;
|
|
350
|
-
height: ${actionHeight('--cell-action-height')};
|
|
351
|
-
padding: 0 var(--spacing-medium, 8px);
|
|
352
|
-
border: 1px solid var(--md-sys-color-outline-variant);
|
|
353
|
-
border-radius: var(--md-sys-shape-corner-small);
|
|
354
|
-
background: var(--md-sys-color-surface-container-lowest);
|
|
355
|
-
color: var(--md-sys-color-on-surface);
|
|
356
|
-
font: inherit;
|
|
357
|
-
font-size: var(--ui-t-body, 13px);
|
|
358
|
-
font-weight: 600;
|
|
359
|
-
white-space: nowrap;
|
|
360
|
-
cursor: pointer;
|
|
128
|
+
ox-filters-form {
|
|
129
|
+
flex: 1;
|
|
361
130
|
}
|
|
362
131
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
132
|
+
ox-grist {
|
|
133
|
+
/* Cards of a row stand at one height; a card with an extra fact row does not stick out below the others. */
|
|
134
|
+
--data-card-record-card-height: auto;
|
|
135
|
+
--data-card-thumbnail-aspect: 4 / 3;
|
|
136
|
+
--data-card-thumbnail-background: var(--md-sys-color-surface-container-lowest);
|
|
366
137
|
}
|
|
367
138
|
|
|
368
|
-
td button:disabled {
|
|
369
|
-
opacity: 0.38;
|
|
370
|
-
cursor: default;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
td.end {
|
|
374
|
-
text-align: right;
|
|
375
|
-
}
|
|
376
139
|
`
|
|
377
140
|
]; }
|
|
378
141
|
get context() {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
142
|
+
return {
|
|
143
|
+
title: i18next.t('figure-library.title'),
|
|
144
|
+
search: {
|
|
145
|
+
placeholder: i18next.t('figure-library.text.search'),
|
|
146
|
+
handler: (search) => {
|
|
147
|
+
this.grist.searchText = search;
|
|
148
|
+
},
|
|
149
|
+
value: this.grist?.searchText || ''
|
|
150
|
+
},
|
|
151
|
+
actions: [
|
|
383
152
|
{
|
|
384
153
|
title: i18next.t('figure-library.button.upload'),
|
|
385
154
|
icon: 'upload_file',
|
|
386
155
|
action: () => this.chooseFile(),
|
|
387
|
-
disabled: this.busy,
|
|
388
156
|
emphasis: { raised: true }
|
|
389
157
|
}
|
|
390
158
|
]
|
|
391
|
-
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
render() {
|
|
162
|
+
return html `
|
|
163
|
+
<input id="file" type="file" accept=".figpkg,.zip" hidden @change=${this.importFile} />
|
|
164
|
+
<ox-grist class="page-fill" mode="CARD" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler}>
|
|
165
|
+
<div slot="headroom">
|
|
166
|
+
<ox-filters-form autofocus without-search></ox-filters-form>
|
|
167
|
+
</div>
|
|
168
|
+
</ox-grist>
|
|
169
|
+
`;
|
|
170
|
+
}
|
|
171
|
+
async pageInitialized() {
|
|
172
|
+
await this.configure();
|
|
173
|
+
}
|
|
174
|
+
/*
|
|
175
|
+
* The filter options are read once here (and again after an import), never per render: an async options function
|
|
176
|
+
* runs on every render of the filter bar and replaces the open list's options under the pointer.
|
|
177
|
+
*/
|
|
178
|
+
async configure() {
|
|
179
|
+
const { categories, capabilities } = await this.facets();
|
|
180
|
+
this.gristConfig = {
|
|
181
|
+
list: {
|
|
182
|
+
thumbnail: 'thumbnail',
|
|
183
|
+
fields: ['title', 'meta'],
|
|
184
|
+
details: []
|
|
185
|
+
},
|
|
186
|
+
columns: [
|
|
392
187
|
{
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
/* With no candidate yet, saving is how one is made from the active map — so it stays on. */
|
|
397
|
-
disabled: this.busy || (!dirty && !!candidate)
|
|
188
|
+
type: 'image',
|
|
189
|
+
name: 'thumbnail',
|
|
190
|
+
record: { editable: false, renderEmpty: true, renderer: (_value, _column, record) => this.thumbnailOf(record) }
|
|
398
191
|
},
|
|
399
192
|
{
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
193
|
+
type: 'string',
|
|
194
|
+
name: 'title',
|
|
195
|
+
record: {
|
|
196
|
+
editable: false,
|
|
197
|
+
renderer: (_value, _column, record) => (record.release ?? record.latest).name
|
|
198
|
+
}
|
|
405
199
|
},
|
|
406
200
|
{
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
disabled: !candidate || dirty,
|
|
411
|
-
disabledTitle: dirty ? i18next.t('figure-library.text.save-before-check') : ''
|
|
201
|
+
type: 'string',
|
|
202
|
+
name: 'meta',
|
|
203
|
+
record: { editable: false, renderer: (_value, _column, record) => html `<figure-card-meta .figure=${record}></figure-card-meta>` }
|
|
412
204
|
},
|
|
205
|
+
{ type: 'string', name: 'name', hidden: true, record: { editable: false }, filter: 'search' },
|
|
413
206
|
{
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
207
|
+
type: 'select',
|
|
208
|
+
name: 'category',
|
|
209
|
+
header: i18next.t('figure-library.label.category'),
|
|
210
|
+
hidden: true,
|
|
211
|
+
record: { editable: false },
|
|
212
|
+
filter: { operator: 'eq', options: categories }
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
type: 'select',
|
|
216
|
+
name: 'capability',
|
|
217
|
+
header: i18next.t('figure-library.label.capability'),
|
|
218
|
+
hidden: true,
|
|
219
|
+
record: { editable: false },
|
|
220
|
+
filter: { operator: 'eq', options: capabilities }
|
|
420
221
|
}
|
|
421
|
-
]
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
222
|
+
],
|
|
223
|
+
rows: {
|
|
224
|
+
selectable: false,
|
|
225
|
+
appendable: false,
|
|
226
|
+
handlers: {
|
|
227
|
+
click: (_columns, _data, _column, record) => record && this.openReleases(record)
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
pagination: { pages: [24, 48, 96] }
|
|
427
231
|
};
|
|
428
232
|
}
|
|
429
|
-
|
|
430
|
-
* Opened straight from the address, pageUpdated runs before the page stands and the first read never
|
|
431
|
-
* starts - the screen sat on "loading" (before ox-page-state, on empty tables). pageInitialized reads too.
|
|
432
|
-
*/
|
|
433
|
-
async pageInitialized() {
|
|
434
|
-
await this.enter();
|
|
435
|
-
}
|
|
436
|
-
async pageUpdated(changes, lifecycle) {
|
|
233
|
+
async pageUpdated() {
|
|
437
234
|
if (this.active)
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
async enter() {
|
|
441
|
-
/* ox-url-tabs reads the address on connect but announces only later changes; the body follows the same address. */
|
|
442
|
-
this.tab = new URLSearchParams(location.search).get('tab') === 'type-map' ? 'type-map' : 'library';
|
|
443
|
-
await this.refresh();
|
|
235
|
+
this.grist?.fetch();
|
|
444
236
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
try {
|
|
460
|
-
const [releases, maps] = await Promise.all([
|
|
461
|
-
client.query({ query: RELEASES, fetchPolicy: 'network-only' }),
|
|
462
|
-
client.query({ query: MAPS, fetchPolicy: 'network-only' })
|
|
463
|
-
]);
|
|
464
|
-
if (releases.errors?.length || maps.errors?.length)
|
|
465
|
-
throw releases.errors?.length ? releases.errors : maps.errors;
|
|
466
|
-
this.releases = releases.data.figureLibraryReleases.items;
|
|
467
|
-
this.maps = maps.data.figureTypeMaps;
|
|
468
|
-
const candidate = this.maps.find(map => map.state === 'CANDIDATE') ?? this.maps.find(map => map.state === 'ACTIVE');
|
|
469
|
-
let lines = new Map();
|
|
470
|
-
if (candidate) {
|
|
471
|
-
const entries = await client.query({ query: LINES, variables: { version: candidate.version }, fetchPolicy: 'network-only' });
|
|
472
|
-
lines = new Map(entries.data.figureTypeMapEntries.map((line) => [line.name, line.release?.id]));
|
|
473
|
-
}
|
|
474
|
-
this.candidate = lines;
|
|
475
|
-
this.saved = new Map(lines);
|
|
476
|
-
this.failure = '';
|
|
477
|
-
this.loadError = null;
|
|
478
|
-
}
|
|
479
|
-
catch (e) {
|
|
480
|
-
if (this.loading)
|
|
481
|
-
this.loadError = e;
|
|
482
|
-
else
|
|
483
|
-
this.failure = i18next.t('figure-library.text.load-failed');
|
|
484
|
-
}
|
|
485
|
-
finally {
|
|
486
|
-
this.loading = false;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
render() {
|
|
490
|
-
return html `
|
|
491
|
-
<ox-page-state .loading=${this.loading} .error=${this.loadError} @retry=${() => this.refresh()}>
|
|
492
|
-
<div class="page">
|
|
493
|
-
<ox-url-tabs
|
|
494
|
-
.tabs=${[
|
|
495
|
-
{ key: 'library', label: i18next.t('figure-library.tab.library') },
|
|
496
|
-
{ key: 'type-map', label: i18next.t('figure-library.tab.type-map') }
|
|
497
|
-
]}
|
|
498
|
-
@tab-change=${(e) => (this.tab = e.detail.key)}
|
|
499
|
-
></ox-url-tabs>
|
|
500
|
-
<input id="file" type="file" accept=".figpkg,.zip" hidden @change=${this.importFile} />
|
|
501
|
-
${this.failure ? html `<p class="finding" role="alert">${this.failure}</p>` : nothing}
|
|
502
|
-
${this.tab === 'library' ? this.renderLibrary() : this.renderTypeMap()}
|
|
503
|
-
</div>
|
|
504
|
-
</ox-page-state>
|
|
505
|
-
`;
|
|
237
|
+
/** The filter options, from what the figures that draw carry. */
|
|
238
|
+
async facets() {
|
|
239
|
+
const response = await client.query({ query: FACETS, fetchPolicy: 'network-only' });
|
|
240
|
+
const facets = response.data?.figureLibraryFacets ?? { categories: [], capabilities: [] };
|
|
241
|
+
return {
|
|
242
|
+
categories: [
|
|
243
|
+
...facets.categories.map((value) => ({ display: value, value })),
|
|
244
|
+
...(facets.uncategorized ? [{ display: i18next.t('figure-library.text.no-category'), value: NONE }] : [])
|
|
245
|
+
],
|
|
246
|
+
capabilities: [
|
|
247
|
+
...facets.capabilities.map((value) => ({ display: i18next.t(`figure.label.role-${value}`, { defaultValue: value }), value })),
|
|
248
|
+
...(facets.incapable ? [{ display: i18next.t('figure-library.text.no-capability'), value: NONE }] : [])
|
|
249
|
+
]
|
|
250
|
+
};
|
|
506
251
|
}
|
|
507
|
-
thumbnailOf(
|
|
508
|
-
const hash = release
|
|
252
|
+
thumbnailOf(record) {
|
|
253
|
+
const hash = (record?.release ?? record?.latest)?.dependencies?.find((d) => d.role === 'thumbnail')?.hash;
|
|
509
254
|
if (!hash)
|
|
510
|
-
return
|
|
255
|
+
return html `<figure-thumb-mark .label=${i18next.t('figure-library.text.no-thumbnail')}></figure-thumb-mark>`;
|
|
511
256
|
const { contextPath } = getPathInfo(location.pathname);
|
|
512
|
-
return html `<img
|
|
257
|
+
return html `<img alt="" src=${`${contextPath}/figure-library-file/${hash}`} />`;
|
|
258
|
+
}
|
|
259
|
+
openReleases(record) {
|
|
260
|
+
openPopup(html `<figure-releases-popup .name=${record.name} .drawing=${record.release?.id ?? ''} @saved=${() => this.grist.fetch()}></figure-releases-popup>`, {
|
|
261
|
+
backdrop: true,
|
|
262
|
+
size: 'large',
|
|
263
|
+
title: i18next.t('figure-library.title.releases-of', { name: (record.release ?? record.latest).name, count: record.releaseCount })
|
|
264
|
+
});
|
|
513
265
|
}
|
|
514
266
|
chooseFile() {
|
|
515
267
|
;
|
|
516
268
|
this.renderRoot.querySelector('#file')?.click();
|
|
517
269
|
}
|
|
518
|
-
renderLibrary() {
|
|
519
|
-
return html `
|
|
520
|
-
${this.imported ? this.renderImported(this.imported) : nothing}
|
|
521
|
-
|
|
522
|
-
<section class="page-section">
|
|
523
|
-
<header class="page-section-header">
|
|
524
|
-
<h3>${i18next.t('figure-library.title.releases')}</h3>
|
|
525
|
-
</header>
|
|
526
|
-
${this.releases.length
|
|
527
|
-
? html `<p class="page-section-note">${i18next.t('figure-library.text.release-count', { count: this.releases.length })}</p>
|
|
528
|
-
<table>
|
|
529
|
-
<thead>
|
|
530
|
-
<tr>
|
|
531
|
-
<th></th>
|
|
532
|
-
<th>${i18next.t('figure-library.label.name')}</th>
|
|
533
|
-
<th>${i18next.t('figure-library.label.release')}</th>
|
|
534
|
-
<th>${i18next.t('figure-library.label.source')}</th>
|
|
535
|
-
<th>${i18next.t('figure-library.label.imported-at')}</th>
|
|
536
|
-
<th>${i18next.t('figure-library.label.state')}</th>
|
|
537
|
-
</tr>
|
|
538
|
-
</thead>
|
|
539
|
-
<tbody>
|
|
540
|
-
${this.releases.map(release => html `
|
|
541
|
-
<tr>
|
|
542
|
-
<td class="thumb">${this.thumbnailOf(release)}</td>
|
|
543
|
-
<td>${release.name}<span class="sub ref">${fullName(release)}</span></td>
|
|
544
|
-
<td><span class="ref">${release.ref}</span></td>
|
|
545
|
-
<td>${release.sourceUrl ?? ''}</td>
|
|
546
|
-
<td class="when">${when(release.createdAt)}</td>
|
|
547
|
-
<td>
|
|
548
|
-
<span class="marks">
|
|
549
|
-
${release.formatSupported
|
|
550
|
-
? nothing
|
|
551
|
-
: html `<span class="mark crit">${i18next.t('figure-library.text.format-unsupported')}</span>`}
|
|
552
|
-
${release.deprecated ? html `<span class="mark">${i18next.t('figure-library.text.deprecated')}</span>` : nothing}
|
|
553
|
-
</span>
|
|
554
|
-
</td>
|
|
555
|
-
</tr>
|
|
556
|
-
`)}
|
|
557
|
-
</tbody>
|
|
558
|
-
</table>`
|
|
559
|
-
: html `<p class="empty">${i18next.t('figure-library.text.no-releases')}</p>`}
|
|
560
|
-
</section>
|
|
561
|
-
`;
|
|
562
|
-
}
|
|
563
270
|
renderImported(result) {
|
|
564
271
|
return html `
|
|
565
|
-
<
|
|
566
|
-
<header class="page-section-header">
|
|
567
|
-
<h3>${i18next.t('figure-library.title.import-result')}</h3>
|
|
568
|
-
</header>
|
|
272
|
+
<div style="padding: 16px; display: flex; flex-direction: column; gap: 8px; font-size: var(--ui-t-body, 13px);">
|
|
569
273
|
${result.problems.length
|
|
570
|
-
? html `<p
|
|
274
|
+
? html `<p style="margin: 0; color: var(--ui-crit, var(--md-sys-color-error));" role="alert">
|
|
571
275
|
${i18next.t('figure-library.text.package-refused', { code: result.problems.map(p => p.code).join(', ') })}
|
|
572
276
|
</p>`
|
|
573
|
-
: html `<div
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
: nothing}
|
|
581
|
-
${o.outcome === 'refused' && o.code ? html `<span class="sub">${o.code}</span>` : nothing}
|
|
582
|
-
</li>`)}
|
|
583
|
-
</ul>
|
|
584
|
-
</div>`}
|
|
585
|
-
</section>
|
|
586
|
-
`;
|
|
587
|
-
}
|
|
588
|
-
renderTypeMap() {
|
|
589
|
-
const candidate = this.maps.find(map => map.state === 'CANDIDATE');
|
|
590
|
-
const names = [...new Set(this.releases.map(fullName))].sort();
|
|
591
|
-
const dirty = this.isDirty();
|
|
592
|
-
return html `
|
|
593
|
-
<section class="page-section">
|
|
594
|
-
<header class="page-section-header">
|
|
595
|
-
<h3>${candidate ? i18next.t('figure-library.text.candidate', { name: candidate.name }) : i18next.t('figure-library.text.new-candidate')}</h3>
|
|
596
|
-
</header>
|
|
597
|
-
<p class="page-section-note">
|
|
598
|
-
${dirty
|
|
599
|
-
? i18next.t('figure-library.text.candidate-unsaved')
|
|
600
|
-
: this.report
|
|
601
|
-
? i18next.t('figure-library.text.candidate-checked')
|
|
602
|
-
: i18next.t('figure-library.text.check-before-activate')}
|
|
603
|
-
</p>
|
|
604
|
-
${names.length
|
|
605
|
-
? html `<table>
|
|
606
|
-
<thead>
|
|
607
|
-
<tr>
|
|
608
|
-
<th>${i18next.t('figure-library.label.figure')}</th>
|
|
609
|
-
<th>${i18next.t('figure-library.label.release')}</th>
|
|
610
|
-
</tr>
|
|
611
|
-
</thead>
|
|
612
|
-
<tbody>
|
|
613
|
-
${names.map(name => {
|
|
614
|
-
const versions = this.releases.filter(release => fullName(release) === name).sort((a, b) => b.version - a.version);
|
|
615
|
-
const chosen = this.candidate.get(name) ?? '';
|
|
616
|
-
return html `
|
|
617
|
-
<tr>
|
|
618
|
-
<td><span class="ref">${name}</span></td>
|
|
619
|
-
<td>
|
|
620
|
-
<select @change=${(e) => this.choose(name, e.target.value)}>
|
|
621
|
-
<option value="" ?selected=${!chosen}>${i18next.t('figure-library.text.not-in-map')}</option>
|
|
622
|
-
${versions.map(release => html `<option value=${release.id} ?selected=${chosen === release.id}>${release.ref}</option>`)}
|
|
623
|
-
</select>
|
|
624
|
-
</td>
|
|
625
|
-
</tr>
|
|
626
|
-
`;
|
|
627
|
-
})}
|
|
628
|
-
</tbody>
|
|
629
|
-
</table>`
|
|
630
|
-
: html `<p class="empty">${i18next.t('figure-library.text.no-releases')}</p>`}
|
|
631
|
-
</section>
|
|
632
|
-
|
|
633
|
-
${this.report ? this.renderReport(this.report) : nothing}
|
|
634
|
-
|
|
635
|
-
<section class="page-section">
|
|
636
|
-
<header class="page-section-header">
|
|
637
|
-
<h3>${i18next.t('figure-library.title.map-releases')}</h3>
|
|
638
|
-
</header>
|
|
639
|
-
${this.maps.length
|
|
640
|
-
? html `<table>
|
|
641
|
-
<thead>
|
|
642
|
-
<tr>
|
|
643
|
-
<th>${i18next.t('figure-library.label.type-map')}</th>
|
|
644
|
-
<th>${i18next.t('figure-library.label.state')}</th>
|
|
645
|
-
<th>${i18next.t('figure-library.label.activated-at')}</th>
|
|
646
|
-
<th></th>
|
|
647
|
-
</tr>
|
|
648
|
-
</thead>
|
|
649
|
-
<tbody>
|
|
650
|
-
${this.maps.map(map => html `
|
|
651
|
-
<tr>
|
|
652
|
-
<td>${map.name}</td>
|
|
653
|
-
<td>
|
|
654
|
-
<span class="mark ${map.state === 'ACTIVE' ? 'on' : ''}">${i18next.t(`figure-library.state.${map.state.toLowerCase()}`)}</span>
|
|
655
|
-
</td>
|
|
656
|
-
<td class="when">${when(map.activatedAt)}</td>
|
|
657
|
-
<td class="end">
|
|
658
|
-
${map.state === 'ARCHIVED'
|
|
659
|
-
? html `<button ?disabled=${this.busy} @click=${() => this.activate(map.version)}>
|
|
660
|
-
${i18next.t('figure-library.button.activate-again')}
|
|
661
|
-
</button>`
|
|
662
|
-
: nothing}
|
|
663
|
-
</td>
|
|
664
|
-
</tr>
|
|
665
|
-
`)}
|
|
666
|
-
</tbody>
|
|
667
|
-
</table>`
|
|
668
|
-
: html `<p class="empty">${i18next.t('figure-library.text.no-maps')}</p>`}
|
|
669
|
-
</section>
|
|
670
|
-
`;
|
|
671
|
-
}
|
|
672
|
-
choose(name, releaseId) {
|
|
673
|
-
const next = new Map(this.candidate);
|
|
674
|
-
if (releaseId)
|
|
675
|
-
next.set(name, releaseId);
|
|
676
|
-
else
|
|
677
|
-
next.delete(name);
|
|
678
|
-
this.candidate = next;
|
|
679
|
-
this.report = undefined;
|
|
680
|
-
}
|
|
681
|
-
async activate(version) {
|
|
682
|
-
this.busy = true;
|
|
683
|
-
try {
|
|
684
|
-
await client.mutate({ mutation: ACTIVATE, variables: { version } });
|
|
685
|
-
this.report = undefined;
|
|
686
|
-
await this.refresh();
|
|
687
|
-
}
|
|
688
|
-
catch (e) {
|
|
689
|
-
this.failure = e?.message ?? '';
|
|
690
|
-
}
|
|
691
|
-
finally {
|
|
692
|
-
this.busy = false;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
renderReport(report) {
|
|
696
|
-
const reach = (item) => html `<span class="sub">${i18next.t('figure-library.text.reach', { boards: item.boards, nodes: item.nodes })}</span>`;
|
|
697
|
-
const group = (key, items, line) => items?.length
|
|
698
|
-
? html `<div class="report-group">
|
|
699
|
-
<h4>${i18next.t(`figure-library.check.${key}`)}</h4>
|
|
700
|
-
<ul class="report-list">
|
|
701
|
-
${items.map(item => html `<li>${line(item)}</li>`)}
|
|
702
|
-
</ul>
|
|
703
|
-
</div>`
|
|
704
|
-
: nothing;
|
|
705
|
-
const nothingToReport = ['missing', 'changed', 'added', 'deprecated', 'unsupported', 'dependencies', 'carrierConflicts'].every(key => !report[key]?.length);
|
|
706
|
-
return html `
|
|
707
|
-
<section class="page-section">
|
|
708
|
-
<header class="page-section-header">
|
|
709
|
-
<h3>${i18next.t('figure-library.title.check-report')}</h3>
|
|
710
|
-
</header>
|
|
711
|
-
<div class="page-card">
|
|
712
|
-
${nothingToReport ? html `<p class="sub">${i18next.t('figure-library.check.nothing')}</p>` : nothing}
|
|
713
|
-
${group('missing', report.missing, item => html `<span class="ref">${item.name}</span> ${reach(item)}`)}
|
|
714
|
-
${group('changed', report.changed, item => html `<span class="ref">${item.from}</span> → <span class="ref">${item.to}</span> ${reach(item)}
|
|
715
|
-
${item.contract.checked
|
|
716
|
-
? item.contract.changes.length
|
|
717
|
-
? html `<ul class="changes">
|
|
718
|
-
${item.contract.changes.map((change) => html `<li class=${change.blocking ? 'breaking' : ''}>
|
|
719
|
-
${changeText(change)}${change.blocking ? html ` · ${i18next.t('figure-library.text.breaking')}` : nothing}
|
|
720
|
-
</li>`)}
|
|
721
|
-
</ul>`
|
|
722
|
-
: nothing
|
|
723
|
-
: html `<span class="sub">${i18next.t('figure-library.check.uncheckable')}</span>`}`)}
|
|
724
|
-
${group('added', report.added, item => html `<span class="ref">${item.ref}</span>`)}
|
|
725
|
-
${group('deprecated', report.deprecated, item => html `<span class="ref">${item.ref}</span> ${reach(item)}`)}
|
|
726
|
-
${group('unsupported', report.unsupported, item => html `<span class="ref">${item.ref}</span> ${reach(item)}`)}
|
|
727
|
-
${group('dependencies', report.dependencies, item => html `<span class="ref">${item.ref}</span> ${reach(item)}`)}
|
|
728
|
-
${group('carrierConflicts', report.carrierConflicts, item => html `${item.carrierType} ${item.lines.map((line) => html `<span class="ref">${line.ref}</span> `)}`)}
|
|
729
|
-
</div>
|
|
730
|
-
</section>
|
|
277
|
+
: result.outcomes.map(o => html `<div>
|
|
278
|
+
<span style="font-family: var(--ui-mono, monospace);">${o.ref}</span> ·
|
|
279
|
+
<strong style=${o.outcome === 'refused' ? 'color: var(--ui-crit, var(--md-sys-color-error))' : ''}>${i18next.t(`figure-library.outcome.${o.outcome}`)}</strong>
|
|
280
|
+
${o.differs?.length ? html `<div>${i18next.t('figure-library.text.differs', { fields: o.differs.join(', ') })}</div>` : nothing}
|
|
281
|
+
${o.outcome === 'refused' && o.code ? html `<div>${o.code}</div>` : nothing}
|
|
282
|
+
</div>`)}
|
|
283
|
+
</div>
|
|
731
284
|
`;
|
|
732
285
|
}
|
|
733
286
|
};
|
|
734
|
-
__decorate([
|
|
735
|
-
state(),
|
|
736
|
-
__metadata("design:type", String)
|
|
737
|
-
], FigureLibraryPage.prototype, "tab", void 0);
|
|
738
|
-
__decorate([
|
|
739
|
-
state(),
|
|
740
|
-
__metadata("design:type", Array)
|
|
741
|
-
], FigureLibraryPage.prototype, "releases", void 0);
|
|
742
|
-
__decorate([
|
|
743
|
-
state(),
|
|
744
|
-
__metadata("design:type", Array)
|
|
745
|
-
], FigureLibraryPage.prototype, "maps", void 0);
|
|
746
|
-
__decorate([
|
|
747
|
-
state(),
|
|
748
|
-
__metadata("design:type", Map)
|
|
749
|
-
], FigureLibraryPage.prototype, "candidate", void 0);
|
|
750
|
-
__decorate([
|
|
751
|
-
state(),
|
|
752
|
-
__metadata("design:type", Map)
|
|
753
|
-
], FigureLibraryPage.prototype, "saved", void 0);
|
|
754
287
|
__decorate([
|
|
755
288
|
state(),
|
|
756
289
|
__metadata("design:type", Object)
|
|
757
|
-
], FigureLibraryPage.prototype, "
|
|
290
|
+
], FigureLibraryPage.prototype, "gristConfig", void 0);
|
|
758
291
|
__decorate([
|
|
759
|
-
|
|
760
|
-
__metadata("design:type",
|
|
761
|
-
], FigureLibraryPage.prototype, "
|
|
762
|
-
__decorate([
|
|
763
|
-
state(),
|
|
764
|
-
__metadata("design:type", Object)
|
|
765
|
-
], FigureLibraryPage.prototype, "busy", void 0);
|
|
766
|
-
__decorate([
|
|
767
|
-
state(),
|
|
768
|
-
__metadata("design:type", Object)
|
|
769
|
-
], FigureLibraryPage.prototype, "loading", void 0);
|
|
770
|
-
__decorate([
|
|
771
|
-
state(),
|
|
772
|
-
__metadata("design:type", Object)
|
|
773
|
-
], FigureLibraryPage.prototype, "loadError", void 0);
|
|
774
|
-
__decorate([
|
|
775
|
-
state(),
|
|
776
|
-
__metadata("design:type", Object)
|
|
777
|
-
], FigureLibraryPage.prototype, "failure", void 0);
|
|
292
|
+
query('ox-grist'),
|
|
293
|
+
__metadata("design:type", DataGrist)
|
|
294
|
+
], FigureLibraryPage.prototype, "grist", void 0);
|
|
778
295
|
FigureLibraryPage = __decorate([
|
|
779
296
|
customElement('figure-library-page')
|
|
780
297
|
], FigureLibraryPage);
|