vgapp 1.2.2 → 1.2.3

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 (59) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/README.md +48 -48
  3. package/app/langs/en/buttons.json +17 -17
  4. package/app/langs/en/messages.json +36 -36
  5. package/app/langs/ru/buttons.json +17 -17
  6. package/app/langs/ru/messages.json +36 -36
  7. package/app/modules/vgfilepreview/js/i18n.js +56 -56
  8. package/app/modules/vgfilepreview/js/renderers/image-modal.js +145 -145
  9. package/app/modules/vgfilepreview/js/renderers/image.js +92 -92
  10. package/app/modules/vgfilepreview/js/renderers/index.js +19 -19
  11. package/app/modules/vgfilepreview/js/renderers/office-modal.js +168 -168
  12. package/app/modules/vgfilepreview/js/renderers/office.js +79 -79
  13. package/app/modules/vgfilepreview/js/renderers/pdf-modal.js +260 -260
  14. package/app/modules/vgfilepreview/js/renderers/pdf.js +76 -76
  15. package/app/modules/vgfilepreview/js/renderers/playlist.js +71 -71
  16. package/app/modules/vgfilepreview/js/renderers/text-modal.js +343 -343
  17. package/app/modules/vgfilepreview/js/renderers/text.js +83 -83
  18. package/app/modules/vgfilepreview/js/renderers/video-modal.js +272 -272
  19. package/app/modules/vgfilepreview/js/renderers/video.js +80 -80
  20. package/app/modules/vgfilepreview/js/renderers/zip-modal.js +522 -522
  21. package/app/modules/vgfilepreview/js/renderers/zip.js +89 -89
  22. package/app/modules/vgfilepreview/js/vgfilepreview.js +7 -7
  23. package/app/modules/vgfilepreview/readme.md +68 -68
  24. package/app/modules/vgfilepreview/scss/_variables.scss +113 -113
  25. package/app/modules/vgfilepreview/scss/vgfilepreview.scss +464 -464
  26. package/app/modules/vgfiles/js/base.js +26 -26
  27. package/app/modules/vgfiles/js/droppable.js +260 -260
  28. package/app/modules/vgfiles/js/render.js +153 -153
  29. package/app/modules/vgfiles/js/vgfiles.js +104 -104
  30. package/app/modules/vgfiles/readme.md +123 -123
  31. package/app/modules/vgfiles/scss/_variables.scss +18 -18
  32. package/app/modules/vgfiles/scss/vgfiles.scss +148 -148
  33. package/app/modules/vgformsender/js/hideshowpass.js +16 -16
  34. package/app/modules/vgformsender/js/vgformsender.js +144 -144
  35. package/app/modules/vgformsender/scss/vgformsender.scss +34 -34
  36. package/app/modules/vgmodal/js/vgmodal.drag.js +332 -332
  37. package/app/modules/vgmodal/js/vgmodal.js +1 -1
  38. package/app/modules/vgmodal/js/vgmodal.resize.js +435 -435
  39. package/app/modules/vgnav/js/vgnav.js +135 -135
  40. package/app/modules/vgnav/readme.md +67 -67
  41. package/app/modules/vgnestable/README.md +307 -307
  42. package/app/modules/vgnestable/scss/_variables.scss +60 -60
  43. package/app/modules/vgnestable/scss/vgnestable.scss +163 -163
  44. package/app/modules/vgselect/js/vgselect.js +39 -39
  45. package/app/modules/vgselect/scss/vgselect.scss +22 -22
  46. package/app/modules/vgspy/readme.md +28 -28
  47. package/app/modules/vgtoast/js/vgtoast.js +166 -135
  48. package/app/modules/vgtoast/readme.md +18 -18
  49. package/app/modules/vgtoast/scss/vgtoast.scss +48 -48
  50. package/app/utils/js/components/audio-metadata.js +240 -240
  51. package/app/utils/js/components/file-icon.js +109 -109
  52. package/app/utils/js/components/file-preview.js +304 -304
  53. package/app/utils/js/components/sanitize.js +150 -150
  54. package/app/utils/js/components/video-metadata.js +140 -140
  55. package/build/vgapp.css +1 -1
  56. package/build/vgapp.css.map +1 -1
  57. package/build/vgapp.js.map +1 -1
  58. package/index.scss +9 -9
  59. package/package.json +1 -1
