vgapp 0.7.3 → 0.7.5

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.
@@ -16,12 +16,6 @@ import VGCollapse from "../../vgcollapse/js/vgcollapse";
16
16
  import {getSVG} from "../../module-fn";
17
17
  import VGHideShowPass from "./hideshowpass";
18
18
 
19
- /**
20
- * TODO
21
- * доделай динамическое добавление полей в форму,
22
- * но не меняй место их получения (их нужно получить прямо перед отправкой, после того как выполнился промис beforeSend)
23
- */
24
-
25
19
  /**
26
20
  * Constants
27
21
  */
@@ -31,6 +25,8 @@ const NAME_KEY = 'vg.fs';
31
25
  /**
32
26
  * Constants Events
33
27
  */
28
+ const CLASS_NAME_ALERT = 'vg-form-sender-alert';
29
+
34
30
  const EVENT_KEY_SUCCESS = 'vg.fs.success';
35
31
  const EVENT_KEY_ERROR = 'vg.fs.error';
36
32
  const EVENT_KEY_BEFORE = 'vg.fs.before';
@@ -100,13 +96,15 @@ class VGFormSender extends BaseModule {
100
96
  spinner: {
101
97
  enabled: false,
102
98
  element: '<span class="spinner-border spinner-border-sm me-2"></span>'
103
- }
99
+ },
100
+ click: noop,
104
101
  },
105
102
  }, params));
106
103
 
104
+ this._button = Selectors.find('[type="submit"]', this._element) || Selectors.find('[form="' + this._element.id + '"]') || null;
105
+
107
106
  this._params.ajax.route = Manipulator.get(this._element, 'action').toLowerCase();
108
107
  this._params.ajax.method = Manipulator.get(this._element, 'method').toLowerCase();
109
- this._button = Selectors.find('[type="submit"]', this._element) || Selectors.find('[form="' + this._element.id + '"]') || null;
110
108
 
111
109
  this._params.isBtnText = Manipulator.get(this._element, 'data-btn-text') !== 'false';
112
110
  this._params.isJsonParse = Manipulator.get(this._element, 'data-json-parse') !== 'false';
@@ -149,13 +147,23 @@ class VGFormSender extends BaseModule {
149
147
  return this
150
148
  }
151
149
 
