nuxt-ui-tools 1.14.0 → 1.16.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/dist/module.json +1 -1
- package/dist/runtime/form/fields/matrix/component.vue +4 -1
- package/dist/runtime/form/fields/matrix/types.d.ts +2 -0
- package/dist/runtime/table/components/actions/row-actions.d.vue.ts +3 -3
- package/dist/runtime/table/components/actions/row-actions.vue +14 -8
- package/dist/runtime/table/components/actions/row-actions.vue.d.ts +3 -3
- package/dist/runtime/table/components/table/table-empty-state.vue +5 -4
- package/dist/runtime/table/composables/use-table-columns.js +25 -42
- package/dist/runtime/table/types/actions.d.ts +5 -0
- package/dist/runtime/table/utils/actions.d.ts +4 -0
- package/dist/runtime/table/utils/actions.js +11 -0
- package/dist/runtime/table/utils/columns/index.d.ts +1 -0
- package/dist/runtime/table/utils/columns/index.js +1 -0
- package/dist/runtime/table/utils/columns/preferences.d.ts +40 -0
- package/dist/runtime/table/utils/columns/preferences.js +145 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -91,13 +91,16 @@ function controlClass(field) {
|
|
|
91
91
|
mergeFormUiClass(
|
|
92
92
|
[
|
|
93
93
|
rowPadding,
|
|
94
|
+
'text-left font-medium',
|
|
94
95
|
bordered ? 'border-b border-r border-default' : 'border-b border-default'
|
|
95
96
|
].join(' '),
|
|
96
97
|
formUi.ui.value.matrix?.ui?.corner
|
|
97
98
|
)
|
|
98
99
|
"
|
|
99
100
|
:style="{ width: rowHeaderWidth, minWidth: rowHeaderWidth }"
|
|
100
|
-
|
|
101
|
+
>
|
|
102
|
+
{{ resolveFormText(fieldProps.rowHeaderLabel) }}
|
|
103
|
+
</th>
|
|
101
104
|
<th
|
|
102
105
|
v-for="column in visibleFields"
|
|
103
106
|
:id="columnLabelId(column)"
|
|
@@ -17,6 +17,8 @@ export type FormMatrixEntry = FormMatrixRow | FormMatrixSection;
|
|
|
17
17
|
export interface FormMatrixProps {
|
|
18
18
|
minWidth?: number | string;
|
|
19
19
|
rowHeaderWidth?: number | string;
|
|
20
|
+
/** Heading of the row label column, shown in the header corner. */
|
|
21
|
+
rowHeaderLabel?: FormText;
|
|
20
22
|
bordered?: boolean;
|
|
21
23
|
striped?: boolean;
|
|
22
24
|
hoverable?: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DropdownMenuProps } from '@nuxt/ui/components/DropdownMenu.vue';
|
|
1
|
+
import type { DropdownMenuItem, DropdownMenuProps } from '@nuxt/ui/components/DropdownMenu.vue';
|
|
2
2
|
import type { DataListControlSize } from '../../types/index.js';
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
content?: DropdownMenuProps['content'];
|
|
@@ -10,10 +10,10 @@ type __VLS_Props = {
|
|
|
10
10
|
ui?: DropdownMenuProps['ui'];
|
|
11
11
|
};
|
|
12
12
|
declare var __VLS_8: {
|
|
13
|
-
items:
|
|
13
|
+
items: DropdownMenuItem[][];
|
|
14
14
|
open: boolean;
|
|
15
15
|
}, __VLS_24: {
|
|
16
|
-
items:
|
|
16
|
+
items: DropdownMenuItem[][];
|
|
17
17
|
open: boolean;
|
|
18
18
|
};
|
|
19
19
|
type __VLS_Slots = {} & {
|
|
@@ -6,7 +6,7 @@ import { computed, ref, useAttrs } from "vue";
|
|
|
6
6
|
import { useDataListBreakpoint } from "../../composables/use-data-list-breakpoint";
|
|
7
7
|
import { useTableInternals } from "../../composables/use-table-internals";
|
|
8
8
|
import { useTableRowActionScope } from "../../composables/use-table-row-actions";
|
|
9
|
-
import {
|
|
9
|
+
import { createRowActionDropdownGroups, resolveVisibleTableRowActions } from "../../utils";
|
|
10
10
|
defineOptions({
|
|
11
11
|
inheritAttrs: false
|
|
12
12
|
});
|
|
@@ -23,12 +23,18 @@ const attrs = useAttrs();
|
|
|
23
23
|
const internals = useTableInternals();
|
|
24
24
|
const { isMobile } = useDataListBreakpoint();
|
|
25
25
|
const sheetOpen = ref(false);
|
|
26
|
-
const sheetItems = computed(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
const sheetItems = computed(
|
|
27
|
+
() => items.value.flatMap(
|
|
28
|
+
(group, index) => group.map((item, itemIndex) => ({
|
|
29
|
+
color: item.color,
|
|
30
|
+
disabled: item.disabled,
|
|
31
|
+
dividerBefore: index > 0 && itemIndex === 0,
|
|
32
|
+
icon: item.icon,
|
|
33
|
+
label: item.label,
|
|
34
|
+
onSelect: item.onSelect
|
|
35
|
+
}))
|
|
36
|
+
)
|
|
37
|
+
);
|
|
32
38
|
function runSheetItem(item) {
|
|
33
39
|
sheetOpen.value = false;
|
|
34
40
|
item.onSelect?.(new Event("select"));
|
|
@@ -48,7 +54,7 @@ const items = computed(() => {
|
|
|
48
54
|
if (!scope?.value) {
|
|
49
55
|
return [];
|
|
50
56
|
}
|
|
51
|
-
return
|
|
57
|
+
return createRowActionDropdownGroups({
|
|
52
58
|
actions: visibleActions.value,
|
|
53
59
|
scope: scope.value
|
|
54
60
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DropdownMenuProps } from '@nuxt/ui/components/DropdownMenu.vue';
|
|
1
|
+
import type { DropdownMenuItem, DropdownMenuProps } from '@nuxt/ui/components/DropdownMenu.vue';
|
|
2
2
|
import type { DataListControlSize } from '../../types/index.js';
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
content?: DropdownMenuProps['content'];
|
|
@@ -10,10 +10,10 @@ type __VLS_Props = {
|
|
|
10
10
|
ui?: DropdownMenuProps['ui'];
|
|
11
11
|
};
|
|
12
12
|
declare var __VLS_8: {
|
|
13
|
-
items:
|
|
13
|
+
items: DropdownMenuItem[][];
|
|
14
14
|
open: boolean;
|
|
15
15
|
}, __VLS_24: {
|
|
16
|
-
items:
|
|
16
|
+
items: DropdownMenuItem[][];
|
|
17
17
|
open: boolean;
|
|
18
18
|
};
|
|
19
19
|
type __VLS_Slots = {} & {
|
|
@@ -18,17 +18,18 @@ const emptyProps = computed(() => dataListUi.ui.value.table?.props?.empty);
|
|
|
18
18
|
const filtered = computed(
|
|
19
19
|
() => internals.filters.hasActiveUiFilters.value || Boolean(internals.filters.searchQuery.value)
|
|
20
20
|
);
|
|
21
|
+
const custom = computed(() => filtered.value ? void 0 : emptyProps.value);
|
|
21
22
|
const icon = computed(
|
|
22
|
-
() =>
|
|
23
|
+
() => custom.value?.icon ?? (filtered.value ? "i-lucide-search-x" : "i-lucide-inbox")
|
|
23
24
|
);
|
|
24
25
|
const title = computed(
|
|
25
|
-
() =>
|
|
26
|
+
() => custom.value?.title ?? (filtered.value ? t("table.states.empty.filteredTitle") : t("table.states.empty.title"))
|
|
26
27
|
);
|
|
27
28
|
const description = computed(() => {
|
|
28
|
-
if (
|
|
29
|
+
if (custom.value?.description === false) {
|
|
29
30
|
return "";
|
|
30
31
|
}
|
|
31
|
-
return
|
|
32
|
+
return custom.value?.description || (filtered.value ? t("table.states.empty.filteredDescription") : t("table.states.empty.description"));
|
|
32
33
|
});
|
|
33
34
|
function reset() {
|
|
34
35
|
internals.filters.clearAllFilters();
|
|
@@ -2,6 +2,9 @@ import { useCookie } from "nuxt/app";
|
|
|
2
2
|
import { computed, ref, watch } from "vue";
|
|
3
3
|
import {
|
|
4
4
|
ROW_ACTIONS_COLUMN_ID,
|
|
5
|
+
applyColumnPreferences,
|
|
6
|
+
decodeColumnPreferences,
|
|
7
|
+
encodeColumnPreferences,
|
|
5
8
|
hasVisibleTableRowActions,
|
|
6
9
|
createColumnMenuItems,
|
|
7
10
|
createDefaultColumnState,
|
|
@@ -79,12 +82,18 @@ export function useTableColumns(params) {
|
|
|
79
82
|
{ immediate: true }
|
|
80
83
|
);
|
|
81
84
|
const persistPreferences = computed(() => params.schema.value.persistence?.preferences !== false);
|
|
82
|
-
const preferencesCookie = useCookie(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
const preferencesCookie = useCookie(`${params.schema.value.tableKey}::columns`, {
|
|
86
|
+
decode: (value) => value ?? null,
|
|
87
|
+
default: () => null,
|
|
88
|
+
encode: (value) => value ?? "",
|
|
89
|
+
maxAge: 60 * 60 * 24 * 365
|
|
90
|
+
});
|
|
91
|
+
const storedPreferences = persistPreferences.value ? decodeColumnPreferences(preferencesCookie.value) : null;
|
|
92
|
+
if (storedPreferences) {
|
|
93
|
+
tableState.value = applyColumnPreferences({
|
|
94
|
+
preferences: storedPreferences,
|
|
95
|
+
state: tableState.value
|
|
96
|
+
});
|
|
88
97
|
}
|
|
89
98
|
watch(
|
|
90
99
|
tableState,
|
|
@@ -92,12 +101,19 @@ export function useTableColumns(params) {
|
|
|
92
101
|
if (!persistPreferences.value) {
|
|
93
102
|
return;
|
|
94
103
|
}
|
|
95
|
-
const next =
|
|
96
|
-
|
|
104
|
+
const next = encodeColumnPreferences({
|
|
105
|
+
defaults: createResetColumnState({
|
|
106
|
+
currentState: state,
|
|
107
|
+
runtimeColumns: runtimeColumns.value,
|
|
108
|
+
schema: params.schema.value
|
|
109
|
+
}),
|
|
110
|
+
state
|
|
111
|
+
});
|
|
112
|
+
if (next !== preferencesCookie.value) {
|
|
97
113
|
preferencesCookie.value = next;
|
|
98
114
|
}
|
|
99
115
|
},
|
|
100
|
-
{ deep: true }
|
|
116
|
+
{ deep: true, immediate: true }
|
|
101
117
|
);
|
|
102
118
|
watch(
|
|
103
119
|
() => params.state.queryState.sorting.value,
|
|
@@ -251,36 +267,3 @@ export function useTableColumns(params) {
|
|
|
251
267
|
visibleOrderedColumns
|
|
252
268
|
};
|
|
253
269
|
}
|
|
254
|
-
function toPersistedPreferences(state) {
|
|
255
|
-
return {
|
|
256
|
-
order: state.columnOrder,
|
|
257
|
-
pinning: state.columnPinning,
|
|
258
|
-
sizing: state.columnSizing,
|
|
259
|
-
visibility: state.columnVisibility
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
function applyPersistedPreferences(state, persisted) {
|
|
263
|
-
const known = new Set(state.columnOrder);
|
|
264
|
-
return {
|
|
265
|
-
...state,
|
|
266
|
-
columnOrder: [
|
|
267
|
-
...persisted.order.filter((id) => known.has(id)),
|
|
268
|
-
...state.columnOrder.filter((id) => !persisted.order.includes(id))
|
|
269
|
-
],
|
|
270
|
-
columnPinning: {
|
|
271
|
-
left: (persisted.pinning.left ?? state.columnPinning.left ?? []).filter(
|
|
272
|
-
(id) => known.has(id)
|
|
273
|
-
),
|
|
274
|
-
right: (persisted.pinning.right ?? state.columnPinning.right ?? []).filter(
|
|
275
|
-
(id) => known.has(id)
|
|
276
|
-
)
|
|
277
|
-
},
|
|
278
|
-
columnSizing: Object.fromEntries(
|
|
279
|
-
Object.entries(persisted.sizing).filter(([id]) => known.has(id))
|
|
280
|
-
),
|
|
281
|
-
columnVisibility: {
|
|
282
|
-
...state.columnVisibility,
|
|
283
|
-
...Object.fromEntries(Object.entries(persisted.visibility).filter(([id]) => known.has(id)))
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
}
|
|
@@ -57,6 +57,11 @@ export interface TableRowActionContext<TRow extends GenericObject = GenericObjec
|
|
|
57
57
|
export interface TableRowAction<TRow extends GenericObject = GenericObject, TContext extends GenericObject = GenericObject, TPageContext extends GenericObject = GenericObject> extends Omit<DropdownMenuItem, 'children' | 'disabled' | 'loading' | 'label' | 'onSelect'> {
|
|
58
58
|
key: string;
|
|
59
59
|
label?: TableTextValue;
|
|
60
|
+
/**
|
|
61
|
+
* Actions sharing a group render together, separated from the other groups by a divider.
|
|
62
|
+
* Groups follow the order of their first visible action; actions without a group share one.
|
|
63
|
+
*/
|
|
64
|
+
group?: string;
|
|
60
65
|
condition?: boolean | ((context: TableRowActionContext<TRow, TContext, TPageContext>) => boolean);
|
|
61
66
|
disabled?: boolean | ((context: TableRowActionContext<TRow, TContext, TPageContext>) => boolean);
|
|
62
67
|
loading?: boolean | ((context: TableRowActionContext<TRow, TContext, TPageContext>) => boolean);
|
|
@@ -38,5 +38,9 @@ export declare function createRowActionDropdownItems(options: {
|
|
|
38
38
|
actions: ResolvedRowAction[];
|
|
39
39
|
scope: TableInjectedRowActionScope;
|
|
40
40
|
}): DropdownMenuItem[];
|
|
41
|
+
export declare function createRowActionDropdownGroups(options: {
|
|
42
|
+
actions: ResolvedRowAction[];
|
|
43
|
+
scope: TableInjectedRowActionScope;
|
|
44
|
+
}): DropdownMenuItem[][];
|
|
41
45
|
export declare function resolveTableActionLabel(label: TableTextValue | undefined): string | undefined;
|
|
42
46
|
export {};
|
|
@@ -44,6 +44,16 @@ export function createRowActionDropdownItems(options) {
|
|
|
44
44
|
(action) => mapRowActionToDropdownItem({ action, scope: options.scope })
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
|
+
export function createRowActionDropdownGroups(options) {
|
|
48
|
+
const groups = /* @__PURE__ */ new Map();
|
|
49
|
+
for (const action of options.actions) {
|
|
50
|
+
const key = action.group ?? "";
|
|
51
|
+
const items = groups.get(key) ?? [];
|
|
52
|
+
items.push(mapRowActionToDropdownItem({ action, scope: options.scope }));
|
|
53
|
+
groups.set(key, items);
|
|
54
|
+
}
|
|
55
|
+
return [...groups.values()];
|
|
56
|
+
}
|
|
47
57
|
function mapRowActionToDropdownItem(options) {
|
|
48
58
|
const children = options.action.children ? createRowActionDropdownItems({
|
|
49
59
|
actions: options.action.children,
|
|
@@ -67,6 +77,7 @@ function mapRowActionToDropdownItem(options) {
|
|
|
67
77
|
};
|
|
68
78
|
delete item.condition;
|
|
69
79
|
delete item.action;
|
|
80
|
+
delete item.group;
|
|
70
81
|
return item;
|
|
71
82
|
}
|
|
72
83
|
function resolveActionLabel(action) {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { TableColumnState } from './types.js';
|
|
2
|
+
export interface ColumnPreferences {
|
|
3
|
+
order?: string[];
|
|
4
|
+
hidden?: string[];
|
|
5
|
+
shown?: string[];
|
|
6
|
+
left?: string[];
|
|
7
|
+
right?: string[];
|
|
8
|
+
widths?: Record<string, number>;
|
|
9
|
+
}
|
|
10
|
+
export declare function encodeColumnPreferences(options: {
|
|
11
|
+
state: TableColumnState;
|
|
12
|
+
defaults: TableColumnState;
|
|
13
|
+
}): string | null;
|
|
14
|
+
export declare function decodeColumnPreferences(value: string | null | undefined): ColumnPreferences | null;
|
|
15
|
+
export declare function applyColumnPreferences(options: {
|
|
16
|
+
state: TableColumnState;
|
|
17
|
+
preferences: ColumnPreferences;
|
|
18
|
+
}): {
|
|
19
|
+
columnOrder: string[];
|
|
20
|
+
columnPinning: {
|
|
21
|
+
left: string[];
|
|
22
|
+
right: string[];
|
|
23
|
+
};
|
|
24
|
+
columnSizing: Record<string, number>;
|
|
25
|
+
columnVisibility: {
|
|
26
|
+
[x: string]: boolean;
|
|
27
|
+
};
|
|
28
|
+
columnSizingInfo: {
|
|
29
|
+
startOffset: number | null;
|
|
30
|
+
startSize: number | null;
|
|
31
|
+
deltaOffset: number | null;
|
|
32
|
+
deltaPercentage: number | null;
|
|
33
|
+
isResizingColumn: false | string;
|
|
34
|
+
columnSizingStart: [string, number][];
|
|
35
|
+
};
|
|
36
|
+
sorting: {
|
|
37
|
+
id: string;
|
|
38
|
+
desc: boolean;
|
|
39
|
+
}[];
|
|
40
|
+
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { isArray, isFiniteNumber, isPlainObject, isString } from "../../../shared/utils/predicate.js";
|
|
2
|
+
import { uniqueColumnIds } from "./schema.js";
|
|
3
|
+
import { ROW_ACTIONS_COLUMN_ID, SELECT_COLUMN_ID } from "./types.js";
|
|
4
|
+
const FORMAT_VERSION = "1";
|
|
5
|
+
const SECTION_SEPARATOR = "!";
|
|
6
|
+
const ITEM_SEPARATOR = "~";
|
|
7
|
+
const WIDTH_SEPARATOR = "*";
|
|
8
|
+
const INTERNAL_COLUMN_IDS = /* @__PURE__ */ new Set([SELECT_COLUMN_ID, ROW_ACTIONS_COLUMN_ID]);
|
|
9
|
+
export function encodeColumnPreferences(options) {
|
|
10
|
+
const sections = [];
|
|
11
|
+
const order = userColumnIds(options.state.columnOrder);
|
|
12
|
+
const defaultOrder = userColumnIds(options.defaults.columnOrder);
|
|
13
|
+
const visibilityChanges = defaultOrder.filter(
|
|
14
|
+
(id) => (options.state.columnVisibility[id] ?? options.defaults.columnVisibility[id]) !== options.defaults.columnVisibility[id]
|
|
15
|
+
);
|
|
16
|
+
const left = userColumnIds(options.state.columnPinning.left ?? []);
|
|
17
|
+
const right = userColumnIds(options.state.columnPinning.right ?? []);
|
|
18
|
+
const widths = Object.entries(options.state.columnSizing).filter(
|
|
19
|
+
([, width]) => Number.isFinite(width)
|
|
20
|
+
);
|
|
21
|
+
if (!sameIds(order, defaultOrder)) {
|
|
22
|
+
sections.push(`o${joinIds(order)}`);
|
|
23
|
+
}
|
|
24
|
+
const hidden = visibilityChanges.filter((id) => options.state.columnVisibility[id] === false);
|
|
25
|
+
const shown = visibilityChanges.filter((id) => options.state.columnVisibility[id] === true);
|
|
26
|
+
if (hidden.length) {
|
|
27
|
+
sections.push(`h${joinIds(hidden)}`);
|
|
28
|
+
}
|
|
29
|
+
if (shown.length) {
|
|
30
|
+
sections.push(`v${joinIds(shown)}`);
|
|
31
|
+
}
|
|
32
|
+
if (!sameIds(left, userColumnIds(options.defaults.columnPinning.left ?? []))) {
|
|
33
|
+
sections.push(`l${joinIds(left)}`);
|
|
34
|
+
}
|
|
35
|
+
if (!sameIds(right, userColumnIds(options.defaults.columnPinning.right ?? []))) {
|
|
36
|
+
sections.push(`r${joinIds(right)}`);
|
|
37
|
+
}
|
|
38
|
+
if (widths.length) {
|
|
39
|
+
sections.push(
|
|
40
|
+
`w${widths.map(([id, width]) => `${escapeId(id)}${WIDTH_SEPARATOR}${Math.round(width)}`).join(ITEM_SEPARATOR)}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return sections.length ? [FORMAT_VERSION, ...sections].join(SECTION_SEPARATOR) : null;
|
|
44
|
+
}
|
|
45
|
+
export function decodeColumnPreferences(value) {
|
|
46
|
+
if (!value) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
if (value.startsWith("{") || value.startsWith("%7B")) {
|
|
50
|
+
return decodeLegacyPreferences(value);
|
|
51
|
+
}
|
|
52
|
+
const [version, ...sections] = value.split(SECTION_SEPARATOR);
|
|
53
|
+
if (version !== FORMAT_VERSION) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const preferences = {};
|
|
57
|
+
for (const section of sections) {
|
|
58
|
+
const key = section.charAt(0);
|
|
59
|
+
const ids = splitIds(section.slice(1));
|
|
60
|
+
if (key === "o") preferences.order = ids;
|
|
61
|
+
else if (key === "h") preferences.hidden = ids;
|
|
62
|
+
else if (key === "v") preferences.shown = ids;
|
|
63
|
+
else if (key === "l") preferences.left = ids;
|
|
64
|
+
else if (key === "r") preferences.right = ids;
|
|
65
|
+
else if (key === "w") preferences.widths = decodeWidths(section.slice(1));
|
|
66
|
+
}
|
|
67
|
+
return preferences;
|
|
68
|
+
}
|
|
69
|
+
export function applyColumnPreferences(options) {
|
|
70
|
+
const known = new Set(options.state.columnOrder);
|
|
71
|
+
const keep = (ids) => (ids ?? []).filter((id) => known.has(id));
|
|
72
|
+
const { preferences, state } = options;
|
|
73
|
+
const order = keep(preferences.order);
|
|
74
|
+
return {
|
|
75
|
+
...state,
|
|
76
|
+
columnOrder: preferences.order ? uniqueColumnIds({ columnIds: [...order, ...state.columnOrder] }) : state.columnOrder,
|
|
77
|
+
columnPinning: {
|
|
78
|
+
left: preferences.left ? uniqueColumnIds({ columnIds: [SELECT_COLUMN_ID, ...keep(preferences.left)] }) : state.columnPinning.left ?? [],
|
|
79
|
+
right: preferences.right ? withRowActionsLast({
|
|
80
|
+
ids: keep(preferences.right),
|
|
81
|
+
hadRowActions: (state.columnPinning.right ?? []).includes(ROW_ACTIONS_COLUMN_ID)
|
|
82
|
+
}) : state.columnPinning.right ?? []
|
|
83
|
+
},
|
|
84
|
+
columnSizing: preferences.widths ? Object.fromEntries(Object.entries(preferences.widths).filter(([id]) => known.has(id))) : state.columnSizing,
|
|
85
|
+
columnVisibility: {
|
|
86
|
+
...state.columnVisibility,
|
|
87
|
+
...Object.fromEntries(keep(preferences.hidden).map((id) => [id, false])),
|
|
88
|
+
...Object.fromEntries(keep(preferences.shown).map((id) => [id, true]))
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function decodeLegacyPreferences(value) {
|
|
93
|
+
let legacy;
|
|
94
|
+
try {
|
|
95
|
+
legacy = JSON.parse(value.startsWith("{") ? value : decodeURIComponent(value));
|
|
96
|
+
} catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
if (!isPlainObject(legacy)) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const visibility = isPlainObject(legacy.visibility) ? Object.entries(legacy.visibility) : [];
|
|
103
|
+
const pinning = isPlainObject(legacy.pinning) ? legacy.pinning : {};
|
|
104
|
+
return {
|
|
105
|
+
hidden: visibility.filter(([, visible]) => visible === false).map(([id]) => id),
|
|
106
|
+
left: isArray(pinning.left) ? pinning.left.filter((id) => isString(id)) : void 0,
|
|
107
|
+
order: isArray(legacy.order) ? legacy.order.filter((id) => isString(id)) : void 0,
|
|
108
|
+
right: isArray(pinning.right) ? pinning.right.filter((id) => isString(id)) : void 0,
|
|
109
|
+
widths: isPlainObject(legacy.sizing) ? Object.fromEntries(
|
|
110
|
+
Object.entries(legacy.sizing).filter(
|
|
111
|
+
(entry) => isFiniteNumber(entry[1])
|
|
112
|
+
)
|
|
113
|
+
) : void 0
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function decodeWidths(value) {
|
|
117
|
+
return Object.fromEntries(
|
|
118
|
+
value.split(ITEM_SEPARATOR).flatMap((entry) => {
|
|
119
|
+
const separator = entry.lastIndexOf(WIDTH_SEPARATOR);
|
|
120
|
+
const width = Number(entry.slice(separator + 1));
|
|
121
|
+
return separator > 0 && Number.isFinite(width) ? [[decodeURIComponent(entry.slice(0, separator)), width]] : [];
|
|
122
|
+
})
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
function userColumnIds(ids) {
|
|
126
|
+
return ids.filter((id) => !INTERNAL_COLUMN_IDS.has(id));
|
|
127
|
+
}
|
|
128
|
+
function sameIds(first, second) {
|
|
129
|
+
return first.length === second.length && first.every((id, index) => id === second[index]);
|
|
130
|
+
}
|
|
131
|
+
function joinIds(ids) {
|
|
132
|
+
return ids.map(escapeId).join(ITEM_SEPARATOR);
|
|
133
|
+
}
|
|
134
|
+
function splitIds(value) {
|
|
135
|
+
return value ? value.split(ITEM_SEPARATOR).map((id) => decodeURIComponent(id)) : [];
|
|
136
|
+
}
|
|
137
|
+
function escapeId(id) {
|
|
138
|
+
return encodeURIComponent(id).replace(
|
|
139
|
+
/[!'()*~]/gu,
|
|
140
|
+
(character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
function withRowActionsLast(options) {
|
|
144
|
+
return options.hadRowActions ? [...options.ids, ROW_ACTIONS_COLUMN_ID] : options.ids;
|
|
145
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-ui-tools",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Nuxt module and runtime toolkit for UI-heavy Nuxt applications",
|
|
5
5
|
"homepage": "https://github.com/ChronicStone/nuxt-ui-tools#readme",
|
|
6
6
|
"bugs": "https://github.com/ChronicStone/nuxt-ui-tools/issues",
|