vgapp 1.2.5 → 1.3.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 (48) hide show
  1. package/README.md +131 -20
  2. package/app/modules/base-module.js +111 -17
  3. package/app/modules/vgalert/js/vgalert.js +3 -3
  4. package/app/modules/vgdynamictable/index.js +5 -0
  5. package/app/modules/vgdynamictable/js/editable.js +438 -0
  6. package/app/modules/vgdynamictable/js/expandable.js +248 -0
  7. package/app/modules/vgdynamictable/js/filters.js +450 -0
  8. package/app/modules/vgdynamictable/js/fixed.js +566 -0
  9. package/app/modules/vgdynamictable/js/options.js +646 -0
  10. package/app/modules/vgdynamictable/js/pagination.js +623 -0
  11. package/app/modules/vgdynamictable/js/search.js +82 -0
  12. package/app/modules/vgdynamictable/js/skeleton.js +136 -0
  13. package/app/modules/vgdynamictable/js/sortable.js +442 -0
  14. package/app/modules/vgdynamictable/js/summary-footer.js +284 -0
  15. package/app/modules/vgdynamictable/js/table-remote.js +821 -0
  16. package/app/modules/vgdynamictable/js/table-state.js +243 -0
  17. package/app/modules/vgdynamictable/js/table-url-state.js +444 -0
  18. package/app/modules/vgdynamictable/js/utils/common.js +48 -0
  19. package/app/modules/vgdynamictable/js/vgdynamictable.js +3829 -0
  20. package/app/modules/vgdynamictable/js/viewport.js +322 -0
  21. package/app/modules/vgdynamictable/readme.md +251 -0
  22. package/app/modules/vgdynamictable/scss/_actions.scss +193 -0
  23. package/app/modules/vgdynamictable/scss/_pagination.scss +183 -0
  24. package/app/modules/vgdynamictable/scss/_skeleton.scss +60 -0
  25. package/app/modules/vgdynamictable/scss/_sortable.scss +63 -0
  26. package/app/modules/vgdynamictable/scss/_table.scss +157 -0
  27. package/app/modules/vgdynamictable/scss/_variables.scss +130 -0
  28. package/app/modules/vgdynamictable/scss/vgdynamictable.scss +267 -0
  29. package/app/modules/vgrangeslider/index.js +3 -0
  30. package/app/modules/vgrangeslider/js/skins.js +222 -0
  31. package/app/modules/vgrangeslider/js/vgrangeslider.js +704 -0
  32. package/app/modules/vgrangeslider/readme.md +523 -0
  33. package/app/modules/vgrangeslider/scss/_variables.scss +53 -0
  34. package/app/modules/vgrangeslider/scss/vgrangeslider.scss +240 -0
  35. package/app/utils/js/components/ajax.js +116 -7
  36. package/app/vgapp.js +107 -0
  37. package/build/vgapp.css +2 -3246
  38. package/build/vgapp.css.map +1 -1
  39. package/build/vgapp.js +3 -30
  40. package/build/vgapp.js.LICENSE.txt +1 -0
  41. package/build/vgapp.js.map +1 -1
  42. package/index.js +15 -8
  43. package/index.scss +6 -0
  44. package/package.json +21 -1
  45. package/.gitattributes +0 -1
  46. package/CHANGELOG.md +0 -369
  47. package/agents.md +0 -14
  48. package/webpack.config.js +0 -63
