@webitel/ui-sdk 26.8.56 → 26.8.57

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 (34) hide show
  1. package/dist/clients-B8MJJx6E.js +39958 -0
  2. package/dist/{components-CWSUHV29.js → components-BWyW5EEY.js} +3 -3
  3. package/dist/{engineCallFileType.zod-C-t93kQg.js → engineCallFileType-D7QVFOac.js} +1 -1
  4. package/dist/{generateInstance-C9d7J_TX.js → genClient-HHiOUj56.js} +969 -755
  5. package/dist/ui-sdk.js +2 -2
  6. package/dist/ui-sdk.umd.cjs +2056 -2056
  7. package/dist/{wt-call-media-action-Bn2bGCWs.js → wt-call-media-action-Bkyppnsm.js} +1 -1
  8. package/dist/{wt-chat-emoji-DRK_E-lD.js → wt-chat-emoji-Cj3B8oR5.js} +1 -1
  9. package/dist/{wt-display-chip-items-C5z7aCDZ.js → wt-display-chip-items-Cvm5rOYr.js} +1 -1
  10. package/dist/{wt-screen-recordings-action-Dj6ITuhE.js → wt-screen-recordings-action-DI1qlUi1.js} +1 -1
  11. package/dist/{wt-send-message-popup-G26F9NPH.js → wt-send-message-popup-OYvzhdyL.js} +2 -2
  12. package/dist/{wt-type-extension-value-input--Vc1cs5d.js → wt-type-extension-value-input-BfUPxO-s.js} +2 -2
  13. package/dist/{wt-vidstack-player-FD4gfDSE.js → wt-vidstack-player-DjQEPOTu.js} +1 -1
  14. package/package.json +6 -2
  15. package/src/modules/UploadCsvPopup/components/__tests__/wt-upload-csv-popup.spec.js +32 -0
  16. package/src/modules/UploadCsvPopup/components/wt-upload-csv-popup.vue +15 -26
  17. package/src/modules/UploadCsvPopup/composable/__tests__/useUploadCsv.spec.js +393 -0
  18. package/src/modules/UploadCsvPopup/composable/useUploadCsv.ts +36 -19
  19. package/src/modules/UploadCsvPopup/index.ts +11 -0
  20. package/src/modules/UploadCsvPopup/scripts/__tests__/normalizeCSVData.spec.js +125 -0
  21. package/src/modules/UploadCsvPopup/scripts/__tests__/parseCSV.spec.js +63 -0
  22. package/src/modules/UploadCsvPopup/scripts/normalizeCSVData.ts +2 -0
  23. package/src/modules/UploadCsvPopup/scripts/parseCSV.ts +0 -23
  24. package/types/.tsbuildinfo +1 -1
  25. package/types/api/defaults/getDefaultInstance/getDefaultInstance.d.ts +1 -1
  26. package/types/modules/UploadCsvPopup/components/__tests__/wt-upload-csv-popup.spec.d.ts +1 -0
  27. package/types/modules/UploadCsvPopup/components/wt-upload-csv-popup.vue.d.ts +5 -5
  28. package/types/modules/UploadCsvPopup/composable/__tests__/useUploadCsv.spec.d.ts +1 -0
  29. package/types/modules/UploadCsvPopup/composable/useUploadCsv.d.ts +7 -3
  30. package/types/modules/UploadCsvPopup/index.d.ts +5 -0
  31. package/types/modules/UploadCsvPopup/scripts/__tests__/normalizeCSVData.spec.d.ts +1 -0
  32. package/types/modules/UploadCsvPopup/scripts/__tests__/parseCSV.spec.d.ts +1 -0
  33. package/types/modules/UploadCsvPopup/scripts/normalizeCSVData.d.ts +2 -0
  34. package/dist/clients-CWSXQd89.js +0 -40124
@@ -1,6 +1,11 @@
1
1
  import { computed, type Ref, ref, watch } from 'vue';
2
2
 
