@webitel/ui-datalist 1.0.36 → 1.0.38
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/package.json +2 -5
- package/src/modules/filters/classes/Filter.ts +2 -0
- package/src/modules/filters/components/config/{dynamic-filter-config-form-value-input.vue → dynamic-view/dynamic-filter-config-form-value-input.vue} +1 -1
- package/src/modules/filters/components/config/{dynamic-filter-config-form.vue → dynamic-view/dynamic-filter-config-form.vue} +2 -2
- package/src/modules/filters/components/config/static-view/static-filter-field.vue +56 -0
- package/src/modules/filters/components/dynamic-filter-add-action.vue +2 -2
- package/src/modules/filters/components/preview/dynamic-filter-preview.vue +7 -24
- package/src/modules/filters/components/search-bar/dynamic-filter-search.vue +28 -12
- package/src/modules/filters/components/table-filters-panel.vue +65 -15
- package/src/modules/filters/components/types/Filter.types.ts +26 -0
- package/src/modules/filters/composables/useFilterConfigsToolkit.ts +21 -1
- package/src/modules/filters/modules/filterConfig/classes/FilterConfig.ts +3 -0
- package/src/modules/filters/modules/filterConfig/components/_shared/has-options/has-option-filter-value-field.vue +9 -4
- package/src/modules/filters/modules/filterConfig/components/contact-group/contact-group-filter-value-field.vue +39 -25
- package/src/modules/filters/modules/filterConfig/components/contact-label/contact-label-filter-value-field.vue +31 -17
- package/src/modules/filters/modules/filterConfig/components/has-user/has-user-filter-value-field.vue +18 -6
- package/src/modules/form/composables/useFormComponent.ts +26 -0
- package/src/modules/form/composables/useItemCardSaveText.ts +22 -0
- package/src/modules/form/composables/useValidation.ts +34 -0
- package/src/modules/form/index.ts +3 -0
- package/src/modules/form/stores/createFormStore.ts +4 -3
- package/src/modules/table/createTableStore.store.ts +33 -9
- package/src/modules/types/tableStore.types.ts +1 -0
- package/types/modules/filter-presets/stores/createFilterPresetsStore.d.ts +1 -0
- package/types/modules/filters/components/config/dynamic-view/dynamic-filter-config-form-label.vue.d.ts +11 -0
- package/types/modules/filters/components/config/dynamic-view/dynamic-filter-config-form-value-input.vue.d.ts +16 -0
- package/types/modules/filters/components/config/dynamic-view/dynamic-filter-config-form.vue.d.ts +93 -0
- package/types/modules/filters/components/config/dynamic-view/dynamic-filter-config-view.vue.d.ts +27 -0
- package/types/modules/filters/components/config/static-view/static-filter-field.vue.d.ts +11 -0
- package/types/modules/filters/components/dynamic-filter-add-action.vue.d.ts +2 -2
- package/types/modules/filters/components/preview/dynamic-filter-preview.vue.d.ts +12 -21
- package/types/modules/filters/components/search-bar/dynamic-filter-search.vue.d.ts +1 -0
- package/types/modules/filters/components/table-filters-panel.vue.d.ts +7 -0
- package/types/modules/filters/components/types/Filter.types.d.ts +20 -0
- package/types/modules/filters/composables/useFilterConfigsToolkit.d.ts +2 -1
- package/types/modules/filters/modules/filterConfig/classes/FilterConfig.d.ts +2 -1
- package/types/modules/filters/modules/filterConfig/components/_custom/type-extension-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/_shared/durations/duration-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/_shared/has-options/has-option-filter-value-field.vue.d.ts +4 -1
- package/types/modules/filters/modules/filterConfig/components/agent/agent-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 +2 -2
- package/types/modules/filters/modules/filterConfig/components/call-direction/call-direction-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 +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-assignee/filterConfig.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-author/case-author-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-close-reason-groups/case-close-reason-groups-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-impacted/case-impacted-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-priority/case-priority-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-reporter/case-reporter-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-sla/case-sla-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-sla-condition/case-sla-condition-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-source/case-source-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/case-status/case-status-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/contact/contact-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/contact-group/contact-group-filter-value-field.vue.d.ts +4 -2
- package/types/modules/filters/modules/filterConfig/components/contact-group/index.d.ts +6 -2
- package/types/modules/filters/modules/filterConfig/components/contact-label/contact-label-filter-value-field.vue.d.ts +4 -2
- package/types/modules/filters/modules/filterConfig/components/contact-label/index.d.ts +6 -2
- package/types/modules/filters/modules/filterConfig/components/contact-owner/contact-owner-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/contact-owner/index.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/gateway/gateway-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/grantee/grantee-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/hangup-cause/hangup-cause-filter-value-field.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/has-attachment/has-attachment-filter-value-field.vue.d.ts +2 -2
- 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 +10 -4
- package/types/modules/filters/modules/filterConfig/components/index.d.ts +17 -6
- package/types/modules/filters/modules/filterConfig/components/queue/queue-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 +2 -2
- package/types/modules/filters/modules/filterConfig/components/rating/rating-from-to-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 +2 -2
- package/types/modules/filters/modules/filterConfig/components/tag/tag-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/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 +2 -2
- package/types/modules/filters/modules/filterConfig/components/variable/variable-filter-value-field.vue.d.ts +2 -2
- package/types/modules/form/composables/useFormComponent.d.ts +9 -0
- package/types/modules/form/composables/useItemCardSaveText.d.ts +7 -0
- package/types/modules/form/composables/useValidation.d.ts +10 -0
- package/types/modules/form/index.d.ts +3 -0
- package/types/modules/form/stores/createFormStore.d.ts +18 -9
- package/types/modules/table/createTableStore.store.d.ts +2 -0
- package/types/modules/types/tableStore.types.d.ts +1 -0
- /package/src/modules/filters/components/config/{dynamic-filter-config-form-label.vue → dynamic-view/dynamic-filter-config-form-label.vue} +0 -0
- /package/src/modules/filters/components/config/{dynamic-filter-config-view.vue → dynamic-view/dynamic-filter-config-view.vue} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webitel/ui-datalist",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.38",
|
|
4
4
|
"description": "Toolkit for building data lists in webitel ui system",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build:types": "vue-tsc -p ./tsconfig.build.json",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@vuelidate/validators": "^2.0.4",
|
|
54
54
|
"@webitel/styleguide": "^24.12.26",
|
|
55
55
|
"@webitel/ui-sdk": "^25.4.76",
|
|
56
|
-
"zod": "^
|
|
56
|
+
"zod": "^3.25.55"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@eslint/js": "^9.22.0",
|
|
@@ -81,9 +81,6 @@
|
|
|
81
81
|
"vite-plugin-checker": "^0.9.0",
|
|
82
82
|
"vue-tsc": "^2.2.8"
|
|
83
83
|
},
|
|
84
|
-
"overrides": {
|
|
85
|
-
"zod": "^4.0.0-beta.20250505T195954"
|
|
86
|
-
},
|
|
87
84
|
"engines": {
|
|
88
85
|
"npm": "10",
|
|
89
86
|
"node": "v22"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</template>
|
|
10
10
|
|
|
11
11
|
<script setup lang="ts">
|
|
12
|
-
import {AnyFilterConfig} from "
|
|
12
|
+
import {AnyFilterConfig} from "../../../modules/filterConfig/classes/FilterConfig";
|
|
13
13
|
|
|
14
14
|
const filterValue = defineModel<unknown>();
|
|
15
15
|
|
|
@@ -65,8 +65,8 @@ import deepcopy from 'deep-copy';
|
|
|
65
65
|
import { computed, ref, watch } from 'vue';
|
|
66
66
|
import { useI18n } from 'vue-i18n';
|
|
67
67
|
|
|
68
|
-
import {FilterInitParams, IFilter} from "
|
|
69
|
-
import {BaseFilterConfig} from "
|
|
68
|
+
import {FilterInitParams, IFilter} from "../../../classes/Filter";
|
|
69
|
+
import {BaseFilterConfig} from "../../../modules/filterConfig/classes/FilterConfig";
|
|
70
70
|
import DynamicFilterConfigFormLabel from './dynamic-filter-config-form-label.vue';
|
|
71
71
|
import DynamicFilterConfigFormValueInput from "./dynamic-filter-config-form-value-input.vue";
|
|
72
72
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="static-filter-field">
|
|
3
|
+
<component
|
|
4
|
+
:is="filterConfig.valueInputComponent"
|
|
5
|
+
:disable-validation="true /*for static filters validation is not needed (different presentation with dynamic filters)*/"
|
|
6
|
+
:filter-config="filterConfig"
|
|
7
|
+
:hide-label="true /*for static filters need to hide label and display placeholder (different presentation with dynamic filters)*/"
|
|
8
|
+
:model-value="filterValue"
|
|
9
|
+
:placeholder="filterConfig.label"
|
|
10
|
+
@update:model-value="onValueChange"
|
|
11
|
+
/>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script lang="ts" setup>
|
|
16
|
+
import { isEmpty } from '@webitel/ui-sdk/scripts';
|
|
17
|
+
import { computed } from 'vue';
|
|
18
|
+
import { StaticFilterEmits, StaticFilterProps } from '../../types/Filter.types';
|
|
19
|
+
|
|
20
|
+
/* Author @Lera24
|
|
21
|
+
Static filters
|
|
22
|
+
Description - [https://webitel.atlassian.net/browse/WTEL-6934]
|
|
23
|
+
Example - section CRM / lookups Contact groups / Contacts tab / Adding contacts popup (click on the "+" button) */
|
|
24
|
+
|
|
25
|
+
const props = defineProps<StaticFilterProps>();
|
|
26
|
+
|
|
27
|
+
const emit = defineEmits<StaticFilterEmits>();
|
|
28
|
+
|
|
29
|
+
const filterValue = computed(() => props.filter?.value);
|
|
30
|
+
|
|
31
|
+
const onValueChange = (value) => {
|
|
32
|
+
if (isEmpty(value) && typeof value !== 'boolean') {
|
|
33
|
+
return emit('delete:filter', props.filter);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (isEmpty(filterValue.value)) {
|
|
37
|
+
return emit('add:filter', {
|
|
38
|
+
name: props.filterConfig.name,
|
|
39
|
+
value,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
emit('update:filter', {
|
|
44
|
+
...props.filter,
|
|
45
|
+
value,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
;
|
|
49
|
+
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<style lang="scss" scoped>
|
|
53
|
+
.static-filter-field {
|
|
54
|
+
flex: 1;
|
|
55
|
+
}
|
|
56
|
+
</style>
|
|
@@ -35,8 +35,8 @@ import { useI18n } from 'vue-i18n';
|
|
|
35
35
|
|
|
36
36
|
import {FilterInitParams} from "../classes/Filter";
|
|
37
37
|
import {BaseFilterConfig} from "../modules/filterConfig/classes/FilterConfig";
|
|
38
|
-
import DynamicFilterConfigForm from './config/dynamic-filter-config-form.vue';
|
|
39
|
-
import DynamicFilterConfigView from './config/dynamic-filter-config-view.vue';
|
|
38
|
+
import DynamicFilterConfigForm from './config/dynamic-view/dynamic-filter-config-form.vue';
|
|
39
|
+
import DynamicFilterConfigView from './config/dynamic-view/dynamic-filter-config-view.vue';
|
|
40
40
|
|
|
41
41
|
interface Props {
|
|
42
42
|
filterConfigs: BaseFilterConfig[];
|
|
@@ -70,34 +70,17 @@ import {
|
|
|
70
70
|
WtTooltip,
|
|
71
71
|
} from '@webitel/ui-sdk/components';
|
|
72
72
|
import { computed, ref, watch } from 'vue';
|
|
73
|
-
import { useI18n } from 'vue-i18n';
|
|
74
73
|
|
|
75
|
-
import {
|
|
76
|
-
import {
|
|
74
|
+
import { IFilter } from '../../classes/Filter';
|
|
75
|
+
import { DynamicFilterProps, DynamicFilterEmits } from '../types/Filter.types';
|
|
77
76
|
import { FilterOptionToPreviewApiSearchMethodMap } from '../../modules/filterConfig/components';
|
|
78
|
-
import
|
|
79
|
-
import
|
|
80
|
-
import DynamicFilterConfigView from '../config/dynamic-filter-config-view.vue';
|
|
77
|
+
import DynamicFilterConfigForm from '../config/dynamic-view/dynamic-filter-config-form.vue';
|
|
78
|
+
import DynamicFilterConfigView from '../config/dynamic-view/dynamic-filter-config-view.vue';
|
|
81
79
|
import DynamicFilterPreviewInfo from './dynamic-filter-preview-info.vue';
|
|
82
80
|
|
|
83
|
-
|
|
84
|
-
filter: IFilter;
|
|
85
|
-
/**
|
|
86
|
-
* @description
|
|
87
|
-
* this filter config
|
|
88
|
-
*/
|
|
89
|
-
filterConfig: AnyFilterConfig;
|
|
90
|
-
readonly?: boolean;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const { t } = useI18n();
|
|
94
|
-
|
|
95
|
-
const props = defineProps<Props>();
|
|
81
|
+
const props = defineProps<DynamicFilterProps>();
|
|
96
82
|
|
|
97
|
-
const emit = defineEmits<
|
|
98
|
-
'update:filter': [FilterData];
|
|
99
|
-
'delete:filter': [IFilter];
|
|
100
|
-
}>();
|
|
83
|
+
const emit = defineEmits<DynamicFilterEmits>();
|
|
101
84
|
|
|
102
85
|
const localValue = ref();
|
|
103
86
|
|
|
@@ -167,8 +150,8 @@ const deleteFilter = () => {
|
|
|
167
150
|
<style lang="scss" scoped>
|
|
168
151
|
.wt-chip {
|
|
169
152
|
display: flex;
|
|
170
|
-
justify-content: center;
|
|
171
153
|
align-items: center;
|
|
154
|
+
justify-content: center;
|
|
172
155
|
gap: var(--spacing-2xs);
|
|
173
156
|
}
|
|
174
157
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:search-mode="searchMode"
|
|
5
5
|
:search-mode-options="searchModeOptions"
|
|
6
6
|
:value="localSearchValue"
|
|
7
|
-
@input="
|
|
7
|
+
@input="inputValue"
|
|
8
8
|
@search="handleSearch"
|
|
9
9
|
@update:search-mode="updateSearchMode"
|
|
10
10
|
/>
|
|
@@ -28,6 +28,7 @@ const props = defineProps<{
|
|
|
28
28
|
* default search name is used when there are no search modes
|
|
29
29
|
*/
|
|
30
30
|
singleSearchName?: string;
|
|
31
|
+
value?: string;
|
|
31
32
|
}>();
|
|
32
33
|
|
|
33
34
|
const defaultSearchName = props.singleSearchName || 'search';
|
|
@@ -41,7 +42,7 @@ const emit = defineEmits<{
|
|
|
41
42
|
const { t } = useI18n();
|
|
42
43
|
|
|
43
44
|
const searchMode: Ref<FilterName> = ref();
|
|
44
|
-
const localSearchValue =
|
|
45
|
+
const localSearchValue = computed(() => props?.value || '');
|
|
45
46
|
|
|
46
47
|
const hasFilter = (filterName = searchMode.value) => {
|
|
47
48
|
return props.filtersManager.filters.has(filterName);
|
|
@@ -72,17 +73,32 @@ const currentSearchName = computed(() => {
|
|
|
72
73
|
return defaultSearchName;
|
|
73
74
|
});
|
|
74
75
|
|
|
76
|
+
const inputValue = (value: string) => {
|
|
77
|
+
localSearchValue.value = value;
|
|
78
|
+
|
|
79
|
+
if (value === '') {
|
|
80
|
+
if (hasFilter(currentSearchName.value)) {
|
|
81
|
+
deleteFilter({
|
|
82
|
+
name: currentSearchName.value,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
75
89
|
const handleSearch = (value = localSearchValue.value) => {
|
|
76
|
-
if
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
if(value) {
|
|
91
|
+
if (hasFilter(currentSearchName.value)) {
|
|
92
|
+
updateFilter({
|
|
93
|
+
name: currentSearchName.value,
|
|
94
|
+
value,
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
addFilter({
|
|
98
|
+
name: currentSearchName.value,
|
|
99
|
+
value,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
86
102
|
}
|
|
87
103
|
};
|
|
88
104
|
|
|
@@ -1,21 +1,36 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<div :class="{ 'table-filters-panel--static-wrapper': staticMode }">
|
|
2
3
|
<dynamic-filter-panel-wrapper>
|
|
3
4
|
<template #filters>
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
<div v-if="staticMode" class="table-filters-panel--static-filters">
|
|
6
|
+
<static-filter-field
|
|
7
|
+
v-for="({ filter, filterConfig }) in staticViewFilterToFilterConfigMappings"
|
|
8
|
+
:key="filterConfig.name"
|
|
9
|
+
:filter="filter"
|
|
10
|
+
:filter-config="filterConfig"
|
|
11
|
+
@add:filter="emit('filter:add', $event)"
|
|
12
|
+
@update:filter="emit('filter:update', $event)"
|
|
13
|
+
@delete:filter="emit('filter:delete', filter)"
|
|
14
|
+
/>
|
|
15
|
+
</div>
|
|
13
16
|
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
<div v-else class="table-filters-panel--dynamic-filters">
|
|
18
|
+
<dynamic-filter-preview
|
|
19
|
+
v-for="({ filter, filterConfig }) of appliedFilterToFilterConfigMappings"
|
|
20
|
+
:key="filter.name"
|
|
21
|
+
:filter="filter"
|
|
22
|
+
:filter-config="filterConfig"
|
|
23
|
+
disable-click-away
|
|
24
|
+
@update:filter="emit('filter:update', $event)"
|
|
25
|
+
@delete:filter="emit('filter:delete', filter)"
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
<dynamic-filter-add-action
|
|
29
|
+
:filter-configs="unAppliedFiltersConfigs"
|
|
30
|
+
:show-label="!appliedFilters.length"
|
|
31
|
+
@add:filter="emit('filter:add', $event)"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
19
34
|
</template>
|
|
20
35
|
|
|
21
36
|
<template #actions>
|
|
@@ -42,11 +57,13 @@
|
|
|
42
57
|
/>
|
|
43
58
|
|
|
44
59
|
<wt-icon-action
|
|
60
|
+
v-if="!staticMode"
|
|
45
61
|
action="close"
|
|
46
62
|
@click="emit('hide')"
|
|
47
63
|
/>
|
|
48
64
|
</template>
|
|
49
65
|
</dynamic-filter-panel-wrapper>
|
|
66
|
+
</div>
|
|
50
67
|
</template>
|
|
51
68
|
|
|
52
69
|
<script lang="ts" setup>
|
|
@@ -61,6 +78,7 @@ import {IFiltersManager} from "../classes/FiltersManager";
|
|
|
61
78
|
import {useFilterConfigsToolkit} from "../composables/useFilterConfigsToolkit";
|
|
62
79
|
import {AnyFilterConfig} from "../modules/filterConfig/classes/FilterConfig";
|
|
63
80
|
import { FilterOption } from '../modules/filterConfig/enums/FilterOption';
|
|
81
|
+
import StaticFilterField from './config/static-view/static-filter-field.vue';
|
|
64
82
|
import DynamicFilterAddAction from './dynamic-filter-add-action.vue';
|
|
65
83
|
import DynamicFilterPanelWrapper from './dynamic-filter-panel-wrapper.vue';
|
|
66
84
|
import DynamicFilterPreview from './preview/dynamic-filter-preview.vue';
|
|
@@ -107,6 +125,14 @@ type Props = {
|
|
|
107
125
|
* TODO: https://github.com/webitel/webitel-ui-sdk/pull/551
|
|
108
126
|
*/
|
|
109
127
|
usePresetsStore?: Store;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @author @Lera24
|
|
131
|
+
* @description
|
|
132
|
+
* Static view filter rendering mode. With it, filters are drawn immediately when the form is opened
|
|
133
|
+
* [https://webitel.atlassian.net/browse/WTEL-6934]
|
|
134
|
+
*/
|
|
135
|
+
staticMode?: boolean;
|
|
110
136
|
};
|
|
111
137
|
|
|
112
138
|
const props = defineProps<Props>();
|
|
@@ -134,6 +160,7 @@ const emit = defineEmits<{
|
|
|
134
160
|
|
|
135
161
|
const {
|
|
136
162
|
filterConfigs,
|
|
163
|
+
staticViewFilterToFilterConfigMappings,
|
|
137
164
|
filtersIncluded,
|
|
138
165
|
appliedFilters,
|
|
139
166
|
appliedFilterToFilterConfigMappings,
|
|
@@ -142,9 +169,32 @@ const {
|
|
|
142
169
|
filterOptions: props.filterOptions,
|
|
143
170
|
filtersManager: props.filtersManager,
|
|
144
171
|
filterableExtensionFields: props.filterableExtensionFields,
|
|
172
|
+
staticMode: props.staticMode,
|
|
145
173
|
});
|
|
146
174
|
|
|
147
175
|
const enablePresets = computed(() => !!props.presetNamespace);
|
|
148
176
|
</script>
|
|
149
177
|
|
|
150
|
-
<style
|
|
178
|
+
<style>
|
|
179
|
+
.table-filters-panel--static-wrapper {
|
|
180
|
+
width: 100%;
|
|
181
|
+
|
|
182
|
+
.dynamic-filter-panel-wrapper {
|
|
183
|
+
align-items: center;
|
|
184
|
+
}
|
|
185
|
+
.dynamic-filter-panel-wrapper__filters {
|
|
186
|
+
display: flex;
|
|
187
|
+
flex-wrap: nowrap;
|
|
188
|
+
grid-gap: var(--spacing-xs);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
.table-filters-panel--dynamic-filters {
|
|
192
|
+
display: flex;
|
|
193
|
+
gap: var(--spacing-sm);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.table-filters-panel--static-filters {
|
|
197
|
+
display: contents;
|
|
198
|
+
gap: var(--spacing-sm);
|
|
199
|
+
}
|
|
200
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AnyFilterConfig } from '../../modules/filterConfig';
|
|
2
|
+
import { FilterData, FilterInitParams, IFilter } from '../../classes/Filter';
|
|
3
|
+
|
|
4
|
+
export interface FilterEmits {
|
|
5
|
+
'update:filter': [FilterData];
|
|
6
|
+
'delete:filter': [IFilter];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface StaticFilterEmits extends FilterEmits {
|
|
10
|
+
'add:filter': [FilterInitParams];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface DynamicFilterEmits extends FilterEmits {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface FilterProps {
|
|
17
|
+
filter: IFilter;
|
|
18
|
+
filterConfig: AnyFilterConfig;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface StaticFilterProps extends FilterProps {
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface DynamicFilterProps extends FilterProps {
|
|
25
|
+
readonly?: boolean;
|
|
26
|
+
}
|
|
@@ -38,12 +38,13 @@ export type FilterConfigToolkitParams = {
|
|
|
38
38
|
filterOptions: (FilterOption | BaseFilterConfig)[];
|
|
39
39
|
filtersManager: IFiltersManager;
|
|
40
40
|
filterableExtensionFields: WebitelProtoDataField[];
|
|
41
|
+
staticMode?: boolean;
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
export const useFilterConfigsToolkit = ({
|
|
44
45
|
filterOptions,
|
|
45
46
|
filtersManager,
|
|
46
|
-
filterableExtensionFields = [],
|
|
47
|
+
filterableExtensionFields = [], staticMode = false,
|
|
47
48
|
}: FilterConfigToolkitParams): FilterConfigToolkit => {
|
|
48
49
|
const { t } = useI18n();
|
|
49
50
|
|
|
@@ -126,11 +127,30 @@ export const useFilterConfigsToolkit = ({
|
|
|
126
127
|
});
|
|
127
128
|
});
|
|
128
129
|
|
|
130
|
+
const staticViewFilterToFilterConfigMappings = computed(() => {
|
|
131
|
+
// Author @Lera24
|
|
132
|
+
// [https://webitel.atlassian.net/browse/WTEL-6934]
|
|
133
|
+
//
|
|
134
|
+
// Static (computed staticViewFilterToFilterConfigMappings) filters
|
|
135
|
+
// use all page filters passed in filterOptions for configuration, without values
|
|
136
|
+
//
|
|
137
|
+
// Dynamic (computed applyFilterToFilterConfigMappings) filters consist of a configuration
|
|
138
|
+
// of filters for which a value has already been defined
|
|
139
|
+
|
|
140
|
+
return filterConfigs.value.map((filterConfig) => {
|
|
141
|
+
return {
|
|
142
|
+
filter: filtersManager.getFilter(filterConfig.name),
|
|
143
|
+
filterConfig,
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
129
148
|
return {
|
|
130
149
|
filterConfigs,
|
|
131
150
|
filtersIncluded,
|
|
132
151
|
appliedFilters,
|
|
133
152
|
appliedFilterToFilterConfigMappings,
|
|
153
|
+
staticViewFilterToFilterConfigMappings,
|
|
134
154
|
unAppliedFiltersConfigs,
|
|
135
155
|
};
|
|
136
156
|
};
|
|
@@ -48,6 +48,7 @@ export class FilterConfig implements BaseFilterConfig {
|
|
|
48
48
|
valueInputComponent: Component;
|
|
49
49
|
valuePreviewComponent: Component;
|
|
50
50
|
label?: ReturnType<MessageResolver> | string;
|
|
51
|
+
staticView?: boolean;
|
|
51
52
|
notDeletable: boolean;
|
|
52
53
|
|
|
53
54
|
constructor({
|
|
@@ -55,6 +56,7 @@ export class FilterConfig implements BaseFilterConfig {
|
|
|
55
56
|
valueInputComponent,
|
|
56
57
|
valuePreviewComponent,
|
|
57
58
|
notDeletable,
|
|
59
|
+
staticView,
|
|
58
60
|
}: FilterConfigBaseParams = {}) {
|
|
59
61
|
|
|
60
62
|
if (name) this.name = name;
|
|
@@ -62,6 +64,7 @@ export class FilterConfig implements BaseFilterConfig {
|
|
|
62
64
|
if (valuePreviewComponent)
|
|
63
65
|
this.valuePreviewComponent = valuePreviewComponent;
|
|
64
66
|
this.notDeletable = !!notDeletable;
|
|
67
|
+
if (staticView) this.staticView = staticView;
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<wt-select
|
|
3
|
-
|
|
4
|
-
:clearable="false"
|
|
3
|
+
:label="labelValue"
|
|
5
4
|
:options="BooleanOptions"
|
|
6
5
|
:value="strModel"
|
|
7
|
-
:label="t('webitelUI.filters.filterValue')"
|
|
8
6
|
class="has-option-filter-value-field"
|
|
9
7
|
track-by="value"
|
|
10
8
|
use-value-from-options-by-prop="value"
|
|
9
|
+
v-bind="attrs"
|
|
11
10
|
@input="strModel = $event"
|
|
12
11
|
/>
|
|
13
12
|
</template>
|
|
@@ -19,18 +18,24 @@ import { useI18n } from 'vue-i18n';
|
|
|
19
18
|
|
|
20
19
|
import { BooleanOptions } from '../../../enums/options/BooleanFilterOptions';
|
|
21
20
|
|
|
21
|
+
const props = defineProps<{
|
|
22
|
+
hideLabel?: boolean;
|
|
23
|
+
}>();
|
|
24
|
+
|
|
22
25
|
const model = defineModel<boolean | null>();
|
|
23
26
|
|
|
24
27
|
const attrs = useAttrs();
|
|
25
28
|
|
|
26
29
|
const { t } = useI18n();
|
|
27
30
|
|
|
31
|
+
const labelValue = computed(() => props?.hideLabel ? null : t('webitelUI.filters.filterValue'))
|
|
32
|
+
|
|
28
33
|
const strModel = computed({
|
|
29
34
|
get: () => {
|
|
30
35
|
return typeof model.value === 'boolean' ? String(model.value) : model.value;
|
|
31
36
|
},
|
|
32
37
|
set: (value: string) => {
|
|
33
|
-
model.value = value === 'true';
|
|
38
|
+
model.value = typeof value === 'string' ? value === 'true' : value;
|
|
34
39
|
},
|
|
35
40
|
});
|
|
36
41
|
</script>
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<wt-select
|
|
3
3
|
:close-on-select="false"
|
|
4
|
-
:label="
|
|
4
|
+
:label="labelValue"
|
|
5
5
|
:search-method="props.filterConfig.searchRecords"
|
|
6
|
-
:v="v
|
|
6
|
+
:v="v$?.model.list"
|
|
7
7
|
:value="model?.list"
|
|
8
8
|
multiple
|
|
9
9
|
track-by="id"
|
|
10
10
|
use-value-from-options-by-prop="id"
|
|
11
|
-
|
|
11
|
+
v-bind="$attrs"
|
|
12
|
+
@input="changeListValue"
|
|
12
13
|
/>
|
|
13
14
|
<wt-checkbox
|
|
14
15
|
v-if="!props.filterConfig?.hideUnassigned"
|
|
15
16
|
:label="t('reusable.showUnassigned')"
|
|
16
17
|
:selected="model?.unassigned"
|
|
17
|
-
:v="v
|
|
18
|
+
:v="v$?.model.unassigned"
|
|
18
19
|
@change="model.unassigned = $event"
|
|
19
20
|
/>
|
|
20
21
|
</template>
|
|
@@ -30,7 +31,10 @@ import { IContactGroupFilterConfig } from './index';
|
|
|
30
31
|
|
|
31
32
|
const props = defineProps<{
|
|
32
33
|
filterConfig: IContactGroupFilterConfig;
|
|
34
|
+
disableValidation?: boolean;
|
|
35
|
+
hideLabel?: boolean;
|
|
33
36
|
}>();
|
|
37
|
+
|
|
34
38
|
type ModelValue = {
|
|
35
39
|
list: string[];
|
|
36
40
|
unassigned: boolean;
|
|
@@ -43,35 +47,45 @@ const emit = defineEmits<{
|
|
|
43
47
|
}>();
|
|
44
48
|
const { t } = useI18n();
|
|
45
49
|
|
|
46
|
-
const
|
|
47
|
-
|
|
50
|
+
const labelValue = computed(() => props?.hideLabel ? null : t('webitelUI.filters.filterValue'))
|
|
51
|
+
|
|
52
|
+
const changeListValue = (event) => {
|
|
53
|
+
if(!event.length && !model.value.unassigned) {
|
|
54
|
+
|
|
55
|
+
return model.value = {}
|
|
56
|
+
} else {
|
|
48
57
|
model.value = {
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
...model.value,
|
|
59
|
+
list: event,
|
|
51
60
|
};
|
|
52
61
|
}
|
|
53
62
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
const v$ = computed(() => {
|
|
64
|
+
if (props.disableValidation) return null;
|
|
65
|
+
return useVuelidate(
|
|
66
|
+
computed(() => ({
|
|
67
|
+
model: {
|
|
68
|
+
list: { required: requiredIf(() => !model.value.unassigned) },
|
|
69
|
+
unassigned: {
|
|
70
|
+
required: requiredIf(() =>
|
|
71
|
+
props.filterConfig?.hideUnassigned && !model.value.list.length
|
|
72
|
+
),
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
})),
|
|
76
|
+
{ model },
|
|
77
|
+
{ $autoDirty: true }
|
|
78
|
+
);
|
|
79
|
+
});
|
|
67
80
|
|
|
68
81
|
watch(
|
|
69
|
-
() => v
|
|
82
|
+
() => v$?.value?.$invalid,
|
|
70
83
|
(invalid) => {
|
|
71
|
-
|
|
84
|
+
if (v$?.value) {
|
|
85
|
+
emit('update:invalid', invalid);
|
|
86
|
+
}
|
|
72
87
|
},
|
|
73
|
-
{ immediate: true }
|
|
74
|
-
);
|
|
88
|
+
{ immediate: true });
|
|
75
89
|
</script>
|
|
76
90
|
|
|
77
91
|
<style scoped></style>
|