@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.
- package/dist/{contacts-BNeuB8IG.js → contacts-Bn25LSM7.js} +2 -2
- package/dist/{index-zPIqrQ5N.js → index-CIA7dKZk.js} +59 -59
- package/dist/{index-CXuua1os.js → index-DEyszQsx.js} +1 -1
- package/dist/{install-BjrTYVuH.js → install-BLruag0s.js} +13988 -12912
- package/dist/{isObject-SoSngRgc.js → isObject-wgGRYtgO.js} +1 -1
- package/dist/ui-sdk.css +1 -1
- package/dist/ui-sdk.js +3 -3
- package/dist/ui-sdk.umd.cjs +565 -279
- package/dist/{useVidstackSrc-DDO7Varm.js → useVidstackSrc-BBi5oq8T.js} +1 -1
- package/dist/{vidstack-Bq6c3Bam-B3uuwZ-b.js → vidstack-Bq6c3Bam-DXIHaRU6.js} +3 -3
- package/dist/{vidstack-D2pY00kU-Diq_9isr.js → vidstack-D2pY00kU-BE_AqirM.js} +3 -3
- package/dist/{vidstack-DDXt6fpN-CaMFUyJ8.js → vidstack-DDXt6fpN-D3xykUxG.js} +2 -2
- package/dist/{vidstack-D_-9AA6_-Bx6tzAhj.js → vidstack-D_-9AA6_-BDS42mA3.js} +2 -2
- package/dist/{vidstack-DqAw8m9J-BWMJ1klt.js → vidstack-DqAw8m9J-DtFh5mkx.js} +1 -1
- package/dist/{vidstack-audio-DJxrwNnm.js → vidstack-audio-BwtaRJRZ.js} +2 -2
- package/dist/{vidstack-dash-DfiQRJoI.js → vidstack-dash-CT0qNTAI.js} +4 -4
- package/dist/{vidstack-google-cast-DnCFt073.js → vidstack-google-cast-C4kSroiv.js} +4 -4
- package/dist/{vidstack-hls-Rp7tO2GF.js → vidstack-hls-CtCsnt_W.js} +4 -4
- package/dist/{vidstack-video-DlMUdTFO.js → vidstack-video-Bzwbx0RC.js} +3 -3
- package/dist/{vidstack-vimeo-DJHkA2Lp.js → vidstack-vimeo-CjK5ElAg.js} +4 -4
- package/dist/{vidstack-youtube-DG2-kzhq.js → vidstack-youtube-C9_vpuPD.js} +3 -3
- package/dist/{wt-action-bar-y0Z_PcDO.js → wt-action-bar-Bc_GH6kU.js} +1 -1
- package/dist/{wt-button-select-DlvGzhui.js → wt-button-select-Cc9o-NiI.js} +1 -1
- package/dist/{wt-call-media-action-Cdas1rBf.js → wt-call-media-action-sWq9pI2N.js} +1 -1
- package/dist/wt-chat-emoji-Cl3YsoL-.js +2909 -0
- package/dist/{wt-confirm-dialog-Dsa9e01T.js → wt-confirm-dialog-yyIkkLwI.js} +1 -1
- package/dist/{wt-context-menu-B43q5hgv.js → wt-context-menu-6WwSx8qR.js} +1 -1
- package/dist/{wt-copy-action-BkjbwUra.js → wt-copy-action-Ea6x__OX.js} +1 -1
- package/dist/{wt-datepicker-C9ra8YDO.js → wt-datepicker-Bi8iXDQC.js} +1 -1
- package/dist/{wt-display-chip-items-BJBcrF_I.js → wt-display-chip-items-CyshgAI0.js} +8 -8
- package/dist/{wt-dual-panel-BHxaWhEJ.js → wt-dual-panel-C3lUe446.js} +1 -1
- package/dist/{wt-dummy-DvlpQwdd.js → wt-dummy-07cnh7OP.js} +1 -1
- package/dist/{wt-error-page-CZ21yq7F.js → wt-error-page-P4gAwDj2.js} +1 -1
- package/dist/{wt-expansion-card-BnOn_xtW.js → wt-expansion-card-DsLok2qe.js} +5 -5
- package/dist/{wt-expansion-panel-BiGgAJP9.js → wt-expansion-panel-BLgze326.js} +9 -9
- package/dist/{wt-filters-panel-wrapper-DZAZUPuS.js → wt-filters-panel-wrapper-BI7tOtsM.js} +1 -1
- package/dist/{wt-galleria-DuA5s2p9.js → wt-galleria-DjUSBG29.js} +1 -1
- package/dist/{wt-inline-add-panel-D-huzxeZ.js → wt-inline-add-panel-Bg32h70I.js} +1 -1
- package/dist/{wt-navigation-menu-Djvm50Oh.js → wt-navigation-menu-BhoGF372.js} +1 -1
- package/dist/{wt-notifications-bar-Ds1CdGwf.js → wt-notifications-bar-o6ePcWRj.js} +2 -2
- package/dist/{wt-pagination-DfcicBop.js → wt-pagination-DXVZMbtn.js} +1 -1
- package/dist/wt-player-Dv6UMcr3.js +291 -0
- package/dist/wt-popover-BPVcjYrX.js +4 -0
- package/dist/{wt-popover-U7JE0uoX.js → wt-popover.vue_vue_type_script_setup_true_lang-BxD5Zt_u.js} +1 -1
- package/dist/{wt-screen-recordings-action-Cq3rkUYN.js → wt-screen-recordings-action-BjIRc7t6.js} +1 -1
- package/dist/{wt-search-bar-C83XJkVf.js → wt-search-bar-CiyJ55hK.js} +1 -1
- package/dist/{wt-selection-popup-D1_D542Y.js → wt-selection-popup-DLkerKfA.js} +1 -1
- package/dist/{wt-send-message-popup-C6UA_uEZ.js → wt-send-message-popup-CjfsCxfI.js} +18 -18
- package/dist/{wt-start-page-CJ0aR8_R.js → wt-start-page-C-3-3fZc.js} +11 -11
- package/dist/{wt-status-select-tB1EnTb8.js → wt-status-select-CiKHudco.js} +1 -1
- package/dist/{wt-stepper-D0Nr0ou6.js → wt-stepper-CvqNjYsK.js} +1 -1
- package/dist/{wt-table-WSCWJ0kN.js → wt-table-CBRWEe6H.js} +10 -10
- package/dist/{wt-table-actions-E-qeuwCv.js → wt-table-actions-ByAbJLsX.js} +1 -1
- package/dist/{wt-table-column-select-DUjDNDdD.js → wt-table-column-select-BsRkHmev.js} +2 -2
- package/dist/{wt-tabs-CkOB-0eU.js → wt-tabs-CtNBd15N.js} +1 -1
- package/dist/{wt-tags-input-D8gx3PLP.js → wt-tags-input-DD9rSzuh.js} +12 -12
- package/dist/{wt-timepicker-D8XuVSbS.js → wt-timepicker-Cka-r9m0.js} +1 -1
- package/dist/{wt-tree-Dw96n1ZK.js → wt-tree-sZocE-Ui.js} +2 -2
- package/dist/{wt-tree-table-B_tmJ7aV.js → wt-tree-table-D8JL2d1D.js} +29 -29
- package/dist/{wt-type-extension-value-input-Di67yDwH.js → wt-type-extension-value-input-C1Ez10TA.js} +3 -3
- package/dist/{wt-vidstack-player-zDlHHScB.js → wt-vidstack-player-Bv44QAeW.js} +10 -10
- package/package.json +1 -1
- package/src/components/_internals/composables/index.ts +7 -0
- package/src/components/_internals/composables/useSelect/useSelect.ts +101 -0
- package/src/components/_internals/composables/useSelect/useSelectCustomValues.ts +89 -0
- package/src/components/_internals/composables/useSelect/useSelectDropdown.ts +93 -0
- package/src/components/_internals/composables/useSelect/useSelectOptions.ts +198 -0
- package/src/components/_internals/composables/useSelect/useSelectUtils.ts +32 -0
- package/src/{composables → components/_internals/composables}/useWtTable/useWtTable.ts +1 -1
- package/src/components/_shared/settings-panel/components/speed-settings/speed-settings.vue +3 -1
- package/src/components/_shared/settings-panel/settings-panel.vue +2 -2
- package/src/components/index.js +6 -0
- package/src/components/wt-chip/wt-chip.vue +11 -2
- package/src/components/wt-expansion-card/wt-expansion-card.vue +1 -1
- package/src/components/wt-expansion-panel/wt-expansion-panel.vue +1 -1
- package/src/components/wt-galleria/wt-galleria.vue +4 -2
- package/src/components/wt-input-number/wt-input-number.vue +1 -2
- package/src/components/wt-input-text/wt-input-text.vue +3 -2
- package/src/components/wt-multi-select/wt-multi-select.vue +254 -0
- package/src/components/wt-password/wt-password.vue +1 -2
- package/src/components/wt-player/wt-player.vue +12 -1
- package/src/components/wt-single-select/wt-single-select.vue +229 -0
- package/src/components/wt-table/wt-table.vue +1 -2
- package/src/components/wt-tree-table/wt-tree-table.vue +1 -2
- package/src/composables/index.ts +0 -6
- package/src/locale/en/en.js +3 -0
- package/src/locale/es/es.js +3 -0
- package/src/locale/kz/kz.js +3 -0
- package/src/locale/pl/pl.js +3 -0
- package/src/locale/ro/ro.js +3 -0
- package/src/locale/ru/ru.js +3 -0
- package/src/locale/uk/uk.js +3 -0
- package/src/locale/uz/uz.js +3 -0
- package/src/locale/vi/vi.js +3 -0
- package/src/plugins/primevue/primevue.plugin.js +4 -0
- package/src/plugins/primevue/theme/components/checkbox/checkbox.js +1 -1
- package/src/plugins/primevue/theme/components/components.js +4 -0
- package/src/plugins/primevue/theme/components/multi-select/multi-select.js +32 -0
- package/src/plugins/primevue/theme/components/single-select/single-select.js +24 -0
- package/types/components/_internals/composables/index.d.ts +7 -0
- package/types/components/_internals/composables/useSelect/useSelect.d.ts +29 -0
- package/types/components/_internals/composables/useSelect/useSelectCustomValues.d.ts +16 -0
- package/types/components/_internals/composables/useSelect/useSelectDropdown.d.ts +20 -0
- package/types/components/_internals/composables/useSelect/useSelectOptions.d.ts +20 -0
- package/types/components/_internals/composables/useSelect/useSelectUtils.d.ts +3 -0
- package/types/{composables → components/_internals/composables}/useWtTable/useWtTable.d.ts +0 -1
- package/types/components/wt-chip/wt-chip.vue.d.ts +5 -1
- package/types/components/wt-multi-select/wt-multi-select.vue.d.ts +82 -0
- package/types/components/wt-select/wt-select.vue.d.ts +1 -1
- package/types/components/wt-single-select/wt-single-select.vue.d.ts +83 -0
- package/types/components/wt-table/wt-table.vue.d.ts +1 -1
- package/types/components/wt-tree-table/wt-tree-table.vue.d.ts +1 -1
- package/types/composables/index.d.ts +0 -6
- package/types/locale/en/en.d.ts +3 -0
- package/types/locale/es/es.d.ts +3 -0
- package/types/locale/i18n.d.ts +27 -0
- package/types/locale/index.d.ts +27 -0
- package/types/locale/kz/kz.d.ts +3 -0
- package/types/locale/pl/pl.d.ts +3 -0
- package/types/locale/ro/ro.d.ts +3 -0
- package/types/locale/ru/ru.d.ts +3 -0
- package/types/locale/uk/uk.d.ts +3 -0
- package/types/locale/uz/uz.d.ts +3 -0
- package/types/locale/vi/vi.d.ts +3 -0
- package/types/plugins/primevue/theme/components/components.d.ts +4 -0
- package/types/plugins/primevue/theme/components/multi-select/multi-select.d.ts +151 -0
- package/types/plugins/primevue/theme/components/single-select/single-select.d.ts +157 -0
- package/dist/wt-chat-emoji-C6ouRDpj.js +0 -2429
- package/dist/wt-player-CQhYaufW.js +0 -282
- package/src/components/wt-select/wt-select-v2.vue +0 -244
- package/types/components/wt-select/wt-select-v2.vue.d.ts +0 -77
- /package/src/{composables → components/_internals/composables}/useExpansion/useExpansion.ts +0 -0
- /package/src/{composables → components/_internals/composables}/useGalleriaFullscreen/useGalleriaFullscreen.ts +0 -0
- /package/src/{composables → components/_internals/composables}/useGalleriaMaskClick/useGalleriaMaskClick.ts +0 -0
- /package/src/{composables → components/_internals/composables}/useInputControl/useInputControl.ts +0 -0
- /package/src/{composables → components/_internals/composables}/useTableColumnDrag/useTableColumnDrag.ts +0 -0
- /package/types/{composables → components/_internals/composables}/useExpansion/useExpansion.d.ts +0 -0
- /package/types/{composables → components/_internals/composables}/useGalleriaFullscreen/useGalleriaFullscreen.d.ts +0 -0
- /package/types/{composables → components/_internals/composables}/useGalleriaMaskClick/useGalleriaMaskClick.d.ts +0 -0
- /package/types/{composables → components/_internals/composables}/useInputControl/useInputControl.d.ts +0 -0
- /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 '../../
|
|
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
|
-
|
|
54
|
+
display: flex;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.settings-panel__button {
|
package/src/components/index.js
CHANGED
|
@@ -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
|
|
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;
|