@@ -1,154 +1,154 @@
1
- import { isElement, normalizeData } from "../../../utils/js/functions";
2
- import Params from "../../../utils/js/components/params";
3
- import Selectors from "../../../utils/js/dom/selectors";
4
- import { Manipulator } from "../../../utils/js/dom/manipulator";
5
-
6
- class VGFilesTemplateRender {
7
- constructor(vgFilesInstance, element, params = {}) {
8
- this.module = vgFilesInstance;
9
- this.element = isElement(element) ? element : null;
10
-
11
- if (!this.element) {
12
- console.error('Invalid element provided:', element);
13
- return;
14
- }
15
-
16
- this._params = new Params(params, element).get();
17
- this._nodes = {
18
- info: this.module._nodes.info,
19
- drop: this.module._nodes.drop
20
- };
21
-
22
- this.bufferTemplate = '';
23
- this.parsedFiles = [];
24
- }
25
-
26
- init() {
27
- const $targetNode = this._nodes.info || this._nodes.drop;
28
- if (!$targetNode) return false;
29
-
30
- const area = this._nodes.info ? 'info' : 'drop';
31
- return this._nativeRenderFiles(area, $targetNode);
32
- }
33
-
34
- _nativeRenderFiles(area, $node) {
35
- const $list = Selectors.find(`.vg-files-${area}--list`, $node);
36
- if (!$list) return false;
37
-
38
- const $items = Array.from($list.children).filter(li => li.tagName === 'LI');
39
- if ($items.length === 0) return false;
40
-
41
- this._setTemplateInBuffer($items);
42
- if (!this.bufferTemplate) return false;
43
-
44
- this.parsedFiles = $items
45
- .map(li => {
46
- const rawData = Manipulator.get(li, 'data-file');
47
- if (!rawData) return null;
48
-
49
- return this._parseDataFile(rawData);
50
- })
51
- .filter(Boolean);
52
-
53
- return true;
54
- }
55
-
56
- _parseDataFile(rawData) {
57
- const dataFile = normalizeData(rawData);
58
- if (!dataFile || typeof dataFile !== 'object' || Array.isArray(dataFile)) return null;
59
-
60
- const binaryMeta = this._extractBinaryMeta(dataFile);
61
- const name = this._toStringOrNull(dataFile.name);
62
- const id = this._toStringOrNull(dataFile.id);
63
- const src = this._toStringOrNull(dataFile.src);
64
- const type = this._toStringOrNull(dataFile.type) || binaryMeta.type || 'application/octet-stream';
65
- const size = this._toNumberOrNull(dataFile.size) ?? binaryMeta.size ?? 0;
66
- const lastModified = this._toNumberOrNull(dataFile.lastModified ?? dataFile['last-modified']) ?? binaryMeta.lastModified ?? Date.now();
67
-
68
- const result = {
69
- id,
70
- name,
71
- size,
72
- type,
73
- src,
74
- lastModified
75
- };
76
-
77
- if (dataFile.image !== undefined && dataFile.image !== null && dataFile.image !== '') {
78
- result.image = dataFile.image;
79
- }
80
-
81
- const requiredKeys = ['id', 'name', 'size', 'type', 'src'];
82
- const isValid = requiredKeys.every((key) => {
83
- const value = result[key];
84
- if (key === 'size') return Number.isFinite(value);
85
- return value !== undefined && value !== null && value !== '';
86
- });
87
-
88
- if (!isValid) return null;
89
-
90
- const customData = {};
91
- const reserved = new Set(['id', 'name', 'size', 'type', 'src', 'image', 'lastModified', 'last-modified']);
92
-
93
- Object.entries(dataFile).forEach(([key, value]) => {
94
- if (reserved.has(key)) return;
95
- if (value === undefined || value === null || value === '') return;
96
- customData[key] = value;
97
- });
98
-
99
- if (Object.keys(customData).length) {
100
- result.customData = customData;
101
- }
102
-
103
- return result;
104
- }
105
-
106
- _extractBinaryMeta(dataFile) {
107
- const binary = dataFile.file || dataFile.blob || dataFile.originFile || null;
108
- if (!(binary instanceof Blob)) return {};
109
-
110
- const size = this._toNumberOrNull(binary.size);
111
- const type = this._toStringOrNull(binary.type);
112
- const lastModified = (binary instanceof File)
113
- ? this._toNumberOrNull(binary.lastModified)
114
- : null;
115
-
116
- return {
117
- size: size ?? null,
118
- type: type || null,
119
- lastModified: lastModified ?? null
120
- };
121
- }
122
-
123
- _toStringOrNull(value) {
124
- if (value === undefined || value === null) return null;
125
- const normalized = String(value).trim();
126
- return normalized ? normalized : null;
127
- }
128
-
129
- _toNumberOrNull(value) {
130
- if (value === undefined || value === null || value === '') return null;
131
- const normalized = Number(value);
132
- return Number.isFinite(normalized) ? normalized : null;
133
- }
134
-
135
- _setTemplateInBuffer($items) {
136
- if (this.bufferTemplate || $items.length === 0) return;
137
-
138
- const firstItem = $items[0];
139
-
140
- if (!Manipulator.has(firstItem, 'data-file')) {
141
- this.bufferTemplate = firstItem.outerHTML;
142
- firstItem.remove();
143
- } else {
144
- this.bufferTemplate = firstItem.outerHTML;
145
- }
146
- }
147
-
148
- dispose() {
149
- this.bufferTemplate = '';
150
- this.parsedFiles = [];
151
- }
152
- }
153
-
1
+ import { isElement, normalizeData } from "../../../utils/js/functions";
2
+ import Params from "../../../utils/js/components/params";
3
+ import Selectors from "../../../utils/js/dom/selectors";
4
+ import { Manipulator } from "../../../utils/js/dom/manipulator";
5
+
6
+ class VGFilesTemplateRender {
7
+ constructor(vgFilesInstance, element, params = {}) {
8
+ this.module = vgFilesInstance;
9
+ this.element = isElement(element) ? element : null;
10
+
11
+ if (!this.element) {
12
+ console.error('Invalid element provided:', element);
13
+ return;
14
+ }
15
+
16
+ this._params = new Params(params, element).get();
17
+ this._nodes = {
18
+ info: this.module._nodes.info,
19
+ drop: this.module._nodes.drop
20
+ };
21
+
22
+ this.bufferTemplate = '';
23
+ this.parsedFiles = [];
24
+ }
25
+
26
+ init() {
27
+ const $targetNode = this._nodes.info || this._nodes.drop;
28
+ if (!$targetNode) return false;
29
+
30
+ const area = this._nodes.info ? 'info' : 'drop';
31
+ return this._nativeRenderFiles(area, $targetNode);
32
+ }
33
+
34
+ _nativeRenderFiles(area, $node) {
35
+ const $list = Selectors.find(`.vg-files-${area}--list`, $node);
36
+ if (!$list) return false;
37
+
38
+ const $items = Array.from($list.children).filter(li => li.tagName === 'LI');
39
+ if ($items.length === 0) return false;
40
+
41
+ this._setTemplateInBuffer($items);
42
+ if (!this.bufferTemplate) return false;
43
+
44
+ this.parsedFiles = $items
45
+ .map(li => {
46
+ const rawData = Manipulator.get(li, 'data-file');
47
+ if (!rawData) return null;
48
+
49
+ return this._parseDataFile(rawData);
50
+ })
51
+ .filter(Boolean);
52
+
53
+ return true;
54
+ }
55
+
56
+ _parseDataFile(rawData) {
57
+ const dataFile = normalizeData(rawData);
58
+ if (!dataFile || typeof dataFile !== 'object' || Array.isArray(dataFile)) return null;
59
+
60
+ const binaryMeta = this._extractBinaryMeta(dataFile);
61
+ const name = this._toStringOrNull(dataFile.name);
62
+ const id = this._toStringOrNull(dataFile.id);
63
+ const src = this._toStringOrNull(dataFile.src);
64
+ const type = this._toStringOrNull(dataFile.type) || binaryMeta.type || 'application/octet-stream';
65
+ const size = this._toNumberOrNull(dataFile.size) ?? binaryMeta.size ?? 0;
66
+ const lastModified = this._toNumberOrNull(dataFile.lastModified ?? dataFile['last-modified']) ?? binaryMeta.lastModified ?? Date.now();
67
+
68
+ const result = {
69
+ id,
70
+ name,
71
+ size,
72
+ type,
73
+ src,
74
+ lastModified
75
+ };
76
+
77
+ if (dataFile.image !== undefined && dataFile.image !== null && dataFile.image !== '') {
78
+ result.image = dataFile.image;
79
+ }
80
+
81
+ const requiredKeys = ['id', 'name', 'size', 'type', 'src'];
82
+ const isValid = requiredKeys.every((key) => {
83
+ const value = result[key];
84
+ if (key === 'size') return Number.isFinite(value);
85
+ return value !== undefined && value !== null && value !== '';
86
+ });
87
+
88
+ if (!isValid) return null;
89
+
90
+ const customData = {};
91
+ const reserved = new Set(['id', 'name', 'size', 'type', 'src', 'image', 'lastModified', 'last-modified']);
92
+
93
+ Object.entries(dataFile).forEach(([key, value]) => {
94
+ if (reserved.has(key)) return;
95
+ if (value === undefined || value === null || value === '') return;
96
+ customData[key] = value;
97
+ });
98
+
99
+ if (Object.keys(customData).length) {
100
+ result.customData = customData;
101
+ }
102
+
103
+ return result;
104
+ }
105
+
106
+ _extractBinaryMeta(dataFile) {
107
+ const binary = dataFile.file || dataFile.blob || dataFile.originFile || null;
108
+ if (!(binary instanceof Blob)) return {};
109
+
110
+ const size = this._toNumberOrNull(binary.size);
111
+ const type = this._toStringOrNull(binary.type);
112
+ const lastModified = (binary instanceof File)
113
+ ? this._toNumberOrNull(binary.lastModified)
114
+ : null;
115
+
116
+ return {
117
+ size: size ?? null,
118
+ type: type || null,
119
+ lastModified: lastModified ?? null
120
+ };
121
+ }
122
+
123
+ _toStringOrNull(value) {
124
+ if (value === undefined || value === null) return null;
125
+ const normalized = String(value).trim();
126
+ return normalized ? normalized : null;
127
+ }
128
+
129
+ _toNumberOrNull(value) {
130
+ if (value === undefined || value === null || value === '') return null;
131
+ const normalized = Number(value);
132
+ return Number.isFinite(normalized) ? normalized : null;
133
+ }
134
+
135
+ _setTemplateInBuffer($items) {
136
+ if (this.bufferTemplate || $items.length === 0) return;
137
+
138
+ const firstItem = $items[0];
139
+
140
+ if (!Manipulator.has(firstItem, 'data-file')) {
141
+ this.bufferTemplate = firstItem.outerHTML;
142
+ firstItem.remove();
143
+ } else {
144
+ this.bufferTemplate = firstItem.outerHTML;
145
+ }
146
+ }
147
+
148
+ dispose() {
149
+ this.bufferTemplate = '';
150
+ this.parsedFiles = [];
151
+ }
152
+ }
153
+
154
154
  export default VGFilesTemplateRender;
