vgapp 1.4.8 → 1.5.0

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 (86) hide show
  1. package/README.md +24 -2
  2. package/app/modules/base-module.js +14 -2
  3. package/app/modules/module-fn.js +5 -4
  4. package/app/modules/vgalert/js/vgalert.js +21 -1
  5. package/app/modules/vgalert/scss/vgalert.scss +48 -0
  6. package/app/modules/vgdropdown/js/vgdropdown.js +58 -27
  7. package/app/modules/vgfilepreview/js/renderers/video-modal.js +5 -1
  8. package/app/modules/vgfilepreview/js/renderers/video.js +6 -1
  9. package/app/modules/vgfilepreview/js/vgfilepreview.js +5 -1
  10. package/app/modules/vgfiles/js/base.js +29 -15
  11. package/app/modules/vgfiles/js/droppable.js +37 -31
  12. package/app/modules/vgfiles/js/vgfiles.js +10 -4
  13. package/app/modules/vgfiles/scss/_mixins.scss +12 -2
  14. package/app/modules/vgfiles/scss/_variables.scss +3 -1
  15. package/app/modules/vgfiles/scss/vgfiles.scss +55 -10
  16. package/app/modules/vgformsender/js/vgformsender.js +5 -2
  17. package/app/modules/vgloadmore/js/vgloadmore.js +35 -7
  18. package/app/modules/vgnestable/js/vgnestable.js +140 -0
  19. package/app/modules/vgnestable/scss/_variables.scss +16 -9
  20. package/app/modules/vgnestable/scss/vgnestable.scss +35 -2
  21. package/app/modules/vgtable/index.js +3 -0
  22. package/app/modules/vgtable/js/_columns.js +567 -0
  23. package/app/modules/vgtable/js/_expandable.js +242 -0
  24. package/app/modules/vgtable/js/_filters.js +264 -0
  25. package/app/modules/vgtable/js/_fixed-columns.js +249 -0
  26. package/app/modules/vgtable/js/_i18n.js +75 -0
  27. package/app/modules/vgtable/js/_options.js +428 -0
  28. package/app/modules/vgtable/js/_pagination.js +491 -0
  29. package/app/modules/vgtable/js/_panning.js +124 -0
  30. package/app/modules/vgtable/js/_params-groups.js +21 -0
  31. package/app/modules/vgtable/js/_remote.js +395 -0
  32. package/app/modules/vgtable/js/_row-reorder.js +268 -0
  33. package/app/modules/vgtable/js/_search.js +134 -0
  34. package/app/modules/vgtable/js/_selection.js +113 -0
  35. package/app/modules/vgtable/js/_skeleton.js +123 -0
  36. package/app/modules/vgtable/js/_sorting.js +340 -0
  37. package/app/modules/vgtable/js/_states.js +143 -0
  38. package/app/modules/vgtable/js/_sticky-header.js +218 -0
  39. package/app/modules/vgtable/js/_url-state.js +178 -0
  40. package/app/modules/vgtable/js/vgtable.js +1444 -0
  41. package/app/modules/vgtable/readme.md +922 -0
  42. package/app/modules/vgtable/scss/_columns.scss +52 -0
  43. package/app/modules/vgtable/scss/_expandable.scss +54 -0
  44. package/app/modules/vgtable/scss/_fixed-columns.scss +117 -0
  45. package/app/modules/vgtable/scss/_pagination.scss +191 -0
  46. package/app/modules/vgtable/scss/_row-reorder.scss +45 -0
  47. package/app/modules/vgtable/scss/_skeleton.scss +65 -0
  48. package/app/modules/vgtable/scss/_sorting.scss +89 -0
  49. package/app/modules/vgtable/scss/_states.scss +70 -0
  50. package/app/modules/vgtable/scss/_sticky-header.scss +127 -0
  51. package/app/modules/vgtable/scss/_variables.scss +296 -0
  52. package/app/modules/vgtable/scss/vgtable.scss +206 -0
  53. package/app/utils/js/components/placement.js +64 -10
  54. package/app/vgapp.js +3 -3
  55. package/build/vgapp.css +1 -1
  56. package/build/vgapp.css.map +1 -1
  57. package/build/vgapp.js +1 -1
  58. package/build/vgapp.js.map +1 -1
  59. package/index.js +1 -1
  60. package/index.scss +3 -3
  61. package/package.json +4 -4
  62. package/app/modules/vgdynamictable/index.js +0 -4
  63. package/app/modules/vgdynamictable/js/editable.js +0 -438
  64. package/app/modules/vgdynamictable/js/expandable.js +0 -248
  65. package/app/modules/vgdynamictable/js/filters.js +0 -450
  66. package/app/modules/vgdynamictable/js/fixed.js +0 -566
  67. package/app/modules/vgdynamictable/js/options.js +0 -650
  68. package/app/modules/vgdynamictable/js/pagination.js +0 -623
  69. package/app/modules/vgdynamictable/js/search.js +0 -82
  70. package/app/modules/vgdynamictable/js/skeleton.js +0 -144
  71. package/app/modules/vgdynamictable/js/sortable.js +0 -442
  72. package/app/modules/vgdynamictable/js/summary-footer.js +0 -284
  73. package/app/modules/vgdynamictable/js/table-remote.js +0 -821
  74. package/app/modules/vgdynamictable/js/table-state.js +0 -243
  75. package/app/modules/vgdynamictable/js/table-url-state.js +0 -444
  76. package/app/modules/vgdynamictable/js/utils/common.js +0 -48
  77. package/app/modules/vgdynamictable/js/vgdynamictable.js +0 -3870
  78. package/app/modules/vgdynamictable/js/viewport.js +0 -322
  79. package/app/modules/vgdynamictable/readme.md +0 -251
  80. package/app/modules/vgdynamictable/scss/_actions.scss +0 -196
  81. package/app/modules/vgdynamictable/scss/_pagination.scss +0 -186
  82. package/app/modules/vgdynamictable/scss/_skeleton.scss +0 -63
  83. package/app/modules/vgdynamictable/scss/_sortable.scss +0 -66
  84. package/app/modules/vgdynamictable/scss/_table.scss +0 -137
  85. package/app/modules/vgdynamictable/scss/_variables.scss +0 -138
  86. package/app/modules/vgdynamictable/scss/vgdynamictable.scss +0 -264
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Описание: доступная вложенная сортировка списков в стиле Nestable без зависимости от jQuery.
3
+ * Возможности: drag-and-drop мышью и touch, клавиатурное перемещение, связанные списки, collapse API, сериализация и AJAX-сохранение.
4
+ */
1
5
  import BaseModule from "../../base-module";
