@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-sdk",
3
- "version": "26.2.100",
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/v2/index.d.ts",
310
- "import": "./src/modules/FilesExport/v2/index.ts"
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>
@@ -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: {
@@ -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',
@@ -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]: 'Күту',
@@ -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',
@@ -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',
@@ -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]: 'Ожидание',
@@ -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]: 'Очікування',
@@ -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',
@@ -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
- import { _wtUiLog } from '../../../../scripts/logger';
4
- import { UseFilesExportOptions, UseFilesExportReturn } from '../types/types';
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 binary = await fetchFileBinary(getFileURL(item));
99
+ const file = await getFile(item);
84
100
  const itemFilename = handleMimeType(item);
85
- zip.file(itemFilename, binary);
101
+ zip.file(itemFilename, file);
86
102
  updateDownloadStatus(downloadStatus.value.count + 1);
87
103
  } catch (err) {
88
104
  _wtUiLog.warn({
@@ -1 +1,2 @@
1
1
  export { useFilesExport } from './composables/useFilesExport';
2
+ export type { ExportedItem } from './types/types';
@@ -6,7 +6,8 @@ export type ExportedItem = {
6
6
  } & Record<string, unknown>;
7
7
 
8
8
  export type UseFilesExportOptions = {
9
- getFileURL: (item: ExportedItem) => string;
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>