@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.
- package/package.json +6 -5
- package/src/components/on-demand/wt-upload-file-icon-btn/wt-upload-file-icon-btn.vue +77 -0
- package/src/locale/en/en.js +9 -0
- package/src/locale/es/es.js +9 -0
- package/src/locale/kz/kz.js +9 -0
- package/src/locale/pl/pl.js +9 -0
- package/src/locale/ro/ro.js +9 -0
- package/src/locale/ru/ru.js +9 -0
- package/src/locale/uk/uk.js +9 -0
- package/src/locale/uz/uz.js +9 -0
- package/src/locale/vi/vi.js +9 -0
- package/src/modules/FilesExport/{v2/composables → composables}/useFilesExport.ts +20 -4
- package/src/modules/FilesExport/{v2/index.ts → index.ts} +1 -0
- package/src/modules/FilesExport/{v2/types → types}/types.ts +2 -1
- package/src/modules/UploadCsvPopup/components/wt-upload-csv-popup.vue +266 -0
- package/src/modules/UploadCsvPopup/composable/useUploadCsv.ts +203 -0
- package/src/modules/UploadCsvPopup/scripts/normalizeCSVData.ts +60 -0
- package/src/modules/UploadCsvPopup/scripts/parseCSV.ts +13 -0
- package/src/modules/UploadCsvPopup/scripts/processFile.ts +12 -0
- package/src/modules/UploadCsvPopup/scripts/splitAndSaveData.ts +25 -0
- package/src/modules/UploadCsvPopup/types/WtUploadCSVHandlingMode.enum.ts +9 -0
- package/types/components/on-demand/wt-upload-file-icon-btn/wt-upload-file-icon-btn.vue.d.ts +12 -0
- package/types/locale/en/en.d.ts +9 -0
- package/types/locale/es/es.d.ts +9 -0
- package/types/locale/i18n.d.ts +81 -0
- package/types/locale/index.d.ts +81 -0
- package/types/locale/kz/kz.d.ts +9 -0
- package/types/locale/pl/pl.d.ts +9 -0
- package/types/locale/ro/ro.d.ts +9 -0
- package/types/locale/ru/ru.d.ts +9 -0
- package/types/locale/uk/uk.d.ts +9 -0
- package/types/locale/uz/uz.d.ts +9 -0
- package/types/locale/vi/vi.d.ts +9 -0
- package/types/modules/FilesExport/{v2/composables → composables}/useFilesExport.d.ts +1 -1
- package/types/modules/FilesExport/{v2/index.d.ts → index.d.ts} +1 -0
- package/types/modules/FilesExport/{v2/types → types}/types.d.ts +2 -1
- package/types/modules/UploadCsvPopup/components/wt-upload-csv-popup.vue.d.ts +22 -0
- package/types/modules/UploadCsvPopup/composable/useUploadCsv.d.ts +33 -0
- package/types/modules/UploadCsvPopup/scripts/normalizeCSVData.d.ts +21 -0
- package/types/modules/UploadCsvPopup/scripts/parseCSV.d.ts +2 -0
- package/types/modules/UploadCsvPopup/scripts/processFile.d.ts +4 -0
- package/types/modules/UploadCsvPopup/scripts/splitAndSaveData.d.ts +5 -0
- package/types/modules/UploadCsvPopup/types/WtUploadCSVHandlingMode.enum.d.ts +6 -0
- package/src/modules/FilesExport/FilesExport.js +0 -164
- package/src/modules/FilesExport/__tests__/FilesExport.spec.js +0 -113
- package/src/modules/FilesExport/mixins/exportFilesMixin.js +0 -71
- package/types/modules/FilesExport/FilesExport.d.ts +0 -31
- package/types/modules/FilesExport/__tests__/FilesExport.spec.d.ts +0 -1
- package/types/modules/FilesExport/mixins/exportFilesMixin.d.ts +0 -16
- /package/src/modules/FilesExport/{v2/utils → utils}/utils.ts +0 -0
- /package/types/modules/FilesExport/{v2/utils → utils}/utils.d.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webitel/ui-sdk",
|
|
3
|
-
"version": "26.2.
|
|
3
|
+
"version": "26.2.102",
|
|
4
4
|
"private": false,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"make-all": "npm version patch --git-tag-version false && npm run build && (npm run build:types || true) && (npm run biome:format:all || true) && npm run publish-lib",
|
|
@@ -111,8 +111,6 @@
|
|
|
111
111
|
}
|
|
112
112
|
},
|
|
113
113
|
"devDependencies": {
|
|
114
|
-
"@vuelidate/core": "^2.0.3",
|
|
115
|
-
"@vuelidate/validators": "^2.0.4",
|
|
116
114
|
"@biomejs/biome": "^2.3.11",
|
|
117
115
|
"@regle/core": "^1.16.2",
|
|
118
116
|
"@tsconfig/node22": "^22.0.0",
|
|
@@ -121,8 +119,11 @@
|
|
|
121
119
|
"@vue/compat": "^3.5.x",
|
|
122
120
|
"@vue/test-utils": "^2.4.6",
|
|
123
121
|
"@vue/tsconfig": "^0.8.1",
|
|
122
|
+
"@vuelidate/core": "^2.0.3",
|
|
123
|
+
"@vuelidate/validators": "^2.0.4",
|
|
124
124
|
"@webitel/styleguide": "^26.2.0-1",
|
|
125
125
|
"clipboard-copy": "^4.x",
|
|
126
|
+
"csv-parse": "^6.1.0",
|
|
126
127
|
"globals": "^16.0.0",
|
|
127
128
|
"globby": "^16.x",
|
|
128
129
|
"happy-dom": "^20.x",
|
|
@@ -306,8 +307,8 @@
|
|
|
306
307
|
"import": "./src/modules*"
|
|
307
308
|
},
|
|
308
309
|
"./modules/FilesExport": {
|
|
309
|
-
"types": "./types/modules/FilesExport/
|
|
310
|
-
"import": "./src/modules/FilesExport/
|
|
310
|
+
"types": "./types/modules/FilesExport/index.d.ts",
|
|
311
|
+
"import": "./src/modules/FilesExport/index.ts"
|
|
311
312
|
},
|
|
312
313
|
"./modules/CallSession": {
|
|
313
314
|
"types": "./types/modules/CallSession/index.d.ts",
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="wt-upload-file-icon-btn">
|
|
3
|
+
<wt-icon-btn
|
|
4
|
+
v-tooltip="t('iconHints.upload')"
|
|
5
|
+
icon="upload"
|
|
6
|
+
@click="triggerFileInput"
|
|
7
|
+
/>
|
|
8
|
+
|
|
9
|
+
<input
|
|
10
|
+
ref="fileInput"
|
|
11
|
+
:accept="accept"
|
|
12
|
+
class="wt-upload-file-icon-btn__input"
|
|
13
|
+
type="file"
|
|
14
|
+
@change="inputFileHandler"
|
|
15
|
+
>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script setup lang="ts">
|
|
20
|
+
import { ref, withDefaults } from 'vue';
|
|
21
|
+
import { useI18n } from 'vue-i18n';
|
|
22
|
+
|
|
23
|
+
defineOptions({
|
|
24
|
+
name: 'UploadFileIconBtn',
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
interface Props {
|
|
28
|
+
accept?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
32
|
+
accept: '.csv',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const emit =
|
|
36
|
+
defineEmits<(e: 'change', files: FileList | null, event: Event) => void>();
|
|
37
|
+
|
|
38
|
+
const { t } = useI18n();
|
|
39
|
+
|
|
40
|
+
const fileInput = ref<HTMLInputElement | null>(null);
|
|
41
|
+
|
|
42
|
+
const triggerFileInput = () => {
|
|
43
|
+
fileInput.value?.click();
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const clearFileInput = () => {
|
|
47
|
+
if (fileInput.value) fileInput.value.value = '';
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const inputFileHandler = (event: Event) => {
|
|
51
|
+
const target = event.target as HTMLInputElement | null;
|
|
52
|
+
const files = target?.files ?? null;
|
|
53
|
+
|
|
54
|
+
emit('change', files, event);
|
|
55
|
+
clearFileInput();
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const { accept } = props;
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<style lang="scss">
|
|
62
|
+
.wt-upload-file-icon-btn {
|
|
63
|
+
position: relative;
|
|
64
|
+
line-height: 0;
|
|
65
|
+
|
|
66
|
+
.wt-upload-file-icon-btn__input {
|
|
67
|
+
position: absolute;
|
|
68
|
+
top: -2px;
|
|
69
|
+
left: 0;
|
|
70
|
+
visibility: hidden;
|
|
71
|
+
width: 24px;
|
|
72
|
+
height: 24px;
|
|
73
|
+
cursor: pointer;
|
|
74
|
+
font-size: 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
</style>
|
package/src/locale/en/en.js
CHANGED
|
@@ -256,6 +256,15 @@ export default deepmerge(
|
|
|
256
256
|
[WebitelMediaExporterExportStatus.Failed]: 'Error',
|
|
257
257
|
},
|
|
258
258
|
},
|
|
259
|
+
importCSV: 'Import CSV',
|
|
260
|
+
CSV: {
|
|
261
|
+
skipHeaders: 'Skip headers',
|
|
262
|
+
charSet: 'Char set',
|
|
263
|
+
separator: 'Separator',
|
|
264
|
+
CSVColumn: 'CSV column',
|
|
265
|
+
fieldName: 'Field name',
|
|
266
|
+
clearMember: 'Clear member',
|
|
267
|
+
},
|
|
259
268
|
},
|
|
260
269
|
channel: {
|
|
261
270
|
state: {
|
package/src/locale/es/es.js
CHANGED
|
@@ -249,6 +249,15 @@ export default {
|
|
|
249
249
|
},
|
|
250
250
|
},
|
|
251
251
|
},
|
|
252
|
+
importCSV: 'Importar CSV',
|
|
253
|
+
CSV: {
|
|
254
|
+
skipHeaders: 'Omitir encabezados',
|
|
255
|
+
charSet: 'Conjunto de caracteres',
|
|
256
|
+
separator: 'Separador',
|
|
257
|
+
CSVColumn: 'Columna CSV',
|
|
258
|
+
fieldName: 'Nombre del campo',
|
|
259
|
+
clearMember: 'Eliminar miembro',
|
|
260
|
+
},
|
|
252
261
|
channel: {
|
|
253
262
|
state: {
|
|
254
263
|
[ChannelState.Waiting]: 'En espera',
|
package/src/locale/kz/kz.js
CHANGED
|
@@ -254,6 +254,15 @@ export default {
|
|
|
254
254
|
},
|
|
255
255
|
},
|
|
256
256
|
},
|
|
257
|
+
importCSV: 'CSV импорттау',
|
|
258
|
+
CSV: {
|
|
259
|
+
skipHeaders: 'Тақырыптарды өткізіп жіберу',
|
|
260
|
+
charSet: 'Таңбалар жиыны',
|
|
261
|
+
separator: 'Бөлгіш',
|
|
262
|
+
CSVColumn: 'CSV бағаны',
|
|
263
|
+
fieldName: 'Өріс атауы',
|
|
264
|
+
clearMember: 'Мүшені тазалау',
|
|
265
|
+
},
|
|
257
266
|
channel: {
|
|
258
267
|
state: {
|
|
259
268
|
[ChannelState.Waiting]: 'Күту',
|
package/src/locale/pl/pl.js
CHANGED
|
@@ -254,6 +254,15 @@ export default {
|
|
|
254
254
|
},
|
|
255
255
|
},
|
|
256
256
|
},
|
|
257
|
+
importCSV: 'Importuj CSV',
|
|
258
|
+
CSV: {
|
|
259
|
+
skipHeaders: 'Pomiń nagłówki',
|
|
260
|
+
charSet: 'Zestaw znaków',
|
|
261
|
+
separator: 'Separator',
|
|
262
|
+
CSVColumn: 'Kolumna CSV',
|
|
263
|
+
fieldName: 'Nazwa pola',
|
|
264
|
+
clearMember: 'Wyczyść członka',
|
|
265
|
+
},
|
|
257
266
|
channel: {
|
|
258
267
|
state: {
|
|
259
268
|
[ChannelState.Waiting]: 'Oczekiwanie',
|
package/src/locale/ro/ro.js
CHANGED
|
@@ -254,6 +254,15 @@ export default {
|
|
|
254
254
|
},
|
|
255
255
|
},
|
|
256
256
|
},
|
|
257
|
+
importCSV: 'Importă CSV',
|
|
258
|
+
CSV: {
|
|
259
|
+
skipHeaders: 'Omite anteturile',
|
|
260
|
+
charSet: 'Set de caractere',
|
|
261
|
+
separator: 'Separator',
|
|
262
|
+
CSVColumn: 'Coloană CSV',
|
|
263
|
+
fieldName: 'Nume câmp',
|
|
264
|
+
clearMember: 'Șterge membrul',
|
|
265
|
+
},
|
|
257
266
|
channel: {
|
|
258
267
|
state: {
|
|
259
268
|
[ChannelState.Waiting]: 'În așteptare',
|
package/src/locale/ru/ru.js
CHANGED
|
@@ -250,6 +250,15 @@ export default {
|
|
|
250
250
|
},
|
|
251
251
|
},
|
|
252
252
|
},
|
|
253
|
+
importCSV: 'Импорт CSV',
|
|
254
|
+
CSV: {
|
|
255
|
+
skipHeaders: 'Пропустить заголовки',
|
|
256
|
+
charSet: 'Кодировка',
|
|
257
|
+
separator: 'Разделитель',
|
|
258
|
+
CSVColumn: 'Столбец CSV',
|
|
259
|
+
fieldName: 'Имя поля',
|
|
260
|
+
clearMember: 'Очистить участника',
|
|
261
|
+
},
|
|
253
262
|
channel: {
|
|
254
263
|
state: {
|
|
255
264
|
[ChannelState.Waiting]: 'Ожидание',
|
package/src/locale/uk/uk.js
CHANGED
|
@@ -249,6 +249,15 @@ export default {
|
|
|
249
249
|
},
|
|
250
250
|
},
|
|
251
251
|
},
|
|
252
|
+
importCSV: 'Імпорт CSV',
|
|
253
|
+
CSV: {
|
|
254
|
+
skipHeaders: 'Пропустити заголовки',
|
|
255
|
+
charSet: 'Кодування',
|
|
256
|
+
separator: 'Роздільник',
|
|
257
|
+
CSVColumn: 'Стовпець CSV',
|
|
258
|
+
fieldName: 'Назва поля',
|
|
259
|
+
clearMember: 'Очистити учасника',
|
|
260
|
+
},
|
|
252
261
|
channel: {
|
|
253
262
|
state: {
|
|
254
263
|
[ChannelState.Waiting]: 'Очікування',
|
package/src/locale/uz/uz.js
CHANGED
|
@@ -255,6 +255,15 @@ export default {
|
|
|
255
255
|
},
|
|
256
256
|
},
|
|
257
257
|
},
|
|
258
|
+
importCSV: 'CSV import qilish',
|
|
259
|
+
CSV: {
|
|
260
|
+
skipHeaders: 'Sarlavhalarni o‘tkazib yuborish',
|
|
261
|
+
charSet: 'Belgilar to‘plami',
|
|
262
|
+
separator: 'Ajratgich',
|
|
263
|
+
CSVColumn: 'CSV ustuni',
|
|
264
|
+
fieldName: 'Maydon nomi',
|
|
265
|
+
clearMember: 'A’zoni tozalash',
|
|
266
|
+
},
|
|
258
267
|
channel: {
|
|
259
268
|
state: {
|
|
260
269
|
[ChannelState.Waiting]: 'Kutmoqda',
|
package/src/locale/vi/vi.js
CHANGED
|
@@ -254,6 +254,15 @@ export default {
|
|
|
254
254
|
},
|
|
255
255
|
},
|
|
256
256
|
},
|
|
257
|
+
importCSV: 'Nhập CSV',
|
|
258
|
+
CSV: {
|
|
259
|
+
skipHeaders: 'Bỏ qua tiêu đề',
|
|
260
|
+
charSet: 'Bộ ký tự',
|
|
261
|
+
separator: 'Dấu phân cách',
|
|
262
|
+
CSVColumn: 'Cột CSV',
|
|
263
|
+
fieldName: 'Tên trường',
|
|
264
|
+
clearMember: 'Xóa thành viên',
|
|
265
|
+
},
|
|
257
266
|
channel: {
|
|
258
267
|
state: {
|
|
259
268
|
[ChannelState.Waiting]: 'Đang chờ',
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import JSZip from 'jszip';
|
|
2
2
|
import { ref } from 'vue';
|
|
3
|
-
|
|
4
|
-
import {
|
|
3
|
+
|
|
4
|
+
import { _wtUiLog } from '../../../scripts/logger';
|
|
5
|
+
import {
|
|
6
|
+
ExportedItem,
|
|
7
|
+
UseFilesExportOptions,
|
|
8
|
+
UseFilesExportReturn,
|
|
9
|
+
} from '../types/types';
|
|
5
10
|
import { fetchFileBinary, handleMimeType, saveZip } from '../utils/utils';
|
|
6
11
|
|
|
7
12
|
export const useFilesExportProgress = () => {
|
|
@@ -56,6 +61,7 @@ export const useFilesExportProgress = () => {
|
|
|
56
61
|
|
|
57
62
|
export const useFilesExport = ({
|
|
58
63
|
getFileURL,
|
|
64
|
+
getFileBlob,
|
|
59
65
|
fetch,
|
|
60
66
|
filename,
|
|
61
67
|
skipFilesWithError,
|
|
@@ -70,6 +76,16 @@ export const useFilesExport = ({
|
|
|
70
76
|
reset: resetProgress,
|
|
71
77
|
} = useFilesExportProgress();
|
|
72
78
|
|
|
79
|
+
const getFile = async (item: ExportedItem) => {
|
|
80
|
+
if (getFileURL) {
|
|
81
|
+
return fetchFileBinary(getFileURL(item));
|
|
82
|
+
}
|
|
83
|
+
if (getFileBlob) {
|
|
84
|
+
return getFileBlob(item);
|
|
85
|
+
}
|
|
86
|
+
throw new Error('getFileURL or getFileBlob is required');
|
|
87
|
+
};
|
|
88
|
+
|
|
73
89
|
const fillZip = async (zip: JSZip) => {
|
|
74
90
|
let page = 1;
|
|
75
91
|
let hasNext = true;
|
|
@@ -80,9 +96,9 @@ export const useFilesExport = ({
|
|
|
80
96
|
});
|
|
81
97
|
for (const item of items) {
|
|
82
98
|
try {
|
|
83
|
-
const
|
|
99
|
+
const file = await getFile(item);
|
|
84
100
|
const itemFilename = handleMimeType(item);
|
|
85
|
-
zip.file(itemFilename,
|
|
101
|
+
zip.file(itemFilename, file);
|
|
86
102
|
updateDownloadStatus(downloadStatus.value.count + 1);
|
|
87
103
|
} catch (err) {
|
|
88
104
|
_wtUiLog.warn({
|
|
@@ -6,7 +6,8 @@ export type ExportedItem = {
|
|
|
6
6
|
} & Record<string, unknown>;
|
|
7
7
|
|
|
8
8
|
export type UseFilesExportOptions = {
|
|
9
|
-
getFileURL
|
|
9
|
+
getFileURL?: (item: ExportedItem) => string;
|
|
10
|
+
getFileBlob?: (item: ExportedItem) => Promise<Blob>;
|
|
10
11
|
fetch: ({ page, size }: { page: number; size?: number }) => Promise<{
|
|
11
12
|
items: ExportedItem[];
|
|
12
13
|
next: boolean;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<wt-popup
|
|
3
|
+
v-bind="$attrs"
|
|
4
|
+
:shown="file"
|
|
5
|
+
class="wt-upload-csv-popup"
|
|
6
|
+
@close="close"
|
|
7
|
+
>
|
|
8
|
+
<template #title>
|
|
9
|
+
{{ t('objects.importCSV') }}
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<template #main>
|
|
13
|
+
<wt-loader
|
|
14
|
+
v-show="isReadingFile"
|
|
15
|
+
class="wt-upload-csv-popup__reading-file-loader"
|
|
16
|
+
/>
|
|
17
|
+
|
|
18
|
+
<section
|
|
19
|
+
v-show="!isReadingFile"
|
|
20
|
+
class="wt-upload-csv-popup-form"
|
|
21
|
+
>
|
|
22
|
+
<wt-checkbox
|
|
23
|
+
v-model:selected="skipHeaders"
|
|
24
|
+
:label="t('objects.CSV.skipHeaders')"
|
|
25
|
+
disabled
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
<form class="wt-upload-csv-popup-form__form">
|
|
29
|
+
<wt-select
|
|
30
|
+
v-model="charset"
|
|
31
|
+
:clearable="false"
|
|
32
|
+
:label="t('objects.CSV.charSet')"
|
|
33
|
+
:options="charsetOptions"
|
|
34
|
+
disabled
|
|
35
|
+
/>
|
|
36
|
+
|
|
37
|
+
<wt-input
|
|
38
|
+
v-model="separator"
|
|
39
|
+
:label="t('objects.CSV.separator')"
|
|
40
|
+
/>
|
|
41
|
+
</form>
|
|
42
|
+
|
|
43
|
+
<!-- PREVIEW SECTION: preview loader, preview table, parsing stack trace -->
|
|
44
|
+
<section>
|
|
45
|
+
<wt-loader
|
|
46
|
+
v-if="isParsingPreview"
|
|
47
|
+
class="wt-upload-csv-popup__parsing-preview-loader"
|
|
48
|
+
/>
|
|
49
|
+
<article
|
|
50
|
+
v-else
|
|
51
|
+
class="wt-upload-csv-popup-form__file-preview"
|
|
52
|
+
>
|
|
53
|
+
<wt-table
|
|
54
|
+
:data="csvPreviewTableData"
|
|
55
|
+
:grid-actions="false"
|
|
56
|
+
:headers="csvPreviewTableHeaders"
|
|
57
|
+
:selectable="false"
|
|
58
|
+
/>
|
|
59
|
+
</article>
|
|
60
|
+
</section>
|
|
61
|
+
|
|
62
|
+
<!-- FIELDS MAPPING -->
|
|
63
|
+
<div class="wt-upload-csv-popup-mapping">
|
|
64
|
+
<div class="wt-upload-csv-popup-mapping-item">
|
|
65
|
+
<p
|
|
66
|
+
class="wt-upload-csv-popup-mapping-item__field typo-subtitle-1"
|
|
67
|
+
>
|
|
68
|
+
{{ t('objects.CSV.fieldName') }}
|
|
69
|
+
</p>
|
|
70
|
+
<p
|
|
71
|
+
class="wt-upload-csv-popup-mapping-item__field typo-subtitle-1"
|
|
72
|
+
>
|
|
73
|
+
{{ t('objects.CSV.CSVColumn') }}
|
|
74
|
+
</p>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<div
|
|
78
|
+
v-for="(field, key) in mappingFields"
|
|
79
|
+
:key="key"
|
|
80
|
+
class="wt-upload-csv-popup-mapping-item"
|
|
81
|
+
>
|
|
82
|
+
<p class="wt-upload-csv-popup-mapping-item__field">
|
|
83
|
+
{{ t(field.locale) }}<span v-if="field.required">*</span>
|
|
84
|
+
</p>
|
|
85
|
+
|
|
86
|
+
<wt-select
|
|
87
|
+
v-if="!field.multiple"
|
|
88
|
+
v-model="field.csv"
|
|
89
|
+
:clearable="!field.required"
|
|
90
|
+
:options="csvColumns"
|
|
91
|
+
:placeholder="t(field.locale)"
|
|
92
|
+
:track-by="null"
|
|
93
|
+
class="wt-upload-csv-popup-mapping-item__select"
|
|
94
|
+
/>
|
|
95
|
+
<wt-tags-input
|
|
96
|
+
v-else
|
|
97
|
+
v-model="field.csv"
|
|
98
|
+
:options="csvColumns"
|
|
99
|
+
:placeholder="t(field.locale)"
|
|
100
|
+
class="wt-upload-csv-popup-mapping-item__select"
|
|
101
|
+
/>
|
|
102
|
+
|
|
103
|
+
<div
|
|
104
|
+
v-if="field.tooltip"
|
|
105
|
+
class="upload-tooltip"
|
|
106
|
+
>
|
|
107
|
+
{{ field.tooltip }}
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</section>
|
|
112
|
+
|
|
113
|
+
<div
|
|
114
|
+
v-show="!isParsingPreview && parseErrorStackTrace"
|
|
115
|
+
class="wt-upload-csv-popup-form__error-stack-trace"
|
|
116
|
+
>
|
|
117
|
+
{{ parseErrorStackTrace }}
|
|
118
|
+
</div>
|
|
119
|
+
</template>
|
|
120
|
+
|
|
121
|
+
<template
|
|
122
|
+
v-if="!isReadingFile"
|
|
123
|
+
#actions
|
|
124
|
+
>
|
|
125
|
+
<wt-button
|
|
126
|
+
:disabled="!allowSaveAction"
|
|
127
|
+
:loading="isParsingCSV"
|
|
128
|
+
@click="processCSV"
|
|
129
|
+
>
|
|
130
|
+
{{ t('reusable.save') }}
|
|
131
|
+
</wt-button>
|
|
132
|
+
<wt-button
|
|
133
|
+
color="secondary"
|
|
134
|
+
@click="close"
|
|
135
|
+
>
|
|
136
|
+
{{ t('reusable.close') }}
|
|
137
|
+
</wt-button>
|
|
138
|
+
</template>
|
|
139
|
+
</wt-popup>
|
|
140
|
+
</template>
|
|
141
|
+
|
|
142
|
+
<script setup lang="ts">
|
|
143
|
+
import { defineEmits, defineProps, ref, toRefs, withDefaults } from 'vue';
|
|
144
|
+
import { useI18n } from 'vue-i18n';
|
|
145
|
+
|
|
146
|
+
import useUploadCsv from '../composable/useUploadCsv';
|
|
147
|
+
import HandlingCSVMode from '../types/WtUploadCSVHandlingMode.enum';
|
|
148
|
+
|
|
149
|
+
interface CharsetOption {
|
|
150
|
+
name: string;
|
|
151
|
+
value: string;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interface Props {
|
|
155
|
+
file: File | null;
|
|
156
|
+
mappingFields: unknown[];
|
|
157
|
+
addBulkItems?: (items: unknown[]) => unknown | Promise<unknown>;
|
|
158
|
+
handlingMode?: string;
|
|
159
|
+
fileUploadHandler?: () => unknown | Promise<unknown>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
163
|
+
file: null,
|
|
164
|
+
mappingFields: () => [],
|
|
165
|
+
handlingMode: HandlingCSVMode.PROCESS,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const emit = defineEmits<{
|
|
169
|
+
(e: 'changeMappingFields', value: unknown[]): void;
|
|
170
|
+
(e: 'save'): void;
|
|
171
|
+
(e: 'close'): void;
|
|
172
|
+
}>();
|
|
173
|
+
|
|
174
|
+
const { t } = useI18n();
|
|
175
|
+
|
|
176
|
+
const skipHeaders = ref(true);
|
|
177
|
+
const separator = ref(',');
|
|
178
|
+
const charsetOptions = ref<CharsetOption[]>([]);
|
|
179
|
+
const charset = ref<CharsetOption>({
|
|
180
|
+
name: 'UTF-8',
|
|
181
|
+
value: 'utf-8',
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const { file, mappingFields } = toRefs(props);
|
|
185
|
+
|
|
186
|
+
const {
|
|
187
|
+
isReadingFile,
|
|
188
|
+
isParsingCSV,
|
|
189
|
+
isParsingPreview,
|
|
190
|
+
parseErrorStackTrace,
|
|
191
|
+
csvPreviewTableData,
|
|
192
|
+
csvPreviewTableHeaders,
|
|
193
|
+
csvColumns,
|
|
194
|
+
allowSaveAction,
|
|
195
|
+
processCSV,
|
|
196
|
+
close,
|
|
197
|
+
} = useUploadCsv({
|
|
198
|
+
props,
|
|
199
|
+
emit,
|
|
200
|
+
skipHeaders,
|
|
201
|
+
separator,
|
|
202
|
+
});
|
|
203
|
+
</script>
|
|
204
|
+
|
|
205
|
+
<style lang="scss">
|
|
206
|
+
.wt-upload-csv-popup {
|
|
207
|
+
:deep(.wt-popup__popup) {
|
|
208
|
+
min-height: 40vh;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.wt-upload-csv-popup__reading-file-loader {
|
|
212
|
+
position: absolute;
|
|
213
|
+
top: 50%;
|
|
214
|
+
left: 50%;
|
|
215
|
+
transform: translate(-50%, -50%);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.wt-upload-csv-popup-form__form {
|
|
219
|
+
display: grid;
|
|
220
|
+
align-items: flex-start;
|
|
221
|
+
grid-template-columns: 1fr 1fr;
|
|
222
|
+
grid-auto-rows: minmax(40px, auto);
|
|
223
|
+
grid-column-gap: 20px;
|
|
224
|
+
grid-row-gap: 10px;
|
|
225
|
+
margin: var(--spacing-sm) 0;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.wt-upload-csv-popup__parsing-preview-loader {
|
|
229
|
+
margin: auto;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.wt-upload-csv-popup-form__file-preview .wt-table {
|
|
233
|
+
overflow: auto;
|
|
234
|
+
max-width: 60vw;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.wt-upload-csv-popup-mapping {
|
|
238
|
+
.wt-upload-csv-popup-mapping-item {
|
|
239
|
+
display: grid;
|
|
240
|
+
align-items: flex-start;
|
|
241
|
+
grid-template-columns: 1fr 1fr;
|
|
242
|
+
grid-auto-rows: minmax(40px, auto);
|
|
243
|
+
grid-column-gap: 20px;
|
|
244
|
+
grid-row-gap: 10px;
|
|
245
|
+
margin-bottom: var(--spacing-sm);
|
|
246
|
+
|
|
247
|
+
&__field {
|
|
248
|
+
align-self: center;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
&__select :deep(.wt-label),
|
|
252
|
+
&__select :deep(.wt-input-info) {
|
|
253
|
+
display: none;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.wt-upload-csv-popup-form__error-stack-trace {
|
|
259
|
+
margin-top: var(--spacing-sm);
|
|
260
|
+
padding: var(--spacing-sm);
|
|
261
|
+
color: var(--error-color);
|
|
262
|
+
border-radius: var(--border-radius);
|
|
263
|
+
background: var(--secondary-color);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
</style>
|