@@ -51,12 +51,12 @@ class VGFiles extends VGFilesBase {
51
51
  maxConcurrent: 1,
52
52
  retryAttempts: 1,
53
53
  retryDelay: 1000,
54
- },
55
- removes: {
56
- buttons: null,
57
- all: { route: '', alert: true, toast: true, confirm: null, buttons: null },
58
- single: { route: '', alert: true, toast: true, confirm: null, buttons: null }
59
- },
54
+ },
55
+ removes: {
56
+ buttons: null,
57
+ all: { route: '', alert: true, toast: true, confirm: null, buttons: null },
58
+ single: { route: '', alert: true, toast: true, confirm: null, buttons: null }
59
+ },
60
60
  sortable: {
61
61
  enabled: false,
62
62
  route: '',
@@ -483,14 +483,14 @@ class VGFiles extends VGFilesBase {
483
483
  if (li) {
484
484
  this._setButtonElement(file);
485
485
 
486
- const fileRemove = Selectors.find('.file-remove', li);
487
- if (fileRemove) {
488
- fileRemove.innerHTML = '';
489
- fileRemove.appendChild(this._setFailingButtons(file));
490
- Classes.add(li, CLASS_NAME_FAILING);
491
- }
492
- }
493
- }
486
+ const fileRemove = Selectors.find('.file-remove', li);
487
+ if (fileRemove) {
488
+ fileRemove.innerHTML = '';
489
+ fileRemove.appendChild(this._setFailingButtons(file));
490
+ Classes.add(li, CLASS_NAME_FAILING);
491
+ }
492
+ }
493
+ }
494
494
 
