@webitel/ui-sdk 24.12.171 → 24.12.173

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 (141) hide show
  1. package/dist/ui-sdk.css +1 -1
  2. package/dist/ui-sdk.js +2630 -2624
  3. package/dist/ui-sdk.umd.cjs +15 -15
  4. package/package.json +7 -4
  5. package/src/api/transformers/index.js +9 -6
  6. package/src/api/transformers/skipIf/skipIf.ts +6 -0
  7. package/src/components/wt-icon-action/iconMappings.js +2 -0
  8. package/src/components/wt-icon-action/wt-icon-action.vue +2 -0
  9. package/src/components/wt-label/_variables.scss +2 -0
  10. package/src/components/wt-label/wt-label.vue +1 -0
  11. package/src/enums/IconAction/IconAction.enum.js +2 -0
  12. package/src/locale/en/en.js +40 -0
  13. package/src/locale/ru/ru.js +40 -1
  14. package/src/locale/ua/ua.js +40 -1
  15. package/src/mixins/validationMixin/useValidation.js +3 -0
  16. package/src/modules/Filters/v2/filter-presets/api/PresetQuery.api.ts +123 -0
  17. package/src/modules/Filters/v2/filter-presets/components/_shared/input-fields/preset-description-field.vue +36 -0
  18. package/src/modules/Filters/v2/filter-presets/components/_shared/input-fields/preset-name-field.vue +31 -0
  19. package/src/modules/Filters/v2/filter-presets/components/_shared/preset-filters-preview.vue +52 -0
  20. package/src/modules/Filters/v2/filter-presets/components/apply-preset/apply-preset-action.vue +226 -0
  21. package/src/modules/Filters/v2/filter-presets/components/apply-preset/preset-preview.vue +197 -0
  22. package/src/modules/Filters/v2/filter-presets/components/save-preset/overwrite-preset-popup.vue +62 -0
  23. package/src/modules/Filters/v2/filter-presets/components/save-preset/save-preset-action.vue +123 -0
  24. package/src/modules/Filters/v2/filter-presets/components/save-preset/save-preset-popup.vue +130 -0
  25. package/src/modules/Filters/v2/filter-presets/index.ts +10 -0
  26. package/src/modules/Filters/v2/filter-presets/stores/createFilterPresetsStore.ts +14 -0
  27. package/src/modules/Filters/v2/filter-presets/stores/headers/headers.ts +24 -0
  28. package/src/modules/Filters/v2/filters/components/dynamic-filter-panel-wrapper.vue +32 -10
  29. package/src/modules/Filters/v2/filters/components/{values → filter-options}/_shared/has-options/has-option-filter-value-field.vue +1 -1
  30. package/src/modules/Filters/v2/filters/components/{values → filter-options}/amd-result/amd-result-filter-value-field.vue +1 -1
  31. package/src/modules/Filters/v2/filters/components/{values → filter-options}/cause/cause-filter-value-field.vue +1 -1
  32. package/src/modules/Filters/v2/filters/components/{values → filter-options}/direction/direction-filter-value-field.vue +1 -1
  33. package/src/modules/Filters/v2/filters/components/{values → filter-options}/has-attachment/has-attachment-filter-value-preview.vue +1 -1
  34. package/src/modules/Filters/v2/filters/components/{values/index.js → filter-options/index.ts} +87 -0
  35. package/src/modules/Filters/v2/filters/components/{values → filter-options}/tag/tag-filter-value-field.vue +1 -1
  36. package/src/modules/Filters/v2/filters/enums/FilterOption.ts +43 -0
  37. package/src/modules/Filters/v2/filters/{components/enums → enums}/amd-result-options.ts +1 -1
  38. package/src/modules/Filters/v2/filters/{components/enums → enums}/boolean-options.ts +1 -1
  39. package/src/modules/Filters/v2/filters/{components/enums → enums}/hangup-cause-options.ts +1 -1
  40. package/src/modules/Filters/v2/filters/{components/enums → enums}/tag-options.ts +1 -1
  41. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/_shared/composables/booleanFilterToolkit.ts +0 -0
  42. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/_shared/composables/useFromToSecToPreviewTime.ts +0 -0
  43. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/_shared/date-time-filter/date-time-filter-value-field.vue +0 -0
  44. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/_shared/durations/duration-filter-value-field.vue +0 -0
  45. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/_shared/types/BooleanFilter.ts +0 -0
  46. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/actual-reaction-time/actual-reaction-time-filter-value-field.vue +0 -0
  47. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/actual-reaction-time/actual-reaction-time-filter-value-preview.vue +0 -0
  48. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/actual-resolution-time/actual-resolution-time-filter-value-field.vue +0 -0
  49. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/actual-resolution-time/actual-resolution-time-filter-value-preview.vue +0 -0
  50. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/agent/agent-filter-value-field.vue +0 -0
  51. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/agent/agent-filter-value-preview.vue +0 -0
  52. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/agent/config.js +0 -0
  53. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/amd-result/amd-result-filter-value-preview.vue +0 -0
  54. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/assignee/assignee-filter-value-field.vue +0 -0
  55. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/assignee/assignee-filter-value-preview.vue +0 -0
  56. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/assignee/config.js +0 -0
  57. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/author/author-filter-value-field.vue +0 -0
  58. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/author/author-filter-value-preview.vue +0 -0
  59. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/author/config.js +0 -0
  60. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/cause/cause-filter-value-preview.vue +0 -0
  61. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/close-reason-groups-case/close-reason-groups-case-filter-value-field.vue +0 -0
  62. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/close-reason-groups-case/close-reason-groups-case-filter-value-preview.vue +0 -0
  63. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/close-reason-groups-case/config.js +0 -0
  64. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/contact/config.js +0 -0
  65. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/contact/contact-filter-value-field.vue +0 -0
  66. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/contact/contact-filter-value-preview.vue +0 -0
  67. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/contact-group/config.js +0 -0
  68. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/contact-group/contact-group-filter-value-field.vue +0 -0
  69. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/contact-group/contact-group-filter-value-preview.vue +0 -0
  70. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/created-at-from/created-at-from-filter-value-field.vue +0 -0
  71. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/created-at-from/created-at-from-filter-value-preview.vue +0 -0
  72. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/created-at-to/created-at-to-filter-value-field.vue +0 -0
  73. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/created-at-to/created-at-to-filter-value-preview.vue +0 -0
  74. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/direction/direction-filter-value-preview.vue +0 -0
  75. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/gateway/config.js +0 -0
  76. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/gateway/gateway-filter-value-field.vue +0 -0
  77. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/gateway/gateway-filter-value-preview.vue +0 -0
  78. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/grantee/config.js +0 -0
  79. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/grantee/grantee-filter-value-field.vue +0 -0
  80. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/grantee/grantee-filter-value-preview.vue +0 -0
  81. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/has-attachment/has-attachment-filter-value-field.vue +0 -0
  82. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/has-file/has-file-filter-value-field.vue +0 -0
  83. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/has-file/has-file-filter-value-preview.vue +0 -0
  84. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/has-rating/has-rating-filter-value-field.vue +0 -0
  85. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/has-rating/has-rating-filter-value-preview.vue +0 -0
  86. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/has-transcription/has-transcription-filter-value-field.vue +0 -0
  87. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/has-transcription/has-transcription-filter-value-preview.vue +0 -0
  88. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/impacted/config.js +0 -0
  89. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/impacted/impacted-filter-value-field.vue +0 -0
  90. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/impacted/impacted-filter-value-preview.vue +0 -0
  91. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/priority-case/config.js +0 -0
  92. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/priority-case/priority-case-filter-value-field.vue +0 -0
  93. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/priority-case/priority-case-filter-value-preview.vue +0 -0
  94. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/queue/config.js +0 -0
  95. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/queue/queue-filter-value-field.vue +0 -0
  96. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/queue/queue-filter-value-preview.vue +0 -0
  97. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/rated-by/config.js +0 -0
  98. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/rated-by/rated-by-filter-value-field.vue +0 -0
  99. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/rated-by/rated-by-filter-value-preview.vue +0 -0
  100. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/rating/rating-from-to-filter-value-field.vue +0 -0
  101. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/rating/rating-from-to-filter-value-preview.vue +0 -0
  102. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/reaction-time/reaction-time-filter-value-field.vue +0 -0
  103. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/reaction-time/reaction-time-filter-value-preview.vue +0 -0
  104. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/reporter/config.js +0 -0
  105. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/reporter/reporter-filter-value-field.vue +0 -0
  106. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/reporter/reporter-filter-value-preview.vue +0 -0
  107. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/resolution-time/resolution-time-filter-value-field.vue +0 -0
  108. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/resolution-time/resolution-time-filter-value-preview.vue +0 -0
  109. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/score/score-from-to-filter-value-field.vue +0 -0
  110. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/score/score-from-to-filter-value-preview.vue +0 -0
  111. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/service-case/config.js +0 -0
  112. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/service-case/service-case-filter-value-field.vue +0 -0
  113. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/service-case/service-case-filter-value-preview.vue +0 -0
  114. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/sla/config.js +0 -0
  115. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/sla/sla-filter-value-field.vue +0 -0
  116. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/sla/sla-filter-value-preview.vue +0 -0
  117. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/sla-condition/config.js +0 -0
  118. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/sla-condition/sla-condition-filter-value-field.vue +0 -0
  119. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/sla-condition/sla-condition-filter-value-preview.vue +0 -0
  120. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/source-case/config.js +0 -0
  121. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/source-case/source-case-filter-value-field.vue +0 -0
  122. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/source-case/source-case-filter-value-preview.vue +0 -0
  123. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/status-case/config.js +0 -0
  124. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/status-case/status-case-filter-value-field.vue +0 -0
  125. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/status-case/status-case-filter-value-preview.vue +0 -0
  126. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/tag/tag-filter-value-preview.vue +0 -0
  127. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/talk-duration/TalkDurationFilter.d.ts +0 -0
  128. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/talk-duration/talk-duration-filter-value-field.vue +0 -0
  129. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/talk-duration/talk-duration-filter-value-preview.vue +0 -0
  130. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/team/config.js +0 -0
  131. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/team/team-filter-value-field.vue +0 -0
  132. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/team/team-filter-value-preview.vue +0 -0
  133. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/total-duration/TotalDurationFilter.d.ts +0 -0
  134. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/total-duration/total-duration-filter-value-field.vue +0 -0
  135. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/total-duration/total-duration-filter-value-preview.vue +0 -0
  136. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/user/config.js +0 -0
  137. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/user/user-filter-value-field.vue +0 -0
  138. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/user/user-filter-value-preview.vue +0 -0
  139. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/variable/variable-filter-value-field.vue +0 -0
  140. /package/src/modules/Filters/v2/filters/components/{values → filter-options}/variable/variable-filter-value-preview.vue +0 -0
  141. /package/src/modules/Filters/v2/filters/{components/enums → enums}/direction-options.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-sdk",