152
- request(data, event) {
150
+ request(event, data = null) {
153
151
  const _this = this;
152
+ const mergeFormData = (target, source) => {
153
+ source.forEach((value, key) => {
154
+ target.set(key, value);
155
+ });
156
+ return target;
157
+ }
154
158
 
155
159
  _this._alertBefore();
156
160
 
157
161
  const submit = () => {
158
- _this._params.ajax.data = new FormData(_this._element);
162
+ let formData = new FormData(_this._element);
163
+
164
+ if (data) _this._params.ajax.data = mergeFormData(data, formData);
165
+ else _this._params.ajax.data = formData;
166
+
159
167
  _this._route(function (status, data) {
160
168
  _this._element.classList.remove('was-validated');
161
169
 
@@ -227,11 +235,23 @@ class VGFormSender extends BaseModule {
227
235
  EventHandler.trigger(_this._element, EVENT_KEY_SUCCESS, [event, _this, data]);
228
236
  }
229
237
 
238
+ static buttonClick(formID, callback, status = 'before') {
239
+ const form = Selectors.find(formID);
240
+ if (form) {
241
+ const instance = VGFormSender.getOrCreateInstance(formID);
242
+ form.addEventListener('vg.fs.' + status, e => {
243
+ execute(callback, [form, instance])
244
+ })
245
+ }
246
+ }
247
+
230
248
  _statusButton(status) {
231
249
  if (!this._button) return;
232
250
 
233
251
  if (status === 'before') {
234
- const button = getDeepestLastChild(this._button) || this._button;
252
+ const button = this._button;
253
+
254
+ this._params.button.initial = this._button.innerHTML.trim();
235
255
 
236
256
  if (this._params.button.spinner.enabled) {
237
257
  this._button.insertAdjacentHTML('afterbegin', this._params.button.spinner.element);
@@ -244,19 +264,25 @@ class VGFormSender extends BaseModule {
244
264
  if (this._params.button.disabled) {
245
265
  Manipulator.set(this._button,'disabled', 'disabled');
246
266
  }
267
+
268
+ execute(this._params.button.click, [this, this._button, 'before'])
247
269
  }
248
270
 
249
271
  if (status === 'after') {
250
272
  if (this._params.button.enabled) {
251
273
  this._button.innerHTML = this._params.button.initial;
252
274
  }
275
+
253
276
  if (this._params.button.disabled) {
254
277
  Manipulator.remove(this._button,'disabled');
255
278
  }
279
+
256
280
  if (this._params.button.spinner.enabled) {
257
281
  let spinner = this._button.querySelector('.spinner-border');
258
282
  if (spinner) spinner.remove();
259
283
  }
284
+
285
+ execute(this._params.button.click, [this, this._button, 'after'])
260
286
  }
261
287
  }
262
288
 
@@ -297,7 +323,7 @@ class VGFormSender extends BaseModule {
297
323
  }
298
324
  } else {
299
325
  if ('errors' in response && normalizeData(response.errors)) {
300
- status = normalizeData(response.errors) ? 'error' : 'success';
326
+ status = normalizeData(response.errors) ? 'danger' : 'success';
301
327
  }
302
328
  }
303
329
  }
@@ -388,7 +414,9 @@ class VGFormSender extends BaseModule {
388
414
  }
389
415
 
390
416
  setDataRelationStatus($element, status, data, type) {
391
- let $alert = Selectors.find('.vg-alert-' + status, $element);
417
+ if (status === 'error') status = 'danger';
418
+
419
+ let $alert = Selectors.find('.'+ CLASS_NAME_ALERT +'-' + status, $element);
392
420
 
393
421
  if (isObject(data)) {
394
422
  if (status === 'error') {
@@ -435,11 +463,11 @@ class VGFormSender extends BaseModule {
435
463
  code = ' ' + data.text + ' (' + data.code + ')';
436
464
  }
437
465
 
438
- if (!title) txt += '<h4 class="vg-alert-content--title">' + code + '</h4>';
439
- else txt += '<h4 class="vg-alert-content--title">' + title + '</h4>';
466
+ if (!title) txt += '<h4 class="'+ CLASS_NAME_ALERT +'-content--title">' + code + '</h4>';
467
+ else txt += '<h4 class="'+ CLASS_NAME_ALERT +'-content--title">' + title + '</h4>';
440
468
 
441
469
  if ('message' in response) {
442
- txt += '<div class="vg-alert-content--message">' + response.message + '</div>'
470
+ txt += '<div class="'+ CLASS_NAME_ALERT +'-content--message">' + response.message + '</div>'
443
471
  }
444
472
 
445
473
  if ('errors' in response && this._params.alert.errors) {
@@ -469,13 +497,13 @@ class VGFormSender extends BaseModule {
469
497
 
470
498
  if (!$alert) {
471
499
  $alert = document.createElement('div');
472
- $alert.classList.add('vg-alert', 'vg-alert-' + status, 'vg-alert-' + type);
500
+ $alert.classList.add(CLASS_NAME_ALERT, CLASS_NAME_ALERT + '-' + status, CLASS_NAME_ALERT + '-' + type);
473
501
 
474
502
  let content = document.createElement('div');
475
- content.classList.add('vg-alert-content');
503
+ content.classList.add(CLASS_NAME_ALERT + '-content');
476
504
 
477
505
  let icon = document.createElement('div');
478
- icon.classList.add('vg-alert-content--icon');
506
+ icon.classList.add(CLASS_NAME_ALERT + '-content--icon');
479
507
 
480
508
  let i = document.createElement('i');
481
509
  i.innerHTML = getSVG(status);
@@ -484,13 +512,13 @@ class VGFormSender extends BaseModule {
484
512
  content.append(icon);
485
513
 
486
514
  let text = document.createElement('div');
487
- text.classList.add('vg-alert-content--text');
515
+ text.classList.add(CLASS_NAME_ALERT + '-content--text');
488
516
  text.innerHTML = data.view;
489
517
 
490
518
  content.append(text);
491
519
  $alert.append(content);
492
520
  } else {
493
- let text = Selectors.find('.vg-alert-content--text', $alert);
521
+ let text = Selectors.find('.'+ CLASS_NAME_ALERT +'-content--text', $alert);
494
522
  text.innerHTML = data.view;
495
523
  }
496
524
 
@@ -529,34 +557,36 @@ EventHandler.on(document, EVENT_SUBMIT_DATA_API, function (event) {
529
557
  }
530
558
  }
531
559
 
532
- /*const collectData = function(data, fields) {
533
- for (let name in fields) {
534
- if (typeof fields[name] === 'object') {
535
- for (let key in fields[name]) {
536
- let arr = Object.keys(fields[name][key]).map(function (i) {
537
- return fields[name][key][i];
560
+ if (!instance._params.submit) {
561
+ event.preventDefault();
562
+
563
+ const collectData = function(data, fields) {
564
+ fields.forEach(function(field) {
565
+ if (isObject(field)) {
566
+ let keys = Object.keys(field);
567
+ keys.forEach(function(key) {
568
+ let value = normalizeData(field[key]);
569
+
570
+ if (Array.isArray(value) || isObject(value)) {
571
+ data.append(key, JSON.stringify(value));
572
+ } else {
573
+ data.append(key, value);
574
+ }
538
575
  });
539
- data.append(name, arr);
540
576
  }
541
- } else {
542
- data.append(name, fields[name]);
543
- }
544
- }
545
-
546
- return data;
547
- }*/
577
+ });
548
578
 
549
- if (!instance._params.submit) {
550
- event.preventDefault();
579
+ return data;
580
+ }
551
581
 
552
- //let data = new FormData(instance._element);
582
+ let data = new FormData(instance._element),
583
+ fields = instance._params.fields;
553
584
 
554
- // TODO доделать
555
- /*if (Array.isArray(instance._params.ajax.fields) && instance._params.ajax.fields.length) {
556
- data = collectData(data, instance._params.ajax.fields);
557
- }*/
585
+ if (Array.isArray(fields) && fields.length) {
586
+ data = collectData(data, fields);
587
+ }
558
588
 
559
- return instance.request(event);
589
+ return instance.request(event, data);
560
590
  }
561
591
  })
562
592
 
@@ -1,3 +1,3 @@
1
1
  $form-sender-map: (
2
2
  'eye-color': $color
3
- );
3
+ );
@@ -6,10 +6,10 @@
6
6
  *--------------------------------------------------------------------------
7
7
  **/
8
8
 
9
- @import "../../../utils/scss/functions";
10
- @import "../../../utils/scss/mixin";
11
- @import "../../../utils/scss/variables";
12
- @import "variables";
9
+ @import '../../../utils/scss/functions';
10
+ @import '../../../utils/scss/mixin';
11
+ @import '../../../utils/scss/variables';
12
+ @import 'variables';
13
13
 
14
14
  .vg-form-sender {
15
15
  @include mix-vars('form-sender', $form-sender-map);
@@ -45,4 +45,53 @@
45
45
  right: 34px;
46
46
  }
47
47
  }
48
+ }
49
+
50
+ .vg-form-sender-alert {
51
+ @include mix-alert-color-mode($class: vg-form-sender-alert);
52
+
53
+ background-color: var(--vg-form-sender-alert-background-color);
54
+ border: 1px solid var(--vg-form-sender-alert-border-color) ;
55
+ border-radius: var(--vg-border-radius);
56
+
57
+ &.vg-form-sender-alert-modal {
58
+ height: 260px;
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+
63
+ .vg-form-sender-alert-content {
64
+ display: flex;
65
+ flex-direction: column;
66
+ align-items: center;
67
+ gap: 1.5rem;
68
+ }
69
+
70
+ .vg-form-sender-alert-content--text {
71
+ text-align: center;
72
+ }
73
+ }
74
+
75
+ &.vg-form-sender-alert-collapse {
76
+ margin-bottom: 2rem;
77
+ padding: 2rem;
78
+
79
+ .vg-form-sender-alert-content {
80
+ display: flex;
81
+ gap: 2rem;
82
+ }
83
+ }
84
+ }
85
+
86
+ .vg-form-sender-alert-content--icon {
87
+ svg {
88
+ path {
89
+ fill: var(--vg-form-sender-alert-icon);
90
+ }
91
+ }
92
+ }
93
+
94
+ .vg-form-sender-alert-content--text {
95
+ font-size: 1.25rem;
96
+ color: var(--vg-form-sender-alert-color);
48
97
  }
@@ -70,12 +70,12 @@ class VGLoadMore extends BaseModule{
70
70
  buttonParams = normalizeData(el.dataset.button);
71
71
 
72
72
  if (!isObject(buttonParams)) {
73
- console.log('Дата атрибут data-button должен быть в формате json и передавать объект');
73
+ console.error('Дата атрибут data-button должен быть в формате json и передавать объект');
74
74
  return;
75
75
  }
76
76
 
77
77
  if (limit < offset) {
78
- console.log('Параметр offset должен быть меньше или равен параметру limit');
78
+ console.error('Параметр offset должен быть меньше или равен параметру limit');
79
79
  return;
80
80
  }
81
81
 
@@ -167,7 +167,7 @@ class VGRollup extends BaseModule {
167
167
  element.classList.add(_this.classes.ellipsis);
168
168
  element.style.webkitLineClamp = line;
169
169
  } else {
170
- console.log("Переменная [data-line] или параметр[line] не должны быть пустыми");
170
+ console.error("Переменная [data-line] или параметр[line] не должны быть пустыми");
171
171
  }
172
172
  }
173
173
  }
@@ -308,7 +308,6 @@ class VGSelect extends BaseModule {
308
308
  let observer = new MutationObserver(() => {
309
309
  clearTimeout(observerTimout);
310
310
  observerTimout = setTimeout(() => {
311
- console.log('asdas')
312
311
  VGSelect.build(select, true);
313
312
  }, 10);
314
313
  });
@@ -51,7 +51,6 @@ class VGSpy extends BaseModule {
51
51
  parentScrollTop: 0
52
52
  }
53
53
  this._params = this._configAfterMerge(this._params);
54
- console.log(this._params)
55
54
 
56
55
  this.refresh();
57
56
  }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Animation Loader
3
+ */
4
+ @keyframes vgLoader {
5
+ 0% {
6
+ transform: rotate(0deg);
7
+ }
8
+ 100% {
9
+ transform: rotate(360deg);
10
+ }
11
+ }
@@ -1,6 +1,7 @@
1
1
  @import "../../utils/scss/functions";
2
- @import "../../utils/scss/mixin";
3
2
  @import "../../utils/scss/variables";
3
+ @import "../../utils/scss/mixin";
4
+ @import "../../utils/scss/animation";
4
5
 
5
6
  .vg-backdrop {
6
7
  @include mix-vars('backdrop', $backdrop-map);
@@ -60,6 +61,7 @@
60
61
  width: 7em;
61
62
  height: 7em;
62
63
  }
64
+
63
65
  .vg-loader {
64
66
  @include mix-vars('loader', $loader-map);
65
67
  margin: var(--vg-loader-margin);
@@ -72,144 +74,4 @@
72
74
  border-left: var(--vg-loader-border-width) var(--vg-loader-border-style) var(--vg-loader-color);
73
75
  transform: var(--vg-loader-transform);
74
76
  animation: var(--vg-loader-animation);
75
- }
76
-
77
- /**
78
- * UI before Animation
79
- */
80
- .ui-success {
81
- &-circle {
82
- stroke-dasharray: 260.75219024795285px, 260.75219024795285px;
83
- stroke-dashoffset: 270.75219024795285px;
84
- transform: rotate(0);
85
- transform-origin: center center;
86
- stroke-linecap: round;
87
- animation: ani-success-circle 1s ease-in both;
88
- }
89
- &-path {
90
- stroke-dasharray: 60px 64px;
91
- stroke-dashoffset: 62px;
92
- stroke-linecap: round;
93
- animation: ani-success-path 0.4s 1s ease-in both;
94
- }
95
- }
96
-
97
- .ui-error {
98
- &-circle {
99
- stroke-dasharray: 260.75219024795285px, 260.75219024795285px;
100
- stroke-dashoffset: 260.75219024795285px;
101
- animation: ani-error-circle 1.2s linear;
102
- }
103
- &-line1 {
104
- stroke-dasharray: 54px 55px;
105
- stroke-dashoffset: 55px;
106
- stroke-linecap: round;
107
- animation: ani-error-line 0.15s 1.2s linear both;
108
- }
109
- &-line2 {
110
- stroke-dasharray: 54px 55px;
111
- stroke-dashoffset: 55px;
112
- stroke-linecap: round;
113
- animation: ani-error-line 0.2s 0.9s linear both;
114
- }
115
- }
116
-
117
- .ui-waiting {
118
- &-circle {
119
- stroke-dasharray: 260.75219024795285px, 260.75219024795285px;
120
- stroke-dashoffset: 260.75219024795285px;
121
- animation: ani-waiting-circle 1.2s linear;
122
- }
123
- &-line1 {
124
- stroke-dasharray: 280.75219024795285px, 200.75219024795285px;
125
- stroke-dashoffset: 280.75219024795285px;
126
- animation: ani-waiting-line 0.8s 0.3s linear both;
127
- transform: rotate(0);
128
- transform-origin: center center;
129
- }
130
- &-line2 {
131
- stroke-dasharray: 54px 55px;
132
- stroke-dashoffset: 55px;
133
- animation: ani-waiting-line2 0.85s .6s ease-in both;
134
- transform: rotate(0) scale(0.9);
135
- transform-origin: center center;
136
- }
137
- }
138
-
139
- /**
140
- * Animation Loader
141
- */
142
- @keyframes vgLoader {
143
- 0% {
144
- transform: rotate(0deg);
145
- }
146
- 100% {
147
- transform: rotate(360deg);
148
- }
149
- }
150
-
151
- // success animation
152
- @keyframes ani-success-circle {
153
- to {
154
- stroke-dashoffset: 782.2565707438586px;
155
- }
156
- }
157
-
158
- @keyframes ani-success-path {
159
- 0% {
160
- stroke-dashoffset: 62px;
161
- }
162
- 65% {
163
- stroke-dashoffset: -5px;
164
- }
165
- 84% {
166
- stroke-dashoffset: 4px;
167
- }
168
- 100% {
169
- stroke-dashoffset: -2px;
170
- }
171
- }
172
-
173
- // error animation
174
- @keyframes ani-error-line {
175
- to {
176
- stroke-dashoffset: 0;
177
- }
178
- }
179
-
180
- @keyframes ani-error-circle {
181
- 0% {
182
- stroke-dasharray: 0, 260.75219024795285px;
183
- stroke-dashoffset: 0;
184
- }
185
- 35% {
186
- stroke-dasharray: 120px, 120px;
187
- stroke-dashoffset: -120px;
188
- }
189
- 70% {
190
- stroke-dasharray: 0, 260.75219024795285px;
191
- stroke-dashoffset: -260.75219024795285px;
192
- }
193
- 100% {
194
- stroke-dasharray: 260.75219024795285px, 0;
195
- stroke-dashoffset: -260.75219024795285px;
196
- }
197
- }
198
-
199
- // waiting animation
200
- @keyframes ani-waiting-circle {
201
- to {
202
- stroke-dashoffset: 782.2565707438586px;
203
- }
204
- }
205
- @keyframes ani-waiting-line {
206
- to {
207
- stroke-dashoffset: 0;
208
- }
209
- }
210
- @keyframes ani-waiting-line2 {
211
- to {
212
- stroke-dashoffset: 0;
213
- transform: rotate(360deg) scale(1);
214
- }
215
77
  }
@@ -19,4 +19,22 @@
19
19
 
20
20
  @function tint-color($color, $weight) {
21
21
  @return mix(white, $color, $weight);
22
+ }
23
+
24
+ @function get-alert-color($type) {
25
+ @if $type == success {
26
+ @return $success-map;
27
+ }
28
+
29
+ @if $type == danger {
30
+ @return $danger-map;
31
+ }
32
+
33
+ @if $type == warning {
34
+ @return $warning-map;
35
+ }
36
+
37
+ @if $type == info {
38
+ @return $info-map;
39
+ }
22
40
  }
@@ -8,4 +8,16 @@
8
8
  --vg-#{$module}-#{$key}: #{$value}
9
9
  }
10
10
  }