3
- import { debounce, isEmpty } from '../../../scripts';
3
+ import { useEventBus } from '../../../composables';
4
+ import {
5
+ debounce,
6
+ eventBus as defaultEventBus,
7
+ isEmpty,
8
+ } from '../../../scripts';
4
9
  import normalizeCSVData, {
5
10
  type CsvDataRow,
6
11
  type CsvMappingField,
@@ -17,12 +22,20 @@ import HandlingCSVMode from '../types/WtUploadCSVHandlingMode.enum';
17
22
  * @param {import('vue').Ref<boolean>} params.skipHeaders
18
23
  * @param {import('vue').Ref<string>} params.separator
19
24
  */
25
+
26
+ export interface UploadCsvParseSettings {
27
+ separator: string;
28
+ }
29
+
20
30
  export interface UseUploadCsvProps {
21
31
  file?: File | null;
22
32
  mappingFields?: CsvMappingField[];
23
33
  addBulkItems?: (items: unknown[]) => unknown | Promise<unknown>;
24
- handlingMode?: string;
25
- fileUploadHandler?: () => unknown | Promise<unknown>;
34
+ handlingMode?: HandlingCSVMode;
35
+ fileUploadHandler?: (
36
+ settings: UploadCsvParseSettings,
37
+ ) => unknown | Promise<unknown>;
38
+ charset?: string;
26
39
  }
27
40
 
28
41
  interface UseUploadCsvParams {
@@ -39,11 +52,12 @@ const useUploadCsv = ({
39
52
  skipHeaders,
40
53
  separator,
41
54
  }: UseUploadCsvParams) => {
55
+ const eventBus = useEventBus() ?? defaultEventBus;
56
+
42
57
  const isReadingFile = ref(false);
43
58
  const isParsingCSV = ref(false);
44
59
  const parsedFile = ref<unknown>(null);
45
60
  const isParsingPreview = ref(false);
46
- const parseErrorStackTrace = ref<unknown>('');
47
61
  const csvPreview = ref<unknown[]>([
48
62
  [],
49
63
  ]);
@@ -101,15 +115,21 @@ const useUploadCsv = ({
101
115
  ),
102
116
  );
103
117
 
118
+ function notifyError(err: unknown) {
119
+ eventBus.$emit('notification', {
120
+ type: 'error',
121
+ text: err instanceof Error ? err.message : String(err),
122
+ });
123
+ }
124
+
104
125
  async function createCSVPreview(file = parsedFile.value) {
105
126
  try {
106
- parseErrorStackTrace.value = '';
107
127
  csvPreview.value = await parseCSV(file as string, {
108
128
  ...parseCSVOptions.value,
109
129
  toLine: 4,
110
130
  });
111
131
  } catch (err) {
112
- parseErrorStackTrace.value = err;
132
+ notifyError(err);
113
133
  csvPreview.value = [
114
134
  [],
115
135
  ];
@@ -138,7 +158,9 @@ const useUploadCsv = ({
138
158
 
139
159
  isReadingFile.value = true;
140
160
 
141
- parsedFile.value = await processFile(props.file as File, {});
161
+ parsedFile.value = await processFile(props.file as File, {
162
+ charset: props.charset,
163
+ });
142
164
  await createCSVPreview(parsedFile.value);
143
165
 
144
166
  isReadingFile.value = false;
@@ -165,20 +187,17 @@ const useUploadCsv = ({
165
187
  isParsingCSV.value = true;
166
188
 
167
189
  try {
168
- parseErrorStackTrace.value = '';
169
-
170
- const handler =
171
- props.handlingMode === HandlingCSVMode.PROCESS
172
- ? handleCSVProcessing
173
- : props.fileUploadHandler;
174
-
175
- if (handler) {
176
- await handler();
190
+ if (props.handlingMode === HandlingCSVMode.PROCESS) {
191
+ await handleCSVProcessing();
192
+ } else {
193
+ await props.fileUploadHandler?.({
194
+ separator: separator.value,
195
+ });
177
196
  }
178
197
 
179
198
  close();
180
199
  } catch (err) {
181
- parseErrorStackTrace.value = err;
200
+ notifyError(err);
182
201
  throw err;
183
202
  } finally {
184
203
  isParsingCSV.value = false;
@@ -194,7 +213,6 @@ const useUploadCsv = ({
194
213
  emit('close');
195
214
  }
196
215
 
197
- // watchers (те, що були в mixin.watch)
198
216
  watch(skipHeaders, async () => {
199
217
  await handleParseOptionsChange();
200
218
  });
@@ -214,7 +232,6 @@ const useUploadCsv = ({
214
232
  isReadingFile,
215
233
  isParsingCSV,
216
234
  isParsingPreview,
217
- parseErrorStackTrace,
218
235
  csvPreviewTableData,
219
236
  csvPreviewTableHeaders,
220
237
  filteredCsvPreviewTableHeaders,
@@ -0,0 +1,11 @@
1
+ export { default as WtUploadCsvPopup } from './components/wt-upload-csv-popup.vue';
2
+ export type {
3
+ UploadCsvParseSettings,
4
+ UseUploadCsvProps,
5
+ } from './composable/useUploadCsv';
6
+ export { default as useUploadCsv } from './composable/useUploadCsv';
7
+ export type {
8
+ CsvDataRow,
9
+ CsvMappingField,
10
+ } from './scripts/normalizeCSVData';
11
+ export { HandlingCSVMode } from './types/WtUploadCSVHandlingMode.enum';
@@ -0,0 +1,125 @@
1
+ import normalizeCSVData from '../normalizeCSVData';
2
+
3
+ describe('normalizeCSVData', () => {
4
+ const mappings = [
5
+ {
6
+ // webitel field name
7
+ name: 'name',
8
+ // csv column name
9
+ csv: 'col1',
10
+ // is this webitel field required?
11
+ required: true,
12
+ // ui
13
+ locale: '',
14
+ },
15
+ {
16
+ name: 'phone',
17
+ csv: [
18
+ 'col2',
19
+ 'col3',
20
+ ],
21
+ required: true,
22
+ },
23
+ ];
24
+
25
+ it('normalizes simple data', () => {
26
+ const input = [
27
+ {
28
+ col1: 'John',
29
+ col2: '123',
30
+ col3: '456',
31
+ },
32
+ {
33
+ col1: 'Jane',
34
+ col2: '789',
35
+ col3: '012',
36
+ },
37
+ ];
38
+ const result = normalizeCSVData({
39
+ data: input,
40
+ mappings,
41
+ });
42
+ const output = [
43
+ {
44
+ name: 'John',
45
+ phone: [
46
+ '123',
47
+ '456',
48
+ ],
49
+ },
50
+ {
51
+ name: 'Jane',
52
+ phone: [
53
+ '789',
54
+ '012',
55
+ ],
56
+ },
57
+ ];
58
+ expect(result).toEqual(output);
59
+ });
60
+
61
+ it('throws an error at normalizing data with required (!) empty value', () => {
62
+ const input = [
63
+ {
64
+ col1: '',
65
+ col2: '123',
66
+ col3: '3424',
67
+ },
68
+ {
69
+ col1: 'name',
70
+ col2: '131312',
71
+ col3: '012',
72
+ },
73
+ ];
74
+ try {
75
+ normalizeCSVData({
76
+ data: input,
77
+ mappings,
78
+ });
79
+ } catch (err) {
80
+ expect(err).toBeTruthy();
81
+ return;
82
+ }
83
+ expect(false).toBe(true); // reject test if no error
84
+ });
85
+
86
+ it(`returns correct fields for mapping, including empty fields,
87
+ if one of them is empty`, () => {
88
+ const input = [
89
+ {
90
+ col1: 'name',
91
+ col2: '123',
92
+ col3: '',
93
+ },
94
+ {
95
+ col1: 'name',
96
+ col2: '123',
97
+ col3: '012',
98
+ },
99
+ ];
100
+
101
+ const result = normalizeCSVData({
102
+ data: input,
103
+ mappings,
104
+ });
105
+
106
+ const output = [
107
+ {
108
+ name: 'name',
109
+ phone: [
110
+ '123',
111
+ '',
112
+ ],
113
+ },
114
+ {
115
+ name: 'name',
116
+ phone: [
117
+ '123',
118
+ '012',
119
+ ],
120
+ },
121
+ ];
122
+
123
+ expect(result).toEqual(output);
124
+ });
125
+ });
@@ -0,0 +1,63 @@
1
+ import parseCSV from '../parseCSV';
2
+
3
+ describe('parseCSV', () => {
4
+ it('parses a csv into rows keyed by the header', async () => {
5
+ const csv = 'col1,col2\nJohn,30';
6
+
7
+ const result = await parseCSV(csv, {
8
+ columns: true,
9
+ });
10
+
11
+ expect(result).toEqual([
12
+ {
13
+ col1: 'John',
14
+ col2: '30',
15
+ },
16
+ ]);
17
+ });
18
+
19
+ /*
20
+ WTEL-10058: the parser used to coerce 'true'/'false' and JSON-looking cells
21
+ for every consumer. Type casting belongs to whoever knows the field types —
22
+ CRM does it in prepareCsvLookupRows. Everything here stays a string.
23
+ */
24
+ it.each([
25
+ 'true',
26
+ 'false',
27
+ '[1,2]',
28
+ '{"a":1}',
29
+ '42',
30
+ ])('keeps %s as a string', async (value) => {
31
+ const csv = `col1\n"${value.replaceAll('"', '""')}"`;
32
+
33
+ const result = await parseCSV(csv, {
34
+ columns: true,
35
+ });
36
+
37
+ expect(result[0].col1).toBe(value);
38
+ });
39
+
40
+ it('respects a custom delimiter', async () => {
41
+ const csv = 'col1;col2\nJohn;30';
42
+
43
+ const result = await parseCSV(csv, {
44
+ columns: true,
45
+ delimiter: ';',
46
+ });
47
+
48
+ expect(result[0]).toEqual({
49
+ col1: 'John',
50
+ col2: '30',
51
+ });
52
+ });
53
+
54
+ it('rejects on a malformed csv', async () => {
55
+ const csv = 'col1,col2\n"unterminated,30\nJane,25';
56
+
57
+ await expect(
58
+ parseCSV(csv, {
59
+ columns: true,
60
+ }),
61
+ ).rejects.toBeTruthy();
62
+ });
63
+ });
@@ -9,6 +9,8 @@ export interface CsvMappingField {
9
9
  locale?: string;
10
10
  /** the field maps to several csv columns */
11
11
  multiple?: boolean;
12
+ /** hint rendered under the mapping row */
13
+ tooltip?: string;
12
14
  }
13
15
 
14
16
  export type CsvDataRow = Record<string, unknown>;
@@ -6,29 +6,6 @@ const parseCSV = (csvStr: string, options: Options = {}): Promise<unknown[]> =>
6
6
  csvStr,
7
7
  {
8
8
  columns: true,
9
- cast: (value /* context */) => {
10
- if (typeof value !== 'string') return value;
11
-
12
- const trimmed = value.trim();
13
-
14
- // boolean
15
- if (trimmed === 'true') return true;
16
- if (trimmed === 'false') return false;
17
-
18
- // array / object (JSON)
19
- if (
20
- (trimmed.startsWith('[') && trimmed.endsWith(']')) ||
21
- (trimmed.startsWith('{') && trimmed.endsWith('}'))
22
- ) {
23
- try {
24
- return JSON.parse(trimmed);
25
- } catch {
26
- return value;
27
- }
28
- }
29
-
30
- return value;
31
- },
32
9
  ...options,
33
10
  },
34
11
  (err, output) => {