@webitel/ui-datalist 26.8.6 → 26.8.8
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/Readme.md +1 -0
- package/package.json +3 -2
- package/src/modules/filter-presets/components/apply-preset/apply-preset-action.vue +16 -4
- package/src/modules/filter-presets/components/save-preset/save-preset-action.vue +18 -4
- package/src/modules/filters/__tests__/createTableFiltersStore.spec.ts +38 -2
- package/src/modules/filters/components/column/column-filter-preview.vue +70 -0
- package/src/modules/filters/components/column/column-filter.vue +76 -0
- package/src/modules/filters/components/config/dynamic-view/dynamic-filter-config-form-value-input.vue +2 -0
- package/src/modules/filters/components/config/dynamic-view/dynamic-filter-config-form.vue +43 -5
- package/src/modules/filters/components/config/static-view/static-filter-field.vue +6 -21
- package/src/modules/filters/components/filters-actions-menu.vue +177 -0
- package/src/modules/filters/components/preview/dynamic-filter-preview.vue +5 -60
- package/src/modules/filters/components/table-filters-panel.vue +6 -28
- package/src/modules/filters/components/types/Filter.types.ts +5 -0
- package/src/modules/filters/composables/useColumnFilter.ts +116 -0
- package/src/modules/filters/composables/useFilterValueChange.ts +58 -0
- package/src/modules/filters/composables/useFilterValuePreview.ts +87 -0
- package/src/modules/filters/composables/useSelectedFilters.ts +64 -0
- package/src/modules/filters/createTableFiltersStore.ts +13 -5
- package/src/modules/filters/index.ts +4 -0
- package/src/modules/filters/modules/filterConfig/components/_custom/filterConfig.ts +1 -1
- package/src/modules/filters/modules/filterConfig/components/_custom/type-extension-filter-value-field.vue +9 -5
- package/src/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-filter-value-field.vue +7 -4
- package/src/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-options/date-time-options-filter-value-field.vue +7 -4
- package/src/modules/filters/modules/filterConfig/components/_shared/durations/duration-filter-value-field.vue +7 -4
- package/src/modules/filters/modules/filterConfig/components/_shared/string-filter/string-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/agent/agent-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/amd-result/amd-result-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/call-direction/call-direction-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/case-assignee/case-assignee-filter-value-field.vue +4 -4
- package/src/modules/filters/modules/filterConfig/components/case-author/case-author-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/case-close-reason-groups/case-close-reason-groups-filter-value-field.vue +7 -4
- package/src/modules/filters/modules/filterConfig/components/case-impacted/case-impacted-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/case-priority/case-priority-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/case-reporter/case-reporter-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/case-service/case-service-filter-value-field.vue +1 -32
- package/src/modules/filters/modules/filterConfig/components/case-sla/case-sla-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/case-sla-condition/case-sla-condition-filter-value-field.vue +7 -4
- package/src/modules/filters/modules/filterConfig/components/case-source/case-source-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/case-status/case-status-filter-value-field.vue +7 -4
- package/src/modules/filters/modules/filterConfig/components/contact/contact-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/contact-owner/contact-owner-filter-value-field.vue +3 -3
- package/src/modules/filters/modules/filterConfig/components/gateway/gateway-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/grantee/grantee-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/hangup-cause/hangup-cause-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/has-attachment/has-attachment-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/rated-by/rated-by-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/rating/rating-from-to-filter-value-field.vue +7 -4
- package/src/modules/filters/modules/filterConfig/components/score/score-from-to-filter-value-field.vue +4 -4
- package/src/modules/filters/modules/filterConfig/components/tag/tag-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/user/user-filter-value-field.vue +6 -3
- package/src/modules/filters/modules/filterConfig/components/variable/variable-filter-value-field.vue +6 -3
- package/src/modules/headers/__tests__/createTableHeadersStore.spec.ts +34 -2
- package/src/modules/headers/createTableHeadersStore.ts +19 -5
- package/src/modules/pagination/__tests__/createTablePaginationStore.spec.ts +27 -3
- package/src/modules/pagination/createTablePaginationStore.ts +23 -4
- package/src/modules/table/__tests__/createTableStore.spec.ts +26 -0
- package/src/modules/table/createTableStore.store.ts +34 -15
- package/src/modules/types/tableStore.types.ts +21 -2
- package/types/.tsbuildinfo +1 -1
- package/types/modules/filter-presets/components/apply-preset/apply-preset-action.vue.d.ts +15 -1
- package/types/modules/filter-presets/components/save-preset/save-preset-action.vue.d.ts +17 -1
- package/types/modules/filter-presets/stores/createFilterPresetsStore.d.ts +2 -35
- package/types/modules/filters/components/column/column-filter-preview.vue.d.ts +21 -0
- package/types/modules/filters/components/column/column-filter.vue.d.ts +36 -0
- package/types/modules/filters/components/config/dynamic-view/dynamic-filter-config-form-label.vue.d.ts +2 -2
- package/types/modules/filters/components/config/dynamic-view/dynamic-filter-config-form-value-input.vue.d.ts +3 -2
- package/types/modules/filters/components/config/dynamic-view/dynamic-filter-config-form.vue.d.ts +13 -1
- package/types/modules/filters/components/config/static-view/static-filter-field.vue.d.ts +2 -2
- package/types/modules/filters/components/filters-actions-menu.vue.d.ts +29 -0
- package/types/modules/filters/components/table-filters-panel.vue.d.ts +6 -6
- package/types/modules/filters/components/types/Filter.types.d.ts +4 -0
- package/types/modules/filters/composables/useColumnFilter.d.ts +27 -0
- package/types/modules/filters/composables/useFilterValueChange.d.ts +23 -0
- package/types/modules/filters/composables/useFilterValuePreview.d.ts +21 -0
- package/types/modules/filters/composables/useSelectedFilters.d.ts +22 -0
- package/types/modules/filters/createTableFiltersStore.d.ts +6 -2
- package/types/modules/filters/index.d.ts +3 -1
- package/types/modules/filters/modules/filterConfig/components/_custom/type-extension-filter-value-field.vue.d.ts +3 -2
- package/types/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-options/date-time-options-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/_shared/durations/duration-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/_shared/string-filter/string-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/agent/agent-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/agent-status/agent-status-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/amd-result/amd-result-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/auditor/auditor-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/auditor/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/bucket/bucket-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/bucket/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/call-direction/call-direction-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/call-reporting-result/call-reporting-result-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-assignee/case-assignee-filter-value-field.vue.d.ts +3 -2
- package/types/modules/filters/modules/filterConfig/components/case-assignee/filterConfig.d.ts +4 -2
- package/types/modules/filters/modules/filterConfig/components/case-author/case-author-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/case-close-reason-groups/case-close-reason-groups-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/case-impacted/case-impacted-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/case-priority/case-priority-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/case-reporter/case-reporter-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/case-sla/case-sla-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/case-sla-condition/case-sla-condition-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/case-source/case-source-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/case-status/case-status-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/contact/contact-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/contact-group/contact-group-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/contact-group/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/contact-label/contact-label-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/contact-label/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/contact-owner/contact-owner-filter-value-field.vue.d.ts +3 -2
- package/types/modules/filters/modules/filterConfig/components/contact-owner/index.d.ts +4 -2
- package/types/modules/filters/modules/filterConfig/components/gateway/gateway-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/grantee/grantee-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/hangup-cause/hangup-cause-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/has-attachment/has-attachment-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/has-file/has-file-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/has-rating/has-rating-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/has-transcription/has-transcription-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/has-user/has-user-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/index.d.ts +24 -22
- package/types/modules/filters/modules/filterConfig/components/queue/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/queue/queue-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/queue-period/queue-period-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/queue-type/queue-type-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/rated-by/rated-by-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/rating/rating-from-to-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/region/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/region/region-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/score/score-from-to-filter-value-field.vue.d.ts +3 -2
- package/types/modules/filters/modules/filterConfig/components/skill/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/skill/skill-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/stop-cause/stop-cause-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/supervisor/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/supervisor/supervisor-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/tag/tag-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/tags/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/tags/tags-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/talk-duration/talk-duration-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/team/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/team/team-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/total-duration/total-duration-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/user/user-filter-value-field.vue.d.ts +8 -4
- package/types/modules/filters/modules/filterConfig/components/utilization-progress/utilization-progress-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/variable/variable-filter-value-field.vue.d.ts +8 -4
- package/types/modules/headers/createTableHeadersStore.d.ts +48 -20
- package/types/modules/pagination/createTablePaginationStore.d.ts +7 -3
- package/types/modules/permissions-page/stores/createPermissionsStore.d.ts +4 -70
- package/types/modules/table/createTableStore.store.d.ts +76 -141
- package/types/modules/types/tableStore.types.d.ts +20 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<has-option-filter-value-field
|
|
3
3
|
:model-value="model"
|
|
4
|
-
:v="v$.model"
|
|
4
|
+
:v="!disableValidation && v$.model"
|
|
5
5
|
@update:model-value="model = $event"
|
|
6
6
|
/>
|
|
7
7
|
</template>
|
|
@@ -13,6 +13,10 @@ import { computed, watch } from 'vue';
|
|
|
13
13
|
|
|
14
14
|
import HasOptionFilterValueField from '../_shared/has-options/has-option-filter-value-field.vue';
|
|
15
15
|
|
|
16
|
+
const props = defineProps<{
|
|
17
|
+
disableValidation?: boolean;
|
|
18
|
+
}>();
|
|
19
|
+
|
|
16
20
|
const model = defineModel<boolean | null>();
|
|
17
21
|
|
|
18
22
|
const v$ = useVuelidate(
|
|
@@ -29,8 +33,7 @@ const v$ = useVuelidate(
|
|
|
29
33
|
},
|
|
30
34
|
);
|
|
31
35
|
|
|
32
|
-
v$.value.$touch();
|
|
33
|
-
|
|
36
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
34
37
|
const emit = defineEmits<{
|
|
35
38
|
'update:invalid': [
|
|
36
39
|
boolean,
|
package/src/modules/filters/modules/filterConfig/components/rated-by/rated-by-filter-value-field.vue
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
:label="t('webitelUI.filters.filterValue')"
|
|
4
4
|
:search-method="searchMethod"
|
|
5
5
|
:model-value="model"
|
|
6
|
-
:v="v$.model"
|
|
6
|
+
:v="!disableValidation && v$.model"
|
|
7
7
|
option-value="id"
|
|
8
8
|
@update:model-value="handleInput"
|
|
9
9
|
/>
|
|
@@ -20,6 +20,10 @@ import { searchMethod } from './config.js';
|
|
|
20
20
|
|
|
21
21
|
type ModelValue = number[];
|
|
22
22
|
|
|
23
|
+
const props = defineProps<{
|
|
24
|
+
disableValidation?: boolean;
|
|
25
|
+
}>();
|
|
26
|
+
|
|
23
27
|
const model = defineModel<ModelValue>();
|
|
24
28
|
|
|
25
29
|
const emit = defineEmits<{
|
|
@@ -42,8 +46,7 @@ const v$ = useVuelidate(
|
|
|
42
46
|
$autoDirty: true,
|
|
43
47
|
},
|
|
44
48
|
);
|
|
45
|
-
v$.value.$touch();
|
|
46
|
-
|
|
49
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
47
50
|
watch(
|
|
48
51
|
() => v$.value.$invalid,
|
|
49
52
|
(invalid) => {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<wt-input-number
|
|
4
4
|
:label="`${t('reusable.from')}:`"
|
|
5
5
|
:placeholder="t('webitelUI.filters.filterValue')"
|
|
6
|
-
:v="vFrom"
|
|
6
|
+
:v="!disableValidation && vFrom"
|
|
7
7
|
:model-value="value.from"
|
|
8
8
|
class="rating-from-to-filter-value-field__input"
|
|
9
9
|
@update:model-value="handleInput('from', $event)"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<wt-input-number
|
|
13
13
|
:label="`${t('reusable.to')}:`"
|
|
14
14
|
:placeholder="t('webitelUI.filters.filterValue')"
|
|
15
|
-
:v="vTo"
|
|
15
|
+
:v="!disableValidation && vTo"
|
|
16
16
|
:model-value="value.to"
|
|
17
17
|
class="rating-from-to-filter-value-field__input"
|
|
18
18
|
@update:model-value="handleInput('to', $event)"
|
|
@@ -26,6 +26,10 @@ import { maxValue, requiredIf } from '@vuelidate/validators';
|
|
|
26
26
|
import { computed, watch } from 'vue';
|
|
27
27
|
import { useI18n } from 'vue-i18n';
|
|
28
28
|
|
|
29
|
+
const props = defineProps<{
|
|
30
|
+
disableValidation?: boolean;
|
|
31
|
+
}>();
|
|
32
|
+
|
|
29
33
|
type ModelValue = {
|
|
30
34
|
from: number | null;
|
|
31
35
|
to: number | null;
|
|
@@ -80,8 +84,7 @@ const v$ = useVuelidate<{
|
|
|
80
84
|
$autoDirty: true,
|
|
81
85
|
},
|
|
82
86
|
);
|
|
83
|
-
v$.value.$touch();
|
|
84
|
-
|
|
87
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
85
88
|
const vFrom = computed(() => {
|
|
86
89
|
const modelValidation = v$.value.model;
|
|
87
90
|
if (!modelValidation) return undefined;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:model-value="value.from"
|
|
5
5
|
:max="props.numberMax"
|
|
6
6
|
:min="0"
|
|
7
|
-
:v="vFrom"
|
|
7
|
+
:v="!disableValidation && vFrom"
|
|
8
8
|
:label="`${t('reusable.from')}:`"
|
|
9
9
|
:placeholder="t('webitelUI.filters.filterValue')"
|
|
10
10
|
class="score-from-to-filter-value-field__input"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
:model-value="value.to"
|
|
17
17
|
:max="props.numberMax"
|
|
18
18
|
:min="0"
|
|
19
|
-
:v="vTo"
|
|
19
|
+
:v="!disableValidation && vTo"
|
|
20
20
|
:label="`${t('reusable.to')}:`"
|
|
21
21
|
:placeholder="t('webitelUI.filters.filterValue')"
|
|
22
22
|
class="score-from-to-filter-value-field__input"
|
|
@@ -54,6 +54,7 @@ const value = computed<ModelValue>(
|
|
|
54
54
|
const props = withDefaults(
|
|
55
55
|
defineProps<{
|
|
56
56
|
numberMax?: number;
|
|
57
|
+
disableValidation?: boolean;
|
|
57
58
|
}>(),
|
|
58
59
|
{
|
|
59
60
|
numberMax: 100,
|
|
@@ -88,8 +89,7 @@ const v$ = useVuelidate<{
|
|
|
88
89
|
$autoDirty: true,
|
|
89
90
|
},
|
|
90
91
|
);
|
|
91
|
-
v$.value.$touch();
|
|
92
|
-
|
|
92
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
93
93
|
const vFrom = computed(() => {
|
|
94
94
|
const modelValidation = v$.value.model;
|
|
95
95
|
if (!modelValidation) return undefined;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
:label="t('webitelUI.filters.filterValue')"
|
|
4
4
|
:options="CallHistoryTagFilterOptions"
|
|
5
5
|
v-model:model-value="model"
|
|
6
|
-
:v="v$.model"
|
|
6
|
+
:v="!disableValidation && v$.model"
|
|
7
7
|
data-key="value"
|
|
8
8
|
option-value="value"
|
|
9
9
|
/>
|
|
@@ -18,6 +18,10 @@ import { useI18n } from 'vue-i18n';
|
|
|
18
18
|
|
|
19
19
|
import { CallHistoryTagFilterOptions } from '../../enums/options/CallHistoryTagFilterOptions';
|
|
20
20
|
|
|
21
|
+
const props = defineProps<{
|
|
22
|
+
disableValidation?: boolean;
|
|
23
|
+
}>();
|
|
24
|
+
|
|
21
25
|
const model = defineModel<string>();
|
|
22
26
|
const { t } = useI18n();
|
|
23
27
|
|
|
@@ -35,8 +39,7 @@ const v$ = useVuelidate(
|
|
|
35
39
|
},
|
|
36
40
|
);
|
|
37
41
|
|
|
38
|
-
v$.value.$touch();
|
|
39
|
-
|
|
42
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
40
43
|
const emit = defineEmits<{
|
|
41
44
|
'update:invalid': [
|
|
42
45
|
boolean,
|
package/src/modules/filters/modules/filterConfig/components/user/user-filter-value-field.vue
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
:label="t('webitelUI.filters.filterValue')"
|
|
4
4
|
:search-method="searchMethod"
|
|
5
5
|
:model-value="model"
|
|
6
|
-
:v="v$.model"
|
|
6
|
+
:v="!disableValidation && v$.model"
|
|
7
7
|
option-value="id"
|
|
8
8
|
@update:model-value="handleInput"
|
|
9
9
|
/>
|
|
@@ -20,6 +20,10 @@ import { searchMethod } from './config.js';
|
|
|
20
20
|
|
|
21
21
|
type ModelValue = number[];
|
|
22
22
|
|
|
23
|
+
const props = defineProps<{
|
|
24
|
+
disableValidation?: boolean;
|
|
25
|
+
}>();
|
|
26
|
+
|
|
23
27
|
const model = defineModel<ModelValue>();
|
|
24
28
|
|
|
25
29
|
const emit = defineEmits<{
|
|
@@ -42,8 +46,7 @@ const v$ = useVuelidate(
|
|
|
42
46
|
$autoDirty: true,
|
|
43
47
|
},
|
|
44
48
|
);
|
|
45
|
-
v$.value.$touch();
|
|
46
|
-
|
|
49
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
47
50
|
watch(
|
|
48
51
|
() => v$.value.$invalid,
|
|
49
52
|
(invalid) => {
|
package/src/modules/filters/modules/filterConfig/components/variable/variable-filter-value-field.vue
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<wt-input-text
|
|
3
3
|
v-model:model-value="model"
|
|
4
4
|
:label="t('webitelUI.filters.filterValue')"
|
|
5
|
-
:v="v$.model"
|
|
5
|
+
:v="!disableValidation && v$.model"
|
|
6
6
|
/>
|
|
7
7
|
</template>
|
|
8
8
|
|
|
@@ -14,6 +14,10 @@ import { useI18n } from 'vue-i18n';
|
|
|
14
14
|
|
|
15
15
|
type ModelValue = string;
|
|
16
16
|
|
|
17
|
+
const props = defineProps<{
|
|
18
|
+
disableValidation?: boolean;
|
|
19
|
+
}>();
|
|
20
|
+
|
|
17
21
|
const model = defineModel<ModelValue>();
|
|
18
22
|
if (!model.value) {
|
|
19
23
|
model.value = '';
|
|
@@ -35,8 +39,7 @@ const v$ = useVuelidate(
|
|
|
35
39
|
},
|
|
36
40
|
);
|
|
37
41
|
|
|
38
|
-
v$.value.$touch();
|
|
39
|
-
|
|
42
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
40
43
|
const emit = defineEmits<{
|
|
41
44
|
'update:invalid': [
|
|
42
45
|
boolean,
|
|
@@ -58,6 +58,7 @@ describe('tableHeadersStoreBody', () => {
|
|
|
58
58
|
|
|
59
59
|
beforeEach(async () => {
|
|
60
60
|
localStorage.clear();
|
|
61
|
+
sessionStorage.clear();
|
|
61
62
|
|
|
62
63
|
router = createRouter({
|
|
63
64
|
history: createMemoryHistory(),
|
|
@@ -73,9 +74,9 @@ describe('tableHeadersStoreBody', () => {
|
|
|
73
74
|
runWithRouter = (fn) => app.runWithContext(fn);
|
|
74
75
|
});
|
|
75
76
|
|
|
76
|
-
const setUpStore = async () => {
|
|
77
|
+
const setUpStore = async (options?: { isNested?: boolean }) => {
|
|
77
78
|
const store = createStore();
|
|
78
|
-
await runWithRouter(() => store.setupPersistence());
|
|
79
|
+
await runWithRouter(() => store.setupPersistence(options));
|
|
79
80
|
return store;
|
|
80
81
|
};
|
|
81
82
|
|
|
@@ -226,6 +227,37 @@ describe('tableHeadersStoreBody', () => {
|
|
|
226
227
|
]);
|
|
227
228
|
expect(store.headers.value.some(({ field }) => !field)).toBe(false);
|
|
228
229
|
});
|
|
230
|
+
|
|
231
|
+
describe('a nested list', () => {
|
|
232
|
+
it('keeps a changed sort out of the route query, in a namespaced sessionStorage key instead', async () => {
|
|
233
|
+
const store = await setUpStore({
|
|
234
|
+
isNested: true,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
store.updateSort(store.headers.value[0], 'asc');
|
|
238
|
+
await flushWrites();
|
|
239
|
+
|
|
240
|
+
expect(router.currentRoute.value.query.sort).toBeUndefined();
|
|
241
|
+
expect(sessionStorage.getItem(`${id}/sort`)).toBe('+name');
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('keeps a changed field set out of the route query, in localStorage instead', async () => {
|
|
245
|
+
const store = await setUpStore({
|
|
246
|
+
isNested: true,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
store.updateShownHeaders(
|
|
250
|
+
store.headers.value.map((header) => ({
|
|
251
|
+
...header,
|
|
252
|
+
show: header.field === 'name',
|
|
253
|
+
})),
|
|
254
|
+
);
|
|
255
|
+
await flushWrites();
|
|
256
|
+
|
|
257
|
+
expect(router.currentRoute.value.query[fieldsQueryKey]).toBeUndefined();
|
|
258
|
+
expect(localStorage.getItem(fieldsQueryKey)).toBe('name');
|
|
259
|
+
});
|
|
260
|
+
});
|
|
229
261
|
});
|
|
230
262
|
|
|
231
263
|
describe('access', () => {
|
|
@@ -249,15 +249,23 @@ export const tableHeadersStoreBody = ({
|
|
|
249
249
|
|
|
250
250
|
let persistedStorageControllers: PersistedStorageController[] = [];
|
|
251
251
|
|
|
252
|
-
const setupPersistence = async (
|
|
252
|
+
const setupPersistence = async ({
|
|
253
|
+
isNested = false,
|
|
254
|
+
}: {
|
|
255
|
+
isNested?: boolean;
|
|
256
|
+
} = {}) => {
|
|
253
257
|
const fieldsStorage = usePersistedStorage({
|
|
254
258
|
name: 'fields',
|
|
255
259
|
value: fields,
|
|
256
260
|
/* order is the restore priority: a shared link wins over local columns */
|
|
257
|
-
storages:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
+
storages: isNested
|
|
262
|
+
? [
|
|
263
|
+
PersistedStorageType.LocalStorage,
|
|
264
|
+
]
|
|
265
|
+
: [
|
|
266
|
+
PersistedStorageType.Route,
|
|
267
|
+
PersistedStorageType.LocalStorage,
|
|
268
|
+
],
|
|
261
269
|
storagePath: id,
|
|
262
270
|
onStore: (save, { name }) => {
|
|
263
271
|
const value = fields.value.join(',');
|
|
@@ -277,6 +285,12 @@ export const tableHeadersStoreBody = ({
|
|
|
277
285
|
const sortStorage = usePersistedStorage({
|
|
278
286
|
name: 'sort',
|
|
279
287
|
value: sort,
|
|
288
|
+
...(isNested && {
|
|
289
|
+
storages: [
|
|
290
|
+
PersistedStorageType.SessionStorage,
|
|
291
|
+
],
|
|
292
|
+
storagePath: id,
|
|
293
|
+
}),
|
|
280
294
|
});
|
|
281
295
|
|
|
282
296
|
const columnWidthsStorage = usePersistedStorage({
|
|
@@ -19,6 +19,8 @@ describe('tablePaginationStoreBody', () => {
|
|
|
19
19
|
let runWithRouter: <T>(fn: () => T) => T;
|
|
20
20
|
|
|
21
21
|
beforeEach(async () => {
|
|
22
|
+
sessionStorage.clear();
|
|
23
|
+
|
|
22
24
|
router = createRouter({
|
|
23
25
|
history: createMemoryHistory(),
|
|
24
26
|
routes,
|
|
@@ -33,9 +35,14 @@ describe('tablePaginationStoreBody', () => {
|
|
|
33
35
|
runWithRouter = (fn) => app.runWithContext(fn);
|
|
34
36
|
});
|
|
35
37
|
|
|
36
|
-
const setUpStore = async (
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
const setUpStore = async (
|
|
39
|
+
options?: {
|
|
40
|
+
isNested?: boolean;
|
|
41
|
+
},
|
|
42
|
+
namespace?: string,
|
|
43
|
+
) => {
|
|
44
|
+
const store = tablePaginationStoreBody(namespace);
|
|
45
|
+
await runWithRouter(() => store.setupPersistence(options));
|
|
39
46
|
return store;
|
|
40
47
|
};
|
|
41
48
|
|
|
@@ -131,4 +138,21 @@ describe('tablePaginationStoreBody', () => {
|
|
|
131
138
|
expect(router.currentRoute.value.query.page).toBe('5');
|
|
132
139
|
});
|
|
133
140
|
});
|
|
141
|
+
|
|
142
|
+
describe('a nested list', () => {
|
|
143
|
+
it('keeps a changed page out of the route query, in a namespaced sessionStorage key instead', async () => {
|
|
144
|
+
const store = await setUpStore(
|
|
145
|
+
{
|
|
146
|
+
isNested: true,
|
|
147
|
+
},
|
|
148
|
+
'cases',
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
store.updatePage(3);
|
|
152
|
+
await new Promise((resolve) => setTimeout(resolve));
|
|
153
|
+
|
|
154
|
+
expect(router.currentRoute.value.query.page).toBeUndefined();
|
|
155
|
+
expect(sessionStorage.getItem('cases/page')).toBe('3');
|
|
156
|
+
});
|
|
157
|
+
});
|
|
134
158
|
});
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { ref } from 'vue';
|
|
2
2
|
|
|
3
3
|
import { createDatalistStore } from '../_shared/createDatalistStore';
|
|
4
|
-
import
|
|
4
|
+
import {
|
|
5
|
+
type PersistedStorageController,
|
|
6
|
+
PersistedStorageType,
|
|
7
|
+
} from '../persist/PersistedStorage.types';
|
|
5
8
|
import { usePersistedStorage } from '../persist/usePersistedStorage';
|
|
6
9
|
import type { Identifiable } from '../types/createDatalistStore.types';
|
|
7
10
|
import type { useTableStoreConfig } from '../types/tableStore.types';
|
|
8
11
|
|
|
9
|
-
export const tablePaginationStoreBody = () => {
|
|
12
|
+
export const tablePaginationStoreBody = (namespace?: string) => {
|
|
10
13
|
const page = ref(1);
|
|
11
14
|
const size = ref(10);
|
|
12
15
|
const next = ref(false);
|
|
@@ -27,10 +30,20 @@ export const tablePaginationStoreBody = () => {
|
|
|
27
30
|
|
|
28
31
|
let persistedStorageControllers: PersistedStorageController[] = [];
|
|
29
32
|
|
|
30
|
-
const setupPersistence = (
|
|
33
|
+
const setupPersistence = ({
|
|
34
|
+
isNested = false,
|
|
35
|
+
}: {
|
|
36
|
+
isNested?: boolean;
|
|
37
|
+
} = {}) => {
|
|
31
38
|
const pageStorage = usePersistedStorage({
|
|
32
39
|
name: 'page',
|
|
33
40
|
value: page,
|
|
41
|
+
...(isNested && {
|
|
42
|
+
storages: [
|
|
43
|
+
PersistedStorageType.SessionStorage,
|
|
44
|
+
],
|
|
45
|
+
storagePath: namespace,
|
|
46
|
+
}),
|
|
34
47
|
onStore: (save, { name }) => {
|
|
35
48
|
return save({
|
|
36
49
|
name,
|
|
@@ -47,6 +60,12 @@ export const tablePaginationStoreBody = () => {
|
|
|
47
60
|
const sizeStorage = usePersistedStorage({
|
|
48
61
|
name: 'size',
|
|
49
62
|
value: size,
|
|
63
|
+
...(isNested && {
|
|
64
|
+
storages: [
|
|
65
|
+
PersistedStorageType.SessionStorage,
|
|
66
|
+
],
|
|
67
|
+
storagePath: namespace,
|
|
68
|
+
}),
|
|
50
69
|
onStore: (save, { name }) => {
|
|
51
70
|
return save({
|
|
52
71
|
name,
|
|
@@ -98,7 +117,7 @@ export const createTablePaginationStore = <Entity extends Identifiable>(
|
|
|
98
117
|
) => {
|
|
99
118
|
const id = `${namespace}/pagination`;
|
|
100
119
|
return createDatalistStore({
|
|
101
|
-
storeBody: tablePaginationStoreBody,
|
|
120
|
+
storeBody: () => tablePaginationStoreBody(namespace),
|
|
102
121
|
namespace: id,
|
|
103
122
|
config,
|
|
104
123
|
});
|
|
@@ -259,4 +259,30 @@ describe('tableStoreBody', () => {
|
|
|
259
259
|
);
|
|
260
260
|
});
|
|
261
261
|
});
|
|
262
|
+
|
|
263
|
+
describe('filters persistence of a nested list', () => {
|
|
264
|
+
it('keeps an added filter out of the route query, in sessionStorage instead', async () => {
|
|
265
|
+
const useStore = createTableStore('cases-nested-filters/datalist', {
|
|
266
|
+
apiModule: {
|
|
267
|
+
getList,
|
|
268
|
+
},
|
|
269
|
+
headers,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
mountTab(useStore);
|
|
273
|
+
await flush();
|
|
274
|
+
|
|
275
|
+
const store = useStore();
|
|
276
|
+
store.addFilter({
|
|
277
|
+
name: 'search',
|
|
278
|
+
value: 'lorem',
|
|
279
|
+
});
|
|
280
|
+
await flush();
|
|
281
|
+
|
|
282
|
+
expect(router.currentRoute.value.query).toEqual({});
|
|
283
|
+
expect(
|
|
284
|
+
sessionStorage.getItem('cases-nested-filters/datalist/filters'),
|
|
285
|
+
).toContain('lorem');
|
|
286
|
+
});
|
|
287
|
+
});
|
|
262
288
|
});
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import deepEqual from 'deep-equal';
|
|
2
|
-
import set from 'lodash
|
|
3
|
-
import { nextTick, type Ref, ref, toRaw, watch } from 'vue';
|
|
2
|
+
import { set } from 'lodash-es';
|
|
3
|
+
import { computed, nextTick, type Ref, ref, toRaw, watch } from 'vue';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
createDatalistStore,
|
|
7
7
|
makeThisToRefs,
|
|
8
8
|
} from '../_shared/createDatalistStore';
|
|
9
|
+
import type { FilterName } from '../filters';
|
|
9
10
|
import { createTableFiltersStore } from '../filters/createTableFiltersStore';
|
|
10
11
|
import { createTableHeadersStore } from '../headers/createTableHeadersStore';
|
|
11
12
|
import { createTablePaginationStore } from '../pagination/createTablePaginationStore';
|
|
12
13
|
import type { Identifiable } from '../types/createDatalistStore.types';
|
|
13
14
|
import type {
|
|
15
|
+
DatalistTableHeader,
|
|
14
16
|
LoadDataListOptions,
|
|
15
17
|
PatchItemPropertyParams,
|
|
16
18
|
useTableStoreConfig,
|
|
17
19
|
} from '../types/tableStore.types';
|
|
18
20
|
|
|
21
|
+
const getFilterName = (
|
|
22
|
+
filter: DatalistTableHeader['filter'],
|
|
23
|
+
): FilterName | undefined =>
|
|
24
|
+
typeof filter === 'object' ? filter?.name : filter;
|
|
25
|
+
|
|
19
26
|
export const tableStoreBody = <Entity extends Identifiable>(
|
|
20
27
|
namespace: string,
|
|
21
28
|
config: useTableStoreConfig<Entity>,
|
|
@@ -58,8 +65,8 @@ export const tableStoreBody = <Entity extends Identifiable>(
|
|
|
58
65
|
|
|
59
66
|
const headersStore = useHeadersStore();
|
|
60
67
|
const {
|
|
61
|
-
headers,
|
|
62
|
-
shownHeaders,
|
|
68
|
+
headers: rawHeaders,
|
|
69
|
+
shownHeaders: rawShownHeaders,
|
|
63
70
|
fields,
|
|
64
71
|
sort,
|
|
65
72
|
columnWidths,
|
|
@@ -90,6 +97,20 @@ export const tableStoreBody = <Entity extends Identifiable>(
|
|
|
90
97
|
updateSearchMode,
|
|
91
98
|
} = filtersStore;
|
|
92
99
|
|
|
100
|
+
const withFilteredFlag = (list: DatalistTableHeader[]) =>
|
|
101
|
+
list.map((header) => {
|
|
102
|
+
const name = getFilterName(header.filter);
|
|
103
|
+
return name
|
|
104
|
+
? {
|
|
105
|
+
...header,
|
|
106
|
+
filtered: filtersManager.value.hasFilter(name),
|
|
107
|
+
}
|
|
108
|
+
: header;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const headers = computed(() => withFilteredFlag(rawHeaders.value));
|
|
112
|
+
const shownHeaders = computed(() => withFilteredFlag(rawShownHeaders.value));
|
|
113
|
+
|
|
93
114
|
/**
|
|
94
115
|
* @internal
|
|
95
116
|
* @description
|
|
@@ -317,9 +338,15 @@ export const tableStoreBody = <Entity extends Identifiable>(
|
|
|
317
338
|
|
|
318
339
|
if (!disablePersistence) {
|
|
319
340
|
await Promise.allSettled([
|
|
320
|
-
setupPaginationPersistence(
|
|
321
|
-
|
|
322
|
-
|
|
341
|
+
setupPaginationPersistence({
|
|
342
|
+
isNested: isNested.value,
|
|
343
|
+
}),
|
|
344
|
+
setupFiltersPersistence({
|
|
345
|
+
isNested: isNested.value,
|
|
346
|
+
}),
|
|
347
|
+
setupHeadersPersistence({
|
|
348
|
+
isNested: isNested.value,
|
|
349
|
+
}),
|
|
323
350
|
]);
|
|
324
351
|
}
|
|
325
352
|
|
|
@@ -367,14 +394,6 @@ export const tableStoreBody = <Entity extends Identifiable>(
|
|
|
367
394
|
|
|
368
395
|
await setupStore();
|
|
369
396
|
|
|
370
|
-
/*
|
|
371
|
-
on the first setup the restore path is authoritative.
|
|
372
|
-
|
|
373
|
-
a store initialized with a parentId is a list nested in a card page, not a
|
|
374
|
-
registry: it shares the query param names with the registry stores, and
|
|
375
|
-
the url it would publish into is the card one – so it keeps writing on
|
|
376
|
-
change only, and syncs merely on demand
|
|
377
|
-
*/
|
|
378
397
|
if (isStoreAlreadySetUp && !disablePersistence && !storeParentId) {
|
|
379
398
|
await syncPersistence();
|
|
380
399
|
}
|
|
@@ -2,15 +2,26 @@ import type { ApiModule } from '@webitel/ui-sdk/api/types/ApiModule';
|
|
|
2
2
|
import type { WtTableHeader } from '@webitel/ui-sdk/components/wt-table/types/WtTable';
|
|
3
3
|
import type { Ref } from 'vue';
|
|
4
4
|
|
|
5
|
-
import type { IFiltersManager } from '../filters';
|
|
5
|
+
import type { FilterName, IFiltersManager } from '../filters';
|
|
6
6
|
import type { DatalistStoreProviderType } from './StoreProvider';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Minimal shape of an already-resolved header filter. Deliberately not the full
|
|
10
|
+
* `AnyFilterConfig` (with its `Component` props): `createTableHeadersStore` keeps headers in a
|
|
11
|
+
* plain `ref<DatalistTableHeader[]>`, and `Component` props there send Vue's `UnwrapRef` into
|
|
12
|
+
* excessive type-instantiation depth (TS2589). `useColumnFilter`'s `isResolvedFilterConfig`
|
|
13
|
+
* narrows a value of this shape back to `AnyFilterConfig` for actual use.
|
|
14
|
+
*/
|
|
15
|
+
export type ResolvedHeaderFilter = {
|
|
16
|
+
name: FilterName;
|
|
17
|
+
};
|
|
18
|
+
|
|
8
19
|
/**
|
|
9
20
|
* Table header shape used inside the datalist stores. In addition to the
|
|
10
21
|
* base {@link WtTableHeader} shape, datalist stores key columns by `field`
|
|
11
22
|
* and may flag dynamically-appended headers for lazy initialization.
|
|
12
23
|
*/
|
|
13
|
-
export type DatalistTableHeader = WtTableHeader & {
|
|
24
|
+
export type DatalistTableHeader = Omit<WtTableHeader, 'filter'> & {
|
|
14
25
|
field: string;
|
|
15
26
|
shouldBeInitialized?: boolean;
|
|
16
27
|
/**
|
|
@@ -20,6 +31,14 @@ export type DatalistTableHeader = WtTableHeader & {
|
|
|
20
31
|
* restorable from persisted state. Omitted means allowed.
|
|
21
32
|
*/
|
|
22
33
|
access?: () => boolean | Ref<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Name of the filter shown in the column header popover (`column-filter` slot),
|
|
36
|
+
* or an already-resolved config for it (build one with `createFilterConfig`). Passing a
|
|
37
|
+
* config here lets `headers.ts` map the header to its filter once, instead of
|
|
38
|
+
* `useColumnFilter` searching `filterOptions`/`filterableExtensionFields` for it on every
|
|
39
|
+
* column.
|
|
40
|
+
*/
|
|
41
|
+
filter?: WtTableHeader['filter'] | ResolvedHeaderFilter;
|
|
23
42
|
};
|
|
24
43
|
|
|
25
44
|
export type TrackSelectedRowBy<T> = (row: T) => T;
|