@revenexx/studio-shared 0.4.0 → 0.4.2
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/module.d.mts +5 -3
- package/dist/module.json +2 -2
- package/dist/module.mjs +7 -3
- package/dist/runtime/components/Dashboard/DashboardConfirmDialog.vue +1 -1
- package/dist/runtime/components/Dashboard/DashboardGrid.vue +45 -1
- package/dist/runtime/components/Dashboard/DashboardNameDialog.vue +1 -1
- package/dist/runtime/components/Dashboard/DashboardPickerDialog.vue +1 -1
- package/dist/runtime/components/Dashboard/DashboardShareDialog.vue +1 -1
- package/dist/runtime/components/Dashboard/DashboardWidgetConfigDialog.vue +1 -1
- package/dist/runtime/components/Dashboard/DashboardWidgetFrame.d.vue.ts +2 -2
- package/dist/runtime/components/Dashboard/DashboardWidgetFrame.vue +14 -3
- package/dist/runtime/components/Dashboard/DashboardWidgetFrame.vue.d.ts +2 -2
- package/dist/runtime/components/DataTable/DataTable.d.vue.ts +73 -34
- package/dist/runtime/components/DataTable/DataTable.vue +352 -52
- package/dist/runtime/components/DataTable/DataTable.vue.d.ts +73 -34
- package/dist/runtime/components/DataTable/FacetPanel.vue +57 -8
- package/dist/runtime/components/DataTable/FilterMenu.vue +5 -5
- package/dist/runtime/components/DataTable/SavedViewsMenu.vue +61 -12
- package/dist/runtime/components/DataTable/SortMenu.vue +4 -1
- package/dist/runtime/components/DataTable/ToolbarLabelTrigger.d.vue.ts +23 -0
- package/dist/runtime/components/DataTable/ToolbarLabelTrigger.vue +29 -0
- package/dist/runtime/components/DataTable/ToolbarLabelTrigger.vue.d.ts +23 -0
- package/dist/runtime/components/DataTable/types.d.ts +17 -0
- package/dist/runtime/components/Form/FieldGrid.vue +1 -1
- package/dist/runtime/components/Form/SaveBar.d.vue.ts +1 -1
- package/dist/runtime/components/Form/SaveBar.vue.d.ts +1 -1
- package/dist/runtime/components/Media/MediaFolderTree.d.vue.ts +4 -4
- package/dist/runtime/components/Media/MediaFolderTree.vue +1 -2
- package/dist/runtime/components/Media/MediaFolderTree.vue.d.ts +4 -4
- package/dist/runtime/components/Media/MediaPickerDialog.d.vue.ts +11 -0
- package/dist/runtime/components/Media/MediaPickerDialog.vue +206 -54
- package/dist/runtime/components/Media/MediaPickerDialog.vue.d.ts +11 -0
- package/dist/runtime/components/Media/MediaUploader.vue +1 -1
- package/dist/runtime/components/Shared/AppIcon.d.vue.ts +1 -1
- package/dist/runtime/components/Shared/AppIcon.vue.d.ts +1 -1
- package/dist/runtime/components/Shared/CardSizeToggle.d.vue.ts +11 -0
- package/dist/runtime/components/Shared/CardSizeToggle.vue +19 -0
- package/dist/runtime/components/Shared/CardSizeToggle.vue.d.ts +11 -0
- package/dist/runtime/components/Shared/DetailSheet.d.vue.ts +1 -1
- package/dist/runtime/components/Shared/DetailSheet.vue +9 -5
- package/dist/runtime/components/Shared/DetailSheet.vue.d.ts +1 -1
- package/dist/runtime/components/Shared/EmptyNote.d.vue.ts +19 -0
- package/dist/runtime/components/Shared/EmptyNote.vue +25 -0
- package/dist/runtime/components/Shared/EmptyNote.vue.d.ts +19 -0
- package/dist/runtime/components/Shared/KpiTile.d.vue.ts +6 -0
- package/dist/runtime/components/Shared/KpiTile.vue +10 -9
- package/dist/runtime/components/Shared/KpiTile.vue.d.ts +6 -0
- package/dist/runtime/components/Shared/PageHeader.vue +15 -4
- package/dist/runtime/components/Shared/RecordLayout.vue +1 -2
- package/dist/runtime/components/Shared/RecordRailCard.vue +3 -3
- package/dist/runtime/components/Shared/SelectionBar.d.vue.ts +22 -0
- package/dist/runtime/components/Shared/SelectionBar.vue +40 -0
- package/dist/runtime/components/Shared/SelectionBar.vue.d.ts +22 -0
- package/dist/runtime/components/Shared/SidebarNav.d.vue.ts +36 -2
- package/dist/runtime/components/Shared/SidebarNav.vue +74 -25
- package/dist/runtime/components/Shared/SidebarNav.vue.d.ts +36 -2
- package/dist/runtime/components/Shared/SidebarNavAreas.d.vue.ts +7 -0
- package/dist/runtime/components/Shared/SidebarNavAreas.vue +291 -0
- package/dist/runtime/components/Shared/SidebarNavAreas.vue.d.ts +7 -0
- package/dist/runtime/components/Shared/SidebarNavLink.d.vue.ts +1 -9
- package/dist/runtime/components/Shared/SidebarNavLink.vue +31 -5
- package/dist/runtime/components/Shared/SidebarNavLink.vue.d.ts +1 -9
- package/dist/runtime/components/Shared/SortHeader.vue +6 -2
- package/dist/runtime/components/Shared/StateCard.vue +1 -1
- package/dist/runtime/components/Shared/TabBar.vue +6 -7
- package/dist/runtime/components/Shared/Wizard.d.vue.ts +11 -1
- package/dist/runtime/components/Shared/Wizard.vue +9 -5
- package/dist/runtime/components/Shared/Wizard.vue.d.ts +11 -1
- package/dist/runtime/composables/useMediaLibrary.d.ts +12 -0
- package/dist/runtime/composables/useSavedViews.d.ts +11 -1
- package/dist/runtime/composables/useSavedViews.js +4 -4
- package/dist/runtime/composables/useWidgetFigures.d.ts +12 -0
- package/dist/runtime/composables/useWidgetFigures.js +24 -0
- package/dist/runtime/composables/useWidgetHeader.d.ts +15 -0
- package/dist/runtime/composables/useWidgetHeader.js +15 -0
- package/dist/runtime/lib/auditEnvelope.d.ts +43 -0
- package/dist/runtime/lib/auditEnvelope.js +55 -0
- package/dist/runtime/lib/cardSize.d.ts +13 -0
- package/dist/runtime/lib/cardSize.js +20 -0
- package/dist/runtime/lib/dashboardIcons.js +2 -0
- package/dist/runtime/lib/dataTableFilters.d.ts +22 -0
- package/dist/runtime/lib/dataTableFilters.js +5 -0
- package/dist/runtime/lib/facets.d.ts +13 -0
- package/dist/runtime/lib/formLayout.d.ts +74 -4
- package/dist/runtime/lib/formLayout.js +53 -6
- package/dist/runtime/lib/gridTracks.d.ts +14 -1
- package/dist/runtime/lib/gridTracks.js +13 -2
- package/dist/runtime/lib/isoLists.d.ts +37 -2
- package/dist/runtime/lib/isoLists.js +54 -1
- package/dist/runtime/lib/notice.d.ts +14 -0
- package/dist/runtime/lib/notice.js +19 -0
- package/dist/runtime/lib/pageSize.d.ts +15 -0
- package/dist/runtime/lib/pageSize.js +26 -0
- package/dist/runtime/lib/sidebarAreas.d.ts +46 -0
- package/dist/runtime/lib/sidebarAreas.js +25 -0
- package/dist/runtime/lib/sidebarNav.d.ts +39 -2
- package/dist/runtime/lib/sidebarNav.js +30 -4
- package/dist/runtime/lib/solarIconMap.d.ts +2 -1
- package/dist/runtime/lib/solarIconMap.js +50 -4
- package/dist/runtime/lib/swipeToClose.d.ts +25 -0
- package/dist/runtime/lib/swipeToClose.js +118 -0
- package/dist/runtime/lib/tableExport.d.ts +31 -0
- package/dist/runtime/lib/tableExport.js +143 -0
- package/dist/runtime/lib/talkback.d.ts +5 -0
- package/dist/runtime/lib/talkback.js +8 -0
- package/dist/runtime/lib/talkbackTokenBatch.d.ts +35 -0
- package/dist/runtime/lib/talkbackTokenBatch.js +101 -0
- package/dist/runtime/types/nav.d.ts +9 -0
- package/dist/types.d.mts +4 -0
- package/package.json +4 -3
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Facet, FacetSelection } from '../../lib/facets.js';
|
|
2
|
+
import type { DataTableColumn, DataTableFilter, DataTableRail, DataTableSavedViews, DataTableState, DataTableViewMode, RowKey, SortState } from './types.js';
|
|
2
3
|
declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
4
|
props: import("vue").PublicProps & __VLS_PrettifyLocal<({
|
|
4
5
|
data: T[];
|
|
5
|
-
columns:
|
|
6
|
-
rowKey:
|
|
6
|
+
columns: DataTableColumn<T>[];
|
|
7
|
+
rowKey: RowKey<T>;
|
|
7
8
|
/** `label` is the field's accessible name; it defaults to the placeholder
|
|
8
9
|
* where the surface wrote one (see `searchLabel`). */
|
|
9
10
|
search?: boolean | {
|
|
@@ -20,7 +21,7 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
20
21
|
};
|
|
21
22
|
/** Built-in status/dimension filter pills (static mode). One dimension, or
|
|
22
23
|
* several (each renders as its own sub-menu). */
|
|
23
|
-
filterTabs?:
|
|
24
|
+
filterTabs?: DataTableFilter<T> | DataTableFilter<T>[];
|
|
24
25
|
/**
|
|
25
26
|
* The surface's declared dimensions, as one facet model (PE-6xx).
|
|
26
27
|
*
|
|
@@ -37,17 +38,17 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
37
38
|
* second placement: a tree pinned in a left column beside a panel is two
|
|
38
39
|
* places to look and two commit rules for one question.
|
|
39
40
|
*/
|
|
40
|
-
facets?:
|
|
41
|
+
facets?: Facet[];
|
|
41
42
|
/** Say which facet each chip belongs to (see `FacetChips.showFacet`). */
|
|
42
43
|
chipFacetLabels?: boolean;
|
|
43
44
|
/** Saved views control — the surface supplies snapshot/apply, the table
|
|
44
45
|
* owns the control, the storage and the dialogs. */
|
|
45
|
-
savedViews?:
|
|
46
|
+
savedViews?: DataTableSavedViews | null;
|
|
46
47
|
/** View-mode switch (e.g. List | Gallery). Any mode other than `list`
|
|
47
48
|
* renders the `#view` slot in place of the table body. */
|
|
48
|
-
viewModes?:
|
|
49
|
+
viewModes?: DataTableViewMode[] | null;
|
|
49
50
|
/** Collapse handle for the surface's left rail (see `ListSurface`). */
|
|
50
|
-
rail?: boolean |
|
|
51
|
+
rail?: boolean | DataTableRail;
|
|
51
52
|
/**
|
|
52
53
|
* Scroll the ROWS inside the table instead of the page.
|
|
53
54
|
*
|
|
@@ -73,6 +74,12 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
73
74
|
scrollBody?: boolean | "fit" | {
|
|
74
75
|
maxHeight?: string;
|
|
75
76
|
};
|
|
77
|
+
/**
|
|
78
|
+
* Extra room `'fit'` keeps free under the table — for a bar the host floats
|
|
79
|
+
* over the bottom of the list while rows are selected, so it never covers
|
|
80
|
+
* the pagination row (Re-QA 18.10.).
|
|
81
|
+
*/
|
|
82
|
+
reserveBottom?: number;
|
|
76
83
|
pagination?: boolean | {
|
|
77
84
|
pageSize?: number;
|
|
78
85
|
};
|
|
@@ -110,18 +117,51 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
110
117
|
* above in the sequence.
|
|
111
118
|
*/
|
|
112
119
|
reorderDisabled?: string | null;
|
|
120
|
+
/**
|
|
121
|
+
* Below 768px every row is drawn as a card — title, status badge, two lines
|
|
122
|
+
* of key facts — instead of a grid two columns of which fit (R4, Charge 2).
|
|
123
|
+
* Off for a table that is already narrow by nature.
|
|
124
|
+
*/
|
|
125
|
+
mobileCards?: boolean;
|
|
126
|
+
/** `localStorage` key the row-height choice is remembered under (D4). */
|
|
127
|
+
densityKey?: string;
|
|
128
|
+
/**
|
|
129
|
+
* Which table the rows-per-page choice is remembered for (PE-1052). Falls
|
|
130
|
+
* back to the saved views' `storageKey`; with neither, the size is not kept.
|
|
131
|
+
*/
|
|
132
|
+
pageSizeKey?: string | null;
|
|
133
|
+
/**
|
|
134
|
+
* A table set INTO a card on a detail page (Michael 14.10.): no frame or
|
|
135
|
+
* corners of its own, the grey head row running edge to edge, and the
|
|
136
|
+
* search row plain white — the tinted toolbar is a list page's chrome, and
|
|
137
|
+
* inside a card it read as a second box with too little contrast.
|
|
138
|
+
*/
|
|
139
|
+
embedded?: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Draw the control row at all. A detail-page card hides it until the
|
|
142
|
+
* operator asks (the filter toggle in the card head, Michael 14.10.), so a
|
|
143
|
+
* table of three rows is three rows and not a toolbar with a table under it.
|
|
144
|
+
*/
|
|
145
|
+
toolbar?: boolean;
|
|
113
146
|
} & {
|
|
114
|
-
|
|
147
|
+
query?: string;
|
|
148
|
+
sort?: SortState;
|
|
115
149
|
page?: number;
|
|
116
150
|
viewMode?: string;
|
|
117
151
|
railOpen?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Row height (D4, Charge 2). Standard is 44px with a second line only in the
|
|
154
|
+
* identifying column; compact is 36px and one line everywhere. The reader's
|
|
155
|
+
* choice, remembered across lists — it is about their screen, not one list.
|
|
156
|
+
*/
|
|
157
|
+
density?: "standard" | "compact";
|
|
118
158
|
/**
|
|
119
159
|
* The committed facet selection. Two-way so a chip removed under the toolbar,
|
|
120
160
|
* a facet picked in the surface's pinned rail and the panel's own Apply all
|
|
121
161
|
* write to one place — and so the surface can seed it from a saved view or a
|
|
122
162
|
* URL without this component holding a second copy to drift from.
|
|
123
163
|
*/
|
|
124
|
-
facetSelection?:
|
|
164
|
+
facetSelection?: FacetSelection;
|
|
125
165
|
}) & {
|
|
126
166
|
onRowClick?: ((row: T) => any) | undefined;
|
|
127
167
|
onStateChange?: ((state: DataTableState) => any) | undefined;
|
|
@@ -132,50 +172,49 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
132
172
|
to: number;
|
|
133
173
|
keys: (string | number)[];
|
|
134
174
|
}) => any) | undefined;
|
|
175
|
+
"onUpdate:query"?: ((value: string) => any) | undefined;
|
|
135
176
|
"onUpdate:sort"?: ((value: SortState) => any) | undefined;
|
|
136
177
|
"onUpdate:page"?: ((value: number) => any) | undefined;
|
|
137
178
|
"onUpdate:viewMode"?: ((value: string) => any) | undefined;
|
|
138
179
|
"onUpdate:railOpen"?: ((value: boolean) => any) | undefined;
|
|
180
|
+
"onUpdate:density"?: ((value: "compact" | "standard") => any) | undefined;
|
|
139
181
|
"onUpdate:facetSelection"?: ((value: FacetSelection) => any) | undefined;
|
|
140
182
|
}> & (typeof globalThis extends {
|
|
141
183
|
__VLS_PROPS_FALLBACK: infer P;
|
|
142
184
|
} ? P : {});
|
|
143
|
-
expose: (exposed: {
|
|
185
|
+
expose: (exposed: import("vue").ShallowUnwrapRef<{
|
|
186
|
+
visibleColumns: any;
|
|
187
|
+
}>) => void;
|
|
144
188
|
attrs: any;
|
|
145
189
|
slots: {
|
|
146
|
-
[
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
'
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
} & {
|
|
156
|
-
'toolbar-left'?: (props: {}) => any;
|
|
157
|
-
} & {
|
|
158
|
-
'toolbar-right'?: (props: {}) => any;
|
|
159
|
-
} & {
|
|
160
|
-
actions?: (props: {}) => any;
|
|
161
|
-
} & {
|
|
190
|
+
[name: `header-${string}`]: (props: Record<string, never>) => unknown;
|
|
191
|
+
[name: `cell-${string}`]: (props: {
|
|
192
|
+
row: T;
|
|
193
|
+
}) => unknown;
|
|
194
|
+
'filter-menu'?: (props: Record<string, never>) => unknown;
|
|
195
|
+
scope?: (props: Record<string, never>) => unknown;
|
|
196
|
+
'toolbar-left'?: (props: Record<string, never>) => unknown;
|
|
197
|
+
'toolbar-right'?: (props: Record<string, never>) => unknown;
|
|
198
|
+
actions?: (props: Record<string, never>) => unknown;
|
|
162
199
|
view?: (props: {
|
|
163
|
-
rows:
|
|
200
|
+
rows: T[];
|
|
164
201
|
loading: boolean;
|
|
165
|
-
}) =>
|
|
166
|
-
} & {
|
|
202
|
+
}) => unknown;
|
|
167
203
|
empty?: (props: {
|
|
168
|
-
query:
|
|
169
|
-
filters:
|
|
204
|
+
query: string;
|
|
205
|
+
filters: {
|
|
206
|
+
label: string;
|
|
207
|
+
values: string[];
|
|
208
|
+
}[];
|
|
170
209
|
clear: () => void;
|
|
171
|
-
}) =>
|
|
210
|
+
}) => unknown;
|
|
172
211
|
};
|
|
173
212
|
emit: (((evt: "rowClick", row: T) => void) & ((evt: "stateChange", state: DataTableState) => void) & ((evt: "orderChange", keys: (string | number)[]) => void) & ((evt: "rowMove", move: {
|
|
174
213
|
key: string | number;
|
|
175
214
|
from: number;
|
|
176
215
|
to: number;
|
|
177
216
|
keys: (string | number)[];
|
|
178
|
-
}) => void)) & (((event: "update:sort", value: SortState) => void) & ((event: "update:page", value: number) => void) & ((event: "update:viewMode", value: string) => void) & ((event: "update:railOpen", value: boolean) => void) & ((event: "update:facetSelection", value: FacetSelection) => void));
|
|
217
|
+
}) => void)) & (((event: "update:query", value: string) => void) & ((event: "update:sort", value: SortState) => void) & ((event: "update:page", value: number) => void) & ((event: "update:viewMode", value: string) => void) & ((event: "update:railOpen", value: boolean) => void) & ((event: "update:density", value: "compact" | "standard") => void) & ((event: "update:facetSelection", value: FacetSelection) => void));
|
|
179
218
|
}>) => import("vue").VNode & {
|
|
180
219
|
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
181
220
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, ref, watch } from "vue";
|
|
2
|
+
import { computed, onBeforeUnmount, ref, watch } from "vue";
|
|
3
3
|
import { AltArrowDown, AltArrowRight, Filter, Magnifier } from "#solar-icons";
|
|
4
4
|
import {
|
|
5
5
|
Button,
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
Input,
|
|
8
8
|
Popover,
|
|
9
9
|
PopoverContent,
|
|
10
|
-
PopoverTrigger
|
|
11
|
-
ToolbarFilterTrigger
|
|
10
|
+
PopoverTrigger
|
|
12
11
|
} from "@revenexx/studio";
|
|
12
|
+
import ToolbarLabelTrigger from "./ToolbarLabelTrigger.vue";
|
|
13
13
|
import {
|
|
14
14
|
allNodes,
|
|
15
15
|
copySelection,
|
|
@@ -57,12 +57,54 @@ function matches(facet, label) {
|
|
|
57
57
|
return label.toLowerCase().includes(query.value);
|
|
58
58
|
}
|
|
59
59
|
function visibleOptions(facet) {
|
|
60
|
+
if (facet.search) return searchedOptions(facet);
|
|
60
61
|
return (facet.options ?? []).filter((option) => matches(facet, option.label));
|
|
61
62
|
}
|
|
63
|
+
const remote = ref({});
|
|
64
|
+
const pickedHits = ref({});
|
|
65
|
+
let remoteTimer = null;
|
|
66
|
+
let remoteSeq = 0;
|
|
67
|
+
onBeforeUnmount(() => {
|
|
68
|
+
if (remoteTimer) clearTimeout(remoteTimer);
|
|
69
|
+
});
|
|
70
|
+
function remoteTerm(facet) {
|
|
71
|
+
return !query.value || facet.label.toLowerCase().includes(query.value) ? "" : search.value.trim();
|
|
72
|
+
}
|
|
73
|
+
async function runRemote(facet) {
|
|
74
|
+
if (!facet.search) return;
|
|
75
|
+
const mine = ++remoteSeq;
|
|
76
|
+
remote.value = { ...remote.value, [facet.key]: { options: remote.value[facet.key]?.options ?? [], busy: true } };
|
|
77
|
+
let options = [];
|
|
78
|
+
try {
|
|
79
|
+
options = await facet.search(remoteTerm(facet));
|
|
80
|
+
} catch {
|
|
81
|
+
options = [];
|
|
82
|
+
}
|
|
83
|
+
if (mine !== remoteSeq) return;
|
|
84
|
+
remote.value = { ...remote.value, [facet.key]: { options, busy: false } };
|
|
85
|
+
}
|
|
86
|
+
watch([() => activeFacet.value?.key, query, open], () => {
|
|
87
|
+
const facet = activeFacet.value;
|
|
88
|
+
if (!open.value || !facet?.search) return;
|
|
89
|
+
if (remoteTimer) clearTimeout(remoteTimer);
|
|
90
|
+
remoteTimer = setTimeout(() => {
|
|
91
|
+
void runRemote(facet);
|
|
92
|
+
}, 250);
|
|
93
|
+
}, { immediate: true });
|
|
94
|
+
function searchedOptions(facet) {
|
|
95
|
+
const ticked = draft.value[facet.key];
|
|
96
|
+
const values = Array.isArray(ticked) ? ticked : [];
|
|
97
|
+
const named = new Map((facet.options ?? []).map((o) => [o.value, o]));
|
|
98
|
+
for (const [value, option] of Object.entries(pickedHits.value[facet.key] ?? {})) named.set(value, option);
|
|
99
|
+
const head = values.map((value) => named.get(value) ?? { value, label: value });
|
|
100
|
+
const seen = new Set(values);
|
|
101
|
+
return [...head, ...(remote.value[facet.key]?.options ?? []).filter((o) => !seen.has(o.value))];
|
|
102
|
+
}
|
|
62
103
|
const visibleFacets = computed(() => {
|
|
63
104
|
if (!query.value) return panelFacets.value;
|
|
64
105
|
return panelFacets.value.filter((facet) => {
|
|
65
106
|
if (facet.label.toLowerCase().includes(query.value)) return true;
|
|
107
|
+
if (facet.search) return true;
|
|
66
108
|
if (facet.kind === "check") return visibleOptions(facet).length > 0;
|
|
67
109
|
if (facet.kind === "tree") return visibleNodes(facet).length > 0;
|
|
68
110
|
return false;
|
|
@@ -73,6 +115,8 @@ function isTicked(key, value) {
|
|
|
73
115
|
return Array.isArray(current) && current.includes(value);
|
|
74
116
|
}
|
|
75
117
|
function tick(key, value, on) {
|
|
118
|
+
const hit = remote.value[key]?.options.find((o) => o.value === value);
|
|
119
|
+
if (on && hit) pickedHits.value = { ...pickedHits.value, [key]: { ...pickedHits.value[key] ?? {}, [value]: hit } };
|
|
76
120
|
const single = props.facets.find((f) => f.key === key)?.single;
|
|
77
121
|
draft.value = toggleFacetValue(draft.value, key, value, on, { single });
|
|
78
122
|
}
|
|
@@ -138,8 +182,7 @@ const nothingToReset = computed(() => Object.keys(draft.value).every((key) => is
|
|
|
138
182
|
<template>
|
|
139
183
|
<Popover v-model:open="open">
|
|
140
184
|
<PopoverTrigger as-child>
|
|
141
|
-
<
|
|
142
|
-
icon-only
|
|
185
|
+
<ToolbarLabelTrigger
|
|
143
186
|
:active="appliedCount > 0"
|
|
144
187
|
:count="appliedCount"
|
|
145
188
|
:label="t('shared.facetpanel.trigger.label')"
|
|
@@ -148,7 +191,7 @@ const nothingToReset = computed(() => Object.keys(draft.value).every((key) => is
|
|
|
148
191
|
<template #icon>
|
|
149
192
|
<Filter :size="14" weight="BoldDuotone" />
|
|
150
193
|
</template>
|
|
151
|
-
</
|
|
194
|
+
</ToolbarLabelTrigger>
|
|
152
195
|
</PopoverTrigger>
|
|
153
196
|
|
|
154
197
|
<PopoverContent
|
|
@@ -229,13 +272,19 @@ const nothingToReset = computed(() => Object.keys(draft.value).every((key) => is
|
|
|
229
272
|
<!-- Wraps rather than truncates: a label reading "Net 30 days,
|
|
230
273
|
2% early settlement" is unusable cut off, and the pane cannot
|
|
231
274
|
grow to fit it without becoming the layout it replaced. -->
|
|
232
|
-
<span class="min-w-0 flex-1">
|
|
275
|
+
<span class="min-w-0 flex-1">
|
|
276
|
+
{{ option.label }}
|
|
277
|
+
<span v-if="option.description" class="block text-xs text-muted-foreground">{{ option.description }}</span>
|
|
278
|
+
</span>
|
|
233
279
|
<span
|
|
234
280
|
v-if="option.count !== void 0"
|
|
235
281
|
class="shrink-0 tabular-nums text-muted-foreground"
|
|
236
282
|
>{{ option.count }}</span>
|
|
237
283
|
</label>
|
|
238
|
-
<
|
|
284
|
+
<div v-if="activeFacet.search && remote[activeFacet.key]?.busy && !visibleOptions(activeFacet).length" class="space-y-1.5 p-1">
|
|
285
|
+
<div v-for="i in 4" :key="i" class="h-6 animate-pulse rounded-md bg-muted" />
|
|
286
|
+
</div>
|
|
287
|
+
<p v-else-if="!visibleOptions(activeFacet).length" class="px-1.5 py-6 text-center text-sm text-muted-foreground">
|
|
239
288
|
{{ query ? t("shared.facetpanel.empty.noMatch", { query: search }) : t("shared.facetpanel.empty.noOption") }}
|
|
240
289
|
</p>
|
|
241
290
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { Filter } from "#solar-icons";
|
|
3
|
-
import { Popover, PopoverContent, PopoverTrigger
|
|
3
|
+
import { Popover, PopoverContent, PopoverTrigger } from "@revenexx/studio";
|
|
4
|
+
import ToolbarLabelTrigger from "./ToolbarLabelTrigger.vue";
|
|
4
5
|
defineProps({
|
|
5
6
|
width: { type: String, required: false, default: "w-72" },
|
|
6
7
|
active: { type: Boolean, required: false, default: false },
|
|
@@ -12,16 +13,15 @@ const t = useT();
|
|
|
12
13
|
<template>
|
|
13
14
|
<Popover>
|
|
14
15
|
<PopoverTrigger as-child>
|
|
15
|
-
<
|
|
16
|
-
icon-only
|
|
16
|
+
<ToolbarLabelTrigger
|
|
17
17
|
:active="active"
|
|
18
18
|
:count="count"
|
|
19
|
-
:label="t('shared.datatable.
|
|
19
|
+
:label="t('shared.datatable.toolbar.filter.action')"
|
|
20
20
|
>
|
|
21
21
|
<template #icon>
|
|
22
22
|
<Filter :size="14" weight="BoldDuotone" />
|
|
23
23
|
</template>
|
|
24
|
-
</
|
|
24
|
+
</ToolbarLabelTrigger>
|
|
25
25
|
</PopoverTrigger>
|
|
26
26
|
|
|
27
27
|
<PopoverContent align="start" :class="['p-0', width]">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { Bookmark, CheckCircle, Diskette, TrashBinMinimalistic } from "#solar-icons";
|
|
2
|
+
import { Bookmark, CheckCircle, Diskette, TrashBinMinimalistic, UsersGroupRounded } from "#solar-icons";
|
|
3
3
|
import {
|
|
4
4
|
Button,
|
|
5
5
|
Dialog,
|
|
@@ -14,7 +14,8 @@ import {
|
|
|
14
14
|
DropdownMenuLabel,
|
|
15
15
|
DropdownMenuSeparator,
|
|
16
16
|
DropdownMenuTrigger,
|
|
17
|
-
Input
|
|
17
|
+
Input,
|
|
18
|
+
Switch
|
|
18
19
|
} from "@revenexx/studio";
|
|
19
20
|
import { sameJson } from "../../lib/canonicalJson";
|
|
20
21
|
const props = defineProps({
|
|
@@ -46,11 +47,17 @@ function applyDefault() {
|
|
|
46
47
|
function applyView(v) {
|
|
47
48
|
props.config.apply(v.snapshot);
|
|
48
49
|
}
|
|
50
|
+
const isMine = (v) => v.mine !== false;
|
|
51
|
+
const myViews = computed(() => views.value.filter(isMine));
|
|
52
|
+
const sharedViews = computed(() => views.value.filter((v) => !isMine(v)));
|
|
49
53
|
const saveOpen = ref(false);
|
|
50
54
|
const saveName = ref("");
|
|
55
|
+
const saveShared = ref(false);
|
|
51
56
|
const saving = ref(false);
|
|
52
57
|
function openSave() {
|
|
53
|
-
|
|
58
|
+
const own = appliedView.value && isMine(appliedView.value) ? appliedView.value : null;
|
|
59
|
+
saveName.value = own?.name ?? "";
|
|
60
|
+
saveShared.value = own?.shared === true;
|
|
54
61
|
saveOpen.value = true;
|
|
55
62
|
}
|
|
56
63
|
async function save() {
|
|
@@ -58,8 +65,8 @@ async function save() {
|
|
|
58
65
|
if (!name || saving.value) return;
|
|
59
66
|
saving.value = true;
|
|
60
67
|
try {
|
|
61
|
-
const entry = await store.save(props.config.storageKey, name, props.config.snapshot());
|
|
62
|
-
const at = views.value.findIndex((v) => v.name === name);
|
|
68
|
+
const entry = await store.save(props.config.storageKey, name, props.config.snapshot(), { shared: saveShared.value });
|
|
69
|
+
const at = views.value.findIndex((v) => v.name === name && isMine(v));
|
|
63
70
|
if (at >= 0) views.value.splice(at, 1, entry);
|
|
64
71
|
else views.value = [...views.value, entry].sort((a, b) => a.name.localeCompare(b.name));
|
|
65
72
|
saveOpen.value = false;
|
|
@@ -82,7 +89,8 @@ async function remove() {
|
|
|
82
89
|
<DropdownMenuTrigger as-child>
|
|
83
90
|
<Button
|
|
84
91
|
:variant="hasAppliedView ? 'default' : 'outline'"
|
|
85
|
-
:size="size
|
|
92
|
+
:size="size"
|
|
93
|
+
class="size-8 gap-1.5 px-0"
|
|
86
94
|
:data-active="hasAppliedView"
|
|
87
95
|
:aria-label="t('shared.datatable.savedviews.trigger.aria', { name: activeLabel })"
|
|
88
96
|
:title="t('shared.datatable.savedviews.trigger.aria', { name: activeLabel })"
|
|
@@ -97,6 +105,8 @@ async function remove() {
|
|
|
97
105
|
<span class="flex shrink-0 items-center" :class="hasAppliedView ? '' : 'text-primary'">
|
|
98
106
|
<Bookmark :class="size === 'sm' ? 'size-3.5' : 'size-4'" weight="BoldDuotone" />
|
|
99
107
|
</span>
|
|
108
|
+
<!-- Icon only, the word for screen readers (Michael 12.10.). -->
|
|
109
|
+
<span class="sr-only">{{ t("shared.datatable.savedviews.heading") }}</span>
|
|
100
110
|
</Button>
|
|
101
111
|
</DropdownMenuTrigger>
|
|
102
112
|
<!--
|
|
@@ -105,7 +115,7 @@ async function remove() {
|
|
|
105
115
|
market switcher's and the column picker's grew right — a menu that opens
|
|
106
116
|
the other way is one a reader has to re-find every time.
|
|
107
117
|
-->
|
|
108
|
-
<DropdownMenuContent align="start" class="w-
|
|
118
|
+
<DropdownMenuContent align="start" class="w-80">
|
|
109
119
|
<!-- Named, like the market switcher's "Showing" and the column picker's
|
|
110
120
|
"Columns": a menu of bare rows does not say what it is a menu OF. -->
|
|
111
121
|
<DropdownMenuLabel>{{ t("shared.datatable.savedviews.heading") }}</DropdownMenuLabel>
|
|
@@ -118,16 +128,27 @@ async function remove() {
|
|
|
118
128
|
<span class="flex-1 truncate" :class="isDefault ? 'font-medium text-primary' : ''">{{ allLabel }}</span>
|
|
119
129
|
<CheckCircle v-if="isDefault" :size="14" weight="Bold" class="shrink-0 text-primary" />
|
|
120
130
|
</DropdownMenuItem>
|
|
121
|
-
<template v-if="
|
|
131
|
+
<template v-if="myViews.length">
|
|
122
132
|
<DropdownMenuSeparator />
|
|
133
|
+
<DropdownMenuLabel v-if="sharedViews.length" class="text-xs font-medium text-muted-foreground">
|
|
134
|
+
{{ t("shared.datatable.savedviews.group.mine") }}
|
|
135
|
+
</DropdownMenuLabel>
|
|
123
136
|
<DropdownMenuItem
|
|
124
|
-
v-for="v in
|
|
137
|
+
v-for="v in myViews"
|
|
125
138
|
:key="v.id"
|
|
126
139
|
class="gap-2"
|
|
127
140
|
:aria-current="isActive(v) ? 'true' : void 0"
|
|
128
141
|
@select="applyView(v)"
|
|
129
142
|
>
|
|
130
143
|
<span class="min-w-0 flex-1 truncate" :class="isActive(v) ? 'font-medium text-primary' : ''">{{ v.name }}</span>
|
|
144
|
+
<span
|
|
145
|
+
v-if="v.shared"
|
|
146
|
+
class="inline-flex shrink-0 items-center gap-0.5 rounded border border-primary/20 bg-primary/[0.06] px-1 text-[10.5px] font-medium text-primary"
|
|
147
|
+
:title="t('shared.datatable.savedviews.savedialog.field.shared.label')"
|
|
148
|
+
>
|
|
149
|
+
<UsersGroupRounded :size="11" weight="Bold" />
|
|
150
|
+
{{ t("shared.datatable.savedviews.badge.shared") }}
|
|
151
|
+
</span>
|
|
131
152
|
<CheckCircle v-if="isActive(v)" :size="14" weight="Bold" class="shrink-0 text-primary" />
|
|
132
153
|
<span
|
|
133
154
|
role="button"
|
|
@@ -140,6 +161,26 @@ async function remove() {
|
|
|
140
161
|
</span>
|
|
141
162
|
</DropdownMenuItem>
|
|
142
163
|
</template>
|
|
164
|
+
<template v-if="sharedViews.length">
|
|
165
|
+
<DropdownMenuSeparator />
|
|
166
|
+
<DropdownMenuLabel class="text-xs font-medium text-muted-foreground">
|
|
167
|
+
{{ t("shared.datatable.savedviews.group.shared") }}
|
|
168
|
+
</DropdownMenuLabel>
|
|
169
|
+
<DropdownMenuItem
|
|
170
|
+
v-for="v in sharedViews"
|
|
171
|
+
:key="v.id"
|
|
172
|
+
class="gap-2"
|
|
173
|
+
:aria-current="isActive(v) ? 'true' : void 0"
|
|
174
|
+
@select="applyView(v)"
|
|
175
|
+
>
|
|
176
|
+
<UsersGroupRounded :size="13" weight="Bold" class="shrink-0 text-primary/70" />
|
|
177
|
+
<span class="min-w-0 flex-1 truncate" :class="isActive(v) ? 'font-medium text-primary' : ''">{{ v.name }}</span>
|
|
178
|
+
<span v-if="v.ownerName" class="max-w-24 shrink-0 truncate text-xs text-muted-foreground">
|
|
179
|
+
{{ t("shared.datatable.savedviews.owner", { name: v.ownerName }) }}
|
|
180
|
+
</span>
|
|
181
|
+
<CheckCircle v-if="isActive(v)" :size="14" weight="Bold" class="shrink-0 text-primary" />
|
|
182
|
+
</DropdownMenuItem>
|
|
183
|
+
</template>
|
|
143
184
|
<DropdownMenuSeparator />
|
|
144
185
|
<DropdownMenuItem class="gap-2" @select="openSave">
|
|
145
186
|
<Diskette :size="14" class="shrink-0 text-muted-foreground" />
|
|
@@ -160,7 +201,7 @@ async function remove() {
|
|
|
160
201
|
<Dialog :open="saveOpen" @update:open="(v2) => {
|
|
161
202
|
if (!v2) saveOpen = false;
|
|
162
203
|
}">
|
|
163
|
-
<DialogContent>
|
|
204
|
+
<DialogContent class="sm:max-w-xl">
|
|
164
205
|
<DialogHeader>
|
|
165
206
|
<DialogTitle>{{ t("shared.datatable.savedviews.savedialog.title") }}</DialogTitle>
|
|
166
207
|
<DialogDescription>{{ t("shared.datatable.savedviews.savedialog.description") }}</DialogDescription>
|
|
@@ -174,6 +215,14 @@ async function remove() {
|
|
|
174
215
|
@keydown.enter="save"
|
|
175
216
|
/>
|
|
176
217
|
</div>
|
|
218
|
+
<!-- PE-1052: private by default; the owner may share it with the tenant. -->
|
|
219
|
+
<div class="flex items-start justify-between gap-4 rounded-md border border-black/[0.06] px-3 py-2.5">
|
|
220
|
+
<div class="min-w-0">
|
|
221
|
+
<label for="saved-view-shared" class="text-sm font-medium">{{ t("shared.datatable.savedviews.savedialog.field.shared.label") }}</label>
|
|
222
|
+
<p class="mt-0.5 text-xs text-muted-foreground">{{ t("shared.datatable.savedviews.savedialog.field.shared.hint") }}</p>
|
|
223
|
+
</div>
|
|
224
|
+
<Switch id="saved-view-shared" v-model="saveShared" class="mt-0.5 shrink-0" />
|
|
225
|
+
</div>
|
|
177
226
|
<DialogFooter>
|
|
178
227
|
<Button variant="outline" @click="saveOpen = false">
|
|
179
228
|
{{ t("shared.datatable.savedviews.savedialog.action.cancel") }}
|
|
@@ -189,9 +238,9 @@ async function remove() {
|
|
|
189
238
|
<Dialog :open="deleteTarget !== null" @update:open="(v2) => {
|
|
190
239
|
if (!v2) deleteTarget = null;
|
|
191
240
|
}">
|
|
192
|
-
<DialogContent>
|
|
241
|
+
<DialogContent class="sm:max-w-xl">
|
|
193
242
|
<DialogHeader>
|
|
194
|
-
<DialogTitle>{{ t("shared.datatable.savedviews.deletedialog.title") }}</DialogTitle>
|
|
243
|
+
<DialogTitle>{{ t("shared.datatable.savedviews.deletedialog.title", { name: deleteTarget?.name ?? "" }) }}</DialogTitle>
|
|
195
244
|
<DialogDescription>
|
|
196
245
|
{{ t("shared.datatable.savedviews.deletedialog.description", { name: deleteTarget?.name ?? "" }) }}
|
|
197
246
|
</DialogDescription>
|
|
@@ -37,7 +37,8 @@ function pick(key, direction) {
|
|
|
37
37
|
<DropdownMenuTrigger as-child>
|
|
38
38
|
<Button
|
|
39
39
|
:variant="sorted ? 'default' : 'outline'"
|
|
40
|
-
:size="size
|
|
40
|
+
:size="size"
|
|
41
|
+
class="size-8 gap-1.5 px-0"
|
|
41
42
|
:data-active="sorted"
|
|
42
43
|
:aria-label="t('shared.datatable.sortmenu.aria', { sort: label })"
|
|
43
44
|
:title="t('shared.datatable.sortmenu.aria', { sort: label })"
|
|
@@ -48,6 +49,8 @@ function pick(key, direction) {
|
|
|
48
49
|
<span class="flex shrink-0 items-center" :class="sorted ? '' : 'text-primary'">
|
|
49
50
|
<component :is="icon" weight="Linear" :class="size === 'sm' ? 'size-3.5' : 'size-4'" />
|
|
50
51
|
</span>
|
|
52
|
+
<!-- Icon only, the word for screen readers (Michael 12.10.). -->
|
|
53
|
+
<span class="sr-only">{{ t("shared.datatable.sortmenu.trigger") }}</span>
|
|
51
54
|
</Button>
|
|
52
55
|
</DropdownMenuTrigger>
|
|
53
56
|
<DropdownMenuContent align="start" class="w-56">
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
label: string;
|
|
3
|
+
active?: boolean;
|
|
4
|
+
count?: number;
|
|
5
|
+
size?: 'sm' | 'default';
|
|
6
|
+
};
|
|
7
|
+
declare var __VLS_8: {};
|
|
8
|
+
type __VLS_Slots = {} & {
|
|
9
|
+
icon?: (props: typeof __VLS_8) => any;
|
|
10
|
+
};
|
|
11
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
12
|
+
size: "sm" | "default";
|
|
13
|
+
count: number;
|
|
14
|
+
active: boolean;
|
|
15
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
20
|
+
new (): {
|
|
21
|
+
$slots: S;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { Button } from "@revenexx/studio";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
label: { type: String, required: true },
|
|
5
|
+
active: { type: Boolean, required: false, default: false },
|
|
6
|
+
count: { type: Number, required: false, default: 0 },
|
|
7
|
+
size: { type: String, required: false, default: "sm" }
|
|
8
|
+
});
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<Button
|
|
13
|
+
:variant="props.active ? 'default' : 'outline'"
|
|
14
|
+
:size="props.size"
|
|
15
|
+
class="relative size-8 gap-1.5 px-0"
|
|
16
|
+
:data-active="props.active"
|
|
17
|
+
:aria-label="props.label"
|
|
18
|
+
:title="props.label"
|
|
19
|
+
>
|
|
20
|
+
<span class="flex shrink-0 items-center" :class="props.active ? '' : 'text-primary'">
|
|
21
|
+
<slot name="icon" />
|
|
22
|
+
</span>
|
|
23
|
+
<span class="sr-only">{{ props.label }}</span>
|
|
24
|
+
<span
|
|
25
|
+
v-if="props.active && props.count > 0"
|
|
26
|
+
class="flex h-4 min-w-4 items-center justify-center rounded-full bg-primary-foreground px-1 text-[0.625rem]/none font-semibold tabular-nums text-primary absolute -top-1.5 -right-1.5 bg-primary text-primary-foreground ring-2 ring-card"
|
|
27
|
+
>{{ props.count }}</span>
|
|
28
|
+
</Button>
|
|
29
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
label: string;
|
|
3
|
+
active?: boolean;
|
|
4
|
+
count?: number;
|
|
5
|
+
size?: 'sm' | 'default';
|
|
6
|
+
};
|
|
7
|
+
declare var __VLS_8: {};
|
|
8
|
+
type __VLS_Slots = {} & {
|
|
9
|
+
icon?: (props: typeof __VLS_8) => any;
|
|
10
|
+
};
|
|
11
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
12
|
+
size: "sm" | "default";
|
|
13
|
+
count: number;
|
|
14
|
+
active: boolean;
|
|
15
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
20
|
+
new (): {
|
|
21
|
+
$slots: S;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -25,6 +25,13 @@ export interface DataTableColumn<T = unknown> {
|
|
|
25
25
|
alignRight?: boolean;
|
|
26
26
|
/** Optional icon component for the header. */
|
|
27
27
|
icon?: Component;
|
|
28
|
+
/** The narrowest this column may get when it takes a share (`fr`) of the
|
|
29
|
+
* width — for a name or company column that must stay readable while ID
|
|
30
|
+
* columns size to their content. The `primary` column has its own floor. */
|
|
31
|
+
floor?: string;
|
|
32
|
+
/** Keeps a trailing column (the row's „…“ menu) in view while the table
|
|
33
|
+
* scrolls sideways, like the identifying column on the left. */
|
|
34
|
+
pinRight?: boolean;
|
|
28
35
|
/** Marks the identifying column. When set (and no `#cell-<key>` slot is
|
|
29
36
|
* given) the DataTable renders the value as the bold record anchor —
|
|
30
37
|
* `font-semibold text-[#0B0522]`, truncated — optionally led by a tinted
|
|
@@ -36,7 +43,17 @@ export interface DataTableColumn<T = unknown> {
|
|
|
36
43
|
* `cellIcon` must NOT be a getter: Solar icons are functional components, so
|
|
37
44
|
* the table can't tell a getter from an icon and would crash invoking it.) */
|
|
38
45
|
cellIcon?: Component;
|
|
46
|
+
/**
|
|
47
|
+
* The column's part in the phone layout, where each row is drawn as a card
|
|
48
|
+
* (R4, Charge 2). `title` heads the card (defaults to the `primary` column),
|
|
49
|
+
* `status` sits beside it as the badge, `meta` columns fill the two lines of
|
|
50
|
+
* key facts in declared order, `hidden` leaves the column out. Unset: the
|
|
51
|
+
* table decides from `primary` and the column key.
|
|
52
|
+
*/
|
|
53
|
+
card?: 'title' | 'status' | 'meta' | 'hidden';
|
|
39
54
|
}
|
|
55
|
+
/** Row height (D4, Charge 2): `standard` 44px, `compact` 36px. */
|
|
56
|
+
export type DataTableDensity = 'standard' | 'compact';
|
|
40
57
|
/** A built-in filter dimension rendered under the generic "Filter" dropdown as
|
|
41
58
|
* a labelled sub-menu (datatable-ux). Static mode only: the DataTable filters
|
|
42
59
|
* `data` in-memory and shows a count per option. Pass one, or an array of
|
|
@@ -29,8 +29,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
29
29
|
onCancel?: (() => any) | undefined;
|
|
30
30
|
}>, {
|
|
31
31
|
dirty: boolean;
|
|
32
|
-
canSubmit: boolean;
|
|
33
32
|
busy: boolean;
|
|
33
|
+
canSubmit: boolean;
|
|
34
34
|
allowClean: boolean;
|
|
35
35
|
hideCancel: boolean;
|
|
36
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|