@webitel/ui-datalist 1.1.46 → 1.1.48

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 (117) hide show
  1. package/package.json +2 -1
  2. package/src/modules/_shared/createDatalistStore.ts +5 -1
  3. package/src/modules/card/composables/useCardComponent.ts +0 -1
  4. package/src/modules/card/composables/useCardValidation.ts +1 -1
  5. package/src/modules/card/stores/createCardStore.ts +7 -1
  6. package/src/modules/filter-presets/api/PresetQuery.ts +1 -1
  7. package/src/modules/filter-presets/components/_shared/input-fields/preset-name-field.vue +1 -2
  8. package/src/modules/filter-presets/components/apply-preset/apply-preset-action.vue +7 -6
  9. package/src/modules/filter-presets/components/save-preset/save-preset-action.vue +5 -4
  10. package/src/modules/filter-presets/components/save-preset/save-preset-popup.vue +0 -4
  11. package/src/modules/filter-presets/stores/createFilterPresetsStore.ts +7 -1
  12. package/src/modules/filter-presets/stores/headers/headers.ts +2 -2
  13. package/src/modules/filters/classes/FiltersManager.ts +5 -2
  14. package/src/modules/filters/components/config/dynamic-view/dynamic-filter-config-form.vue +20 -1
  15. package/src/modules/filters/components/config/dynamic-view/dynamic-filter-config-view.vue +1 -1
  16. package/src/modules/filters/components/dynamic-filter-add-action.vue +4 -2
  17. package/src/modules/filters/components/preview/dynamic-filter-preview.vue +11 -8
  18. package/src/modules/filters/components/search-bar/dynamic-filter-search.vue +3 -1
  19. package/src/modules/filters/components/table-filters-panel.vue +2 -2
  20. package/src/modules/filters/composables/useFilterConfigsToolkit.ts +7 -2
  21. package/src/modules/filters/createTableFiltersStore.ts +3 -2
  22. package/src/modules/filters/modules/filterConfig/classes/FilterConfig.ts +39 -8
  23. package/src/modules/filters/modules/filterConfig/classes/createFilterConfig.ts +1 -1
  24. package/src/modules/filters/modules/filterConfig/components/_custom/filterConfig.ts +7 -8
  25. package/src/modules/filters/modules/filterConfig/components/_custom/type-extension-filter-value-field.vue +27 -10
  26. package/src/modules/filters/modules/filterConfig/components/_custom/type-extension-filter-value-preview.vue +21 -5
  27. package/src/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-filter-value-field.vue +46 -1
  28. package/src/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-options/date-time-options-filter-value-field.vue +59 -3
  29. package/src/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-options/date-time-options-filter-value-preview.vue +13 -7
  30. package/src/modules/filters/modules/filterConfig/components/_shared/durations/duration-filter-value-field.vue +16 -3
  31. package/src/modules/filters/modules/filterConfig/components/_shared/lookup-filter-preview/lookup-filter-value-preview.vue +14 -6
  32. package/src/modules/filters/modules/filterConfig/components/case-actual-reaction-time/case-actual-reaction-time-filter-value-preview.vue +4 -1
  33. package/src/modules/filters/modules/filterConfig/components/case-actual-resolution-time/case-actual-resolution-time-filter-value-preview.vue +4 -1
  34. package/src/modules/filters/modules/filterConfig/components/case-assignee/case-assignee-filter-value-field.vue +16 -3
  35. package/src/modules/filters/modules/filterConfig/components/case-assignee/case-assignee-filter-value-preview.vue +7 -3
  36. package/src/modules/filters/modules/filterConfig/components/case-assignee/filterConfig.ts +9 -5
  37. package/src/modules/filters/modules/filterConfig/components/case-close-reason-groups/case-close-reason-groups-filter-value-field.vue +16 -3
  38. package/src/modules/filters/modules/filterConfig/components/case-close-reason-groups/case-close-reason-groups-filter-value-preview.vue +2 -2
  39. package/src/modules/filters/modules/filterConfig/components/case-priority/case-priority-filter-value-preview.vue +2 -2
  40. package/src/modules/filters/modules/filterConfig/components/case-reaction-time/case-reaction-time-filter-value-preview.vue +4 -1
  41. package/src/modules/filters/modules/filterConfig/components/case-resolution-time/case-resolution-time-filter-value-preview.vue +4 -1
  42. package/src/modules/filters/modules/filterConfig/components/case-service/case-service-filter-value-field.vue +1 -1
  43. package/src/modules/filters/modules/filterConfig/components/case-service/case-service-filter-value-preview.vue +2 -2
  44. package/src/modules/filters/modules/filterConfig/components/case-sla/case-sla-filter-value-preview.vue +2 -2
  45. package/src/modules/filters/modules/filterConfig/components/case-sla-condition/case-sla-condition-filter-value-field.vue +16 -3
  46. package/src/modules/filters/modules/filterConfig/components/case-sla-condition/case-sla-condition-filter-value-preview.vue +2 -2
  47. package/src/modules/filters/modules/filterConfig/components/case-source/case-source-filter-value-preview.vue +2 -2
  48. package/src/modules/filters/modules/filterConfig/components/case-status/case-status-filter-value-field.vue +16 -3
  49. package/src/modules/filters/modules/filterConfig/components/case-status/case-status-filter-value-preview.vue +2 -2
  50. package/src/modules/filters/modules/filterConfig/components/contact-group/contact-group-filter-value-field.vue +19 -6
  51. package/src/modules/filters/modules/filterConfig/components/contact-group/contact-group-filter-value-preview.vue +7 -3
  52. package/src/modules/filters/modules/filterConfig/components/contact-group/index.ts +6 -3
  53. package/src/modules/filters/modules/filterConfig/components/contact-label/index.ts +14 -5
  54. package/src/modules/filters/modules/filterConfig/components/has-attachment/has-attachment-filter-value-field.vue +1 -1
  55. package/src/modules/filters/modules/filterConfig/components/index.ts +58 -57
  56. package/src/modules/filters/modules/filterConfig/components/rating/rating-from-to-filter-value-field.vue +16 -3
  57. package/src/modules/filters/modules/filterConfig/components/rating/rating-from-to-filter-value-preview.vue +4 -1
  58. package/src/modules/filters/modules/filterConfig/components/score/score-from-to-filter-value-field.vue +16 -3
  59. package/src/modules/filters/modules/filterConfig/components/score/score-from-to-filter-value-preview.vue +4 -1
  60. package/src/modules/filters/modules/filterConfig/components/tag/tag-filter-value-preview.vue +1 -1
  61. package/src/modules/filters/modules/filterConfig/components/utilization-progress/utilization-progress-filter-value-preview.vue +3 -1
  62. package/src/modules/filters/modules/filterConfig/components/variable/variable-filter-value-field.vue +2 -2
  63. package/src/modules/filters/modules/filterConfig/composables/useQueueTypeOptions.ts +2 -2
  64. package/src/modules/filters/modules/filterConfig/types/DynamicFilterPreviewComponent.ts +2 -2
  65. package/src/modules/headers/createTableHeadersStore.ts +9 -6
  66. package/src/modules/pagination/createTablePaginationStore.ts +2 -1
  67. package/src/modules/table/createTableStore.store.ts +3 -12
  68. package/src/modules/types/createDatalistStore.types.ts +1 -1
  69. package/src/modules/types/tableStore.types.ts +12 -2
  70. package/types/modules/card/composables/useCardComponent.d.ts +3 -3
  71. package/types/modules/card/composables/useCardValidation.d.ts +1 -1
  72. package/types/modules/card/composables/useNestedCardComponent.d.ts +3 -3
  73. package/types/modules/card/stores/createCardStore.d.ts +5 -1
  74. package/types/modules/filter-presets/api/PresetQuery.d.ts +2 -2
  75. package/types/modules/filter-presets/components/_shared/input-fields/preset-name-field.vue.d.ts +1 -2
  76. package/types/modules/filter-presets/components/apply-preset/apply-preset-action.vue.d.ts +2 -2
  77. package/types/modules/filter-presets/stores/createFilterPresetsStore.d.ts +90 -16
  78. package/types/modules/filter-presets/stores/headers/headers.d.ts +2 -2
  79. package/types/modules/filters/classes/FiltersManager.d.ts +7 -2
  80. package/types/modules/filters/components/preview/dynamic-filter-preview.vue.d.ts +2 -3
  81. package/types/modules/filters/components/table-filters-panel.vue.d.ts +2 -2
  82. package/types/modules/filters/composables/useFilterConfigsToolkit.d.ts +6 -2
  83. package/types/modules/filters/createTableFiltersStore.d.ts +17 -6
  84. package/types/modules/filters/modules/filterConfig/classes/FilterConfig.d.ts +33 -8
  85. package/types/modules/filters/modules/filterConfig/classes/createFilterConfig.d.ts +1 -1
  86. package/types/modules/filters/modules/filterConfig/components/_custom/filterConfig.d.ts +3 -3
  87. package/types/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-filter-value-field.vue.d.ts +2 -0
  88. package/types/modules/filters/modules/filterConfig/components/_shared/date-time-filter/date-time-options/date-time-options-filter-value-field.vue.d.ts +2 -0
  89. package/types/modules/filters/modules/filterConfig/components/_shared/lookup-filter-preview/lookup-filter-value-preview.vue.d.ts +1 -4
  90. package/types/modules/filters/modules/filterConfig/components/case-actual-reaction-time/case-actual-reaction-time-filter-value-preview.vue.d.ts +4 -1
  91. package/types/modules/filters/modules/filterConfig/components/case-actual-resolution-time/case-actual-resolution-time-filter-value-preview.vue.d.ts +4 -1
  92. package/types/modules/filters/modules/filterConfig/components/case-assignee/case-assignee-filter-value-preview.vue.d.ts +4 -2
  93. package/types/modules/filters/modules/filterConfig/components/case-assignee/filterConfig.d.ts +10 -5
  94. package/types/modules/filters/modules/filterConfig/components/case-close-reason-groups/case-close-reason-groups-filter-value-preview.vue.d.ts +2 -2
  95. package/types/modules/filters/modules/filterConfig/components/case-priority/case-priority-filter-value-preview.vue.d.ts +2 -2
  96. package/types/modules/filters/modules/filterConfig/components/case-reaction-time/case-reaction-time-filter-value-preview.vue.d.ts +4 -1
  97. package/types/modules/filters/modules/filterConfig/components/case-resolution-time/case-resolution-time-filter-value-preview.vue.d.ts +4 -1
  98. package/types/modules/filters/modules/filterConfig/components/case-service/case-service-filter-value-preview.vue.d.ts +2 -2
  99. package/types/modules/filters/modules/filterConfig/components/case-sla/case-sla-filter-value-preview.vue.d.ts +2 -2
  100. package/types/modules/filters/modules/filterConfig/components/case-sla-condition/case-sla-condition-filter-value-preview.vue.d.ts +2 -2
  101. package/types/modules/filters/modules/filterConfig/components/case-source/case-source-filter-value-preview.vue.d.ts +2 -2
  102. package/types/modules/filters/modules/filterConfig/components/case-status/case-status-filter-value-preview.vue.d.ts +2 -2
  103. package/types/modules/filters/modules/filterConfig/components/contact-group/contact-group-filter-value-field.vue.d.ts +2 -2
  104. package/types/modules/filters/modules/filterConfig/components/contact-group/contact-group-filter-value-preview.vue.d.ts +4 -2
  105. package/types/modules/filters/modules/filterConfig/components/contact-group/index.d.ts +19 -14
  106. package/types/modules/filters/modules/filterConfig/components/contact-label/index.d.ts +4 -2
  107. package/types/modules/filters/modules/filterConfig/components/has-attachment/has-attachment-filter-value-field.vue.d.ts +3 -3
  108. package/types/modules/filters/modules/filterConfig/components/index.d.ts +50 -39
  109. package/types/modules/filters/modules/filterConfig/components/rating/rating-from-to-filter-value-preview.vue.d.ts +4 -1
  110. package/types/modules/filters/modules/filterConfig/components/score/score-from-to-filter-value-preview.vue.d.ts +4 -1
  111. package/types/modules/filters/modules/filterConfig/components/utilization-progress/utilization-progress-filter-value-preview.vue.d.ts +3 -1
  112. package/types/modules/filters/modules/filterConfig/types/DynamicFilterPreviewComponent.d.ts +2 -2
  113. package/types/modules/headers/createTableHeadersStore.d.ts +66 -12
  114. package/types/modules/pagination/createTablePaginationStore.d.ts +2 -1
  115. package/types/modules/table/createTableStore.store.d.ts +93 -24
  116. package/types/modules/types/createDatalistStore.types.d.ts +1 -1
  117. package/types/modules/types/tableStore.types.d.ts +11 -2
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@webitel/ui-datalist",
3
- "version": "1.1.46",
3
+ "version": "1.1.48",
4
4
  "description": "Toolkit for building data lists in webitel ui system",