495
495
  const payload = { file: uploadData.file };
496
496
 
@@ -586,11 +586,11 @@ class VGFiles extends VGFilesBase {
586
586
  return { accepted: Boolean(result), data: null };
587
587
  }
588
588
 
589
- _runDefaultRemoveConfirm(trigger, params) {
590
- return new Promise((resolve) => {
591
- VGAlert.confirm(trigger, {
592
- lang: params.lang,
593
- ajax: params.ajax,
589
+ _runDefaultRemoveConfirm(trigger, params) {
590
+ return new Promise((resolve) => {
591
+ VGAlert.confirm(trigger, {
592
+ lang: params.lang,
593
+ ajax: params.ajax,
594
594
  buttons: params.buttons,
595
595
  message: params.message
596
596
  });
@@ -601,58 +601,58 @@ class VGFiles extends VGFilesBase {
601
601
 
602
602
  EventHandler.one(trigger, 'vg.alert.reject', () => {
603
603
  resolve({ accepted: false, data: null });
604
- });
605
- });
606
- }
607
-
608
- _isPlainObject(value) {
609
- return value && typeof value === 'object' && !Array.isArray(value);
610
- }
611
-
612
- _mergeButtonConfigs(...configs) {
613
- return configs.reduce((acc, config) => {
614
- if (!this._isPlainObject(config)) return acc;
615
-
616
- Object.entries(config).forEach(([key, value]) => {
617
- if (this._isPlainObject(acc[key]) && this._isPlainObject(value)) {
618
- acc[key] = this._mergeButtonConfigs(acc[key], value);
619
- return;
620
- }
621
-
622
- acc[key] = Array.isArray(value) ? value.slice() : value;
623
- });
624
-
625
- return acc;
626
- }, {});
627
- }
628
-
629
- _getDefaultRemoveConfirmButtons() {
630
- return {
631
- agree: {
632
- text: lang_buttons(this._params.lang, NAME)['agree'],
633
- class: ["btn-danger"],
634
- },
635
- cancel: {
636
- text: lang_buttons(this._params.lang, NAME)['cancel'],
637
- class: ["btn-outline-danger"],
638
- },
639
- };
640
- }
641
-
642
- _getRemoveConfirmButtons(type) {
643
- return this._mergeButtonConfigs(
644
- this._getDefaultRemoveConfirmButtons(),
645
- this._params?.removes?.buttons,
646
- this._params?.removes?.[type]?.buttons
647
- );
648
- }
649
-
650
- _confirmRemove(type, trigger, ajax, message) {
651
- const buttons = this._getRemoveConfirmButtons(type);
652
-
653
- const confirmParams = {
654
- type,
655
- trigger,
604
+ });
605
+ });
606
+ }
607
+
608
+ _isPlainObject(value) {
609
+ return value && typeof value === 'object' && !Array.isArray(value);
610
+ }
611
+
612
+ _mergeButtonConfigs(...configs) {
613
+ return configs.reduce((acc, config) => {
614
+ if (!this._isPlainObject(config)) return acc;
615
+
616
+ Object.entries(config).forEach(([key, value]) => {
617
+ if (this._isPlainObject(acc[key]) && this._isPlainObject(value)) {
618
+ acc[key] = this._mergeButtonConfigs(acc[key], value);
619
+ return;
620
+ }
621
+
622
+ acc[key] = Array.isArray(value) ? value.slice() : value;
623
+ });
624
+
625
+ return acc;
626
+ }, {});
627
+ }
628
+
629
+ _getDefaultRemoveConfirmButtons() {
630
+ return {
631
+ agree: {
632
+ text: lang_buttons(this._params.lang, NAME)['agree'],
633
+ class: ["btn-danger"],
634
+ },
635
+ cancel: {
636
+ text: lang_buttons(this._params.lang, NAME)['cancel'],
637
+ class: ["btn-outline-danger"],
638
+ },
639
+ };
640
+ }
641
+
642
+ _getRemoveConfirmButtons(type) {
643
+ return this._mergeButtonConfigs(
644
+ this._getDefaultRemoveConfirmButtons(),
645
+ this._params?.removes?.buttons,
646
+ this._params?.removes?.[type]?.buttons
647
+ );
648
+ }
649
+
650
+ _confirmRemove(type, trigger, ajax, message) {
651
+ const buttons = this._getRemoveConfirmButtons(type);
652
+
653
+ const confirmParams = {
654
+ type,
655
+ trigger,
656
656
  lang: this._params.lang,
657
657
  ajax,
658
658
  buttons,
@@ -711,15 +711,15 @@ class VGFiles extends VGFilesBase {
711
711
  }
712
712
  });
713
713
 
714
- if (this._params.ajax && this._params.removes.single.route) {
715
- if (!id) {
716
- this._files = this._files.filter(f => !(f.name === name && f.size === size));
717
- this._updateStatsAfterRemove();
718
- this._files.length ? this.build() : this.clear(true);
719
- emitRemove();
720
- this._resetFileInput();
721
- return;
722
- }
714
+ if (this._params.ajax && this._params.removes.single.route) {
715
+ if (!id) {
716
+ this._files = this._files.filter(f => !(f.name === name && f.size === size));
717
+ this._updateStatsAfterRemove();
718
+ this._files.length ? this.build() : this.clear(true);
719
+ emitRemove();
720
+ this._resetFileInput();
721
+ return;
722
+ }
723
723
 
724
724
  const routeBase = this._params.removes.single.route;
725
725
  const routeSeparator = routeBase.includes('?') ? '&' : '?';
@@ -809,36 +809,36 @@ class VGFiles extends VGFilesBase {
809
809
  return Selectors.find(`button[data-name="${file.name}"][data-size="${file.size}"]`, this._element);
810
810
  }
811
811
 
812
- _setButtonElement(file, isAjax = false, status = '') {
813
- let icon = getSVG('trash'), action = 'data-vg-dismiss';
814
- if (!this._params.info) icon = getSVG('cross');
815
- if (isAjax) {
816
- icon = getSVG('spinner');
817
- if (status === 'completed') icon = getSVG('check');
818
- else action = 'data-vg-reload';
819
- }
820
-
821
- return this._tpl.button([
822
- this._tpl.i({}, icon, { isHTML: true })
823
- ], 'button', this._buildFileDataAttributes(file, {
812
+ _setButtonElement(file, isAjax = false, status = '') {
813
+ let icon = getSVG('trash'), action = 'data-vg-dismiss';
814
+ if (!this._params.info) icon = getSVG('cross');
815
+ if (isAjax) {
816
+ icon = getSVG('spinner');
817
+ if (status === 'completed') icon = getSVG('check');
818
+ else action = 'data-vg-reload';
819
+ }
820
+
821
+ return this._tpl.button([
822
+ this._tpl.i({}, icon, { isHTML: true })
823
+ ], 'button', this._buildFileDataAttributes(file, {
824
824
  type: 'button',
825
825
  [action]: 'file',
826
826
  'data-name': file.name,
827
827
  'data-size': file.size ?? 0,
828
828
  'data-type': file.type || '',
829
829
  'data-last-modified': file.lastModified || '',
830
- 'data-id': file.id || ''
831
- }));
832
- }
833
-
834
- _setFailingButtons(file) {
835
- const wrapper = this._tpl.div({ class: 'file-failing-actions' }, [
836
- this._setButtonElement(file, true, 'failing'),
837
- this._setButtonElement(file)
838
- ]);
839
-
840
- return wrapper;
841
- }
830
+ 'data-id': file.id || ''
831
+ }));
832
+ }
833
+
834
+ _setFailingButtons(file) {
835
+ const wrapper = this._tpl.div({ class: 'file-failing-actions' }, [
836
+ this._setButtonElement(file, true, 'failing'),
837
+ this._setButtonElement(file)
838
+ ]);
839
+
840
+ return wrapper;
841
+ }
842
842
 
843
843
  _renderStat() {
844
844
  if (!this._nodes.stat) return;