@webitel/ui-datalist 1.1.73 → 1.1.75
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 -1
- package/src/modules/card/composables/__tests__/useCardValidation.spec.ts +67 -0
- package/src/modules/card/composables/useCardValidation.ts +7 -1
- package/src/modules/filters/modules/filterConfig/components/_shared/string-filter/string-filter-value-field.vue +57 -0
- package/src/modules/filters/modules/filterConfig/components/_shared/string-filter/string-filter-value-preview.vue +11 -0
- package/src/modules/filters/modules/filterConfig/components/bucket/bucket-filter-value-field.vue +81 -0
- package/src/modules/filters/modules/filterConfig/components/bucket/bucket-filter-value-preview.vue +13 -0
- package/src/modules/filters/modules/filterConfig/components/bucket/index.ts +25 -0
- package/src/modules/filters/modules/filterConfig/components/call-reporting-result/call-reporting-result-filter-value-field.vue +81 -0
- package/src/modules/filters/modules/filterConfig/components/call-reporting-result/call-reporting-result-filter-value-preview.vue +35 -0
- package/src/modules/filters/modules/filterConfig/components/index.ts +46 -0
- package/src/modules/filters/modules/filterConfig/components/stop-cause/stop-cause-filter-value-field.vue +81 -0
- package/src/modules/filters/modules/filterConfig/components/stop-cause/stop-cause-filter-value-preview.vue +35 -0
- package/src/modules/filters/modules/filterConfig/components/tags/index.ts +25 -0
- package/src/modules/filters/modules/filterConfig/components/tags/tags-filter-value-field.vue +97 -0
- package/src/modules/filters/modules/filterConfig/components/tags/tags-filter-value-preview.vue +19 -0
- package/src/modules/filters/modules/filterConfig/composables/useCallReportingResultOptions.ts +21 -0
- package/src/modules/filters/modules/filterConfig/composables/useStopCauseOptions.ts +22 -0
- package/src/modules/filters/modules/filterConfig/enums/FilterOption.ts +12 -0
- package/types/.tsbuildinfo +1 -1
- package/types/modules/card/composables/useCardComponent.d.ts +1 -1
- package/types/modules/card/composables/useCardValidation.d.ts +2 -1
- package/types/modules/card/composables/useNestedCardComponent.d.ts +1 -1
- package/types/modules/filter-presets/stores/createFilterPresetsStore.d.ts +3 -0
- package/types/modules/filters/components/config/dynamic-view/dynamic-filter-config-form.vue.d.ts +2 -2
- package/types/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-options/date-time-options-filter-value-field.vue.d.ts +2 -8
- package/types/modules/filters/modules/filterConfig/components/_shared/string-filter/string-filter-value-field.vue.d.ts +13 -0
- package/types/modules/filters/modules/filterConfig/components/_shared/string-filter/string-filter-value-preview.vue.d.ts +6 -0
- package/types/modules/filters/modules/filterConfig/components/bucket/bucket-filter-value-field.vue.d.ts +19 -0
- package/types/modules/filters/modules/filterConfig/components/bucket/bucket-filter-value-preview.vue.d.ts +6 -0
- package/types/modules/filters/modules/filterConfig/components/bucket/index.d.ts +32 -0
- package/types/modules/filters/modules/filterConfig/components/call-reporting-result/call-reporting-result-filter-value-field.vue.d.ts +18 -0
- package/types/modules/filters/modules/filterConfig/components/call-reporting-result/call-reporting-result-filter-value-preview.vue.d.ts +6 -0
- package/types/modules/filters/modules/filterConfig/components/index.d.ts +75 -1
- package/types/modules/filters/modules/filterConfig/components/stop-cause/stop-cause-filter-value-field.vue.d.ts +18 -0
- package/types/modules/filters/modules/filterConfig/components/stop-cause/stop-cause-filter-value-preview.vue.d.ts +6 -0
- package/types/modules/filters/modules/filterConfig/components/tags/index.d.ts +32 -0
- package/types/modules/filters/modules/filterConfig/components/tags/tags-filter-value-field.vue.d.ts +19 -0
- package/types/modules/filters/modules/filterConfig/components/tags/tags-filter-value-preview.vue.d.ts +7 -0
- package/types/modules/filters/modules/filterConfig/composables/useCallReportingResultOptions.d.ts +6 -0
- package/types/modules/filters/modules/filterConfig/composables/useQueueTypeOptions.d.ts +1 -1
- package/types/modules/filters/modules/filterConfig/composables/useStopCauseOptions.d.ts +6 -0
- package/types/modules/filters/modules/filterConfig/enums/FilterOption.d.ts +12 -0
- package/types/modules/headers/createTableHeadersStore.d.ts +6 -0
- package/types/modules/permissions-page/stores/createPermissionsStore.d.ts +6 -0
- package/types/modules/table/createTableStore.store.d.ts +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webitel/ui-datalist",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.75",
|
|
4
4
|
"description": "Toolkit for building data lists in webitel ui system",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build:types": "vue-tsc -b tsconfig.build.json",
|
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
"Readme.md",
|
|
32
32
|
"CHANGELOG.md"
|
|
33
33
|
],
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"change-case": "^5.4.4"
|
|
36
|
+
},
|
|
34
37
|
"peerDependencies": {
|
|
35
38
|
"@regle/schemas": "^1.x",
|
|
36
39
|
"@vuelidate/core": "^2.0.3",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useRegleSchema } from '@regle/schemas';
|
|
2
|
+
import { getQueueDefaults } from '@webitel/api-services/api';
|
|
3
|
+
import { QueueType } from '@webitel/api-services/enums';
|
|
4
|
+
import { queueSchema } from '@webitel/api-services/validations';
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { effectScope, ref } from 'vue';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A card whose required-ness comes from a root `superRefine` — the queue, whose
|
|
10
|
+
* rules depend on `type` — has to surface those issues on the field the issue
|
|
11
|
+
* names. If it does not, `useCardSaveAction` aborts on `$validate()` while
|
|
12
|
+
* `r$.$error` stays false, so the button looks enabled and the click does
|
|
13
|
+
* nothing at all.
|
|
14
|
+
*
|
|
15
|
+
* The trap is a field seeded as `{}`: regle then files the issue under an index
|
|
16
|
+
* of a collection nobody reads. Seeding `undefined` keeps the `$fields` entry
|
|
17
|
+
* and the error.
|
|
18
|
+
*
|
|
19
|
+
* [WTEL-10140](https://webitel.atlassian.net/browse/WTEL-10140)
|
|
20
|
+
*/
|
|
21
|
+
describe('card validation of a root-level required rule', () => {
|
|
22
|
+
const validateDraft = async (draft: Record<string, unknown>) => {
|
|
23
|
+
const state = ref(draft);
|
|
24
|
+
const scope = effectScope(true);
|
|
25
|
+
// biome-ignore lint/suspicious/noExplicitAny: regle's inferred state type
|
|
26
|
+
let r$: any;
|
|
27
|
+
|
|
28
|
+
scope.run(() => {
|
|
29
|
+
({ r$ } = useRegleSchema(state, queueSchema as never));
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const result = await r$.$validate();
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
valid: result.valid,
|
|
36
|
+
rootError: r$.$error,
|
|
37
|
+
calendarErrors: r$.$fields?.calendar?.$errors,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
it('reports the missing calendar of a preview dialer on the field', async () => {
|
|
42
|
+
const { valid, rootError, calendarErrors } = await validateDraft({
|
|
43
|
+
...getQueueDefaults(QueueType.PREVIEW_DIALER),
|
|
44
|
+
name: 'a preview dialer',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(valid).toBe(false);
|
|
48
|
+
// what keeps the save button from looking clickable
|
|
49
|
+
expect(rootError).toBe(true);
|
|
50
|
+
// what the calendar select renders
|
|
51
|
+
expect(calendarErrors).toHaveLength(1);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('accepts the same draft once the calendar is filled', async () => {
|
|
55
|
+
const { valid, rootError } = await validateDraft({
|
|
56
|
+
...getQueueDefaults(QueueType.PREVIEW_DIALER),
|
|
57
|
+
name: 'a preview dialer',
|
|
58
|
+
calendar: {
|
|
59
|
+
id: '1',
|
|
60
|
+
name: '24/7',
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
expect(valid).toBe(true);
|
|
65
|
+
expect(rootError).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -2,6 +2,8 @@ import type { RegleShortcutDefinition } from '@regle/core';
|
|
|
2
2
|
import type { RegleSchema } from '@regle/schemas';
|
|
3
3
|
import { computed, type Ref } from 'vue';
|
|
4
4
|
|
|
5
|
+
import type { CardValidationFields } from '../types/CardValidationFields.types';
|
|
6
|
+
|
|
5
7
|
export const useCardValidation = <
|
|
6
8
|
// biome-ignore lint/suspicious/noExplicitAny: matches RegleSchema's own state constraint
|
|
7
9
|
TState extends Record<string, any>,
|
|
@@ -16,7 +18,11 @@ export const useCardValidation = <
|
|
|
16
18
|
});
|
|
17
19
|
|
|
18
20
|
const validationFields = computed(() => {
|
|
19
|
-
|
|
21
|
+
// Regle types $fields as a union with an empty-object arm to also
|
|
22
|
+
// support discriminated-union state shapes; TState here is always a
|
|
23
|
+
// plain card entity, so that arm never applies — narrow it away once,
|
|
24
|
+
// here, instead of at every card component consuming this composable.
|
|
25
|
+
return validationSchema.value.r$.$fields as CardValidationFields<TState>;
|
|
20
26
|
});
|
|
21
27
|
|
|
22
28
|
const hasValidationErrors = computed(() => {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<wt-input-text
|
|
3
|
+
v-model:model-value="model"
|
|
4
|
+
:label="t('webitelUI.filters.filterValue')"
|
|
5
|
+
:v="v$.model"
|
|
6
|
+
/>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script lang="ts" setup>
|
|
10
|
+
import { useVuelidate } from '@vuelidate/core';
|
|
11
|
+
import { required } from '@vuelidate/validators';
|
|
12
|
+
import { computed, watch } from 'vue';
|
|
13
|
+
import { useI18n } from 'vue-i18n';
|
|
14
|
+
|
|
15
|
+
type ModelValue = string;
|
|
16
|
+
|
|
17
|
+
const model = defineModel<ModelValue>();
|
|
18
|
+
if (!model.value) {
|
|
19
|
+
model.value = '';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const { t } = useI18n();
|
|
23
|
+
|
|
24
|
+
const v$ = useVuelidate(
|
|
25
|
+
computed(() => ({
|
|
26
|
+
model: {
|
|
27
|
+
required,
|
|
28
|
+
},
|
|
29
|
+
})),
|
|
30
|
+
{
|
|
31
|
+
model,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
$autoDirty: true,
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
v$.value.$touch();
|
|
39
|
+
|
|
40
|
+
const emit = defineEmits<{
|
|
41
|
+
'update:invalid': [
|
|
42
|
+
boolean,
|
|
43
|
+
];
|
|
44
|
+
}>();
|
|
45
|
+
|
|
46
|
+
watch(
|
|
47
|
+
() => v$.value.$invalid,
|
|
48
|
+
(invalid) => {
|
|
49
|
+
emit('update:invalid', invalid);
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
immediate: true,
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<style scoped></style>
|
package/src/modules/filters/modules/filterConfig/components/bucket/bucket-filter-value-field.vue
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<wt-multi-select
|
|
3
|
+
:label="labelValue"
|
|
4
|
+
:search-method="props.filterConfig.searchRecords"
|
|
5
|
+
:model-value="model"
|
|
6
|
+
:v="!disableValidation && v$.model"
|
|
7
|
+
option-value="id"
|
|
8
|
+
@update:model-value="handleInput"
|
|
9
|
+
/>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts" setup>
|
|
13
|
+
import { useVuelidate } from '@vuelidate/core';
|
|
14
|
+
import { required } from '@vuelidate/validators';
|
|
15
|
+
import { WtMultiSelect } from '@webitel/ui-sdk/components';
|
|
16
|
+
import { computed, onMounted, watch } from 'vue';
|
|
17
|
+
import { useI18n } from 'vue-i18n';
|
|
18
|
+
|
|
19
|
+
import { WtSysTypeFilterConfig } from '../../classes/FilterConfig';
|
|
20
|
+
|
|
21
|
+
type ModelValue = number[];
|
|
22
|
+
|
|
23
|
+
const props = defineProps<{
|
|
24
|
+
filterConfig: WtSysTypeFilterConfig;
|
|
25
|
+
disableValidation?: boolean;
|
|
26
|
+
}>();
|
|
27
|
+
|
|
28
|
+
const model = defineModel<ModelValue>();
|
|
29
|
+
|
|
30
|
+
const emit = defineEmits<{
|
|
31
|
+
'update:invalid': [
|
|
32
|
+
boolean,
|
|
33
|
+
];
|
|
34
|
+
}>();
|
|
35
|
+
const { t } = useI18n();
|
|
36
|
+
|
|
37
|
+
const labelValue = computed(() =>
|
|
38
|
+
t(
|
|
39
|
+
`webitelUI.filters.${
|
|
40
|
+
props?.filterConfig?.showFilterName
|
|
41
|
+
? props?.filterConfig.name
|
|
42
|
+
: 'filterValue'
|
|
43
|
+
}`,
|
|
44
|
+
),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const v$ = useVuelidate(
|
|
48
|
+
computed(() => ({
|
|
49
|
+
model: {
|
|
50
|
+
required,
|
|
51
|
+
},
|
|
52
|
+
})),
|
|
53
|
+
{
|
|
54
|
+
model,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
$autoDirty: true,
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
v$.value.$touch();
|
|
61
|
+
|
|
62
|
+
onMounted(() => {
|
|
63
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
watch(
|
|
67
|
+
() => v$.value.$invalid,
|
|
68
|
+
(invalid) => {
|
|
69
|
+
emit('update:invalid', invalid);
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
immediate: true,
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const handleInput = (value: ModelValue) => {
|
|
77
|
+
model.value = value;
|
|
78
|
+
};
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<style scoped></style>
|
package/src/modules/filters/modules/filterConfig/components/bucket/bucket-filter-value-preview.vue
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<lookup-filter-value-preview v-bind="props" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script lang="ts" setup>
|
|
6
|
+
import LookupFilterValuePreview from '../_shared/lookup-filter-preview/lookup-filter-value-preview.vue';
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
value: Record<string, unknown>[];
|
|
10
|
+
}>();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<style scoped></style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BucketsAPI } from '@webitel/api-services/api';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type FilterConfigBaseParams,
|
|
5
|
+
WtSysTypeFilterConfig,
|
|
6
|
+
} from '../../classes/FilterConfig';
|
|
7
|
+
import { FilterOption } from '../../enums/FilterOption';
|
|
8
|
+
import BucketFilterValueField from './bucket-filter-value-field.vue';
|
|
9
|
+
import BucketFilterValuePreview from './bucket-filter-value-preview.vue';
|
|
10
|
+
|
|
11
|
+
class BucketFilterConfig extends WtSysTypeFilterConfig {
|
|
12
|
+
readonly name = FilterOption.Bucket;
|
|
13
|
+
valueInputComponent = BucketFilterValueField;
|
|
14
|
+
valuePreviewComponent = BucketFilterValuePreview;
|
|
15
|
+
|
|
16
|
+
searchRecords(params: object): Promise<{
|
|
17
|
+
items: unknown[];
|
|
18
|
+
next?: boolean;
|
|
19
|
+
}> {
|
|
20
|
+
return BucketsAPI.getLookup(params);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const createBucketFilterConfig = (params?: FilterConfigBaseParams) =>
|
|
25
|
+
new BucketFilterConfig(params);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<wt-multi-select
|
|
3
|
+
:label="labelValue"
|
|
4
|
+
:options="options"
|
|
5
|
+
v-model:model-value="model"
|
|
6
|
+
:v="!disableValidation && v$.model"
|
|
7
|
+
chips-view
|
|
8
|
+
data-key="value"
|
|
9
|
+
option-label="label"
|
|
10
|
+
option-value="value"
|
|
11
|
+
/>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script lang="ts" setup>
|
|
15
|
+
import { useVuelidate } from '@vuelidate/core';
|
|
16
|
+
import { required } from '@vuelidate/validators';
|
|
17
|
+
import { WtMultiSelect } from '@webitel/ui-sdk/components';
|
|
18
|
+
import { computed, onMounted, watch } from 'vue';
|
|
19
|
+
import { useI18n } from 'vue-i18n';
|
|
20
|
+
|
|
21
|
+
import { WtSysTypeFilterConfig } from '../../classes/FilterConfig';
|
|
22
|
+
import { useCallReportingResultOptions } from '../../composables/useCallReportingResultOptions';
|
|
23
|
+
|
|
24
|
+
const model = defineModel<string[]>();
|
|
25
|
+
const { t } = useI18n();
|
|
26
|
+
|
|
27
|
+
const props = defineProps<{
|
|
28
|
+
filterConfig?: WtSysTypeFilterConfig;
|
|
29
|
+
disableValidation?: boolean;
|
|
30
|
+
}>();
|
|
31
|
+
|
|
32
|
+
const v$ = useVuelidate(
|
|
33
|
+
computed(() => ({
|
|
34
|
+
model: {
|
|
35
|
+
required,
|
|
36
|
+
},
|
|
37
|
+
})),
|
|
38
|
+
{
|
|
39
|
+
model,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
$autoDirty: true,
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
v$.value.$touch();
|
|
47
|
+
|
|
48
|
+
const emit = defineEmits<{
|
|
49
|
+
'update:invalid': [
|
|
50
|
+
boolean,
|
|
51
|
+
];
|
|
52
|
+
}>();
|
|
53
|
+
|
|
54
|
+
const labelValue = computed(() =>
|
|
55
|
+
t(
|
|
56
|
+
`webitelUI.filters.${
|
|
57
|
+
props?.filterConfig?.showFilterName
|
|
58
|
+
? props?.filterConfig.name
|
|
59
|
+
: 'filterValue'
|
|
60
|
+
}`,
|
|
61
|
+
),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const { options } = useCallReportingResultOptions();
|
|
65
|
+
|
|
66
|
+
onMounted(() => {
|
|
67
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
watch(
|
|
71
|
+
() => v$.value.$invalid,
|
|
72
|
+
(invalid) => {
|
|
73
|
+
emit('update:invalid', invalid);
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
immediate: true,
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<style scoped></style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ul>
|
|
3
|
+
<li
|
|
4
|
+
v-for="(label, index) of arrayValues"
|
|
5
|
+
:key="index"
|
|
6
|
+
>
|
|
7
|
+
{{ label }}
|
|
8
|
+
</li>
|
|
9
|
+
</ul>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts" setup>
|
|
13
|
+
import { computed } from 'vue';
|
|
14
|
+
|
|
15
|
+
import { useCallReportingResultOptions } from '../../composables/useCallReportingResultOptions';
|
|
16
|
+
|
|
17
|
+
const props = defineProps<{
|
|
18
|
+
value?: string[];
|
|
19
|
+
}>();
|
|
20
|
+
|
|
21
|
+
const { options } = useCallReportingResultOptions();
|
|
22
|
+
|
|
23
|
+
const arrayLabels = computed(() =>
|
|
24
|
+
options.value.reduce<Record<string, string>>((acc, { value, label }) => {
|
|
25
|
+
acc[value] = label;
|
|
26
|
+
return acc;
|
|
27
|
+
}, {}),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const arrayValues = computed(() =>
|
|
31
|
+
(props.value ?? []).map((v) => arrayLabels.value[v] || v),
|
|
32
|
+
);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style scoped></style>
|
|
@@ -4,6 +4,8 @@ import type { FilterConfigSearchMethodParams } from '../classes/FilterConfig';
|
|
|
4
4
|
import { FilterOption } from '../enums/FilterOption';
|
|
5
5
|
import DateTimeOptionsFilterValueField from './_shared/date-time-filter/date-time-options/date-time-options-filter-value-field.vue';
|
|
6
6
|
import DateTimeOptionsFilterValuePreview from './_shared/date-time-filter/date-time-options/date-time-options-filter-value-preview.vue';
|
|
7
|
+
import StringFilterValueField from './_shared/string-filter/string-filter-value-field.vue';
|
|
8
|
+
import StringFilterValuePreview from './_shared/string-filter/string-filter-value-preview.vue';
|
|
7
9
|
import AgentFilter from './agent/agent-filter-value-field.vue';
|
|
8
10
|
import AgentFilterPreview from './agent/agent-filter-value-preview.vue';
|
|
9
11
|
import { searchMethod as agentSearchMethod } from './agent/config';
|
|
@@ -14,8 +16,13 @@ import AmdResultFilterPreview from './amd-result/amd-result-filter-value-preview
|
|
|
14
16
|
import { createAuditorFilterConfig } from './auditor';
|
|
15
17
|
import AuditorFilter from './auditor/auditor-filter-value-field.vue';
|
|
16
18
|
import AuditorFilterPreview from './auditor/auditor-filter-value-preview.vue';
|
|
19
|
+
import { createBucketFilterConfig } from './bucket';
|
|
20
|
+
import BucketFilter from './bucket/bucket-filter-value-field.vue';
|
|
21
|
+
import BucketFilterPreview from './bucket/bucket-filter-value-preview.vue';
|
|
17
22
|
import CallDirectionFilterValueField from './call-direction/call-direction-filter-value-field.vue';
|
|
18
23
|
import CallDirectionFilterValuePreview from './call-direction/call-direction-filter-value-preview.vue';
|
|
24
|
+
import CallReportingResultFilter from './call-reporting-result/call-reporting-result-filter-value-field.vue';
|
|
25
|
+
import CallReportingResultFilterPreview from './call-reporting-result/call-reporting-result-filter-value-preview.vue';
|
|
19
26
|
import CaseActualReactionTimeFilterValueField from './case-actual-reaction-time/case-actual-reaction-time-filter-value-field.vue';
|
|
20
27
|
import CaseActualReactionTimeFilterValuePreview from './case-actual-reaction-time/case-actual-reaction-time-filter-value-preview.vue';
|
|
21
28
|
import CaseActualResolutionTimeFilterValueField from './case-actual-resolution-time/case-actual-resolution-time-filter-value-field.vue';
|
|
@@ -105,11 +112,16 @@ import ScoreFilterPreview from './score/score-from-to-filter-value-preview.vue';
|
|
|
105
112
|
import { createSkillFilterConfig } from './skill';
|
|
106
113
|
import SkillFilter from './skill/skill-filter-value-field.vue';
|
|
107
114
|
import SkillFilterPreview from './skill/skill-filter-value-preview.vue';
|
|
115
|
+
import StopCauseFilter from './stop-cause/stop-cause-filter-value-field.vue';
|
|
116
|
+
import StopCauseFilterPreview from './stop-cause/stop-cause-filter-value-preview.vue';
|
|
108
117
|
import { createSupervisorFilterConfig } from './supervisor';
|
|
109
118
|
import SupervisorFilter from './supervisor/supervisor-filter-value-field.vue';
|
|
110
119
|
import SupervisorFilterPreview from './supervisor/supervisor-filter-value-preview.vue';
|
|
111
120
|
import TagFilter from './tag/tag-filter-value-field.vue';
|
|
112
121
|
import TagFilterPreview from './tag/tag-filter-value-preview.vue';
|
|
122
|
+
import { createQueueTagsFilterConfig } from './tags';
|
|
123
|
+
import TagsFilter from './tags/tags-filter-value-field.vue';
|
|
124
|
+
import TagsFilterPreview from './tags/tags-filter-value-preview.vue';
|
|
113
125
|
import TalkDurationFilter from './talk-duration/talk-duration-filter-value-field.vue';
|
|
114
126
|
import TalkDurationFilterPreview from './talk-duration/talk-duration-filter-value-preview.vue';
|
|
115
127
|
import { createTeamFilterConfig } from './team';
|
|
@@ -134,8 +146,12 @@ export {
|
|
|
134
146
|
AmdResultFilterPreview,
|
|
135
147
|
AuditorFilter,
|
|
136
148
|
AuditorFilterPreview,
|
|
149
|
+
BucketFilter,
|
|
150
|
+
BucketFilterPreview,
|
|
137
151
|
CallDirectionFilterValueField,
|
|
138
152
|
CallDirectionFilterValuePreview,
|
|
153
|
+
CallReportingResultFilter,
|
|
154
|
+
CallReportingResultFilterPreview,
|
|
139
155
|
CaseActualReactionTimeFilterValueField,
|
|
140
156
|
CaseActualReactionTimeFilterValuePreview,
|
|
141
157
|
CaseActualResolutionTimeFilterValueField,
|
|
@@ -205,10 +221,14 @@ export {
|
|
|
205
221
|
ScoreFilterPreview,
|
|
206
222
|
SkillFilter,
|
|
207
223
|
SkillFilterPreview,
|
|
224
|
+
StopCauseFilter,
|
|
225
|
+
StopCauseFilterPreview,
|
|
208
226
|
SupervisorFilter,
|
|
209
227
|
SupervisorFilterPreview,
|
|
210
228
|
TagFilter,
|
|
211
229
|
TagFilterPreview,
|
|
230
|
+
TagsFilter,
|
|
231
|
+
TagsFilterPreview,
|
|
212
232
|
TalkDurationFilter,
|
|
213
233
|
TalkDurationFilterPreview,
|
|
214
234
|
TeamFilter,
|
|
@@ -246,6 +266,7 @@ export const FilterOptionToValueComponentMap: Record<FilterOption, Component> =
|
|
|
246
266
|
[FilterOption.HasFile]: HasFileFilter,
|
|
247
267
|
[FilterOption.Score]: ScoreFilter,
|
|
248
268
|
[FilterOption.Tag]: TagFilter,
|
|
269
|
+
[FilterOption.QueueTags]: TagsFilter,
|
|
249
270
|
[FilterOption.TalkDuration]: TalkDurationFilter,
|
|
250
271
|
[FilterOption.Team]: TeamFilter,
|
|
251
272
|
[FilterOption.TotalDuration]: TotalDurationFilter,
|
|
@@ -254,6 +275,17 @@ export const FilterOptionToValueComponentMap: Record<FilterOption, Component> =
|
|
|
254
275
|
[FilterOption.User]: UserFilter,
|
|
255
276
|
[FilterOption.Variable]: VariableFilter,
|
|
256
277
|
[FilterOption.CreatedAt]: DateTimeOptionsFilterValueField,
|
|
278
|
+
[FilterOption.JoinedAt]: DateTimeOptionsFilterValueField,
|
|
279
|
+
[FilterOption.LeavingAt]: DateTimeOptionsFilterValueField,
|
|
280
|
+
[FilterOption.OfferingAt]: DateTimeOptionsFilterValueField,
|
|
281
|
+
[FilterOption.Bucket]: BucketFilter,
|
|
282
|
+
[FilterOption.StopCause]: StopCauseFilter,
|
|
283
|
+
[FilterOption.MemberPriority]: RatingFromToFilter,
|
|
284
|
+
[FilterOption.MemberAttempts]: RatingFromToFilter,
|
|
285
|
+
[FilterOption.AttemptDuration]: RatingFromToFilter,
|
|
286
|
+
[FilterOption.MemberName]: StringFilterValueField,
|
|
287
|
+
[FilterOption.MemberDestination]: StringFilterValueField,
|
|
288
|
+
[FilterOption.CallReportingResult]: CallReportingResultFilter,
|
|
257
289
|
[FilterOption.CaseStatus]: CaseStatusFilterValueField,
|
|
258
290
|
[FilterOption.CaseSource]: CaseSourceFilterValueField,
|
|
259
291
|
[FilterOption.CaseService]: CaseServiceFilterValueField,
|
|
@@ -279,6 +311,17 @@ export const FilterOptionToPreviewComponentMap: Record<
|
|
|
279
311
|
Component
|
|
280
312
|
> = {
|
|
281
313
|
[FilterOption.CreatedAt]: DateTimeOptionsFilterValuePreview,
|
|
314
|
+
[FilterOption.JoinedAt]: DateTimeOptionsFilterValuePreview,
|
|
315
|
+
[FilterOption.LeavingAt]: DateTimeOptionsFilterValuePreview,
|
|
316
|
+
[FilterOption.OfferingAt]: DateTimeOptionsFilterValuePreview,
|
|
317
|
+
[FilterOption.Bucket]: BucketFilterPreview,
|
|
318
|
+
[FilterOption.StopCause]: StopCauseFilterPreview,
|
|
319
|
+
[FilterOption.MemberPriority]: RatingFromToFilterPreview,
|
|
320
|
+
[FilterOption.MemberAttempts]: RatingFromToFilterPreview,
|
|
321
|
+
[FilterOption.AttemptDuration]: RatingFromToFilterPreview,
|
|
322
|
+
[FilterOption.MemberName]: StringFilterValuePreview,
|
|
323
|
+
[FilterOption.MemberDestination]: StringFilterValuePreview,
|
|
324
|
+
[FilterOption.CallReportingResult]: CallReportingResultFilterPreview,
|
|
282
325
|
[FilterOption.Agent]: AgentFilterPreview,
|
|
283
326
|
[FilterOption.Region]: RegionFilterPreview,
|
|
284
327
|
[FilterOption.UtilizationProgress]: UtilizationProgressFilterPreview,
|
|
@@ -300,6 +343,7 @@ export const FilterOptionToPreviewComponentMap: Record<
|
|
|
300
343
|
[FilterOption.HasFile]: HasFileFilterPreview,
|
|
301
344
|
[FilterOption.Score]: ScoreFilterPreview,
|
|
302
345
|
[FilterOption.Tag]: TagFilterPreview,
|
|
346
|
+
[FilterOption.QueueTags]: TagsFilterPreview,
|
|
303
347
|
[FilterOption.TalkDuration]: TalkDurationFilterPreview,
|
|
304
348
|
[FilterOption.Team]: TeamFilterPreview,
|
|
305
349
|
[FilterOption.TotalDuration]: TotalDurationFilterPreview,
|
|
@@ -379,4 +423,6 @@ export const FilterOptionToFilterConfigCreatorMap = {
|
|
|
379
423
|
[FilterOption.Supervisor]: createSupervisorFilterConfig,
|
|
380
424
|
[FilterOption.Auditor]: createAuditorFilterConfig,
|
|
381
425
|
[FilterOption.Region]: createRegionFilterConfig,
|
|
426
|
+
[FilterOption.Bucket]: createBucketFilterConfig,
|
|
427
|
+
[FilterOption.QueueTags]: createQueueTagsFilterConfig,
|
|
382
428
|
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<wt-multi-select
|
|
3
|
+
:label="labelValue"
|
|
4
|
+
:options="options"
|
|
5
|
+
v-model:model-value="model"
|
|
6
|
+
:v="!disableValidation && v$.model"
|
|
7
|
+
chips-view
|
|
8
|
+
data-key="value"
|
|
9
|
+
option-label="label"
|
|
10
|
+
option-value="value"
|
|
11
|
+
/>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script lang="ts" setup>
|
|
15
|
+
import { useVuelidate } from '@vuelidate/core';
|
|
16
|
+
import { required } from '@vuelidate/validators';
|
|
17
|
+
import { WtMultiSelect } from '@webitel/ui-sdk/components';
|
|
18
|
+
import { computed, onMounted, watch } from 'vue';
|
|
19
|
+
import { useI18n } from 'vue-i18n';
|
|
20
|
+
|
|
21
|
+
import { WtSysTypeFilterConfig } from '../../classes/FilterConfig';
|
|
22
|
+
import { useStopCauseOptions } from '../../composables/useStopCauseOptions';
|
|
23
|
+
|
|
24
|
+
const model = defineModel<string[]>();
|
|
25
|
+
const { t } = useI18n();
|
|
26
|
+
|
|
27
|
+
const props = defineProps<{
|
|
28
|
+
filterConfig?: WtSysTypeFilterConfig;
|
|
29
|
+
disableValidation?: boolean;
|
|
30
|
+
}>();
|
|
31
|
+
|
|
32
|
+
const v$ = useVuelidate(
|
|
33
|
+
computed(() => ({
|
|
34
|
+
model: {
|
|
35
|
+
required,
|
|
36
|
+
},
|
|
37
|
+
})),
|
|
38
|
+
{
|
|
39
|
+
model,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
$autoDirty: true,
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
v$.value.$touch();
|
|
47
|
+
|
|
48
|
+
const emit = defineEmits<{
|
|
49
|
+
'update:invalid': [
|
|
50
|
+
boolean,
|
|
51
|
+
];
|
|
52
|
+
}>();
|
|
53
|
+
|
|
54
|
+
const labelValue = computed(() =>
|
|
55
|
+
t(
|
|
56
|
+
`webitelUI.filters.${
|
|
57
|
+
props?.filterConfig?.showFilterName
|
|
58
|
+
? props?.filterConfig.name
|
|
59
|
+
: 'filterValue'
|
|
60
|
+
}`,
|
|
61
|
+
),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const { options } = useStopCauseOptions();
|
|
65
|
+
|
|
66
|
+
onMounted(() => {
|
|
67
|
+
if (!props?.disableValidation) v$.value.$touch();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
watch(
|
|
71
|
+
() => v$.value.$invalid,
|
|
72
|
+
(invalid) => {
|
|
73
|
+
emit('update:invalid', invalid);
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
immediate: true,
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<style scoped></style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ul>
|
|
3
|
+
<li
|
|
4
|
+
v-for="(label, index) of arrayValues"
|
|
5
|
+
:key="index"
|
|
6
|
+
>
|
|
7
|
+
{{ label }}
|
|
8
|
+
</li>
|
|
9
|
+
</ul>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts" setup>
|
|
13
|
+
import { computed } from 'vue';
|
|
14
|
+
|
|
15
|
+
import { useStopCauseOptions } from '../../composables/useStopCauseOptions';
|
|
16
|
+
|
|
17
|
+
const props = defineProps<{
|
|
18
|
+
value?: string[];
|
|
19
|
+
}>();
|
|
20
|
+
|
|
21
|
+
const { options } = useStopCauseOptions();
|
|
22
|
+
|
|
23
|
+
const arrayLabels = computed(() =>
|
|
24
|
+
options.value.reduce<Record<string, string>>((acc, { value, label }) => {
|
|
25
|
+
acc[value] = label;
|
|
26
|
+
return acc;
|
|
27
|
+
}, {}),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const arrayValues = computed(() =>
|
|
31
|
+
(props.value ?? []).map((v) => arrayLabels.value[v] || v),
|
|
32
|
+
);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style scoped></style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { QueuesAPI } from '@webitel/api-services/api';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type FilterConfigBaseParams,
|
|
5
|
+
WtSysTypeFilterConfig,
|
|
6
|
+
} from '../../classes/FilterConfig';
|
|
7
|
+
import { FilterOption } from '../../enums/FilterOption';
|
|
8
|
+
import TagsFilterValueField from './tags-filter-value-field.vue';
|
|
9
|
+
import TagsFilterValuePreview from './tags-filter-value-preview.vue';
|
|
10
|
+
|
|
11
|
+
class QueueTagsFilterConfig extends WtSysTypeFilterConfig {
|
|
12
|
+
readonly name = FilterOption.QueueTags;
|
|
13
|
+
valueInputComponent = TagsFilterValueField;
|
|
14
|
+
valuePreviewComponent = TagsFilterValuePreview;
|
|
15
|
+
|
|
16
|
+
searchRecords(params: object): Promise<{
|
|
17
|
+
items: unknown[];
|
|
18
|
+
next?: boolean;
|
|
19
|
+
}> {
|
|
20
|
+
return QueuesAPI.getQueuesTags(params);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const createQueueTagsFilterConfig = (params?: FilterConfigBaseParams) =>
|
|
25
|
+
new QueueTagsFilterConfig(params);
|