11
+ }
12
+
13
+ @mixin mix-alert-color-mode($class) {
14
+ $colors: ['success', 'info', 'warning', 'danger'];
15
+
16
+ @each $value in $colors {
17
+ &.#{$class}-#{$value} {
18
+ @each $property, $val in get-alert-color($value) {
19
+ --#{$class}-#{$property}: #{$val};
20
+ }
21
+ }
22
+ }
11
23
  }
@@ -54,25 +54,25 @@ $loader-map: (
54
54
  );
55
55
 
56
56
  // Colors Status
57
- $danger: #dc3545 !default;
58
- $danger-border: tint-color($danger, 60%) !default;
59
- $danger-text: shade-color($danger, 60%) !default;
60
- $danger-bg: tint-color($danger, 80%) !default;
57
+ $danger: #FF2A2C !default;
58
+ $danger-border: #FFCCC7 !default;
59
+ $danger-text: #DF0306 !default;
60
+ $danger-bg: #FFF2F0 !default;
61
61
 
62
- $success: #198754;
63
- $success-border: tint-color($success, 60%) !default;
64
- $success-text: shade-color($success, 60%) !default;
65
- $success-bg: tint-color($success, 80%) !default;
62
+ $success: #4FD90B;
63
+ $success-border: #BAF98A !default;
64
+ $success-text: #40BE02 !default;
65
+ $success-bg: #F6FFED !default;
66
66
 
