@fieldia/viewer 0.6.0 → 0.8.0
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/bundle/fieldia.js +36 -62
- package/bundle/fieldia.js.map +4 -4
- package/package.json +3 -3
- package/src/lib/dialog.js +10 -0
- package/src/lib/dialog.js.map +1 -1
- package/src/lib/dialog.mjs +10 -0
- package/src/lib/dialog.mjs.map +1 -1
- package/src/lib/labels.d.mts +43 -0
- package/src/lib/labels.d.ts +43 -0
- package/src/lib/labels.js +128 -0
- package/src/lib/labels.js.map +1 -0
- package/src/lib/labels.mjs +125 -0
- package/src/lib/labels.mjs.map +1 -0
- package/src/lib/related.d.mts +7 -0
- package/src/lib/related.d.ts +7 -0
- package/src/lib/related.js +88 -0
- package/src/lib/related.js.map +1 -0
- package/src/lib/related.mjs +84 -0
- package/src/lib/related.mjs.map +1 -0
- package/src/lib/viewer.d.mts +27 -31
- package/src/lib/viewer.d.ts +27 -31
- package/src/lib/viewer.js +210 -197
- package/src/lib/viewer.js.map +1 -1
- package/src/lib/viewer.mjs +207 -196
- package/src/lib/viewer.mjs.map +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { openFormDialog, openSearchDialog } from './dialog.mjs';
|
|
2
|
+
/** The field a page's records are named by: its title, or "name", or its first line of text. */
|
|
3
|
+
export function nameFieldOf(page) {
|
|
4
|
+
if (page.layout.type === 'sheet' && page.layout.title?.field)
|
|
5
|
+
return page.layout.title.field;
|
|
6
|
+
if (page.fields['name'])
|
|
7
|
+
return 'name';
|
|
8
|
+
return Object.entries(page.fields).find(([, def]) => def.type === 'char')?.[0] ?? null;
|
|
9
|
+
}
|
|
10
|
+
/** A form made of fields, for values edited in a dialog (a line, for one). */
|
|
11
|
+
function valuesPage(fields, title, readonly) {
|
|
12
|
+
const shown = Object.fromEntries(Object.entries(fields).map(([name, def]) => [name, readonly ? { ...def, readonly: true } : def]));
|
|
13
|
+
return {
|
|
14
|
+
fieldia: '0.1',
|
|
15
|
+
id: 'values',
|
|
16
|
+
title,
|
|
17
|
+
data: { kind: 'record', model: 'values' },
|
|
18
|
+
fields: shown,
|
|
19
|
+
layout: {
|
|
20
|
+
type: 'sections',
|
|
21
|
+
id: 'values',
|
|
22
|
+
children: [{ type: 'section', id: 'values-section', columns: 2, children: Object.keys(shown).map((name) => ({ type: 'field', id: `values-${name}`, field: name })) }],
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Only finding and making linked records: values edited in a dialog are no record of the source's to load, save or recalculate. */
|
|
27
|
+
function lookupsOf(source) {
|
|
28
|
+
if (!source)
|
|
29
|
+
return undefined;
|
|
30
|
+
return {
|
|
31
|
+
...(source.search ? { search: (request) => source.search(request) } : {}),
|
|
32
|
+
...(source.create ? { create: (request) => source.create(request) } : {}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** The dialogs a page's widgets may open, made from the viewer's own options. */
|
|
36
|
+
export function pageDialogs(options) {
|
|
37
|
+
const pageFor = (model) => (typeof options.relatedPages === 'function' ? options.relatedPages(model) : options.relatedPages?.[model]) ?? null;
|
|
38
|
+
// A dialog's page looks and reads like the page that opened it, and can open dialogs of its own.
|
|
39
|
+
const shared = {
|
|
40
|
+
locale: options.locale,
|
|
41
|
+
skin: options.skin,
|
|
42
|
+
dir: options.dir,
|
|
43
|
+
widgets: options.widgets,
|
|
44
|
+
preferences: options.preferences,
|
|
45
|
+
relatedPages: options.relatedPages,
|
|
46
|
+
translate: options.translate,
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
canOpen: (model) => pageFor(model) !== null,
|
|
50
|
+
async openRecord(model, request) {
|
|
51
|
+
const related = pageFor(model);
|
|
52
|
+
if (!related)
|
|
53
|
+
return null;
|
|
54
|
+
const nameField = nameFieldOf(related);
|
|
55
|
+
const result = await openFormDialog({
|
|
56
|
+
...shared,
|
|
57
|
+
page: related,
|
|
58
|
+
dataSource: options.dataSource,
|
|
59
|
+
recordId: request.recordId ?? null,
|
|
60
|
+
values: request.name && nameField ? { [nameField]: request.name } : undefined,
|
|
61
|
+
title: request.title,
|
|
62
|
+
size: 'large',
|
|
63
|
+
});
|
|
64
|
+
if (!result.saved || result.recordId === null)
|
|
65
|
+
return null;
|
|
66
|
+
const name = nameField ? result.values[nameField] : null;
|
|
67
|
+
return { id: result.recordId, label: typeof name === 'string' && name ? name : request.name ?? request.title };
|
|
68
|
+
},
|
|
69
|
+
searchMore: (request) => openSearchDialog({ title: request.title, search: request.search, locale: options.locale, skin: options.skin, dir: options.dir }),
|
|
70
|
+
async editValues(request) {
|
|
71
|
+
const result = await openFormDialog({
|
|
72
|
+
...shared,
|
|
73
|
+
page: valuesPage(request.fields, request.title, request.readonly === true),
|
|
74
|
+
dataSource: lookupsOf(options.dataSource),
|
|
75
|
+
values: request.values,
|
|
76
|
+
title: request.title,
|
|
77
|
+
mode: 'values',
|
|
78
|
+
...(request.recompute ? { recompute: request.recompute } : {}),
|
|
79
|
+
});
|
|
80
|
+
return result.saved ? result.values : null;
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=related.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"related.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/related.ts"],"names":[],"mappings":"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"}
|
package/src/lib/viewer.d.mts
CHANGED
|
@@ -1,37 +1,8 @@
|
|
|
1
1
|
import { type Form, type FormOptions, type Page, type Locale } from '@fieldia/core';
|
|
2
2
|
import { type IconSet, type PreferenceStore, type WidgetFactory } from '@fieldia/widgets';
|
|
3
3
|
export type Skin = 'underline' | 'outlined';
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
save: string;
|
|
7
|
-
discard: string;
|
|
8
|
-
saving: string;
|
|
9
|
-
saved: string;
|
|
10
|
-
submit: string;
|
|
11
|
-
next: string;
|
|
12
|
-
back: string;
|
|
13
|
-
/** Passing over an optional step. */
|
|
14
|
-
skip: string;
|
|
15
|
-
/** The list of a wizard's steps, for screen readers. */
|
|
16
|
-
steps: string;
|
|
17
|
-
stepOf: string;
|
|
18
|
-
submitted: string;
|
|
19
|
-
submitAnother: string;
|
|
20
|
-
draftFound: string;
|
|
21
|
-
restore: string;
|
|
22
|
-
discardDraft: string;
|
|
23
|
-
ok: string;
|
|
24
|
-
cancel: string;
|
|
25
|
-
loading: string;
|
|
26
|
-
/** A form in a dialog: the button that saves it and closes the dialog, and the × that closes it. */
|
|
27
|
-
saveClose: string;
|
|
28
|
-
close: string;
|
|
29
|
-
/** The × on an alert that may be dismissed. */
|
|
30
|
-
dismiss: string;
|
|
31
|
-
}
|
|
32
|
-
export declare const VIEWER_LABELS: Record<Locale, ViewerLabels>;
|
|
33
|
-
/** English, kept under its old name. */
|
|
34
|
-
export declare const DEFAULT_LABELS: ViewerLabels;
|
|
4
|
+
import { type ViewerLabels } from './labels.mjs';
|
|
5
|
+
export { VIEWER_LABELS, DEFAULT_LABELS, type ViewerLabels } from './labels.mjs';
|
|
35
6
|
/** Fill a slot with the app's own content. Return a function to clean up. */
|
|
36
7
|
export type SlotRenderer = (element: HTMLElement, context: {
|
|
37
8
|
form: Form;
|
|
@@ -66,6 +37,28 @@ export interface ViewerOptions extends Omit<FormOptions, 'page'> {
|
|
|
66
37
|
* gives them: the inside of a 24×24 SVG, drawn with lines in the text colour.
|
|
67
38
|
*/
|
|
68
39
|
icons?: IconSet;
|
|
40
|
+
/**
|
|
41
|
+
* Keys around the fields. Ctrl+Enter (Cmd+Enter on a Mac) saves, from
|
|
42
|
+
* wherever the cursor is, unless `saveWithCtrlEnter` is false. With
|
|
43
|
+
* `enterMovesToNext`, Enter moves to the next field instead of sending the form.
|
|
44
|
+
*/
|
|
45
|
+
keys?: {
|
|
46
|
+
saveWithCtrlEnter?: boolean;
|
|
47
|
+
enterMovesToNext?: boolean;
|
|
48
|
+
};
|
|
49
|
+
/** A ✓ by a field's label once someone has filled it in and it would pass its checks. */
|
|
50
|
+
showValid?: boolean;
|
|
51
|
+
/** Where a save's progress shows: beside Save (the default), as a toast in a corner, or as a bar across the top. */
|
|
52
|
+
saveStatus?: 'inline' | 'toast' | 'bar';
|
|
53
|
+
/** Show the whole form read-only: every field locked, no Save. Buttons still run. */
|
|
54
|
+
readonly?: boolean;
|
|
55
|
+
/** An Edit button that unlocks a read-only form, and a Done that saves and locks it again. */
|
|
56
|
+
editSwitch?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The app's own translator, for apps that keep translations by text or by
|
|
59
|
+
* key: every word of the page goes through it. Record data never does.
|
|
60
|
+
*/
|
|
61
|
+
translate?: (text: string) => string;
|
|
69
62
|
}
|
|
70
63
|
export interface ViewerHandle {
|
|
71
64
|
readonly form: Form;
|
|
@@ -75,6 +68,9 @@ export interface ViewerHandle {
|
|
|
75
68
|
save(): Promise<boolean>;
|
|
76
69
|
/** Check the form without saving, taking the focus to the first problem. */
|
|
77
70
|
check(): boolean;
|
|
71
|
+
/** Lock or unlock the whole form. */
|
|
72
|
+
setReadonly(readonly: boolean): void;
|
|
73
|
+
isReadonly(): boolean;
|
|
78
74
|
destroy(): void;
|
|
79
75
|
}
|
|
80
76
|
/**
|
package/src/lib/viewer.d.ts
CHANGED
|
@@ -1,37 +1,8 @@
|
|
|
1
1
|
import { type Form, type FormOptions, type Page, type Locale } from '@fieldia/core';
|
|
2
2
|
import { type IconSet, type PreferenceStore, type WidgetFactory } from '@fieldia/widgets';
|
|
3
3
|
export type Skin = 'underline' | 'outlined';
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
save: string;
|
|
7
|
-
discard: string;
|
|
8
|
-
saving: string;
|
|
9
|
-
saved: string;
|
|
10
|
-
submit: string;
|
|
11
|
-
next: string;
|
|
12
|
-
back: string;
|
|
13
|
-
/** Passing over an optional step. */
|
|
14
|
-
skip: string;
|
|
15
|
-
/** The list of a wizard's steps, for screen readers. */
|
|
16
|
-
steps: string;
|
|
17
|
-
stepOf: string;
|
|
18
|
-
submitted: string;
|
|
19
|
-
submitAnother: string;
|
|
20
|
-
draftFound: string;
|
|
21
|
-
restore: string;
|
|
22
|
-
discardDraft: string;
|
|
23
|
-
ok: string;
|
|
24
|
-
cancel: string;
|
|
25
|
-
loading: string;
|
|
26
|
-
/** A form in a dialog: the button that saves it and closes the dialog, and the × that closes it. */
|
|
27
|
-
saveClose: string;
|
|
28
|
-
close: string;
|
|
29
|
-
/** The × on an alert that may be dismissed. */
|
|
30
|
-
dismiss: string;
|
|
31
|
-
}
|
|
32
|
-
export declare const VIEWER_LABELS: Record<Locale, ViewerLabels>;
|
|
33
|
-
/** English, kept under its old name. */
|
|
34
|
-
export declare const DEFAULT_LABELS: ViewerLabels;
|
|
4
|
+
import { type ViewerLabels } from './labels';
|
|
5
|
+
export { VIEWER_LABELS, DEFAULT_LABELS, type ViewerLabels } from './labels';
|
|
35
6
|
/** Fill a slot with the app's own content. Return a function to clean up. */
|
|
36
7
|
export type SlotRenderer = (element: HTMLElement, context: {
|
|
37
8
|
form: Form;
|
|
@@ -66,6 +37,28 @@ export interface ViewerOptions extends Omit<FormOptions, 'page'> {
|
|
|
66
37
|
* gives them: the inside of a 24×24 SVG, drawn with lines in the text colour.
|
|
67
38
|
*/
|
|
68
39
|
icons?: IconSet;
|
|
40
|
+
/**
|
|
41
|
+
* Keys around the fields. Ctrl+Enter (Cmd+Enter on a Mac) saves, from
|
|
42
|
+
* wherever the cursor is, unless `saveWithCtrlEnter` is false. With
|
|
43
|
+
* `enterMovesToNext`, Enter moves to the next field instead of sending the form.
|
|
44
|
+
*/
|
|
45
|
+
keys?: {
|
|
46
|
+
saveWithCtrlEnter?: boolean;
|
|
47
|
+
enterMovesToNext?: boolean;
|
|
48
|
+
};
|
|
49
|
+
/** A ✓ by a field's label once someone has filled it in and it would pass its checks. */
|
|
50
|
+
showValid?: boolean;
|
|
51
|
+
/** Where a save's progress shows: beside Save (the default), as a toast in a corner, or as a bar across the top. */
|
|
52
|
+
saveStatus?: 'inline' | 'toast' | 'bar';
|
|
53
|
+
/** Show the whole form read-only: every field locked, no Save. Buttons still run. */
|
|
54
|
+
readonly?: boolean;
|
|
55
|
+
/** An Edit button that unlocks a read-only form, and a Done that saves and locks it again. */
|
|
56
|
+
editSwitch?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The app's own translator, for apps that keep translations by text or by
|
|
59
|
+
* key: every word of the page goes through it. Record data never does.
|
|
60
|
+
*/
|
|
61
|
+
translate?: (text: string) => string;
|
|
69
62
|
}
|
|
70
63
|
export interface ViewerHandle {
|
|
71
64
|
readonly form: Form;
|
|
@@ -75,6 +68,9 @@ export interface ViewerHandle {
|
|
|
75
68
|
save(): Promise<boolean>;
|
|
76
69
|
/** Check the form without saving, taking the focus to the first problem. */
|
|
77
70
|
check(): boolean;
|
|
71
|
+
/** Lock or unlock the whole form. */
|
|
72
|
+
setReadonly(readonly: boolean): void;
|
|
73
|
+
isReadonly(): boolean;
|
|
78
74
|
destroy(): void;
|
|
79
75
|
}
|
|
80
76
|
/**
|