@webitel/ui-sdk 26.2.100 → 26.2.102

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 (51) hide show
  1. package/package.json +6 -5
  2. package/src/components/on-demand/wt-upload-file-icon-btn/wt-upload-file-icon-btn.vue +77 -0
  3. package/src/locale/en/en.js +9 -0
  4. package/src/locale/es/es.js +9 -0
  5. package/src/locale/kz/kz.js +9 -0
  6. package/src/locale/pl/pl.js +9 -0
  7. package/src/locale/ro/ro.js +9 -0
  8. package/src/locale/ru/ru.js +9 -0
  9. package/src/locale/uk/uk.js +9 -0
  10. package/src/locale/uz/uz.js +9 -0
  11. package/src/locale/vi/vi.js +9 -0
  12. package/src/modules/FilesExport/{v2/composables → composables}/useFilesExport.ts +20 -4
  13. package/src/modules/FilesExport/{v2/index.ts → index.ts} +1 -0
  14. package/src/modules/FilesExport/{v2/types → types}/types.ts +2 -1
  15. package/src/modules/UploadCsvPopup/components/wt-upload-csv-popup.vue +266 -0
  16. package/src/modules/UploadCsvPopup/composable/useUploadCsv.ts +203 -0
  17. package/src/modules/UploadCsvPopup/scripts/normalizeCSVData.ts +60 -0
  18. package/src/modules/UploadCsvPopup/scripts/parseCSV.ts +13 -0
  19. package/src/modules/UploadCsvPopup/scripts/processFile.ts +12 -0
  20. package/src/modules/UploadCsvPopup/scripts/splitAndSaveData.ts +25 -0
  21. package/src/modules/UploadCsvPopup/types/WtUploadCSVHandlingMode.enum.ts +9 -0
  22. package/types/components/on-demand/wt-upload-file-icon-btn/wt-upload-file-icon-btn.vue.d.ts +12 -0
  23. package/types/locale/en/en.d.ts +9 -0
  24. package/types/locale/es/es.d.ts +9 -0
  25. package/types/locale/i18n.d.ts +81 -0
  26. package/types/locale/index.d.ts +81 -0
  27. package/types/locale/kz/kz.d.ts +9 -0
  28. package/types/locale/pl/pl.d.ts +9 -0
  29. package/types/locale/ro/ro.d.ts +9 -0
  30. package/types/locale/ru/ru.d.ts +9 -0
  31. package/types/locale/uk/uk.d.ts +9 -0
  32. package/types/locale/uz/uz.d.ts +9 -0
  33. package/types/locale/vi/vi.d.ts +9 -0
  34. package/types/modules/FilesExport/{v2/composables → composables}/useFilesExport.d.ts +1 -1
  35. package/types/modules/FilesExport/{v2/index.d.ts → index.d.ts} +1 -0
  36. package/types/modules/FilesExport/{v2/types → types}/types.d.ts +2 -1
  37. package/types/modules/UploadCsvPopup/components/wt-upload-csv-popup.vue.d.ts +22 -0
  38. package/types/modules/UploadCsvPopup/composable/useUploadCsv.d.ts +33 -0
  39. package/types/modules/UploadCsvPopup/scripts/normalizeCSVData.d.ts +21 -0
  40. package/types/modules/UploadCsvPopup/scripts/parseCSV.d.ts +2 -0
  41. package/types/modules/UploadCsvPopup/scripts/processFile.d.ts +4 -0
  42. package/types/modules/UploadCsvPopup/scripts/splitAndSaveData.d.ts +5 -0
  43. package/types/modules/UploadCsvPopup/types/WtUploadCSVHandlingMode.enum.d.ts +6 -0
  44. package/src/modules/FilesExport/FilesExport.js +0 -164
  45. package/src/modules/FilesExport/__tests__/FilesExport.spec.js +0 -113
  46. package/src/modules/FilesExport/mixins/exportFilesMixin.js +0 -71
  47. package/types/modules/FilesExport/FilesExport.d.ts +0 -31
  48. package/types/modules/FilesExport/__tests__/FilesExport.spec.d.ts +0 -1
  49. package/types/modules/FilesExport/mixins/exportFilesMixin.d.ts +0 -16
  50. /package/src/modules/FilesExport/{v2/utils → utils}/utils.ts +0 -0
  51. /package/types/modules/FilesExport/{v2/utils → utils}/utils.d.ts +0 -0
