@webitel/ui-datalist 1.0.5 → 1.0.6
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 +4 -3
- package/src/filter-presets/components/_shared/preset-filters-preview.vue +2 -11
- package/src/filter-presets/components/apply-preset/apply-preset-action.vue +5 -0
- package/src/filter-presets/components/save-preset/save-preset-action.vue +31 -4
- package/src/filter-presets/components/save-preset/save-preset-popup.vue +5 -1
- package/src/filters/classes/FiltersManager.ts +8 -2
- package/src/filters/components/dynamic-filter-add-action.vue +2 -3
- package/src/filters/components/filter-options/_shared/lookup-filter-preview/lookup-filter-value-preview.vue +21 -0
- package/src/filters/components/filter-options/agent/agent-filter-value-preview.vue +4 -20
- package/src/filters/components/filter-options/agent/config.js +0 -1
- package/src/filters/components/filter-options/contact/contact-filter-value-preview.vue +4 -20
- package/src/filters/components/filter-options/created-at/created-at-filter-value-field.vue +97 -0
- package/src/filters/components/filter-options/created-at/created-at-filter-value-preview.vue +64 -0
- package/src/filters/components/filter-options/gateway/gateway-filter-value-preview.vue +6 -21
- package/src/filters/components/filter-options/grantee/grantee-filter-value-preview.vue +6 -21
- package/src/filters/components/filter-options/index.ts +45 -0
- package/src/filters/components/filter-options/queue/queue-filter-value-preview.vue +4 -20
- package/src/filters/components/filter-options/rated-by/rated-by-filter-value-preview.vue +6 -21
- package/src/filters/components/filter-options/service-case/config.js +1 -1
- package/src/filters/components/filter-options/team/team-filter-value-preview.vue +4 -20
- package/src/filters/components/filter-options/user/user-filter-value-preview.vue +6 -21
- package/src/filters/components/preview/dynamic-filter-preview-info.vue +1 -0
- package/src/filters/components/preview/dynamic-filter-preview.vue +82 -19
- package/src/filters/components/table-filters-panel.vue +25 -27
- package/src/filters/enums/FilterOption.ts +12 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webitel/ui-datalist",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Toolkit for building data lists in webitel ui system",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"lint:fix": "eslint --fix ./src && prettier --write --check ./src",
|
|
@@ -29,12 +29,13 @@
|
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"vue": "^3.5",
|
|
31
31
|
"axios": "^1",
|
|
32
|
-
"pinia": "^3.x"
|
|
32
|
+
"pinia": "^3.x",
|
|
33
|
+
"date-fns": "^4"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"@vuelidate/core": "^2.0.3",
|
|
36
37
|
"@vuelidate/validators": "^2.0.4",
|
|
37
|
-
"@webitel/ui-sdk": "^25.4.
|
|
38
|
+
"@webitel/ui-sdk": "^25.4.55"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"vue-tsc": "^2.2.8",
|
|
@@ -9,16 +9,8 @@
|
|
|
9
9
|
v-for="filter of props.filters"
|
|
10
10
|
:key="filter.name"
|
|
11
11
|
:filter="filter"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<template #info>
|
|
15
|
-
<component
|
|
16
|
-
:is="FilterOptionToPreviewComponentMap[filter.name]"
|
|
17
|
-
:value="filter.value"
|
|
18
|
-
>
|
|
19
|
-
</component>
|
|
20
|
-
</template>
|
|
21
|
-
</dynamic-filter-preview>
|
|
12
|
+
readonly
|
|
13
|
+
/>
|
|
22
14
|
</template>
|
|
23
15
|
</dynamic-filter-panel-wrapper>
|
|
24
16
|
</div>
|
|
@@ -30,7 +22,6 @@ import { useI18n } from 'vue-i18n';
|
|
|
30
22
|
|
|
31
23
|
import type { IFilter } from '../../../filters';
|
|
32
24
|
import DynamicFilterPanelWrapper from '../../../filters/components/dynamic-filter-panel-wrapper.vue';
|
|
33
|
-
import { FilterOptionToPreviewComponentMap } from '../../../filters/components/filter-options';
|
|
34
25
|
import DynamicFilterPreview from '../../../filters/components/preview/dynamic-filter-preview.vue';
|
|
35
26
|
|
|
36
27
|
type Props = {
|
|
@@ -91,6 +91,11 @@ const props = defineProps<{
|
|
|
91
91
|
*/
|
|
92
92
|
namespace: string;
|
|
93
93
|
usePresetsStore: Store;
|
|
94
|
+
/**
|
|
95
|
+
* @description
|
|
96
|
+
* Is needed for preset to exclude filter values, not related to filters panel
|
|
97
|
+
*/
|
|
98
|
+
filterOptions: FilterOption[];
|
|
94
99
|
}>();
|
|
95
100
|
|
|
96
101
|
const emit = defineEmits<{
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
!presetToOverwriteWith /* on 'overwrite preset' popup hide this popup, but don't reset it*/
|
|
15
15
|
"
|
|
16
16
|
:shown="true /* coz visibility is controlled by v-if*/"
|
|
17
|
-
:filters-manager="
|
|
17
|
+
:filters-manager="localFiltersManager"
|
|
18
18
|
:namespace="namespace"
|
|
19
19
|
@submit="handlePresetSubmit"
|
|
20
20
|
@close="showSaveForm = false"
|
|
@@ -32,11 +32,15 @@
|
|
|
32
32
|
<script lang="ts" setup>
|
|
33
33
|
import { WtIconAction } from '@webitel/ui-sdk/components';
|
|
34
34
|
import { IconAction } from '@webitel/ui-sdk/enums';
|
|
35
|
-
import { computed, inject, type Ref, ref } from 'vue';
|
|
35
|
+
import { computed, inject, reactive, type Ref, ref, watch } from 'vue';
|
|
36
36
|
import { useI18n } from 'vue-i18n';
|
|
37
37
|
import { EnginePresetQuery } from 'webitel-sdk';
|
|
38
38
|
|
|
39
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
createFiltersManager,
|
|
41
|
+
FilterOption,
|
|
42
|
+
IFiltersManager,
|
|
43
|
+
} from '../../../filters';
|
|
40
44
|
import {
|
|
41
45
|
addPreset,
|
|
42
46
|
getPresetList,
|
|
@@ -47,21 +51,44 @@ import SavePresetPopup, { SubmitConfig } from './save-preset-popup.vue';
|
|
|
47
51
|
|
|
48
52
|
const props = defineProps<{
|
|
49
53
|
/**
|
|
54
|
+
* @description
|
|
50
55
|
* presets "section" namespace
|
|
51
56
|
*/
|
|
52
57
|
namespace: string;
|
|
58
|
+
/**
|
|
59
|
+
* @author @dlohvinov
|
|
60
|
+
* serves as a source for local filters manager
|
|
61
|
+
*/
|
|
53
62
|
filtersManager: IFiltersManager;
|
|
63
|
+
/**
|
|
64
|
+
* @description
|
|
65
|
+
* Is needed for preset to exclude filter values, not related to filters panel
|
|
66
|
+
*/
|
|
67
|
+
filterOptions: FilterOption[];
|
|
54
68
|
}>();
|
|
55
69
|
|
|
56
70
|
const eventBus = inject('$eventBus');
|
|
57
71
|
|
|
72
|
+
const localFiltersManager = reactive(createFiltersManager());
|
|
73
|
+
|
|
74
|
+
watch(
|
|
75
|
+
props.filtersManager,
|
|
76
|
+
() => {
|
|
77
|
+
localFiltersManager.reset();
|
|
78
|
+
localFiltersManager.fromString(
|
|
79
|
+
props.filtersManager.toString({ include: props.filterOptions }),
|
|
80
|
+
);
|
|
81
|
+
},
|
|
82
|
+
{ immediate: true },
|
|
83
|
+
);
|
|
84
|
+
|
|
58
85
|
const { t } = useI18n();
|
|
59
86
|
|
|
60
87
|
/**
|
|
61
88
|
* disable "save" btn if there's nothing to save
|
|
62
89
|
* */
|
|
63
90
|
const disableAction = computed(() => {
|
|
64
|
-
return !
|
|
91
|
+
return !localFiltersManager.getAllKeys().length;
|
|
65
92
|
});
|
|
66
93
|
|
|
67
94
|
/**
|
|
@@ -53,7 +53,7 @@ import { computed, reactive, ref } from 'vue';
|
|
|
53
53
|
import { useI18n } from 'vue-i18n';
|
|
54
54
|
import { EnginePresetQuery } from 'webitel-sdk';
|
|
55
55
|
|
|
56
|
-
import type { IFiltersManager } from '../../../
|
|
56
|
+
import type { IFiltersManager } from '../../../filters';
|
|
57
57
|
import PresetDescriptionField from '../_shared/input-fields/preset-description-field.vue';
|
|
58
58
|
import PresetNameField from '../_shared/input-fields/preset-name-field.vue';
|
|
59
59
|
import PresetFiltersPreview from '../_shared/preset-filters-preview.vue';
|
|
@@ -65,6 +65,10 @@ export type SubmitConfig = {
|
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
const props = defineProps<{
|
|
68
|
+
/**
|
|
69
|
+
* @description
|
|
70
|
+
* is needed here for `.toString()`
|
|
71
|
+
*/
|
|
68
72
|
filtersManager: IFiltersManager;
|
|
69
73
|
}>();
|
|
70
74
|
|
|
@@ -70,8 +70,14 @@ class FiltersManager implements IFiltersManager {
|
|
|
70
70
|
return filters;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
toString(
|
|
74
|
-
|
|
73
|
+
toString({
|
|
74
|
+
include,
|
|
75
|
+
exclude,
|
|
76
|
+
}: {
|
|
77
|
+
include?: FilterName[];
|
|
78
|
+
exclude?: FilterName[];
|
|
79
|
+
} = {}): string {
|
|
80
|
+
const filtersData = this.getFiltersList({ include, exclude }).reduce(
|
|
75
81
|
(acc, { name, label, value }) => {
|
|
76
82
|
if (isEmpty(value) && value == null) return acc;
|
|
77
83
|
|
|
@@ -21,8 +21,7 @@
|
|
|
21
21
|
:options="props.filterOptions"
|
|
22
22
|
@cancel="() => tooltipSlotScope.hide()"
|
|
23
23
|
@submit="
|
|
24
|
-
(payload) =>
|
|
25
|
-
submitFilterChange(payload, { hide: tooltipSlotScope.hide })
|
|
24
|
+
(payload) => submit(payload, { hide: tooltipSlotScope.hide })
|
|
26
25
|
"
|
|
27
26
|
/>
|
|
28
27
|
</slot>
|
|
@@ -54,7 +53,7 @@ const emit = defineEmits<{
|
|
|
54
53
|
'add:filter': [FilterInitParams];
|
|
55
54
|
}>();
|
|
56
55
|
|
|
57
|
-
const
|
|
56
|
+
const submit = (payload: FilterInitParams, { hide }) => {
|
|
58
57
|
emit('add:filter', payload);
|
|
59
58
|
hide();
|
|
60
59
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ul v-if="value">
|
|
3
|
+
<li
|
|
4
|
+
v-for="({ name, id }, index) of value"
|
|
5
|
+
:key="id || index"
|
|
6
|
+
>
|
|
7
|
+
{{ name }}
|
|
8
|
+
</li>
|
|
9
|
+
</ul>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts" setup>
|
|
13
|
+
defineProps<{
|
|
14
|
+
/**
|
|
15
|
+
* would be great to use a type for this
|
|
16
|
+
* */
|
|
17
|
+
value: Record<string, unknown>[];
|
|
18
|
+
}>();
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<style scoped></style>
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<li
|
|
4
|
-
v-for="({ name }, index) of localValue"
|
|
5
|
-
:key="index"
|
|
6
|
-
>
|
|
7
|
-
{{ name }}
|
|
8
|
-
</li>
|
|
9
|
-
</ul>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
10
3
|
</template>
|
|
11
4
|
|
|
12
5
|
<script lang="ts" setup>
|
|
13
|
-
import {
|
|
6
|
+
import type { EngineAgent } from 'webitel-sdk';
|
|
14
7
|
|
|
15
|
-
import
|
|
8
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
16
9
|
|
|
17
10
|
const props = defineProps<{
|
|
18
|
-
value:
|
|
11
|
+
value: EngineAgent[];
|
|
19
12
|
}>();
|
|
20
|
-
|
|
21
|
-
const localValue = ref([]);
|
|
22
|
-
|
|
23
|
-
const getLocalValue = async () => {
|
|
24
|
-
const { items } = await searchMethod({ id: props.value });
|
|
25
|
-
localValue.value = items;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
getLocalValue();
|
|
29
13
|
</script>
|
|
30
14
|
|
|
31
15
|
<style scoped></style>
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<li
|
|
4
|
-
v-for="({ name }, index) of localValue"
|
|
5
|
-
:key="index"
|
|
6
|
-
>
|
|
7
|
-
{{ name }}
|
|
8
|
-
</li>
|
|
9
|
-
</ul>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
10
3
|
</template>
|
|
11
4
|
|
|
12
5
|
<script lang="ts" setup>
|
|
13
|
-
import {
|
|
6
|
+
import type { WebitelContactsContact } from 'webitel-sdk';
|
|
14
7
|
|
|
15
|
-
import
|
|
8
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
16
9
|
|
|
17
10
|
const props = defineProps<{
|
|
18
|
-
value:
|
|
11
|
+
value: WebitelContactsContact[];
|
|
19
12
|
}>();
|
|
20
|
-
|
|
21
|
-
const localValue = ref([]);
|
|
22
|
-
|
|
23
|
-
const getLocalValue = async () => {
|
|
24
|
-
const { items } = await searchMethod({ id: props.value });
|
|
25
|
-
localValue.value = items;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
getLocalValue();
|
|
29
13
|
</script>
|
|
30
14
|
|
|
31
15
|
<style scoped></style>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="created-at-filter-value-field">
|
|
3
|
+
<wt-radio
|
|
4
|
+
v-for="value of radioOpts"
|
|
5
|
+
:key="value"
|
|
6
|
+
v-model="selectedRadioValue"
|
|
7
|
+
:label="t(`webitelUI.filters.datetime.${value}`)"
|
|
8
|
+
:value="value"
|
|
9
|
+
@input="handleRadioChange"
|
|
10
|
+
/>
|
|
11
|
+
<wt-datepicker
|
|
12
|
+
v-if="showDatepickers"
|
|
13
|
+
:value="model.from"
|
|
14
|
+
:label="t('reusable.from')"
|
|
15
|
+
mode="datetime"
|
|
16
|
+
@input="changeAbsoluteValue($event, 'from')"
|
|
17
|
+
/>
|
|
18
|
+
<wt-datepicker
|
|
19
|
+
v-if="showDatepickers"
|
|
20
|
+
:value="model.to"
|
|
21
|
+
:label="t('reusable.to')"
|
|
22
|
+
mode="datetime"
|
|
23
|
+
@input="changeAbsoluteValue($event, 'to')"
|
|
24
|
+
/>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script lang="ts" setup>
|
|
29
|
+
import { WtRadio } from '@webitel/ui-sdk/components';
|
|
30
|
+
import { RelativeDatetimeValue } from '@webitel/ui-sdk/enums';
|
|
31
|
+
import { endOfToday, startOfToday } from 'date-fns';
|
|
32
|
+
import { computed, ref } from 'vue';
|
|
33
|
+
import { useI18n } from 'vue-i18n';
|
|
34
|
+
|
|
35
|
+
const model = defineModel<
|
|
36
|
+
RelativeDatetimeValue | { from: number; to: number }
|
|
37
|
+
>();
|
|
38
|
+
|
|
39
|
+
const { t } = useI18n();
|
|
40
|
+
|
|
41
|
+
const radioOpts = [
|
|
42
|
+
RelativeDatetimeValue.Today,
|
|
43
|
+
RelativeDatetimeValue.ThisWeek,
|
|
44
|
+
RelativeDatetimeValue.ThisMonth,
|
|
45
|
+
RelativeDatetimeValue.Custom,
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const selectedRadioValue = ref();
|
|
49
|
+
|
|
50
|
+
const initialize = () => {
|
|
51
|
+
if (!model.value) {
|
|
52
|
+
/* initialize */
|
|
53
|
+
selectedRadioValue.value = radioOpts[0];
|
|
54
|
+
model.value = selectedRadioValue.value;
|
|
55
|
+
} else if (typeof model.value === 'string') {
|
|
56
|
+
/* RelativeDatetimeValue */
|
|
57
|
+
selectedRadioValue.value = model.value;
|
|
58
|
+
} else {
|
|
59
|
+
/* { from, to } */
|
|
60
|
+
selectedRadioValue.value = RelativeDatetimeValue.Custom;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
initialize();
|
|
65
|
+
|
|
66
|
+
const showDatepickers = computed(() => {
|
|
67
|
+
return selectedRadioValue.value === RelativeDatetimeValue.Custom;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const handleRadioChange = (value: RelativeDatetimeValue) => {
|
|
71
|
+
if (value === RelativeDatetimeValue.Custom) {
|
|
72
|
+
model.value = {
|
|
73
|
+
from: startOfToday().getTime(),
|
|
74
|
+
to: endOfToday().getTime(),
|
|
75
|
+
};
|
|
76
|
+
} else {
|
|
77
|
+
model.value = value;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const changeAbsoluteValue = (value: number, prop: 'from' | 'to') => {
|
|
82
|
+
const newModelValue = {
|
|
83
|
+
...(model.value as { from: number; to: number }),
|
|
84
|
+
[prop]: value,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
model.value = newModelValue;
|
|
88
|
+
};
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<style scoped>
|
|
92
|
+
.created-at-filter-value-field {
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
gap: var(--spacing-xs);
|
|
96
|
+
}
|
|
97
|
+
</style>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="created-at-filter-value-preview">
|
|
3
|
+
<p v-if="isRelativeValue">
|
|
4
|
+
{{ t(`webitelUI.filters.datetime.${props.value}`) }}
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<template v-else>
|
|
8
|
+
<div>
|
|
9
|
+
<p class="created-at-filter-value-preview__title">
|
|
10
|
+
{{ t('reusable.from') }}
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<span>{{ from }}</span>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div>
|
|
17
|
+
<p class="created-at-filter-value-preview__title">
|
|
18
|
+
{{ t('reusable.to') }}
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
<span>{{ to }}</span>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script lang="ts" setup>
|
|
28
|
+
import { RelativeDatetimeValue } from '@webitel/ui-sdk/enums';
|
|
29
|
+
import { isRelativeDatetimeValue } from '@webitel/ui-sdk/scripts';
|
|
30
|
+
import { computed } from 'vue';
|
|
31
|
+
import { useI18n } from 'vue-i18n';
|
|
32
|
+
|
|
33
|
+
const props = defineProps<{
|
|
34
|
+
value: { from: number; to: number } | RelativeDatetimeValue;
|
|
35
|
+
}>();
|
|
36
|
+
|
|
37
|
+
const { t } = useI18n();
|
|
38
|
+
|
|
39
|
+
const isRelativeValue = computed(() => {
|
|
40
|
+
return isRelativeDatetimeValue(props.value);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const from = computed(() => {
|
|
44
|
+
return isRelativeDatetimeValue.value
|
|
45
|
+
? false
|
|
46
|
+
: new Date(props.value.from).toLocaleString();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const to = computed(() => {
|
|
50
|
+
return isRelativeDatetimeValue.value
|
|
51
|
+
? false
|
|
52
|
+
: new Date(props.value.to).toLocaleString();
|
|
53
|
+
});
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<style lang="scss" scoped>
|
|
57
|
+
@use '@webitel/styleguide/typography' as *;
|
|
58
|
+
|
|
59
|
+
.duration-filter-value-preview {
|
|
60
|
+
&__title {
|
|
61
|
+
@extend %typo-subtitle-1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
</style>
|
|
@@ -1,31 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<li
|
|
4
|
-
v-for="({ name }, index) of localValue"
|
|
5
|
-
:key="index"
|
|
6
|
-
>
|
|
7
|
-
{{ name }}
|
|
8
|
-
</li>
|
|
9
|
-
</ul>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
10
3
|
</template>
|
|
11
4
|
|
|
12
5
|
<script lang="ts" setup>
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
import { searchMethod } from './config.js';
|
|
6
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
16
7
|
|
|
17
8
|
const props = defineProps<{
|
|
18
|
-
|
|
9
|
+
/**
|
|
10
|
+
* would be great to use generated type for this
|
|
11
|
+
* */
|
|
12
|
+
value: Record<string, unknown>[];
|
|
19
13
|
}>();
|
|
20
|
-
|
|
21
|
-
const localValue = ref([]);
|
|
22
|
-
|
|
23
|
-
const getLocalValue = async () => {
|
|
24
|
-
const { items } = await searchMethod({ id: props.value });
|
|
25
|
-
localValue.value = items;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
getLocalValue();
|
|
29
14
|
</script>
|
|
30
15
|
|
|
31
16
|
<style scoped></style>
|
|
@@ -1,31 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<li
|
|
4
|
-
v-for="({ name }, index) of localValue"
|
|
5
|
-
:key="index"
|
|
6
|
-
>
|
|
7
|
-
{{ name }}
|
|
8
|
-
</li>
|
|
9
|
-
</ul>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
10
3
|
</template>
|
|
11
4
|
|
|
12
5
|
<script lang="ts" setup>
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
import { searchMethod } from './config.js';
|
|
6
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
16
7
|
|
|
17
8
|
const props = defineProps<{
|
|
18
|
-
|
|
9
|
+
/**
|
|
10
|
+
* would be great to use generated type for this
|
|
11
|
+
* */
|
|
12
|
+
value: Record<string, unknown>[];
|
|
19
13
|
}>();
|
|
20
|
-
|
|
21
|
-
const localValue = ref([]);
|
|
22
|
-
|
|
23
|
-
const getLocalValue = async () => {
|
|
24
|
-
const { items } = await searchMethod({ ids: props.value });
|
|
25
|
-
localValue.value = items;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
getLocalValue();
|
|
29
14
|
</script>
|
|
30
15
|
|
|
31
16
|
<style scoped></style>
|
|
@@ -7,28 +7,37 @@ import ActualResolutionTimeFilter from './actual-resolution-time/actual-resoluti
|
|
|
7
7
|
import ActualResolutionTimeFilterPreview from './actual-resolution-time/actual-resolution-time-filter-value-preview.vue';
|
|
8
8
|
import AgentFilter from './agent/agent-filter-value-field.vue';
|
|
9
9
|
import AgentFilterPreview from './agent/agent-filter-value-preview.vue';
|
|
10
|
+
import { searchMethod as agentSearchMethod } from './agent/config';
|
|
10
11
|
import AmdResultFilter from './amd-result/amd-result-filter-value-field.vue';
|
|
11
12
|
import AmdResultFilterPreview from './amd-result/amd-result-filter-value-preview.vue';
|
|
12
13
|
import AssigneeFilter from './assignee/assignee-filter-value-field.vue';
|
|
13
14
|
import AssigneeFilterPreview from './assignee/assignee-filter-value-preview.vue';
|
|
15
|
+
import { searchMethod as assigneeSearchMethod } from './assignee/config';
|
|
14
16
|
import AuthorFilter from './author/author-filter-value-field.vue';
|
|
15
17
|
import AuthorFilterPreview from './author/author-filter-value-preview.vue';
|
|
18
|
+
import { searchMethod as authorSearchMethod } from './author/config';
|
|
16
19
|
import CauseFilter from './cause/cause-filter-value-field.vue';
|
|
17
20
|
import CauseFilterPreview from './cause/cause-filter-value-preview.vue';
|
|
18
21
|
import CloseReasonGroupsCaseFilter from './close-reason-groups-case/close-reason-groups-case-filter-value-field.vue';
|
|
19
22
|
import CloseReasonGroupsCaseFilterPreview from './close-reason-groups-case/close-reason-groups-case-filter-value-preview.vue';
|
|
23
|
+
import { searchMethod as contactSearchMethod } from './contact/config';
|
|
20
24
|
import ContactFilter from './contact/contact-filter-value-field.vue';
|
|
21
25
|
import ContactFilterPreview from './contact/contact-filter-value-preview.vue';
|
|
26
|
+
import { searchMethod as contactGroupSearchMethod } from './contact-group/config';
|
|
22
27
|
import ContactGroupFilter from './contact-group/contact-group-filter-value-field.vue';
|
|
23
28
|
import ContactGroupFilterPreview from './contact-group/contact-group-filter-value-preview.vue';
|
|
29
|
+
import CreatedAtFilterValueField from './created-at/created-at-filter-value-field.vue';
|
|
30
|
+
import CreatedAtFilterPreview from './created-at/created-at-filter-value-preview.vue';
|
|
24
31
|
import CreatedAtFromFilter from './created-at-from/created-at-from-filter-value-field.vue';
|
|
25
32
|
import CreatedAtFromFilterPreview from './created-at-from/created-at-from-filter-value-preview.vue';
|
|
26
33
|
import CreatedAtToFilter from './created-at-to/created-at-to-filter-value-field.vue';
|
|
27
34
|
import CreatedAtToFilterPreview from './created-at-to/created-at-to-filter-value-preview.vue';
|
|
28
35
|
import DirectionFilter from './direction/direction-filter-value-field.vue';
|
|
29
36
|
import DirectionFilterPreview from './direction/direction-filter-value-preview.vue';
|
|
37
|
+
import { searchMethod as gatewaySearchMethod } from './gateway/config';
|
|
30
38
|
import GatewayFilter from './gateway/gateway-filter-value-field.vue';
|
|
31
39
|
import GatewayFilterPreview from './gateway/gateway-filter-value-preview.vue';
|
|
40
|
+
import { searchMethod as granteeSearchMethod } from './grantee/config';
|
|
32
41
|
import GranteeFilter from './grantee/grantee-filter-value-field.vue';
|
|
33
42
|
import GranteeFilterPreview from './grantee/grantee-filter-value-preview.vue';
|
|
34
43
|
import HasAttachmentFilter from './has-attachment/has-attachment-filter-value-field.vue';
|
|
@@ -39,30 +48,38 @@ import HasRatingFilterValueField from './has-rating/has-rating-filter-value-fiel
|
|
|
39
48
|
import HasRatingFilterValuePreview from './has-rating/has-rating-filter-value-preview.vue';
|
|
40
49
|
import HasTranscriptionFilter from './has-transcription/has-transcription-filter-value-field.vue';
|
|
41
50
|
import HasTranscriptionFilterPreview from './has-transcription/has-transcription-filter-value-preview.vue';
|
|
51
|
+
import { searchMethod as impactedSearchMethod } from './impacted/config';
|
|
42
52
|
import ImpactedFilter from './impacted/impacted-filter-value-field.vue';
|
|
43
53
|
import ImpactedFilterPreview from './impacted/impacted-filter-value-preview.vue';
|
|
54
|
+
import { searchMethod as priorityCaseSearchMethod } from './priority-case/config';
|
|
44
55
|
import CasePriorityFilter from './priority-case/priority-case-filter-value-field.vue';
|
|
45
56
|
import CasePriorityFilterPreview from './priority-case/priority-case-filter-value-preview.vue';
|
|
57
|
+
import { searchMethod as queueSearchMethod } from './queue/config';
|
|
46
58
|
import QueueFilter from './queue/queue-filter-value-field.vue';
|
|
47
59
|
import QueueFilterPreview from './queue/queue-filter-value-preview.vue';
|
|
60
|
+
import { searchMethod as ratedBySearchMethod } from './rated-by/config';
|
|
48
61
|
import RatedByFilter from './rated-by/rated-by-filter-value-field.vue';
|
|
49
62
|
import RatedByFilterPreview from './rated-by/rated-by-filter-value-preview.vue';
|
|
50
63
|
import RatingFromToFilter from './rating/rating-from-to-filter-value-field.vue';
|
|
51
64
|
import RatingFromToFilterPreview from './rating/rating-from-to-filter-value-preview.vue';
|
|
52
65
|
import ReactionTimeFilter from './reaction-time/reaction-time-filter-value-field.vue';
|
|
53
66
|
import ReactionTimeFilterPreview from './reaction-time/reaction-time-filter-value-preview.vue';
|
|
67
|
+
import { searchMethod as reporterSearchMethod } from './reporter/config';
|
|
54
68
|
import ReporterFilter from './reporter/reporter-filter-value-field.vue';
|
|
55
69
|
import ReporterFilterPreview from './reporter/reporter-filter-value-preview.vue';
|
|
56
70
|
import ResolutionTimeFilter from './resolution-time/resolution-time-filter-value-field.vue';
|
|
57
71
|
import ResolutionTimeFilterPreview from './resolution-time/resolution-time-filter-value-preview.vue';
|
|
58
72
|
import ScoreFilter from './score/score-from-to-filter-value-field.vue';
|
|
59
73
|
import ScoreFilterPreview from './score/score-from-to-filter-value-preview.vue';
|
|
74
|
+
import { searchMethod as serviceCaseSearchMethod } from './service-case/config';
|
|
60
75
|
import CaseServiceFilter from './service-case/service-case-filter-value-field.vue';
|
|
61
76
|
import CaseServiceFilterPreview from './service-case/service-case-filter-value-preview.vue';
|
|
77
|
+
import { searchMethod as slaSearchMethod } from './sla/config';
|
|
62
78
|
import SlaFilter from './sla/sla-filter-value-field.vue';
|
|
63
79
|
import SlaFilterPreview from './sla/sla-filter-value-preview.vue';
|
|
64
80
|
import SlaConditionFilter from './sla-condition/sla-condition-filter-value-field.vue';
|
|
65
81
|
import SlaConditionFilterPreview from './sla-condition/sla-condition-filter-value-preview.vue';
|
|
82
|
+
import { searchMethod as sourceCaseSearchMethod } from './source-case/config';
|
|
66
83
|
import CaseSourceFilter from './source-case/source-case-filter-value-field.vue';
|
|
67
84
|
import CaseSourceFilterPreview from './source-case/source-case-filter-value-preview.vue';
|
|
68
85
|
import CaseStatusFilter from './status-case/status-case-filter-value-field.vue';
|
|
@@ -71,10 +88,12 @@ import TagFilter from './tag/tag-filter-value-field.vue';
|
|
|
71
88
|
import TagFilterPreview from './tag/tag-filter-value-preview.vue';
|
|
72
89
|
import TalkDurationFilter from './talk-duration/talk-duration-filter-value-field.vue';
|
|
73
90
|
import TalkDurationFilterPreview from './talk-duration/talk-duration-filter-value-preview.vue';
|
|
91
|
+
import { searchMethod as teamSearchMethod } from './team/config';
|
|
74
92
|
import TeamFilter from './team/team-filter-value-field.vue';
|
|
75
93
|
import TeamFilterPreview from './team/team-filter-value-preview.vue';
|
|
76
94
|
import TotalDurationFilter from './total-duration/total-duration-filter-value-field.vue';
|
|
77
95
|
import TotalDurationFilterPreview from './total-duration/total-duration-filter-value-preview.vue';
|
|
96
|
+
import { searchMethod as userSearchMethod } from './user/config';
|
|
78
97
|
import UserFilter from './user/user-filter-value-field.vue';
|
|
79
98
|
import UserFilterPreview from './user/user-filter-value-preview.vue';
|
|
80
99
|
import VariableFilter from './variable/variable-filter-value-field.vue';
|
|
@@ -109,6 +128,7 @@ export {
|
|
|
109
128
|
ContactFilterPreview,
|
|
110
129
|
ContactGroupFilter,
|
|
111
130
|
ContactGroupFilterPreview,
|
|
131
|
+
CreatedAtFilterValueField,
|
|
112
132
|
CreatedAtFromFilter,
|
|
113
133
|
CreatedAtFromFilterPreview,
|
|
114
134
|
CreatedAtToFilter,
|
|
@@ -182,6 +202,7 @@ export const FilterOptionToValueComponentMap: Record<FilterOption, Component> =
|
|
|
182
202
|
[FilterOption.HasTranscription]: HasTranscriptionFilter,
|
|
183
203
|
[FilterOption.User]: UserFilter,
|
|
184
204
|
[FilterOption.Variable]: VariableFilter,
|
|
205
|
+
[FilterOption.CreatedAt]: CreatedAtFilterValueField,
|
|
185
206
|
[FilterOption.CreatedAtFrom]: CreatedAtFromFilter,
|
|
186
207
|
[FilterOption.CreatedAtTo]: CreatedAtToFilter,
|
|
187
208
|
[FilterOption.Status]: CaseStatusFilter,
|
|
@@ -208,6 +229,7 @@ export const FilterOptionToPreviewComponentMap: Record<
|
|
|
208
229
|
FilterOption,
|
|
209
230
|
Component
|
|
210
231
|
> = {
|
|
232
|
+
[FilterOption.CreatedAt]: CreatedAtFilterPreview,
|
|
211
233
|
[FilterOption.Agent]: AgentFilterPreview,
|
|
212
234
|
[FilterOption.AmdResult]: AmdResultFilterPreview,
|
|
213
235
|
[FilterOption.Contact]: ContactFilterPreview,
|
|
@@ -248,3 +270,26 @@ export const FilterOptionToPreviewComponentMap: Record<
|
|
|
248
270
|
[FilterOption.ActualResolutionTime]: ActualResolutionTimeFilterPreview,
|
|
249
271
|
[FilterOption.HasAttachment]: HasAttachmentFilterPreview,
|
|
250
272
|
};
|
|
273
|
+
|
|
274
|
+
export const FilterOptionToApiSearchMethodMap: Record<
|
|
275
|
+
FilterOption,
|
|
276
|
+
(unknown) => { items }
|
|
277
|
+
> = {
|
|
278
|
+
[FilterOption.Agent]: agentSearchMethod,
|
|
279
|
+
[FilterOption.Gateway]: gatewaySearchMethod,
|
|
280
|
+
[FilterOption.Grantee]: granteeSearchMethod,
|
|
281
|
+
[FilterOption.Queue]: queueSearchMethod,
|
|
282
|
+
[FilterOption.RatedBy]: ratedBySearchMethod,
|
|
283
|
+
[FilterOption.Reporter]: reporterSearchMethod,
|
|
284
|
+
[FilterOption.Sla]: slaSearchMethod,
|
|
285
|
+
[FilterOption.Service]: serviceCaseSearchMethod,
|
|
286
|
+
[FilterOption.Source]: sourceCaseSearchMethod,
|
|
287
|
+
[FilterOption.User]: userSearchMethod,
|
|
288
|
+
[FilterOption.ContactGroup]: contactGroupSearchMethod,
|
|
289
|
+
[FilterOption.Assignee]: assigneeSearchMethod,
|
|
290
|
+
[FilterOption.Author]: authorSearchMethod,
|
|
291
|
+
[FilterOption.Priority]: priorityCaseSearchMethod,
|
|
292
|
+
[FilterOption.Impacted]: impactedSearchMethod,
|
|
293
|
+
[FilterOption.Contact]: contactSearchMethod,
|
|
294
|
+
[FilterOption.Team]: teamSearchMethod,
|
|
295
|
+
};
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<li
|
|
4
|
-
v-for="({ name }, index) of localValue"
|
|
5
|
-
:key="index"
|
|
6
|
-
>
|
|
7
|
-
{{ name }}
|
|
8
|
-
</li>
|
|
9
|
-
</ul>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
10
3
|
</template>
|
|
11
4
|
|
|
12
5
|
<script lang="ts" setup>
|
|
13
|
-
import {
|
|
6
|
+
import type { EngineQueue } from 'webitel-sdk';
|
|
14
7
|
|
|
15
|
-
import
|
|
8
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
16
9
|
|
|
17
10
|
const props = defineProps<{
|
|
18
|
-
value:
|
|
11
|
+
value: EngineQueue[];
|
|
19
12
|
}>();
|
|
20
|
-
|
|
21
|
-
const localValue = ref([]);
|
|
22
|
-
|
|
23
|
-
const getLocalValue = async () => {
|
|
24
|
-
const { items } = await searchMethod({ id: props.value });
|
|
25
|
-
localValue.value = items;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
getLocalValue();
|
|
29
13
|
</script>
|
|
30
14
|
|
|
31
15
|
<style scoped></style>
|
|
@@ -1,31 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<li
|
|
4
|
-
v-for="({ name }, index) of localValue"
|
|
5
|
-
:key="index"
|
|
6
|
-
>
|
|
7
|
-
{{ name }}
|
|
8
|
-
</li>
|
|
9
|
-
</ul>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
10
3
|
</template>
|
|
11
4
|
|
|
12
5
|
<script lang="ts" setup>
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
import { searchMethod } from './config.js';
|
|
6
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
16
7
|
|
|
17
8
|
const props = defineProps<{
|
|
18
|
-
|
|
9
|
+
/**
|
|
10
|
+
* would be great to use generated type for this
|
|
11
|
+
* */
|
|
12
|
+
value: Record<string, unknown>[];
|
|
19
13
|
}>();
|
|
20
|
-
|
|
21
|
-
const localValue = ref([]);
|
|
22
|
-
|
|
23
|
-
const getLocalValue = async () => {
|
|
24
|
-
const { items } = await searchMethod({ id: props.value });
|
|
25
|
-
localValue.value = items;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
getLocalValue();
|
|
29
14
|
</script>
|
|
30
15
|
|
|
31
16
|
<style scoped></style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import ServiceCatalogsAPI from '@webitel/ui-sdk/api/clients/caseServiceCatalogs/
|
|
1
|
+
import ServiceCatalogsAPI from '@webitel/ui-sdk/api/clients/caseServiceCatalogs/serviceCatalogs';
|
|
2
2
|
import ServicesAPI from '@webitel/ui-sdk/api/clients/caseServices/services';
|
|
3
3
|
|
|
4
4
|
export const searchMethod = ServiceCatalogsAPI.getList;
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<li
|
|
4
|
-
v-for="({ name }, index) of localValue"
|
|
5
|
-
:key="index"
|
|
6
|
-
>
|
|
7
|
-
{{ name }}
|
|
8
|
-
</li>
|
|
9
|
-
</ul>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
10
3
|
</template>
|
|
11
4
|
|
|
12
5
|
<script lang="ts" setup>
|
|
13
|
-
import {
|
|
6
|
+
import type { EngineAgentTeam } from 'webitel-sdk';
|
|
14
7
|
|
|
15
|
-
import
|
|
8
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
16
9
|
|
|
17
10
|
const props = defineProps<{
|
|
18
|
-
value:
|
|
11
|
+
value: EngineAgentTeam[];
|
|
19
12
|
}>();
|
|
20
|
-
|
|
21
|
-
const localValue = ref([]);
|
|
22
|
-
|
|
23
|
-
const getLocalValue = async () => {
|
|
24
|
-
const { items } = await searchMethod({ id: props.value });
|
|
25
|
-
localValue.value = items;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
getLocalValue();
|
|
29
13
|
</script>
|
|
30
14
|
|
|
31
15
|
<style scoped></style>
|
|
@@ -1,31 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<li
|
|
4
|
-
v-for="({ name }, index) of localValue"
|
|
5
|
-
:key="index"
|
|
6
|
-
>
|
|
7
|
-
{{ name }}
|
|
8
|
-
</li>
|
|
9
|
-
</ul>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
10
3
|
</template>
|
|
11
4
|
|
|
12
5
|
<script lang="ts" setup>
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
import { searchMethod } from './config.js';
|
|
6
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
16
7
|
|
|
17
8
|
const props = defineProps<{
|
|
18
|
-
|
|
9
|
+
/**
|
|
10
|
+
* would be great to use generated type for this
|
|
11
|
+
* */
|
|
12
|
+
value: Record<string, unknown>[];
|
|
19
13
|
}>();
|
|
20
|
-
|
|
21
|
-
const localValue = ref([]);
|
|
22
|
-
|
|
23
|
-
const getLocalValue = async () => {
|
|
24
|
-
const { items } = await searchMethod({ id: props.value });
|
|
25
|
-
localValue.value = items;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
getLocalValue();
|
|
29
14
|
</script>
|
|
30
15
|
|
|
31
16
|
<style scoped></style>
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<dynamic-filter-config-view :disabled="
|
|
2
|
+
<dynamic-filter-config-view :disabled="readonly">
|
|
3
3
|
<template #activator="{ visible: configFormVisible }">
|
|
4
|
-
<wt-tooltip
|
|
4
|
+
<wt-tooltip
|
|
5
|
+
:disabled="configFormVisible"
|
|
6
|
+
@update:visible="!localValue && fillLocalValue()"
|
|
7
|
+
>
|
|
5
8
|
<template #activator>
|
|
6
9
|
<wt-chip color="primary">
|
|
7
10
|
{{ filter.label || t(`webitelUI.filters.${filter.name}`) }}
|
|
8
11
|
<wt-icon-btn
|
|
9
|
-
v-if="!
|
|
12
|
+
v-if="!filterConfig.notDeletable && !readonly"
|
|
10
13
|
icon="close--filled"
|
|
11
14
|
size="sm"
|
|
12
15
|
color="on-primary"
|
|
@@ -23,9 +26,14 @@
|
|
|
23
26
|
|
|
24
27
|
<template #default>
|
|
25
28
|
<slot name="info">
|
|
29
|
+
<wt-loader
|
|
30
|
+
v-if="!localValue"
|
|
31
|
+
size="sm"
|
|
32
|
+
/>
|
|
26
33
|
<component
|
|
27
34
|
:is="FilterOptionToPreviewComponentMap[filter.name]"
|
|
28
|
-
|
|
35
|
+
v-else
|
|
36
|
+
:value="localValue"
|
|
29
37
|
/>
|
|
30
38
|
</slot>
|
|
31
39
|
</template>
|
|
@@ -34,15 +42,18 @@
|
|
|
34
42
|
</wt-tooltip>
|
|
35
43
|
</template>
|
|
36
44
|
|
|
37
|
-
<template #content="
|
|
45
|
+
<template #content="{ tooltipSlotScope }">
|
|
38
46
|
<slot
|
|
39
47
|
name="form"
|
|
40
|
-
v-bind="
|
|
48
|
+
v-bind="{ tooltipSlotScope }"
|
|
41
49
|
>
|
|
42
50
|
<dynamic-filter-config-form
|
|
43
|
-
:filter="filter"
|
|
44
|
-
|
|
45
|
-
@
|
|
51
|
+
:filter="props.filter"
|
|
52
|
+
:options="filterOptions"
|
|
53
|
+
@cancel="() => tooltipSlotScope.hide()"
|
|
54
|
+
@submit="
|
|
55
|
+
(payload) => submit(payload, { hide: tooltipSlotScope.hide })
|
|
56
|
+
"
|
|
46
57
|
/>
|
|
47
58
|
</slot>
|
|
48
59
|
</template>
|
|
@@ -50,20 +61,34 @@
|
|
|
50
61
|
</template>
|
|
51
62
|
|
|
52
63
|
<script lang="ts" setup>
|
|
53
|
-
import {
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
import {
|
|
65
|
+
WtChip,
|
|
66
|
+
WtIconBtn,
|
|
67
|
+
WtLoader,
|
|
68
|
+
WtTooltip,
|
|
69
|
+
} from '@webitel/ui-sdk/components';
|
|
70
|
+
import { computed, ref } from 'vue';
|
|
56
71
|
import { useI18n } from 'vue-i18n';
|
|
57
72
|
|
|
58
|
-
import type {
|
|
73
|
+
import type { FilterOption } from '../../enums/FilterOption';
|
|
74
|
+
import type { FilterData, IFilter } from '../../types/Filter';
|
|
59
75
|
import DynamicFilterConfigForm from '../config/dynamic-filter-config-form.vue';
|
|
60
76
|
import DynamicFilterConfigView from '../config/dynamic-filter-config-view.vue';
|
|
61
|
-
import {
|
|
77
|
+
import {
|
|
78
|
+
FilterOptionToApiSearchMethodMap,
|
|
79
|
+
FilterOptionToPreviewComponentMap,
|
|
80
|
+
} from '../filter-options';
|
|
62
81
|
import DynamicFilterPreviewInfo from './dynamic-filter-preview-info.vue';
|
|
63
82
|
|
|
64
83
|
interface Props {
|
|
65
84
|
filter: IFilter;
|
|
66
|
-
|
|
85
|
+
/**
|
|
86
|
+
* @description
|
|
87
|
+
* is needed for form component to localize selected filter name value and/or
|
|
88
|
+
* pass filter options configs
|
|
89
|
+
*/
|
|
90
|
+
filterOptions: FilterOption[];
|
|
91
|
+
readonly?: boolean;
|
|
67
92
|
}
|
|
68
93
|
|
|
69
94
|
const { t } = useI18n();
|
|
@@ -71,16 +96,50 @@ const { t } = useI18n();
|
|
|
71
96
|
const props = defineProps<Props>();
|
|
72
97
|
|
|
73
98
|
const emit = defineEmits<{
|
|
74
|
-
'update:filter': [
|
|
99
|
+
'update:filter': [FilterData];
|
|
75
100
|
'delete:filter': [IFilter];
|
|
76
101
|
}>();
|
|
77
102
|
|
|
78
|
-
const
|
|
79
|
-
|
|
103
|
+
const filterConfig = computed(() => {
|
|
104
|
+
const thisFilterOption =
|
|
105
|
+
props.filterOptions?.find((option) => {
|
|
106
|
+
return option.value === props.filter.name;
|
|
107
|
+
}) || {};
|
|
108
|
+
|
|
109
|
+
return thisFilterOption;
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const localValue = ref();
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @author @dlohvinov
|
|
116
|
+
*
|
|
117
|
+
* @description
|
|
118
|
+
* loading filters preview data -> main preview component
|
|
119
|
+
* instead of tooltip-components to avoid api requests spam
|
|
120
|
+
*/
|
|
121
|
+
const fillLocalValue = async (filter = props.filter) => {
|
|
122
|
+
const filterName = props.filter.name;
|
|
123
|
+
const filterValue = filter.value;
|
|
124
|
+
|
|
125
|
+
const valueSearchMethod = FilterOptionToApiSearchMethodMap[filterName];
|
|
126
|
+
|
|
127
|
+
if (valueSearchMethod) {
|
|
128
|
+
const { items } = await valueSearchMethod({ id: filterValue });
|
|
129
|
+
localValue.value = items;
|
|
130
|
+
} else {
|
|
131
|
+
localValue.value = filterValue;
|
|
132
|
+
}
|
|
80
133
|
};
|
|
81
134
|
|
|
82
|
-
const
|
|
135
|
+
const submit = (filter: IFilter, { hide }) => {
|
|
83
136
|
emit('update:filter', filter);
|
|
137
|
+
fillLocalValue(filter);
|
|
138
|
+
hide();
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const deleteFilter = () => {
|
|
142
|
+
emit('delete:filter', props.filter);
|
|
84
143
|
};
|
|
85
144
|
</script>
|
|
86
145
|
|
|
@@ -91,4 +150,8 @@ const submitFilterChange = (filter: FilterInitParams) => {
|
|
|
91
150
|
align-items: center;
|
|
92
151
|
gap: var(--spacing-2xs);
|
|
93
152
|
}
|
|
153
|
+
|
|
154
|
+
.wt-loader {
|
|
155
|
+
margin: auto;
|
|
156
|
+
}
|
|
94
157
|
</style>
|
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<dynamic-filter-panel-wrapper>
|
|
3
3
|
<template #filters>
|
|
4
|
-
<!-- WTF? - /* https://webitel.atlassian.net/browse/WTEL-6308?focusedCommentId=657415 */ -->
|
|
5
|
-
<!--TODO-->
|
|
6
|
-
<!-- <dynamic-filter-preview-->
|
|
7
|
-
<!-- v-if="!hasCreatedAtFromFilter"-->
|
|
8
|
-
<!-- :filter="defaultCreatedAtFromFilterDataPreview"-->
|
|
9
|
-
<!-- dummy-->
|
|
10
|
-
<!-- >-->
|
|
11
|
-
<!-- <template #info>-->
|
|
12
|
-
<!-- <component-->
|
|
13
|
-
<!-- :is="FilterOptionToPreviewComponentMap[FilterOption.CreatedAtFrom]"-->
|
|
14
|
-
<!-- :value="defaultCreatedAtFromFilterDataPreview.value"-->
|
|
15
|
-
<!-- />-->
|
|
16
|
-
<!-- </template>-->
|
|
17
|
-
<!-- </dynamic-filter-preview>-->
|
|
18
|
-
|
|
19
4
|
<dynamic-filter-preview
|
|
20
5
|
v-for="filter of appliedFilters"
|
|
21
6
|
:key="filter.name"
|
|
22
7
|
:filter="filter"
|
|
8
|
+
:filter-options="localizedFilterOptions"
|
|
23
9
|
disable-click-away
|
|
24
10
|
@update:filter="emit('filter:update', $event)"
|
|
25
11
|
@delete:filter="emit('filter:delete', filter)"
|
|
@@ -36,6 +22,7 @@
|
|
|
36
22
|
<apply-preset-action
|
|
37
23
|
:namespace="props.presetNamespace"
|
|
38
24
|
:use-presets-store="props.usePresetsStore"
|
|
25
|
+
:filter-options="props.filterOptions"
|
|
39
26
|
@apply="emit('preset:apply', $event)"
|
|
40
27
|
/>
|
|
41
28
|
|
|
@@ -43,6 +30,7 @@
|
|
|
43
30
|
v-if="enablePresets"
|
|
44
31
|
:namespace="props.presetNamespace"
|
|
45
32
|
:filters-manager="props.filtersManager"
|
|
33
|
+
:filter-options="props.filterOptions"
|
|
46
34
|
/>
|
|
47
35
|
|
|
48
36
|
<wt-icon-action
|
|
@@ -80,7 +68,8 @@ type Props = {
|
|
|
80
68
|
filterOptions: FilterOption[];
|
|
81
69
|
/**
|
|
82
70
|
* @description
|
|
83
|
-
*
|
|
71
|
+
* create local filters manager from snapshot
|
|
72
|
+
* inside save-preset.vue
|
|
84
73
|
*/
|
|
85
74
|
filtersManager: IFiltersManager;
|
|
86
75
|
/**
|
|
@@ -130,7 +119,21 @@ const { t } = useI18n();
|
|
|
130
119
|
|
|
131
120
|
const appliedFilters = computed(() => {
|
|
132
121
|
return props.filtersManager.getFiltersList({
|
|
133
|
-
include: props.filterOptions
|
|
122
|
+
include: props.filterOptions.map((opt) => {
|
|
123
|
+
return opt.value || opt;
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const localizedFilterOptions = computed(() => {
|
|
129
|
+
return props.filterOptions.map((opt) => {
|
|
130
|
+
const isExtended = typeof opt !== 'string';
|
|
131
|
+
|
|
132
|
+
const name = isExtended
|
|
133
|
+
? t(`webitelUI.filters.${opt.value}`)
|
|
134
|
+
: t(`webitelUI.filters.${opt}`);
|
|
135
|
+
|
|
136
|
+
return isExtended ? { name, ...opt } : { name, value: opt };
|
|
134
137
|
});
|
|
135
138
|
});
|
|
136
139
|
|
|
@@ -139,16 +142,11 @@ const appliedFilters = computed(() => {
|
|
|
139
142
|
* available filters to add, with appliedFilters excluded
|
|
140
143
|
*/
|
|
141
144
|
const availableFilterOptions = computed(() => {
|
|
142
|
-
return
|
|
143
|
-
.
|
|
144
|
-
return
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
})
|
|
148
|
-
.map((opt) => ({
|
|
149
|
-
name: t(`webitelUI.filters.${opt}`),
|
|
150
|
-
value: opt,
|
|
151
|
-
}));
|
|
145
|
+
return localizedFilterOptions.value.filter(({ value: opt }) => {
|
|
146
|
+
return appliedFilters.value.every((filter) => {
|
|
147
|
+
return filter.name !== opt;
|
|
148
|
+
});
|
|
149
|
+
});
|
|
152
150
|
});
|
|
153
151
|
|
|
154
152
|
const enablePresets = computed(() => !!props.presetNamespace);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { FilterName } from '../types/Filter';
|
|
2
|
+
|
|
1
3
|
export const FilterOption = {
|
|
2
4
|
Agent: 'agent',
|
|
3
5
|
AmdResult: 'amdResult',
|
|
@@ -18,6 +20,7 @@ export const FilterOption = {
|
|
|
18
20
|
HasTranscription: 'hasTranscription',
|
|
19
21
|
User: 'user',
|
|
20
22
|
Variable: 'variable',
|
|
23
|
+
CreatedAt: 'createdAt',
|
|
21
24
|
CreatedAtFrom: 'createdAtFrom',
|
|
22
25
|
CreatedAtTo: 'createdAtTo',
|
|
23
26
|
Status: 'status',
|
|
@@ -38,6 +41,13 @@ export const FilterOption = {
|
|
|
38
41
|
ActualReactionTime: 'actualReactionTime',
|
|
39
42
|
ActualResolutionTime: 'actualResolutionTime',
|
|
40
43
|
HasAttachment: 'hasAttachment',
|
|
41
|
-
} as
|
|
44
|
+
} as FilterName;
|
|
45
|
+
|
|
46
|
+
type SimpleFilterOption = (typeof FilterOption)[keyof typeof FilterOption];
|
|
47
|
+
|
|
48
|
+
type ExtendedFilterOption = {
|
|
49
|
+
name: FilterOption;
|
|
50
|
+
notDeletable?: boolean;
|
|
51
|
+
};
|
|
42
52
|
|
|
43
|
-
export type FilterOption =
|
|
53
|
+
export type FilterOption = SimpleFilterOption | ExtendedFilterOption;
|