5
5
  "scripts": {
6
6
  "build:types": "vue-tsc -p ./tsconfig.build.json",
7
+ "typecheck": "vue-tsc --noEmit -p ./tsconfig.typecheck.json",
7
8
  "lint:fix": "npx biome check --write ./src",
8
9
  "biome:ci:gh": "biome ci ./src --reporter=github",
9
10
  "test:unit": "node -e \"process.exit(0)\"",
@@ -61,12 +61,16 @@ export const createDatalistStore = <
61
61
  }
62
62
 
63
63
  if (thisStoreType === DatalistStoreProvider.Pinia) {
64
+ // TODO(types): a Pinia StoreDefinition is a valid store factory (callable,
65
+ // returns a store exposing `$patch`), but its generic-extracted shape does
66
+ // not structurally match PatchableStoreFactory. Reconcile the two factory
67
+ // types instead of asserting here.
64
68
  return definePiniaStore(namespace, () =>
65
69
  storeBody({
66
70
  ...config,
67
71
  storeType: thisStoreType,
68
72
  }),
69
- );
73
+ ) as PatchableStoreFactory<StoreBody>;
70
74
  }
71
75
 
72
76
  throw new Error(`Unsupported store type: ${thisStoreType}`);
@@ -60,7 +60,6 @@ export const useCardComponent = <CardEntity>({
60
60
  });
