@gravity-ui/dashkit 6.8.0 → 6.10.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 (29) hide show
  1. package/README.md +1 -1
  2. package/build/cjs/components/OverlayControls/OverlayControls.d.ts +5 -3
  3. package/build/cjs/shared/modules/__tests__/helpers.test.js +212 -2
  4. package/build/cjs/shared/modules/helpers.d.ts +14 -5
  5. package/build/cjs/shared/modules/helpers.js +89 -19
  6. package/build/cjs/shared/modules/state-and-params.d.ts +2 -2
  7. package/build/cjs/shared/modules/state-and-params.js +73 -42
  8. package/build/cjs/shared/modules/uniq-id.js +3 -0
  9. package/build/cjs/shared/types/config.d.ts +13 -0
  10. package/build/cjs/shared/types/state-and-params.d.ts +4 -2
  11. package/build/cjs/typings/plugin.d.ts +4 -4
  12. package/build/cjs/utils/__tests__/update-manager.test.js +193 -5
  13. package/build/cjs/utils/update-manager.d.ts +2 -2
  14. package/build/cjs/utils/update-manager.js +71 -4
  15. package/build/esm/components/OverlayControls/OverlayControls.d.ts +5 -3
  16. package/build/esm/components/OverlayControls/OverlayControls.js +2 -2
  17. package/build/esm/shared/modules/__tests__/helpers.test.js +213 -3
  18. package/build/esm/shared/modules/helpers.d.ts +14 -5
  19. package/build/esm/shared/modules/helpers.js +87 -19
  20. package/build/esm/shared/modules/state-and-params.d.ts +2 -2
  21. package/build/esm/shared/modules/state-and-params.js +74 -43
  22. package/build/esm/shared/modules/uniq-id.js +4 -1
  23. package/build/esm/shared/types/config.d.ts +13 -0
  24. package/build/esm/shared/types/state-and-params.d.ts +4 -2
  25. package/build/esm/typings/plugin.d.ts +4 -4
  26. package/build/esm/utils/__tests__/update-manager.test.js +193 -5
  27. package/build/esm/utils/update-manager.d.ts +2 -2
  28. package/build/esm/utils/update-manager.js +72 -5
  29. package/package.json +1 -1
@@ -5,21 +5,75 @@ const tslib_1 = require("tslib");
5
5
  const groupBy_1 = tslib_1.__importDefault(require("lodash/groupBy"));
6
6
  const constants_1 = require("../constants");
7
7
  const helpers_1 = require("./helpers");