2
6
  import VGCollapse from "../../vgcollapse/js/vgcollapse";
3
7
  import { mergeDeepObject, normalizeData } from "../../../utils/js/functions";
@@ -11,6 +15,7 @@ const NAME = "nestable";
11
15
  const NAME_KEY = "vg.nestable";
12
16
 
13
17
  const SELECTOR_DATA_TOGGLE = '[data-vg-toggle="nestable"]';
18
+ const SELECTOR_DATA_ACTION = '[data-vg-nestable-action]';
14
19
 
15
20
  const CLASS_ITEM_DRAGGING = "is-dragging";
16
21
  const CLASS_ITEM_GHOST = "is-drag-ghost";
@@ -24,6 +29,7 @@ const CLASS_INNER = "vg-nestable-inner";
24
29
  const CLASS_HANDLE = "vg-nestable-handle";
25
30
  const CLASS_HANDLE_ICON = "vg-nestable-handle-icon";
26
31
  const CLASS_COLLAPSE_TOGGLE = "vg-nestable-collapse-toggle";
32
+ const CLASS_EMPTY = "vg-nestable-empty";
27
33
  const CLASS_DROP_TARGET = "is-drop-target";
28
34
  const CLASS_DROP_DENIED = "is-drop-denied";
29
35
  const CLASS_DROP_BEFORE = "is-drop-before";
@@ -44,6 +50,8 @@ const EVENT_KEY_DROP = `${NAME_KEY}.drop`;
44
50
  const EVENT_KEY_TRANSFER = `${NAME_KEY}.transfer`;
45
51
  const EVENT_KEY_PLACEHOLDER_MOVE = `${NAME_KEY}.placeholdermove`;
