@webitel/ui-sdk 26.6.12 → 26.6.14

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/{contacts-BNeuB8IG.js → contacts-Bn25LSM7.js} +2 -2
  2. package/dist/{index-zPIqrQ5N.js → index-CIA7dKZk.js} +59 -59
  3. package/dist/{index-CXuua1os.js → index-DEyszQsx.js} +1 -1
  4. package/dist/{install-BjrTYVuH.js → install-BLruag0s.js} +13988 -12912
  5. package/dist/{isObject-SoSngRgc.js → isObject-wgGRYtgO.js} +1 -1
  6. package/dist/ui-sdk.css +1 -1
  7. package/dist/ui-sdk.js +3 -3
  8. package/dist/ui-sdk.umd.cjs +565 -279
  9. package/dist/{useVidstackSrc-DDO7Varm.js → useVidstackSrc-BBi5oq8T.js} +1 -1
  10. package/dist/{vidstack-Bq6c3Bam-B3uuwZ-b.js → vidstack-Bq6c3Bam-DXIHaRU6.js} +3 -3
  11. package/dist/{vidstack-D2pY00kU-Diq_9isr.js → vidstack-D2pY00kU-BE_AqirM.js} +3 -3
  12. package/dist/{vidstack-DDXt6fpN-CaMFUyJ8.js → vidstack-DDXt6fpN-D3xykUxG.js} +2 -2
  13. package/dist/{vidstack-D_-9AA6_-Bx6tzAhj.js → vidstack-D_-9AA6_-BDS42mA3.js} +2 -2
  14. package/dist/{vidstack-DqAw8m9J-BWMJ1klt.js → vidstack-DqAw8m9J-DtFh5mkx.js} +1 -1
  15. package/dist/{vidstack-audio-DJxrwNnm.js → vidstack-audio-BwtaRJRZ.js} +2 -2
  16. package/dist/{vidstack-dash-DfiQRJoI.js → vidstack-dash-CT0qNTAI.js} +4 -4
  17. package/dist/{vidstack-google-cast-DnCFt073.js → vidstack-google-cast-C4kSroiv.js} +4 -4
  18. package/dist/{vidstack-hls-Rp7tO2GF.js → vidstack-hls-CtCsnt_W.js} +4 -4
  19. package/dist/{vidstack-video-DlMUdTFO.js → vidstack-video-Bzwbx0RC.js} +3 -3
  20. package/dist/{vidstack-vimeo-DJHkA2Lp.js → vidstack-vimeo-CjK5ElAg.js} +4 -4
  21. package/dist/{vidstack-youtube-DG2-kzhq.js → vidstack-youtube-C9_vpuPD.js} +3 -3
  22. package/dist/{wt-action-bar-y0Z_PcDO.js → wt-action-bar-Bc_GH6kU.js} +1 -1
  23. package/dist/{wt-button-select-DlvGzhui.js → wt-button-select-Cc9o-NiI.js} +1 -1
  24. package/dist/{wt-call-media-action-Cdas1rBf.js → wt-call-media-action-sWq9pI2N.js} +1 -1
  25. package/dist/wt-chat-emoji-Cl3YsoL-.js +2909 -0
  26. package/dist/{wt-confirm-dialog-Dsa9e01T.js → wt-confirm-dialog-yyIkkLwI.js} +1 -1
  27. package/dist/{wt-context-menu-B43q5hgv.js → wt-context-menu-6WwSx8qR.js} +1 -1
  28. package/dist/{wt-copy-action-BkjbwUra.js → wt-copy-action-Ea6x__OX.js} +1 -1
  29. package/dist/{wt-datepicker-C9ra8YDO.js → wt-datepicker-Bi8iXDQC.js} +1 -1
  30. package/dist/{wt-display-chip-items-BJBcrF_I.js → wt-display-chip-items-CyshgAI0.js} +8 -8
  31. package/dist/{wt-dual-panel-BHxaWhEJ.js → wt-dual-panel-C3lUe446.js} +1 -1
  32. package/dist/{wt-dummy-DvlpQwdd.js → wt-dummy-07cnh7OP.js} +1 -1
  33. package/dist/{wt-error-page-CZ21yq7F.js → wt-error-page-P4gAwDj2.js} +1 -1
  34. package/dist/{wt-expansion-card-BnOn_xtW.js → wt-expansion-card-DsLok2qe.js} +5 -5
  35. package/dist/{wt-expansion-panel-BiGgAJP9.js → wt-expansion-panel-BLgze326.js} +9 -9
  36. package/dist/{wt-filters-panel-wrapper-DZAZUPuS.js → wt-filters-panel-wrapper-BI7tOtsM.js} +1 -1
  37. package/dist/{wt-galleria-DuA5s2p9.js → wt-galleria-DjUSBG29.js} +1 -1
  38. package/dist/{wt-inline-add-panel-D-huzxeZ.js → wt-inline-add-panel-Bg32h70I.js} +1 -1
  39. package/dist/{wt-navigation-menu-Djvm50Oh.js → wt-navigation-menu-BhoGF372.js} +1 -1
  40. package/dist/{wt-notifications-bar-Ds1CdGwf.js → wt-notifications-bar-o6ePcWRj.js} +2 -2
  41. package/dist/{wt-pagination-DfcicBop.js → wt-pagination-DXVZMbtn.js} +1 -1
  42. package/dist/wt-player-Dv6UMcr3.js +291 -0
  43. package/dist/wt-popover-BPVcjYrX.js +4 -0
  44. package/dist/{wt-popover-U7JE0uoX.js → wt-popover.vue_vue_type_script_setup_true_lang-BxD5Zt_u.js} +1 -1
  45. package/dist/{wt-screen-recordings-action-Cq3rkUYN.js → wt-screen-recordings-action-BjIRc7t6.js} +1 -1
  46. package/dist/{wt-search-bar-C83XJkVf.js → wt-search-bar-CiyJ55hK.js} +1 -1
  47. package/dist/{wt-selection-popup-D1_D542Y.js → wt-selection-popup-DLkerKfA.js} +1 -1
  48. package/dist/{wt-send-message-popup-C6UA_uEZ.js → wt-send-message-popup-CjfsCxfI.js} +18 -18
  49. package/dist/{wt-start-page-CJ0aR8_R.js → wt-start-page-C-3-3fZc.js} +11 -11
  50. package/dist/{wt-status-select-tB1EnTb8.js → wt-status-select-CiKHudco.js} +1 -1
  51. package/dist/{wt-stepper-D0Nr0ou6.js → wt-stepper-CvqNjYsK.js} +1 -1
  52. package/dist/{wt-table-WSCWJ0kN.js → wt-table-CBRWEe6H.js} +10 -10
  53. package/dist/{wt-table-actions-E-qeuwCv.js → wt-table-actions-ByAbJLsX.js} +1 -1
  54. package/dist/{wt-table-column-select-DUjDNDdD.js → wt-table-column-select-BsRkHmev.js} +2 -2
  55. package/dist/{wt-tabs-CkOB-0eU.js → wt-tabs-CtNBd15N.js} +1 -1
  56. package/dist/{wt-tags-input-D8gx3PLP.js → wt-tags-input-DD9rSzuh.js} +12 -12
  57. package/dist/{wt-timepicker-D8XuVSbS.js → wt-timepicker-Cka-r9m0.js} +1 -1
  58. package/dist/{wt-tree-Dw96n1ZK.js → wt-tree-sZocE-Ui.js} +2 -2
  59. package/dist/{wt-tree-table-B_tmJ7aV.js → wt-tree-table-D8JL2d1D.js} +29 -29
  60. package/dist/{wt-type-extension-value-input-Di67yDwH.js → wt-type-extension-value-input-C1Ez10TA.js} +3 -3
  61. package/dist/{wt-vidstack-player-zDlHHScB.js → wt-vidstack-player-Bv44QAeW.js} +10 -10
  62. package/package.json +1 -1
  63. package/src/components/_internals/composables/index.ts +7 -0
  64. package/src/components/_internals/composables/useSelect/useSelect.ts +101 -0
  65. package/src/components/_internals/composables/useSelect/useSelectCustomValues.ts +89 -0
  66. package/src/components/_internals/composables/useSelect/useSelectDropdown.ts +93 -0
  67. package/src/components/_internals/composables/useSelect/useSelectOptions.ts +198 -0
  68. package/src/components/_internals/composables/useSelect/useSelectUtils.ts +32 -0
  69. package/src/{composables → components/_internals/composables}/useWtTable/useWtTable.ts +1 -1
  70. package/src/components/_shared/settings-panel/components/speed-settings/speed-settings.vue +3 -1
  71. package/src/components/_shared/settings-panel/settings-panel.vue +2 -2
  72. package/src/components/index.js +6 -0
  73. package/src/components/wt-chip/wt-chip.vue +11 -2
  74. package/src/components/wt-expansion-card/wt-expansion-card.vue +1 -1
  75. package/src/components/wt-expansion-panel/wt-expansion-panel.vue +1 -1
  76. package/src/components/wt-galleria/wt-galleria.vue +4 -2
  77. package/src/components/wt-input-number/wt-input-number.vue +1 -2
  78. package/src/components/wt-input-text/wt-input-text.vue +3 -2
  79. package/src/components/wt-multi-select/wt-multi-select.vue +254 -0
  80. package/src/components/wt-password/wt-password.vue +1 -2
  81. package/src/components/wt-player/wt-player.vue +12 -1
  82. package/src/components/wt-single-select/wt-single-select.vue +229 -0
  83. package/src/components/wt-table/wt-table.vue +1 -2
  84. package/src/components/wt-tree-table/wt-tree-table.vue +1 -2
  85. package/src/composables/index.ts +0 -6
  86. package/src/locale/en/en.js +3 -0
  87. package/src/locale/es/es.js +3 -0
  88. package/src/locale/kz/kz.js +3 -0
  89. package/src/locale/pl/pl.js +3 -0
  90. package/src/locale/ro/ro.js +3 -0
  91. package/src/locale/ru/ru.js +3 -0
  92. package/src/locale/uk/uk.js +3 -0
  93. package/src/locale/uz/uz.js +3 -0
  94. package/src/locale/vi/vi.js +3 -0
  95. package/src/plugins/primevue/primevue.plugin.js +4 -0
  96. package/src/plugins/primevue/theme/components/checkbox/checkbox.js +1 -1
  97. package/src/plugins/primevue/theme/components/components.js +4 -0
  98. package/src/plugins/primevue/theme/components/multi-select/multi-select.js +32 -0
  99. package/src/plugins/primevue/theme/components/single-select/single-select.js +24 -0
  100. package/types/components/_internals/composables/index.d.ts +7 -0
  101. package/types/components/_internals/composables/useSelect/useSelect.d.ts +29 -0
  102. package/types/components/_internals/composables/useSelect/useSelectCustomValues.d.ts +16 -0
  103. package/types/components/_internals/composables/useSelect/useSelectDropdown.d.ts +20 -0
  104. package/types/components/_internals/composables/useSelect/useSelectOptions.d.ts +20 -0
  105. package/types/components/_internals/composables/useSelect/useSelectUtils.d.ts +3 -0
  106. package/types/{composables → components/_internals/composables}/useWtTable/useWtTable.d.ts +0 -1
  107. package/types/components/wt-chip/wt-chip.vue.d.ts +5 -1
  108. package/types/components/wt-multi-select/wt-multi-select.vue.d.ts +82 -0
  109. package/types/components/wt-select/wt-select.vue.d.ts +1 -1
  110. package/types/components/wt-single-select/wt-single-select.vue.d.ts +83 -0
  111. package/types/components/wt-table/wt-table.vue.d.ts +1 -1
  112. package/types/components/wt-tree-table/wt-tree-table.vue.d.ts +1 -1
  113. package/types/composables/index.d.ts +0 -6
  114. package/types/locale/en/en.d.ts +3 -0
  115. package/types/locale/es/es.d.ts +3 -0
  116. package/types/locale/i18n.d.ts +27 -0
  117. package/types/locale/index.d.ts +27 -0
  118. package/types/locale/kz/kz.d.ts +3 -0
  119. package/types/locale/pl/pl.d.ts +3 -0
  120. package/types/locale/ro/ro.d.ts +3 -0
  121. package/types/locale/ru/ru.d.ts +3 -0
  122. package/types/locale/uk/uk.d.ts +3 -0
  123. package/types/locale/uz/uz.d.ts +3 -0
  124. package/types/locale/vi/vi.d.ts +3 -0
  125. package/types/plugins/primevue/theme/components/components.d.ts +4 -0
  126. package/types/plugins/primevue/theme/components/multi-select/multi-select.d.ts +151 -0
  127. package/types/plugins/primevue/theme/components/single-select/single-select.d.ts +157 -0
  128. package/dist/wt-chat-emoji-C6ouRDpj.js +0 -2429
  129. package/dist/wt-player-CQhYaufW.js +0 -282
  130. package/src/components/wt-select/wt-select-v2.vue +0 -244
  131. package/types/components/wt-select/wt-select-v2.vue.d.ts +0 -77
  132. /package/src/{composables → components/_internals/composables}/useExpansion/useExpansion.ts +0 -0
  133. /package/src/{composables → components/_internals/composables}/useGalleriaFullscreen/useGalleriaFullscreen.ts +0 -0
  134. /package/src/{composables → components/_internals/composables}/useGalleriaMaskClick/useGalleriaMaskClick.ts +0 -0
  135. /package/src/{composables → components/_internals/composables}/useInputControl/useInputControl.ts +0 -0
  136. /package/src/{composables → components/_internals/composables}/useTableColumnDrag/useTableColumnDrag.ts +0 -0
  137. /package/types/{composables → components/_internals/composables}/useExpansion/useExpansion.d.ts +0 -0
  138. /package/types/{composables → components/_internals/composables}/useGalleriaFullscreen/useGalleriaFullscreen.d.ts +0 -0
  139. /package/types/{composables → components/_internals/composables}/useGalleriaMaskClick/useGalleriaMaskClick.d.ts +0 -0
  140. /package/types/{composables → components/_internals/composables}/useInputControl/useInputControl.d.ts +0 -0
  141. /package/types/{composables → components/_internals/composables}/useTableColumnDrag/useTableColumnDrag.d.ts +0 -0