3
- "version": "24.12.171",
3
+ "version": "24.12.173",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -20,7 +20,8 @@
20
20
  "link": "npm link",
21
21
  "update-node": "nvm install --lts && nvm alias default node",
22
22
  "i": "npm install",
23
- "lint:package": "publint"
23
+ "lint:package": "publint",
24
+ "orval": "orval"
24
25
  },
25
26
  "main": "./dist/ui-sdk.js",
26
27
  "type": "module",
@@ -113,11 +114,12 @@
113
114
  "@vuelidate/validators": "^2.0.4",
114
115
  "@vuepic/vue-datepicker": "^4.5.1",
115
116
  "@vueuse/components": "^11.2.0",
116
- "@webitel/styleguide": "^24.12.22",
117
+ "@webitel/styleguide": "^24.12.25",
117
118
  "autosize": "^6.0.1",
118
119
  "axios": "^1.7.7",
119
120
  "clipboard-copy": "^4.0.1",
120
121
  "csv-stringify": "^5.5.3",
122
+ "date-fns": "^4.1.0",
121
123
  "deep-copy": "^1.4.2",
122
124
  "deep-equal": "^2.2.3",
123
125
  "deepmerge": "^4.3.1",
@@ -138,7 +140,7 @@
138
140
  "vue-router": "^4.4.5",
