@webitel/ui-datalist 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/Readme.md +19 -0
  2. package/package.json +3 -1
  3. package/src/filter-presets/api/PresetQuery.api.ts +123 -0
  4. package/src/filter-presets/components/_shared/input-fields/preset-description-field.vue +33 -0
  5. package/src/filter-presets/components/_shared/input-fields/preset-name-field.vue +29 -0
  6. package/src/filter-presets/components/_shared/preset-filters-preview.vue +45 -0
  7. package/src/filter-presets/components/apply-preset/apply-preset-action.vue +234 -0
  8. package/src/filter-presets/components/apply-preset/preset-preview.vue +210 -0
  9. package/src/filter-presets/components/save-preset/overwrite-preset-popup.vue +64 -0
  10. package/src/filter-presets/components/save-preset/save-preset-action.vue +139 -0
  11. package/src/filter-presets/components/save-preset/save-preset-popup.vue +136 -0
  12. package/src/filter-presets/index.ts +5 -0
  13. package/src/filter-presets/stores/createFilterPresetsStore.ts +17 -0
  14. package/src/filter-presets/stores/headers/headers.ts +24 -0
  15. package/src/filters/classes/Filter.ts +30 -0
  16. package/src/filters/classes/FilterStorage.ts +34 -0
  17. package/src/filters/classes/FilterStorageOptions.d.ts +6 -0
  18. package/src/filters/classes/FiltersManager.ts +189 -0
  19. package/src/filters/components/config/dynamic-filter-config-form-label.vue +50 -0
  20. package/src/filters/components/config/dynamic-filter-config-form.vue +140 -0
  21. package/src/filters/components/config/dynamic-filter-config-view.vue +40 -0
  22. package/src/filters/components/dynamic-filter-add-action.vue +54 -0
  23. package/src/filters/components/dynamic-filter-panel-wrapper.vue +57 -0
  24. package/src/filters/components/dynamic-filter-search.vue +61 -0
  25. package/src/filters/components/filter-options/_shared/composables/booleanFilterToolkit.ts +39 -0
  26. package/src/filters/components/filter-options/_shared/composables/useFromToSecToPreviewTime.ts +41 -0
  27. package/src/filters/components/filter-options/_shared/date-time-filter/date-time-filter-value-field.vue +56 -0
  28. package/src/filters/components/filter-options/_shared/durations/duration-filter-value-field.vue +84 -0
  29. package/src/filters/components/filter-options/_shared/has-options/has-option-filter-value-field.vue +38 -0
  30. package/src/filters/components/filter-options/_shared/types/BooleanFilter.ts +1 -0
  31. package/src/filters/components/filter-options/actual-reaction-time/actual-reaction-time-filter-value-field.vue +18 -0
  32. package/src/filters/components/filter-options/actual-reaction-time/actual-reaction-time-filter-value-preview.vue +44 -0
  33. package/src/filters/components/filter-options/actual-resolution-time/actual-resolution-time-filter-value-field.vue +18 -0
  34. package/src/filters/components/filter-options/actual-resolution-time/actual-resolution-time-filter-value-preview.vue +44 -0
  35. package/src/filters/components/filter-options/agent/agent-filter-value-field.vue +58 -0
  36. package/src/filters/components/filter-options/agent/agent-filter-value-preview.vue +31 -0
  37. package/src/filters/components/filter-options/agent/config.js +4 -0
  38. package/src/filters/components/filter-options/amd-result/amd-result-filter-value-field.vue +52 -0
  39. package/src/filters/components/filter-options/amd-result/amd-result-filter-value-preview.vue +18 -0
  40. package/src/filters/components/filter-options/assignee/assignee-filter-value-field.vue +74 -0
  41. package/src/filters/components/filter-options/assignee/assignee-filter-value-preview.vue +36 -0
  42. package/src/filters/components/filter-options/assignee/config.js +4 -0
  43. package/src/filters/components/filter-options/author/author-filter-value-field.vue +56 -0
  44. package/src/filters/components/filter-options/author/author-filter-value-preview.vue +31 -0
  45. package/src/filters/components/filter-options/author/config.js +4 -0
  46. package/src/filters/components/filter-options/cause/cause-filter-value-field.vue +52 -0
  47. package/src/filters/components/filter-options/cause/cause-filter-value-preview.vue +18 -0
  48. package/src/filters/components/filter-options/close-reason-groups-case/close-reason-groups-case-filter-value-field.vue +102 -0
  49. package/src/filters/components/filter-options/close-reason-groups-case/close-reason-groups-case-filter-value-preview.vue +34 -0
  50. package/src/filters/components/filter-options/close-reason-groups-case/config.js +7 -0
  51. package/src/filters/components/filter-options/contact/config.js +4 -0
  52. package/src/filters/components/filter-options/contact/contact-filter-value-field.vue +56 -0
  53. package/src/filters/components/filter-options/contact/contact-filter-value-preview.vue +31 -0
  54. package/src/filters/components/filter-options/contact-group/config.js +4 -0
  55. package/src/filters/components/filter-options/contact-group/contact-group-filter-value-field.vue +74 -0
  56. package/src/filters/components/filter-options/contact-group/contact-group-filter-value-preview.vue +38 -0
  57. package/src/filters/components/filter-options/created-at-from/created-at-from-filter-value-field.vue +24 -0
  58. package/src/filters/components/filter-options/created-at-from/created-at-from-filter-value-preview.vue +15 -0
  59. package/src/filters/components/filter-options/created-at-to/created-at-to-filter-value-field.vue +24 -0
  60. package/src/filters/components/filter-options/created-at-to/created-at-to-filter-value-preview.vue +15 -0
  61. package/src/filters/components/filter-options/direction/direction-filter-value-field.vue +51 -0
  62. package/src/filters/components/filter-options/direction/direction-filter-value-preview.vue +17 -0
  63. package/src/filters/components/filter-options/gateway/config.js +4 -0
  64. package/src/filters/components/filter-options/gateway/gateway-filter-value-field.vue +56 -0
  65. package/src/filters/components/filter-options/gateway/gateway-filter-value-preview.vue +31 -0
  66. package/src/filters/components/filter-options/grantee/config.js +4 -0
  67. package/src/filters/components/filter-options/grantee/grantee-filter-value-field.vue +56 -0
  68. package/src/filters/components/filter-options/grantee/grantee-filter-value-preview.vue +31 -0
  69. package/src/filters/components/filter-options/has-attachment/has-attachment-filter-value-field.vue +43 -0
  70. package/src/filters/components/filter-options/has-attachment/has-attachment-filter-value-preview.vue +24 -0
  71. package/src/filters/components/filter-options/has-file/has-file-filter-value-field.vue +33 -0
  72. package/src/filters/components/filter-options/has-file/has-file-filter-value-preview.vue +15 -0
  73. package/src/filters/components/filter-options/has-rating/has-rating-filter-value-field.vue +33 -0
  74. package/src/filters/components/filter-options/has-rating/has-rating-filter-value-preview.vue +15 -0
  75. package/src/filters/components/filter-options/has-transcription/has-transcription-filter-value-field.vue +33 -0
  76. package/src/filters/components/filter-options/has-transcription/has-transcription-filter-value-preview.vue +15 -0
  77. package/src/filters/components/filter-options/impacted/config.js +4 -0
  78. package/src/filters/components/filter-options/impacted/impacted-filter-value-field.vue +56 -0
  79. package/src/filters/components/filter-options/impacted/impacted-filter-value-preview.vue +31 -0
  80. package/src/filters/components/filter-options/index.ts +250 -0
  81. package/src/filters/components/filter-options/priority-case/config.js +4 -0
  82. package/src/filters/components/filter-options/priority-case/priority-case-filter-value-field.vue +57 -0
  83. package/src/filters/components/filter-options/priority-case/priority-case-filter-value-preview.vue +31 -0
  84. package/src/filters/components/filter-options/queue/config.js +4 -0
  85. package/src/filters/components/filter-options/queue/queue-filter-value-field.vue +56 -0
  86. package/src/filters/components/filter-options/queue/queue-filter-value-preview.vue +31 -0
  87. package/src/filters/components/filter-options/rated-by/config.js +4 -0
  88. package/src/filters/components/filter-options/rated-by/rated-by-filter-value-field.vue +56 -0
  89. package/src/filters/components/filter-options/rated-by/rated-by-filter-value-preview.vue +31 -0
  90. package/src/filters/components/filter-options/rating/rating-from-to-filter-value-field.vue +101 -0
  91. package/src/filters/components/filter-options/rating/rating-from-to-filter-value-preview.vue +39 -0
  92. package/src/filters/components/filter-options/reaction-time/reaction-time-filter-value-field.vue +18 -0
  93. package/src/filters/components/filter-options/reaction-time/reaction-time-filter-value-preview.vue +44 -0
  94. package/src/filters/components/filter-options/reporter/config.js +4 -0
  95. package/src/filters/components/filter-options/reporter/reporter-filter-value-field.vue +56 -0
  96. package/src/filters/components/filter-options/reporter/reporter-filter-value-preview.vue +31 -0
  97. package/src/filters/components/filter-options/resolution-time/resolution-time-filter-value-field.vue +18 -0
  98. package/src/filters/components/filter-options/resolution-time/resolution-time-filter-value-preview.vue +44 -0
  99. package/src/filters/components/filter-options/score/score-from-to-filter-value-field.vue +100 -0
  100. package/src/filters/components/filter-options/score/score-from-to-filter-value-preview.vue +39 -0
  101. package/src/filters/components/filter-options/service-case/config.js +6 -0
  102. package/src/filters/components/filter-options/service-case/service-case-filter-value-field.vue +82 -0
  103. package/src/filters/components/filter-options/service-case/service-case-filter-value-preview.vue +34 -0
  104. package/src/filters/components/filter-options/sla/config.js +4 -0
  105. package/src/filters/components/filter-options/sla/sla-filter-value-field.vue +57 -0
  106. package/src/filters/components/filter-options/sla/sla-filter-value-preview.vue +31 -0
  107. package/src/filters/components/filter-options/sla-condition/config.js +6 -0
  108. package/src/filters/components/filter-options/sla-condition/sla-condition-filter-value-field.vue +98 -0
  109. package/src/filters/components/filter-options/sla-condition/sla-condition-filter-value-preview.vue +37 -0
  110. package/src/filters/components/filter-options/source-case/config.js +4 -0
  111. package/src/filters/components/filter-options/source-case/source-case-filter-value-field.vue +57 -0
  112. package/src/filters/components/filter-options/source-case/source-case-filter-value-preview.vue +31 -0
  113. package/src/filters/components/filter-options/status-case/config.js +7 -0
  114. package/src/filters/components/filter-options/status-case/status-case-filter-value-field.vue +102 -0
  115. package/src/filters/components/filter-options/status-case/status-case-filter-value-preview.vue +37 -0
  116. package/src/filters/components/filter-options/tag/tag-filter-value-field.vue +52 -0
  117. package/src/filters/components/filter-options/tag/tag-filter-value-preview.vue +38 -0
  118. package/src/filters/components/filter-options/talk-duration/TalkDurationFilter.d.ts +4 -0
  119. package/src/filters/components/filter-options/talk-duration/talk-duration-filter-value-field.vue +19 -0
  120. package/src/filters/components/filter-options/talk-duration/talk-duration-filter-value-preview.vue +44 -0
  121. package/src/filters/components/filter-options/team/config.js +4 -0
  122. package/src/filters/components/filter-options/team/team-filter-value-field.vue +56 -0
  123. package/src/filters/components/filter-options/team/team-filter-value-preview.vue +31 -0
  124. package/src/filters/components/filter-options/total-duration/TotalDurationFilter.d.ts +4 -0
  125. package/src/filters/components/filter-options/total-duration/total-duration-filter-value-field.vue +19 -0
  126. package/src/filters/components/filter-options/total-duration/total-duration-filter-value-preview.vue +44 -0
  127. package/src/filters/components/filter-options/user/config.js +4 -0
  128. package/src/filters/components/filter-options/user/user-filter-value-field.vue +56 -0
  129. package/src/filters/components/filter-options/user/user-filter-value-preview.vue +31 -0
  130. package/src/filters/components/filter-options/variable/variable-filter-value-field.vue +50 -0
  131. package/src/filters/components/filter-options/variable/variable-filter-value-preview.vue +39 -0
  132. package/src/filters/components/preview/dynamic-filter-preview-info.vue +35 -0
  133. package/src/filters/components/preview/dynamic-filter-preview.vue +76 -0
  134. package/src/filters/components/table-filters-panel.vue +87 -0
  135. package/src/filters/createTableFiltersStore.ts +81 -0
  136. package/src/filters/enums/FilterOption.ts +43 -0
  137. package/src/filters/enums/amd-result-options.ts +38 -0
  138. package/src/filters/enums/boolean-options.ts +16 -0
  139. package/src/filters/enums/direction-options.ts +20 -0
  140. package/src/filters/enums/hangup-cause-options.ts +265 -0
  141. package/src/filters/enums/tag-options.ts +8 -0
  142. package/src/filters/index.ts +27 -0
  143. package/src/filters/scripts/utils.ts +31 -0
  144. package/src/filters/types/Filter.d.ts +46 -0
  145. package/src/filters/types/FiltersManager.d.ts +76 -0
  146. package/src/headers/createTableHeadersStore.ts +140 -0
  147. package/src/index.d.ts +0 -0
  148. package/src/index.ts +3 -0
  149. package/src/pagination/createTablePaginationStore.ts +64 -0
  150. package/src/persist/PersistedStorage.types.ts +51 -0
  151. package/src/persist/useLocalStoragePersistedStorage.ts +37 -0
  152. package/src/persist/usePersistedStorage.ts +151 -0
  153. package/src/persist/useRoutePersistedStorage.ts +41 -0
  154. package/src/table/createTableStore.store.ts +206 -0
  155. package/src/types/tableStore.types.ts +61 -0
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <wt-select
3
+ :close-on-select="false"
4
+ :label="t('webitelUI.filters.filterValue')"
5
+ :search-method="searchMethod"
6
+ :value="model"
7
+ :v="v$.model"
8
+ multiple
9
+ use-value-from-options-by-prop="id"
10
+ @input="handleInput"
11
+ />
12
+ </template>
13
+
14
+ <script lang="ts" setup>
15
+ import { useVuelidate } from '@vuelidate/core';
16
+ import { required } from '@vuelidate/validators';
17
+ import { computed, watch } from 'vue';
18
+ import { useI18n } from 'vue-i18n';
19
+
20
+ import WtSelect from '../../../../../../../components/wt-select/wt-select.vue';
21
+ import { searchMethod } from './config.js';
22
+
23
+ type ModelValue = number[];
24
+
25
+ const model = defineModel<ModelValue>();
26
+
27
+ const emit = defineEmits<{
28
+ 'update:invalid': [boolean];
29
+ }>();
30
+ const { t } = useI18n();
31
+
32
+ const v$ = useVuelidate(
33
+ computed(() => ({
34
+ model: {
35
+ required,
36
+ },
37
+ })),
38
+ { model },
39
+ { $autoDirty: true },
40
+ );
41
+ v$.value.$touch();
42
+
43
+ watch(
44
+ () => v$.value.$invalid,
45
+ (invalid) => {
46
+ emit('update:invalid', invalid);
47
+ },
48
+ { immediate: true },
49
+ );
50
+
51
+ const handleInput = (value: ModelValue) => {
52
+ model.value = value;
53
+ };
54
+ </script>
55
+
56
+ <style lang="scss" scoped></style>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <ul v-if="localValue">
3
+ <li
4
+ v-for="({ name }, index) of localValue"
5
+ :key="index"
6
+ >
7
+ {{ name }}
8
+ </li>
9
+ </ul>
10
+ </template>
11
+
12
+ <script lang="ts" setup>
13
+ import { ref } from 'vue';
14
+
15
+ import { searchMethod } from './config.js';
16
+
17
+ const props = defineProps<{
18
+ value: number[];
19
+ }>();
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
+ </script>
30
+
31
+ <style lang="scss" scoped></style>
@@ -0,0 +1,101 @@
1
+ <template>
2
+ <div class="rating-from-to-filter-value-field">
3
+ <wt-input
4
+ v-if="model"
5
+ :label="`${t('reusable.from')}:`"
6
+ :number-min="0"
7
+ :placeholder="t('webitelUI.filters.filterValue')"
8
+ :v="v$.model?.from"
9
+ :value="model.from"
10
+ class="rating-from-to-filter-value-field__input"
11
+ type="number"
12
+ @input="handleInput('from', $event)"
13
+ />
14
+
15
+ <wt-input
16
+ v-if="model"
17
+ :label="`${t('reusable.to')}:`"
18
+ :number-min="0"
19
+ :placeholder="t('webitelUI.filters.filterValue')"
20
+ :v="v$.model?.to"
21
+ :value="model.to"
22
+ class="rating-from-to-filter-value-field__input"
23
+ type="number"
24
+ @input="handleInput('to', $event)"
25
+ />
26
+ </div>
27
+ </template>
28
+
29
+ <script lang="ts" setup>
30
+ import { useVuelidate } from '@vuelidate/core';
31
+ import { maxValue, requiredIf } from '@vuelidate/validators';
32
+ import { computed, watch } from 'vue';
33
+ import { useI18n } from 'vue-i18n';
34
+
35
+ import { WtInput } from '../../../../../../../components';
36
+
37
+ type ModelValue = {
38
+ from: number;
39
+ to: number;
40
+ };
41
+ const model = defineModel<ModelValue>();
42
+ if (!model.value) {
43
+ model.value = {
44
+ from: null,
45
+ to: null,
46
+ };
47
+ }
48
+
49
+ const emit = defineEmits<{
50
+ 'update:invalid': [boolean];
51
+ }>();
52
+
53
+ const { t } = useI18n();
54
+
55
+ const v$ = useVuelidate(
56
+ computed(() => ({
57
+ model: {
58
+ from: {
59
+ required: requiredIf(() => !model.value.to),
60
+ maxValue: maxValue(
61
+ model?.value?.to && model.value.from > model.value.to
62
+ ? model.value.to
63
+ : Infinity,
64
+ ),
65
+ },
66
+ to: {
67
+ required: requiredIf(() => !model.value.from),
68
+ },
69
+ },
70
+ })),
71
+ { model },
72
+ { $autoDirty: true },
73
+ );
74
+ v$.value.$touch();
75
+
76
+ const handleInput = (key: keyof ModelValue, value: number) => {
77
+ const newValue = { ...model.value };
78
+ newValue[key] = value;
79
+ model.value = newValue;
80
+ };
81
+
82
+ watch(
83
+ () => v$.value.$invalid,
84
+ (invalid) => {
85
+ emit('update:invalid', invalid);
86
+ },
87
+ { immediate: true },
88
+ );
89
+ </script>
90
+
91
+ <style lang="scss" scoped>
92
+ .rating-from-to-filter-value-field {
93
+ display: flex;
94
+ align-items: center;
95
+ grid-gap: var(--spacing-xs);
96
+
97
+ &__input {
98
+ flex: 1;
99
+ }
100
+ }
101
+ </style>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <div class="score-from-to-filter-value-preview">
3
+ <div v-if="props.value.from">
4
+ <p class="score-from-to-filter-value-preview__title">
5
+ {{ t('reusable.from') }}
6
+ </p>
7
+
8
+ <span>{{ props.value.from }}</span>
9
+ </div>
10
+
11
+ <div v-if="props.value.to">
12
+ <p class="score-from-to-filter-value-preview__title">
13
+ {{ t('reusable.to') }}
14
+ </p>
15
+
16
+ <span>{{ props.value.to }}</span>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script lang="ts" setup>
22
+ import { useI18n } from 'vue-i18n';
23
+
24
+ const props = defineProps<{
25
+ value: number[];
26
+ }>();
27
+
28
+ const { t } = useI18n();
29
+ </script>
30
+
31
+ <style lang="scss" scoped>
32
+ @use '@webitel/styleguide/typography' as *;
33
+
34
+ .score-from-to-filter-value-preview {
35
+ &__title {
36
+ @extend %typo-subtitle-1;
37
+ }
38
+ }
39
+ </style>
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <date-time-filter-value-field
3
+ :model-value="model"
4
+ @update:model-value="model = $event"
5
+ />
6
+ </template>
7
+
8
+ <script lang="ts" setup>
9
+ import DateTimeFilterValueField from '../_shared/date-time-filter/date-time-filter-value-field.vue';
10
+
11
+ type ModelValue = {
12
+ from: number;
13
+ to: number;
14
+ };
15
+ const model = defineModel<ModelValue>();
16
+ </script>
17
+
18
+ <style lang="scss" scoped></style>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <div class="reaction-time-filter-value-preview">
3
+ <div v-if="props.value.from">
4
+ <p class="reaction-time-filter-value-preview__title">
5
+ {{ t('reusable.from') }}
6
+ </p>
7
+
8
+ <span>{{ convertTimestampToDate(props.value.from) }}</span>
9
+ </div>
10
+
11
+ <div v-if="props.value.to">
12
+ <p class="reaction-time-filter-value-preview__title">
13
+ {{ t('reusable.to') }}
14
+ </p>
15
+
16
+ <span>{{ convertTimestampToDate(props.value.to) }}</span>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script lang="ts" setup>
22
+ import { format } from 'date-fns';
23
+ import { useI18n } from 'vue-i18n';
24
+
25
+ const props = defineProps<{
26
+ value: number[];
27
+ }>();
28
+
29
+ const { t } = useI18n();
30
+
31
+ function convertTimestampToDate(value) {
32
+ return format(new Date(value), 'dd.MM.yyyy HH:mm');
33
+ }
34
+ </script>
35
+
36
+ <style lang="scss" scoped>
37
+ @use '@webitel/styleguide/typography' as *;
38
+
39
+ .reaction-time-filter-value-preview {
40
+ &__title {
41
+ @extend %typo-subtitle-1;
42
+ }
43
+ }
44
+ </style>
@@ -0,0 +1,4 @@
1
+ import ContactsAPI from '../../../../../../../api/clients/сontacts/contacts.js';
2
+
3
+ export const searchMethod = ContactsAPI.getLookup;
4
+ export const localePath = '';
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <wt-select
3
+ :close-on-select="false"
4
+ :label="t('webitelUI.filters.filterValue')"
5
+ :search-method="searchMethod"
6
+ :v="v$.model"
7
+ :value="model"
8
+ multiple
9
+ use-value-from-options-by-prop="id"
10
+ @input="handleInput"
11
+ />
12
+ </template>
13
+
14
+ <script lang="ts" setup>
15
+ import { useVuelidate } from '@vuelidate/core';
16
+ import { required } from '@vuelidate/validators';
17
+ import { computed, watch } from 'vue';
18
+ import { useI18n } from 'vue-i18n';
19
+
20
+ import WtSelect from '../../../../../../../components/wt-select/wt-select.vue';
21
+ import { searchMethod } from './config.js';
22
+
23
+ type ModelValue = number[];
24
+
25
+ const model = defineModel<ModelValue>();
26
+
27
+ const emit = defineEmits<{
28
+ 'update:invalid': [boolean];
29
+ }>();
30
+ const { t } = useI18n();
31
+
32
+ const v$ = useVuelidate(
33
+ computed(() => ({
34
+ model: {
35
+ required,
36
+ },
37
+ })),
38
+ { model },
39
+ { $autoDirty: true },
40
+ );
41
+ v$.value.$touch();
42
+
43
+ watch(
44
+ () => v$.value.$invalid,
45
+ (invalid) => {
46
+ emit('update:invalid', invalid);
47
+ },
48
+ { immediate: true },
49
+ );
50
+
51
+ const handleInput = (value: ModelValue) => {
52
+ model.value = value;
53
+ };
54
+ </script>
55
+
56
+ <style lang="scss" scoped></style>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <ul v-if="localValue">
3
+ <li
4
+ v-for="({ name }, index) of localValue"
5
+ :key="index"
6
+ >
7
+ {{ name }}
8
+ </li>
9
+ </ul>
10
+ </template>
11
+
12
+ <script lang="ts" setup>
13
+ import { ref } from 'vue';
14
+
15
+ import { searchMethod } from './config.js';
16
+
17
+ const props = defineProps<{
18
+ value: number[];
19
+ }>();
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
+ </script>
30
+
31
+ <style lang="scss" scoped></style>
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <date-time-filter-value-field
3
+ :model-value="model"
4
+ @update:model-value="model = $event"
5
+ />
6
+ </template>
7
+
8
+ <script lang="ts" setup>
9
+ import DateTimeFilterValueField from '../_shared/date-time-filter/date-time-filter-value-field.vue';
10
+
11
+ type ModelValue = {
12
+ from: number;
13
+ to: number;
14
+ };
15
+ const model = defineModel<ModelValue>();
16
+ </script>
17
+
18
+ <style lang="scss" scoped></style>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <div class="resolution-time-filter-value-preview">
3
+ <div v-if="props.value.from">
4
+ <p class="resolution-time-filter-value-preview__title">
5
+ {{ t('reusable.from') }}
6
+ </p>
7
+
8
+ <span>{{ convertTimestampToDate(props.value.from) }}</span>
9
+ </div>
10
+
11
+ <div v-if="props.value.to">
12
+ <p class="resolution-time-filter-value-preview__title">
13
+ {{ t('reusable.to') }}
14
+ </p>
15
+
16
+ <span>{{ convertTimestampToDate(props.value.to) }}</span>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script lang="ts" setup>
22
+ import { format } from 'date-fns';
23
+ import { useI18n } from 'vue-i18n';
24
+
25
+ const props = defineProps<{
26
+ value: number[];
27
+ }>();
28
+
29
+ const { t } = useI18n();
30
+
31
+ function convertTimestampToDate(value) {
32
+ return format(new Date(value), 'dd.MM.yyyy HH:mm');
33
+ }
34
+ </script>
35
+
36
+ <style lang="scss" scoped>
37
+ @use '@webitel/styleguide/typography' as *;
38
+
39
+ .resolution-time-filter-value-preview {
40
+ &__title {
41
+ @extend %typo-subtitle-1;
42
+ }
43
+ }
44
+ </style>
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <div class="score-from-to-filter-value-field">
3
+ <wt-input
4
+ v-if="model"
5
+ :value="model.from"
6
+ :number-max="props.numberMax"
7
+ :number-min="0"
8
+ :v="v$.model?.from"
9
+ :label="`${t('reusable.from')}:`"
10
+ :placeholder="t('webitelUI.filters.filterValue')"
11
+ class="score-from-to-filter-value-field__input"
12
+ name="score-from-to-filter-value-field-from"
13
+ type="number"
14
+ @input="handleInput('from', $event)"
15
+ />
16
+
17
+ <wt-input
18
+ v-if="model"
19
+ :value="model.to"
20
+ :number-max="props.numberMax"
21
+ :number-min="0"
22
+ :v="v$.model?.to"
23
+ :label="`${t('reusable.to')}:`"
24
+ :placeholder="t('webitelUI.filters.filterValue')"
25
+ class="score-from-to-filter-value-field__input"
26
+ name="score-from-to-filter-value-field-to"
27
+ type="number"
28
+ @input="handleInput('to', $event)"
29
+ />
30
+ </div>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import { useVuelidate } from '@vuelidate/core';
35
+ import { requiredIf } from '@vuelidate/validators';
36
+ import { computed, watch } from 'vue';
37
+ import { useI18n } from 'vue-i18n';
38
+
39
+ type ModelValue = {
40
+ from: number;
41
+ to: number;
42
+ };
43
+ const model = defineModel<ModelValue>();
44
+ if (!model.value) {
45
+ model.value = {
46
+ from: null,
47
+ to: null,
48
+ };
49
+ }
50
+
51
+ const props = withDefaults(
52
+ defineProps<{
53
+ numberMax: number;
54
+ }>(),
55
+ {
56
+ numberMax: 100,
57
+ },
58
+ );
59
+
60
+ const emit = defineEmits<{
61
+ 'update:invalid': [boolean];
62
+ }>();
63
+
64
+ const { t } = useI18n();
65
+
66
+ const v$ = useVuelidate(
67
+ computed(() => ({
68
+ model: {
69
+ from: { required: requiredIf(() => !model.value.to) },
70
+ to: { required: requiredIf(() => !model.value.from) },
71
+ },
72
+ })),
73
+ { model },
74
+ { $autoDirty: true },
75
+ );
76
+ v$.value.$touch();
77
+
78
+ const handleInput = (key: keyof ModelValue, value: number) => {
79
+ const newValue = { ...model.value };
80
+ newValue[key] = value;
81
+ model.value = newValue;
82
+ };
83
+
84
+ watch(
85
+ () => v$.value.$invalid,
86
+ (invalid) => {
87
+ emit('update:invalid', invalid);
88
+ },
89
+ { immediate: true },
90
+ );
91
+ </script>
92
+
93
+ <style lang="scss" scoped>
94
+ .score-from-to-filter-value-field {
95
+ display: grid;
96
+ grid-template-columns: repeat(2, 1fr);
97
+ align-items: center;
98
+ grid-gap: var(--spacing-xs);
99
+ }
100
+ </style>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <div class="score-from-to-filter-value-preview">
3
+ <div v-if="props.value.from">
4
+ <p class="score-from-to-filter-value-preview__title">
5
+ {{ t('reusable.from') }}
6
+ </p>
7
+
8
+ <span>{{ props.value.from }}</span>
9
+ </div>
10
+
11
+ <div v-if="props.value.to">
12
+ <p class="score-from-to-filter-value-preview__title">
13
+ {{ t('reusable.to') }}
14
+ </p>
15
+
16
+ <span>{{ props.value.to }}</span>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script lang="ts" setup>
22
+ import { useI18n } from 'vue-i18n';
23
+
24
+ const props = defineProps<{
25
+ value: number[];
26
+ }>();
27
+
28
+ const { t } = useI18n();
29
+ </script>
30
+
31
+ <style lang="scss" scoped>
32
+ @use '@webitel/styleguide/typography' as *;
33
+
34
+ .score-from-to-filter-value-preview {
35
+ &__title {
36
+ @extend %typo-subtitle-1;
37
+ }
38
+ }
39
+ </style>
@@ -0,0 +1,6 @@
1
+ import ServiceCatalogsAPI from '../../../../../../../api/clients/caseServiceCatalogs/service-catalogs.js';
2
+ import ServicesAPI from '../../../../../../../api/clients/caseServices/services.js';
3
+
4
+ export const searchMethod = ServiceCatalogsAPI.getList;
5
+ export const servicesSearchMethod = ServicesAPI.getList;
6
+ export const localePath = '';
@@ -0,0 +1,82 @@
1
+ <template>
2
+ <wt-tree
3
+ :model-value="model"
4
+ :data="catalogData"
5
+ item-data="id"
6
+ item-label="name"
7
+ children-prop="service"
8
+ class="service-case-filter-value-field"
9
+ multiple
10
+ @update:model-value="model = $event"
11
+ />
12
+ </template>
13
+
14
+ <script lang="ts" setup>
15
+ import deepCopy from 'deep-copy';
16
+ import { onMounted, ref } from 'vue';
17
+
18
+ import WtTree from '../../../../../../../components/wt-tree/wt-tree.vue';
19
+ import { searchMethod } from './config.js';
20
+
21
+ type ModelValue = string[];
22
+ const model = defineModel<ModelValue>({
23
+ default: [],
24
+ });
25
+
26
+ const catalogData = ref([]);
27
+
28
+ const loadCatalogs = async () => {
29
+ const { items } = await searchMethod({
30
+ size: -1, // To get all catalogs with services we need to pass size -1
31
+ fields: ['id', 'name', 'closeReasonGroup', 'status', 'service'],
32
+ hasSubservices: true,
33
+ });
34
+
35
+ catalogData.value = deepCopy(items);
36
+ };
37
+
38
+ if (!model.value) {
39
+ model.value = [];
40
+ }
41
+
42
+ onMounted(loadCatalogs);
43
+ </script>
44
+
45
+ <style lang="scss">
46
+ $form-width: 800px;
47
+
48
+ .service-case-filter-value-field {
49
+ grid-area: value;
50
+ background: transparent;
51
+ height: 100%;
52
+ max-height: 350px;
53
+ overflow-y: auto;
54
+ }
55
+
56
+ .dynamic-filter-config-form {
57
+ &:has(.service-case-filter-value-field) {
58
+ display: grid;
59
+ grid-template-rows: 64px 1fr auto;
60
+ grid-template-columns: repeat(2, 1fr);
61
+ grid-template-areas:
62
+ 'column label'
63
+ 'value value'
64
+ 'footer footer';
65
+ width: $form-width;
66
+ height: 500px;
67
+
68
+ .wt-select {
69
+ grid-area: column;
70
+ height: fit-content;
71
+ }
72
+
73
+ .wt-input {
74
+ grid-area: label;
75
+ }
76
+
77
+ .dynamic-filter-config-form-footer {
78
+ grid-area: footer;
79
+ }
80
+ }
81
+ }
82
+ </style>