@things-factory/figure-library 10.1.207 → 10.1.210
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/figure-palette-group.d.ts +52 -0
- package/dist-client/figure-palette-group.js +41 -0
- package/dist-client/figure-palette-group.js.map +1 -0
- package/dist-client/figure-palette.d.ts +7 -0
- package/dist-client/figure-palette.js +49 -0
- package/dist-client/figure-palette.js.map +1 -0
- package/dist-client/item-types/index.d.ts +10 -0
- package/dist-client/item-types/index.js +48 -0
- package/dist-client/item-types/index.js.map +1 -0
- package/dist-client/item-types/item-types-editor.d.ts +9 -0
- package/dist-client/item-types/item-types-editor.js +49 -0
- package/dist-client/item-types/item-types-editor.js.map +1 -0
- package/dist-client/item-types/item-types-renderer.d.ts +2 -0
- package/dist-client/item-types/item-types-renderer.js +8 -0
- package/dist-client/item-types/item-types-renderer.js.map +1 -0
- package/dist-client/item-types/item-types-rows.d.ts +16 -0
- package/dist-client/item-types/item-types-rows.js +58 -0
- package/dist-client/item-types/item-types-rows.js.map +1 -0
- package/dist-client/item-types/ox-item-types-input.d.ts +24 -0
- package/dist-client/item-types/ox-item-types-input.js +284 -0
- package/dist-client/item-types/ox-item-types-input.js.map +1 -0
- package/dist-client/pages/figure-library-page.d.ts +3 -3
- package/dist-client/pages/figure-library-page.js +34 -5
- package/dist-client/pages/figure-library-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/figure-releases-popup.d.ts +10 -0
- package/dist-client/viewparts/figure-releases-popup.js +68 -0
- package/dist-client/viewparts/figure-releases-popup.js.map +1 -1
- package/dist-server/service/figure-library-release/figure-library-release.js +2 -2
- package/dist-server/service/figure-library-release/figure-library-release.js.map +1 -1
- package/dist-server/service/figure-library-resolver.d.ts +3 -0
- package/dist-server/service/figure-library-resolver.js +48 -2
- package/dist-server/service/figure-library-resolver.js.map +1 -1
- package/dist-server/service/figure-library-types.d.ts +2 -0
- package/dist-server/service/figure-library-types.js +8 -0
- package/dist-server/service/figure-library-types.js.map +1 -1
- package/dist-server/service/figure-type-map/figure-type-map-entry.d.ts +3 -0
- package/dist-server/service/figure-type-map/figure-type-map-entry.js +21 -0
- package/dist-server/service/figure-type-map/figure-type-map-entry.js.map +1 -1
- package/dist-server/service/library/blueprints.js +4 -0
- package/dist-server/service/library/blueprints.js.map +1 -1
- package/dist-server/service/library/extensions.js +3 -0
- package/dist-server/service/library/extensions.js.map +1 -1
- package/dist-server/service/library/figures.d.ts +8 -0
- package/dist-server/service/library/figures.js +5 -1
- package/dist-server/service/library/figures.js.map +1 -1
- package/dist-server/service/library/inspection.d.ts +1 -1
- package/dist-server/service/library/inspection.js +2 -0
- package/dist-server/service/library/inspection.js.map +1 -1
- package/dist-server/service/library/type-map.d.ts +15 -0
- package/dist-server/service/library/type-map.js +59 -0
- package/dist-server/service/library/type-map.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -8
- package/translations/en.json +27 -2
- package/translations/es.json +27 -2
- package/translations/ja.json +27 -2
- package/translations/ko.json +32 -7
- package/translations/ms.json +27 -2
- package/translations/zh.json +27 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** One line of the domain's type map, as the tray reads it. */
|
|
2
|
+
export interface FigureTypeMapLine {
|
|
3
|
+
name: string;
|
|
4
|
+
/** Whether the domain draws the name as an item a holder holds (ADR-0155 개정 1 E). */
|
|
5
|
+
item?: boolean;
|
|
6
|
+
release?: {
|
|
7
|
+
ref: string;
|
|
8
|
+
name: string;
|
|
9
|
+
formatSupported: boolean;
|
|
10
|
+
assetFormat?: string;
|
|
11
|
+
dependencies?: Array<{
|
|
12
|
+
role: string;
|
|
13
|
+
hash: string;
|
|
14
|
+
}>;
|
|
15
|
+
} | null;
|
|
16
|
+
}
|
|
17
|
+
export interface FigurePaletteTemplate {
|
|
18
|
+
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
group: 'figure';
|
|
21
|
+
/** The release's thumbnail; a modeller's tray template always has the field, undefined when there is none. */
|
|
22
|
+
icon: string | undefined;
|
|
23
|
+
model: {
|
|
24
|
+
type: string;
|
|
25
|
+
left: number;
|
|
26
|
+
top: number;
|
|
27
|
+
};
|
|
28
|
+
unavailableLabel?: string;
|
|
29
|
+
unavailableReason?: string;
|
|
30
|
+
/**
|
|
31
|
+
* The domain draws it as an item a holder holds (ADR-0155 개정 1 E). The platform tray offers it all the same
|
|
32
|
+
* (ADR-0123 결정 11); a modeller whose boards place items only by data leaves it out (fmsim's, where items are carriers).
|
|
33
|
+
*/
|
|
34
|
+
item: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface FigurePaletteGroup {
|
|
37
|
+
name: 'figure';
|
|
38
|
+
description: string;
|
|
39
|
+
icon: string;
|
|
40
|
+
symbol: string;
|
|
41
|
+
templates: FigurePaletteTemplate[];
|
|
42
|
+
}
|
|
43
|
+
/** The lines a board can place now: those with a release in a format this server reads. */
|
|
44
|
+
export declare function placeableFigureTypes(lines: readonly FigureTypeMapLine[]): string[];
|
|
45
|
+
/**
|
|
46
|
+
* The tray group. `contextPath` is where this server's figure files are served from; `t` the app's translator.
|
|
47
|
+
* A line with no release has nothing to draw and is left out.
|
|
48
|
+
*/
|
|
49
|
+
export declare function figurePaletteGroupOf(lines: readonly FigureTypeMapLine[], { contextPath, t }: {
|
|
50
|
+
contextPath: string;
|
|
51
|
+
t: (key: string, options?: Record<string, unknown>) => string;
|
|
52
|
+
}): FigurePaletteGroup;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The modeller tray's "Figure" group, from the domain's figure type map (ADR-0114): one template per line, with the
|
|
3
|
+
* release it draws with. A line whose format this server cannot read is shown dimmed with its reason and cannot be
|
|
4
|
+
* placed. Pure: the lines and the words come in, the group goes out -- `figure-palette.ts` asks the server.
|
|
5
|
+
*/
|
|
6
|
+
/** The lines a board can place now: those with a release in a format this server reads. */
|
|
7
|
+
export function placeableFigureTypes(lines) {
|
|
8
|
+
return lines.filter(line => line.release?.formatSupported).map(line => line.name);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The tray group. `contextPath` is where this server's figure files are served from; `t` the app's translator.
|
|
12
|
+
* A line with no release has nothing to draw and is left out.
|
|
13
|
+
*/
|
|
14
|
+
export function figurePaletteGroupOf(lines, { contextPath, t }) {
|
|
15
|
+
return {
|
|
16
|
+
name: 'figure',
|
|
17
|
+
description: t('figure-library.palette.description'),
|
|
18
|
+
icon: '',
|
|
19
|
+
symbol: 'deployed_code',
|
|
20
|
+
templates: lines
|
|
21
|
+
.filter(line => line.release)
|
|
22
|
+
.map(line => {
|
|
23
|
+
const release = line.release;
|
|
24
|
+
const thumbnail = (release.dependencies ?? []).find(d => d.role === 'thumbnail')?.hash;
|
|
25
|
+
return {
|
|
26
|
+
type: line.name,
|
|
27
|
+
description: release.name,
|
|
28
|
+
group: 'figure',
|
|
29
|
+
icon: thumbnail ? `${contextPath}/figure-library-file/${thumbnail}` : undefined,
|
|
30
|
+
/* No box: placed, the figure takes the size it is made at through the drawing's scale (ADR-0144 2.3). */
|
|
31
|
+
model: { type: line.name, left: 0, top: 0 },
|
|
32
|
+
item: !!line.item,
|
|
33
|
+
...(!release.formatSupported && {
|
|
34
|
+
unavailableLabel: t('figure-library.text.format-unsupported'),
|
|
35
|
+
unavailableReason: t('figure-library.text.cannot-use-format', { format: release.assetFormat })
|
|
36
|
+
})
|
|
37
|
+
};
|
|
38
|
+
})
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=figure-palette-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figure-palette-group.js","sourceRoot":"","sources":["../client/figure-palette-group.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwCH,2FAA2F;AAC3F,MAAM,UAAU,oBAAoB,CAAC,KAAmC;IACtE,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACnF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAmC,EACnC,EAAE,WAAW,EAAE,CAAC,EAA0F;IAE1G,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,CAAC,CAAC,oCAAoC,CAAC;QACpD,IAAI,EAAE,EAAE;QACR,MAAM,EAAE,eAAe;QACvB,SAAS,EAAE,KAAK;aACb,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;aAC5B,GAAG,CAAC,IAAI,CAAC,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,OAAQ,CAAA;YAC7B,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,IAAI,CAAA;YACtF,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,OAAO,CAAC,IAAI;gBACzB,KAAK,EAAE,QAAiB;gBACxB,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,WAAW,wBAAwB,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS;gBAC/E,yGAAyG;gBACzG,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;gBAC3C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI;gBACjB,GAAG,CAAC,CAAC,OAAO,CAAC,eAAe,IAAI;oBAC9B,gBAAgB,EAAE,CAAC,CAAC,wCAAwC,CAAC;oBAC7D,iBAAiB,EAAE,CAAC,CAAC,uCAAuC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;iBAC/F,CAAC;aACH,CAAA;QACH,CAAC,CAAC;KACL,CAAA;AACH,CAAC","sourcesContent":["/*\n * The modeller tray's \"Figure\" group, from the domain's figure type map (ADR-0114): one template per line, with the\n * release it draws with. A line whose format this server cannot read is shown dimmed with its reason and cannot be\n * placed. Pure: the lines and the words come in, the group goes out -- `figure-palette.ts` asks the server.\n */\n\n/** One line of the domain's type map, as the tray reads it. */\nexport interface FigureTypeMapLine {\n name: string\n /** Whether the domain draws the name as an item a holder holds (ADR-0155 개정 1 E). */\n item?: boolean\n release?: {\n ref: string\n name: string\n formatSupported: boolean\n assetFormat?: string\n dependencies?: Array<{ role: string; hash: string }>\n } | null\n}\n\nexport interface FigurePaletteTemplate {\n type: string\n description: string\n group: 'figure'\n /** The release's thumbnail; a modeller's tray template always has the field, undefined when there is none. */\n icon: string | undefined\n model: { type: string; left: number; top: number }\n unavailableLabel?: string\n unavailableReason?: string\n /**\n * The domain draws it as an item a holder holds (ADR-0155 개정 1 E). The platform tray offers it all the same\n * (ADR-0123 결정 11); a modeller whose boards place items only by data leaves it out (fmsim's, where items are carriers).\n */\n item: boolean\n}\n\nexport interface FigurePaletteGroup {\n name: 'figure'\n description: string\n icon: string\n symbol: string\n templates: FigurePaletteTemplate[]\n}\n\n/** The lines a board can place now: those with a release in a format this server reads. */\nexport function placeableFigureTypes(lines: readonly FigureTypeMapLine[]): string[] {\n return lines.filter(line => line.release?.formatSupported).map(line => line.name)\n}\n\n/**\n * The tray group. `contextPath` is where this server's figure files are served from; `t` the app's translator.\n * A line with no release has nothing to draw and is left out.\n */\nexport function figurePaletteGroupOf(\n lines: readonly FigureTypeMapLine[],\n { contextPath, t }: { contextPath: string; t: (key: string, options?: Record<string, unknown>) => string }\n): FigurePaletteGroup {\n return {\n name: 'figure',\n description: t('figure-library.palette.description'),\n icon: '',\n symbol: 'deployed_code',\n templates: lines\n .filter(line => line.release)\n .map(line => {\n const release = line.release!\n const thumbnail = (release.dependencies ?? []).find(d => d.role === 'thumbnail')?.hash\n return {\n type: line.name,\n description: release.name,\n group: 'figure' as const,\n icon: thumbnail ? `${contextPath}/figure-library-file/${thumbnail}` : undefined,\n /* No box: placed, the figure takes the size it is made at through the drawing's scale (ADR-0144 2.3). */\n model: { type: line.name, left: 0, top: 0 },\n item: !!line.item,\n ...(!release.formatSupported && {\n unavailableLabel: t('figure-library.text.format-unsupported'),\n unavailableReason: t('figure-library.text.cannot-use-format', { format: release.assetFormat })\n })\n }\n })\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type FigurePaletteGroup } from './figure-palette-group.js';
|
|
2
|
+
export * from './figure-palette-group.js';
|
|
3
|
+
/**
|
|
4
|
+
* Asks the type map, registers the figures that can be placed, and gives the tray its "Figure" group. A server with no
|
|
5
|
+
* figure library, or a user with no right to read it, gets no group and no error: the tray simply has none.
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerFigurePalette(registerGroup: (group: FigurePaletteGroup) => void): Promise<void>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The figures this board server imported (ADR-0114), in a board modeller's tray. Every app whose boards place library
|
|
3
|
+
* figures calls this once from its bootstrap and hands it its modeller's `registerGroup` -- the tray belongs to the
|
|
4
|
+
* modeller the app uses, and an app may carry its own (fmsim).
|
|
5
|
+
*/
|
|
6
|
+
import gql from 'graphql-tag';
|
|
7
|
+
import { resolveUnknownTypes } from '@hatiolab/things-scene';
|
|
8
|
+
import { client } from '@operato/graphql';
|
|
9
|
+
import { i18next } from '@operato/i18n';
|
|
10
|
+
import { getPathInfo } from '@operato/utils';
|
|
11
|
+
import { figurePaletteGroupOf, placeableFigureTypes } from './figure-palette-group.js';
|
|
12
|
+
export * from './figure-palette-group.js';
|
|
13
|
+
const TYPE_MAP = gql `
|
|
14
|
+
query {
|
|
15
|
+
figureTypeMap {
|
|
16
|
+
name
|
|
17
|
+
item
|
|
18
|
+
release {
|
|
19
|
+
ref
|
|
20
|
+
name
|
|
21
|
+
formatSupported
|
|
22
|
+
assetFormat
|
|
23
|
+
dependencies
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
/**
|
|
29
|
+
* Asks the type map, registers the figures that can be placed, and gives the tray its "Figure" group. A server with no
|
|
30
|
+
* figure library, or a user with no right to read it, gets no group and no error: the tray simply has none.
|
|
31
|
+
*/
|
|
32
|
+
export async function registerFigurePalette(registerGroup) {
|
|
33
|
+
try {
|
|
34
|
+
const lines = (await client.query({ query: TYPE_MAP, fetchPolicy: 'network-only' })).data?.figureTypeMap ?? [];
|
|
35
|
+
/*
|
|
36
|
+
A figure placed from the tray must already be registered: the scene resolves types only when a board opens, and
|
|
37
|
+
a type nobody registered is placed as the stand-in that cannot move. The figure provider registers them now.
|
|
38
|
+
*/
|
|
39
|
+
const placeable = placeableFigureTypes(lines);
|
|
40
|
+
if (placeable.length)
|
|
41
|
+
await resolveUnknownTypes({ components: placeable.map(type => ({ type })) });
|
|
42
|
+
const { contextPath } = getPathInfo(location.pathname);
|
|
43
|
+
registerGroup(figurePaletteGroupOf(lines, { contextPath, t: (key, options) => i18next.t(key, options) }));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
/* No figure library on this server or no right to read it: the tray has no Figure group. */
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=figure-palette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figure-palette.js","sourceRoot":"","sources":["../client/figure-palette.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAmD,MAAM,2BAA2B,CAAA;AAEvI,cAAc,2BAA2B,CAAA;AAEzC,MAAM,QAAQ,GAAG,GAAG,CAAA;;;;;;;;;;;;;;CAcnB,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,aAAkD;IAC5F,IAAI,CAAC;QACH,MAAM,KAAK,GAAwB,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,aAAa,IAAI,EAAE,CAAA;QACnI;;;UAGE;QACF,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;QAC7C,IAAI,SAAS,CAAC,MAAM;YAAE,MAAM,mBAAmB,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;QAElG,MAAM,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACtD,aAAa,CAAC,oBAAoB,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3G,CAAC;IAAC,MAAM,CAAC;QACP,4FAA4F;IAC9F,CAAC;AACH,CAAC","sourcesContent":["/*\n * The figures this board server imported (ADR-0114), in a board modeller's tray. Every app whose boards place library\n * figures calls this once from its bootstrap and hands it its modeller's `registerGroup` -- the tray belongs to the\n * modeller the app uses, and an app may carry its own (fmsim).\n */\nimport gql from 'graphql-tag'\n\nimport { resolveUnknownTypes } from '@hatiolab/things-scene'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { getPathInfo } from '@operato/utils'\n\nimport { figurePaletteGroupOf, placeableFigureTypes, type FigurePaletteGroup, type FigureTypeMapLine } from './figure-palette-group.js'\n\nexport * from './figure-palette-group.js'\n\nconst TYPE_MAP = gql`\n query {\n figureTypeMap {\n name\n item\n release {\n ref\n name\n formatSupported\n assetFormat\n dependencies\n }\n }\n }\n`\n\n/**\n * Asks the type map, registers the figures that can be placed, and gives the tray its \"Figure\" group. A server with no\n * figure library, or a user with no right to read it, gets no group and no error: the tray simply has none.\n */\nexport async function registerFigurePalette(registerGroup: (group: FigurePaletteGroup) => void): Promise<void> {\n try {\n const lines: FigureTypeMapLine[] = (await client.query({ query: TYPE_MAP, fetchPolicy: 'network-only' })).data?.figureTypeMap ?? []\n /*\n A figure placed from the tray must already be registered: the scene resolves types only when a board opens, and\n a type nobody registered is placed as the stand-in that cannot move. The figure provider registers them now.\n */\n const placeable = placeableFigureTypes(lines)\n if (placeable.length) await resolveUnknownTypes({ components: placeable.map(type => ({ type })) })\n\n const { contextPath } = getPathInfo(location.pathname)\n registerGroup(figurePaletteGroupOf(lines, { contextPath, t: (key, options) => i18next.t(key, options) }))\n } catch {\n /* No figure library on this server or no right to read it: the tray has no Figure group. */\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ITEM_TYPES_THEME, type ItemTypeTable } from '@hatiolab/things-scene';
|
|
2
|
+
export { ITEM_TYPES_THEME };
|
|
3
|
+
export * from './item-types-rows.js';
|
|
4
|
+
export declare function registerItemTypesEditor(type?: string): void;
|
|
5
|
+
/**
|
|
6
|
+
* The domain's item type table (ADR-0155): its active theme of the type, read by things-scene's rule. Asked each time a
|
|
7
|
+
* scene opens, so a board opened after the table changed draws by the new one. A server without themes, or a user with
|
|
8
|
+
* no right to read them, gets an empty table.
|
|
9
|
+
*/
|
|
10
|
+
export declare function fetchDomainItemTypes(type?: string): Promise<ItemTypeTable>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Item types (ADR-0155): the domain's table, kept as a theme of type item-types -- or the type an app keeps them under
|
|
3
|
+
* (fmsim, whose items are carriers: carrier-types). An app's bootstrap calls registerItemTypesEditor() once, with its
|
|
4
|
+
* type, so its theme screen edits and shows that type's value.
|
|
5
|
+
*/
|
|
6
|
+
import gql from 'graphql-tag';
|
|
7
|
+
import { registerEditor, registerRenderer } from '@operato/data-grist';
|
|
8
|
+
import { client } from '@operato/graphql';
|
|
9
|
+
import { ITEM_TYPES_THEME, itemTypesFromThemes } from '@hatiolab/things-scene';
|
|
10
|
+
import { OxGristEditorItemTypes } from './item-types-editor.js';
|
|
11
|
+
import { OxGristRendererItemTypes } from './item-types-renderer.js';
|
|
12
|
+
export { ITEM_TYPES_THEME };
|
|
13
|
+
export * from './item-types-rows.js';
|
|
14
|
+
export function registerItemTypesEditor(type = ITEM_TYPES_THEME) {
|
|
15
|
+
registerEditor(type, OxGristEditorItemTypes);
|
|
16
|
+
registerRenderer(type, OxGristRendererItemTypes);
|
|
17
|
+
}
|
|
18
|
+
const ITEM_TYPE_THEMES = gql `
|
|
19
|
+
query ($filters: [Filter!]) {
|
|
20
|
+
themes(filters: $filters) {
|
|
21
|
+
items {
|
|
22
|
+
name
|
|
23
|
+
type
|
|
24
|
+
active
|
|
25
|
+
value
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
/**
|
|
31
|
+
* The domain's item type table (ADR-0155): its active theme of the type, read by things-scene's rule. Asked each time a
|
|
32
|
+
* scene opens, so a board opened after the table changed draws by the new one. A server without themes, or a user with
|
|
33
|
+
* no right to read them, gets an empty table.
|
|
34
|
+
*/
|
|
35
|
+
export async function fetchDomainItemTypes(type = ITEM_TYPES_THEME) {
|
|
36
|
+
try {
|
|
37
|
+
const { data } = await client.query({
|
|
38
|
+
query: ITEM_TYPE_THEMES,
|
|
39
|
+
variables: { filters: [{ name: 'type', operator: 'eq', value: type }] },
|
|
40
|
+
fetchPolicy: 'network-only'
|
|
41
|
+
});
|
|
42
|
+
return itemTypesFromThemes(data?.themes?.items ?? [], type);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return itemTypesFromThemes([], type);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/item-types/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAsB,MAAM,wBAAwB,CAAA;AAElG,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AAEnE,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AAEpC,MAAM,UAAU,uBAAuB,CAAC,OAAe,gBAAgB;IACrE,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAA;IAC5C,gBAAgB,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,gBAAgB,GAAG,GAAG,CAAA;;;;;;;;;;;CAW3B,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAe,gBAAgB;IACxE,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,gBAAgB;YACvB,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE;YACvE,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAA;QACF,OAAO,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,CAAA;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,mBAAmB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IACtC,CAAC;AACH,CAAC","sourcesContent":["/*\n * Item types (ADR-0155): the domain's table, kept as a theme of type item-types -- or the type an app keeps them under\n * (fmsim, whose items are carriers: carrier-types). An app's bootstrap calls registerItemTypesEditor() once, with its\n * type, so its theme screen edits and shows that type's value.\n */\nimport gql from 'graphql-tag'\n\nimport { registerEditor, registerRenderer } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { ITEM_TYPES_THEME, itemTypesFromThemes, type ItemTypeTable } from '@hatiolab/things-scene'\n\nimport { OxGristEditorItemTypes } from './item-types-editor.js'\nimport { OxGristRendererItemTypes } from './item-types-renderer.js'\n\nexport { ITEM_TYPES_THEME }\nexport * from './item-types-rows.js'\n\nexport function registerItemTypesEditor(type: string = ITEM_TYPES_THEME): void {\n registerEditor(type, OxGristEditorItemTypes)\n registerRenderer(type, OxGristRendererItemTypes)\n}\n\nconst ITEM_TYPE_THEMES = gql`\n query ($filters: [Filter!]) {\n themes(filters: $filters) {\n items {\n name\n type\n active\n value\n }\n }\n }\n`\n\n/**\n * The domain's item type table (ADR-0155): its active theme of the type, read by things-scene's rule. Asked each time a\n * scene opens, so a board opened after the table changed draws by the new one. A server without themes, or a user with\n * no right to read them, gets an empty table.\n */\nexport async function fetchDomainItemTypes(type: string = ITEM_TYPES_THEME): Promise<ItemTypeTable> {\n try {\n const { data } = await client.query({\n query: ITEM_TYPE_THEMES,\n variables: { filters: [{ name: 'type', operator: 'eq', value: type }] },\n fetchPolicy: 'network-only'\n })\n return itemTypesFromThemes(data?.themes?.items ?? [], type)\n } catch {\n return itemTypesFromThemes([], type)\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import './ox-item-types-input.js';
|
|
2
|
+
import { OxGristEditor } from '@operato/data-grist';
|
|
3
|
+
export declare class OxGristEditorItemTypes extends OxGristEditor {
|
|
4
|
+
private popup?;
|
|
5
|
+
get editorTemplate(): import("lit-html").TemplateResult<1>;
|
|
6
|
+
_onclick(e: Event): void;
|
|
7
|
+
_onkeydown(e: KeyboardEvent): void;
|
|
8
|
+
openTable(): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
/*
|
|
3
|
+
* The value cell of a theme of type item-types (ADR-0155): shows how many types the table has and opens the table in a
|
|
4
|
+
* popup. The value is written back as it came -- an object, or text for a store that keeps text.
|
|
5
|
+
*/
|
|
6
|
+
import './ox-item-types-input.js';
|
|
7
|
+
import { html } from 'lit';
|
|
8
|
+
import { customElement } from 'lit/decorators.js';
|
|
9
|
+
import { OxGristEditor } from '@operato/data-grist';
|
|
10
|
+
import { i18next } from '@operato/i18n';
|
|
11
|
+
import { openPopup } from '@operato/popup';
|
|
12
|
+
import { rowsOf, valueOf } from './item-types-rows.js';
|
|
13
|
+
let OxGristEditorItemTypes = class OxGristEditorItemTypes extends OxGristEditor {
|
|
14
|
+
get editorTemplate() {
|
|
15
|
+
return html `<div tabindex="0">${i18next.t('figure-library.item-types.count', { count: rowsOf(this.value).length })}</div>`;
|
|
16
|
+
}
|
|
17
|
+
_onclick(e) {
|
|
18
|
+
e.stopPropagation();
|
|
19
|
+
this.openTable();
|
|
20
|
+
}
|
|
21
|
+
_onkeydown(e) {
|
|
22
|
+
if (e.key == 'Enter') {
|
|
23
|
+
e.stopPropagation();
|
|
24
|
+
this.openTable();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
openTable() {
|
|
28
|
+
delete this.popup;
|
|
29
|
+
const asText = typeof this.value === 'string';
|
|
30
|
+
const confirmCallback = (rows) => {
|
|
31
|
+
const value = valueOf(rows);
|
|
32
|
+
this.dispatchEvent(new CustomEvent('field-change', {
|
|
33
|
+
bubbles: true,
|
|
34
|
+
composed: true,
|
|
35
|
+
detail: { before: this.value, after: asText ? JSON.stringify(value) : value, record: this.record, column: this.column, row: this.row }
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
this.popup = openPopup(html `<ox-item-types-input .rows=${rowsOf(this.value)} .confirmCallback=${confirmCallback}></ox-item-types-input>`, {
|
|
39
|
+
backdrop: true,
|
|
40
|
+
size: 'large',
|
|
41
|
+
title: `${i18next.t('figure-library.item-types.title')} : ${this.record?.name ?? ''}`
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
OxGristEditorItemTypes = __decorate([
|
|
46
|
+
customElement('ox-grist-editor-item-types')
|
|
47
|
+
], OxGristEditorItemTypes);
|
|
48
|
+
export { OxGristEditorItemTypes };
|
|
49
|
+
//# sourceMappingURL=item-types-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item-types-editor.js","sourceRoot":"","sources":["../../client/item-types/item-types-editor.ts"],"names":[],"mappings":";AAAA;;;GAGG;AACH,OAAO,0BAA0B,CAAA;AAEjC,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,SAAS,EAAoB,MAAM,gBAAgB,CAAA;AAE5D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAoB,MAAM,sBAAsB,CAAA;AAGjE,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,aAAa;IAGvD,IAAI,cAAc;QAChB,OAAO,IAAI,CAAA,qBAAqB,OAAO,CAAC,CAAC,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAA;IAC5H,CAAC;IAED,QAAQ,CAAC,CAAQ;QACf,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,IAAI,CAAC,SAAS,EAAE,CAAA;IAClB,CAAC;IAED,UAAU,CAAC,CAAgB;QACzB,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,EAAE,CAAC;YACrB,CAAC,CAAC,eAAe,EAAE,CAAA;YACnB,IAAI,CAAC,SAAS,EAAE,CAAA;QAClB,CAAC;IACH,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,KAAK,CAAA;QACjB,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAA;QAC7C,MAAM,eAAe,GAAG,CAAC,IAAmB,EAAE,EAAE;YAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;YAC3B,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,cAAc,EAAE;gBAC9B,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;aACvI,CAAC,CACH,CAAA;QACH,CAAC,CAAA;QACD,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAA,8BAA8B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,eAAe,yBAAyB,EAAE;YACxI,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE;SACtF,CAAC,CAAA;IACJ,CAAC;CACF,CAAA;AAtCY,sBAAsB;IADlC,aAAa,CAAC,4BAA4B,CAAC;GAC/B,sBAAsB,CAsClC","sourcesContent":["/*\n * The value cell of a theme of type item-types (ADR-0155): shows how many types the table has and opens the table in a\n * popup. The value is written back as it came -- an object, or text for a store that keeps text.\n */\nimport './ox-item-types-input.js'\n\nimport { html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { OxGristEditor } from '@operato/data-grist'\nimport { i18next } from '@operato/i18n'\nimport { openPopup, type PopupHandle } from '@operato/popup'\n\nimport { rowsOf, valueOf, type ItemTypeRow } from './item-types-rows.js'\n\n@customElement('ox-grist-editor-item-types')\nexport class OxGristEditorItemTypes extends OxGristEditor {\n private popup?: PopupHandle\n\n get editorTemplate() {\n return html`<div tabindex=\"0\">${i18next.t('figure-library.item-types.count', { count: rowsOf(this.value).length })}</div>`\n }\n\n _onclick(e: Event): void {\n e.stopPropagation()\n this.openTable()\n }\n\n _onkeydown(e: KeyboardEvent): void {\n if (e.key == 'Enter') {\n e.stopPropagation()\n this.openTable()\n }\n }\n\n openTable() {\n delete this.popup\n const asText = typeof this.value === 'string'\n const confirmCallback = (rows: ItemTypeRow[]) => {\n const value = valueOf(rows)\n this.dispatchEvent(\n new CustomEvent('field-change', {\n bubbles: true,\n composed: true,\n detail: { before: this.value, after: asText ? JSON.stringify(value) : value, record: this.record, column: this.column, row: this.row }\n })\n )\n }\n this.popup = openPopup(html`<ox-item-types-input .rows=${rowsOf(this.value)} .confirmCallback=${confirmCallback}></ox-item-types-input>`, {\n backdrop: true,\n size: 'large',\n title: `${i18next.t('figure-library.item-types.title')} : ${this.record?.name ?? ''}`\n })\n }\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/* The value cell of a theme of type item-types, shown: its codes, as many as fit (ADR-0155). */
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
import { rowsOf } from './item-types-rows.js';
|
|
4
|
+
export const OxGristRendererItemTypes = (value) => {
|
|
5
|
+
const codes = rowsOf(value).map(r => r.code).filter(Boolean);
|
|
6
|
+
return html `<span title=${codes.join(', ')}>${codes.join(' · ')}</span>`;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=item-types-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item-types-renderer.js","sourceRoot":"","sources":["../../client/item-types/item-types-renderer.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAI1B,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAE7C,MAAM,CAAC,MAAM,wBAAwB,GAAkB,CAAC,KAAc,EAAE,EAAE;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC5D,OAAO,IAAI,CAAA,eAAe,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAA;AAC1E,CAAC,CAAA","sourcesContent":["/* The value cell of a theme of type item-types, shown: its codes, as many as fit (ADR-0155). */\nimport { html } from 'lit'\n\nimport type { FieldRenderer } from '@operato/data-grist'\n\nimport { rowsOf } from './item-types-rows.js'\n\nexport const OxGristRendererItemTypes: FieldRenderer = (value: unknown) => {\n const codes = rowsOf(value).map(r => r.code).filter(Boolean)\n return html`<span title=${codes.join(', ')}>${codes.join(' · ')}</span>`\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ItemTypeIssue } from '@hatiolab/things-scene';
|
|
2
|
+
/** One row as typed. */
|
|
3
|
+
export interface ItemTypeRow {
|
|
4
|
+
code: string;
|
|
5
|
+
name: string;
|
|
6
|
+
figure: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const emptyRow: () => ItemTypeRow;
|
|
9
|
+
/** The rows of a theme's value; a value given as text (a store that keeps text) is read as JSON. Anything else: none. */
|
|
10
|
+
export declare function rowsOf(value: unknown): ItemTypeRow[];
|
|
11
|
+
/** The value the rows make. Rows with nothing typed are left out. */
|
|
12
|
+
export declare function valueOf(rows: ReadonlyArray<ItemTypeRow>): {
|
|
13
|
+
types: any[];
|
|
14
|
+
};
|
|
15
|
+
/** What does not hold, by row: the issues of things-scene's rule, each on the rows (of those written) it names. */
|
|
16
|
+
export declare function rowIssues(rows: ReadonlyArray<ItemTypeRow>): Map<number, ItemTypeIssue[]>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The item type table as the editor shows it (ADR-0155): one row per type, each cell as typed. The value a theme of
|
|
3
|
+
* type item-types (fmsim: carrier-types) keeps is `{ types: [{ code, name, figure }] }` -- a type has no size
|
|
4
|
+
* (amendment 1); what holds is judged by things-scene's one rule (readItemTypes), so the editor and every scene read a
|
|
5
|
+
* table the same way.
|
|
6
|
+
*/
|
|
7
|
+
import { readItemTypes } from '@hatiolab/things-scene';
|
|
8
|
+
export const emptyRow = () => ({ code: '', name: '', figure: '' });
|
|
9
|
+
const text = (v) => (v === undefined || v === null ? '' : String(v));
|
|
10
|
+
/** The rows of a theme's value; a value given as text (a store that keeps text) is read as JSON. Anything else: none. */
|
|
11
|
+
export function rowsOf(value) {
|
|
12
|
+
let v = value;
|
|
13
|
+
if (typeof v === 'string') {
|
|
14
|
+
try {
|
|
15
|
+
v = JSON.parse(v);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const types = v && typeof v === 'object' && Array.isArray(v.types) ? v.types : [];
|
|
22
|
+
return types.map((t) => ({ code: text(t?.code), name: text(t?.name), figure: text(t?.figure) }));
|
|
23
|
+
}
|
|
24
|
+
/** The value the rows make. Rows with nothing typed are left out. */
|
|
25
|
+
export function valueOf(rows) {
|
|
26
|
+
return {
|
|
27
|
+
types: rows
|
|
28
|
+
.filter(r => Object.values(r).some(c => c.trim() !== ''))
|
|
29
|
+
.map(r => {
|
|
30
|
+
const type = { code: r.code };
|
|
31
|
+
if (r.name.trim())
|
|
32
|
+
type.name = r.name;
|
|
33
|
+
if (r.figure.trim())
|
|
34
|
+
type.figure = r.figure.trim();
|
|
35
|
+
return type;
|
|
36
|
+
})
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** What does not hold, by row: the issues of things-scene's rule, each on the rows (of those written) it names. */
|
|
40
|
+
export function rowIssues(rows) {
|
|
41
|
+
const written = rows.map((r, i) => [r, i]).filter(([r]) => Object.values(r).some(c => c.trim() !== ''));
|
|
42
|
+
const { issues } = readItemTypes(valueOf(rows));
|
|
43
|
+
const byRow = new Map();
|
|
44
|
+
const add = (at, issue) => {
|
|
45
|
+
const row = written[at]?.[1];
|
|
46
|
+
if (row !== undefined)
|
|
47
|
+
byRow.set(row, [...(byRow.get(row) ?? []), issue]);
|
|
48
|
+
};
|
|
49
|
+
for (const issue of issues) {
|
|
50
|
+
if ('at' in issue && typeof issue.at === 'number')
|
|
51
|
+
add(issue.at, issue);
|
|
52
|
+
else if ('at' in issue && Array.isArray(issue.at))
|
|
53
|
+
for (const at of issue.at)
|
|
54
|
+
add(at, issue);
|
|
55
|
+
}
|
|
56
|
+
return byRow;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=item-types-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item-types-rows.js","sourceRoot":"","sources":["../../client/item-types/item-types-rows.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The item type table as the editor shows it (ADR-0155): one row per type, each cell as typed. The value a theme of\n * type item-types (fmsim: carrier-types) keeps is `{ types: [{ code, name, figure }] }` -- a type has no size\n * (amendment 1); what holds is judged by things-scene's one rule (readItemTypes), so the editor and every scene read a\n * table the same way.\n */\nimport { readItemTypes, type ItemTypeIssue } from '@hatiolab/things-scene'\n\n/** One row as typed. */\nexport interface ItemTypeRow {\n code: string\n name: string\n figure: string\n}\n\nexport const emptyRow = (): ItemTypeRow => ({ code: '', name: '', figure: '' })\n\nconst text = (v: unknown) => (v === undefined || v === null ? '' : String(v))\n\n/** The rows of a theme's value; a value given as text (a store that keeps text) is read as JSON. Anything else: none. */\nexport function rowsOf(value: unknown): ItemTypeRow[] {\n let v = value\n if (typeof v === 'string') {\n try {\n v = JSON.parse(v)\n } catch {\n return []\n }\n }\n const types = v && typeof v === 'object' && Array.isArray((v as any).types) ? (v as any).types : []\n return types.map((t: any) => ({ code: text(t?.code), name: text(t?.name), figure: text(t?.figure) }))\n}\n\n/** The value the rows make. Rows with nothing typed are left out. */\nexport function valueOf(rows: ReadonlyArray<ItemTypeRow>): { types: any[] } {\n return {\n types: rows\n .filter(r => Object.values(r).some(c => c.trim() !== ''))\n .map(r => {\n const type: any = { code: r.code }\n if (r.name.trim()) type.name = r.name\n if (r.figure.trim()) type.figure = r.figure.trim()\n return type\n })\n }\n}\n\n/** What does not hold, by row: the issues of things-scene's rule, each on the rows (of those written) it names. */\nexport function rowIssues(rows: ReadonlyArray<ItemTypeRow>): Map<number, ItemTypeIssue[]> {\n const written = rows.map((r, i) => [r, i] as const).filter(([r]) => Object.values(r).some(c => c.trim() !== ''))\n const { issues } = readItemTypes(valueOf(rows))\n const byRow = new Map<number, ItemTypeIssue[]>()\n const add = (at: number, issue: ItemTypeIssue) => {\n const row = written[at]?.[1]\n if (row !== undefined) byRow.set(row, [...(byRow.get(row) ?? []), issue])\n }\n for (const issue of issues) {\n if ('at' in issue && typeof issue.at === 'number') add(issue.at, issue)\n else if ('at' in issue && Array.isArray(issue.at)) for (const at of issue.at) add(at, issue)\n }\n return byRow\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import '@material/web/icon/icon.js';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
import { type ItemTypeRow } from './item-types-rows.js';
|
|
4
|
+
export declare class OxItemTypesInput extends LitElement {
|
|
5
|
+
static styles: import("lit").CSSResult[];
|
|
6
|
+
/** The rows as typed; the popup's own copy (see the note in ox-popup-value-map-input on re-rendered popups). */
|
|
7
|
+
rows: ItemTypeRow[];
|
|
8
|
+
confirmCallback?: (rows: ItemTypeRow[]) => void;
|
|
9
|
+
/** The domain's item figures; null until they are read, empty when the library cannot be read or marks none. */
|
|
10
|
+
private figures;
|
|
11
|
+
/** Thumbnails that could not be drawn: an empty box in their place, not a broken image. */
|
|
12
|
+
private unreadThumbnails;
|
|
13
|
+
connectedCallback(): void;
|
|
14
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
15
|
+
private renderRow;
|
|
16
|
+
private issueText;
|
|
17
|
+
private onInput;
|
|
18
|
+
private onAdd;
|
|
19
|
+
private onRemove;
|
|
20
|
+
private onCancel;
|
|
21
|
+
private onConfirm;
|
|
22
|
+
/** The names the domain's library marks as items, by display name. None when the library cannot be read. */
|
|
23
|
+
private fetchFigures;
|
|
24
|
+
}
|