@@ -239,6 +239,15 @@ declare namespace _default {
239
239
  export { status_2 as status };
240
240
  }
241
241
  }
242
+ export let importCSV: string;
243
+ export namespace CSV {
244
+ let skipHeaders: string;
245
+ let charSet: string;
246
+ let separator: string;
247
+ let CSVColumn: string;
248
+ let fieldName: string;
249
+ let clearMember: string;
250
+ }
242
251
  export namespace channel_1 {
243
252
  let state_1: {
244
253
  [x: number]: string;
@@ -239,6 +239,15 @@ declare namespace _default {
239
239
  export { status_2 as status };
240
240
  }
241
241
  }
242
+ export let importCSV: string;
243
+ export namespace CSV {
244
+ let skipHeaders: string;
245
+ let charSet: string;
246
+ let separator: string;
247
+ let CSVColumn: string;
248
+ let fieldName: string;
249
+ let clearMember: string;
250
+ }
242
251
  export namespace channel_1 {
243
252
  let state_1: {
244
253
  [x: number]: string;
@@ -242,6 +242,15 @@ declare namespace _default {
242
242
  export { status_2 as status };
243
243
  }
244
244
  }
245
+ export let importCSV: string;
246
+ export namespace CSV {
247
+ let skipHeaders: string;
248
+ let charSet: string;
249
+ let separator: string;
250
+ let CSVColumn: string;
251
+ let fieldName: string;
252
+ let clearMember: string;
253
+ }
245
254
  export namespace channel_1 {
246
255
  let state_1: {
247
256
  [x: number]: string;
@@ -241,6 +241,15 @@ declare namespace _default {
241
241
  export { status_2 as status };
242
242
  }
243
243
  }
244
+ export let importCSV: string;
245
+ export namespace CSV {
246
+ let skipHeaders: string;
247
+ let charSet: string;
248
+ let separator: string;
249
+ let CSVColumn: string;
250
+ let fieldName: string;
251
+ let clearMember: string;
252
+ }
244
253
  export namespace channel_1 {
245
254
  let state_1: {
246
255
  [x: number]: string;
@@ -20,4 +20,4 @@ export declare const useFilesExportProgress: () => {
20
20
  updateZippingStatus: (percent: number) => void;
21
21
  reset: () => void;
22
22
  };
23
- export declare const useFilesExport: ({ getFileURL, fetch, filename, skipFilesWithError, }: UseFilesExportOptions) => UseFilesExportReturn;
23
+ export declare const useFilesExport: ({ getFileURL, getFileBlob, fetch, filename, skipFilesWithError, }: UseFilesExportOptions) => UseFilesExportReturn;
@@ -1 +1,2 @@
1
1
  export { useFilesExport } from './composables/useFilesExport';
2
+ export type { ExportedItem } from './types/types';
@@ -4,7 +4,8 @@ export type ExportedItem = {
4
4
  mimeType?: string;
5
5
  } & Record<string, unknown>;
6
6
  export type UseFilesExportOptions = {
7
- getFileURL: (item: ExportedItem) => string;
7
+ getFileURL?: (item: ExportedItem) => string;
8
+ getFileBlob?: (item: ExportedItem) => Promise<Blob>;
8
9
  fetch: ({ page, size }: {
9
10
  page: number;
10
11
  size?: number;
@@ -0,0 +1,22 @@
1
+ interface Props {
2
+ file: File | null;
3
+ mappingFields: unknown[];
4
+ addBulkItems?: (items: unknown[]) => unknown | Promise<unknown>;
5
+ handlingMode?: string;
6
+ fileUploadHandler?: () => unknown | Promise<unknown>;
7
+ }
8
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
9
+ close: () => any;
10
+ save: () => any;
11
+ changeMappingFields: (value: unknown[]) => any;
12
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
13
+ onClose?: () => any;
14
+ onSave?: () => any;
15
+ onChangeMappingFields?: (value: unknown[]) => any;
16
+ }>, {
17
+ file: File | null;
18
+ mappingFields: unknown[];
19
+ handlingMode: string;
20
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @param {Object} params
3
+ * @param {Object} params.props - component props (file, mappingFields, handlingMode, addBulkItems, fileUploadHandler)
4
+ * @param {Function} params.emit - emit from setup
5
+ * @param {import('vue').Ref<boolean>} params.skipHeaders
6
+ * @param {import('vue').Ref<string>} params.separator
7
+ */
8
+ declare const useUploadCsv: ({ props, emit, skipHeaders, separator }: {
9
+ props: any;
10
+ emit: any;
11
+ skipHeaders: any;
12
+ separator: any;
13
+ }) => {
14
+ isReadingFile: import("vue").Ref<boolean, boolean>;
15
+ isParsingCSV: import("vue").Ref<boolean, boolean>;
16
+ isParsingPreview: import("vue").Ref<boolean, boolean>;
17
+ parseErrorStackTrace: import("vue").Ref<string, string>;
18
+ csvPreviewTableData: import("vue").ComputedRef<any[][]>;
19
+ csvPreviewTableHeaders: import("vue").ComputedRef<{
20
+ text: string;
21
+ value: string;
22
+ }[]>;
23
+ filteredCsvPreviewTableHeaders: import("vue").ComputedRef<{
24
+ text: string;
25
+ value: string;
26
+ }[]>;
27
+ csvColumns: import("vue").ComputedRef<string[]>;
28
+ allowSaveAction: import("vue").ComputedRef<any>;
29
+ processCSV: () => Promise<void>;
30
+ handleSave: () => Promise<void>;
31
+ close: () => void;
32
+ };
33
+ export default useUploadCsv;
@@ -0,0 +1,21 @@
1
+ /**
2
+ *
3
+ * @param data
4
+ * @param mappings
5
+ *
6
+ * Data format: {
7
+ * [colName]: [value]
8
+ * }
9
+ *
10
+ * Mappings format: {
11
+ * name: string, // webitel field name
12
+ * csv: string | string[], // csv column name
13
+ * required: boolean, // is this webitel field required?
14
+ * locale: string, // ui
15
+ * }
16
+ */
17
+ declare const normalizeCSVData: ({ data, mappings }: {
18
+ data: any;
19
+ mappings: any;
20
+ }) => any;
21
+ export default normalizeCSVData;
@@ -0,0 +1,2 @@
1
+ declare const parseCSV: (csvStr: any, options?: {}) => Promise<unknown>;
2
+ export default parseCSV;
@@ -0,0 +1,4 @@
1
+ declare const processFile: (file: any, { charset }?: {
2
+ charset?: string;
3
+ }) => Promise<unknown>;
4
+ export default processFile;
@@ -0,0 +1,5 @@
1
+ declare const splitAndSaveData: ({ data, saveCallback }: {
2
+ data: any;
3
+ saveCallback: any;
4
+ }) => Promise<void>;
5
+ export default splitAndSaveData;
@@ -0,0 +1,6 @@
1
+ export declare const HandlingCSVMode: {
2
+ readonly UPLOAD: "upload";
3
+ readonly PROCESS: "process";
4
+ };
5
+ export type HandlingCSVMode = (typeof HandlingCSVMode)[keyof typeof HandlingCSVMode];
6
+ export default HandlingCSVMode;
@@ -1,164 +0,0 @@
1
- import { getCallMediaUrl } from '@webitel/api-services/api';
2
- import { EngineCallFileType } from '@webitel/api-services/gen/models';
3
- import { saveAs } from 'file-saver-es';
4
- import JSZip from 'jszip';
5
- import jszipUtils from 'jszip-utils';
6
- import path from 'path-browserify';
7
-
8
- import { _wtUiLog } from '../../scripts/logger.js';
9
-
10
- export default class FilesExport {
11
- filename = 'files';
12
-
13
- fetchMethod = null;
14
-
15
- isLoading = false;
16
-
17
- skipFilesWithError = false;
18
-
19
- downloadProgress = {
20
- count: 0,
21
- };
22
-
23
- zippingProgress = {
24
- percent: 0,
25
- };
26
-
27
- filesURL = getCallMediaUrl;
28
-
29
- constructor({ fetchMethod, filename, filesURL, skipFilesWithError = false }) {
30
- if (fetchMethod) this.fetchMethod = fetchMethod;
31
- if (filename) this.filename = filename;
32
- if (filesURL) this.filesURL = filesURL;
33
- this.skipFilesWithError = skipFilesWithError;
34
- }
35
-
36
- _fetchFileBinary(fileId) {
37
- const url = this.filesURL(fileId);
38
- return new Promise((resolve, reject) =>
39
- jszipUtils.getBinaryContent(url, (err, data) => {
40
- if (err) {
41
- reject(err);
42
- } else {
43
- resolve(data);
44
- }
45
- }),
46
- );
47
- }
48
-
49
- resetProgress() {
50
- this.downloadProgress = {
51
- count: 0,
52
- };
53
- this.zippingProgress = {
54
- percent: 0,
55
- };
56
- }
57
-
58
- // Recursively adds files to zip archive, filtering by fileType
59
- // Supports FileTypeAudio, FileTypeVideo, FileTypeScreensharing (defaults to FileTypeAudio)
60
- async _addFilesToZip(
61
- items,
62
- zip,
63
- fileType = EngineCallFileType.FileTypeAudio,
64
- ) {
65
- for (const item of items) {
66
- if (item.files) {
67
- // If item has nested files object, filter by fileType and recurse
68
- if (item.files?.[fileType]) {
69
- await this._addFilesToZip(item.files[fileType], zip, fileType);
70
- } else continue;
71
- } else {
72
- try {
73
- const binary = await this._fetchFileBinary(item.id);
74
- const ext = item.mimeType.split('/').pop();
75
- // itemName needed to remove extension from item.name https://stackoverflow.com/a/31615711
76
- const itemName = path.parse(item.name).name;
77
- zip.file(`${itemName}.${ext}`, binary);
78
- this.downloadProgress.count += 1;
79
- } catch (err) {
80
- _wtUiLog.warn({
81
- entity: 'script',
82
- module: 'FilesExport',
83
- })(`An error occurred while downloading a file id=${item.id}`, err);
84
- if (!this.skipFilesWithError) {
85
- throw err;
86
- }
87
- }
88
- }
89
- }
90
- }
91
-
92
- async _generateZip(zip) {
93
- try {
94
- return await zip.generateAsync(
95
- {
96
- type: 'blob',
97
- },
98
- (progress) => {
99
- this.zippingProgress = progress;
100
- },
101
- );
102
- } catch (err) {
103
- throw new Error('Failed to generate zip file');
104
- }
105
- }
106
-
107
- async _saveZip(file) {
108
- try {
109
- saveAs(file, `${this.filename}.zip`);
110
- } catch (err) {
111
- throw new Error('Failed to save a file');
112
- }
113
- }
114
-
115
- // Fetches history items and adds files of specified type to zip
116
- async _fetchAndZip(zip, requestParams, fileType) {
117
- const params = {
118
- from: 0,
119
- size: 5000,
120
- fields: [
121
- 'files',
122
- ],
123
- ...requestParams,
124
- };
125
-
126
- let page = 1;
127
- let isNext = false;
128
- do {
129
- const { items, next } = await this.fetchMethod({
130
- ...params,
131
- page,
132
- });
133
- // Filter and add files of the specified type
134
- await this._addFilesToZip(items, zip, fileType);
135
-
136
- isNext = next;
137
- page += 1;
138
- } while (isNext);
139
- }
140
-
141
- // Exports files to a zip archive
142
- // fileType: FileTypeAudio (default), FileTypeVideo, or FileTypeScreensharing
143
- async exportFiles(
144
- files,
145
- { reqParams, fileType = EngineCallFileType.FileTypeAudio },
146
- ) {
147
- try {
148
- this.isLoading = true;
149
- const zip = new JSZip();
150
- // If files provided, use them; otherwise fetch from API with fileType filter
151
- if (files?.length) await this._addFilesToZip(files, zip, fileType);
152
- else {
153
- await this._fetchAndZip(zip, reqParams, fileType);
154
- }
155
- const file = await this._generateZip(zip);
156
- await this._saveZip(file);
157
- this.resetProgress();
158
- } catch (err) {
159
- throw err;
160
- } finally {
161
- this.isLoading = false;
162
- }
163
- }
164
- }
@@ -1,113 +0,0 @@
1
- import '../../../../tests/mocks/localStorageMock';
2
-
3
- import { shallowMount } from '@vue/test-utils';
4
- import * as fileSaver from 'file-saver-es';
5
- import jszip from 'jszip';
6
- import jszipUtils from 'jszip-utils';
7
-
8
- import FilesExportMixin from '../mixins/exportFilesMixin.js';
9
-
10
- vi.mock('jszip');
11
- vi.mock('jszip-utils');
12
- vi.mock('file-saver-es', () => ({
13
- saveAs: vi.fn(),
14
- }));
15
-
16
- const dataList = [
17
- {
18
- files: [
19
- {
20
- name: 'jest',
21
- id: '1',
22
- mimeType: 'mime/type',
23
- },
24
- ],
25
- },
26
- ];
27
- const selectedDataList = [
28
- {
29
- _isSelected: true,
30
- files: [
31
- {
32
- name: 'jest1',
33
- id: '1',
34
- mimeType: 'mime/type',
35
- },
36
- ],
37
- },
38
- {
39
- _isSelected: true,
40
- files: [
41
- {
42
- name: 'jest2',
43
- id: '2',
44
- mimeType: 'mime/type',
45
- },
46
- ],
47
- },
48
- ];
49
-
50
- describe('File Export', () => {
51
- jszipUtils.getBinaryContent.mockImplementation((url, callback) =>
52
- callback(null, {}),
53
- );
54
- let wrapper;
55
- const Component = {
56
- render() {},
57
- mixins: [
58
- FilesExportMixin,
59
- ],
60
- created() {
61
- this.initFilesExport({
62
- fetchMethod: () => ({
63
- items: dataList,
64
- }),
65
- filename: 'jest',
66
- });
67
- },
68
- data: () => ({
69
- dataList,
70
- }),
71
- };
72
-
73
- it('goes through all important steps to save file', async () => {
74
- wrapper = shallowMount(Component);
75
- await wrapper.vm.exportFiles();
76
- expect(jszip).toHaveBeenCalled();
77
- expect(jszipUtils.getBinaryContent).toHaveBeenCalled();
78
- expect(fileSaver.saveAs).toHaveBeenCalled();
79
- });
80
-
81
- it('mixin correctly computes empty export progress from class data', () => {
82
- wrapper = shallowMount(Component);
83
- expect(wrapper.vm.filesDownloadProgress).toBe(0);
84
- expect(wrapper.vm.filesZippingProgress).toBe(0);
85
- });
86
-
87
- it('mixin correctly computes selectedFiles()', () => {
88
- wrapper = shallowMount(Component, {
89
- computed: {
90
- selectedItems() {
91
- return selectedDataList;
92
- },
93
- },
94
- });
95
- expect(wrapper.vm.getSelectedFiles()).toEqual([
96
- ...selectedDataList[0].files,
97
- ...selectedDataList[1].files,
98
- ]);
99
- });
100
-
101
- it('mixin catches export error and resets isFilesLoading on export error', async () => {
102
- wrapper = shallowMount(Component);
103
- wrapper.vm.FilesExport = null; // like FilesExport wasn't initialized
104
- // wrapper.vm.FilesExport.exportFiles = function () { throw new Error(); };
105
- // await expect(async () => Promise.reject(await wrapper.vm.exportFiles())).rejects.toThrowError();
106
- try {
107
- await wrapper.vm.exportFiles();
108
- } catch (err) {
109
- expect(err).toBeTruthy();
110
- expect(wrapper.vm.isFilesLoading).toBeFalsy();
111
- }
112
- });
113
- });
@@ -1,71 +0,0 @@
1
- import { EngineCallFileType } from '@webitel/api-services/gen/models';
2
-
3
- import FilesExport from '../FilesExport.js';
4
-
5
- export default {
6
- data: () => ({
7
- FilesExport: null,
8
- }),
9
-
10
- computed: {
11
- isFilesLoading() {
12
- return this.FilesExport?.isLoading;
13
- },
14
-
15
- filesDownloadProgress() {
16
- return this.FilesExport ? this.FilesExport.downloadProgress.count : 0;
17
- },
18
-
19
- filesZippingProgress() {
20
- return this.FilesExport
21
- ? Math.floor(this.FilesExport.zippingProgress.percent)
22
- : 0;
23
- },
24
- },
25
-
26
- methods: {
27
- initFilesExport(options) {
28
- this.FilesExport = new FilesExport(options);
29
- },
30
-
31
- // Gets selected files of a specific type from selectedItems
32
- // fileType: FileTypeAudio (default), FileTypeVideo, or FileTypeScreensharing
33
- getSelectedFiles(fileType = EngineCallFileType.FileTypeAudio) {
34
- let files = null;
35
- if (this.selectedItems?.length) {
36
- files = this.selectedItems.reduce(
37
- (filesAccumulator, next) =>
38
- // Check if item has files and contains files of the specified type
39
- next.files && next.files[fileType]
40
- ? [
41
- ...filesAccumulator,
42
- ...next.files[fileType],
43
- ]
44
- : filesAccumulator,
45
- [],
46
- );
47
- }
48
- return files;
49
- },
50
-
51
- // Exports files of a specific type to a zip archive
52
- // fileType: FileTypeAudio (default), FileTypeVideo, or FileTypeScreensharing
53
- async exportFiles(
54
- files,
55
- reqParams = {},
56
- fileType = EngineCallFileType.FileTypeAudio,
57
- ) {
58
- if (!this.FilesExport) throw new Error('FilesExport is not initialized');
59
- // Use provided files or get from selectedItems filtered by fileType
60
- const exportFiles = files || this.getSelectedFiles(fileType);
61
- try {
62
- await this.FilesExport.exportFiles(exportFiles, {
63
- reqParams,
64
- fileType,
65
- });
66
- } catch (err) {
67
- throw err;
68
- }
69
- },
70
- },
71
- };
@@ -1,31 +0,0 @@
1
- export default class FilesExport {
2
- constructor({ fetchMethod, filename, filesURL, skipFilesWithError }: {
3
- fetchMethod: any;
4
- filename: any;
5
- filesURL: any;
6
- skipFilesWithError?: boolean;
7
- });
8
- filename: string;
9
- fetchMethod: any;
10
- isLoading: boolean;
11
- skipFilesWithError: boolean;
12
- downloadProgress: {
13
- count: number;
14
- };
15
- zippingProgress: {
16
- percent: number;
17
- };
18
- filesURL: (id: any, { download }?: {
19
- download?: boolean;
20
- }) => string;
21
- _fetchFileBinary(fileId: any): Promise<any>;
22
- resetProgress(): void;
23
- _addFilesToZip(items: any, zip: any, fileType?: "file_type_audio"): Promise<void>;
24
- _generateZip(zip: any): Promise<any>;
25
- _saveZip(file: any): Promise<void>;
26
- _fetchAndZip(zip: any, requestParams: any, fileType: any): Promise<void>;
27
- exportFiles(files: any, { reqParams, fileType }: {
28
- reqParams: any;
29
- fileType?: "file_type_audio";
30
- }): Promise<void>;
31
- }
@@ -1,16 +0,0 @@
1
- declare namespace _default {
2
- function data(): {
3
- FilesExport: any;
4
- };
5
- namespace computed {
6
- function isFilesLoading(): any;
7
- function filesDownloadProgress(): any;
8
- function filesZippingProgress(): number;
9
- }
10
- namespace methods {
11
- function initFilesExport(options: any): void;
12
- function getSelectedFiles(fileType?: "file_type_audio"): any;
13
- function exportFiles(files: any, reqParams?: {}, fileType?: "file_type_audio"): Promise<void>;
14
- }
15
- }
16
- export default _default;