@cratis/scene.blueprint.default 4.39.0 → 4.41.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/ComponentName.ts +27 -0
- package/defaultBlueprint.ts +1 -0
- package/defaultBlueprintComponents.ts +10 -1
- package/dist/cjs/ComponentName.js +9 -0
- package/dist/cjs/ComponentName.js.map +1 -1
- package/dist/cjs/defaultBlueprint.js +18 -1
- package/dist/cjs/defaultBlueprint.js.map +1 -1
- package/dist/cjs/defaultBlueprintComponentMetadata.js +9 -0
- package/dist/cjs/defaultBlueprintComponentMetadata.js.map +1 -1
- package/dist/cjs/defaultBlueprintComponents.js +28 -1
- package/dist/cjs/defaultBlueprintComponents.js.map +1 -1
- package/dist/cjs/foundation/BulkBar.js +62 -0
- package/dist/cjs/foundation/BulkBar.js.map +1 -0
- package/dist/cjs/foundation/DataList.js +436 -0
- package/dist/cjs/foundation/DataList.js.map +1 -0
- package/dist/cjs/foundation/FormScreenBody.js +447 -0
- package/dist/cjs/foundation/FormScreenBody.js.map +1 -0
- package/dist/cjs/foundation/FoundationStates.js +2 -1
- package/dist/cjs/foundation/FoundationStates.js.map +1 -1
- package/dist/cjs/foundation/GlobalSearch.js +54 -0
- package/dist/cjs/foundation/GlobalSearch.js.map +1 -0
- package/dist/cjs/foundation/KanbanBoard.js +222 -0
- package/dist/cjs/foundation/KanbanBoard.js.map +1 -0
- package/dist/cjs/foundation/NotificationsButton.js +45 -0
- package/dist/cjs/foundation/NotificationsButton.js.map +1 -0
- package/dist/cjs/foundation/SubNavigation.js +72 -0
- package/dist/cjs/foundation/SubNavigation.js.map +1 -0
- package/dist/cjs/foundation/TabSet.js +101 -0
- package/dist/cjs/foundation/TabSet.js.map +1 -0
- package/dist/cjs/foundation/WizardProgress.js +185 -0
- package/dist/cjs/foundation/WizardProgress.js.map +1 -0
- package/dist/cjs/foundation/boardModel.js +67 -0
- package/dist/cjs/foundation/boardModel.js.map +1 -0
- package/dist/cjs/foundation/formModel.js +158 -0
- package/dist/cjs/foundation/formModel.js.map +1 -0
- package/dist/cjs/foundation/foundationComponentMetadata.js +54 -0
- package/dist/cjs/foundation/foundationComponentMetadata.js.map +1 -1
- package/dist/cjs/foundation/foundationDescriptors.js +400 -0
- package/dist/cjs/foundation/foundationDescriptors.js.map +1 -1
- package/dist/cjs/foundation/foundationSamples.js +303 -0
- package/dist/cjs/foundation/foundationSamples.js.map +1 -1
- package/dist/cjs/foundation/foundationStrings.js +72 -0
- package/dist/cjs/foundation/foundationStrings.js.map +1 -1
- package/dist/cjs/foundation/listModel.js +200 -0
- package/dist/cjs/foundation/listModel.js.map +1 -0
- package/dist/cjs/foundation/tabModel.js +41 -0
- package/dist/cjs/foundation/tabModel.js.map +1 -0
- package/dist/cjs/foundation/templates/boardScreenTemplate.js +76 -0
- package/dist/cjs/foundation/templates/boardScreenTemplate.js.map +1 -0
- package/dist/cjs/foundation/templates/dashboardScreenTemplate.js +128 -0
- package/dist/cjs/foundation/templates/dashboardScreenTemplate.js.map +1 -0
- package/dist/cjs/foundation/templates/formScreenTemplate.js +71 -0
- package/dist/cjs/foundation/templates/formScreenTemplate.js.map +1 -0
- package/dist/cjs/foundation/templates/index.js +39 -0
- package/dist/cjs/foundation/templates/index.js.map +1 -0
- package/dist/cjs/foundation/templates/listScreenTemplate.js +124 -0
- package/dist/cjs/foundation/templates/listScreenTemplate.js.map +1 -0
- package/dist/cjs/foundation/templates/masterDetailScreenTemplate.js +79 -0
- package/dist/cjs/foundation/templates/masterDetailScreenTemplate.js.map +1 -0
- package/dist/cjs/foundation/templates/recordPageTemplate.js +137 -0
- package/dist/cjs/foundation/templates/recordPageTemplate.js.map +1 -0
- package/dist/cjs/foundation/templates/templateParts.js +38 -0
- package/dist/cjs/foundation/templates/templateParts.js.map +1 -0
- package/dist/cjs/foundation/templates/wizardScreenTemplate.js +95 -0
- package/dist/cjs/foundation/templates/wizardScreenTemplate.js.map +1 -0
- package/dist/cjs/foundation/templates/workspaceScreenTemplate.js +62 -0
- package/dist/cjs/foundation/templates/workspaceScreenTemplate.js.map +1 -0
- package/dist/cjs/foundation/urlState.js +57 -0
- package/dist/cjs/foundation/urlState.js.map +1 -0
- package/dist/cjs/foundation/useCompactWidth.js +23 -0
- package/dist/cjs/foundation/useCompactWidth.js.map +1 -0
- package/dist/cjs/foundation/wizardModel.js +50 -0
- package/dist/cjs/foundation/wizardModel.js.map +1 -0
- package/dist/cjs/gallery/GalleryScreenPreview.js +76 -4
- package/dist/cjs/gallery/GalleryScreenPreview.js.map +1 -1
- package/dist/cjs/gallery/applicationChrome.js +18 -1
- package/dist/cjs/gallery/applicationChrome.js.map +1 -1
- package/dist/cjs/gallery/composeScreen.js +5 -3
- package/dist/cjs/gallery/composeScreen.js.map +1 -1
- package/dist/cjs/gallery/screens.js +83 -2
- package/dist/cjs/gallery/screens.js.map +1 -1
- package/dist/cjs/index.js +96 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/ComponentName.d.ts +10 -1
- package/dist/esm/ComponentName.d.ts.map +1 -1
- package/dist/esm/ComponentName.js +9 -0
- package/dist/esm/ComponentName.js.map +1 -1
- package/dist/esm/defaultBlueprint.d.ts.map +1 -1
- package/dist/esm/defaultBlueprint.js +18 -1
- package/dist/esm/defaultBlueprint.js.map +1 -1
- package/dist/esm/defaultBlueprintComponentMetadata.js +9 -0
- package/dist/esm/defaultBlueprintComponentMetadata.js.map +1 -1
- package/dist/esm/defaultBlueprintComponents.d.ts.map +1 -1
- package/dist/esm/defaultBlueprintComponents.js +28 -1
- package/dist/esm/defaultBlueprintComponents.js.map +1 -1
- package/dist/esm/foundation/BulkBar.d.ts +4 -0
- package/dist/esm/foundation/BulkBar.d.ts.map +1 -0
- package/dist/esm/foundation/BulkBar.js +59 -0
- package/dist/esm/foundation/BulkBar.js.map +1 -0
- package/dist/esm/foundation/DataList.d.ts +3 -0
- package/dist/esm/foundation/DataList.d.ts.map +1 -0
- package/dist/esm/foundation/DataList.js +434 -0
- package/dist/esm/foundation/DataList.js.map +1 -0
- package/dist/esm/foundation/FormScreenBody.d.ts +3 -0
- package/dist/esm/foundation/FormScreenBody.d.ts.map +1 -0
- package/dist/esm/foundation/FormScreenBody.js +445 -0
- package/dist/esm/foundation/FormScreenBody.js.map +1 -0
- package/dist/esm/foundation/FoundationStates.js +2 -1
- package/dist/esm/foundation/FoundationStates.js.map +1 -1
- package/dist/esm/foundation/GlobalSearch.d.ts +3 -0
- package/dist/esm/foundation/GlobalSearch.d.ts.map +1 -0
- package/dist/esm/foundation/GlobalSearch.js +52 -0
- package/dist/esm/foundation/GlobalSearch.js.map +1 -0
- package/dist/esm/foundation/KanbanBoard.d.ts +3 -0
- package/dist/esm/foundation/KanbanBoard.d.ts.map +1 -0
- package/dist/esm/foundation/KanbanBoard.js +220 -0
- package/dist/esm/foundation/KanbanBoard.js.map +1 -0
- package/dist/esm/foundation/NotificationsButton.d.ts +3 -0
- package/dist/esm/foundation/NotificationsButton.d.ts.map +1 -0
- package/dist/esm/foundation/NotificationsButton.js +43 -0
- package/dist/esm/foundation/NotificationsButton.js.map +1 -0
- package/dist/esm/foundation/SubNavigation.d.ts +3 -0
- package/dist/esm/foundation/SubNavigation.d.ts.map +1 -0
- package/dist/esm/foundation/SubNavigation.js +70 -0
- package/dist/esm/foundation/SubNavigation.js.map +1 -0
- package/dist/esm/foundation/TabSet.d.ts +3 -0
- package/dist/esm/foundation/TabSet.d.ts.map +1 -0
- package/dist/esm/foundation/TabSet.js +99 -0
- package/dist/esm/foundation/TabSet.js.map +1 -0
- package/dist/esm/foundation/WizardProgress.d.ts +3 -0
- package/dist/esm/foundation/WizardProgress.d.ts.map +1 -0
- package/dist/esm/foundation/WizardProgress.js +183 -0
- package/dist/esm/foundation/WizardProgress.js.map +1 -0
- package/dist/esm/foundation/boardModel.d.ts +22 -0
- package/dist/esm/foundation/boardModel.d.ts.map +1 -0
- package/dist/esm/foundation/boardModel.js +61 -0
- package/dist/esm/foundation/boardModel.js.map +1 -0
- package/dist/esm/foundation/formModel.d.ts +48 -0
- package/dist/esm/foundation/formModel.d.ts.map +1 -0
- package/dist/esm/foundation/formModel.js +147 -0
- package/dist/esm/foundation/formModel.js.map +1 -0
- package/dist/esm/foundation/foundationComponentMetadata.d.ts.map +1 -1
- package/dist/esm/foundation/foundationComponentMetadata.js +54 -0
- package/dist/esm/foundation/foundationComponentMetadata.js.map +1 -1
- package/dist/esm/foundation/foundationDescriptors.d.ts.map +1 -1
- package/dist/esm/foundation/foundationDescriptors.js +400 -0
- package/dist/esm/foundation/foundationDescriptors.js.map +1 -1
- package/dist/esm/foundation/foundationSamples.d.ts.map +1 -1
- package/dist/esm/foundation/foundationSamples.js +303 -0
- package/dist/esm/foundation/foundationSamples.js.map +1 -1
- package/dist/esm/foundation/foundationStrings.d.ts +72 -0
- package/dist/esm/foundation/foundationStrings.d.ts.map +1 -1
- package/dist/esm/foundation/foundationStrings.js +72 -0
- package/dist/esm/foundation/foundationStrings.js.map +1 -1
- package/dist/esm/foundation/index.d.ts +17 -0
- package/dist/esm/foundation/index.d.ts.map +1 -1
- package/dist/esm/foundation/index.js +17 -0
- package/dist/esm/foundation/index.js.map +1 -1
- package/dist/esm/foundation/listModel.d.ts +49 -0
- package/dist/esm/foundation/listModel.d.ts.map +1 -0
- package/dist/esm/foundation/listModel.js +183 -0
- package/dist/esm/foundation/listModel.js.map +1 -0
- package/dist/esm/foundation/tabModel.d.ts +10 -0
- package/dist/esm/foundation/tabModel.d.ts.map +1 -0
- package/dist/esm/foundation/tabModel.js +37 -0
- package/dist/esm/foundation/tabModel.js.map +1 -0
- package/dist/esm/foundation/templates/boardScreenTemplate.d.ts +3 -0
- package/dist/esm/foundation/templates/boardScreenTemplate.d.ts.map +1 -0
- package/dist/esm/foundation/templates/boardScreenTemplate.js +74 -0
- package/dist/esm/foundation/templates/boardScreenTemplate.js.map +1 -0
- package/dist/esm/foundation/templates/dashboardScreenTemplate.d.ts +3 -0
- package/dist/esm/foundation/templates/dashboardScreenTemplate.d.ts.map +1 -0
- package/dist/esm/foundation/templates/dashboardScreenTemplate.js +126 -0
- package/dist/esm/foundation/templates/dashboardScreenTemplate.js.map +1 -0
- package/dist/esm/foundation/templates/formScreenTemplate.d.ts +3 -0
- package/dist/esm/foundation/templates/formScreenTemplate.d.ts.map +1 -0
- package/dist/esm/foundation/templates/formScreenTemplate.js +69 -0
- package/dist/esm/foundation/templates/formScreenTemplate.js.map +1 -0
- package/dist/esm/foundation/templates/index.d.ts +11 -0
- package/dist/esm/foundation/templates/index.d.ts.map +1 -0
- package/dist/esm/foundation/templates/index.js +25 -0
- package/dist/esm/foundation/templates/index.js.map +1 -0
- package/dist/esm/foundation/templates/listScreenTemplate.d.ts +3 -0
- package/dist/esm/foundation/templates/listScreenTemplate.d.ts.map +1 -0
- package/dist/esm/foundation/templates/listScreenTemplate.js +122 -0
- package/dist/esm/foundation/templates/listScreenTemplate.js.map +1 -0
- package/dist/esm/foundation/templates/masterDetailScreenTemplate.d.ts +3 -0
- package/dist/esm/foundation/templates/masterDetailScreenTemplate.d.ts.map +1 -0
- package/dist/esm/foundation/templates/masterDetailScreenTemplate.js +77 -0
- package/dist/esm/foundation/templates/masterDetailScreenTemplate.js.map +1 -0
- package/dist/esm/foundation/templates/recordPageTemplate.d.ts +3 -0
- package/dist/esm/foundation/templates/recordPageTemplate.d.ts.map +1 -0
- package/dist/esm/foundation/templates/recordPageTemplate.js +135 -0
- package/dist/esm/foundation/templates/recordPageTemplate.js.map +1 -0
- package/dist/esm/foundation/templates/templateParts.d.ts +6 -0
- package/dist/esm/foundation/templates/templateParts.d.ts.map +1 -0
- package/dist/esm/foundation/templates/templateParts.js +33 -0
- package/dist/esm/foundation/templates/templateParts.js.map +1 -0
- package/dist/esm/foundation/templates/wizardScreenTemplate.d.ts +3 -0
- package/dist/esm/foundation/templates/wizardScreenTemplate.d.ts.map +1 -0
- package/dist/esm/foundation/templates/wizardScreenTemplate.js +93 -0
- package/dist/esm/foundation/templates/wizardScreenTemplate.js.map +1 -0
- package/dist/esm/foundation/templates/workspaceScreenTemplate.d.ts +3 -0
- package/dist/esm/foundation/templates/workspaceScreenTemplate.d.ts.map +1 -0
- package/dist/esm/foundation/templates/workspaceScreenTemplate.js +60 -0
- package/dist/esm/foundation/templates/workspaceScreenTemplate.js.map +1 -0
- package/dist/esm/foundation/urlState.d.ts +4 -0
- package/dist/esm/foundation/urlState.d.ts.map +1 -0
- package/dist/esm/foundation/urlState.js +53 -0
- package/dist/esm/foundation/urlState.js.map +1 -0
- package/dist/esm/foundation/useCompactWidth.d.ts +3 -0
- package/dist/esm/foundation/useCompactWidth.d.ts.map +1 -0
- package/dist/esm/foundation/useCompactWidth.js +20 -0
- package/dist/esm/foundation/useCompactWidth.js.map +1 -0
- package/dist/esm/foundation/wizardModel.d.ts +16 -0
- package/dist/esm/foundation/wizardModel.d.ts.map +1 -0
- package/dist/esm/foundation/wizardModel.js +43 -0
- package/dist/esm/foundation/wizardModel.js.map +1 -0
- package/dist/esm/gallery/GalleryScreenPreview.d.ts +13 -2
- package/dist/esm/gallery/GalleryScreenPreview.d.ts.map +1 -1
- package/dist/esm/gallery/GalleryScreenPreview.js +75 -5
- package/dist/esm/gallery/GalleryScreenPreview.js.map +1 -1
- package/dist/esm/gallery/applicationChrome.d.ts.map +1 -1
- package/dist/esm/gallery/applicationChrome.js +18 -1
- package/dist/esm/gallery/applicationChrome.js.map +1 -1
- package/dist/esm/gallery/composeScreen.d.ts.map +1 -1
- package/dist/esm/gallery/composeScreen.js +5 -3
- package/dist/esm/gallery/composeScreen.js.map +1 -1
- package/dist/esm/gallery/screens.d.ts.map +1 -1
- package/dist/esm/gallery/screens.js +83 -2
- package/dist/esm/gallery/screens.js.map +1 -1
- package/dist/esm/index.js +27 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/foundation/BulkBar.tsx +38 -0
- package/foundation/DataList.tsx +208 -0
- package/foundation/FormScreenBody.tsx +196 -0
- package/foundation/FoundationStates.tsx +1 -1
- package/foundation/GlobalSearch.tsx +33 -0
- package/foundation/KanbanBoard.tsx +97 -0
- package/foundation/NotificationsButton.tsx +28 -0
- package/foundation/SubNavigation.tsx +49 -0
- package/foundation/TabSet.tsx +65 -0
- package/foundation/WizardProgress.tsx +109 -0
- package/foundation/boardModel.ts +64 -0
- package/foundation/formModel.ts +146 -0
- package/foundation/foundationComponentMetadata.ts +9 -0
- package/foundation/foundationDescriptors.ts +195 -0
- package/foundation/foundationSamples.ts +56 -0
- package/foundation/foundationStrings.ts +72 -0
- package/foundation/index.ts +17 -0
- package/foundation/listModel.ts +190 -0
- package/foundation/tabModel.ts +41 -0
- package/foundation/templates/boardScreenTemplate.ts +28 -0
- package/foundation/templates/dashboardScreenTemplate.ts +37 -0
- package/foundation/templates/formScreenTemplate.ts +28 -0
- package/foundation/templates/index.ts +26 -0
- package/foundation/templates/listScreenTemplate.ts +37 -0
- package/foundation/templates/masterDetailScreenTemplate.ts +28 -0
- package/foundation/templates/recordPageTemplate.ts +36 -0
- package/foundation/templates/templateParts.ts +30 -0
- package/foundation/templates/wizardScreenTemplate.ts +33 -0
- package/foundation/templates/workspaceScreenTemplate.ts +27 -0
- package/foundation/urlState.ts +52 -0
- package/foundation/useCompactWidth.ts +23 -0
- package/foundation/wizardModel.ts +54 -0
- package/gallery/GalleryScreenPreview.tsx +64 -5
- package/gallery/applicationChrome.ts +6 -1
- package/gallery/composeScreen.ts +4 -2
- package/gallery/screens.ts +16 -1
- package/package.json +10 -8
- package/sampleData/foundation-en.json +512 -0
- package/shell/layout.css +513 -0
- package/thumbnails/BoardScreen.svg +15 -0
- package/thumbnails/DashboardScreen.svg +18 -0
- package/thumbnails/FormScreen.svg +14 -0
- package/thumbnails/ListScreen.svg +16 -0
- package/thumbnails/MasterDetailScreen.svg +22 -0
- package/thumbnails/RecordPage.svg +17 -0
- package/thumbnails/WizardScreen.svg +16 -0
- package/thumbnails/WorkspaceScreen.svg +12 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
/** How a column's cell is drawn. */ var CellKind = /*#__PURE__*/ function(CellKind) {
|
|
4
|
+
CellKind["Text"] = "text";
|
|
5
|
+
CellKind["Number"] = "number";
|
|
6
|
+
CellKind["Currency"] = "currency";
|
|
7
|
+
CellKind["Date"] = "date";
|
|
8
|
+
CellKind["Status"] = "status";
|
|
9
|
+
return CellKind;
|
|
10
|
+
}({});
|
|
11
|
+
/** The ways the same records can be laid out. */ var ListVariant = /*#__PURE__*/ function(ListVariant) {
|
|
12
|
+
ListVariant["Table"] = "table";
|
|
13
|
+
ListVariant["Cards"] = "cards";
|
|
14
|
+
ListVariant["Grouped"] = "grouped";
|
|
15
|
+
return ListVariant;
|
|
16
|
+
}({});
|
|
17
|
+
const records = (value)=>Array.isArray(value) ? value.filter((entry)=>typeof entry === 'object' && entry !== null && !Array.isArray(entry)) : [];
|
|
18
|
+
/** Reads columns, dropping those without a field and repeated fields. */ function readListColumns(value) {
|
|
19
|
+
const seen = new Set();
|
|
20
|
+
return records(value).flatMap((entry)=>{
|
|
21
|
+
if (typeof entry.field !== 'string' || entry.field.length === 0 || seen.has(entry.field)) return [];
|
|
22
|
+
seen.add(entry.field);
|
|
23
|
+
const tones = typeof entry.tones === 'object' && entry.tones !== null && !Array.isArray(entry.tones) ? Object.fromEntries(Object.entries(entry.tones).filter((pair)=>typeof pair[1] === 'string')) : {};
|
|
24
|
+
return [
|
|
25
|
+
{
|
|
26
|
+
field: entry.field,
|
|
27
|
+
header: typeof entry.header === 'string' && entry.header.length > 0 ? entry.header : entry.field,
|
|
28
|
+
kind: Object.values(CellKind).includes(entry.kind) ? entry.kind : "text",
|
|
29
|
+
sortable: entry.sortable !== false,
|
|
30
|
+
tones,
|
|
31
|
+
...typeof entry.currency === 'string' ? {
|
|
32
|
+
currency: entry.currency
|
|
33
|
+
} : {}
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/** Reads the variant, defaulting to the table. */ const readListVariant = (value)=>Object.values(ListVariant).includes(value) ? value : "table";
|
|
39
|
+
/** The value of a row's field as text for searching and display: a primitive as itself, anything else empty. */ const textOf = (row, field)=>{
|
|
40
|
+
const value = row[field];
|
|
41
|
+
return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';
|
|
42
|
+
};
|
|
43
|
+
/** The id of a row: its `idField`, else its position, so a list without ids still selects and keys sensibly. */ const rowId = (row, index, idField)=>{
|
|
44
|
+
const value = row[idField];
|
|
45
|
+
return typeof value === 'string' || typeof value === 'number' ? String(value) : `row-${index}`;
|
|
46
|
+
};
|
|
47
|
+
/** Rows that contain the search text in any shown column, without regard to case or accents; empty search keeps every row. */ function searchRows(rows, columns, search) {
|
|
48
|
+
const needle = normalize(search);
|
|
49
|
+
if (needle.length === 0) return rows;
|
|
50
|
+
return rows.filter((row)=>columns.some((column)=>normalize(textOf(row, column.field)).includes(needle)));
|
|
51
|
+
}
|
|
52
|
+
/** Rows that satisfy a filter of conditions joined by AND or OR, in nested groups - the value the filter builder publishes. */ function filterRows(rows, filter) {
|
|
53
|
+
if (typeof filter !== 'object' || filter === null) return rows;
|
|
54
|
+
const group = filter;
|
|
55
|
+
const tests = [
|
|
56
|
+
...(group.conditions ?? []).filter((condition)=>typeof condition?.field === 'string').filter(active).map((condition)=>(row)=>satisfies(row, condition)),
|
|
57
|
+
...(group.groups ?? []).filter((nested)=>hasConditions(nested)).map((nested)=>(row)=>filterRows([
|
|
58
|
+
row
|
|
59
|
+
], nested).length === 1)
|
|
60
|
+
];
|
|
61
|
+
if (tests.length === 0) return rows;
|
|
62
|
+
return rows.filter((row)=>group.operator === 'or' ? tests.some((test)=>test(row)) : tests.every((test)=>test(row)));
|
|
63
|
+
}
|
|
64
|
+
const active = (condition)=>[
|
|
65
|
+
'isEmpty',
|
|
66
|
+
'true',
|
|
67
|
+
'false'
|
|
68
|
+
].includes(condition.operator) || (condition.value ?? '').trim().length > 0;
|
|
69
|
+
const hasConditions = (group)=>{
|
|
70
|
+
const candidate = group;
|
|
71
|
+
return (candidate?.conditions ?? []).some(active) || (candidate?.groups ?? []).some(hasConditions);
|
|
72
|
+
};
|
|
73
|
+
function satisfies(row, condition) {
|
|
74
|
+
const raw = row[condition.field];
|
|
75
|
+
const text = normalize(typeof raw === 'string' || typeof raw === 'number' || typeof raw === 'boolean' ? String(raw) : '');
|
|
76
|
+
const value = normalize(condition.value ?? '');
|
|
77
|
+
const number = Number(raw);
|
|
78
|
+
const wanted = Number(condition.value);
|
|
79
|
+
switch(condition.operator){
|
|
80
|
+
case 'contains':
|
|
81
|
+
return text.includes(value);
|
|
82
|
+
case 'equals':
|
|
83
|
+
case 'is':
|
|
84
|
+
case 'on':
|
|
85
|
+
return typeof raw === 'number' ? number === wanted : text === value;
|
|
86
|
+
case 'notEquals':
|
|
87
|
+
case 'isNot':
|
|
88
|
+
return typeof raw === 'number' ? number !== wanted : text !== value;
|
|
89
|
+
case 'startsWith':
|
|
90
|
+
return text.startsWith(value);
|
|
91
|
+
case 'isEmpty':
|
|
92
|
+
return text.length === 0;
|
|
93
|
+
case 'greater':
|
|
94
|
+
return number > wanted;
|
|
95
|
+
case 'greaterOrEqual':
|
|
96
|
+
return number >= wanted;
|
|
97
|
+
case 'less':
|
|
98
|
+
return number < wanted;
|
|
99
|
+
case 'lessOrEqual':
|
|
100
|
+
return number <= wanted;
|
|
101
|
+
case 'before':
|
|
102
|
+
return text < value;
|
|
103
|
+
case 'after':
|
|
104
|
+
return text > value;
|
|
105
|
+
case 'true':
|
|
106
|
+
return raw === true || text === 'true';
|
|
107
|
+
case 'false':
|
|
108
|
+
return raw === false || text === 'false';
|
|
109
|
+
default:
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function normalize(text) {
|
|
114
|
+
return text.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLocaleLowerCase();
|
|
115
|
+
}
|
|
116
|
+
/** Reads a sort from its address form, `field` or `-field` for descending; a field that is not a sortable column is no sort at all. */ function parseSort(text, columns) {
|
|
117
|
+
if (!text) return undefined;
|
|
118
|
+
const descending = text.startsWith('-');
|
|
119
|
+
const field = descending ? text.slice(1) : text;
|
|
120
|
+
return columns.some((column)=>column.field === field && column.sortable) ? {
|
|
121
|
+
field,
|
|
122
|
+
descending
|
|
123
|
+
} : undefined;
|
|
124
|
+
}
|
|
125
|
+
/** A sort in its address form. */ const formatSort = (sort)=>sort === undefined ? undefined : `${sort.descending ? '-' : ''}${sort.field}`;
|
|
126
|
+
/** The next sort when a header is pressed: ascending, then descending, then none. */ const nextSort = (current, field)=>current?.field !== field ? {
|
|
127
|
+
field,
|
|
128
|
+
descending: false
|
|
129
|
+
} : current.descending ? undefined : {
|
|
130
|
+
field,
|
|
131
|
+
descending: true
|
|
132
|
+
};
|
|
133
|
+
/** Rows in order of a column, numbers as numbers and text by the locale, with ties kept in their original order. */ function sortRows(rows, sort, locale) {
|
|
134
|
+
if (!sort) return rows;
|
|
135
|
+
const collator = new Intl.Collator(locale, {
|
|
136
|
+
numeric: true,
|
|
137
|
+
sensitivity: 'base'
|
|
138
|
+
});
|
|
139
|
+
return rows.map((row, index)=>({
|
|
140
|
+
row,
|
|
141
|
+
index
|
|
142
|
+
})).sort((left, right)=>{
|
|
143
|
+
const a = left.row[sort.field];
|
|
144
|
+
const b = right.row[sort.field];
|
|
145
|
+
const order = typeof a === 'number' && typeof b === 'number' ? a - b : collator.compare(textOf(left.row, sort.field), textOf(right.row, sort.field));
|
|
146
|
+
return order === 0 ? left.index - right.index : sort.descending ? -order : order;
|
|
147
|
+
}).map((entry)=>entry.row);
|
|
148
|
+
}
|
|
149
|
+
/** The slice of rows on a page (1-based), and how many pages there are; a page out of range is clamped rather than empty. */ function paginate(rows, page, pageSize) {
|
|
150
|
+
const size = pageSize > 0 ? Math.floor(pageSize) : rows.length || 1;
|
|
151
|
+
const pages = Math.max(1, Math.ceil(rows.length / size));
|
|
152
|
+
const clamped = Math.min(Math.max(1, Math.floor(Number.isFinite(page) ? page : 1)), pages);
|
|
153
|
+
return {
|
|
154
|
+
rows: rows.slice((clamped - 1) * size, clamped * size),
|
|
155
|
+
page: clamped,
|
|
156
|
+
pages
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/** Groups rows by a field in the order the groups are first seen, with the sum of a numeric field as the subtotal when one is named. */ function groupRows(rows, groupBy, totalField) {
|
|
160
|
+
const groups = [];
|
|
161
|
+
for (const row of rows){
|
|
162
|
+
const key = textOf(row, groupBy);
|
|
163
|
+
const group = groups.find((candidate)=>candidate.key === key) ?? (groups.push({
|
|
164
|
+
key,
|
|
165
|
+
rows: []
|
|
166
|
+
}), groups[groups.length - 1]);
|
|
167
|
+
group.rows.push(row);
|
|
168
|
+
}
|
|
169
|
+
return totalField === undefined ? groups : groups.map((group)=>({
|
|
170
|
+
...group,
|
|
171
|
+
subtotal: group.rows.reduce((sum, row)=>sum + (typeof row[totalField] === 'number' ? row[totalField] : 0), 0)
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
/** Toggles an id in a selection that allows one or many. */ const toggleSelection = (selected, id, multiple)=>selected.includes(id) ? selected.filter((candidate)=>candidate !== id) : multiple ? [
|
|
175
|
+
...selected,
|
|
176
|
+
id
|
|
177
|
+
] : [
|
|
178
|
+
id
|
|
179
|
+
];
|
|
180
|
+
/** Reads a selection from its address form: ids separated by commas. */ const parseSelection = (text)=>text ? text.split(',').filter((id)=>id.length > 0) : [];
|
|
181
|
+
|
|
182
|
+
export { CellKind, ListVariant, filterRows, formatSort, groupRows, nextSort, paginate, parseSelection, parseSort, readListColumns, readListVariant, rowId, searchRows, sortRows, textOf, toggleSelection };
|
|
183
|
+
//# sourceMappingURL=listModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listModel.js","sources":["../../../foundation/listModel.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/** How a column's cell is drawn. */\nexport enum CellKind {\n Text = 'text',\n Number = 'number',\n Currency = 'currency',\n Date = 'date',\n Status = 'status',\n}\n\n/** One column of a list. */\nexport interface ListColumn {\n field: string;\n header: string;\n kind: CellKind;\n sortable: boolean;\n /** For a status column: the tone of each value (`success`, `warning`, `danger`, `info`, `neutral`). */\n tones: Record<string, string>;\n /** For a currency column: the ISO 4217 code. */\n currency?: string;\n}\n\n/** One record of a list, with the field values as the query returned them. */\nexport type ListRow = Record<string, unknown>;\n\n/** How the list is sorted. */\nexport interface ListSort {\n field: string;\n descending: boolean;\n}\n\n/** The ways the same records can be laid out. */\nexport enum ListVariant {\n Table = 'table',\n Cards = 'cards',\n Grouped = 'grouped',\n}\n\nconst records = (value: unknown): Record<string, unknown>[] =>\n Array.isArray(value) ? value.filter((entry): entry is Record<string, unknown> => typeof entry === 'object' && entry !== null && !Array.isArray(entry)) : [];\n\n/** Reads columns, dropping those without a field and repeated fields. */\nexport function readListColumns(value: unknown): ListColumn[] {\n const seen = new Set<string>();\n return records(value).flatMap(entry => {\n if (typeof entry.field !== 'string' || entry.field.length === 0 || seen.has(entry.field)) return [];\n seen.add(entry.field);\n const tones = typeof entry.tones === 'object' && entry.tones !== null && !Array.isArray(entry.tones)\n ? Object.fromEntries(Object.entries(entry.tones as Record<string, unknown>).filter((pair): pair is [string, string] => typeof pair[1] === 'string')) : {};\n return [{\n field: entry.field,\n header: typeof entry.header === 'string' && entry.header.length > 0 ? entry.header : entry.field,\n kind: (Object.values(CellKind) as string[]).includes(entry.kind as string) ? (entry.kind as CellKind) : CellKind.Text,\n sortable: entry.sortable !== false,\n tones,\n ...(typeof entry.currency === 'string' ? { currency: entry.currency } : {}),\n }];\n });\n}\n\n/** Reads the variant, defaulting to the table. */\nexport const readListVariant = (value: unknown): ListVariant => ((Object.values(ListVariant) as string[]).includes(value as string) ? (value as ListVariant) : ListVariant.Table);\n\n/** The value of a row's field as text for searching and display: a primitive as itself, anything else empty. */\nexport const textOf = (row: ListRow, field: string): string => {\n const value = row[field];\n return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : '';\n};\n\n/** The id of a row: its `idField`, else its position, so a list without ids still selects and keys sensibly. */\nexport const rowId = (row: ListRow, index: number, idField: string): string => {\n const value = row[idField];\n return typeof value === 'string' || typeof value === 'number' ? String(value) : `row-${index}`;\n};\n\n/** Rows that contain the search text in any shown column, without regard to case or accents; empty search keeps every row. */\nexport function searchRows(rows: ListRow[], columns: ListColumn[], search: string): ListRow[] {\n const needle = normalize(search);\n if (needle.length === 0) return rows;\n return rows.filter(row => columns.some(column => normalize(textOf(row, column.field)).includes(needle)));\n}\n\n/** Rows that satisfy a filter of conditions joined by AND or OR, in nested groups - the value the filter builder publishes. */\nexport function filterRows(rows: ListRow[], filter: unknown): ListRow[] {\n if (typeof filter !== 'object' || filter === null) return rows;\n const group = filter as { operator?: string; conditions?: { field: string; operator: string; value: string }[]; groups?: unknown[] };\n const tests = [\n ...(group.conditions ?? []).filter(condition => typeof condition?.field === 'string').filter(active).map(condition => (row: ListRow) => satisfies(row, condition)),\n ...(group.groups ?? []).filter(nested => hasConditions(nested)).map(nested => (row: ListRow) => filterRows([row], nested).length === 1),\n ];\n if (tests.length === 0) return rows;\n return rows.filter(row => (group.operator === 'or' ? tests.some(test => test(row)) : tests.every(test => test(row))));\n}\n\nconst active = (condition: { operator: string; value: string }) => ['isEmpty', 'true', 'false'].includes(condition.operator) || (condition.value ?? '').trim().length > 0;\nconst hasConditions = (group: unknown): boolean => {\n const candidate = group as { conditions?: { operator: string; value: string }[]; groups?: unknown[] } | null;\n return (candidate?.conditions ?? []).some(active) || (candidate?.groups ?? []).some(hasConditions);\n};\n\nfunction satisfies(row: ListRow, condition: { field: string; operator: string; value: string }): boolean {\n const raw = row[condition.field];\n const text = normalize(typeof raw === 'string' || typeof raw === 'number' || typeof raw === 'boolean' ? String(raw) : '');\n const value = normalize(condition.value ?? '');\n const number = Number(raw);\n const wanted = Number(condition.value);\n switch (condition.operator) {\n case 'contains': return text.includes(value);\n case 'equals': case 'is': case 'on': return typeof raw === 'number' ? number === wanted : text === value;\n case 'notEquals': case 'isNot': return typeof raw === 'number' ? number !== wanted : text !== value;\n case 'startsWith': return text.startsWith(value);\n case 'isEmpty': return text.length === 0;\n case 'greater': return number > wanted;\n case 'greaterOrEqual': return number >= wanted;\n case 'less': return number < wanted;\n case 'lessOrEqual': return number <= wanted;\n case 'before': return text < value;\n case 'after': return text > value;\n case 'true': return raw === true || text === 'true';\n case 'false': return raw === false || text === 'false';\n default: return true;\n }\n}\n\nfunction normalize(text: string): string {\n return text.normalize('NFD').replace(/\\p{Diacritic}/gu, '').toLocaleLowerCase();\n}\n\n/** Reads a sort from its address form, `field` or `-field` for descending; a field that is not a sortable column is no sort at all. */\nexport function parseSort(text: string | undefined, columns: ListColumn[]): ListSort | undefined {\n if (!text) return undefined;\n const descending = text.startsWith('-');\n const field = descending ? text.slice(1) : text;\n return columns.some(column => column.field === field && column.sortable) ? { field, descending } : undefined;\n}\n\n/** A sort in its address form. */\nexport const formatSort = (sort: ListSort | undefined): string | undefined => (sort === undefined ? undefined : `${sort.descending ? '-' : ''}${sort.field}`);\n\n/** The next sort when a header is pressed: ascending, then descending, then none. */\nexport const nextSort = (current: ListSort | undefined, field: string): ListSort | undefined =>\n current?.field !== field ? { field, descending: false } : current.descending ? undefined : { field, descending: true };\n\n/** Rows in order of a column, numbers as numbers and text by the locale, with ties kept in their original order. */\nexport function sortRows(rows: ListRow[], sort: ListSort | undefined, locale: string): ListRow[] {\n if (!sort) return rows;\n const collator = new Intl.Collator(locale, { numeric: true, sensitivity: 'base' });\n return rows.map((row, index) => ({ row, index })).sort((left, right) => {\n const a = left.row[sort.field];\n const b = right.row[sort.field];\n const order = typeof a === 'number' && typeof b === 'number' ? a - b : collator.compare(textOf(left.row, sort.field), textOf(right.row, sort.field));\n return (order === 0 ? left.index - right.index : sort.descending ? -order : order);\n }).map(entry => entry.row);\n}\n\n/** The slice of rows on a page (1-based), and how many pages there are; a page out of range is clamped rather than empty. */\nexport function paginate<T>(rows: T[], page: number, pageSize: number): { rows: T[]; page: number; pages: number } {\n const size = pageSize > 0 ? Math.floor(pageSize) : rows.length || 1;\n const pages = Math.max(1, Math.ceil(rows.length / size));\n const clamped = Math.min(Math.max(1, Math.floor(Number.isFinite(page) ? page : 1)), pages);\n return { rows: rows.slice((clamped - 1) * size, clamped * size), page: clamped, pages };\n}\n\n/** A group of rows with a subtotal, for the grouped variant. */\nexport interface ListGroup {\n key: string;\n rows: ListRow[];\n subtotal?: number;\n}\n\n/** Groups rows by a field in the order the groups are first seen, with the sum of a numeric field as the subtotal when one is named. */\nexport function groupRows(rows: ListRow[], groupBy: string, totalField?: string): ListGroup[] {\n const groups: ListGroup[] = [];\n for (const row of rows) {\n const key = textOf(row, groupBy);\n const group = groups.find(candidate => candidate.key === key) ?? (groups.push({ key, rows: [] }), groups[groups.length - 1]);\n group.rows.push(row);\n }\n\n return totalField === undefined ? groups : groups.map(group => ({ ...group, subtotal: group.rows.reduce((sum, row) => sum + (typeof row[totalField] === 'number' ? (row[totalField] as number) : 0), 0) }));\n}\n\n/** Toggles an id in a selection that allows one or many. */\nexport const toggleSelection = (selected: string[], id: string, multiple: boolean): string[] =>\n selected.includes(id) ? selected.filter(candidate => candidate !== id) : multiple ? [...selected, id] : [id];\n\n/** Reads a selection from its address form: ids separated by commas. */\nexport const parseSelection = (text: string | undefined): string[] => (text ? text.split(',').filter(id => id.length > 0) : []);\n"],"names":["CellKind","ListVariant","records","value","Array","isArray","filter","entry","readListColumns","seen","Set","flatMap","field","length","has","add","tones","Object","fromEntries","entries","pair","header","kind","values","includes","sortable","currency","readListVariant","textOf","row","String","rowId","index","idField","searchRows","rows","columns","search","needle","normalize","some","column","filterRows","group","tests","conditions","condition","active","map","satisfies","groups","nested","hasConditions","operator","test","every","trim","candidate","raw","text","number","Number","wanted","startsWith","replace","toLocaleLowerCase","parseSort","undefined","descending","slice","formatSort","sort","nextSort","current","sortRows","locale","collator","Intl","Collator","numeric","sensitivity","left","right","a","b","order","compare","paginate","page","pageSize","size","Math","floor","pages","max","ceil","clamped","min","isFinite","groupRows","groupBy","totalField","key","find","push","subtotal","reduce","sum","toggleSelection","selected","id","multiple","parseSelection","split"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface TabItem {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
badge?: string;
|
|
5
|
+
disabled: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function readTabs(value: unknown): TabItem[];
|
|
8
|
+
export declare function activeTab(tabs: TabItem[], requested: string | undefined): string | undefined;
|
|
9
|
+
export declare function stepTab(tabs: TabItem[], current: string | undefined, direction: 'next' | 'previous' | 'first' | 'last'): string | undefined;
|
|
10
|
+
//# sourceMappingURL=tabModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabModel.d.ts","sourceRoot":"","sources":["../../../foundation/tabModel.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACrB;AAGD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CAWlD;AAGD,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG5F;AAGD,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ3I"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
/** One tab or sub-section: an id the address and the slot content use, a label, and an optional count badge. */ /** Reads tabs out of a property value; entries without an id are dropped and a repeated id keeps its first. */ function readTabs(value) {
|
|
4
|
+
if (!Array.isArray(value)) return [];
|
|
5
|
+
const seen = new Set();
|
|
6
|
+
return value.flatMap((entry)=>{
|
|
7
|
+
if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) return [];
|
|
8
|
+
const { id, label, badge, disabled } = entry;
|
|
9
|
+
if (typeof id !== 'string' || id.length === 0 || seen.has(id)) return [];
|
|
10
|
+
seen.add(id);
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
id,
|
|
14
|
+
label: typeof label === 'string' && label.length > 0 ? label : id,
|
|
15
|
+
disabled: disabled === true,
|
|
16
|
+
...typeof badge === 'string' || typeof badge === 'number' ? {
|
|
17
|
+
badge: String(badge)
|
|
18
|
+
} : {}
|
|
19
|
+
}
|
|
20
|
+
];
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/** The active tab: the requested one when it exists and is enabled, else the first enabled one. Deep links to a tab that was removed fall back instead of showing nothing. */ function activeTab(tabs, requested) {
|
|
24
|
+
const wanted = tabs.find((tab)=>tab.id === requested && !tab.disabled);
|
|
25
|
+
return (wanted ?? tabs.find((tab)=>!tab.disabled))?.id;
|
|
26
|
+
}
|
|
27
|
+
/** The enabled tab one step from the current one, wrapping, or the first/last for Home and End. */ function stepTab(tabs, current, direction) {
|
|
28
|
+
const enabled = tabs.filter((tab)=>!tab.disabled);
|
|
29
|
+
if (enabled.length === 0) return undefined;
|
|
30
|
+
if (direction === 'first') return enabled[0].id;
|
|
31
|
+
if (direction === 'last') return enabled[enabled.length - 1].id;
|
|
32
|
+
const index = Math.max(0, enabled.findIndex((tab)=>tab.id === current));
|
|
33
|
+
return enabled[(index + (direction === 'next' ? 1 : -1) + enabled.length) % enabled.length].id;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { activeTab, readTabs, stepTab };
|
|
37
|
+
//# sourceMappingURL=tabModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabModel.js","sources":["../../../foundation/tabModel.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/** One tab or sub-section: an id the address and the slot content use, a label, and an optional count badge. */\nexport interface TabItem {\n id: string;\n label: string;\n badge?: string;\n disabled: boolean;\n}\n\n/** Reads tabs out of a property value; entries without an id are dropped and a repeated id keeps its first. */\nexport function readTabs(value: unknown): TabItem[] {\n if (!Array.isArray(value)) return [];\n\n const seen = new Set<string>();\n return value.flatMap((entry): TabItem[] => {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) return [];\n const { id, label, badge, disabled } = entry as Record<string, unknown>;\n if (typeof id !== 'string' || id.length === 0 || seen.has(id)) return [];\n seen.add(id);\n return [{ id, label: typeof label === 'string' && label.length > 0 ? label : id, disabled: disabled === true, ...(typeof badge === 'string' || typeof badge === 'number' ? { badge: String(badge) } : {}) }];\n });\n}\n\n/** The active tab: the requested one when it exists and is enabled, else the first enabled one. Deep links to a tab that was removed fall back instead of showing nothing. */\nexport function activeTab(tabs: TabItem[], requested: string | undefined): string | undefined {\n const wanted = tabs.find(tab => tab.id === requested && !tab.disabled);\n return (wanted ?? tabs.find(tab => !tab.disabled))?.id;\n}\n\n/** The enabled tab one step from the current one, wrapping, or the first/last for Home and End. */\nexport function stepTab(tabs: TabItem[], current: string | undefined, direction: 'next' | 'previous' | 'first' | 'last'): string | undefined {\n const enabled = tabs.filter(tab => !tab.disabled);\n if (enabled.length === 0) return undefined;\n if (direction === 'first') return enabled[0].id;\n if (direction === 'last') return enabled[enabled.length - 1].id;\n\n const index = Math.max(0, enabled.findIndex(tab => tab.id === current));\n return enabled[(index + (direction === 'next' ? 1 : -1) + enabled.length) % enabled.length].id;\n}\n"],"names":["readTabs","value","Array","isArray","seen","Set","flatMap","entry","id","label","badge","disabled","length","has","add","String","activeTab","tabs","requested","wanted","find","tab","stepTab","current","direction","enabled","filter","undefined","index","Math","max","findIndex"],"mappings":"AAAA;AACA;AAEA,iOASO,SAASA,SAASC,KAAc,EAAA;AACnC,IAAA,IAAI,CAACC,KAAAA,CAAMC,OAAO,CAACF,KAAAA,CAAAA,EAAQ,OAAO,EAAE;AAEpC,IAAA,MAAMG,OAAO,IAAIC,GAAAA,EAAAA;IACjB,OAAOJ,KAAAA,CAAMK,OAAO,CAAC,CAACC,KAAAA,GAAAA;QAClB,IAAI,OAAOA,KAAAA,KAAU,QAAA,IAAYA,KAAAA,KAAU,IAAA,IAAQL,MAAMC,OAAO,CAACI,KAAAA,CAAAA,EAAQ,OAAO,EAAE;QAClF,MAAM,EAAEC,EAAE,EAAEC,KAAK,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGJ,KAAAA;AACvC,QAAA,IAAI,OAAOC,EAAAA,KAAO,QAAA,IAAYA,EAAAA,CAAGI,MAAM,KAAK,CAAA,IAAKR,IAAAA,CAAKS,GAAG,CAACL,EAAAA,CAAAA,EAAK,OAAO,EAAE;AACxEJ,QAAAA,IAAAA,CAAKU,GAAG,CAACN,EAAAA,CAAAA;QACT,OAAO;AAAC,YAAA;AAAEA,gBAAAA,EAAAA;AAAIC,gBAAAA,KAAAA,EAAO,OAAOA,KAAAA,KAAU,QAAA,IAAYA,MAAMG,MAAM,GAAG,IAAIH,KAAAA,GAAQD,EAAAA;AAAIG,gBAAAA,QAAAA,EAAUA,QAAAA,KAAa,IAAA;AAAM,gBAAA,GAAI,OAAOD,KAAAA,KAAU,QAAA,IAAY,OAAOA,UAAU,QAAA,GAAW;AAAEA,oBAAAA,KAAAA,EAAOK,MAAAA,CAAOL,KAAAA;AAAO,iBAAA,GAAI;AAAI;AAAE,SAAA;AAChN,IAAA,CAAA,CAAA;AACJ;AAEA,+KACO,SAASM,SAAAA,CAAUC,IAAe,EAAEC,SAA6B,EAAA;AACpE,IAAA,MAAMC,MAAAA,GAASF,IAAAA,CAAKG,IAAI,CAACC,CAAAA,GAAAA,GAAOA,GAAAA,CAAIb,EAAE,KAAKU,SAAAA,IAAa,CAACG,GAAAA,CAAIV,QAAQ,CAAA;IACrE,OAAQQ,CAAAA,MAAAA,IAAUF,IAAAA,CAAKG,IAAI,CAACC,CAAAA,GAAAA,GAAO,CAACA,GAAAA,CAAIV,QAAQ,CAAA,GAAIH,EAAAA;AACxD;AAEA,oGACO,SAASc,OAAAA,CAAQL,IAAe,EAAEM,OAA2B,EAAEC,SAAiD,EAAA;IACnH,MAAMC,OAAAA,GAAUR,KAAKS,MAAM,CAACL,CAAAA,GAAAA,GAAO,CAACA,IAAIV,QAAQ,CAAA;AAChD,IAAA,IAAIc,OAAAA,CAAQb,MAAM,KAAK,CAAA,EAAG,OAAOe,SAAAA;AACjC,IAAA,IAAIH,cAAc,OAAA,EAAS,OAAOC,OAAO,CAAC,CAAA,CAAE,CAACjB,EAAE;IAC/C,IAAIgB,SAAAA,KAAc,MAAA,EAAQ,OAAOC,OAAO,CAACA,QAAQb,MAAM,GAAG,CAAA,CAAE,CAACJ,EAAE;AAE/D,IAAA,MAAMoB,KAAAA,GAAQC,IAAAA,CAAKC,GAAG,CAAC,CAAA,EAAGL,OAAAA,CAAQM,SAAS,CAACV,CAAAA,GAAAA,GAAOA,GAAAA,CAAIb,EAAE,KAAKe,OAAAA,CAAAA,CAAAA;IAC9D,OAAOE,OAAO,CAAC,CAACG,SAASJ,SAAAA,KAAc,SAAS,CAAA,GAAI,EAAC,CAAA,GAAKC,OAAAA,CAAQb,MAAM,IAAIa,QAAQb,MAAM,CAAC,CAACJ,EAAE;AAClG;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boardScreenTemplate.d.ts","sourceRoot":"","sources":["../../../../foundation/templates/boardScreenTemplate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAQrE,eAAO,MAAM,mBAAmB,EAAE,cAgBjC,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { WidthSizeClass } from '@cratis/scene.model';
|
|
2
|
+
import { column, slotLeaf, row } from '../../layouts/flowBuilders.js';
|
|
3
|
+
import { component, fromQuery, foundationTemplateProvenance, thumbnailOf } from './templateParts.js';
|
|
4
|
+
|
|
5
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
6
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
7
|
+
/**
|
|
8
|
+
* The board: columns mapped to a status or stage, cards that move between them - by dragging or by each card's own Move-to menu, so the board is as
|
|
9
|
+
* usable from a keyboard and a screen reader as with a pointer.
|
|
10
|
+
*/ const boardScreenTemplate = {
|
|
11
|
+
name: 'BoardScreen',
|
|
12
|
+
fitsSlot: 'content',
|
|
13
|
+
slots: [
|
|
14
|
+
{
|
|
15
|
+
name: 'header'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'toolbar'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'board'
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
arrangement: {
|
|
25
|
+
root: column([
|
|
26
|
+
slotLeaf('header'),
|
|
27
|
+
row([
|
|
28
|
+
slotLeaf('toolbar')
|
|
29
|
+
], 8),
|
|
30
|
+
slotLeaf('board')
|
|
31
|
+
], 12),
|
|
32
|
+
overrides: [
|
|
33
|
+
{
|
|
34
|
+
width: WidthSizeClass.Compact,
|
|
35
|
+
root: column([
|
|
36
|
+
slotLeaf('header'),
|
|
37
|
+
slotLeaf('toolbar'),
|
|
38
|
+
slotLeaf('board')
|
|
39
|
+
], 16)
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
content: {
|
|
44
|
+
header: [
|
|
45
|
+
component('board-header', 'pageHeader', {
|
|
46
|
+
title: 'Pipeline',
|
|
47
|
+
subtitle: 'Drag a deal to a new stage'
|
|
48
|
+
})
|
|
49
|
+
],
|
|
50
|
+
toolbar: [
|
|
51
|
+
component('board-search', 'globalSearch', {
|
|
52
|
+
placeholder: 'Search the pipeline',
|
|
53
|
+
label: 'Search the pipeline'
|
|
54
|
+
})
|
|
55
|
+
],
|
|
56
|
+
board: [
|
|
57
|
+
component('board-columns', 'kanbanBoard', {
|
|
58
|
+
columns: fromQuery('PipelineColumns'),
|
|
59
|
+
cards: fromQuery('PipelineCards')
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
displayName: 'Board',
|
|
64
|
+
description: 'Columns mapped to a stage with cards that move by dragging or by menu.',
|
|
65
|
+
metadata: {
|
|
66
|
+
...foundationTemplateProvenance,
|
|
67
|
+
type: 'Board',
|
|
68
|
+
category: 'Foundation / Board',
|
|
69
|
+
thumbnail: thumbnailOf('BoardScreen')
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { boardScreenTemplate };
|
|
74
|
+
//# sourceMappingURL=boardScreenTemplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boardScreenTemplate.js","sources":["../../../../foundation/templates/boardScreenTemplate.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ScreenTemplate, WidthSizeClass } from '@cratis/scene.model';\nimport { column, grid, row, slotLeaf } from '../../layouts/flowBuilders';\nimport { component, foundationTemplateProvenance, fromQuery, thumbnailOf } from './templateParts';\n\n/**\n * The board: columns mapped to a status or stage, cards that move between them - by dragging or by each card's own Move-to menu, so the board is as\n * usable from a keyboard and a screen reader as with a pointer.\n */\nexport const boardScreenTemplate: ScreenTemplate = {\n name: 'BoardScreen',\n fitsSlot: 'content',\n slots: [{ name: 'header' }, { name: 'toolbar' }, { name: 'board' }],\n arrangement: {\n root: column([slotLeaf('header'), row([slotLeaf('toolbar')], 8), slotLeaf('board')], 12),\n overrides: [{ width: WidthSizeClass.Compact, root: column([slotLeaf('header'), slotLeaf('toolbar'), slotLeaf('board')], 16) }],\n },\n content: {\n header: [component('board-header', 'pageHeader', { title: 'Pipeline', subtitle: 'Drag a deal to a new stage' })],\n toolbar: [component('board-search', 'globalSearch', { placeholder: 'Search the pipeline', label: 'Search the pipeline' })],\n board: [component('board-columns', 'kanbanBoard', { columns: fromQuery('PipelineColumns'), cards: fromQuery('PipelineCards') })],\n },\n displayName: 'Board',\n description: 'Columns mapped to a stage with cards that move by dragging or by menu.',\n metadata: { ...foundationTemplateProvenance, type: 'Board', category: 'Foundation / Board', thumbnail: thumbnailOf('BoardScreen') },\n};\n"],"names":["boardScreenTemplate","name","fitsSlot","slots","arrangement","root","column","slotLeaf","row","overrides","width","WidthSizeClass","Compact","content","header","component","title","subtitle","toolbar","placeholder","label","board","columns","fromQuery","cards","displayName","description","metadata","foundationTemplateProvenance","type","category","thumbnail","thumbnailOf"],"mappings":";;;;AAAA;AACA;AAMA;;;UAIaA,mBAAAA,GAAsC;IAC/CC,IAAAA,EAAM,aAAA;IACNC,QAAAA,EAAU,SAAA;IACVC,KAAAA,EAAO;AAAC,QAAA;YAAEF,IAAAA,EAAM;AAAS,SAAA;AAAG,QAAA;YAAEA,IAAAA,EAAM;AAAU,SAAA;AAAG,QAAA;YAAEA,IAAAA,EAAM;AAAQ;AAAE,KAAA;IACnEG,WAAAA,EAAa;AACTC,QAAAA,IAAAA,EAAMC,MAAAA,CAAO;YAACC,QAAAA,CAAS,QAAA,CAAA;YAAWC,GAAAA,CAAI;gBAACD,QAAAA,CAAS,SAAA;aAAW,EAAE,CAAA,CAAA;YAAIA,QAAAA,CAAS,OAAA;SAAS,EAAE,EAAA,CAAA;QACrFE,SAAAA,EAAW;AAAC,YAAA;AAAEC,gBAAAA,KAAAA,EAAOC,eAAeC,OAAO;AAAEP,gBAAAA,IAAAA,EAAMC,MAAAA,CAAO;oBAACC,QAAAA,CAAS,QAAA,CAAA;oBAAWA,QAAAA,CAAS,SAAA,CAAA;oBAAYA,QAAAA,CAAS,OAAA;iBAAS,EAAE,EAAA;AAAI;AAAE;AAClI,KAAA;IACAM,OAAAA,EAAS;QACLC,MAAAA,EAAQ;AAACC,YAAAA,SAAAA,CAAU,gBAAgB,YAAA,EAAc;gBAAEC,KAAAA,EAAO,UAAA;gBAAYC,QAAAA,EAAU;AAA6B,aAAA;AAAG,SAAA;QAChHC,OAAAA,EAAS;AAACH,YAAAA,SAAAA,CAAU,gBAAgB,cAAA,EAAgB;gBAAEI,WAAAA,EAAa,qBAAA;gBAAuBC,KAAAA,EAAO;AAAsB,aAAA;AAAG,SAAA;QAC1HC,KAAAA,EAAO;AAACN,YAAAA,SAAAA,CAAU,iBAAiB,aAAA,EAAe;AAAEO,gBAAAA,OAAAA,EAASC,SAAAA,CAAU,iBAAA,CAAA;AAAoBC,gBAAAA,KAAAA,EAAOD,SAAAA,CAAU,eAAA;AAAiB,aAAA;AAAG;AACpI,KAAA;IACAE,WAAAA,EAAa,OAAA;IACbC,WAAAA,EAAa,wEAAA;IACbC,QAAAA,EAAU;AAAE,QAAA,GAAGC,4BAA4B;QAAEC,IAAAA,EAAM,OAAA;QAASC,QAAAA,EAAU,oBAAA;AAAsBC,QAAAA,SAAAA,EAAWC,WAAAA,CAAY,aAAA;AAAe;AACtI;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboardScreenTemplate.d.ts","sourceRoot":"","sources":["../../../../foundation/templates/dashboardScreenTemplate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAQrE,eAAO,MAAM,uBAAuB,EAAE,cAyBrC,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { WidthSizeClass } from '@cratis/scene.model';
|
|
2
|
+
import { column, slotLeaf, grid } from '../../layouts/flowBuilders.js';
|
|
3
|
+
import { component, fromQuery, foundationTemplateProvenance, thumbnailOf } from './templateParts.js';
|
|
4
|
+
|
|
5
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
6
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
7
|
+
/**
|
|
8
|
+
* The dashboard: key figures across the top, charts and tables below, an aside for what needs attention. Every region is its own component with its
|
|
9
|
+
* own five states, so one failed query shows the other regions - the page never fails as a whole.
|
|
10
|
+
*/ const dashboardScreenTemplate = {
|
|
11
|
+
name: 'DashboardScreen',
|
|
12
|
+
fitsSlot: 'content',
|
|
13
|
+
slots: [
|
|
14
|
+
{
|
|
15
|
+
name: 'header'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'kpis'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'charts'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'tables'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'aside'
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
arrangement: {
|
|
31
|
+
root: column([
|
|
32
|
+
slotLeaf('header'),
|
|
33
|
+
slotLeaf('kpis'),
|
|
34
|
+
grid([
|
|
35
|
+
slotLeaf('charts', {
|
|
36
|
+
span: 2
|
|
37
|
+
}),
|
|
38
|
+
slotLeaf('aside')
|
|
39
|
+
], 3, 16),
|
|
40
|
+
slotLeaf('tables')
|
|
41
|
+
], 16),
|
|
42
|
+
overrides: [
|
|
43
|
+
{
|
|
44
|
+
width: WidthSizeClass.Compact,
|
|
45
|
+
root: column([
|
|
46
|
+
slotLeaf('header'),
|
|
47
|
+
slotLeaf('kpis'),
|
|
48
|
+
slotLeaf('charts'),
|
|
49
|
+
slotLeaf('tables'),
|
|
50
|
+
slotLeaf('aside')
|
|
51
|
+
], 16)
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
content: {
|
|
56
|
+
header: [
|
|
57
|
+
component('dashboard-header', 'pageHeader', {
|
|
58
|
+
title: 'Sales overview',
|
|
59
|
+
subtitle: 'This quarter compared to last'
|
|
60
|
+
})
|
|
61
|
+
],
|
|
62
|
+
kpis: [
|
|
63
|
+
component('kpi-pipeline', 'statCard', {
|
|
64
|
+
label: 'Open pipeline',
|
|
65
|
+
value: fromQuery('Kpis', '0.value'),
|
|
66
|
+
change: fromQuery('Kpis', '0.change'),
|
|
67
|
+
format: 'currency',
|
|
68
|
+
currency: 'USD',
|
|
69
|
+
comparison: 'last quarter'
|
|
70
|
+
}),
|
|
71
|
+
component('kpi-won', 'statCard', {
|
|
72
|
+
label: 'Deals won',
|
|
73
|
+
value: fromQuery('Kpis', '1.value'),
|
|
74
|
+
change: fromQuery('Kpis', '1.change'),
|
|
75
|
+
comparison: 'last quarter'
|
|
76
|
+
}),
|
|
77
|
+
component('kpi-response', 'statCard', {
|
|
78
|
+
label: 'Response time (hours)',
|
|
79
|
+
value: fromQuery('Kpis', '2.value'),
|
|
80
|
+
change: fromQuery('Kpis', '2.change'),
|
|
81
|
+
goodDirection: 'down',
|
|
82
|
+
comparison: 'last quarter'
|
|
83
|
+
})
|
|
84
|
+
],
|
|
85
|
+
charts: [
|
|
86
|
+
component('chart-revenue', 'chartWrapper', {
|
|
87
|
+
title: 'Revenue by quarter',
|
|
88
|
+
kind: 'line',
|
|
89
|
+
categories: fromQuery('RevenueChart', '0.categories'),
|
|
90
|
+
series: fromQuery('RevenueChart', '0.series')
|
|
91
|
+
}),
|
|
92
|
+
component('chart-stages', 'chartWrapper', {
|
|
93
|
+
title: 'Deals by stage',
|
|
94
|
+
kind: 'funnel',
|
|
95
|
+
categories: fromQuery('StageChart', '0.categories'),
|
|
96
|
+
series: fromQuery('StageChart', '0.series')
|
|
97
|
+
})
|
|
98
|
+
],
|
|
99
|
+
tables: [
|
|
100
|
+
component('dashboard-deals', 'dataList', {
|
|
101
|
+
label: 'Closing soon',
|
|
102
|
+
rows: fromQuery('Deals'),
|
|
103
|
+
columns: fromQuery('DealColumns'),
|
|
104
|
+
titleField: 'name',
|
|
105
|
+
pageSize: 5
|
|
106
|
+
})
|
|
107
|
+
],
|
|
108
|
+
aside: [
|
|
109
|
+
component('dashboard-activity', 'activityFeed', {
|
|
110
|
+
label: 'Recent activity',
|
|
111
|
+
entries: fromQuery('Activity')
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
displayName: 'Dashboard',
|
|
116
|
+
description: 'Key figures, charts and tables, each region with its own loading, empty and error states.',
|
|
117
|
+
metadata: {
|
|
118
|
+
...foundationTemplateProvenance,
|
|
119
|
+
type: 'Dashboard',
|
|
120
|
+
category: 'Foundation / Dashboard',
|
|
121
|
+
thumbnail: thumbnailOf('DashboardScreen')
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export { dashboardScreenTemplate };
|
|
126
|
+
//# sourceMappingURL=dashboardScreenTemplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboardScreenTemplate.js","sources":["../../../../foundation/templates/dashboardScreenTemplate.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ScreenTemplate, WidthSizeClass } from '@cratis/scene.model';\nimport { column, grid, row, slotLeaf } from '../../layouts/flowBuilders';\nimport { component, foundationTemplateProvenance, fromQuery, thumbnailOf } from './templateParts';\n\n/**\n * The dashboard: key figures across the top, charts and tables below, an aside for what needs attention. Every region is its own component with its\n * own five states, so one failed query shows the other regions - the page never fails as a whole.\n */\nexport const dashboardScreenTemplate: ScreenTemplate = {\n name: 'DashboardScreen',\n fitsSlot: 'content',\n slots: [{ name: 'header' }, { name: 'kpis' }, { name: 'charts' }, { name: 'tables' }, { name: 'aside' }],\n arrangement: {\n root: column([slotLeaf('header'), slotLeaf('kpis'), grid([slotLeaf('charts', { span: 2 }), slotLeaf('aside')], 3, 16), slotLeaf('tables')], 16),\n overrides: [{ width: WidthSizeClass.Compact, root: column([slotLeaf('header'), slotLeaf('kpis'), slotLeaf('charts'), slotLeaf('tables'), slotLeaf('aside')], 16) }],\n },\n content: {\n header: [component('dashboard-header', 'pageHeader', { title: 'Sales overview', subtitle: 'This quarter compared to last' })],\n kpis: [\n component('kpi-pipeline', 'statCard', { label: 'Open pipeline', value: fromQuery('Kpis', '0.value'), change: fromQuery('Kpis', '0.change'), format: 'currency', currency: 'USD', comparison: 'last quarter' }),\n component('kpi-won', 'statCard', { label: 'Deals won', value: fromQuery('Kpis', '1.value'), change: fromQuery('Kpis', '1.change'), comparison: 'last quarter' }),\n component('kpi-response', 'statCard', { label: 'Response time (hours)', value: fromQuery('Kpis', '2.value'), change: fromQuery('Kpis', '2.change'), goodDirection: 'down', comparison: 'last quarter' }),\n ],\n charts: [\n component('chart-revenue', 'chartWrapper', { title: 'Revenue by quarter', kind: 'line', categories: fromQuery('RevenueChart', '0.categories'), series: fromQuery('RevenueChart', '0.series') }),\n component('chart-stages', 'chartWrapper', { title: 'Deals by stage', kind: 'funnel', categories: fromQuery('StageChart', '0.categories'), series: fromQuery('StageChart', '0.series') }),\n ],\n tables: [component('dashboard-deals', 'dataList', { label: 'Closing soon', rows: fromQuery('Deals'), columns: fromQuery('DealColumns'), titleField: 'name', pageSize: 5 })],\n aside: [component('dashboard-activity', 'activityFeed', { label: 'Recent activity', entries: fromQuery('Activity') })],\n },\n displayName: 'Dashboard',\n description: 'Key figures, charts and tables, each region with its own loading, empty and error states.',\n metadata: { ...foundationTemplateProvenance, type: 'Dashboard', category: 'Foundation / Dashboard', thumbnail: thumbnailOf('DashboardScreen') },\n};\n"],"names":["dashboardScreenTemplate","name","fitsSlot","slots","arrangement","root","column","slotLeaf","grid","span","overrides","width","WidthSizeClass","Compact","content","header","component","title","subtitle","kpis","label","value","fromQuery","change","format","currency","comparison","goodDirection","charts","kind","categories","series","tables","rows","columns","titleField","pageSize","aside","entries","displayName","description","metadata","foundationTemplateProvenance","type","category","thumbnail","thumbnailOf"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formScreenTemplate.d.ts","sourceRoot":"","sources":["../../../../foundation/templates/formScreenTemplate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAkB,MAAM,qBAAqB,CAAC;AAQrE,eAAO,MAAM,kBAAkB,EAAE,cAgBhC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { WidthSizeClass } from '@cratis/scene.model';
|
|
2
|
+
import { column, slotLeaf } from '../../layouts/flowBuilders.js';
|
|
3
|
+
import { component, fromQuery, foundationTemplateProvenance, thumbnailOf } from './templateParts.js';
|
|
4
|
+
|
|
5
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
6
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
7
|
+
/**
|
|
8
|
+
* The form: titled sections of fields in a one-to-three column grid, validated, with Save, Save and new and Cancel. One template serves create, edit, read-only
|
|
9
|
+
* and settings (a save for each section) by its mode, and warns before unsaved changes are lost.
|
|
10
|
+
*/ const formScreenTemplate = {
|
|
11
|
+
name: 'FormScreen',
|
|
12
|
+
fitsSlot: 'content',
|
|
13
|
+
slots: [
|
|
14
|
+
{
|
|
15
|
+
name: 'header'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'body'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'actions'
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
arrangement: {
|
|
25
|
+
root: column([
|
|
26
|
+
slotLeaf('header'),
|
|
27
|
+
slotLeaf('body'),
|
|
28
|
+
slotLeaf('actions')
|
|
29
|
+
], 16),
|
|
30
|
+
overrides: [
|
|
31
|
+
{
|
|
32
|
+
width: WidthSizeClass.Compact,
|
|
33
|
+
root: column([
|
|
34
|
+
slotLeaf('header'),
|
|
35
|
+
slotLeaf('body'),
|
|
36
|
+
slotLeaf('actions')
|
|
37
|
+
], 16)
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
content: {
|
|
42
|
+
header: [
|
|
43
|
+
component('form-header', 'pageHeader', {
|
|
44
|
+
title: 'New account',
|
|
45
|
+
subtitle: 'Fields marked * are required'
|
|
46
|
+
})
|
|
47
|
+
],
|
|
48
|
+
body: [
|
|
49
|
+
component('form-body', 'formScreenBody', {
|
|
50
|
+
mode: 'create',
|
|
51
|
+
sections: fromQuery('RecordSections'),
|
|
52
|
+
values: fromQuery('RecordValues', '0'),
|
|
53
|
+
errors: fromQuery('FormErrors', '0')
|
|
54
|
+
})
|
|
55
|
+
],
|
|
56
|
+
actions: []
|
|
57
|
+
},
|
|
58
|
+
displayName: 'Form',
|
|
59
|
+
description: 'Sections of validated fields with Save, Save and new, Cancel and an unsaved-changes guard.',
|
|
60
|
+
metadata: {
|
|
61
|
+
...foundationTemplateProvenance,
|
|
62
|
+
type: 'Form',
|
|
63
|
+
category: 'Foundation / Form',
|
|
64
|
+
thumbnail: thumbnailOf('FormScreen')
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export { formScreenTemplate };
|
|
69
|
+
//# sourceMappingURL=formScreenTemplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formScreenTemplate.js","sources":["../../../../foundation/templates/formScreenTemplate.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ScreenTemplate, WidthSizeClass } from '@cratis/scene.model';\nimport { column, grid, row, slotLeaf } from '../../layouts/flowBuilders';\nimport { component, foundationTemplateProvenance, fromQuery, thumbnailOf } from './templateParts';\n\n/**\n * The form: titled sections of fields in a one-to-three column grid, validated, with Save, Save and new and Cancel. One template serves create, edit, read-only\n * and settings (a save for each section) by its mode, and warns before unsaved changes are lost.\n */\nexport const formScreenTemplate: ScreenTemplate = {\n name: 'FormScreen',\n fitsSlot: 'content',\n slots: [{ name: 'header' }, { name: 'body' }, { name: 'actions' }],\n arrangement: {\n root: column([slotLeaf('header'), slotLeaf('body'), slotLeaf('actions')], 16),\n overrides: [{ width: WidthSizeClass.Compact, root: column([slotLeaf('header'), slotLeaf('body'), slotLeaf('actions')], 16) }],\n },\n content: {\n header: [component('form-header', 'pageHeader', { title: 'New account', subtitle: 'Fields marked * are required' })],\n body: [component('form-body', 'formScreenBody', { mode: 'create', sections: fromQuery('RecordSections'), values: fromQuery('RecordValues', '0'), errors: fromQuery('FormErrors', '0') })],\n actions: [],\n },\n displayName: 'Form',\n description: 'Sections of validated fields with Save, Save and new, Cancel and an unsaved-changes guard.',\n metadata: { ...foundationTemplateProvenance, type: 'Form', category: 'Foundation / Form', thumbnail: thumbnailOf('FormScreen') },\n};\n"],"names":["formScreenTemplate","name","fitsSlot","slots","arrangement","root","column","slotLeaf","overrides","width","WidthSizeClass","Compact","content","header","component","title","subtitle","body","mode","sections","fromQuery","values","errors","actions","displayName","description","metadata","foundationTemplateProvenance","type","category","thumbnail","thumbnailOf"],"mappings":";;;;AAAA;AACA;AAMA;;;UAIaA,kBAAAA,GAAqC;IAC9CC,IAAAA,EAAM,YAAA;IACNC,QAAAA,EAAU,SAAA;IACVC,KAAAA,EAAO;AAAC,QAAA;YAAEF,IAAAA,EAAM;AAAS,SAAA;AAAG,QAAA;YAAEA,IAAAA,EAAM;AAAO,SAAA;AAAG,QAAA;YAAEA,IAAAA,EAAM;AAAU;AAAE,KAAA;IAClEG,WAAAA,EAAa;AACTC,QAAAA,IAAAA,EAAMC,MAAAA,CAAO;YAACC,QAAAA,CAAS,QAAA,CAAA;YAAWA,QAAAA,CAAS,MAAA,CAAA;YAASA,QAAAA,CAAS,SAAA;SAAW,EAAE,EAAA,CAAA;QAC1EC,SAAAA,EAAW;AAAC,YAAA;AAAEC,gBAAAA,KAAAA,EAAOC,eAAeC,OAAO;AAAEN,gBAAAA,IAAAA,EAAMC,MAAAA,CAAO;oBAACC,QAAAA,CAAS,QAAA,CAAA;oBAAWA,QAAAA,CAAS,MAAA,CAAA;oBAASA,QAAAA,CAAS,SAAA;iBAAW,EAAE,EAAA;AAAI;AAAE;AACjI,KAAA;IACAK,OAAAA,EAAS;QACLC,MAAAA,EAAQ;AAACC,YAAAA,SAAAA,CAAU,eAAe,YAAA,EAAc;gBAAEC,KAAAA,EAAO,aAAA;gBAAeC,QAAAA,EAAU;AAA+B,aAAA;AAAG,SAAA;QACpHC,IAAAA,EAAM;AAACH,YAAAA,SAAAA,CAAU,aAAa,gBAAA,EAAkB;gBAAEI,IAAAA,EAAM,QAAA;AAAUC,gBAAAA,QAAAA,EAAUC,SAAAA,CAAU,gBAAA,CAAA;AAAmBC,gBAAAA,MAAAA,EAAQD,UAAU,cAAA,EAAgB,GAAA,CAAA;AAAME,gBAAAA,MAAAA,EAAQF,UAAU,YAAA,EAAc,GAAA;AAAK,aAAA;AAAG,SAAA;AACzLG,QAAAA,OAAAA,EAAS;AACb,KAAA;IACAC,WAAAA,EAAa,MAAA;IACbC,WAAAA,EAAa,4FAAA;IACbC,QAAAA,EAAU;AAAE,QAAA,GAAGC,4BAA4B;QAAEC,IAAAA,EAAM,MAAA;QAAQC,QAAAA,EAAU,mBAAA;AAAqBC,QAAAA,SAAAA,EAAWC,WAAAA,CAAY,YAAA;AAAc;AACnI;;"}
|