46
52
  const EVENT_KEY_DESTROY = `${NAME_KEY}.destroy`;
53
+ const EVENT_KEY_COLLAPSE = `${NAME_KEY}.collapse`;
54
+ const EVENT_KEY_EXPAND = `${NAME_KEY}.expand`;
47
55
 
48
56
  class VGNestable extends BaseModule {
49
57
  static _groups = new Map();
@@ -58,8 +66,10 @@ class VGNestable extends BaseModule {
58
66
  itemselector: ".vg-nestable-item", // Sortable item selector.
59
67
  handleselector: ".vg-nestable-handle", // Drag handle selector.
60
68
  idattribute: "data-id", // Item id attribute used by serialize().
69
+ serializedata: true, // Include the remaining data-* attributes, like the original Nestable.
61
70
  childlistclass: "vg-nestable-list", // Class for auto-created child list.
62
71
  handleicon: '', // иконка для хендлера
72
+ emptytext: "Drop items here", // Accessible empty-list hint.
63
73
  indent: 18, // Small horizontal gesture (px) that moves the item under the previous sibling.
64
74
  maxdepth: 6, // Maximum nesting depth.
65
75
  moveaxis: "default", // Drag direction: default | vertical | horizontal.
@@ -85,6 +95,8 @@ class VGNestable extends BaseModule {
85
95
  drop: null,
86
96
  transfer: null,
87
97
  change: null,
98
+ collapse: null,
99
+ expand: null,
88
100
  end: null,
89
101
  save: null,
90
102
  destroy: null
@@ -143,6 +155,7 @@ class VGNestable extends BaseModule {
143
155
  this._activeTouchId = null;
144
156
  this._keyboardDraggedItem = null;
145
157
  this._keyboardStartSnapshot = "";
158
+ this._keyboardOrigin = null;
146
159
  this._liveRegion = null;
147
160
 
148
161
  if (!this._rootList) {
@@ -192,6 +205,10 @@ class VGNestable extends BaseModule {
192
205
  return EVENT_KEY_SAVE;
193
206
  case "destroy":
194
207
  return EVENT_KEY_DESTROY;
208
+ case "collapse":
209
+ return EVENT_KEY_COLLAPSE;
210
+ case "expand":
211
+ return EVENT_KEY_EXPAND;
195
212
  default:
196
213
  return `${NAME_KEY}.${action}`;
197
214
  }
@@ -307,11 +324,100 @@ class VGNestable extends BaseModule {
307
324
  this._syncItemCollapse(item);
308
325
  });
309
326
 
327
+ this._syncEmptyState();
328
+
310
329
  this._emit("refresh", {
311
330
  items: this._getItems().length
312
331
  });
313
332
  }
314
333
 
334
+ /**
335
+ * Expands one branch and keeps its toggle state synchronized.
336
+ * @param {HTMLElement|string} item Item element or selector inside this tree.
337
+ * @returns {boolean}
338
+ */
339
+ expandItem(item) {
340
+ return this._setItemExpanded(item, true);
341
+ }
342
+
343
+ /**
344
+ * Collapses one branch and keeps its toggle state synchronized.
345
+ * @param {HTMLElement|string} item Item element or selector inside this tree.
346
+ * @returns {boolean}
347
+ */
348
+ collapseItem(item) {
349
+ return this._setItemExpanded(item, false);
350
+ }
351
+
352
+ /** Expand every branch, matching the original Nestable public method. */
353
+ expandAll() {
354
+ let changed = 0;
355
+ this._getItems().forEach((item) => {
356
+ if (this.expandItem(item)) changed += 1;
357
+ });
358
+ return changed;
359
+ }
360
+
361
+ /** Collapse every branch, matching the original Nestable public method. */
362
+ collapseAll() {
363
+ let changed = 0;
364
+ this._getItems().forEach((item) => {
365
+ if (this.collapseItem(item)) changed += 1;
366
+ });
367
+ return changed;
368
+ }
369
+
370
+ _setItemExpanded(item, expanded) {
371
+ const target = typeof item === "string" ? this._element.querySelector(item) : item;
372
+ if (!target || !target.matches?.(this._params.itemselector) || !this._rootList.contains(target)) {
373
+ return false;
374
+ }
375
+
376
+ const childList = this._getDirectChildBySelector(target, this._params.listselector);
377
+ if (!childList) return false;
378
+
379
+ const isExpanded = childList.classList.contains("show");
380
+ if (isExpanded === expanded) return false;
381
+
382
+ const collapse = VGCollapse.getOrCreateInstance(childList, { toggle: false });
383
+ if (expanded) {
384
+ collapse.show();
385
+ } else {
386
+ collapse.hide();
387
+ }
388
+
389
+ this._emit(expanded ? "expand" : "collapse", {
390
+ item: target,
391
+ list: childList,
392
+ expanded
393
+ });
394
+ return true;
395
+ }
396
+
397
+ _syncEmptyState() {
398
+ if (!this._rootList) return;
399
+
400
+ const hasItems = Array.from(this._rootList.children)
401
+ .some((child) => child.matches(this._params.itemselector));
402
+ let empty = this._getDirectChildBySelector(this._rootList, `.${CLASS_EMPTY}`);
403
+
404
+ if (hasItems) {
405
+ empty?.remove();
406
+ this._rootList.classList.remove("is-empty");
407
+ return;
408
+ }
409
+
410
+ if (!empty) {
411
+ empty = document.createElement(this._rootList.tagName?.toLowerCase() === "ol" ? "li" : "div");
412
+ empty.className = CLASS_EMPTY;
413
+ empty.setAttribute("aria-live", "polite");
414
+ this._rootList.append(empty);
415
+ }
416
+
417
+ empty.textContent = String(this._params.emptytext || "Drop items here");
418
+ this._rootList.classList.add("is-empty");
419
+ }
420
+
315
421
  _syncItemCollapse(item) {
316
422
  if (!item || !this._params.collapse?.enabled) {
317
423
  return;
@@ -826,6 +932,10 @@ class VGNestable extends BaseModule {
826
932
 
827
933
  this._keyboardDraggedItem = item;
828
934
  this._keyboardStartSnapshot = JSON.stringify(this.serialize());
935
+ this._keyboardOrigin = {
936
+ parent: item.parentElement,
937
+ next: item.nextSibling
938
+ };
829
939
  item.classList.add(CLASS_ITEM_DRAGGING);
830
940
  item.setAttribute("aria-grabbed", "true");
831
941
 
@@ -844,6 +954,13 @@ class VGNestable extends BaseModule {
844
954
 
845
955
  const draggedItem = this._keyboardDraggedItem;
846
956
  const previousPayload = this._keyboardStartSnapshot ? JSON.parse(this._keyboardStartSnapshot) : [];
957
+ if (options.cancelled && this._keyboardOrigin?.parent) {
958
+ const { parent, next } = this._keyboardOrigin;
959
+ parent.insertBefore(draggedItem, next?.parentElement === parent ? next : null);
960
+ this._cleanupEmptyLists();
961
+ this.refresh();
962
+ draggedItem.focus?.();
963
+ }
847
964
  const payload = this.serialize();
848
965
  const changed = this._keyboardStartSnapshot !== JSON.stringify(payload);
849
966
 
@@ -890,6 +1007,7 @@ class VGNestable extends BaseModule {
890
1007
 
891
1008
  this._keyboardDraggedItem = null;
892
1009
  this._keyboardStartSnapshot = "";
1010
+ this._keyboardOrigin = null;
893
1011
  }
894
1012
 
895
1013
  _moveKeyboardUp(item) {
@@ -1878,6 +1996,15 @@ class VGNestable extends BaseModule {
1878
1996
  const childList = item.querySelector(`:scope > ${this._params.listselector}`);
1879
1997
 
1880
1998
  const data = { id: id ?? null };
1999
+ if (normalizeData(this._params.serializedata) !== false) {
2000
+ Array.from(item.attributes).forEach((attribute) => {
2001
+ if (!attribute.name.startsWith("data-") || attribute.name === this._params.idattribute) return;
2002
+ const key = attribute.name
2003
+ .slice(5)
2004
+ .replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
2005
+ data[key] = normalizeData(attribute.value === "" ? "true" : attribute.value);
2006
+ });
2007
+ }
1881
2008
 
1882
2009
  if (childList) {
1883
2010
  const children = this._serializeList(childList);
@@ -1895,6 +2022,19 @@ EventHandler.on(document, `DOMContentLoaded.${NAME_KEY}.data.api`, () => {
1895
2022
  Selectors.findAll(SELECTOR_DATA_TOGGLE).forEach((el) => VGNestable.getOrCreateInstance(el));
1896
2023
  });
1897
2024
 
2025
+ EventHandler.on(document, `click.${NAME_KEY}.data.api`, SELECTOR_DATA_ACTION, function (event) {
2026
+ event.preventDefault();
2027
+ const selector = this.getAttribute("data-vg-target");
2028
+ const element = selector ? Selectors.find(selector) : this.closest(SELECTOR_DATA_TOGGLE);
2029
+ if (!element) return;
2030
+
2031
+ const instance = VGNestable.getOrCreateInstance(element);
2032
+ const action = String(this.getAttribute("data-vg-nestable-action") || "").trim();
2033
+ if (["expandAll", "collapseAll"].includes(action)) {
2034
+ instance[action]();
2035
+ }
2036
+ });
2037
+
1898
2038
  export default VGNestable;
1899
2039
 
1900
2040
 
@@ -1,6 +1,13 @@
1
1
  @use "../../../utils/scss" as vg;
2
2
 
3
3
  $nestable-map: (
4
+ max-width: 40rem,
5
+ empty-min-height: 5rem,
6
+ empty-padding: 1rem,
7
+ empty-border: vg.$border-width dashed var(--vg-border-disabled-color, rgba(0, 0, 0, .18)),
8
+ empty-bg: var(--vg-surface-subtle-bg, rgba(0, 0, 0, .025)),
9
+ empty-color: var(--vg-text-muted-color, rgba(0, 0, 0, .6)),
10
+ empty-border-radius: .5rem,
4
11
  list-transition: "background-color .15s ease, outline-color .15s ease",
5
12
  list-drop-target-bg: var(--vg-primary-subtle-bg, rgba(13, 110, 253, .06)),
6
13
  list-drop-target-outline: vg.$border-width dashed var(--vg-primary-outline-color, rgba(13, 110, 253, .45)),
@@ -9,7 +16,7 @@ $nestable-map: (
9
16
  list-drop-denied-outline: vg.$border-width dashed var(--vg-danger-outline-color, rgba(220, 53, 69, .5)),
10
17
  list-drop-denied-outline-offset: 2px,
11
18
  list-nested-margin-top: .35rem,
12
- list-nested-padding-left: 1.25rem,
19
+ list-nested-padding-left: 1.875rem,
13
20
  list-nested-border-left: vg.$border-width dashed var(--vg-border-disabled-color, rgba(0, 0, 0, .12)),
14
21
 
15
22
  item-margin: .35rem 0,
@@ -25,15 +32,15 @@ $nestable-map: (
25
32
  item-disabled-handle-color: var(--vg-text-placeholder-color, rgba(0, 0, 0, .28)),
26
33
 
27
34
  inner-gap: .5rem,
28
- inner-min-height: 40px,
29
- inner-padding: .45rem .65rem,
35
+ inner-min-height: 42px,
36
+ inner-padding: .4rem .65rem .4rem .35rem,
30
37
  inner-border: vg.$border-width vg.$border-style var(--vg-border-disabled-color, rgba(0, 0, 0, .12)),
31
38
  inner-bg: var(--vg-surface-bg, #{vg.$surface-bg}),
32
39
  inner-border-radius: .45rem,
33
40
 
34
- handle-size: 1.85rem,
35
- handle-border: vg.$border-width vg.$border-style var(--vg-border-disabled-color, rgba(0, 0, 0, .12)),
36
- handle-bg: var(--vg-surface-subtle-bg, rgba(0, 0, 0, .03)),
41
+ handle-size: 2rem,
42
+ handle-border: 0,
43
+ handle-bg: transparent,
37
44
  handle-border-radius: .35rem,
38
45
  handle-cursor: grab,
39
46
  handle-active-cursor: grabbing,
@@ -61,9 +68,9 @@ $nestable-map: (
61
68
  placeholder-bg: var(--vg-primary-subtle-bg, rgba(13, 110, 253, .08)),
62
69
  placeholder-border-radius: .45rem,
63
70
  placeholder-margin: .35rem 0,
64
- placeholder-min-height: 40px,
71
+ placeholder-min-height: 42px,
65
72
 
66
73
  drag-element-opacity: 1,
67
- drag-element-transform: scale(1.01),
68
- drag-element-shadow: 0 12px 30px var(--vg-shadow-color, rgba(0, 0, 0, .2))
74
+ drag-element-transform: translate3d(0, 0, 0) scale(1.01),
75
+ drag-element-shadow: 0 10px 24px var(--vg-shadow-color, rgba(0, 0, 0, .18))
69
76
  ) !default;
@@ -12,6 +12,23 @@
12
12
 
13
13
  .vg-nestable {
14
14
  @include vg.mix-vars('nestable', vars.$nestable-map);
15
+ position: relative;
16
+ display: block;
17
+ width: 100%;
18
+ max-width: var(--vg-nestable-max-width);
19
+
20
+ &-empty {
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ min-height: var(--vg-nestable-empty-min-height);
25
+ padding: var(--vg-nestable-empty-padding);
26
+ border: var(--vg-nestable-empty-border);
27
+ background: var(--vg-nestable-empty-bg);
28
+ color: var(--vg-nestable-empty-color);
29
+ border-radius: var(--vg-nestable-empty-border-radius);
30
+ text-align: center;
31
+ }
15
32
 
16
33
  &-list {
17
34
  list-style: none;
@@ -19,6 +36,10 @@
19
36
  padding: 0;
20
37
  transition: var(--vg-nestable-list-transition);
21
38
 
39
+ &.is-empty {
40
+ min-height: var(--vg-nestable-empty-min-height);
41
+ }
42
+
22
43
  &.is-drop-target {
23
44
  background: var(--vg-nestable-list-drop-target-bg);
24
45
  outline: var(--vg-nestable-list-drop-target-outline);
@@ -94,6 +115,7 @@
94
115
  border: var(--vg-nestable-inner-border);
95
116
  background: var(--vg-nestable-inner-bg);
96
117
  border-radius: var(--vg-nestable-inner-border-radius);
118
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .025);
97
119
  }
98
120
 
99
121
  &-handle {
@@ -110,6 +132,14 @@
110
132
  cursor: var(--vg-nestable-handle-cursor);
111
133
  user-select: none;
112
134
  touch-action: none;
135
+ color: var(--vg-nestable-handle-icon-color);
136
+
137
+ &:hover,
138
+ &:focus-visible {
139
+ background: var(--vg-nestable-toggle-hover-bg);
140
+ color: var(--vg-text-color, currentColor);
141
+ outline: none;
142
+ }
113
143
 
114
144
  &:active {
115
145
  cursor: var(--vg-nestable-handle-active-cursor);
@@ -178,6 +208,7 @@
178
208
  border-radius: var(--vg-nestable-placeholder-border-radius);
179
209
  margin: var(--vg-nestable-placeholder-margin);
180
210
  min-height: var(--vg-nestable-placeholder-min-height);
211
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--vg-nestable-item-drop-line) 12%, transparent);
181
212
  }
182
213
 
183
214
  &-placeholder-hidden {
@@ -191,10 +222,12 @@
191
222
  &-item.is-drag-ghost#{&}-drag-element {
192
223
  opacity: var(--vg-nestable-drag-element-opacity);
193
224
  transform: var(--vg-nestable-drag-element-transform);
194
- box-shadow: var(--vg-nestable-drag-element-shadow);
225
+ transform-origin: top left;
226
+ filter: drop-shadow(var(--vg-nestable-drag-element-shadow));
195
227
 
196
- > .vg-nestable-inner {
228
+ .vg-nestable-inner {
197
229
  background: var(--vg-nestable-inner-bg);
230
+ box-shadow: 0 2px 5px rgba(0, 0, 0, .08);
198
231
  }
199
232
  }
200
233
  }
@@ -0,0 +1,3 @@
1
+ import VGTable from "./js/vgtable";
2
+
3
+ export default VGTable;