@@ -0,0 +1,240 @@
1
+ /**
2
+ *--------------------------------------------------------------------------
3
+ * Module: VGRangeSlider
4
+ *--------------------------------------------------------------------------
5
+ **/
6
+
7
+ @import "../../../utils/scss/functions";
8
+ @import "../../../utils/scss/mixin";
9
+ @import "../../../utils/scss/variables";
10
+ @import "variables";
11
+
12
+ .vg-range-slider {
13
+ @include mix-vars('range-slider', $range-slider-map);
14
+
15
+ --vg-range-slider-ruler-height: calc(
16
+ var(--vg-range-slider-ruler-mark-height) +
17
+ var(--vg-range-slider-ruler-label-offset) +
18
+ (var(--vg-range-slider-ruler-label-font-size) * var(--vg-range-slider-ruler-label-line-height))
19
+ );
20
+ --vg-range-slider-ruler-offset-y: calc(var(--vg-range-slider-ruler-gap-y) * -1);
21
+ --vg-range-slider-wrapper-padding-bottom-ruler: calc(
22
+ var(--vg-range-slider-ruler-height) + var(--vg-range-slider-ruler-gap-y)
23
+ );
24
+
25
+ position: relative;
26
+ display: grid;
27
+ gap: var(--vg-range-slider-gap);
28
+ color: var(--vg-range-slider-text);
29
+
30
+ &.disabled {
31
+ opacity: .65;
32
+ }
33
+
34
+ &__wrapper {
35
+ position: relative;
36
+ min-height: var(--vg-range-slider-wrapper-min-height);
37
+ padding: var(--vg-range-slider-wrapper-padding-top) 0 var(--vg-range-slider-wrapper-padding-bottom);
38
+ }
39
+
40
+ &.is-skin-ruler {
41
+ .vg-range-slider__wrapper {
42
+ padding-bottom: var(--vg-range-slider-wrapper-padding-bottom-ruler);
43
+ }
44
+
45
+ .vg-range-slider__labels {
46
+ display: none;
47
+ }
48
+ }
49
+
50
+ &.is-ruler-dim-inactive {
51
+ .vg-range-slider__ruler-item {
52
+ opacity: var(--vg-range-slider-ruler-inactive-opacity);
53
+ }
54
+
55
+ .vg-range-slider__ruler-item.is-active {
56
+ opacity: var(--vg-range-slider-ruler-active-opacity);
57
+ }
58
+ }
59
+
60
+ &.is-skin-status {
61
+ &.is-status-success {
62
+ --vg-range-slider-fill: var(--vg-range-slider-status-success);
63
+ --vg-range-slider-thumb-border: var(--vg-range-slider-status-success);
64
+ --vg-range-slider-tooltip-bg: var(--vg-range-slider-status-success);
65
+ --vg-range-slider-tooltip-color: var(--vg-range-slider-status-success-contrast);
66
+ }
67
+
68
+ &.is-status-warning {
69
+ --vg-range-slider-fill: var(--vg-range-slider-status-warning);
70
+ --vg-range-slider-thumb-border: var(--vg-range-slider-status-warning);
71
+ --vg-range-slider-tooltip-bg: var(--vg-range-slider-status-warning);
72
+ --vg-range-slider-tooltip-color: var(--vg-range-slider-status-warning-contrast);
73
+ }
74
+
75
+ &.is-status-danger {
76
+ --vg-range-slider-fill: var(--vg-range-slider-status-danger);
77
+ --vg-range-slider-thumb-border: var(--vg-range-slider-status-danger);
78
+ --vg-range-slider-tooltip-bg: var(--vg-range-slider-status-danger);
79
+ --vg-range-slider-tooltip-color: var(--vg-range-slider-status-danger-contrast);
80
+ }
81
+ }
82
+
83
+ &__track,
84
+ &__fill {
85
+ position: absolute;
86
+ top: 50%;
87
+ transform: translateY(-50%);
88
+ height: var(--vg-range-slider-height);
89
+ border-radius: var(--vg-range-slider-radius);
90
+ }
91
+
92
+ &__track {
93
+ left: 0;
94
+ right: 0;
95
+ z-index: var(--vg-range-slider-z-track);
96
+ background: var(--vg-range-slider-bg);
97
+ }
98
+
99
+ &__fill {
100
+ left: 0;
101
+ width: 0;
102
+ z-index: var(--vg-range-slider-z-fill);
103
+ background: var(--vg-range-slider-fill);
104
+ }
105
+
106
+ &__input {
107
+ position: absolute;
108
+ top: 50%;
109
+ left: 0;
110
+ width: 100%;
111
+ height: var(--vg-range-slider-input-height);
112
+ transform: translateY(-50%);
113
+ margin: 0;
114
+ background: transparent;
115
+ pointer-events: none;
116
+ z-index: var(--vg-range-slider-z-input);
117
+ appearance: none;
118
+ -webkit-appearance: none;
119
+
120
+ &::-webkit-slider-runnable-track {
121
+ height: var(--vg-range-slider-height);
122
+ background: transparent;
123
+ }
124
+
125
+ &::-moz-range-track {
126
+ height: var(--vg-range-slider-height);
127
+ background: transparent;
128
+ }
129
+
130
+ &::-webkit-slider-thumb {
131
+ width: var(--vg-range-slider-thumb-size);
132
+ height: var(--vg-range-slider-thumb-size);
133
+ margin-top: calc((var(--vg-range-slider-height) - var(--vg-range-slider-thumb-size)) / 2);
134
+ border: var(--vg-range-slider-thumb-border-width) solid var(--vg-range-slider-thumb-border);
135
+ border-radius: 50%;
136
+ background: var(--vg-range-slider-thumb);
137
+ box-shadow: var(--vg-range-slider-thumb-shadow);
138
+ cursor: pointer;
139
+ pointer-events: auto;
140
+ appearance: none;
141
+ -webkit-appearance: none;
142
+ }
143
+
144
+ &::-moz-range-thumb {
145
+ width: var(--vg-range-slider-thumb-size);
146
+ height: var(--vg-range-slider-thumb-size);
147
+ border: var(--vg-range-slider-thumb-border-width) solid var(--vg-range-slider-thumb-border);
148
+ border-radius: 50%;
149
+ background: var(--vg-range-slider-thumb);
150
+ box-shadow: var(--vg-range-slider-thumb-shadow);
151
+ cursor: pointer;
152
+ pointer-events: auto;
153
+ }
154
+
155
+ &:focus {
156
+ outline: none;
157
+ }
158
+ }
159
+
160
+ &__tooltip {
161
+ position: absolute;
162
+ top: 0;
163
+ z-index: var(--vg-range-slider-z-tooltip);
164
+ transform: translate(-50%, -100%);
165
+ padding: var(--vg-range-slider-tooltip-padding-y) var(--vg-range-slider-tooltip-padding-x);
166
+ border-radius: var(--vg-range-slider-tooltip-radius);
167
+ background: var(--vg-range-slider-tooltip-bg);
168
+ box-shadow: var(--vg-range-slider-tooltip-shadow);
169
+ color: var(--vg-range-slider-tooltip-color);
170
+ font-size: var(--vg-range-slider-tooltip-font-size);
171
+ line-height: var(--vg-range-slider-tooltip-line-height);
172
+ white-space: nowrap;
173
+ pointer-events: none;
174
+
175
+ &.is-hidden {
176
+ opacity: 0;
177
+ visibility: hidden;
178
+ }
179
+ }
180
+
181
+ &__labels {
182
+ display: flex;
183
+ align-items: center;
184
+ gap: var(--vg-range-slider-labels-gap);
185
+ font-size: var(--vg-range-slider-labels-font-size);
186
+ line-height: var(--vg-range-slider-labels-line-height);
187
+ }
188
+
189
+ &__label {
190
+ font-weight: var(--vg-range-slider-label-font-weight);
191
+ }
192
+
193
+ &__separator {
194
+ color: var(--vg-range-slider-muted);
195
+ }
196
+
197
+ &__ruler {
198
+ position: absolute;
199
+ left: 0;
200
+ right: 0;
201
+ bottom: var(--vg-range-slider-ruler-offset-y);
202
+ z-index: var(--vg-range-slider-z-ruler);
203
+ height: var(--vg-range-slider-ruler-height);
204
+ pointer-events: none;
205
+ }
206
+
207
+ &__ruler-item {
208
+ position: absolute;
209
+ bottom: 0;
210
+ transform: translateX(-50%);
211
+ display: flex;
212
+ flex-direction: column;
213
+ align-items: center;
214
+ transition: opacity .2s ease;
215
+
216
+ &.is-active {
217
+ .vg-range-slider__ruler-mark {
218
+ background: var(--vg-range-slider-ruler-active-mark-bg);
219
+ }
220
+
221
+ .vg-range-slider__ruler-label {
222
+ color: var(--vg-range-slider-ruler-active-label-color);
223
+ }
224
+ }
225
+ }
226
+
227
+ &__ruler-mark {
228
+ width: var(--vg-range-slider-ruler-mark-width);
229
+ height: var(--vg-range-slider-ruler-mark-height);
230
+ background: var(--vg-range-slider-ruler-mark-bg);
231
+ }
232
+
233
+ &__ruler-label {
234
+ margin-top: var(--vg-range-slider-ruler-label-offset);
235
+ font-size: var(--vg-range-slider-ruler-label-font-size);
236
+ line-height: var(--vg-range-slider-ruler-label-line-height);
237
+ color: var(--vg-range-slider-ruler-label-color);
238
+ white-space: nowrap;
239
+ }
240
+ }
@@ -1,7 +1,117 @@
1
- import { mergeDeepObject, noop, normalizeData } from "../functions";
1
+ import { isObject, noop, normalizeData } from "../functions";
2
2
 