@@ -0,0 +1,101 @@
1
+ import { useSelectCustomValues } from './useSelectCustomValues';
2
+ import { useSelectDropdown } from './useSelectDropdown';
3
+ import { useSelectOptions } from './useSelectOptions';
4
+
5
+ export const useSelect = ({
6
+ selected,
7
+ options,
8
+ optionLabel,
9
+ optionValue,
10
+ dataKey,
11
+ allowCustomValues,
12
+ manualCustomValues = false,
13
+ filterInput,
14
+ selectRef,
15
+ searchMethod,
16
+ selectId,
17
+ isSingle,
18
+ emit = () => {},
19
+ }) => {
20
+ const {
21
+ filterText,
22
+ filteredOptions,
23
+ isLoading,
24
+ searchHasNext,
25
+ sortOptions,
26
+ getOptionLabel,
27
+ fetchOptions,
28
+ resetAndFetch,
29
+ filterOptions,
30
+ updateSelectedOptionsCache,
31
+ } = useSelectOptions({
32
+ selected,
33
+ options,
34
+ optionLabel,
35
+ optionValue,
36
+ dataKey,
37
+ allowCustomValues,
38
+ searchMethod,
39
+ });
40
+
41
+ const {
42
+ isDropdownOpen,
43
+ onDropdownBeforeShow,
44
+ onDropdownBeforeHide,
45
+ onDropdownShow,
46
+ onDropdownHide,
47
+ } = useSelectDropdown({
48
+ selectId,
49
+ selectRef,
50
+ filterInput,
51
+ searchMethod,
52
+ filteredOptions,
53
+ filterText,
54
+ filterOptions,
55
+ resetAndFetch,
56
+ sortOptions,
57
+ fetchOptions,
58
+ isLoading,
59
+ searchHasNext,
60
+ });
61
+
62
+ const { onInputKeydown } = useSelectCustomValues({
63
+ selected,
64
+ filteredOptions,
65
+ options,
66
+ dataKey,
67
+ filterText,
68
+ filterOptions,
69
+ updateSelectedOptionsCache,
70
+ selectRef,
71
+ allowCustomValues,
72
+ manualCustomValues,
73
+ isSingle,
74
+ emit,
75
+ });
76
+
77
+ const clearValue = () => {
78
+ let value: string | unknown[] | Record<string, unknown> = '';
79
+ if (Array.isArray(selected.value)) value = [];
80
+ else if (typeof selected.value === 'object' && selected.value !== null)
81
+ value = {};
82
+ selected.value = value;
83
+ emit('reset', value);
84
+ };
85
+
86
+ return {
87
+ isLoading,
88
+ isDropdownOpen,
89
+ filterText,
90
+ filteredOptions,
91
+ getOptionLabel,
92
+ fetchOptions,
93
+ filterOptions,
94
+ onDropdownBeforeShow,
95
+ onDropdownBeforeHide,
96
+ onDropdownShow,
97
+ onDropdownHide,
98
+ onInputKeydown,
99
+ clearValue,
100
+ };
101
+ };
@@ -0,0 +1,89 @@
1
+ import { nextTick } from 'vue';
2
+ import { isOptionSelected, toArray } from './useSelectUtils';
3
+
4
+ export const useSelectCustomValues = ({
5
+ selected,
6
+ filteredOptions,
7
+ options,
8
+ dataKey,
9
+ filterText,
10
+ filterOptions,
11
+ updateSelectedOptionsCache,
12
+ selectRef,
13
+ allowCustomValues,
14
+ manualCustomValues,
15
+ isSingle,
16
+ emit,
17
+ }) => {
18
+ const makeCustomOption = (text: string) => {
19
+ const sample = options.value.length
20
+ ? options.value[0]
21
+ : filteredOptions.value[0];
22
+ if (sample && typeof sample === 'object') {
23
+ return Object.fromEntries(
24
+ Object.keys(sample).map((key) => [
25
+ key,
26
+ text,
27
+ ]),
28
+ );
29
+ }
30
+ return text;
31
+ };
32
+
33
+ const onInputKeydown = () => {
34
+ if (!allowCustomValues.value || !filterText.value) return;
35
+
36
+ // check if custom option is already selected
37
+ const selectedAsArray = toArray(selected.value);
38
+ const isAlreadySelected = selectedAsArray.some(
39
+ (s) => (dataKey.value ? s[dataKey.value] : s) === filterText.value,
40
+ );
41
+
42
+ if (isAlreadySelected) return;
43
+
44
+ // TODO: remove this functionality if there is no select that does manually handling
45
+ // if (manualCustomValues.value) {
46
+ // emit('add:custom-value', filterText.value);
47
+ // return;
48
+ // }
49
+
50
+ const customOption = makeCustomOption(filterText.value);
51
+
52
+ const isOptionAlreadyInList = filteredOptions.value.some((option) =>
53
+ isOptionSelected(
54
+ option,
55
+ [
56
+ customOption,
57
+ ],
58
+ dataKey.value,
59
+ ),
60
+ );
61
+
62
+ if (!isOptionAlreadyInList) {
63
+ filteredOptions.value.unshift(customOption);
64
+ }
65
+
66
+ if (isSingle) {
67
+ selectRef.value?.hide();
68
+ selected.value = customOption;
69
+ } else {
70
+ // redefine selected value instead of pushing element is for max-selected-labels prop correct work
71
+ selected.value = [
72
+ ...selected.value,
73
+ customOption,
74
+ ];
75
+ }
76
+
77
+ // Sync cache immediately so the custom value survives the upcoming API refetch
78
+ updateSelectedOptionsCache();
79
+
80
+ nextTick(() => {
81
+ filterText.value = '';
82
+ filterOptions('');
83
+ });
84
+ };
85
+
86
+ return {
87
+ onInputKeydown,
88
+ };
89
+ };
@@ -0,0 +1,93 @@
1
+ import { ref } from 'vue';
2
+
3
+ export const useSelectDropdown = ({
4
+ selectId,
5
+ selectRef,
6
+ filterInput,
7
+ searchMethod,
8
+ filteredOptions,
9
+ filterText,
10
+ filterOptions,
11
+ resetAndFetch,
12
+ sortOptions,
13
+ fetchOptions,
14
+ isLoading,
15
+ searchHasNext,
16
+ }) => {
17
+ const isDropdownOpen = ref(false);
18
+ let overlayResizeObserver: ResizeObserver | null = null;
19
+
20
+ const getListContainer = (): HTMLElement | null => {
21
+ return document.querySelector(`#${selectId.value}_list`)
22
+ ?.parentElement as HTMLElement | null;
23
+ };
24
+
25
+ const handleScroll = (e: Event) => {
26
+ const el = e.target as HTMLElement;
27
+ const nearBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 40;
28
+ if (nearBottom && !isLoading.value && searchHasNext.value) {
29
+ fetchOptions();
30
+ }
31
+ };
32
+
33
+ const onDropdownBeforeShow = () => {
34
+ isDropdownOpen.value = true;
35
+ // @author @HlukhovYe
36
+ // when user previously selected items, they should be on top only after reopening dropdown
37
+ filteredOptions.value = sortOptions(filteredOptions.value);
38
+ };
39
+
40
+ const onDropdownShow = () => {
41
+ filterInput.value?.focus();
42
+ if (searchMethod.value) {
43
+ getListContainer()?.addEventListener('scroll', handleScroll);
44
+ }
45
+ /*
46
+ @author @HlukhovYe
47
+ primevue doesnt align overlay position if use custom options filtering,
48
+ so its necessary to trigger primevue's method alignOverlay manually
49
+ */
50
+ const overlay = selectRef?.value?.overlay;
51
+ if (overlay) {
52
+ overlayResizeObserver = new ResizeObserver(() => {
53
+ selectRef.value?.alignOverlay();
54
+ });
55
+ overlayResizeObserver.observe(overlay);
56
+ }
57
+ };
58
+
59
+ const onDropdownBeforeHide = () => {
60
+ /**
61
+ * @author @HlukhovYe
62
+ * neccessary fix for this problem: https://github.com/primefaces/primevue/issues/8508
63
+ */
64
+ const overlay = selectRef?.value?.overlay;
65
+ if (overlay) overlay.style.pointerEvents = 'none';
66
+ getListContainer()?.scrollTo(0, 0); // scroll dropdown list to top
67
+ };
68
+
69
+ const onDropdownHide = () => {
70
+ isDropdownOpen.value = false;
71
+ overlayResizeObserver?.disconnect();
72
+ overlayResizeObserver = null;
73
+ if (searchMethod.value) {
74
+ /*
75
+ @author @HlukhovYe
76
+ remove scroll listener on dropdown close, no need to remove it on unmount
77
+ */
78
+ getListContainer()?.removeEventListener('scroll', handleScroll);
79
+ if (filterText.value) resetAndFetch();
80
+ } else {
81
+ filterOptions('');
82
+ }
83
+ filterText.value = '';
84
+ };
85
+
86
+ return {
87
+ isDropdownOpen,
88
+ onDropdownBeforeShow,
89
+ onDropdownBeforeHide,
90
+ onDropdownShow,
91
+ onDropdownHide,
92
+ };
93
+ };
@@ -0,0 +1,198 @@
1
+ import { reactive, ref, watch } from 'vue';
2
+ import { useI18n } from 'vue-i18n';
3
+ import debounce from '../../../../scripts/debounce';
4
+ import { dedupeByKey, isOptionSelected, toArray } from './useSelectUtils';
5
+
6
+ export const useSelectOptions = ({
7
+ selected,
8
+ options,
9
+ optionLabel,
10
+ optionValue,
11
+ dataKey,
12
+ allowCustomValues,
13
+ searchMethod,
14
+ }) => {
15
+ const { t } = useI18n();
16
+ const defaultOptionLabel = 'name';
17
+ const filterText = ref('');
18
+ const filteredOptions = ref(options.value);
19
+ const isLoading = ref(false);
20
+ const searchHasNext = ref(true);
21
+ const searchParams = reactive({
22
+ page: 1,
23
+ search: '',
24
+ });
25
+
26
+ /*
27
+ @author @HlukhovYe
28
+ selected options first, then other options
29
+ selected values that are not in the list are prepended as-is
30
+ */
31
+ const sortOptions = (opts) => {
32
+ const deduped = dedupeByKey(opts, dataKey.value);
33
+ if (!selected.value) return deduped;
34
+
35
+ const selectedAsArray = toArray(selected.value);
36
+
37
+ const selectedOptions = [];
38
+ const otherOptions = [];
39
+
40
+ for (const option of deduped) {
41
+ const isSelected = isOptionSelected(
42
+ option,
43
+ selectedAsArray,
44
+ dataKey.value,
45
+ );
46
+ (isSelected ? selectedOptions : otherOptions).push(option);
47
+ }
48
+
49
+ const topOptions =
50
+ dataKey.value || selectedOptions.length
51
+ ? selectedOptions
52
+ : selectedAsArray;
53
+ return topOptions.concat(otherOptions);
54
+ };
55
+
56
+ const getOptionLabel = (option) => {
57
+ if (!option) return '';
58
+ // https://webitel.atlassian.net/browse/WTEL-3181
59
+ // if allowCustomValue select mode, return label as is
60
+ if (allowCustomValues.value && option.isTag) return option.label;
61
+
62
+ // when optionValue is used PrimeVue passes the extracted primitive instead of the full object
63
+ if (optionValue?.value && typeof option !== 'object') {
64
+ const foundOption = (
65
+ filteredOptions.value as Record<string, unknown>[]
66
+ ).find((o) => o[optionValue.value] === option);
67
+ return foundOption ? getOptionLabel(foundOption) : String(option);
68
+ }
69
+
70
+ if (optionLabel.value && option[optionLabel.value])
71
+ return option[optionLabel.value];
72
+ if (option.locale) {
73
+ if (Array.isArray(option.locale)) return t(...option.locale);
74
+ return t(option.locale);
75
+ }
76
+ return option[defaultOptionLabel] || option;
77
+ };
78
+
79
+ // Cache of full option objects for currently selected values,
80
+ // so they can be preserved in filteredOptions after filtering
81
+ const selectedOptionsCache = ref([]);
82
+
83
+ const updateSelectedOptionsCache = () => {
84
+ if (!selected.value) {
85
+ selectedOptionsCache.value = [];
86
+ return;
87
+ }
88
+ const selectedAsArray = toArray(selected.value);
89
+ const isSelected = (option) =>
90
+ isOptionSelected(option, selectedAsArray, dataKey.value);
91
+
92
+ // Find full option objects from filteredOptions that match selected values
93
+ const foundOptions = filteredOptions.value.filter(isSelected);
94
+ // Merge with previous cache, then remove entries no longer selected
95
+ const mergedOptions = dedupeByKey(
96
+ [
97
+ ...selectedOptionsCache.value,
98
+ ...foundOptions,
99
+ ],
100
+ dataKey.value,
101
+ );
102
+ selectedOptionsCache.value = mergedOptions.filter(isSelected);
103
+ };
104
+
105
+ const fetchOptions = async () => {
106
+ if (!searchMethod.value) return;
107
+ const { search, page } = searchParams;
108
+ isLoading.value = true;
109
+ const { items, next } = await searchMethod.value({
110
+ search,
111
+ page,
112
+ });
113
+ const baseOptions =
114
+ searchParams.page === 1
115
+ ? dedupeByKey(
116
+ [
117
+ ...toArray(selected.value).filter(Boolean),
118
+ ...selectedOptionsCache.value,
119
+ ...items,
120
+ ],
121
+ dataKey.value,
122
+ )
123
+ : filteredOptions.value.concat(items);
124
+ filteredOptions.value = sortOptions(baseOptions);
125
+ searchHasNext.value = next;
126
+ searchParams.page += 1;
127
+ isLoading.value = false;
128
+ };
129
+
130
+ const resetAndFetch = (search = '') => {
131
+ searchParams.search = search;
132
+ searchParams.page = 1;
133
+ fetchOptions();
134
+ };
135
+
136
+ const debouncedFetch = debounce((value) => resetAndFetch(value));
137
+
138
+ const filterOptions = (value) => {
139
+ filterText.value = value;
140
+ if (!searchMethod.value) {
141
+ const matchingOptions = options.value.filter((option) =>
142
+ getOptionLabel(option).toLowerCase().includes(value.toLowerCase()),
143
+ );
144
+ filteredOptions.value = sortOptions(
145
+ dedupeByKey(
146
+ [
147
+ ...selectedOptionsCache.value,
148
+ ...matchingOptions,
149
+ ],
150
+ dataKey.value,
151
+ ),
152
+ );
153
+ } else {
154
+ debouncedFetch(value);
155
+ }
156
+ };
157
+
158
+ const addSelectedValueToList = (newVal) => {
159
+ // If the selected value is not in the list, add it
160
+ if (!newVal || !searchMethod.value) return;
161
+ const selectedAsArray = toArray(newVal);
162
+ const missingSelected = selectedAsArray.filter(
163
+ (s) => !isOptionSelected(s, filteredOptions.value, dataKey.value),
164
+ );
165
+ if (missingSelected.length) {
166
+ filteredOptions.value = sortOptions(
167
+ dedupeByKey(
168
+ [
169
+ ...missingSelected,
170
+ ...filteredOptions.value,
171
+ ],
172
+ dataKey.value,
173
+ ),
174
+ );
175
+ }
176
+ };
177
+
178
+ watch(
179
+ () => selected.value,
180
+ (newVal) => {
181
+ updateSelectedOptionsCache();
182
+ addSelectedValueToList(newVal);
183
+ },
184
+ );
185
+
186
+ return {
187
+ filterText,
188
+ filteredOptions,
189
+ isLoading,
190
+ searchHasNext,
191
+ sortOptions,
192
+ getOptionLabel,
193
+ fetchOptions,
194
+ resetAndFetch,
195
+ filterOptions,
196
+ updateSelectedOptionsCache,
197
+ };
198
+ };
@@ -0,0 +1,32 @@
1
+ export const toArray = (value) =>
2
+ Array.isArray(value)
3
+ ? value
4
+ : [
5
+ value,
6
+ ];
7
+
8
+ export const isOptionSelected = (option, selectedArray, dataKey) => {
9
+ return dataKey
10
+ ? selectedArray.some((s) => s != null && s[dataKey] === option[dataKey])
11
+ : selectedArray.some((s) => s === option);
12
+ };
13
+
14
+ export const dedupeByKey = (items: unknown[], key: string): unknown[] => {
15
+ if (!key) {
16
+ // no dataKey — fall back to reference dedup via Set
17
+ return [
18
+ ...new Set(items),
19
+ ];
20
+ }
21
+ const seen = new Map();
22
+ for (const item of items) {
23
+ const k =
24
+ item != null && typeof item === 'object'
25
+ ? (item as Record<string, unknown>)[key]
26
+ : item;
27
+ if (!seen.has(k)) seen.set(k, item);
28
+ }
29
+ return [
30
+ ...seen.values(),
31
+ ];
32
+ };
@@ -1,7 +1,7 @@
1
1
  import { computed, unref } from 'vue';