8
+ function getItemParams({ item, itemsStateAndParams, mapItemsIgnores, itemsWithDefaultsByNamespace, getMergedParams, defaultGlobalParams, globalParams, isFirstVersion, queueData, }) {
9
+ var _a, _b;
10
+ const { id, namespace } = item;
11
+ let defaultWidgetParams = {};
12
+ if ((0, helpers_1.isItemWithTabs)(item)) {
13
+ const currentWidgetTabId = (0, helpers_1.resolveItemInnerId)({ item, itemsStateAndParams });
14
+ const itemTabs = item.data.tabs;
15
+ defaultWidgetParams =
16
+ ((_a = itemTabs.find((tabItem) => (tabItem === null || tabItem === void 0 ? void 0 : tabItem.id) === currentWidgetTabId)) === null || _a === void 0 ? void 0 : _a.params) || {};
17
+ }
18
+ else {
19
+ defaultWidgetParams = item.defaults || {};
20
+ }
21
+ const itemIgnores = mapItemsIgnores[id];
22
+ const affectingItemsWithDefaults = itemsWithDefaultsByNamespace[namespace].filter((itemWithDefaults) => !itemIgnores.includes(itemWithDefaults.id));
23
+ let itemParams = Object.assign({}, getMergedParams(defaultGlobalParams),
24
+ // default parameters to begin with
25
+ affectingItemsWithDefaults.reduceRight((defaultParams, itemWithDefaults) => {
26
+ return Object.assign(Object.assign({}, defaultParams), getMergedParams(itemWithDefaults.defaults || {}));
27
+ }, {}), getMergedParams(globalParams));
28
+ if (isFirstVersion) {
29
+ itemParams = Object.assign(itemParams, ((_b = itemsStateAndParams === null || itemsStateAndParams === void 0 ? void 0 : itemsStateAndParams[id]) === null || _b === void 0 ? void 0 : _b.params) || {});
30
+ }
31
+ else {
32
+ // params according to queue of its applying
33
+ let queueDataItemsParams = {};
34
+ for (const data of queueData) {
35
+ if (data.namespace !== namespace || itemIgnores.includes(data.id)) {
36
+ continue;
37
+ }
38
+ let actionParams;
39
+ let params = data.params;
40
+ const needAliasesForActionParams = data.id !== id && (0, helpers_1.hasActionParam)(data.params);
41
+ if (needAliasesForActionParams) {
42
+ actionParams = (0, helpers_1.pickActionParamsFromParams)(data.params);
43
+ params = (0, helpers_1.pickExceptActionParamsFromParams)(data.params);
44
+ }
45
+ const mergedParams = getMergedParams(params, actionParams);
46
+ queueDataItemsParams = Object.assign(Object.assign({}, queueDataItemsParams), mergedParams);
47
+ }
48
+ itemParams = Object.assign(itemParams, queueDataItemsParams);
49
+ }
50
+ return Object.assign(Object.assign({}, defaultWidgetParams), itemParams);
51
+ }
8
52
  function getItemsParams({ defaultGlobalParams = {}, globalParams = {}, config, itemsStateAndParams, plugins, }) {
9
53
  const { aliases, connections } = config;
10
54
  const items = (0, helpers_1.prerenderItems)({ items: config.items, plugins });
11
55
  const isFirstVersion = (0, helpers_1.getCurrentVersion)(itemsStateAndParams) === 1;
56
+ const allItems = items.reduce((paramsItems, item) => {
57
+ if ((0, helpers_1.isItemWithGroup)(item)) {
58
+ item.data.group.forEach((groupItem) => {
59
+ paramsItems.push(groupItem);
60
+ });
61
+ return paramsItems;
62
+ }
63
+ paramsItems.push(item);
64
+ return paramsItems;
65
+ }, []);
12
66
  const queueData = isFirstVersion
13
67
  ? []
14
68
  : (0, helpers_1.formQueueData)({ items, itemsStateAndParams });
15
69
  // to consider other kind types in future (not only ignore)
16
70
  const mapItemsIgnores = (0, helpers_1.getMapItemsIgnores)({
17
- items,
71
+ items: allItems,
18
72
  ignores: connections.filter(({ kind }) => kind === 'ignore'),
19
73
  itemsStateAndParams,
20
74
  isFirstVersion,
21
75
  });
22
- const groupByNamespace = (0, groupBy_1.default)(items, 'namespace');
76
+ const groupByNamespace = (0, groupBy_1.default)(allItems, 'namespace');
23
77
  const itemsWithDefaultsByNamespace = Object.keys(groupByNamespace).reduce((acc, namespace) => {
24
78
  return Object.assign(Object.assign({}, acc), {
25
79
  // there are defaults only in selectors by now, need to get them from item.data.tabs[].defaults for widgets
@@ -27,49 +81,26 @@ function getItemsParams({ defaultGlobalParams = {}, globalParams = {}, config, i
27
81
  [namespace]: groupByNamespace[namespace].filter((item) => item.defaults) });
28
82
  }, {});
29
83
  return items.reduce((itemsParams, item) => {
30
- var _a, _b;
31
84
  const { id, namespace } = item;
32
- let defaultWidgetParams = {};
33
- if ((0, helpers_1.isItemWithTabs)(item)) {
34
- const currentWidgetTabId = (0, helpers_1.resolveItemInnerId)({ item, itemsStateAndParams });
35
- const itemTabs = item.data.tabs;
36
- defaultWidgetParams =
37
- ((_a = itemTabs.find((tabItem) => (tabItem === null || tabItem === void 0 ? void 0 : tabItem.id) === currentWidgetTabId)) === null || _a === void 0 ? void 0 : _a.params) || {};
38
- }
39
- else {
40
- defaultWidgetParams = item.defaults || {};
41
- }
42
85
  const getMergedParams = (params, actionParams) => (0, helpers_1.mergeParamsWithAliases)({ aliases, namespace, params: params || {}, actionParams });
43
- const itemIgnores = mapItemsIgnores[id];
44
- const affectingItemsWithDefaults = itemsWithDefaultsByNamespace[namespace].filter((itemWithDefaults) => !itemIgnores.includes(itemWithDefaults.id));
45
- let itemParams = Object.assign({}, getMergedParams(defaultGlobalParams),
46
- // default parameters to begin with
47
- affectingItemsWithDefaults.reduceRight((defaultParams, itemWithDefaults) => {
48
- return Object.assign(Object.assign({}, defaultParams), getMergedParams(itemWithDefaults.defaults || {}));
49
- }, {}), getMergedParams(globalParams));
50
- if (isFirstVersion) {
51
- itemParams = Object.assign(itemParams, ((_b = itemsStateAndParams === null || itemsStateAndParams === void 0 ? void 0 : itemsStateAndParams[id]) === null || _b === void 0 ? void 0 : _b.params) || {});
52
- }
53
- else {
54
- // params according to queue of its applying
55
- let queueDataItemsParams = {};
56
- for (const data of Object.values(queueData)) {
57
- if (data.namespace !== namespace || itemIgnores.includes(data.id)) {
58
- continue;
59
- }
60
- let actionParams;
61
- let params = data.params;
62
- const needAliasesForActionParams = data.id !== id && (0, helpers_1.hasActionParam)(data.params);
63
- if (needAliasesForActionParams) {
64
- actionParams = (0, helpers_1.pickActionParamsFromParams)(data.params);
65
- params = (0, helpers_1.pickExceptActionParamsFromParams)(data.params);
66
- }
67
- const mergedParams = getMergedParams(params, actionParams);
68
- queueDataItemsParams = Object.assign(Object.assign({}, queueDataItemsParams), mergedParams);
69
- }
70
- itemParams = Object.assign(itemParams, queueDataItemsParams);
86
+ const paramsOptions = {
87
+ itemsStateAndParams,
88
+ mapItemsIgnores,
89
+ itemsWithDefaultsByNamespace,
90
+ getMergedParams,
91
+ defaultGlobalParams,
92
+ globalParams,
93
+ isFirstVersion,
94
+ queueData,
95
+ };
96
+ if ((0, helpers_1.isItemWithGroup)(item)) {
97
+ const groupParams = item.data.group.reduce((groupItemParams, groupItem) => {
98
+ groupItemParams[groupItem.id] = getItemParams(Object.assign({ item: groupItem }, paramsOptions));
99
+ return groupItemParams;
100
+ }, {});
101
+ return Object.assign(Object.assign({}, itemsParams), { [id]: groupParams });
71
102
  }
72
- return Object.assign(Object.assign({}, itemsParams), { [id]: Object.assign(Object.assign({}, defaultWidgetParams), itemParams) });
103
+ return Object.assign(Object.assign({}, itemsParams), { [id]: getItemParams(Object.assign({ item }, paramsOptions)) });
73
104
  }, {});
74
105
  }
75
106
  exports.getItemsParams = getItemsParams;
@@ -14,6 +14,9 @@ function extractIdsFromConfig(config) {
14
14
  if ((0, helpers_1.isItemWithTabs)(item)) {
15
15
  item.data.tabs.forEach((tabItem) => ids.push(tabItem.id));
16
16
  }
17
+ if ((0, helpers_1.isItemWithGroup)(item)) {
18
+ item.data.group.forEach((groupItem) => ids.push(groupItem.id));
19
+ }
17
20
  });
18
21
  connections.forEach(({ from, to }) => ids.push(from, to));
19
22
  layout.forEach(({ i }) => ids.push(i));
@@ -6,6 +6,12 @@ export interface ConfigLayout {
6
6
  x: number;
7
7
  y: number;
8
8
  }
9
+ export type ConfigItemGroup = {
10
+ id: string;
11
+ defaults?: StringParams;
12
+ namespace: string;
13
+ [key: string]: unknown;
14
+ };
9
15
  export interface ConfigItemData {
10
16
  _editActive?: boolean;
11
17
  tabs?: {
@@ -14,11 +20,15 @@ export interface ConfigItemData {
14
20
  params?: StringParams;
15
21
  [key: string]: unknown;
16
22
  }[];
23
+ group?: ConfigItemGroup[];
17
24
  [key: string]: unknown;
18
25
  }
19
26
  export interface ConfigItemDataWithTabs extends Omit<ConfigItemData, 'tabs'> {
20
27
  tabs: NonNullable<ConfigItemData['tabs']>;
21
28
  }
29
+ export interface ConfigItemDataWithGroup extends Omit<ConfigItemData, 'group'> {
30
+ group: NonNullable<ConfigItemData['group']>;
31
+ }
22
32
  export interface ConfigItem {
23
33
  id: string;
24
34
  data: ConfigItemData;
@@ -31,6 +41,9 @@ export interface ConfigItem {
31
41
  export interface ConfigItemWithTabs extends Omit<ConfigItem, 'data'> {
32
42
  data: ConfigItemDataWithTabs;
33
43
  }
44
+ export interface ConfigItemWithGroup extends Omit<ConfigItem, 'data'> {
45
+ data: ConfigItemDataWithGroup;
46
+ }
34
47
  export interface ConfigAliases {
35
48
  [namespace: string]: string[][];
36
49
  }
@@ -6,6 +6,7 @@ export interface ItemState {
6
6
  export interface QueueItem {
7
7
  id: string;
8
8
  tabId?: string;
9
+ groupItemId?: string;
9
10
  }
10
11
  export type StateAndParamsMetaData = {
11
12
  queue: QueueItem[];
@@ -15,11 +16,12 @@ export type StateAndParamsMeta = {
15
16
  [META_KEY]: StateAndParamsMetaData;
16
17
  };
17
18
  export type ItemStateAndParams = {
18
- params?: StringParams;
19
+ params?: StringParams | Record<string, StringParams>;
19
20
  state?: ItemState;
20
21
  };
21
22
  export type ItemStateAndParamsChangeOptions = {
22
- action: 'setParams' | 'removeItem';
23
+ action?: 'setParams' | 'removeItem';
24
+ groupItemIds?: string[];
23
25
  };
24
26
  export type ItemsStateAndParamsBase = Record<string, ItemStateAndParams>;
25
27
  export type ItemsStateAndParams = ItemsStateAndParamsBase | StateAndParamsMeta;
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  import { ContextProps, SettingsProps, WidgetLayout } from './common';
3
- import { StringParams, ConfigItem, ItemState, ItemStateAndParams, PluginBase, ItemStateAndParamsChangeOptions } from '../shared';
3
+ import { ConfigItem, ItemState, ItemStateAndParams, ItemStateAndParamsChangeOptions, PluginBase, StringParams } from '../shared';
4
4
  import type { ReactGridLayoutProps } from 'react-grid-layout';
5
- export interface PluginWidgetProps {
5
+ export interface PluginWidgetProps<T = StringParams> {
6
6
  id: string;
7
7
  editMode: boolean;
8
- params: StringParams;
8
+ params: T;
9
9
  state: ItemState;
10
10
  onStateAndParamsChange: (stateAndParams: ItemStateAndParams, options?: ItemStateAndParamsChangeOptions) => void;
11
11
  width: number;
@@ -33,7 +33,7 @@ export interface PluginDefaultLayout {
33
33
  minH?: number;
34
34
  maxH?: number;
35
35
  }
36
- export interface Plugin<P extends PluginWidgetProps = any> extends PluginBase {
36
+ export interface Plugin<P extends PluginWidgetProps<T> = any, T = StringParams> extends PluginBase {
37
37
  defaultLayout?: PluginDefaultLayout;
38
38
  renderer: (props: P, forwardedRef: React.RefObject<any>) => React.ReactNode;
39
39
  }
@@ -117,6 +117,61 @@ const config = {
117
117
  },
118
118
  namespace: 'default',
119
119
  },
120
+ {
121
+ id: 'qY',
122
+ data: {
123
+ group: [
124
+ {
125
+ id: '9YN',
126
+ title: 'Category',
127
+ width: '',
128
+ source: {
129
+ datasetId: 'rfvnhj345gugf',
130
+ fieldType: 'string',
131
+ elementType: 'select',
132
+ datasetFieldId: 'ab089',
133
+ datasetFieldType: 'DIMENSION',
134
+ },
135
+ defaults: {
136
+ ab089: '',
137
+ },
138
+ sourceType: 'dataset',
139
+ placementMode: 'auto',
140
+ namespace: 'default',
141
+ },
142
+ {
143
+ id: 'qav',
144
+ title: 'Селектор 1',
145
+ width: '',
146
+ source: {
147
+ fieldName: 'sds',
148
+ elementType: 'select',
149
+ acceptableValues: [
150
+ {
151
+ title: '2',
152
+ value: '2',
153
+ },
154
+ {
155
+ title: '34',
156
+ value: '34',
157
+ },
158
+ ],
159
+ },
160
+ defaults: {
161
+ sds: '',
162
+ },
163
+ sourceType: 'manual',
164
+ placementMode: 'auto',
165
+ namespace: 'default',
166
+ },
167
+ ],
168
+ autoHeight: true,
169
+ buttonApply: false,
170
+ buttonReset: false,
171
+ },
172
+ type: 'group_control',
173
+ namespace: 'default',
174
+ },
120
175
  ],
121
176
  layout: [
122
177
  { h: 4, i: 'al', w: 4, x: 8, y: 0 },
@@ -124,6 +179,7 @@ const config = {
124
179
  { h: 2, i: 'L5', w: 8, x: 0, y: 2 },
125
180
  { h: 2, i: 'C8', w: 8, x: 10, y: 30 },
126
181
  { h: 2, i: 'lko', w: 8, x: 0, y: 12 },
182
+ { h: 2, i: 'qY', w: 8, x: 0, y: 24 },
127
183
  ],
128
184
  aliases: {},
129
185
  connections: [],
@@ -133,7 +189,7 @@ beforeEach(() => {
133
189
  });
134
190
  describe('UpdateManager', () => {
135
191
  describe('changeStateAndParams', () => {
136
- it('control adds params to empty itemsStateAndParams', () => {
192
+ it('control adds params to empty itemsStateAndParams: common control', () => {
137
193
  expect(update_manager_1.UpdateManager.changeStateAndParams({
138
194
  id: 'L5',
139
195
  config,
@@ -152,6 +208,30 @@ describe('UpdateManager', () => {
152
208
  __meta__: { queue: [{ id: 'L5' }], version: 2 },
153
209
  });
154
210
  });
211
+ it('control adds params to empty itemsStateAndParams: group control', () => {
212
+ expect(update_manager_1.UpdateManager.changeStateAndParams({
213
+ id: 'qY',
214
+ config,
215
+ itemsStateAndParams: {},
216
+ stateAndParams: {
217
+ params: {
218
+ ab089: ['red'],
219
+ },
220
+ },
221
+ options: {
222
+ groupItemIds: ['9YN'],
223
+ },
224
+ })).toEqual({
225
+ qY: {
226
+ params: {
227
+ '9YN': {
228
+ ab089: ['red'],
229
+ },
230
+ },
231
+ },
232
+ __meta__: { queue: [{ id: 'qY', groupItemId: '9YN' }], version: 2 },
233
+ });
234
+ });
155
235
  it('state changes only do not push into the queue', () => {
156
236
  expect(update_manager_1.UpdateManager.changeStateAndParams({
157
237
  id: 'al',
@@ -162,7 +242,17 @@ describe('UpdateManager', () => {
162
242
  d079: ['Russia'],
163
243
  },
164
244
  },
165
- __meta__: { queue: [{ id: 'L5' }, { id: 'Unk' }], version: 2 },
245
+ qY: {
246
+ params: {
247
+ '9YN': {
248
+ ab089: ['red'],
249
+ },
250
+ },
251
+ },
252
+ __meta__: {
253
+ queue: [{ id: 'L5' }, { id: 'qY', groupItemId: '9YN' }, { id: 'Unk' }],
254
+ version: 2,
255
+ },
166
256
  },
167
257
  stateAndParams: {
168
258
  state: { tabId: 'Pf' },
@@ -173,12 +263,19 @@ describe('UpdateManager', () => {
173
263
  d079: ['Russia'],
174
264
  },
175
265
  },
266
+ qY: {
267
+ params: {
268
+ '9YN': {
269
+ ab089: ['red'],
270
+ },
271
+ },
272
+ },
176
273
  al: {
177
274
  state: {
178
275
  tabId: 'Pf',
179
276
  },
180
277
  },
181
- __meta__: { queue: [{ id: 'L5' }], version: 2 },
278
+ __meta__: { queue: [{ id: 'L5' }, { id: 'qY', groupItemId: '9YN' }], version: 2 },
182
279
  });
183
280
  });
184
281
  it('tab changes clear previous tab params', () => {
@@ -208,7 +305,7 @@ describe('UpdateManager', () => {
208
305
  __meta__: { queue: [], version: 2 },
209
306
  });
210
307
  });
211
- it('control changes rearrange position in the queue', () => {
308
+ it('control changes rearrange position in the queue: common control', () => {
212
309
  expect(update_manager_1.UpdateManager.changeStateAndParams({
213
310
  id: 'L5',
214
311
  config,
@@ -266,6 +363,74 @@ describe('UpdateManager', () => {
266
363
  },
267
364
  });
268
365
  });
366
+ it('control changes rearrange position in the queue: group control', () => {
367
+ expect(update_manager_1.UpdateManager.changeStateAndParams({
368
+ id: 'qY',
369
+ config,
370
+ itemsStateAndParams: {
371
+ al: {
372
+ params: {
373
+ Country: 'USA',
374
+ },
375
+ },
376
+ qY: {
377
+ params: {
378
+ qav: {
379
+ sds: ['yellow'],
380
+ },
381
+ '9YN': {
382
+ ab089: ['red'],
383
+ },
384
+ },
385
+ },
386
+ __meta__: {
387
+ queue: [
388
+ { id: 'qY', groupItemId: 'qav' },
389
+ { id: 'qY', groupItemId: '9YN' },
390
+ { id: 'al' },
391
+ ],
392
+ version: 2,
393
+ },
394
+ },
395
+ stateAndParams: {
396
+ params: {
397
+ qav: {
398
+ sds: ['violet'],
399
+ },
400
+ '9YN': {
401
+ ab089: ['purple'],
402
+ },
403
+ },
404
+ },
405
+ options: {
406
+ groupItemIds: ['qav'],
407
+ },
408
+ })).toEqual({
409
+ al: {
410
+ params: {
411
+ Country: 'USA',
412
+ },
413
+ },
414
+ qY: {
415
+ params: {
416
+ qav: {
417
+ sds: ['violet'],
418
+ },
419
+ '9YN': {
420
+ ab089: ['red'],
421
+ },
422
+ },
423
+ },
424
+ __meta__: {
425
+ queue: [
426
+ { id: 'qY', groupItemId: '9YN' },
427
+ { id: 'al' },
428
+ { id: 'qY', groupItemId: 'qav' },
429
+ ],
430
+ version: 2,
431
+ },
432
+ });
433
+ });
269
434
  it('control params should merge', () => {
270
435
  expect(update_manager_1.UpdateManager.changeStateAndParams({
271
436
  id: 'lko',
@@ -309,7 +474,7 @@ describe('UpdateManager', () => {
309
474
  __meta__: { queue: [{ id: 'L5' }, { id: 'lko' }], version: 2 },
310
475
  });
311
476
  });
312
- it('control cannot set params not from defaults', () => {
477
+ it('control cannot set params not from defaults: common control', () => {
313
478
  expect(update_manager_1.UpdateManager.changeStateAndParams({
314
479
  id: 'lko',
315
480
  config,
@@ -329,6 +494,29 @@ describe('UpdateManager', () => {
329
494
  __meta__: { queue: [{ id: 'lko' }], version: 2 },
330
495
  });
331
496
  });
497
+ it('control cannot set params not from defaults: group control', () => {
498
+ expect(update_manager_1.UpdateManager.changeStateAndParams({
499
+ id: 'qY',
500
+ config,
501
+ itemsStateAndParams: {},
502
+ stateAndParams: {
503
+ params: {
504
+ sds: ['value'],
505
+ UnknownParam: ['Value'],
506
+ },
507
+ },
508
+ options: { groupItemIds: ['qav'] },
509
+ })).toEqual({
510
+ qY: {
511
+ params: {
512
+ qav: {
513
+ sds: ['value'],
514
+ },
515
+ },
516
+ },
517
+ __meta__: { queue: [{ id: 'qY', groupItemId: 'qav' }], version: 2 },
518
+ });
519
+ });
332
520
  it('filtering_charts_table can set action params not from defaults', () => {
333
521
  expect(update_manager_1.UpdateManager.changeStateAndParams({
334
522
  id: 'Q8',
@@ -1,5 +1,5 @@
1
- import { Config, ConfigItem, ItemsStateAndParams, ItemStateAndParams, ItemStateAndParamsChangeOptions } from '../shared';
2
- import { AddConfigItem, WidgetLayout, SetItemOptions } from '../typings';
1
+ import { Config, ConfigItem, ItemStateAndParams, ItemStateAndParamsChangeOptions, ItemsStateAndParams } from '../shared';
2
+ import { AddConfigItem, SetItemOptions, WidgetLayout } from '../typings';
3
3
  import { RegisterManagerPluginLayout } from './register-manager';
4
4
  interface RemoveItemArg {
5
5
  id: string;
@@ -88,7 +88,12 @@ function getAllowableChangedParams(item, stateAndParams, itemsStateAndParams, pa
88
88
  allowedParams = (0, pick_1.default)(stateParamsConf, Object.keys((tab === null || tab === void 0 ? void 0 : tab.params) || {}));
89
89
  }
90
90
  else {
91
- allowedParams = (0, pick_1.default)(stateParamsConf, Object.keys(item.defaults || {}));
91
+ // check if structure is StringParams or Record<string, StringParams>
92
+ const paramsConf = typeof (stateParamsConf === null || stateParamsConf === void 0 ? void 0 : stateParamsConf[item.id]) === 'object' &&
93
+ !Array.isArray(stateParamsConf === null || stateParamsConf === void 0 ? void 0 : stateParamsConf[item.id])
94
+ ? stateParamsConf[item.id]
95
+ : stateParamsConf;
96
+ allowedParams = (0, pick_1.default)(paramsConf, Object.keys(item.defaults || {}));
92
97
  }
93
98
  if (Object.keys(allowedParams || {}).length !== Object.keys(stateParamsConf || {}).length) {
94
99
  console.warn('Параметры, которых нет в defaults, будут проигнорированы!');
@@ -159,8 +164,54 @@ function getNewItemData({ item, config, counter: argsCounter, salt, options }) {
159
164
  });
160
165
  data = Object.assign(Object.assign({}, item.data), { tabs });
161
166
  }
167
+ if ((0, shared_1.isItemWithGroup)(item)) {
168
+ const group = item.data.group.map((groupItem) => {
169
+ if (groupItem.id) {
170
+ return groupItem;
171
+ }
172
+ const newIdGroupData = (0, get_new_id_1.getNewId)({ config, salt, counter, excludeIds });
173
+ counter = newIdGroupData.counter;
174
+ excludeIds.push(newIdGroupData.id);
175
+ return Object.assign(Object.assign({}, groupItem), { id: newIdGroupData.id, namespace: groupItem.namespace || constants_1.DEFAULT_NAMESPACE });
176
+ });
177
+ data = Object.assign(Object.assign({}, item.data), { group });
178
+ }
162
179
  return { data, counter, excludeIds };
163
180
  }
181
+ function changeGroupParams({ groupItemIds, initiatorId, initiatorItem, itemsStateAndParams, stateAndParams, config, unusedIds, }) {
182
+ var _a;
183
+ const meta = (0, shared_1.addGroupToQueue)({
184
+ id: initiatorId,
185
+ groupItemIds,
186
+ config,
187
+ itemsStateAndParams,
188
+ });
189
+ const updatedItems = {};
190
+ const currentItemParams = (_a = itemsStateAndParams[initiatorId]) === null || _a === void 0 ? void 0 : _a.params;
191
+ for (const groupItem of initiatorItem.data.group) {
192
+ if (groupItemIds.includes(groupItem.id)) {
193
+ const allowableParams = getAllowableChangedParams(groupItem, stateAndParams, itemsStateAndParams);
194
+ const allowableActionParams = getAllowableChangedParams(groupItem, stateAndParams, itemsStateAndParams, { type: 'actionParams', returnPrefix: true });
195
+ updatedItems[groupItem.id] = Object.assign(Object.assign({}, allowableParams), allowableActionParams);
196
+ continue;
197
+ }
198
+ if (currentItemParams && currentItemParams[groupItem.id]) {
199
+ updatedItems[groupItem.id] = currentItemParams[groupItem.id];
200
+ }
201
+ }
202
+ const obj = {
203
+ $unset: unusedIds,
204
+ [initiatorId]: {
205
+ $auto: {
206
+ params: {
207
+ $set: updatedItems,
208
+ },
209
+ },
210
+ },
211
+ [shared_1.META_KEY]: { $set: meta },
212
+ };
213
+ return (0, immutability_helper_1.default)(itemsStateAndParams, obj);
214
+ }
164
215
  class UpdateManager {
165
216
  static addItem({ item, namespace = constants_1.DEFAULT_NAMESPACE, layout, config, options, }) {
166
217
  const layoutY = Math.max(0, ...config.layout.map(({ h, y }) => h + y));
@@ -197,9 +248,13 @@ class UpdateManager {
197
248
  }
198
249
  const itemIndex = config.items.findIndex((item) => item.id === id);
199
250
  const item = config.items[itemIndex];
200
- const itemIds = (0, shared_1.isItemWithTabs)(item)
201
- ? [id].concat(item.data.tabs.map((tab) => tab.id))
202
- : [id];
251
+ let itemIds = [id];
252
+ if ((0, shared_1.isItemWithTabs)(item)) {
253
+ itemIds = [id].concat(item.data.tabs.map((tab) => tab.id));
254
+ }
255
+ if ((0, shared_1.isItemWithGroup)(item)) {
256
+ itemIds = [id].concat(item.data.group.map((groupItem) => groupItem.id));
257
+ }
203
258
  const connections = config.connections.filter(({ from, to }) => !itemIds.includes(from) && !itemIds.includes(to));
204
259
  return {
205
260
  config: (0, immutability_helper_1.default)(config, {
@@ -252,6 +307,7 @@ class UpdateManager {
252
307
  const newTabId = (_a = stateAndParams.state) === null || _a === void 0 ? void 0 : _a.tabId;
253
308
  const isTabSwitched = (0, shared_1.isItemWithTabs)(initiatorItem) && Boolean(newTabId);
254
309
  const currentMeta = (0, shared_1.getItemsStateAndParamsMeta)(itemsStateAndParams);
310
+ const groupItemIds = options === null || options === void 0 ? void 0 : options.groupItemIds;
255
311
  if (action === 'removeItem') {
256
312
  return (0, immutability_helper_1.default)(itemsStateAndParams, {
257
313
  $unset: [...unusedIds, initiatorId],
@@ -266,6 +322,17 @@ class UpdateManager {
266
322
  },
267
323
  });
268
324
  }
325
+ if ((0, shared_1.isItemWithGroup)(initiatorItem) && groupItemIds) {
326
+ return changeGroupParams({
327
+ initiatorId,
328
+ initiatorItem,
329
+ groupItemIds,
330
+ itemsStateAndParams,
331
+ stateAndParams,
332
+ config,
333
+ unusedIds,
334
+ });
335
+ }
269
336
  if ('params' in stateAndParams) {
270
337
  const allowableParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams);
271
338
  const allowableActionParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams, { type: 'actionParams', returnPrefix: true });
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { ButtonView, ButtonSize, IconProps, MenuItemProps } from '@gravity-ui/uikit';
3
- import { ConfigItem, PluginBase, StringParams, Config, ItemState } from '../../shared';
2
+ import { ButtonSize, ButtonView, IconProps, MenuItemProps } from '@gravity-ui/uikit';
3
+ import { Config, ConfigItem, ItemState, PluginBase, StringParams } from '../../shared';
4
4
  import type { RegisterManager } from '../../utils/register-manager';
5
5
  import './OverlayControls.css';
6
6
  export declare enum OverlayControlsPosition {
@@ -46,7 +46,9 @@ type PreparedCopyItemOptionsArg = Pick<ConfigItem, 'data' | 'type' | 'defaults'
46
46
  h: number;
47
47
  };
48
48
  };
49
- export type PreparedCopyItemOptions = PreparedCopyItemOptionsArg;
49
+ export type PreparedCopyItemOptions<C extends object = {}> = PreparedCopyItemOptionsArg & {
50
+ copyContext?: C;
51
+ };
50
52
  type DashKitCtx = React.Context<{
51
53
  context: Record<string, any>;
52
54
  registerManager: RegisterManager;
@@ -2,8 +2,8 @@ import React from 'react';
2
2
  import i18n from '../../i18n';
3
3
  import noop from 'lodash/noop';
4
4
  import { DashKitContext } from '../../context/DashKitContext';
5
- import { Icon, DropdownMenu, Button, } from '@gravity-ui/uikit';
6
- import { COPIED_WIDGET_STORE_KEY, OVERLAY_CONTROLS_CLASS_NAME, MenuItems } from '../../constants';
5
+ import { Button, DropdownMenu, Icon, } from '@gravity-ui/uikit';
6
+ import { COPIED_WIDGET_STORE_KEY, MenuItems, OVERLAY_CONTROLS_CLASS_NAME } from '../../constants';
7
7
  import { DotsIcon } from '../../icons/DotsIcon';
8
8
  import { CogIcon } from '../../icons/CogIcon';
9
9
  import { CloseIcon } from '../../icons/CloseIcon';