67
67
  $warning: #FFC107;
68
- $warning-border: tint-color($warning, 60%) !default;
69
- $warning-text: shade-color($warning, 60%) !default;
70
- $warning-bg: tint-color($warning, 80%) !default;
68
+ $warning-border: #FFDE79 !default;
69
+ $warning-text: #FFC107 !default;
70
+ $warning-bg: #FFF6DA !default;
71
71
 
72
- $info: #0DCAF0;
73
- $info-border: tint-color($info, 60%) !default;
74
- $info-text: shade-color($info, 60%) !default;
75
- $info-bg: tint-color($info, 80%) !default;
72
+ $info: #1F8BFF;
73
+ $info-border: #F0FAFF !default;
74
+ $info-text: #0471E5 !default;
75
+ $info-bg: #ADDDFF !default;
76
76
 
77
77
  $dark: #232323;
78
78
  $dark-border: shade-color($dark, 60%) !default;
@@ -80,24 +80,28 @@ $dark-text: tint-color($dark, 60%) !default;
80
80
  $dark-bg: shade-color($dark, 80%) !default;
81
81
 
82
82
  $success-map: (
83
+ icon: $success,
83
84
  color: $success-text,
84
85
  border-color: $success-border,
85
86
  background-color: $success-bg
86
87
  );
87
88
 
88
89
  $danger-map: (
90
+ icon: $danger,
89
91
  color: $danger-text,
90
92
  border-color: $danger-border,
91
93
  background-color: $danger-bg
92
94
  );
93
95
 
94
96
  $warning-map: (
97
+ icon: $warning,
95
98
  color: $warning-text,
96
99
  border-color: $warning-border,
97
100
  background-color: $warning-bg
98
101
  );
99
102
 
100
103
  $info-map: (
104
+ icon: $info,
101
105
  color: $info-text,
102
106
  border-color: $info-border,
103
107
  background-color: $info-bg