3
- class Ajax {
4
- /**
3
+ class Ajax {
4
+ static _toRouteQueryParamValue(value) {
5
+ if (!Array.isArray(value)) {
6
+ return value;
7
+ }
8
+
9
+ return value
10
+ .map((item) => String(item || '').trim())
11
+ .filter((item) => item !== '')
12
+ .join(',');
13
+ }
14
+
15
+ static buildRouteUrl(route, options = {}) {
16
+ const target = String(route || '').trim();
17
+ if (!target) {
18
+ throw new Error('Request endpoint is empty');
19
+ }
20
+
21
+ const baseParams = isObject(options.baseParams) ? options.baseParams : {};
22
+ const params = isObject(options.params) ? options.params : {};
23
+ const url = new URL(target, window.location.origin);
24
+ const merged = { ...baseParams, ...params };
25
+
26
+ Object.keys(merged).forEach((key) => {
27
+ const value = this._toRouteQueryParamValue(merged[key]);
28
+ if (value === undefined || value === null || value === '') {
29
+ return;
30
+ }
31
+
32
+ url.searchParams.set(key, String(value));
33
+ });
34
+
35
+ return url;
36
+ }
37
+
38
+ static async requestRoute(options = {}) {
39
+ const method = String(options.method || 'GET').toUpperCase().trim() || 'GET';
40
+ const headers = isObject(options.headers) ? { ...options.headers } : {};
41
+ const credentials = String(options.credentials || 'same-origin').trim() || 'same-origin';
42
+ const baseParams = isObject(options.baseParams) ? options.baseParams : {};
43
+ const params = isObject(options.params) ? options.params : {};
44
+ const hasBody = options.body !== undefined && options.body !== null;
45
+ const isGetLike = method === 'GET' || method === 'HEAD';
46
+ const route = String(options.route || options.endpoint || '').trim();
47
+ const url = this.buildRouteUrl(route, {
48
+ baseParams,
49
+ params: isGetLike ? params : {},
50
+ });
51
+ const requestOptions = {
52
+ method,
53
+ credentials,
54
+ headers,
55
+ signal: options.signal || undefined,
56
+ };
57
+
58
+ if (!isGetLike && hasBody) {
59
+ const body = options.body;
60
+ const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;
61
+
62
+ if (isFormData) {
63
+ delete requestOptions.headers['Content-Type'];
64
+ requestOptions.body = body;
65
+ } else if (typeof body === 'string') {
66
+ if (!requestOptions.headers['Content-Type']) {
67
+ requestOptions.headers['Content-Type'] = 'application/json';
68
+ }
69
+ requestOptions.body = body;
70
+ } else {
71
+ if (!requestOptions.headers['Content-Type']) {
72
+ requestOptions.headers['Content-Type'] = 'application/json';
73
+ }
74
+ requestOptions.body = JSON.stringify(body);
75
+ }
76
+ }
77
+
78
+ const response = await fetch(url.toString(), requestOptions);
79
+ const contentType = String(response.headers.get('content-type') || '').toLowerCase();
80
+ const expectsJson = options.responseType === 'json'
81
+ || (options.responseType !== 'text' && contentType.includes('application/json'));
82
+ const payload = await (async () => {
83
+ if (expectsJson) {
84
+ try {
85
+ return await response.json();
86
+ } catch (error) {
87
+ return await response.text();
88
+ }
89
+ }
90
+
91
+ return response.text();
92
+ })();
93
+
94
+ if (!response.ok) {
95
+ const apiError = payload && typeof payload === 'object' && payload.error && typeof payload.error === 'object'
96
+ ? payload.error
97
+ : {};
98
+ const fallbackMessage = typeof payload === 'string' && payload.trim()
99
+ ? payload
100
+ : response.statusText;
101
+ const message = String(apiError.message || fallbackMessage || 'Request failed');
102
+ const error = new Error(message);
103
+ error.status = response.status;
104
+ error.code = apiError.code || 'REQUEST_FAILED';
105
+ error.details = Array.isArray(apiError.details) ? apiError.details : [];
106
+ error.requestId = apiError.request_id || response.headers.get('X-Request-Id') || '';
107
+ error.response = payload;
108
+ throw error;
109
+ }
110
+
111
+ return payload;
112
+ }
113
+
114
+ /**
5
115
  * Конфигурация запроса
6
116
  * @param {Object} options
7
117
  * @param {string} options.baseUrl - Базовый URL API (опционально)
@@ -121,7 +231,7 @@ class Ajax {
121
231
  method,
122
232
  headers,
123
233
  signal,
124
- withCredentials,
234
+ credentials: withCredentials ? 'include' : 'same-origin',
125
235
  ...(body !== undefined && { body }),
126
236
  };
127
237
 
@@ -157,8 +267,7 @@ class Ajax {
157
267
  () => {}
158
268
  );
159
269
  } else {
160
- console.log(data)
161
- onSuccess(data);
270
+ onSuccess(data);
162
271
  }
163
272
  })
164
273
  .catch((error) => {
@@ -284,4 +393,4 @@ class Ajax {
284
393
  }
285
394
  }
286
395
 
287
- export default Ajax;
396
+ export default Ajax;
package/app/vgapp.js ADDED
@@ -0,0 +1,107 @@
1
+ import VGAlert from './modules/vgalert';
2
+ import VGCollapse from './modules/vgcollapse';
3
+ import VGDropdown from './modules/vgdropdown';
4
+ import { VGDynamicTable } from './modules/vgdynamictable';
5
+ import VGFiles from './modules/vgfiles';
6
+ import VGFilePreview from './modules/vgfilepreview';
7
+ import VGFormSender from './modules/vgformsender';
8
+ import VGLawCookie from './modules/vglawcookie';
9
+ import VGLoadMore from './modules/vgloadmore';
10
+ import VGModal from './modules/vgmodal';
11
+ import VGNav from './modules/vgnav';
12
+ import VGNestable from './modules/vgnestable';
13
+ import VGRangeSlider from './modules/vgrangeslider';
14
+ import VGRollup from './modules/vgrollup';
15
+ import VGSelect from './modules/vgselect';
16
+ import VGSidebar from './modules/vgsidebar';
17
+ import VGSpy from './modules/vgspy';
18
+ import VGTabs from './modules/vgtabs';
19
+ import VGToast from './modules/vgtoast';
20
+ import VGTooltip from './modules/vgtooltip';
21
+
22
+ class VGApp {
23
+ constructor() {
24
+ this._modules = new Map();
25
+ }
26
+
27
+ register(...entries) {
28
+ const modules = entries.flatMap((entry) => {
29
+ if (Array.isArray(entry)) {
30
+ return entry;
31
+ }
32
+
33
+ return entry ? [entry] : [];
34
+ });
35
+
36
+ for (const Module of modules) {
37
+ const name = String(Module?.NAME || '').trim();
38
+
39
+ if (!name) {
40
+ throw new Error('VGApp.register() ожидает модуль со статическим NAME.');
41
+ }
42
+
43
+ this._modules.set(name, Module);
44
+ }
45
+
46
+ return this;
47
+ }
48
+
49
+ boot(config = {}) {
50
+ for (const [name, Module] of this._modules) {
51
+ if (typeof Module?.boot !== 'function') {
52
+ continue;
53
+ }
54
+
55
+ const moduleConfig = this._resolveModuleConfig(name, config);
56
+ Module.boot(moduleConfig);
57
+ }
58
+
59
+ return this;
60
+ }
61
+
62
+ get(name) {
63
+ return this._modules.get(String(name).trim());
64
+ }
65
+
66
+ has(name) {
67
+ return this._modules.has(String(name).trim());
68
+ }
69
+
70
+ _resolveModuleConfig(name, config) {
71
+ if (!config || typeof config !== 'object') {
72
+ return undefined;
73
+ }
74
+
75
+ return Object.prototype.hasOwnProperty.call(config, name)
76
+ ? config[name]
77
+ : undefined;
78
+ }
79
+ }
80
+
81
+ const vgapp = new VGApp();
82
+
83
+ vgapp.register(
84
+ VGAlert,
85
+ VGCollapse,
86
+ VGDropdown,
87
+ VGDynamicTable,
88
+ VGFiles,
89
+ VGFilePreview,
90
+ VGFormSender,
91
+ VGLawCookie,
92
+ VGLoadMore,
93
+ VGModal,
94
+ VGNav,
95
+ VGNestable,
96
+ VGRangeSlider,
97
+ VGRollup,
98
+ VGSelect,
99
+ VGSidebar,
100
+ VGSpy,
101
+ VGTabs,
102
+ VGToast,
103
+ VGTooltip,
104
+ );
105
+
106
+ export { VGApp, vgapp };
107
+ export default vgapp;