2
2
  import { useI18n } from 'vue-i18n';
3
3
 
4
- import type { WtTableHeader } from '../../components/wt-table/types/WtTable.d.ts';
4
+ import type { WtTableHeader } from '../../wt-table/types/WtTable';
5
5
 
6
6
  export const useWtTable = ({ headers }) => {
7
7
  const { t } = useI18n();
@@ -60,8 +60,10 @@
60
60
  <script setup lang="ts">
61
61
  import { computed } from 'vue';
62
62
 
63
- import { WtButton, WtIcon, WtSlider } from '../../../../../components';
64
63
  import { ComponentSize } from '../../../../../enums';
64
+ import WtButton from '../../../../wt-button/wt-button.vue';
65
+ import WtIcon from '../../../../wt-icon/wt-icon.vue';
66
+ import WtSlider from '../../../../wt-slider/wt-slider.vue';
65
67
 
66
68
  interface Props {
67
69
  modelValue?: number;
@@ -17,8 +17,8 @@
17
17
  </template>
18
18
 
19
19
  <script setup lang="ts">
20
- import { WtPopover } from '../../../components';
21
20
  import { ComponentSize } from '../../../enums';
21
+ import WtPopover from '../../wt-popover/wt-popover.vue';
22
22
  import SpeedSettings from './components/speed-settings/speed-settings.vue';
23
23
 
24
24
  export interface MediaSettings {
@@ -51,7 +51,7 @@ function handlePlaybackRateUpdate(playbackRate: number) {
51
51
 
52
52
  <style scoped>
53
53
  .settings-panel {
54
- display: flex;
54
+ display: flex;
55
55
  }
56
56
 
57
57
  .settings-panel__button {
@@ -31,6 +31,7 @@ import WtLoadBar from './wt-load-bar/wt-load-bar.vue';
31
31
  import WtLoader from './wt-loader/wt-loader.vue';
32
32
  import WtLogo from './wt-logo/wt-logo.vue';
33
33
  import WtMessage from './wt-message/wt-message.vue';
34
+ import WtMultiSelect from './wt-multi-select/wt-multi-select.vue';
34
35
  import WtNavigationBar from './wt-navigation-bar/wt-navigation-bar.vue';
35
36
  import WtNotification from './wt-notification/wt-notification.vue';
36
37
  import WtPageWrapper from './wt-page-wrapper/wt-page-wrapper.vue';
@@ -40,6 +41,7 @@ import WtProgressBar from './wt-progress-bar/wt-progress-bar.vue';
40
41
  import WtRadio from './wt-radio/wt-radio.vue';
41
42
  import WtRoundedAction from './wt-rounded-action/wt-rounded-action.vue';
42
43
  import WtSelect from './wt-select/wt-select.vue';
44
+ import WtSingleSelect from './wt-single-select/wt-single-select.vue';
43
45
  import WtSwitcher from './wt-switcher/wt-switcher.vue';
44
46
  import WtTextarea from './wt-textarea/wt-textarea.vue';
45
47
  import WtTooltip from './wt-tooltip/wt-tooltip.vue';
@@ -252,6 +254,8 @@ const Components = {
252
254
  WtChatEmoji,
253
255
  WtExpansionCard,
254
256
  WtDatetimeText,
257
+ WtSingleSelect,
258
+ WtMultiSelect,
255
259
  WtScreenRecordingsAction,
256
260
  WtInlineAddPanel,
257
261
  WtCallMediaAction,
@@ -305,6 +309,7 @@ export {
305
309
  WtLoader,
306
310
  WtLogo,
307
311
  WtMessage,
312
+ WtMultiSelect,
308
313
  WtNavigationBar,
309
314
  WtNavigationMenu,
310
315
  WtNotification,
@@ -325,6 +330,7 @@ export {
325
330
  WtSelect,
326
331
  WtSelectionPopup,
327
332
  WtSendMessagePopup,
333
+ WtSingleSelect,
328
334
  WtSlider,
329
335
  WtStartPage,
330
336
  WtStatusSelect,
@@ -6,7 +6,12 @@
6
6
  >
7
7
  <slot />
8
8
  <template #removeicon>
9
- <wt-icon class="wt-chip__close-icon" icon="close--filled" />
9
+ <wt-icon-btn
10
+ class="wt-chip__close-icon"
11
+ icon="close--filled"
12
+ :size="ComponentSize.SM"
13
+ @click="emit('remove', $event)"
14
+ />
10
15
  </template>
11
16
  </p-chip>
12
17
  </template>
@@ -14,7 +19,7 @@
14
19
  <script setup lang="ts">
15
20
  import type { ChipProps } from 'primevue/chip';
16
21
 
17
- import { ChipColor } from '../../enums';
22
+ import { ChipColor, ComponentSize } from '../../enums';
18
23
 
19
24
  interface WtProps extends ChipProps {
20
25
  /**
@@ -36,6 +41,10 @@ withDefaults(defineProps<WtProps>(), {
36
41
  color: ChipColor.MAIN,
37
42
  removable: false,
38
43
  });
44
+
45
+ const emit = defineEmits<{
46
+ remove: [];
47
+ }>();
39
48
  </script>
40
49
 
41
50
  <style scoped>
@@ -34,8 +34,8 @@
34
34
 
35
35
  <script setup lang="ts">
36
36
  import { toRef } from 'vue';
37
- import { useExpansion } from '../../composables';
38
37
  import { ComponentSize } from '../../enums';
38
+ import { useExpansion } from '../_internals/composables';
39
39
  import WtExpandTransition from '../transitions/wt-expand-transition.vue';
40
40
 
41
41
  const props = withDefaults(
@@ -31,8 +31,8 @@
31
31
 
32
32
  <script setup lang="ts">
33
33
  import { toRef } from 'vue';
34
- import { useExpansion } from '../../composables/useExpansion/useExpansion';
35
34
  import { ComponentSize } from '../../enums';
35
+ import { useExpansion } from '../_internals/composables/useExpansion/useExpansion';
36
36
  import WtExpandTransition from '../transitions/wt-expand-transition.vue';
37
37
 
38
38
  /**
@@ -114,9 +114,11 @@ import {
114
114
  ref,
115
115
  watch,
116
116
  } from 'vue';
117
-
118
- import { useGalleriaFullscreen, useGalleriaMaskClick } from '../../composables';
119
117
  import DeleteConfirmationPopup from '../../modules/DeleteConfirmationPopup/components/delete-confirmation-popup.vue';
118
+ import {
119
+ useGalleriaFullscreen,
120
+ useGalleriaMaskClick,
121
+ } from '../_internals/composables';
120
122
  import type { WtGalleriaItem } from './types/WtGalleria.d.ts';
121
123
 
122
124
  /**
@@ -86,10 +86,9 @@ import {
86
86
  useSlots,
87
87
  useTemplateRef,
88
88
  } from 'vue';
89
-
90
- import { useInputControl } from '../../composables';
91
89
  import { ComponentSize, MessageColor, MessageVariant } from '../../enums';
92
90
  import { useValidation } from '../../mixins/validationMixin/useValidation';
91
+ import { useInputControl } from '../_internals/composables';
93
92
 
94
93
  interface WtInputNumberProps extends /* @vue-ignore */ InputNumberProps {
95
94
  label?: string;