vgapp 1.5.7 → 1.5.8
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/app/langs/en/buttons.json +17 -17
- package/app/langs/en/messages.json +36 -36
- package/app/langs/ru/buttons.json +17 -17
- package/app/langs/ru/messages.json +1 -1
- package/app/modules/vgalert/js/vgalert.js +7 -7
- package/app/modules/vgalert/scss/_variables.scss +16 -16
- package/app/modules/vgcollapse/scss/_variables.scss +7 -7
- package/app/modules/vgcollapse/scss/vgcollapse.scss +5 -5
- package/app/modules/vgdropdown/scss/_variables.scss +14 -14
- package/app/modules/vgdropdown/scss/vgdropdown.scss +5 -5
- package/app/modules/vgfilepreview/js/i18n.js +56 -56
- package/app/modules/vgfilepreview/js/renderers/image-modal.js +145 -145
- package/app/modules/vgfilepreview/js/renderers/image.js +92 -92
- package/app/modules/vgfilepreview/js/renderers/index.js +19 -19
- package/app/modules/vgfilepreview/js/renderers/office-modal.js +168 -168
- package/app/modules/vgfilepreview/js/renderers/office.js +79 -79
- package/app/modules/vgfilepreview/js/renderers/pdf-modal.js +260 -260
- package/app/modules/vgfilepreview/js/renderers/pdf.js +76 -76
- package/app/modules/vgfilepreview/js/renderers/playlist.js +71 -71
- package/app/modules/vgfilepreview/js/renderers/text-modal.js +343 -343
- package/app/modules/vgfilepreview/js/renderers/text.js +83 -83
- package/app/modules/vgfilepreview/js/renderers/zip-modal.js +522 -522
- package/app/modules/vgfilepreview/js/renderers/zip.js +89 -89
- package/app/modules/vgfilepreview/readme.md +68 -68
- package/app/modules/vgfiles/js/base.js +198 -198
- package/app/modules/vgfiles/js/droppable.js +17 -17
- package/app/modules/vgfiles/js/render.js +153 -153
- package/app/modules/vgfiles/js/sortable.js +52 -52
- package/app/modules/vgfiles/js/vgfiles.js +43 -43
- package/app/modules/vgfiles/readme.md +123 -123
- package/app/modules/vgfiles/scss/_mixins.scss +13 -13
- package/app/modules/vgfiles/scss/_variables.scss +10 -10
- package/app/modules/vgfiles/scss/vgfiles.scss +28 -28
- package/app/modules/vgformsender/js/hideshowpass.js +22 -22
- package/app/modules/vgformsender/readme.md +1 -1
- package/app/modules/vgformsender/scss/_variables.scss +5 -5
- package/app/modules/vgformsender/scss/vgformsender.scss +42 -42
- package/app/modules/vglawcookie/js/vglawcookie.js +19 -19
- package/app/modules/vglawcookie/scss/_variables.scss +13 -13
- package/app/modules/vglawcookie/scss/vglawcookie.scss +5 -5
- package/app/modules/vgmodal/js/vgmodal.interaction.js +216 -216
- package/app/modules/vgmodal/js/vgmodal.js +9 -9
- package/app/modules/vgmodal/js/vgmodal.minimized.js +227 -227
- package/app/modules/vgmodal/scss/_variables.scss +17 -17
- package/app/modules/vgmodal/scss/vgmodal.scss +77 -77
- package/app/modules/vgnav/js/vgnav.js +62 -62
- package/app/modules/vgnav/scss/_breakpoints.scss +36 -36
- package/app/modules/vgnav/scss/_hamburger.scss +5 -5
- package/app/modules/vgnav/scss/_placement.scss +5 -5
- package/app/modules/vgnav/scss/_toggle.scss +5 -5
- package/app/modules/vgnav/scss/_variables.scss +26 -26
- package/app/modules/vgnav/scss/vgnav.scss +41 -41
- package/app/modules/vgnestable/README.md +39 -39
- package/app/modules/vgrangeslider/js/skins.js +8 -8
- package/app/modules/vgrangeslider/js/vgrangeslider.js +29 -29
- package/app/modules/vgrangeslider/scss/_variables.scss +55 -55
- package/app/modules/vgrangeslider/scss/vgrangeslider.scss +239 -239
- package/app/modules/vgrollup/js/vgrollup.js +15 -15
- package/app/modules/vgrollup/scss/_variables.scss +15 -15
- package/app/modules/vgrollup/scss/vgrollup.scss +6 -6
- package/app/modules/vgselect/js/handlers.js +6 -6
- package/app/modules/vgselect/js/vgselect.js +167 -123
- package/app/modules/vgselect/readme.md +11 -11
- package/app/modules/vgselect/scss/_variables.scss +51 -51
- package/app/modules/vgselect/scss/vgselect.scss +1 -1
- package/app/modules/vgsidebar/js/vgsidebar.js +21 -21
- package/app/modules/vgsidebar/scss/_variables.scss +10 -10
- package/app/modules/vgsidebar/scss/vgsidebar.scss +5 -5
- package/app/modules/vgspy/js/vgspy.js +43 -43
- package/app/modules/vgtable/js/_filters.js +10 -6
- package/app/modules/vgtable/js/_options.js +16 -16
- package/app/modules/vgtable/js/_pagination.js +118 -118
- package/app/modules/vgtable/js/_responsive.js +79 -79
- package/app/modules/vgtable/js/_sticky-header.js +349 -280
- package/app/modules/vgtable/js/vgtable.js +98 -98
- package/app/modules/vgtable/scss/_sorting.scss +6 -6
- package/app/modules/vgtable/scss/_sticky-header.scss +31 -31
- package/app/modules/vgtable/scss/_variables.scss +6 -4
- package/app/modules/vgtable/scss/vgtable.scss +8 -4
- package/app/modules/vgtabs/js/vgtabs.js +91 -91
- package/app/modules/vgtabs/scss/_variables.scss +23 -23
- package/app/modules/vgtabs/scss/vgtabs.scss +5 -5
- package/app/modules/vgtoast/js/vgtoast.js +4 -4
- package/app/modules/vgtoast/scss/_variables.scss +13 -13
- package/app/modules/vgtoast/scss/vgtoast.scss +5 -5
- package/app/modules/vgtooltip/js/vgtooltip.js +127 -127
- package/app/modules/vgtooltip/scss/_variables.scss +10 -10
- package/app/modules/vgtooltip/scss/vgtooltip.scss +5 -5
- package/app/utils/js/components/audio-metadata.js +240 -240
- package/app/utils/js/components/backdrop.js +116 -116
- package/app/utils/js/components/file-icon.js +7 -7
- package/app/utils/js/components/file-preview.js +304 -304
- package/app/utils/js/components/responsive.js +165 -165
- package/app/utils/js/components/sanitize.js +150 -150
- package/app/utils/js/components/video-metadata.js +140 -140
- package/app/utils/scss/_backdrop.scss +5 -5
- package/app/utils/scss/_theme-default.scss +12 -12
- package/app/utils/scss/_theme.scss +7 -7
- package/app/utils/scss/default.scss +9 -9
- package/app/utils/scss/functions.scss +21 -21
- package/app/utils/scss/index.scss +4 -4
- package/app/utils/scss/mixin.scss +16 -16
- package/app/utils/scss/variables.scss +147 -147
- package/build/vgapp.css +1 -1
- package/build/vgapp.css.map +1 -1
- package/build/vgapp.js +1 -1
- package/build/vgapp.js.map +1 -1
- package/index.js +7 -7
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Описание: базовая логика выбора, валидации и отображения файлов VGFiles.
|
|
3
|
-
* Возможности: управляет файлами, валидацией, списками, миниатюрами и иконками, действиями, статистикой и скрытыми полями.
|
|
2
|
+
* Описание: базовая логика выбора, валидации и отображения файлов VGFiles.
|
|
3
|
+
* Возможности: управляет файлами, валидацией, списками, миниатюрами и иконками, действиями, статистикой и скрытыми полями.
|
|
4
4
|
*/
|
|
5
5
|
import BaseModule from "../../base-module";
|
|
6
6
|
import {mergeDeepObject} from "../../../utils/js/functions";
|
|
@@ -8,8 +8,8 @@ import Html from "../../../utils/js/components/templater";
|
|
|
8
8
|
import {lang_messages} from "../../../utils/js/components/lang";
|
|
9
9
|
import {Classes, Manipulator} from "../../../utils/js/dom/manipulator";
|
|
10
10
|
import Selectors from "../../../utils/js/dom/selectors";
|
|
11
|
-
import {getSVG} from "../../module-fn";
|
|
12
|
-
import {resolveFileIconName} from "../../../utils/js/components/file-icon";
|
|
11
|
+
import {getSVG} from "../../module-fn";
|
|
12
|
+
import {resolveFileIconName} from "../../../utils/js/components/file-icon";
|
|
13
13
|
import VGFilePreview from "../../vgfilepreview";
|
|
14
14
|
import {extractAudioMetadata} from "../../../utils/js/components/audio-metadata";
|
|
15
15
|
|
|
@@ -27,10 +27,10 @@ class VGFilesBase extends BaseModule {
|
|
|
27
27
|
this._isInitialized = true;
|
|
28
28
|
|
|
29
29
|
this._tpl = Html('dom');
|
|
30
|
-
this._files = [];
|
|
31
|
-
this._errors = new Set();
|
|
32
|
-
this._validationErrorsByKey = new Map();
|
|
33
|
-
this._fileObjectUrls = new Map();
|
|
30
|
+
this._files = [];
|
|
31
|
+
this._errors = new Set();
|
|
32
|
+
this._validationErrorsByKey = new Map();
|
|
33
|
+
this._fileObjectUrls = new Map();
|
|
34
34
|
this._audioMetaPromises = new Map();
|
|
35
35
|
|
|
36
36
|
this._nodes = {
|
|
@@ -199,10 +199,10 @@ class VGFilesBase extends BaseModule {
|
|
|
199
199
|
filesToProcess = this._mergeFilesByOrder(incoming, this._files, Boolean(this._params.prepend));
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
this._files = this._filterFiles(filesToProcess);
|
|
203
|
-
this._syncSingleInputSubmission();
|
|
204
|
-
|
|
205
|
-
this._renderErrors();
|
|
202
|
+
this._files = this._filterFiles(filesToProcess);
|
|
203
|
+
this._syncSingleInputSubmission();
|
|
204
|
+
|
|
205
|
+
this._renderErrors();
|
|
206
206
|
this._enrichAudioMetadata(this._files);
|
|
207
207
|
|
|
208
208
|
return this._files;
|
|
@@ -283,119 +283,119 @@ class VGFilesBase extends BaseModule {
|
|
|
283
283
|
return attrs;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
_filterFiles(files) {
|
|
287
|
-
this._errors.clear();
|
|
288
|
-
this._validationErrorsByKey.clear();
|
|
289
|
-
const { count, sizes, total } = this._params.limits;
|
|
290
|
-
const maxSize = sizes * 1024 * 1024;
|
|
291
|
-
const maxTotalSize = total * 1024 * 1024;
|
|
292
|
-
|
|
293
|
-
let currentTotalSize = 0;
|
|
294
|
-
let validCount = 0;
|
|
295
|
-
const visibleFiles = [];
|
|
296
|
-
|
|
297
|
-
for (const file of files) {
|
|
298
|
-
const fileErrors = new Set();
|
|
299
|
-
|
|
300
|
-
if (count > 0 && validCount >= count) {
|
|
301
|
-
this._errors.add('is-count');
|
|
302
|
-
continue;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if (this._params.types.length && !this._params.types.includes(file.type)) {
|
|
306
|
-
fileErrors.add('is-types');
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
if (file.size > maxSize) {
|
|
310
|
-
fileErrors.add('is-sizes');
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (!fileErrors.size && maxTotalSize > 0 && currentTotalSize + file.size > maxTotalSize) {
|
|
314
|
-
fileErrors.add('is-total-size');
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
visibleFiles.push(file);
|
|
318
|
-
|
|
319
|
-
if (fileErrors.size) {
|
|
320
|
-
fileErrors.forEach(error => this._errors.add(error));
|
|
321
|
-
this._validationErrorsByKey.set(this._getFileKey(file), fileErrors);
|
|
322
|
-
continue;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
validCount += 1;
|
|
326
|
-
currentTotalSize += file.size;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return visibleFiles;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
_isFileValid(file) {
|
|
333
|
-
return !this._validationErrorsByKey.has(this._getFileKey(file));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
_syncSingleInputSubmission() {
|
|
337
|
-
if (Number(this._params?.limits?.count) !== 1) return;
|
|
338
|
-
|
|
339
|
-
const selectedFile = this._files[0];
|
|
340
|
-
const canSubmit = !this._params.ajax && (!selectedFile || this._isFileValid(selectedFile));
|
|
341
|
-
this._preventOriginalInputFromSubmit(canSubmit);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
_getFileValidationMessages(file) {
|
|
345
|
-
const errors = this._validationErrorsByKey.get(this._getFileKey(file));
|
|
346
|
-
if (!errors?.size) return [];
|
|
347
|
-
|
|
348
|
-
const messages = lang_messages(this._params.lang, 'files') || this._getFallbackErrors();
|
|
349
|
-
return Array.from(errors, error => messages[error] || error);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
_getFileValidationLabel(file) {
|
|
353
|
-
const messages = this._getFileValidationMessages(file);
|
|
354
|
-
if (!messages.length) return '';
|
|
355
|
-
|
|
356
|
-
const fileName = this._getShortValidationFileName(file?.name);
|
|
357
|
-
return [fileName, messages.join('. ')].filter(Boolean).join(' — ');
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
_getFullFileValidationLabel(file) {
|
|
361
|
-
const messages = this._getFileValidationMessages(file);
|
|
362
|
-
if (!messages.length) return '';
|
|
363
|
-
|
|
364
|
-
const fileName = String(file?.name || '').trim();
|
|
365
|
-
return [fileName, messages.join('. ')].filter(Boolean).join(' — ');
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
_getShortValidationFileName(fileName) {
|
|
369
|
-
const name = String(fileName || '').trim();
|
|
370
|
-
if (name.length <= 24) return name;
|
|
371
|
-
|
|
372
|
-
const dotIndex = name.lastIndexOf('.');
|
|
373
|
-
const hasExtension = dotIndex > 0 && name.length - dotIndex <= 10;
|
|
374
|
-
const baseName = hasExtension ? name.slice(0, dotIndex) : name;
|
|
375
|
-
const extension = hasExtension ? name.slice(dotIndex) : '';
|
|
376
|
-
|
|
377
|
-
return `${baseName.slice(0, 5)}...${extension}`;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
_decorateValidationItem(item, file) {
|
|
381
|
-
if (this._isFileValid(file)) return item;
|
|
382
|
-
|
|
383
|
-
Classes.add(item, 'failing');
|
|
384
|
-
Classes.add(item, 'validation-error');
|
|
385
|
-
|
|
386
|
-
return item;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
_forgetFileValidation(file) {
|
|
390
|
-
if (!file) return;
|
|
391
|
-
|
|
392
|
-
this._validationErrorsByKey.delete(this._getFileKey(file));
|
|
393
|
-
this._errors.clear();
|
|
394
|
-
this._validationErrorsByKey.forEach(errors => {
|
|
395
|
-
errors.forEach(error => this._errors.add(error));
|
|
396
|
-
});
|
|
397
|
-
this._renderErrors();
|
|
398
|
-
}
|
|
286
|
+
_filterFiles(files) {
|
|
287
|
+
this._errors.clear();
|
|
288
|
+
this._validationErrorsByKey.clear();
|
|
289
|
+
const { count, sizes, total } = this._params.limits;
|
|
290
|
+
const maxSize = sizes * 1024 * 1024;
|
|
291
|
+
const maxTotalSize = total * 1024 * 1024;
|
|
292
|
+
|
|
293
|
+
let currentTotalSize = 0;
|
|
294
|
+
let validCount = 0;
|
|
295
|
+
const visibleFiles = [];
|
|
296
|
+
|
|
297
|
+
for (const file of files) {
|
|
298
|
+
const fileErrors = new Set();
|
|
299
|
+
|
|
300
|
+
if (count > 0 && validCount >= count) {
|
|
301
|
+
this._errors.add('is-count');
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (this._params.types.length && !this._params.types.includes(file.type)) {
|
|
306
|
+
fileErrors.add('is-types');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (file.size > maxSize) {
|
|
310
|
+
fileErrors.add('is-sizes');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (!fileErrors.size && maxTotalSize > 0 && currentTotalSize + file.size > maxTotalSize) {
|
|
314
|
+
fileErrors.add('is-total-size');
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
visibleFiles.push(file);
|
|
318
|
+
|
|
319
|
+
if (fileErrors.size) {
|
|
320
|
+
fileErrors.forEach(error => this._errors.add(error));
|
|
321
|
+
this._validationErrorsByKey.set(this._getFileKey(file), fileErrors);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
validCount += 1;
|
|
326
|
+
currentTotalSize += file.size;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return visibleFiles;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
_isFileValid(file) {
|
|
333
|
+
return !this._validationErrorsByKey.has(this._getFileKey(file));
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
_syncSingleInputSubmission() {
|
|
337
|
+
if (Number(this._params?.limits?.count) !== 1) return;
|
|
338
|
+
|
|
339
|
+
const selectedFile = this._files[0];
|
|
340
|
+
const canSubmit = !this._params.ajax && (!selectedFile || this._isFileValid(selectedFile));
|
|
341
|
+
this._preventOriginalInputFromSubmit(canSubmit);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
_getFileValidationMessages(file) {
|
|
345
|
+
const errors = this._validationErrorsByKey.get(this._getFileKey(file));
|
|
346
|
+
if (!errors?.size) return [];
|
|
347
|
+
|
|
348
|
+
const messages = lang_messages(this._params.lang, 'files') || this._getFallbackErrors();
|
|
349
|
+
return Array.from(errors, error => messages[error] || error);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
_getFileValidationLabel(file) {
|
|
353
|
+
const messages = this._getFileValidationMessages(file);
|
|
354
|
+
if (!messages.length) return '';
|
|
355
|
+
|
|
356
|
+
const fileName = this._getShortValidationFileName(file?.name);
|
|
357
|
+
return [fileName, messages.join('. ')].filter(Boolean).join(' — ');
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
_getFullFileValidationLabel(file) {
|
|
361
|
+
const messages = this._getFileValidationMessages(file);
|
|
362
|
+
if (!messages.length) return '';
|
|
363
|
+
|
|
364
|
+
const fileName = String(file?.name || '').trim();
|
|
365
|
+
return [fileName, messages.join('. ')].filter(Boolean).join(' — ');
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
_getShortValidationFileName(fileName) {
|
|
369
|
+
const name = String(fileName || '').trim();
|
|
370
|
+
if (name.length <= 24) return name;
|
|
371
|
+
|
|
372
|
+
const dotIndex = name.lastIndexOf('.');
|
|
373
|
+
const hasExtension = dotIndex > 0 && name.length - dotIndex <= 10;
|
|
374
|
+
const baseName = hasExtension ? name.slice(0, dotIndex) : name;
|
|
375
|
+
const extension = hasExtension ? name.slice(dotIndex) : '';
|
|
376
|
+
|
|
377
|
+
return `${baseName.slice(0, 5)}...${extension}`;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
_decorateValidationItem(item, file) {
|
|
381
|
+
if (this._isFileValid(file)) return item;
|
|
382
|
+
|
|
383
|
+
Classes.add(item, 'failing');
|
|
384
|
+
Classes.add(item, 'validation-error');
|
|
385
|
+
|
|
386
|
+
return item;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
_forgetFileValidation(file) {
|
|
390
|
+
if (!file) return;
|
|
391
|
+
|
|
392
|
+
this._validationErrorsByKey.delete(this._getFileKey(file));
|
|
393
|
+
this._errors.clear();
|
|
394
|
+
this._validationErrorsByKey.forEach(errors => {
|
|
395
|
+
errors.forEach(error => this._errors.add(error));
|
|
396
|
+
});
|
|
397
|
+
this._renderErrors();
|
|
398
|
+
}
|
|
399
399
|
|
|
400
400
|
_getSizes(size, isArray = false) {
|
|
401
401
|
const totalSize = isArray ? this._files.reduce((acc, f) => acc + f.size, 0) : size;
|
|
@@ -419,12 +419,12 @@ class VGFilesBase extends BaseModule {
|
|
|
419
419
|
}
|
|
420
420
|
}
|
|
421
421
|
|
|
422
|
-
_renderErrors() {
|
|
423
|
-
if (!this._errors.size) {
|
|
424
|
-
const $errorCont = Selectors.find(`.${this._getClass('errors')}`, this._element);
|
|
425
|
-
if ($errorCont) $errorCont.remove();
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
422
|
+
_renderErrors() {
|
|
423
|
+
if (!this._errors.size) {
|
|
424
|
+
const $errorCont = Selectors.find(`.${this._getClass('errors')}`, this._element);
|
|
425
|
+
if ($errorCont) $errorCont.remove();
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
428
|
|
|
429
429
|
const messages = lang_messages(this._params.lang, 'files') || this._getFallbackErrors();
|
|
430
430
|
let $errorCont = Selectors.find(`.${this._getClass('errors')}`, this._element);
|
|
@@ -436,32 +436,32 @@ class VGFilesBase extends BaseModule {
|
|
|
436
436
|
$errorCont.innerHTML = '';
|
|
437
437
|
}
|
|
438
438
|
|
|
439
|
-
if (this._validationErrorsByKey.size) {
|
|
440
|
-
const renderedErrors = new Set();
|
|
441
|
-
this._files.forEach(file => {
|
|
442
|
-
const msg = this._getFileValidationLabel(file);
|
|
443
|
-
if (!msg) return;
|
|
444
|
-
|
|
445
|
-
const fileErrors = this._validationErrorsByKey.get(this._getFileKey(file));
|
|
446
|
-
fileErrors?.forEach(error => renderedErrors.add(error));
|
|
447
|
-
const fullMsg = this._getFullFileValidationLabel(file);
|
|
448
|
-
const attrs = { class: 'error-item' };
|
|
449
|
-
if (fullMsg && fullMsg !== msg) attrs.title = fullMsg;
|
|
450
|
-
$errorCont.append(this._tpl.span(attrs, msg));
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
this._errors.forEach(errKey => {
|
|
454
|
-
if (renderedErrors.has(errKey)) return;
|
|
455
|
-
const msg = messages[errKey] || errKey;
|
|
456
|
-
$errorCont.append(this._tpl.span({ class: 'error-item' }, msg));
|
|
457
|
-
});
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
this._errors.forEach(errKey => {
|
|
462
|
-
const msg = messages[errKey] || errKey;
|
|
463
|
-
$errorCont.append(this._tpl.span({ class: 'error-item' }, msg));
|
|
464
|
-
});
|
|
439
|
+
if (this._validationErrorsByKey.size) {
|
|
440
|
+
const renderedErrors = new Set();
|
|
441
|
+
this._files.forEach(file => {
|
|
442
|
+
const msg = this._getFileValidationLabel(file);
|
|
443
|
+
if (!msg) return;
|
|
444
|
+
|
|
445
|
+
const fileErrors = this._validationErrorsByKey.get(this._getFileKey(file));
|
|
446
|
+
fileErrors?.forEach(error => renderedErrors.add(error));
|
|
447
|
+
const fullMsg = this._getFullFileValidationLabel(file);
|
|
448
|
+
const attrs = { class: 'error-item' };
|
|
449
|
+
if (fullMsg && fullMsg !== msg) attrs.title = fullMsg;
|
|
450
|
+
$errorCont.append(this._tpl.span(attrs, msg));
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
this._errors.forEach(errKey => {
|
|
454
|
+
if (renderedErrors.has(errKey)) return;
|
|
455
|
+
const msg = messages[errKey] || errKey;
|
|
456
|
+
$errorCont.append(this._tpl.span({ class: 'error-item' }, msg));
|
|
457
|
+
});
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
this._errors.forEach(errKey => {
|
|
462
|
+
const msg = messages[errKey] || errKey;
|
|
463
|
+
$errorCont.append(this._tpl.span({ class: 'error-item' }, msg));
|
|
464
|
+
});
|
|
465
465
|
}
|
|
466
466
|
|
|
467
467
|
_getFallbackErrors() {
|
|
@@ -523,7 +523,7 @@ class VGFilesBase extends BaseModule {
|
|
|
523
523
|
};
|
|
524
524
|
}
|
|
525
525
|
|
|
526
|
-
_renderUIDropList(files) {
|
|
526
|
+
_renderUIDropList(files) {
|
|
527
527
|
if (!this._nodes.drop) return;
|
|
528
528
|
|
|
529
529
|
let $list = Selectors.find(`.${this._getClass('drop-list')}`, this._nodes.drop);
|
|
@@ -536,10 +536,10 @@ class VGFilesBase extends BaseModule {
|
|
|
536
536
|
const fragment = document.createDocumentFragment();
|
|
537
537
|
|
|
538
538
|
files.forEach((file) => {
|
|
539
|
-
let classes = [...$itemsTemplateClasses];
|
|
539
|
+
let classes = [...$itemsTemplateClasses];
|
|
540
540
|
|
|
541
|
-
if (this._params.detach) classes.push('with-remove')
|
|
542
|
-
if (this._params.customButtons?.hideOnUploadState) classes.push('hide-custom-buttons-on-upload-state')
|
|
541
|
+
if (this._params.detach) classes.push('with-remove')
|
|
542
|
+
if (this._params.customButtons?.hideOnUploadState) classes.push('hide-custom-buttons-on-upload-state')
|
|
543
543
|
if (this._params.sortable.enabled) classes.push('with-sortable')
|
|
544
544
|
if (this._params.limits.count === 1) {
|
|
545
545
|
classes.push('single');
|
|
@@ -567,7 +567,7 @@ class VGFilesBase extends BaseModule {
|
|
|
567
567
|
parts
|
|
568
568
|
);
|
|
569
569
|
|
|
570
|
-
fragment.appendChild(this._decorateValidationItem($li, file));
|
|
570
|
+
fragment.appendChild(this._decorateValidationItem($li, file));
|
|
571
571
|
});
|
|
572
572
|
|
|
573
573
|
$list.innerHTML = '';
|
|
@@ -708,13 +708,13 @@ class VGFilesBase extends BaseModule {
|
|
|
708
708
|
return '';
|
|
709
709
|
}
|
|
710
710
|
|
|
711
|
-
_createInfoListItem(file, i, itemsTemplate, itemTemplateClasses, fileKey, signature) {
|
|
711
|
+
_createInfoListItem(file, i, itemsTemplate, itemTemplateClasses, fileKey, signature) {
|
|
712
712
|
let classes = [...itemTemplateClasses];
|
|
713
713
|
|
|
714
714
|
if (this._params.image) classes.push('with-image');
|
|
715
715
|
if (this._params.info) classes.push('with-info');
|
|
716
|
-
if (this._params.detach) classes.push('with-remove')
|
|
717
|
-
if (this._params.customButtons?.hideOnUploadState) classes.push('hide-custom-buttons-on-upload-state')
|
|
716
|
+
if (this._params.detach) classes.push('with-remove')
|
|
717
|
+
if (this._params.customButtons?.hideOnUploadState) classes.push('hide-custom-buttons-on-upload-state')
|
|
718
718
|
if (this._params.sortable.enabled) classes.push('with-sortable');
|
|
719
719
|
const previewPath = this._resolveFilePreviewPath(file);
|
|
720
720
|
const displayName = this._resolveDisplayName(file);
|
|
@@ -742,12 +742,12 @@ class VGFilesBase extends BaseModule {
|
|
|
742
742
|
liAttrs['data-vg-filepreview-display-name'] = displayName || file.name || '';
|
|
743
743
|
}
|
|
744
744
|
|
|
745
|
-
const item = this._tpl.li(
|
|
746
|
-
this._buildFileDataAttributes(file, liAttrs),
|
|
747
|
-
parts
|
|
748
|
-
);
|
|
749
|
-
|
|
750
|
-
return this._decorateValidationItem(item, file);
|
|
745
|
+
const item = this._tpl.li(
|
|
746
|
+
this._buildFileDataAttributes(file, liAttrs),
|
|
747
|
+
parts
|
|
748
|
+
);
|
|
749
|
+
|
|
750
|
+
return this._decorateValidationItem(item, file);
|
|
751
751
|
}
|
|
752
752
|
|
|
753
753
|
_renderTemplatePart(element, file, index = null, options = {}) {
|
|
@@ -814,28 +814,28 @@ class VGFilesBase extends BaseModule {
|
|
|
814
814
|
}
|
|
815
815
|
}
|
|
816
816
|
|
|
817
|
-
_renderUIImage(file) {
|
|
818
|
-
const $container = this._tpl.div({ class: 'file-image' });
|
|
819
|
-
const renderIcon = () => {
|
|
820
|
-
const icon = this._getIconByFileType(file);
|
|
821
|
-
$container.replaceChildren(this._tpl.i({}, icon, { isHTML: true }));
|
|
822
|
-
};
|
|
823
|
-
const customData = this._getFileCustomData(file);
|
|
824
|
-
let imageSrc = String(file?.image || '').trim() || String(customData.audioCover || '').trim();
|
|
825
|
-
|
|
826
|
-
if (!imageSrc && resolveFileIconName({ type: file?.type, name: file?.name || file?.src }) === 'file-image') {
|
|
827
|
-
imageSrc = String(file?.src || '').trim() || this._getFileObjectUrl(file);
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
if (imageSrc) {
|
|
831
|
-
const image = this._tpl.img(imageSrc, this._resolveDisplayName(file), { class: 'file-preview' });
|
|
832
|
-
image.addEventListener('error', renderIcon, { once: true });
|
|
833
|
-
$container.appendChild(image);
|
|
834
|
-
} else {
|
|
835
|
-
renderIcon();
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
return $container;
|
|
817
|
+
_renderUIImage(file) {
|
|
818
|
+
const $container = this._tpl.div({ class: 'file-image' });
|
|
819
|
+
const renderIcon = () => {
|
|
820
|
+
const icon = this._getIconByFileType(file);
|
|
821
|
+
$container.replaceChildren(this._tpl.i({}, icon, { isHTML: true }));
|
|
822
|
+
};
|
|
823
|
+
const customData = this._getFileCustomData(file);
|
|
824
|
+
let imageSrc = String(file?.image || '').trim() || String(customData.audioCover || '').trim();
|
|
825
|
+
|
|
826
|
+
if (!imageSrc && resolveFileIconName({ type: file?.type, name: file?.name || file?.src }) === 'file-image') {
|
|
827
|
+
imageSrc = String(file?.src || '').trim() || this._getFileObjectUrl(file);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
if (imageSrc) {
|
|
831
|
+
const image = this._tpl.img(imageSrc, this._resolveDisplayName(file), { class: 'file-preview' });
|
|
832
|
+
image.addEventListener('error', renderIcon, { once: true });
|
|
833
|
+
$container.appendChild(image);
|
|
834
|
+
} else {
|
|
835
|
+
renderIcon();
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
return $container;
|
|
839
839
|
}
|
|
840
840
|
|
|
841
841
|
_resolveDisplayName(file) {
|
|
@@ -1023,7 +1023,7 @@ class VGFilesBase extends BaseModule {
|
|
|
1023
1023
|
|
|
1024
1024
|
if (isSingle) return;
|
|
1025
1025
|
|
|
1026
|
-
files.filter(file => this._isFileValid(file)).forEach((file, index) => {
|
|
1026
|
+
files.filter(file => this._isFileValid(file)).forEach((file, index) => {
|
|
1027
1027
|
const input = document.createElement('input');
|
|
1028
1028
|
input.type = 'file';
|
|
1029
1029
|
input.name = `${baseName}[${index}]`;
|
|
@@ -1065,10 +1065,10 @@ class VGFilesBase extends BaseModule {
|
|
|
1065
1065
|
if (resetInput) {
|
|
1066
1066
|
this._resetFileInput();
|
|
1067
1067
|
}
|
|
1068
|
-
this._cleanupFakeInputs();
|
|
1069
|
-
this._cleanupErrors();
|
|
1070
|
-
this._validationErrorsByKey.clear();
|
|
1071
|
-
this._files = [];
|
|
1068
|
+
this._cleanupFakeInputs();
|
|
1069
|
+
this._cleanupErrors();
|
|
1070
|
+
this._validationErrorsByKey.clear();
|
|
1071
|
+
this._files = [];
|
|
1072
1072
|
|
|
1073
1073
|
if (this._nodes.info) {
|
|
1074
1074
|
Classes.remove(this._nodes.info, 'show');
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
import { isElement } from "../../../utils/js/functions";
|
|
6
6
|
import EventHandler from "../../../utils/js/dom/event";
|
|
7
7
|
import Selectors from "../../../utils/js/dom/selectors";
|
|
8
|
-
import { Classes } from "../../../utils/js/dom/manipulator";
|
|
9
|
-
import BaseModule from "../../base-module";
|
|
10
|
-
import {isVGFilesSortableDragActive, VG_FILES_SORTABLE_DATA_TYPE} from "./sortable";
|
|
8
|
+
import { Classes } from "../../../utils/js/dom/manipulator";
|
|
9
|
+
import BaseModule from "../../base-module";
|
|
10
|
+
import {isVGFilesSortableDragActive, VG_FILES_SORTABLE_DATA_TYPE} from "./sortable";
|
|
11
11
|
|
|
12
12
|
const CLASS_NAME_CONTAINER = 'vg-files';
|
|
13
13
|
const CLASS_NAME_DROP = `${CLASS_NAME_CONTAINER}-drop`;
|
|
@@ -254,20 +254,20 @@ class VGFilesDroppable extends BaseModule {
|
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
_isSortableDrag(e) {
|
|
258
|
-
if (isVGFilesSortableDragActive()) return true;
|
|
259
|
-
if (document.querySelector('.dragging')) return true;
|
|
260
|
-
|
|
261
|
-
try {
|
|
262
|
-
const dataTransfer = e?.dataTransfer;
|
|
263
|
-
const types = Array.from(dataTransfer?.types || []);
|
|
264
|
-
if (types.includes(VG_FILES_SORTABLE_DATA_TYPE)) return true;
|
|
265
|
-
|
|
266
|
-
return (dataTransfer?.getData?.(VG_FILES_SORTABLE_DATA_TYPE) || '') === '1' ||
|
|
267
|
-
(dataTransfer?.getData?.('text/plain') || '') === 'vgsortable';
|
|
268
|
-
} catch (_) {
|
|
269
|
-
return false;
|
|
270
|
-
}
|
|
257
|
+
_isSortableDrag(e) {
|
|
258
|
+
if (isVGFilesSortableDragActive()) return true;
|
|
259
|
+
if (document.querySelector('.dragging')) return true;
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
const dataTransfer = e?.dataTransfer;
|
|
263
|
+
const types = Array.from(dataTransfer?.types || []);
|
|
264
|
+
if (types.includes(VG_FILES_SORTABLE_DATA_TYPE)) return true;
|
|
265
|
+
|
|
266
|
+
return (dataTransfer?.getData?.(VG_FILES_SORTABLE_DATA_TYPE) || '') === '1' ||
|
|
267
|
+
(dataTransfer?.getData?.('text/plain') || '') === 'vgsortable';
|
|
268
|
+
} catch (_) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
_getVisibleDropZonesInViewport() {
|