139
141
  "webitel-sdk": "^24.10.29",
140
142
  "xlsx": "^0.18.5",
141
- "date-fns": "^4.1.0"
143
+ "zod": "^3.24.2"
142
144
  },
143
145
  "devDependencies": {
144
146
  "@eslint/js": "^9.17.0",
@@ -159,6 +161,7 @@
159
161
  "happy-dom": "^15.11.6",
160
162
  "markdown-it": "^14.1.0",
161
163
  "markdown-table": "^3.0.4",
164
+ "orval": "^7.6.0",
162
165
  "path": "^0.12.7",
163
166
  "pinia": "^2.3.0",
164
167
  "postcss": "^8.4.49",
@@ -8,16 +8,19 @@ import notify from './notify/notify.transformer.js';
8
8
  import sanitize from './sanitize/sanitize.transformer.js';
9
9
  import snakeToCamel from './snakeToCamel/snakeToCamel.transformer.js';
10
10
  import starToSearch from './starToSearch/starToSearch.transformer.js';
11
+ import { skipIf } from './skipIf/skipIf';
11
12
 
12
- export default applyTransform;
13
13
  export {
14
+ camelToSnake,
15
+ generateUrl,
14
16
  log,
15
17
  merge,
18
+ mergeEach,
16
19
  notify,
17
- starToSearch,
18
- camelToSnake,
19
- snakeToCamel,
20
20
  sanitize,
21
- generateUrl,
22
- mergeEach,
21
+ skipIf,
22
+ snakeToCamel,
23
+ starToSearch,
23
24
  };
25
+
26
+ export default applyTransform;
@@ -0,0 +1,6 @@
1
+ export const skipIf = (transformer: (...payload: unknown[]) => unknown, ifFn: boolean | ((...payload: unknown[]) => boolean)) => (payload: unknown) => {
2
+ if (typeof ifFn === 'function' ? ifFn(payload) : ifFn) {
3
+ return payload;
4
+ }
5
+ return transformer(payload);
6
+ };
@@ -17,4 +17,6 @@ export const WtIconActionIconMappings = Object.freeze({
17
17
  [IconAction.CLEAR]: 'clear',
18
18
  [IconAction.ADD_FILTER]: 'add-filter',
19
19
  [IconAction.SAVE]: 'save',
20
+ [IconAction.SAVE_PRESET]: 'save',
21
+ [IconAction.APPLY_PRESET]: 'load-preset',
20
22
  });
@@ -36,6 +36,8 @@ const props = defineProps({
36
36
  IconAction.REFRESH,
37
37
  IconAction.SAVE,
38
38
  IconAction.CANCEL,
39
+ IconAction.SAVE_PRESET,
40
+ IconAction.APPLY_PRESET,
39
41
  ]).includes(v),
40
42
  },
