nuxt-ui-tools 1.5.0 → 1.6.1
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/module.mjs +1 -0
- package/dist/runtime/i18n/locales/en.js +23 -2
- package/dist/runtime/i18n/locales/fr.js +23 -2
- package/dist/runtime/i18n/types.d.ts +21 -0
- package/dist/runtime/table/components/data-list/data-list-content.vue +7 -1
- package/dist/runtime/table/components/data-list/data-list-error-state.d.vue.ts +18 -1
- package/dist/runtime/table/components/data-list/data-list-error-state.vue +65 -41
- package/dist/runtime/table/components/data-list/data-list-error-state.vue.d.ts +18 -1
- package/dist/runtime/table/components/data-list/sort-menu-panel.vue +33 -25
- package/dist/runtime/table/components/drawers/column-panel.vue +19 -6
- package/dist/runtime/table/components/filters/shared/dynamic-filter-picker.vue +1 -1
- package/dist/runtime/table/components/filters/shared/filter-editor-header.d.vue.ts +16 -0
- package/dist/runtime/table/components/filters/shared/filter-editor-header.vue +46 -0
- package/dist/runtime/table/components/filters/shared/filter-editor-header.vue.d.ts +16 -0
- package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.d.vue.ts +3 -1
- package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue +5 -4
- package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue.d.ts +3 -1
- package/dist/runtime/table/components/filters/shared/filter-option-picker-content.vue +4 -1
- package/dist/runtime/table/components/filters/shared/filter-option-single-list.vue +3 -3
- package/dist/runtime/table/components/filters/shared/filter-option-tree-content.vue +7 -3
- package/dist/runtime/table/components/filters/shared/filter-popover-shell.vue +10 -1
- package/dist/runtime/table/components/filters/shared/filter-searchable-panel.vue +14 -6
- package/dist/runtime/table/components/filters/shared/filter-trigger-tag.vue +5 -1
- package/dist/runtime/table/components/filters/tags/boolean-filter-tag.d.vue.ts +6 -1
- package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue +19 -5
- package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue.d.ts +6 -1
- package/dist/runtime/table/components/filters/tags/date-filter-tag.d.vue.ts +6 -1
- package/dist/runtime/table/components/filters/tags/date-filter-tag.vue +65 -29
- package/dist/runtime/table/components/filters/tags/date-filter-tag.vue.d.ts +6 -1
- package/dist/runtime/table/components/filters/tags/number-filter-tag.d.vue.ts +6 -1
- package/dist/runtime/table/components/filters/tags/number-filter-tag.vue +66 -18
- package/dist/runtime/table/components/filters/tags/number-filter-tag.vue.d.ts +6 -1
- package/dist/runtime/table/components/filters/tags/option-filter-tag.d.vue.ts +2 -2
- package/dist/runtime/table/components/filters/tags/option-filter-tag.vue +10 -34
- package/dist/runtime/table/components/filters/tags/option-filter-tag.vue.d.ts +2 -2
- package/dist/runtime/table/components/filters/tags/text-filter-tag.d.vue.ts +6 -1
- package/dist/runtime/table/components/filters/tags/text-filter-tag.vue +39 -14
- package/dist/runtime/table/components/filters/tags/text-filter-tag.vue.d.ts +6 -1
- package/dist/runtime/table/components/grid/grid-renderer.d.vue.ts +8 -2
- package/dist/runtime/table/components/grid/grid-renderer.vue +47 -115
- package/dist/runtime/table/components/grid/grid-renderer.vue.d.ts +8 -2
- package/dist/runtime/table/components/layout/progress-line.d.vue.ts +9 -0
- package/dist/runtime/table/components/layout/progress-line.vue +43 -0
- package/dist/runtime/table/components/layout/progress-line.vue.d.ts +9 -0
- package/dist/runtime/table/components/table/table-empty-state.d.vue.ts +1 -1
- package/dist/runtime/table/components/table/table-empty-state.vue +1 -1
- package/dist/runtime/table/components/table/table-empty-state.vue.d.ts +1 -1
- package/dist/runtime/table/components/table/table-layout.d.ts +57 -0
- package/dist/runtime/table/components/table/table-layout.js +23 -0
- package/dist/runtime/table/components/table/table-renderer.d.vue.ts +8 -16
- package/dist/runtime/table/components/table/table-renderer.vue +180 -274
- package/dist/runtime/table/components/table/table-renderer.vue.d.ts +8 -16
- package/dist/runtime/table/components/table/table-row.d.vue.ts +19 -0
- package/dist/runtime/table/components/table/table-row.vue +51 -0
- package/dist/runtime/table/components/table/table-row.vue.d.ts +19 -0
- package/dist/runtime/table/components/table/table-skeleton-cell.d.ts +9 -0
- package/dist/runtime/table/components/table/table-skeleton-cell.js +104 -0
- package/dist/runtime/table/components/utils/search-query-input.vue +27 -1
- package/dist/runtime/table/composables/use-deferred-commit.d.ts +20 -0
- package/dist/runtime/table/composables/use-deferred-commit.js +31 -0
- package/dist/runtime/table/composables/use-table-data.d.ts +5 -1
- package/dist/runtime/table/composables/use-table-data.js +20 -2
- package/dist/runtime/table/composables/use-table-summaries.js +10 -1
- package/dist/runtime/table/types/columns.d.ts +18 -3
- package/dist/runtime/table/types/data-list.d.ts +1 -0
- package/dist/runtime/table/types/layout.d.ts +1 -1
- package/dist/runtime/table/utils/columns/defs.js +1 -1
- package/dist/runtime/table/utils/filters/date.d.ts +6 -0
- package/dist/runtime/table/utils/filters/date.js +26 -2
- package/dist/runtime/table/utils/filters/index.d.ts +1 -0
- package/dist/runtime/table/utils/filters/index.js +1 -0
- package/dist/runtime/table/utils/filters/number.d.ts +5 -0
- package/dist/runtime/table/utils/filters/number.js +11 -0
- package/dist/runtime/table/utils/filters/ui.js +5 -5
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
dynamic?: boolean;
|
|
5
5
|
session?: boolean;
|
|
6
6
|
embedded?: boolean;
|
|
7
|
+
header?: boolean;
|
|
7
8
|
initialOperator?: TableFilterOperator;
|
|
8
9
|
};
|
|
9
10
|
declare var __VLS_10: {
|
|
@@ -28,11 +29,15 @@ type __VLS_Slots = {} & {
|
|
|
28
29
|
};
|
|
29
30
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
31
|
dismiss: () => any;
|
|
32
|
+
back: () => any;
|
|
31
33
|
sessionClosed: () => any;
|
|
32
34
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
33
35
|
onDismiss?: (() => any) | undefined;
|
|
36
|
+
onBack?: (() => any) | undefined;
|
|
34
37
|
onSessionClosed?: (() => any) | undefined;
|
|
35
|
-
}>, {
|
|
38
|
+
}>, {
|
|
39
|
+
header: boolean;
|
|
40
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
36
41
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
37
42
|
declare const _default: typeof __VLS_export;
|
|
38
43
|
export default _default;
|
|
@@ -3,17 +3,21 @@ import UButton from "@nuxt/ui/components/Button.vue";
|
|
|
3
3
|
import UInputNumber from "@nuxt/ui/components/InputNumber.vue";
|
|
4
4
|
import USlider from "@nuxt/ui/components/Slider.vue";
|
|
5
5
|
import { computed, ref, watch } from "vue";
|
|
6
|
+
import { useUiToolsLocale } from "#ui-tools/i18n";
|
|
6
7
|
import { isArray, isDate, isNumber, isObject, isNullish } from "../../../../shared/utils/predicate";
|
|
7
8
|
import { useDataListUi } from "../../../composables/use-data-list-ui";
|
|
9
|
+
import { useDeferredCommit } from "../../../composables/use-deferred-commit";
|
|
8
10
|
import { useFilterTagSession } from "../../../composables/use-filter-tag-session";
|
|
9
11
|
import { useTableInternals } from "../../../composables/use-table-internals";
|
|
10
12
|
import {
|
|
11
13
|
mergeDataListUiClass,
|
|
14
|
+
parseTypedNumber,
|
|
12
15
|
resolveDataListControlGeometry,
|
|
13
16
|
resolveFilterEditorSizeClasses,
|
|
14
17
|
resolveFilterTriggerIcon,
|
|
15
18
|
resolveNumberFilterUi
|
|
16
19
|
} from "../../../utils";
|
|
20
|
+
import FilterEditorHeader from "../shared/filter-editor-header.vue";
|
|
17
21
|
import FilterMatchModePanel from "../shared/filter-match-mode-panel.vue";
|
|
18
22
|
import FilterPopoverShell from "../shared/filter-popover-shell.vue";
|
|
19
23
|
import FilterStageTransition from "../shared/filter-stage-transition.vue";
|
|
@@ -23,15 +27,20 @@ const props = defineProps({
|
|
|
23
27
|
dynamic: { type: Boolean, required: false },
|
|
24
28
|
session: { type: Boolean, required: false },
|
|
25
29
|
embedded: { type: Boolean, required: false },
|
|
30
|
+
header: { type: Boolean, required: false, default: true },
|
|
26
31
|
initialOperator: { type: String, required: false }
|
|
27
32
|
});
|
|
28
|
-
const emit = defineEmits(["dismiss", "sessionClosed"]);
|
|
33
|
+
const emit = defineEmits(["back", "dismiss", "sessionClosed"]);
|
|
29
34
|
const internals = useTableInternals();
|
|
30
35
|
const dataListUi = useDataListUi();
|
|
36
|
+
const { locale } = useUiToolsLocale();
|
|
31
37
|
const dataListFilterUi = computed(() => dataListUi.ui.value.filterTags?.ui);
|
|
32
38
|
const size = computed(() => dataListUi.ui.value.filterTags?.size ?? dataListUi.controlSize.value);
|
|
33
39
|
const sizeClasses = computed(() => resolveFilterEditorSizeClasses(size.value));
|
|
34
40
|
const geometry = computed(() => resolveDataListControlGeometry(size.value));
|
|
41
|
+
const showHeader = computed(
|
|
42
|
+
() => props.header && dataListUi.ui.value.filterTags?.props?.editorHeader !== false
|
|
43
|
+
);
|
|
35
44
|
const pendingOperator = ref(props.initialOperator);
|
|
36
45
|
const localValue = ref("");
|
|
37
46
|
const rangeValue = ref({ from: "", to: "" });
|
|
@@ -60,6 +69,8 @@ const operatorItems = computed(
|
|
|
60
69
|
})
|
|
61
70
|
);
|
|
62
71
|
const filterUi = computed(() => resolveNumberFilterUi(props.definition, operator.value));
|
|
72
|
+
const autoCommit = computed(() => filterUi.value.commitMode === "auto");
|
|
73
|
+
const deferred = useDeferredCommit({ commit: commitValue, flushOnDispose: props.embedded });
|
|
63
74
|
const scalarValue = computed({
|
|
64
75
|
get() {
|
|
65
76
|
return localValue.value === "" ? void 0 : Number(localValue.value);
|
|
@@ -81,6 +92,11 @@ const session = useFilterTagSession({
|
|
|
81
92
|
embedded: props.embedded,
|
|
82
93
|
hasCommittedState: () => !isNullish(internals.filters.getActiveFilterState({ key: props.definition.key })),
|
|
83
94
|
onClose: () => {
|
|
95
|
+
if (autoCommit.value) {
|
|
96
|
+
deferred.flush();
|
|
97
|
+
} else {
|
|
98
|
+
deferred.cancel();
|
|
99
|
+
}
|
|
84
100
|
pendingOperator.value = void 0;
|
|
85
101
|
},
|
|
86
102
|
onDismiss: () => emit("dismiss"),
|
|
@@ -128,6 +144,7 @@ function handleRequestMatchMode() {
|
|
|
128
144
|
session.open();
|
|
129
145
|
}
|
|
130
146
|
function handleOperatorChange(op) {
|
|
147
|
+
deferred.cancel();
|
|
131
148
|
localValue.value = "";
|
|
132
149
|
rangeValue.value = { from: "", to: "" };
|
|
133
150
|
pendingOperator.value = op;
|
|
@@ -135,18 +152,16 @@ function handleOperatorChange(op) {
|
|
|
135
152
|
stageTransitioning.value = true;
|
|
136
153
|
stage.value = "editor";
|
|
137
154
|
}
|
|
138
|
-
function
|
|
139
|
-
if (
|
|
140
|
-
|
|
155
|
+
function scheduleCommit() {
|
|
156
|
+
if (autoCommit.value) {
|
|
157
|
+
deferred.schedule();
|
|
141
158
|
}
|
|
142
159
|
}
|
|
143
|
-
function
|
|
144
|
-
const nextOperator = pendingOperator.value;
|
|
145
|
-
pendingOperator.value = void 0;
|
|
160
|
+
function commitValue() {
|
|
146
161
|
if (operator.value === "between") {
|
|
147
162
|
internals.filters.setScalarFilterValue({
|
|
148
163
|
key: props.definition.key,
|
|
149
|
-
operator:
|
|
164
|
+
operator: pendingOperator.value,
|
|
150
165
|
value: rangeValue.value.from === "" && rangeValue.value.to === "" ? void 0 : Object.fromEntries(
|
|
151
166
|
[
|
|
152
167
|
rangeValue.value.from === "" ? void 0 : ["from", Number(rangeValue.value.from)],
|
|
@@ -154,44 +169,65 @@ function applyFilter() {
|
|
|
154
169
|
].filter((entry) => entry !== void 0)
|
|
155
170
|
)
|
|
156
171
|
});
|
|
157
|
-
session.close();
|
|
158
172
|
return;
|
|
159
173
|
}
|
|
160
174
|
internals.filters.setScalarFilterValue({
|
|
161
175
|
key: props.definition.key,
|
|
162
|
-
operator:
|
|
176
|
+
operator: pendingOperator.value,
|
|
163
177
|
value: scalarValue.value
|
|
164
178
|
});
|
|
179
|
+
}
|
|
180
|
+
function applyFilter() {
|
|
181
|
+
deferred.cancel();
|
|
182
|
+
commitValue();
|
|
183
|
+
pendingOperator.value = void 0;
|
|
165
184
|
session.close();
|
|
166
185
|
}
|
|
167
186
|
function clearFilter() {
|
|
187
|
+
deferred.cancel();
|
|
168
188
|
internals.filters.clearFilter({ key: props.definition.key });
|
|
189
|
+
localValue.value = "";
|
|
190
|
+
rangeValue.value = { from: "", to: "" };
|
|
169
191
|
session.close();
|
|
170
192
|
}
|
|
171
193
|
function updateScalarValue(value) {
|
|
172
194
|
scalarValue.value = value;
|
|
173
|
-
|
|
195
|
+
scheduleCommit();
|
|
196
|
+
}
|
|
197
|
+
function typedNumber(event) {
|
|
198
|
+
const value = event.target instanceof HTMLInputElement ? parseTypedNumber({ locale: locale.value.code, text: event.target.value }) : void 0;
|
|
199
|
+
const digits = filterUi.value.formatOptions?.maximumFractionDigits;
|
|
200
|
+
return isNullish(value) || isNullish(digits) ? value : Number(value.toFixed(digits));
|
|
201
|
+
}
|
|
202
|
+
function typeScalarValue(event) {
|
|
203
|
+
updateScalarValue(typedNumber(event));
|
|
204
|
+
}
|
|
205
|
+
function typeRangeFrom(event) {
|
|
206
|
+
updateRangeFrom(typedNumber(event));
|
|
207
|
+
}
|
|
208
|
+
function typeRangeTo(event) {
|
|
209
|
+
updateRangeTo(typedNumber(event));
|
|
174
210
|
}
|
|
175
211
|
function updateRangeFrom(value) {
|
|
176
212
|
rangeValue.value = {
|
|
177
213
|
...rangeValue.value,
|
|
178
214
|
from: isNullish(value) ? "" : String(value)
|
|
179
215
|
};
|
|
180
|
-
|
|
216
|
+
scheduleCommit();
|
|
181
217
|
}
|
|
182
218
|
function updateRangeTo(value) {
|
|
183
219
|
rangeValue.value = {
|
|
184
220
|
...rangeValue.value,
|
|
185
221
|
to: isNullish(value) ? "" : String(value)
|
|
186
222
|
};
|
|
187
|
-
|
|
223
|
+
scheduleCommit();
|
|
188
224
|
}
|
|
189
225
|
function updateSliderScalarValue(value) {
|
|
190
226
|
if (!isNumber(value)) {
|
|
191
227
|
return;
|
|
192
228
|
}
|
|
193
229
|
scalarValue.value = value;
|
|
194
|
-
|
|
230
|
+
scheduleCommit();
|
|
195
231
|
}
|
|
196
232
|
function updateSliderRangeValue(value) {
|
|
197
233
|
if (!isArray(value) || value.length < 2) {
|
|
@@ -205,7 +241,7 @@ function updateSliderRangeValue(value) {
|
|
|
205
241
|
from: String(from),
|
|
206
242
|
to: String(to)
|
|
207
243
|
};
|
|
208
|
-
|
|
244
|
+
scheduleCommit();
|
|
209
245
|
}
|
|
210
246
|
function resolveIncrementConfig(hideStepper) {
|
|
211
247
|
return hideStepper ? false : { variant: "ghost" };
|
|
@@ -276,11 +312,20 @@ function resolveIncrementConfig(hideStepper) {
|
|
|
276
312
|
)
|
|
277
313
|
"
|
|
278
314
|
>
|
|
315
|
+
<FilterEditorHeader
|
|
316
|
+
v-if="showHeader"
|
|
317
|
+
:label="internals.filters.getFilterLabelText({ label: definition.label })"
|
|
318
|
+
:active="preview.active"
|
|
319
|
+
:embedded="embedded"
|
|
320
|
+
:ui="dataListFilterUi"
|
|
321
|
+
@back="emit('back')"
|
|
322
|
+
@clear="clearFilter"
|
|
323
|
+
/>
|
|
279
324
|
<div
|
|
280
325
|
v-if="operator === 'between'"
|
|
281
326
|
:class="
|
|
282
327
|
mergeDataListUiClass(
|
|
283
|
-
`
|
|
328
|
+
`nut-dl-editor__input grid ${geometry.toolbarGap} ${sizeClasses.searchHeader} ${autoCommit ? '' : 'border-b border-default'}`,
|
|
284
329
|
void 0,
|
|
285
330
|
dataListFilterUi?.inputs
|
|
286
331
|
)
|
|
@@ -304,6 +349,7 @@ function resolveIncrementConfig(hideStepper) {
|
|
|
304
349
|
:decrement="resolveIncrementConfig(filterUi.range.inputs.hideStepper)"
|
|
305
350
|
:size="size"
|
|
306
351
|
@update:model-value="updateRangeFrom"
|
|
352
|
+
@input="typeRangeFrom"
|
|
307
353
|
@keydown.enter.prevent="applyFilter"
|
|
308
354
|
/>
|
|
309
355
|
|
|
@@ -319,6 +365,7 @@ function resolveIncrementConfig(hideStepper) {
|
|
|
319
365
|
:decrement="resolveIncrementConfig(filterUi.range.inputs.hideStepper)"
|
|
320
366
|
:size="size"
|
|
321
367
|
@update:model-value="updateRangeTo"
|
|
368
|
+
@input="typeRangeTo"
|
|
322
369
|
@keydown.enter.prevent="applyFilter"
|
|
323
370
|
/>
|
|
324
371
|
</div>
|
|
@@ -342,7 +389,7 @@ function resolveIncrementConfig(hideStepper) {
|
|
|
342
389
|
v-else
|
|
343
390
|
:class="
|
|
344
391
|
mergeDataListUiClass(
|
|
345
|
-
`
|
|
392
|
+
`nut-dl-editor__input grid ${geometry.toolbarGap} ${sizeClasses.searchHeader} ${autoCommit ? '' : 'border-b border-default'}`,
|
|
346
393
|
void 0,
|
|
347
394
|
dataListFilterUi?.inputs
|
|
348
395
|
)
|
|
@@ -363,6 +410,7 @@ function resolveIncrementConfig(hideStepper) {
|
|
|
363
410
|
:decrement="resolveIncrementConfig(filterUi.scalar.input.hideStepper)"
|
|
364
411
|
:size="size"
|
|
365
412
|
@update:model-value="updateScalarValue"
|
|
413
|
+
@input="typeScalarValue"
|
|
366
414
|
@keydown.enter.prevent="applyFilter"
|
|
367
415
|
/>
|
|
368
416
|
|
|
@@ -381,7 +429,7 @@ function resolveIncrementConfig(hideStepper) {
|
|
|
381
429
|
</div>
|
|
382
430
|
|
|
383
431
|
<div
|
|
384
|
-
v-if="
|
|
432
|
+
v-if="!autoCommit"
|
|
385
433
|
:class="
|
|
386
434
|
mergeDataListUiClass(
|
|
387
435
|
`flex items-center justify-between border-t border-default ${sizeClasses.footer}`,
|
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
dynamic?: boolean;
|
|
5
5
|
session?: boolean;
|
|
6
6
|
embedded?: boolean;
|
|
7
|
+
header?: boolean;
|
|
7
8
|
initialOperator?: TableFilterOperator;
|
|
8
9
|
};
|
|
9
10
|
declare var __VLS_10: {
|
|
@@ -28,11 +29,15 @@ type __VLS_Slots = {} & {
|
|
|
28
29
|
};
|
|
29
30
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
31
|
dismiss: () => any;
|
|
32
|
+
back: () => any;
|
|
31
33
|
sessionClosed: () => any;
|
|
32
34
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
33
35
|
onDismiss?: (() => any) | undefined;
|
|
36
|
+
onBack?: (() => any) | undefined;
|
|
34
37
|
onSessionClosed?: (() => any) | undefined;
|
|
35
|
-
}>, {
|
|
38
|
+
}>, {
|
|
39
|
+
header: boolean;
|
|
40
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
36
41
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
37
42
|
declare const _default: typeof __VLS_export;
|
|
38
43
|
export default _default;
|
|
@@ -29,12 +29,12 @@ type __VLS_Slots = {} & {
|
|
|
29
29
|
};
|
|
30
30
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
31
31
|
dismiss: () => any;
|
|
32
|
-
sessionClosed: () => any;
|
|
33
32
|
back: () => any;
|
|
33
|
+
sessionClosed: () => any;
|
|
34
34
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
35
35
|
onDismiss?: (() => any) | undefined;
|
|
36
|
-
onSessionClosed?: (() => any) | undefined;
|
|
37
36
|
onBack?: (() => any) | undefined;
|
|
37
|
+
onSessionClosed?: (() => any) | undefined;
|
|
38
38
|
}>, {
|
|
39
39
|
header: boolean;
|
|
40
40
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import UButton from "@nuxt/ui/components/Button.vue";
|
|
3
|
-
import UIcon from "@nuxt/ui/components/Icon.vue";
|
|
4
3
|
import { computed, ref } from "vue";
|
|
5
|
-
import { useUiToolsLocale } from "#ui-tools/i18n";
|
|
6
4
|
import { useRangeSelect } from "../../../../shared";
|
|
7
5
|
import { isBoolean, isNumber, isString, isNullish } from "../../../../shared/utils/predicate";
|
|
8
6
|
import { useDataListUi } from "../../../composables/use-data-list-ui";
|
|
@@ -14,6 +12,7 @@ import {
|
|
|
14
12
|
resolveFilterEditorSizeClasses,
|
|
15
13
|
resolveFilterTriggerIcon
|
|
16
14
|
} from "../../../utils";
|
|
15
|
+
import FilterEditorHeader from "../shared/filter-editor-header.vue";
|
|
17
16
|
import FilterMatchModePanel from "../shared/filter-match-mode-panel.vue";
|
|
18
17
|
import FilterOptionPickerContent from "../shared/filter-option-picker-content.vue";
|
|
19
18
|
import FilterPopoverShell from "../shared/filter-popover-shell.vue";
|
|
@@ -30,7 +29,6 @@ const props = defineProps({
|
|
|
30
29
|
const emit = defineEmits(["back", "dismiss", "sessionClosed"]);
|
|
31
30
|
const internals = useTableInternals();
|
|
32
31
|
const dataListUi = useDataListUi();
|
|
33
|
-
const { t } = useUiToolsLocale();
|
|
34
32
|
const dataListFilterUi = computed(() => dataListUi.ui.value.filterTags?.ui);
|
|
35
33
|
const size = computed(() => dataListUi.ui.value.filterTags?.size ?? dataListUi.controlSize.value);
|
|
36
34
|
const sizeClasses = computed(() => resolveFilterEditorSizeClasses(size.value));
|
|
@@ -289,37 +287,15 @@ function handleContentMounted() {
|
|
|
289
287
|
"
|
|
290
288
|
@vue:mounted="handleContentMounted"
|
|
291
289
|
>
|
|
292
|
-
<
|
|
290
|
+
<FilterEditorHeader
|
|
293
291
|
v-if="header !== false && dataListUi.ui.value.filterTags?.props?.editorHeader !== false"
|
|
294
|
-
:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
>
|
|
302
|
-
<button
|
|
303
|
-
v-if="embedded"
|
|
304
|
-
type="button"
|
|
305
|
-
class="nut-dl-editor__back flex size-6 items-center justify-center rounded-md text-muted hover:bg-elevated hover:text-default"
|
|
306
|
-
:aria-label="t('table.filters.sheet.back')"
|
|
307
|
-
@click="emit('back')"
|
|
308
|
-
>
|
|
309
|
-
<UIcon name="i-lucide-arrow-left" class="size-4" />
|
|
310
|
-
</button>
|
|
311
|
-
<span class="min-w-0 flex-1 truncate text-[12.5px] font-semibold text-highlighted">
|
|
312
|
-
{{ internals.filters.getFilterLabelText({ label: definition.label }) }}
|
|
313
|
-
</span>
|
|
314
|
-
<button
|
|
315
|
-
type="button"
|
|
316
|
-
class="rounded text-[12.5px] font-semibold text-primary outline-none focus-visible:ring-2 focus-visible:ring-primary/40 disabled:opacity-40"
|
|
317
|
-
:disabled="!preview.active"
|
|
318
|
-
@click="clearFilter"
|
|
319
|
-
>
|
|
320
|
-
{{ t("table.filters.editor.clear") }}
|
|
321
|
-
</button>
|
|
322
|
-
</div>
|
|
292
|
+
:label="internals.filters.getFilterLabelText({ label: definition.label })"
|
|
293
|
+
:active="preview.active"
|
|
294
|
+
:embedded="embedded"
|
|
295
|
+
:ui="dataListFilterUi"
|
|
296
|
+
@back="emit('back')"
|
|
297
|
+
@clear="clearFilter"
|
|
298
|
+
/>
|
|
323
299
|
<FilterOptionPickerContent
|
|
324
300
|
v-model:search-query="searchQuery"
|
|
325
301
|
:flat-radio-value="state.flatRadioValue.value"
|
|
@@ -336,7 +312,7 @@ function handleContentMounted() {
|
|
|
336
312
|
/>
|
|
337
313
|
|
|
338
314
|
<div
|
|
339
|
-
v-if="state.filterUi.value.commitMode
|
|
315
|
+
v-if="state.filterUi.value.commitMode !== 'auto'"
|
|
340
316
|
:class="
|
|
341
317
|
mergeDataListUiClass(
|
|
342
318
|
`flex items-center justify-between border-t border-default ${sizeClasses.footer}`,
|
|
@@ -29,12 +29,12 @@ type __VLS_Slots = {} & {
|
|
|
29
29
|
};
|
|
30
30
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
31
31
|
dismiss: () => any;
|
|
32
|
-
sessionClosed: () => any;
|
|
33
32
|
back: () => any;
|
|
33
|
+
sessionClosed: () => any;
|
|
34
34
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
35
35
|
onDismiss?: (() => any) | undefined;
|
|
36
|
-
onSessionClosed?: (() => any) | undefined;
|
|
37
36
|
onBack?: (() => any) | undefined;
|
|
37
|
+
onSessionClosed?: (() => any) | undefined;
|
|
38
38
|
}>, {
|
|
39
39
|
header: boolean;
|
|
40
40
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
dynamic?: boolean;
|
|
5
5
|
session?: boolean;
|
|
6
6
|
embedded?: boolean;
|
|
7
|
+
header?: boolean;
|
|
7
8
|
initialOperator?: TableFilterOperator;
|
|
8
9
|
};
|
|
9
10
|
declare var __VLS_10: {
|
|
@@ -28,11 +29,15 @@ type __VLS_Slots = {} & {
|
|
|
28
29
|
};
|
|
29
30
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
31
|
dismiss: () => any;
|
|
32
|
+
back: () => any;
|
|
31
33
|
sessionClosed: () => any;
|
|
32
34
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
33
35
|
onDismiss?: (() => any) | undefined;
|
|
36
|
+
onBack?: (() => any) | undefined;
|
|
34
37
|
onSessionClosed?: (() => any) | undefined;
|
|
35
|
-
}>, {
|
|
38
|
+
}>, {
|
|
39
|
+
header: boolean;
|
|
40
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
36
41
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
37
42
|
declare const _default: typeof __VLS_export;
|
|
38
43
|
export default _default;
|
|
@@ -4,6 +4,7 @@ import UInput from "@nuxt/ui/components/Input.vue";
|
|
|
4
4
|
import { computed, ref } from "vue";
|
|
5
5
|
import { isNullish } from "../../../../shared/utils/predicate";
|
|
6
6
|
import { useDataListUi } from "../../../composables/use-data-list-ui";
|
|
7
|
+
import { useDeferredCommit } from "../../../composables/use-deferred-commit";
|
|
7
8
|
import { useFilterTagSession } from "../../../composables/use-filter-tag-session";
|
|
8
9
|
import { useTableInternals } from "../../../composables/use-table-internals";
|
|
9
10
|
import {
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
resolveFilterTriggerIcon,
|
|
13
14
|
resolveTextFilterUi
|
|
14
15
|
} from "../../../utils";
|
|
16
|
+
import FilterEditorHeader from "../shared/filter-editor-header.vue";
|
|
15
17
|
import FilterMatchModePanel from "../shared/filter-match-mode-panel.vue";
|
|
16
18
|
import FilterPopoverShell from "../shared/filter-popover-shell.vue";
|
|
17
19
|
import FilterStageTransition from "../shared/filter-stage-transition.vue";
|
|
@@ -21,14 +23,18 @@ const props = defineProps({
|
|
|
21
23
|
dynamic: { type: Boolean, required: false },
|
|
22
24
|
session: { type: Boolean, required: false },
|
|
23
25
|
embedded: { type: Boolean, required: false },
|
|
26
|
+
header: { type: Boolean, required: false, default: true },
|
|
24
27
|
initialOperator: { type: String, required: false }
|
|
25
28
|
});
|
|
26
|
-
const emit = defineEmits(["dismiss", "sessionClosed"]);
|
|
29
|
+
const emit = defineEmits(["back", "dismiss", "sessionClosed"]);
|
|
27
30
|
const internals = useTableInternals();
|
|
28
31
|
const dataListUi = useDataListUi();
|
|
29
32
|
const dataListFilterUi = computed(() => dataListUi.ui.value.filterTags?.ui);
|
|
30
33
|
const size = computed(() => dataListUi.ui.value.filterTags?.size ?? dataListUi.controlSize.value);
|
|
31
34
|
const sizeClasses = computed(() => resolveFilterEditorSizeClasses(size.value));
|
|
35
|
+
const showHeader = computed(
|
|
36
|
+
() => props.header && dataListUi.ui.value.filterTags?.props?.editorHeader !== false
|
|
37
|
+
);
|
|
32
38
|
const pendingOperator = ref(props.initialOperator);
|
|
33
39
|
const localValue = ref("");
|
|
34
40
|
const stage = ref("editor");
|
|
@@ -56,6 +62,8 @@ const operatorItems = computed(
|
|
|
56
62
|
})
|
|
57
63
|
);
|
|
58
64
|
const filterUi = computed(() => resolveTextFilterUi(props.definition, operator.value));
|
|
65
|
+
const autoCommit = computed(() => filterUi.value.commitMode === "auto");
|
|
66
|
+
const deferred = useDeferredCommit({ commit: commitValue, flushOnDispose: props.embedded });
|
|
59
67
|
function initLocalState() {
|
|
60
68
|
const value = internals.filters.getFilterState({
|
|
61
69
|
key: props.definition.key
|
|
@@ -67,6 +75,11 @@ const session = useFilterTagSession({
|
|
|
67
75
|
embedded: props.embedded,
|
|
68
76
|
hasCommittedState: () => !isNullish(internals.filters.getActiveFilterState({ key: props.definition.key })),
|
|
69
77
|
onClose: () => {
|
|
78
|
+
if (autoCommit.value) {
|
|
79
|
+
deferred.flush();
|
|
80
|
+
} else {
|
|
81
|
+
deferred.cancel();
|
|
82
|
+
}
|
|
70
83
|
pendingOperator.value = void 0;
|
|
71
84
|
},
|
|
72
85
|
onDismiss: () => emit("dismiss"),
|
|
@@ -86,21 +99,27 @@ function handleRequestMatchMode() {
|
|
|
86
99
|
stage.value = "match-mode";
|
|
87
100
|
session.open();
|
|
88
101
|
}
|
|
89
|
-
function
|
|
90
|
-
const op = pendingOperator.value;
|
|
91
|
-
pendingOperator.value = void 0;
|
|
102
|
+
function commitValue() {
|
|
92
103
|
internals.filters.setScalarFilterValue({
|
|
93
104
|
key: props.definition.key,
|
|
94
|
-
operator:
|
|
105
|
+
operator: pendingOperator.value,
|
|
95
106
|
value: localValue.value.trim() || void 0
|
|
96
107
|
});
|
|
108
|
+
}
|
|
109
|
+
function applyFilter() {
|
|
110
|
+
deferred.cancel();
|
|
111
|
+
commitValue();
|
|
112
|
+
pendingOperator.value = void 0;
|
|
97
113
|
session.close();
|
|
98
114
|
}
|
|
99
115
|
function clearFilter() {
|
|
116
|
+
deferred.cancel();
|
|
100
117
|
internals.filters.clearFilter({ key: props.definition.key });
|
|
118
|
+
localValue.value = "";
|
|
101
119
|
session.close();
|
|
102
120
|
}
|
|
103
121
|
function handleOperatorChange(op) {
|
|
122
|
+
deferred.cancel();
|
|
104
123
|
localValue.value = "";
|
|
105
124
|
pendingOperator.value = op;
|
|
106
125
|
stageDirection.value = "forward";
|
|
@@ -109,12 +128,8 @@ function handleOperatorChange(op) {
|
|
|
109
128
|
}
|
|
110
129
|
function handleValueUpdate(value) {
|
|
111
130
|
localValue.value = isNullish(value) ? "" : String(value);
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
key: props.definition.key,
|
|
115
|
-
operator: pendingOperator.value,
|
|
116
|
-
value: localValue.value.trim() || void 0
|
|
117
|
-
});
|
|
131
|
+
if (autoCommit.value) {
|
|
132
|
+
deferred.schedule();
|
|
118
133
|
}
|
|
119
134
|
}
|
|
120
135
|
</script>
|
|
@@ -183,10 +198,19 @@ function handleValueUpdate(value) {
|
|
|
183
198
|
)
|
|
184
199
|
"
|
|
185
200
|
>
|
|
201
|
+
<FilterEditorHeader
|
|
202
|
+
v-if="showHeader"
|
|
203
|
+
:label="internals.filters.getFilterLabelText({ label: definition.label })"
|
|
204
|
+
:active="preview.active"
|
|
205
|
+
:embedded="embedded"
|
|
206
|
+
:ui="dataListFilterUi"
|
|
207
|
+
@back="emit('back')"
|
|
208
|
+
@clear="clearFilter"
|
|
209
|
+
/>
|
|
186
210
|
<div
|
|
187
211
|
:class="
|
|
188
212
|
mergeDataListUiClass(
|
|
189
|
-
`
|
|
213
|
+
`nut-dl-editor__input ${sizeClasses.searchHeader} ${autoCommit ? '' : 'border-b border-default'}`,
|
|
190
214
|
void 0,
|
|
191
215
|
dataListFilterUi?.inputs
|
|
192
216
|
)
|
|
@@ -202,10 +226,11 @@ function handleValueUpdate(value) {
|
|
|
202
226
|
:highlight="filterUi.input.highlight"
|
|
203
227
|
:fixed="filterUi.input.fixed"
|
|
204
228
|
:size="size"
|
|
229
|
+
variant="none"
|
|
205
230
|
class="w-full min-w-0 max-w-full"
|
|
206
231
|
:ui="{
|
|
207
232
|
root: dataListFilterUi?.search,
|
|
208
|
-
base: dataListFilterUi?.searchInput
|
|
233
|
+
base: mergeDataListUiClass('h-8', void 0, dataListFilterUi?.searchInput)
|
|
209
234
|
}"
|
|
210
235
|
@update:model-value="handleValueUpdate"
|
|
211
236
|
@keydown.enter.prevent="applyFilter"
|
|
@@ -213,7 +238,7 @@ function handleValueUpdate(value) {
|
|
|
213
238
|
</div>
|
|
214
239
|
|
|
215
240
|
<div
|
|
216
|
-
v-if="
|
|
241
|
+
v-if="!autoCommit"
|
|
217
242
|
:class="
|
|
218
243
|
mergeDataListUiClass(
|
|
219
244
|
`flex items-center justify-between border-t border-default ${sizeClasses.footer}`,
|
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
dynamic?: boolean;
|
|
5
5
|
session?: boolean;
|
|
6
6
|
embedded?: boolean;
|
|
7
|
+
header?: boolean;
|
|
7
8
|
initialOperator?: TableFilterOperator;
|
|
8
9
|
};
|
|
9
10
|
declare var __VLS_10: {
|
|
@@ -28,11 +29,15 @@ type __VLS_Slots = {} & {
|
|
|
28
29
|
};
|
|
29
30
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
31
|
dismiss: () => any;
|
|
32
|
+
back: () => any;
|
|
31
33
|
sessionClosed: () => any;
|
|
32
34
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
33
35
|
onDismiss?: (() => any) | undefined;
|
|
36
|
+
onBack?: (() => any) | undefined;
|
|
34
37
|
onSessionClosed?: (() => any) | undefined;
|
|
35
|
-
}>, {
|
|
38
|
+
}>, {
|
|
39
|
+
header: boolean;
|
|
40
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
36
41
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
37
42
|
declare const _default: typeof __VLS_export;
|
|
38
43
|
export default _default;
|
|
@@ -5,9 +5,15 @@ type __VLS_Props = {
|
|
|
5
5
|
fill?: boolean;
|
|
6
6
|
ui?: DataListGridUi;
|
|
7
7
|
};
|
|
8
|
-
declare
|
|
8
|
+
declare function refreshData(): void;
|
|
9
|
+
declare var __VLS_6: {
|
|
10
|
+
error: unknown;
|
|
11
|
+
retry: typeof refreshData;
|
|
12
|
+
}, __VLS_15: {};
|
|
9
13
|
type __VLS_Slots = {} & {
|
|
10
|
-
|
|
14
|
+
error?: (props: typeof __VLS_6) => any;
|
|
15
|
+
} & {
|
|
16
|
+
empty?: (props: typeof __VLS_15) => any;
|
|
11
17
|
};
|
|
12
18
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
19
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|