61
61
 
62
62
  const { save } = useCardSaveAction<CardEntity>({
63
- // @ts-expect-error
64
63
  validate, // fixme: type
65
64
  saveItem,
66
65
  });
@@ -1,7 +1,7 @@
1
1
  import type { RegleSchema } from '@regle/schemas';
2
2
  import { computed, type Ref } from 'vue';
3
3
 
4
- export const useCardValidation = <TState, TSchema>({
4
+ export const useCardValidation = <TState, TSchema = {}>({
5
5
  validationSchema,
6
6
  }: {
7
7
  validationSchema: Ref<RegleSchema<TState, TSchema>>;
@@ -19,7 +19,13 @@ const defaultRegleValidationOptions: RegleSchemaBehaviourOptions &
19
19
  },
20
20
  };
21
21
 
22
- export const createCardStore = <Entity = object>({
22
+ export const createCardStore = <
23
+ Entity extends {
24
+ id?: string | number;
25
+ } = {
26
+ id?: string | number;
27
+ },
28
+ >({
23
29
  namespace,
24
30
  apiModule,
25
31
  standardValidationSchema,
@@ -29,7 +29,7 @@ type GetPresetListRequestConfig = {
29
29
  };
30
30
  };
31
31
 
32
- const getPresetList = async (params, config: GetPresetListRequestConfig) => {
32
+ const getPresetList = async (params, config?: GetPresetListRequestConfig) => {
33
33
  const useStarToSearch = config?.transformers?.useStarToSearch ?? true;
34
34
 
35
35
  const { page, size, search, sort, fields, presetNamespace, id } =
@@ -8,7 +8,6 @@
8
8
  </template>
9
9
 
10
10
  <script setup lang="ts">
11
- import { Validation } from '@vuelidate/core';
12
11
  import { useI18n } from 'vue-i18n';
13
12
 
14
13
  type ModelValue = string;
@@ -16,7 +15,7 @@ type ModelValue = string;
16
15
  const model = defineModel<ModelValue>();
17
16
 
18
17
  type Props = {
19
- v: Validation;
18
+ v: Record<string, unknown>;
20
19
  };
21
20
 
22
21
  const props = defineProps<Props>();
@@ -78,15 +78,16 @@ import {
78
78
  WtPopup,
79
79
  WtSearchBar,
80
80
  } from '@webitel/ui-sdk/components';
81
+ import { useEventBus } from '@webitel/ui-sdk/composables';
81
82
  import { IconAction } from '@webitel/ui-sdk/enums';
82
83
  import { useTableEmpty } from '@webitel/ui-sdk/modules/TableComponentModule/composables/useTableEmpty';
83
- import { type Store, storeToRefs } from 'pinia';
84
- import { computed, inject, onMounted, ref, watch } from 'vue';
84
+ import { type StoreGeneric, storeToRefs } from 'pinia';
85
+ import { computed, onMounted, ref, watch } from 'vue';
85
86
  import { useI18n } from 'vue-i18n';
86
87
  import { EnginePresetQuery } from 'webitel-sdk';
87
88
 
88
89
  import { AnyFilterConfig } from '../../../filters/modules/filterConfig/classes/FilterConfig';
89
- import PresetQueryAPI from '../../api/PresetQuery.ts';
90
+ import PresetQueryAPI from '../../api/PresetQuery';
90
91
  import PresetPreview from './preset-preview.vue';
91
92
 
92
93
  const props = defineProps<{
@@ -94,7 +95,7 @@ const props = defineProps<{
94
95
  * presets "section" namespace
95
96
  */
96
97
  namespace: string;
97
- presetsStore: () => Store;
98
+ presetsStore: StoreGeneric;
98
99
  filterConfigs: AnyFilterConfig[];
99
100
  }>();
100
101
 
@@ -104,7 +105,7 @@ const emit = defineEmits<{
104
105
  ];
105
106
  }>();
106
107
 
107
- const eventBus = inject('$eventBus');
108
+ const eventBus = useEventBus();
108
109
 
109
110
  const { t } = useI18n();
110
111
 
@@ -214,7 +215,7 @@ const updatePreset = async ({ preset, onSuccess, onFailure }) => {
214
215
  id: preset.id,
215
216
  namespace: preset.preset?.namespace,
216
217
  });
217
- eventBus.$emit('notification', {
218
+ eventBus?.$emit('notification', {
218
219
  type: 'success',
219
220
  text: t('systemNotifications.success.update', {
220
221
  entity: t('webitelUI.filters.presets.preset'),
@@ -32,8 +32,9 @@
32
32
 
33
33
  <script lang="ts" setup>
34
34
  import { WtIconAction } from '@webitel/ui-sdk/components';
35
+ import { useEventBus } from '@webitel/ui-sdk/composables';
35
36
  import { IconAction } from '@webitel/ui-sdk/enums';
36
- import { computed, inject, type Ref, reactive, ref, watch } from 'vue';
37
+ import { computed, type Ref, reactive, ref, watch } from 'vue';
37
38
  import { useI18n } from 'vue-i18n';
38
39
  import { EnginePresetQuery } from 'webitel-sdk';
39
40
 
@@ -66,7 +67,7 @@ const props = defineProps<{
66
67
  filterConfigs: AnyFilterConfig[];
67
68
  }>();
68
69
 
69
- const eventBus = inject('$eventBus');
70
+ const eventBus = useEventBus();
70
71
 
71
72
  const localFiltersManager = reactive(createFiltersManager());
72
73
 
@@ -114,7 +115,7 @@ const handlePresetSubmit = async (
114
115
  namespace: props.namespace,
115
116
  });
116
117
 
117
- eventBus.$emit('notification', {
118
+ eventBus?.$emit('notification', {
118
119
  type: 'success',
119
120
  text: t('systemNotifications.success.create', {
120
121
  entity: t('webitelUI.filters.presets.preset'),
@@ -156,7 +157,7 @@ const handlePresetOverwriteConfirmation = async ({
156
157
  namespace: props.namespace,
157
158
  });
158
159
 
159
- eventBus.$emit('notification', {
160
+ eventBus?.$emit('notification', {
160
161
  type: 'success',
161
162
  text: t('systemNotifications.success.update', {
162
163
  entity: t('webitelUI.filters.presets.preset'),
@@ -111,10 +111,6 @@ const v$ = useVuelidate(
111
111
  );
112
112
  v$.value.$touch();
113
113
 
114
- const appliedFilters = computed(() => {
115
- return props.filtersManager.getFiltersList();
116
- });
117
-
118
114
  const save = () => {
119
115
  isSaving.value = true;
120
116
 
@@ -41,7 +41,13 @@ export const filterPresetsStoreBody = (namespace = 'presets') => {
41
41
  };
42
42
 
43
43
  const tableStore = tableStoreBody<EnginePresetQuery>(presetsNamespace, {
44
- apiModule: PresetQueryAPI,
44
+ /* PresetQueryAPI's add/update take preset-specific params, so only the
45
+ ApiModule-conforming methods the table store actually calls go in */
46
+ apiModule: {
47
+ getList: PresetQueryAPI.getList,
48
+ get: PresetQueryAPI.get,
49
+ delete: PresetQueryAPI.delete,
50
+ },
45
51
  headers,
46
52
  disablePersistence: true,
47
53
  });
@@ -1,6 +1,6 @@
1
- import type { WtTableHeader } from 'src/components/wt-table/types/WtTable.d.ts';
1
+ import type { DatalistTableHeader } from '../../../types/tableStore.types';
2
2
 
3
- export const headers: WtTableHeader[] = [
3
+ export const headers: DatalistTableHeader[] = [
4
4
  {
5
5
  value: 'id',
6
6
  field: 'id',
@@ -34,12 +34,15 @@ export interface IFiltersManager {
34
34
  value?: FilterValue;
35
35
  label?: FilterLabel;
36
36
  }) => IFilter;
37
- deleteFilter: (name: FilterName) => IFilter;
37
+ deleteFilter: ({ name }: { name: FilterName }) => IFilter;
38
38
 
39
39
  /**
40
40
  * Converts filters data to String, that can be stored
41
41
  */
42
- toString: () => string;
42
+ toString: (options?: {
43
+ include?: FilterName[];
44
+ exclude?: FilterName[];
45
+ }) => string;
43
46
 
44
47
  /**
45
48
  * Restores filters from string
@@ -9,6 +9,8 @@
9
9
  :model-value="filterName"
10
10
  data-key="name"
11
11
  option-value="name"
12
+ required
13
+ :v="v$.filterName"
12
14
  @update:model-value="onFilterNameUpdate($event)"
13
15
  />
14
16
 
@@ -41,7 +43,7 @@
41
43
 
42
44
  <footer class="dynamic-filter-config-form-footer">
43
45
  <wt-button
44
- :disabled="invalid"
46
+ :disabled="invalid || v$.$invalid"
45
47
  wide
46
48
  @click="submit"
47
49
  >
@@ -60,6 +62,8 @@
60
62
  </template>
61
63
 
62
64
  <script lang="ts" setup>
65
+ import { useVuelidate } from '@vuelidate/core';
66
+ import { required } from '@vuelidate/validators';
63
67
  import { WtButton, WtSingleSelect } from '@webitel/ui-sdk/components';
64
68
  import deepcopy from 'deep-copy';
65
69
  import { computed, ref, watch } from 'vue';
@@ -103,6 +107,21 @@ const filterValue = ref();
103
107
 
104
108
  const editMode = !!props.filter;
105
109
 
110
+ const v$ = useVuelidate(
111
+ computed(() => ({
112
+ filterName: {
113
+ required,
114
+ },
115
+ })),
116
+ {
117
+ filterName,
118
+ },
119
+ {
120
+ $autoDirty: true,
121
+ },
122
+ );
123
+ v$.value.$touch();
124
+
106
125
  const invalid = ref(false);
107
126
 
108
127
  const filterConfigOptions = computed(() => {
@@ -24,7 +24,7 @@
24
24
  * and their styling
25
25
  */
26
26
  import { WtPopover } from '@webitel/ui-sdk/components';
27
- import { defineExpose, ref } from 'vue';
27
+ import { ref } from 'vue';
28
28
 
29
29
  interface Props {
30
30
  disabled?: boolean;
@@ -61,7 +61,9 @@ const submit = (payload: FilterInitParams, { hide }) => {
61
61
  };
62
62
 
63
63
  const popoverContentRef = ref<HTMLElement | null>(null);
64
- const dynamicFilterAddAction = ref<null>(null);
64
+ const dynamicFilterAddAction = ref<{
65
+ hidePopover: () => void;
66
+ } | null>(null);
65
67
 
66
68
  /**
67
69
  * @author @Oleksandr Palonnyi
@@ -75,7 +77,7 @@ const dynamicFilterAddAction = ref<null>(null);
75
77
  * */
76
78
  onClickOutside(
77
79
  popoverContentRef,
78
- () => dynamicFilterAddAction.value?.hidePopover(),
80
+ () => dynamicFilterAddAction?.value?.hidePopover(),
79
81
  {
80
82
  capture: true, // Fix for PrimeVue stopPropagation bug
81
83
  ignore: [
@@ -75,7 +75,8 @@ import {
75
75
  } from '@webitel/ui-sdk/components';
76
76
  import { computed, ref, watch } from 'vue';
77
77
 
78
- import { IFilter } from '../../classes/Filter';
78
+ import { FilterInitParams } from '../../classes/Filter';
79
+ import type { FilterConfigSearchMethodParams } from '../../modules/filterConfig/classes/FilterConfig';
79
80
  import { FilterOptionToPreviewApiSearchMethodMap } from '../../modules/filterConfig/components';
80
81
  import DynamicFilterConfigForm from '../config/dynamic-view/dynamic-filter-config-form.vue';
81
82
  import DynamicFilterConfigView from '../config/dynamic-view/dynamic-filter-config-view.vue';
@@ -107,12 +108,14 @@ const fillLocalValue = async (filter = props.filter) => {
107
108
  const filterName = props.filter.name;
108
109
  const filterValue = filter.value;
109
110
 
110
- const valueSearchMethod = props.filterConfig.searchRecords
111
- ? (...params) => {
112
- /* arrow fn here preserves filterConfig class "this" */
113
- return props.filterConfig.searchRecords(...params);
114
- }
115
- : FilterOptionToPreviewApiSearchMethodMap[filterName];
111
+ const { filterConfig } = props;
112
+ const valueSearchMethod =
113
+ 'searchRecords' in filterConfig
114
+ ? (...params: FilterConfigSearchMethodParams) => {
115
+ /* arrow fn here preserves filterConfig class "this" */
116
+ return filterConfig.searchRecords(...params);
117
+ }
118
+ : FilterOptionToPreviewApiSearchMethodMap[filterName];
116
119
 
117
120
  if (valueSearchMethod) {
118
121
  const { items } = await valueSearchMethod(
@@ -149,7 +152,7 @@ const isRenderPreview = computed(
149
152
  () => localValue.value === false || localValue.value,
150
153
  );
151
154
 
152
- const submit = (filter: IFilter, { hide }) => {
155
+ const submit = (filter: FilterInitParams, { hide }) => {
153
156
  emit('update:filter', filter);
154
157
  hide();
155
158
  };
@@ -68,7 +68,9 @@ const deleteFilter = ({ name }: { name: FilterName }) => {
68
68
  };
69
69
 
70
70
  const restoreLocalSearchValue = (searchMode: string) => {
71
- localSearchValue.value = props.filtersManager.filters.get(searchMode)?.value;
71
+ const restoredValue = props.filtersManager.filters.get(searchMode)?.value;
72
+ localSearchValue.value =
73
+ typeof restoredValue === 'string' ? restoredValue : '';
72
74
  return localSearchValue.value;
73
75
  };
74
76
 
@@ -68,7 +68,7 @@
68
68
 
69
69
  <script lang="ts" setup>
70
70
  import { WtIconAction } from '@webitel/ui-sdk/components';
71
- import { Store } from 'pinia';
71
+ import { StoreGeneric } from 'pinia';
72
72
  import { computed } from 'vue';
73
73
  import { WebitelProtoDataField } from 'webitel-sdk';
74
74
 
@@ -124,7 +124,7 @@ type Props = {
124
124
  *
125
125
  * TODO: https://github.com/webitel/webitel-ui-sdk/pull/551
126
126
  */
127
- usePresetsStore?: Store;
127
+ usePresetsStore?: () => StoreGeneric;
128
128
 
129
129
  /**
130
130
  * @author @Lera24
@@ -32,12 +32,18 @@ export type FilterConfigToolkit = {
32
32
  filter: IFilter;
33
33
  }>
34
34
  >;
35
+ staticViewFilterToFilterConfigMappings: ComputedRef<
36
+ Array<{
37
+ filterConfig: BaseFilterConfig;
38
+ filter: IFilter;
39
+ }>
40
+ >;
35
41
  };
36
42
 
37
43
  export type FilterConfigToolkitParams = {
38
44
  filterOptions: (FilterOption | BaseFilterConfig)[];
39
45
  filtersManager: IFiltersManager;
40
- filterableExtensionFields: WebitelProtoDataField[];
46
+ filterableExtensionFields?: WebitelProtoDataField[];
41
47
  staticMode?: boolean;
42
48
  };
43
49
 
@@ -45,7 +51,6 @@ export const useFilterConfigsToolkit = ({
45
51
  filterOptions,
46
52
  filtersManager,
47
53
  filterableExtensionFields = [],
48
- staticMode = false,
49
54
  }: FilterConfigToolkitParams): FilterConfigToolkit => {
50
55
  const { t } = useI18n();
51
56
 
@@ -3,6 +3,7 @@ import { computed, reactive, ref } from 'vue';
3
3
  import { createDatalistStore } from '../_shared/createDatalistStore';
4
4
  import { PersistedStorageType } from '../persist/PersistedStorage.types';
5
5
  import { usePersistedStorage } from '../persist/usePersistedStorage';
6
+ import type { Identifiable } from '../types/createDatalistStore.types';
6
7
  import type { useTableStoreConfig } from '../types/tableStore.types';
7
8
  import {
8
9
  createFiltersManager,
@@ -12,7 +13,7 @@ import {
12
13
  export const tableFiltersStoreBody = (
13
14
  namespace,
14
15
  config?: {
15
- filtersManagerConfig: FiltersManagerConfig;
16
+ filtersManagerConfig?: FiltersManagerConfig;
16
17
  },
17
18
  ) => {
18
19
  const filtersManager = reactive(
@@ -118,7 +119,7 @@ export const tableFiltersStoreBody = (
118
119
  };
119
120
  };
120
121
 
121
- export const createTableFiltersStore = <Entity>(
122
+ export const createTableFiltersStore = <Entity extends Identifiable>(
122
123
  namespace: string,
123
124
  config: useTableStoreConfig<Entity> & {
124
125
  filtersManagerConfig?: FiltersManagerConfig;
@@ -16,11 +16,12 @@ export type FilterConfigBaseParams = {
16
16
  valueInputComponent?: Component;
17
17
  valuePreviewComponent?: Component;
18
18
  notDeletable?: boolean;
19
- showFilterName: boolean;
19
+ showFilterName?: boolean;
20
+ staticView?: boolean;
20
21
  };
21
22
 
22
23
  export interface IWtSysTypeFilterConfig extends BaseFilterConfig {
23
- searchRecords: (params: FilterConfigSearchMethodParams) => Promise<{
24
+ searchRecords: (...params: FilterConfigSearchMethodParams) => Promise<{
24
25
  items: unknown[];
25
26
  next?: boolean;
26
27
  }>;
@@ -37,14 +38,41 @@ export type FilterConfigSearchMethodParams = [
37
38
  * filter-related data
38
39
  */
39
40
  {
40
- filterName: FilterName;
41
- filterValue: FilterValue;
42
- filterConfig: BaseFilterConfig;
43
- },
41
+ filterName?: FilterName;
42
+ filterValue?: FilterValue;
43
+ filterConfig?: BaseFilterConfig;
44
+ }?,
44
45
  ];
45
46
 
46
47
  export type AnyFilterConfig = IWtSysTypeFilterConfig | BaseFilterConfig;
47
48
 
49
+ /**
50
+ * Loose shapes forwarded into filter-config lookup calls by
51
+ * dynamic-filter-preview.vue and wt-select options loading. The callers pass
52
+ * heterogeneous request params, so these stay permissive on purpose.
53
+ */
54
+ // TODO(types): model per-filter search params and filter values precisely
55
+ export type FilterConfigSearchRequestParams = {
56
+ /** arrives as a scalar id, a list of ids, or a `{ list }` wrapper */
57
+ id?: any;
58
+ size?: number;
59
+ } & Record<string, any>;
60
+
61
+ export type FilterConfigListFilterValue = {
62
+ list?: Array<
63
+ {
64
+ id?: string | number;
65
+ } & Record<string, any>
66
+ >;
67
+ unassigned?: boolean;
68
+ };
69
+
70
+ export type FilterConfigSearchFilterContext = {
71
+ filterName?: FilterName;
72
+ filterValue?: FilterConfigListFilterValue;
73
+ filterConfig?: BaseFilterConfig;
74
+ };
75
+
48
76
  export class FilterConfig implements BaseFilterConfig {
49
77
  name: FilterName;
50
78
  valueInputComponent: Component;
@@ -83,6 +111,9 @@ export abstract class WtSysTypeFilterConfig
83
111
  extends FilterConfig
84
112
  implements IWtSysTypeFilterConfig
85
113
  {
86
- abstract name;
87
- abstract searchRecords;
114
+ abstract name: FilterName;
115
+ abstract searchRecords(...args: unknown[]): Promise<{
116
+ items: unknown[];
117
+ next?: boolean;
118
+ }>;
88
119
  }
@@ -11,7 +11,7 @@ import {
11
11
 
12
12
  export const createFilterConfig = (
13
13
  params: FilterConfigBaseParams &
14
- Required<BaseFilterConfig, 'name'> &
14
+ Required<Pick<BaseFilterConfig, 'name'>> &
15
15
  Record<string, unknown>,
16
16
  ): BaseFilterConfig => {
17
17
  const { name } = params;
@@ -2,19 +2,18 @@ import { sysTypes } from '@webitel/ui-sdk/api/clients/index';
2
2
  import { WtTypeExtensionFieldKind } from '@webitel/ui-sdk/enums';
3
3
  import { get } from 'lodash';
4
4
  import type { WebitelProtoDataField } from 'webitel-sdk';
5
-
6
- import { FilterConfig } from '../../classes/FilterConfig';
7
- import type { CustomFilterOption } from '../../enums/FilterOption';
8
5
  import type {
9
6
  BaseFilterConfig,
10
7
  FilterConfigBaseParams,
11
8
  IWtSysTypeFilterConfig,
12
- } from '../../types/FilterConfig';
9
+ } from '../../classes/FilterConfig';
10
+ import { FilterConfig } from '../../classes/FilterConfig';
13
11
  import TypeExtensionFilterValueField from './type-extension-filter-value-field.vue';
14
12
  import TypeExtensionFilterValuePreview from './type-extension-filter-value-preview.vue';
15
13
 
16
14
  export interface ITypeExtensionFilterConfig extends BaseFilterConfig {
17
15
  readonly field: WebitelProtoDataField;
16
+ searchRecords?: IWtSysTypeFilterConfig['searchRecords'];
18
17
  }
19
18
 
20
19
  class TypeExtensionFilterConfig
@@ -92,7 +91,7 @@ export type {
92
91
  };
93
92
 
94
93
  export const createTypeExtensionFilterConfig = (
95
- name: CustomFilterOption,
94
+ params: FilterConfigBaseParams,
96
95
  {
97
96
  field,
98
97
  }: {
@@ -101,15 +100,15 @@ export const createTypeExtensionFilterConfig = (
101
100
  ) => {
102
101
  switch (field.kind) {
103
102
  case WtTypeExtensionFieldKind.Select:
104
- return new TypeExtensionWtSysTypeFieldFilterConfig(name, {
103
+ return new TypeExtensionWtSysTypeFieldFilterConfig(params, {
105
104
  field,
106
105
  });
107
106
  case WtTypeExtensionFieldKind.Multiselect:
108
- return new TypeExtensionWtSysTypeFieldFilterConfig(name, {
107
+ return new TypeExtensionWtSysTypeFieldFilterConfig(params, {
109
108
  field,
110
109
  });
111
110
  default:
112
- return new TypeExtensionFilterConfig(name, {
111
+ return new TypeExtensionFilterConfig(params, {
113
112
  field,
114
113
  });
115
114
  }
@@ -17,9 +17,7 @@
17
17
  model ??
18
18
  [] /* so that component won't break when model is nullish at init */
19
19
  "
20
- :search-method="
21
- (...params) => props.filterConfig.searchRecords(...params)
22
- "
20
+ :search-method="searchRecords"
23
21
  :required="false /* https://github.com/webitel/webitel-ui-sdk/pull/1359#discussion_r3180877255 */"
24
22
  option-value="id"
25
23
  @update:model-value="model = $event"
@@ -33,9 +31,7 @@
33
31
  model ??
34
32
  [] /* so that component won't break when model is nullish at init */
35
33
  "
36
- :search-method="
37
- (...params) => props.filterConfig.searchRecords(...params)
38
- "
34
+ :search-method="searchRecords"
39
35
 
40
36
  :required="false /* https://github.com/webitel/webitel-ui-sdk/pull/1359#discussion_r3180877255 */""
41
37
  option-value="id"
@@ -43,7 +39,7 @@
43
39
  />
44
40
  </template>
45
41
  <template #[WtTypeExtensionFieldKind.Calendar]>
46
- <date-time-options-filter-value-field v-model:model-value="model" />
42
+ <date-time-options-filter-value-field v-model:model-value="dateTimeModel" />
47
43
  </template>
48
44
  </wt-type-extension-value-input>
49
45
  </template>
@@ -55,10 +51,13 @@ import {
55
51
  WtSingleSelect,
56
52
  WtTypeExtensionValueInput,
57
53
  } from '@webitel/ui-sdk/components';
58
- import { WtTypeExtensionFieldKind } from '@webitel/ui-sdk/enums'; // DO NOT REMOVE THIS IMPORT!! : Webstorm lies you, import is used for dynamic slot computation
59
- import { computed, onMounted, useAttrs, watch } from 'vue';
60
- import { WebitelProtoDataTypeKind } from 'webitel-sdk';
54
+ import {
55
+ type RelativeDatetimeValue,
56
+ WtTypeExtensionFieldKind,
57
+ } from '@webitel/ui-sdk/enums'; // DO NOT REMOVE THIS IMPORT!! : Webstorm lies you, import is used for dynamic slot computation
58
+ import { computed, useAttrs, watch } from 'vue';
61
59
 
60
+ import type { FilterConfigSearchMethodParams } from '../../classes/FilterConfig';
62
61
  import DateTimeOptionsFilterValueField from '../_shared/date-time-filter/date-time-options/date-time-options-filter-value-field.vue';
63
62
  import HasOptionFilterValueField from '../_shared/has-options/has-option-filter-value-field.vue';
64
63
  import { ITypeExtensionFilterConfig } from './index';
@@ -77,6 +76,24 @@ const emit = defineEmits<{
77
76
 
78
77
  const attrs = useAttrs();
79
78
 
79
+ const searchRecords = (...params: FilterConfigSearchMethodParams) =>
80
+ props.filterConfig.searchRecords?.(...params);
81
+
82
+ /* the filter value is dynamically shaped by field kind;
83
+ the Calendar branch always stores a datetime value */
84
+ const dateTimeModel = computed({
85
+ get: () =>
86
+ model.value as
87
+ | RelativeDatetimeValue
88
+ | {
89
+ from: number;
90
+ to: number;
91
+ },
92
+ set: (value) => {
93
+ model.value = value;
94
+ },
95
+ });
96
+
80
97
  const v$ = useVuelidate(
81
98
  computed(() => ({
82
99
  model: {