41
43
  disabled: {
@@ -1,4 +1,6 @@
1
1
  :root {
2
+ --wt-label-padding: var(--spacing-2xs) var(--spacing-xs);
3
+
2
4
  --wt-label-color: var(--text-main-color);
3
5
  --wt-label-error-color: var(--text-error-color);
4
6
  --wt-label-disabled-color: var(--text-disabled-color);
@@ -46,6 +46,7 @@ export default {
46
46
  cursor: text;
47
47
  transition: var(--transition);
48
48
  color: var(--wt-label-color);
49
+ //padding: var(--wt-label-padding);
49
50
 
50
51
  &--invalid {
51
52
  color: var(--wt-label-error-color);
@@ -18,6 +18,8 @@ const IconAction = Object.freeze({
18
18
  CLEAR: 'clear',
19
19
  ADD_FILTER: 'add-filter',
20
20
  SAVE: 'save',
21
+ SAVE_PRESET: 'save-preset',
22
+ APPLY_PRESET: 'apply-preset',
21
23
  });
22
24
 
23
25
  export default IconAction;
@@ -20,6 +20,7 @@ import { snakeToCamel } from '../../scripts/caseConverters.js';
20
20
  export default {
21
21
  // describes reusable buttons, actions, default titles, and other ui elements
22
22
  reusable: {
23
+ replace: 'Replace',
23
24
  download: 'Download',
24
25
  history: 'History',
25
26
  filter: ({ plural }) => plural(['Filter', 'Filters']),
@@ -347,6 +348,7 @@ export default {
347
348
  latinWithNumber:
348
349
  'The code must contain only letters (A-Z, a-z) and numbers (0-9), and must start with a letter',
349
350
  integer: 'The field should contain only whole numbers',
351
+ nameAlreadyInUse: 'This name is already in use',
350
352
  },
351
353
  webitelUI: {
352
354
  searchBar: {
@@ -420,6 +422,12 @@ export default {
420
422
  [IconAction.ADD_FILTER]: ({ linked }) => linked('reusable.add'),
421
423
  [IconAction.SAVE]: ({ linked }) => linked('reusable.save'),
422
424
  [IconAction.CANCEL]: ({ linked }) => linked('reusable.cancel'),
425
+ [IconAction.SAVE_PRESET]: ({ linked }) => {
426
+ return `${linked('reusable.save')} ${linked('webitelUI.filters.presets.preset').toLowerCase()}`;
427
+ },
428
+ [IconAction.APPLY_PRESET]: ({ linked }) => {
429
+ return `${linked('vocabulary.apply')} ${linked('webitelUI.filters.presets.preset').toLowerCase()}`;
430
+ },
423
431
  },
424
432
  },
425
433
  errorPages: {
@@ -624,6 +632,38 @@ export default {
624
632
  variable: ({ linked }) => {
625
633
  return linked('vocabulary.variables');
626
634
  },
635
+ presets: {
636
+ preset: 'Preset | Presets',
637
+ overwritePresetTitle: 'A preset with this name already exists.',
638
+ overwritePresetText: 'Do you want to replace it?',
639
+ notifications: {
640
+ success: {
641
+ /* suka ebuchij linked(,param) ne praciuje */
642
+ update: ({ linked }) => {
643
+ return linked('systemNotifications.success.update', {
644
+ entity: linked('filters.presets.preset'),
645
+ });
646
+ },
647
+ create: ({ linked }) => {
648
+ return linked('systemNotifications.success.create', {
649
+ entity: linked('filters.presets.preset'),
650
+ });
651
+ },
652
+ delete: ({ linked }) => {
653
+ return linked('systemNotifications.success.delete', {
654
+ entity: linked('filters.presets.preset'),
655
+ });
656
+ },
657
+ },
658
+ },
659
+ },
660
+ },
661
+ },
662
+ systemNotifications: {
663
+ success: {
664
+ update: ({ named }) => `The ${named('entity').toLowerCase()} was updated`,
665
+ create: ({ named }) => `The ${named('entity').toLowerCase()} was saved`,
666
+ delete: ({ named }) => `The ${named('entity').toLowerCase()} was deleted`,
627
667
  },
628
668
  },
629
669
  errorNotifications: {
@@ -20,6 +20,7 @@ import { snakeToCamel } from '../../scripts/caseConverters.js';
20
20
  export default {
21
21
  // describes reusable buttons, actions, default titles, and other ui elements
22
22
  reusable: {
23
+ replace: 'Заменить',
23
24
  download: 'Скачать',
24
25
  history: 'История',
25
26
  filter: 'Фильтр | Фильтры',
@@ -345,6 +346,7 @@ export default {
345
346
  latinWithNumber:
346
347
  'Код должен содержать только буквы (A-Z, a-z) и цифры (0-9) и начинатся с буквы',
347
348
  integer: 'Поле должно содержать только целые числа',
349
+ nameAlreadyInUse: 'Это название уже используется',
348
350
  },
349
351
  webitelUI: {
350
352
  searchBar: {
@@ -418,6 +420,12 @@ export default {
418
420
  [IconAction.ADD_FILTER]: ({ linked }) => linked('reusable.add'),
419
421
  [IconAction.SAVE]: ({ linked }) => linked('reusable.save'),
420
422
  [IconAction.CANCEL]: ({ linked }) => linked('reusable.cancel'),
423
+ [IconAction.SAVE_PRESET]: ({ linked }) => {
424
+ return `${linked('reusable.save')} ${linked('webitelUI.filters.presets.preset').toLowerCase()}`;
425
+ },
426
+ [IconAction.APPLY_PRESET]: ({ linked }) => {
427
+ return `${linked('vocabulary.apply')} ${linked('webitelUI.filters.presets.preset').toLowerCase()}`;
428
+ },
421
429
  },
422
430
  },
423
431
  errorPages: {
@@ -460,7 +468,7 @@ export default {
460
468
  },
461
469
  empty: {
462
470
  text: {
463
- empty: 'Записи в разделе еще не созданы',
471
+ empty: 'Записи еще не созданы',
464
472
  filters: 'К сожалению, ни одна запись не соответствует вашим критериям',
465
473
  },
466
474
  },
@@ -621,6 +629,37 @@ export default {
621
629
  variable: ({ linked }) => {
622
630
  return linked('vocabulary.variables');
623
631
  },
632
+ presets: {
633
+ preset: 'Пресет | Пресеты',
634
+ overwritePresetTitle: 'Пресет с таким названием уже существует.',
635
+ overwritePresetText: 'Хотите его заменить?',
636
+ notifications: {
637
+ success: {
638
+ update: ({ linked }) => {
639
+ return linked('systemNotifications.success.update', {
640
+ entity: linked('filters.presets.preset'),
641
+ });
642
+ },
643
+ create: ({ linked }) => {
644
+ return linked('systemNotifications.success.create', {
645
+ entity: linked('filters.presets.preset'),
646
+ });
647
+ },
648
+ delete: ({ linked }) => {
649
+ return linked('systemNotifications.success.delete', {
650
+ entity: linked('filters.presets.preset'),
651
+ });
652
+ },
653
+ },
654
+ },
655
+ },
656
+ },
657
+ },
658
+ systemNotifications: {
659
+ success: {
660
+ update: ({ named }) => `${named('entity')} был обновлён`,
661
+ create: ({ named }) => `${named('entity')} был сохранён`,
662
+ delete: ({ named }) => `${named('entity')} был удалён`,
624
663
  },
625
664
  },
626
665
  errorNotifications: {
@@ -20,6 +20,7 @@ import { snakeToCamel } from '../../scripts/caseConverters.js';
20
20
  export default {
21
21
  // describes reusable buttons, actions, default titles, and other ui elements
22
22
  reusable: {
23
+ replace: 'Замінити',
23
24
  download: 'Завантажити',
24
25
  history: 'Історія',
25
26
  filter: 'Фільтр | Фільтри',
@@ -345,6 +346,7 @@ export default {
345
346
  latinWithNumber:
346
347
  'Код повинен містити лише літери (A-Z, a-z) та цифри (0-9) і починатися з літери',
347
348
  integer: 'Поле повинно містити лише цілі числа',
349
+ nameAlreadyInUse: 'Така назва вже використовується',
348
350
  },
349
351
  webitelUI: {
350
352
  searchBar: {
@@ -418,6 +420,12 @@ export default {
418
420
  [IconAction.ADD_FILTER]: ({ linked }) => linked('reusable.add'),
419
421
  [IconAction.SAVE]: ({ linked }) => linked('reusable.save'),
420
422
  [IconAction.CANCEL]: ({ linked }) => linked('reusable.cancel'),
423
+ [IconAction.SAVE_PRESET]: ({ linked }) => {
424
+ return `${linked('reusable.save')} ${linked('webitelUI.filters.presets.preset').toLowerCase()}`;
425
+ },
426
+ [IconAction.APPLY_PRESET]: ({ linked }) => {
427
+ return `${linked('vocabulary.apply')} ${linked('webitelUI.filters.presets.preset').toLowerCase()}`;
428
+ },
421
429
  },
422
430
  },
423
431
  errorPages: {
@@ -460,7 +468,7 @@ export default {
460
468
  },
461
469
  empty: {
462
470
  text: {
463
- empty: 'Записи у розділі ще не створені',
471
+ empty: 'Записи ще не створені',
464
472
  filters: 'На жаль, жоден запис не відповідає вашим критеріям',
465
473
  },
466
474
  },
@@ -621,6 +629,37 @@ export default {
621
629
  variable: ({ linked }) => {
622
630
  return linked('vocabulary.variables');
623
631
  },
632
+ presets: {
633
+ preset: 'Пресет | Пресети',
634
+ overwritePresetTitle: 'Пресет з такою назвою вже існує.',
635
+ overwritePresetText: 'Бажаєте його замінити?',
636
+ notifications: {
637
+ success: {
638
+ update: ({ linked }) => {
639
+ return linked('systemNotifications.success.update', {
640
+ entity: linked('filters.presets.preset'),
641
+ });
642
+ },
643
+ create: ({ linked }) => {
644
+ return linked('systemNotifications.success.create', {
645
+ entity: linked('filters.presets.preset'),
646
+ });
647
+ },
648
+ delete: ({ linked }) => {
649
+ return linked('systemNotifications.success.delete', {
650
+ entity: linked('filters.presets.preset'),
651
+ });
652
+ },
653
+ },
654
+ },
655
+ },
656
+ },
657
+ },
658
+ systemNotifications: {
659
+ success: {
660
+ update: ({ named }) => `${named('entity')} було оновлено`,
661
+ create: ({ named }) => `${named('entity')} було збережено`,
662
+ delete: ({ named }) => `${named('entity')} було видалено`,
624
663
  },
625
664
  },
626
665
  errorNotifications: {
@@ -62,6 +62,9 @@ export function useValidation({
62
62
  validationText =
63
63
  v.value.regex?.$message ||
64
64
  `${t('validation.isRegExpMatched')} ${v.value.regex?.$params?.regex}`;
65
+ else if (v.value.nameAlreadyInUse.$invalid) {
66
+ validationText = t('validation.nameAlreadyInUse');
67
+ }
65
68
  }
66
69
 
67
70
  if (customValidators?.value) {
@@ -0,0 +1,123 @@
1
+ import {
2
+ EngineCreatePresetQueryRequest,
3
+ EnginePresetQuery,
4
+ PresetQueryServiceApiFactory,
5
+ } from 'webitel-sdk';
6
+
7
+ import {
8
+ getDefaultGetListResponse,
9
+ getDefaultGetParams,
10
+ getDefaultInstance,
11
+ getDefaultOpenAPIConfig,
12
+ } from '../../../../../api/defaults/index';
13
+ import applyTransform, {
14
+ camelToSnake,
15
+ merge,
16
+ notify,
17
+ skipIf,
18
+ snakeToCamel,
19
+ starToSearch,
20
+ } from '../../../../../api/transformers/index';
21
+
22
+ const instance = getDefaultInstance();
23
+ const configuration = getDefaultOpenAPIConfig();
24
+
25
+ const service = PresetQueryServiceApiFactory(configuration, '', instance);
26
+
27
+ type GetPresetListRequestConfig = {
28
+ transformers: {
29
+ useStarToSearch?: boolean;
30
+ };
31
+ };
32
+
33
+ const getPresetList = async (params, config: GetPresetListRequestConfig) => {
34
+ const useStarToSearch = config?.transformers?.useStarToSearch ?? true;
35
+
36
+ const { page, size, search, sort, fields, presetNamespace, id } =
37
+ applyTransform(params, [
38
+ merge(getDefaultGetParams()),
39
+ (params) => (useStarToSearch ? starToSearch('search')(params) : params),
40
+ ]);
41
+
42
+ try {
43
+ const response = await service.searchPresetQuery(
44
+ page,
45
+ size,
46
+ search,
47
+ sort || '-created_at',
48
+ fields || ['id', 'name', 'preset', 'description'],
49
+ id,
50
+ );
51
+ const { items, next } = applyTransform(response.data, [
52
+ snakeToCamel(),
53
+ merge(getDefaultGetListResponse()),
54
+ ]);
55
+ return {
56
+ items: applyTransform(items, [
57
+ (items) =>
58
+ items.filter(({ preset }) => preset.namespace === presetNamespace),
59
+ ]),
60
+ next,
61
+ };
62
+ } catch (err) {
63
+ throw applyTransform(err, [notify]);
64
+ }
65
+ };
66
+
67
+ const addPreset = async ({
68
+ preset,
69
+ namespace,
70
+ }: {
71
+ preset: EngineCreatePresetQueryRequest;
72
+ namespace: string;
73
+ }): Promise<EnginePresetQuery> => {
74
+ const item = applyTransform(preset, [
75
+ camelToSnake(),
76
+ (item) => {
77
+ item.preset.namespace = namespace;
78
+ return item;
79
+ },
80
+ ]);
81
+ try {
82
+ const response = await service.createPresetQuery(item);
83
+ return applyTransform(response.data, [snakeToCamel()]);
84
+ } catch (err) {
85
+ throw applyTransform(err, [skipIf(notify, (err) => err.status === 409)]);
86
+ }
87
+ };
88
+
89
+ const updatePreset = async ({ item: itemInstance, id, namespace }) => {
90
+ const item = applyTransform(itemInstance, [
91
+ camelToSnake(),
92
+ (item) => {
93
+ item.preset.namespace = namespace;
94
+ return item;
95
+ },
96
+ ]);
97
+ try {
98
+ const response = await service.updatePresetQuery(id, item);
99
+ return applyTransform(response.data, [snakeToCamel()]);
100
+ } catch (err) {
101
+ throw applyTransform(err, [skipIf(notify, (err) => err.status === 409)]);
102
+ }
103
+ };
104
+
105
+ const deletePreset = async ({ id }) => {
106
+ try {
107
+ const response = await service.deletePresetQuery(id);
108
+ return applyTransform(response.data, []);
109
+ } catch (err) {
110
+ throw applyTransform(err, [notify]);
111
+ }
112
+ };
113
+
114
+ const PresetQueryAPI = {
115
+ getList: getPresetList,
116
+ add: addPreset,
117
+ update: updatePreset,
118
+ delete: deletePreset,
119
+ };
120
+
121
+ export { addPreset, deletePreset, getPresetList, updatePreset };
122
+
123
+ export default PresetQueryAPI;
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <div
3
+ v-if="props.previewMode && model"
4
+ >
5
+ <wt-label>
6
+ {{ t('vocabulary.description') }}
7
+ </wt-label>
8
+ <p>
9
+ {{ model }}
10
+ </p>
11
+ </div>
12
+
13
+ <wt-textarea
14
+ v-if="!props.previewMode"
15
+ :value="model"
16
+ :label="t('vocabulary.description')"
17
+ @input="model = $event"
18
+ />
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import {useI18n} from "vue-i18n";
23
+ import { WtTextarea, WtLabel } from '../../../../../../../components/index';
24
+
25
+ const model = defineModel<string>();
26
+
27
+ const props = defineProps<{
28
+ previewMode?: boolean;
29
+ }>();
30
+
31
+ const { t } = useI18n();
32
+ </script>
33
+
34
+ <style scoped lang="scss">
35
+
36
+ </style>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <wt-input
3
+ v-model="model"
4
+ :v="props.v"
5
+ :label="t('reusable.name')"
6
+ required
7
+ />
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import {useI18n} from "vue-i18n";
12
+ import {Validation} from '@vuelidate/core';
13
+ import { WtInput } from '../../../../../../../components/index';
14
+
15
+ type ModelValue = string;
16
+
17
+ const model = defineModel<ModelValue>();
18
+
19
+ type Props = {
20
+ v: Validation;
21
+ };
22
+
23
+ const props = defineProps<Props>();
24
+
25
+ const { t } = useI18n();
26
+
27
+ </script>
28
+
29
+ <style scoped lang="scss">
30
+
31
+ </style>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div class="save-preset-filters-preview">
3
+ <wt-label>
4
+ {{ t('webitelUI.filters.filterName') }}
5
+ </wt-label>
6
+ <dynamic-filter-panel-wrapper
7
+ size="sm"
8
+ >
9
+ <template #filters>
10
+ <dynamic-filter-preview
11
+ v-for="(filter) of props.filters"
12
+ :key="filter.name"
13
+ :filter="filter"
14
+ dummy
15
+ >
16
+ <template #info>
17
+ <component
18
+ :is="FilterOptionToPreviewComponentMap[filter.name]"
19
+ :value="filter.value"
20
+ >
21
+ </component>
22
+ </template>
23
+ </dynamic-filter-preview>
24
+ </template>
25
+ </dynamic-filter-panel-wrapper>
26
+ </div>
27
+
28
+ </template>
29
+
30
+ <script setup lang="ts">
31
+ import {useI18n} from "vue-i18n";
32
+
33
+ import { WtLabel } from '../../../../../../components/index';
34
+ import type {IFilter} from "../../../filters";
35
+ import DynamicFilterPanelWrapper
36
+ from "../../../filters/components/dynamic-filter-panel-wrapper.vue";
37
+ import { FilterOptionToPreviewComponentMap} from "../../../filters/components/filter-options";
38
+ import DynamicFilterPreview
39
+ from "../../../filters/components/preview/dynamic-filter-preview.vue";
40
+
41
+ type Props = {
42
+ filters: IFilter[];
43
+ };
44
+
45
+ const props = defineProps<Props>();
46
+
47
+ const { t } = useI18n();
48
+
49
+ </script>
50
+
51
+ <style scoped lang="scss">
52
+ </style>