@gravity-ui/dashkit 7.0.0 → 7.1.1

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.
@@ -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,8 +1,8 @@
1
- import type { ReactGridLayoutProps } from 'react-grid-layout';
1
+ import type ReactGridLayout from 'react-grid-layout';
2
2
  import { OverlayCustomControlItem } from '../components/OverlayControls/OverlayControls';
3
3
  import { MenuItems } from '../constants';
4
4
  export interface Settings {
5
- gridLayout?: ReactGridLayoutProps;
5
+ gridLayout?: ReactGridLayout.ReactGridLayoutProps;
6
6
  theme?: string;
7
7
  isMobile?: boolean;
8
8
  menu?: Array<MenuItem>;
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import type { ReactGridLayoutProps } from 'react-grid-layout';
2
+ import ReactGridLayout from 'react-grid-layout';
3
3
  import { ConfigItem, ItemState, ItemStateAndParams, ItemStateAndParamsChangeOptions, PluginBase, StringParams } from '../shared';
4
4
  import { ContextProps, SettingsProps, WidgetLayout } from './common';
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;
@@ -16,7 +16,7 @@ export interface PluginWidgetProps {
16
16
  settings: SettingsProps;
17
17
  context: ContextProps;
18
18
  layout: WidgetLayout[];
19
- gridLayout: ReactGridLayoutProps;
19
+ gridLayout: ReactGridLayout.ReactGridLayoutProps;
20
20
  adjustWidgetLayout: (data: {
21
21
  widgetId: string;
22
22
  needSetDefault?: boolean;
@@ -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,4 +1,4 @@
1
- import type { ReactGridLayoutProps } from 'react-grid-layout';
1
+ import ReactGridLayout from 'react-grid-layout';
2
2
  import { Plugin, PluginDefaultLayout, Settings } from '../typings';
3
3
  interface RegisterManagerDefaultLayout {
4
4
  x: number;
@@ -23,7 +23,7 @@ export declare class RegisterManager {
23
23
  registerPlugin(plugin: Plugin): void;
24
24
  setSettings(settings?: Settings): void;
25
25
  get settings(): RegisterManagerSettings;
26
- get gridLayout(): ReactGridLayoutProps;
26
+ get gridLayout(): ReactGridLayout.ReactGridLayoutProps;
27
27
  getPlugins(): RegisterManagerPlugin[];
28
28
  getItem(type: string): RegisterManagerPlugin;
29
29
  check(type: string): boolean;
@@ -90,7 +90,12 @@ function getAllowableChangedParams(item, stateAndParams, itemsStateAndParams, pa
90
90
  allowedParams = (0, pick_1.default)(stateParamsConf, Object.keys((tab === null || tab === void 0 ? void 0 : tab.params) || {}));
91
91
  }
92
92
  else {
93
- allowedParams = (0, pick_1.default)(stateParamsConf, Object.keys(item.defaults || {}));
93
+ // check if structure is StringParams or Record<string, StringParams>
94
+ const paramsConf = typeof (stateParamsConf === null || stateParamsConf === void 0 ? void 0 : stateParamsConf[item.id]) === 'object' &&
95
+ !Array.isArray(stateParamsConf === null || stateParamsConf === void 0 ? void 0 : stateParamsConf[item.id])
96
+ ? stateParamsConf[item.id]
97
+ : stateParamsConf;
98
+ allowedParams = (0, pick_1.default)(paramsConf, Object.keys(item.defaults || {}));
94
99
  }
95
100
  if (Object.keys(allowedParams || {}).length !== Object.keys(stateParamsConf || {}).length) {
96
101
  console.warn('Параметры, которых нет в defaults, будут проигнорированы!');
@@ -161,8 +166,54 @@ function getNewItemData({ item, config, counter: argsCounter, salt, options }) {
161
166
  });
162
167
  data = Object.assign(Object.assign({}, item.data), { tabs });
163
168
  }
169
+ if ((0, shared_1.isItemWithGroup)(item)) {
170
+ const group = item.data.group.map((groupItem) => {
171
+ if (groupItem.id) {
172
+ return groupItem;
173
+ }
174
+ const newIdGroupData = (0, get_new_id_1.getNewId)({ config, salt, counter, excludeIds });
175
+ counter = newIdGroupData.counter;
176
+ excludeIds.push(newIdGroupData.id);
177
+ return Object.assign(Object.assign({}, groupItem), { id: newIdGroupData.id, namespace: groupItem.namespace || constants_1.DEFAULT_NAMESPACE });
178
+ });
179
+ data = Object.assign(Object.assign({}, item.data), { group });
180
+ }
164
181
  return { data, counter, excludeIds };
165
182
  }
183
+ function changeGroupParams({ groupItemIds, initiatorId, initiatorItem, itemsStateAndParams, stateAndParams, config, unusedIds, }) {
184
+ var _a;
185
+ const meta = (0, shared_1.addGroupToQueue)({
186
+ id: initiatorId,
187
+ groupItemIds,
188
+ config,
189
+ itemsStateAndParams,
190
+ });
191
+ const updatedItems = {};
192
+ const currentItemParams = (_a = itemsStateAndParams[initiatorId]) === null || _a === void 0 ? void 0 : _a.params;
193
+ for (const groupItem of initiatorItem.data.group) {
194
+ if (groupItemIds.includes(groupItem.id)) {
195
+ const allowableParams = getAllowableChangedParams(groupItem, stateAndParams, itemsStateAndParams);
196
+ const allowableActionParams = getAllowableChangedParams(groupItem, stateAndParams, itemsStateAndParams, { type: 'actionParams', returnPrefix: true });
197
+ updatedItems[groupItem.id] = Object.assign(Object.assign({}, allowableParams), allowableActionParams);
198
+ continue;
199
+ }
200
+ if (currentItemParams && currentItemParams[groupItem.id]) {
201
+ updatedItems[groupItem.id] = currentItemParams[groupItem.id];
202
+ }
203
+ }
204
+ const obj = {
205
+ $unset: unusedIds,
206
+ [initiatorId]: {
207
+ $auto: {
208
+ params: {
209
+ $set: updatedItems,
210
+ },
211
+ },
212
+ },
213
+ [shared_1.META_KEY]: { $set: meta },
214
+ };
215
+ return (0, immutability_helper_1.default)(itemsStateAndParams, obj);
216
+ }
166
217
  class UpdateManager {
167
218
  static addItem({ item, namespace = constants_1.DEFAULT_NAMESPACE, layout, config, options, }) {
168
219
  const layoutY = Math.max(0, ...config.layout.map(({ h, y }) => h + y));
@@ -199,9 +250,13 @@ class UpdateManager {
199
250
  }
200
251
  const itemIndex = config.items.findIndex((item) => item.id === id);
201
252
  const item = config.items[itemIndex];
202
- const itemIds = (0, shared_1.isItemWithTabs)(item)
203
- ? [id].concat(item.data.tabs.map((tab) => tab.id))
204
- : [id];
253
+ let itemIds = [id];
254
+ if ((0, shared_1.isItemWithTabs)(item)) {
255
+ itemIds = [id].concat(item.data.tabs.map((tab) => tab.id));
256
+ }
257
+ if ((0, shared_1.isItemWithGroup)(item)) {
258
+ itemIds = [id].concat(item.data.group.map((groupItem) => groupItem.id));
259
+ }
205
260
  const connections = config.connections.filter(({ from, to }) => !itemIds.includes(from) && !itemIds.includes(to));
206
261
  return {
207
262
  config: (0, immutability_helper_1.default)(config, {
@@ -254,6 +309,7 @@ class UpdateManager {
254
309
  const newTabId = (_a = stateAndParams.state) === null || _a === void 0 ? void 0 : _a.tabId;
255
310
  const isTabSwitched = (0, shared_1.isItemWithTabs)(initiatorItem) && Boolean(newTabId);
256
311
  const currentMeta = (0, shared_1.getItemsStateAndParamsMeta)(itemsStateAndParams);
312
+ const groupItemIds = options === null || options === void 0 ? void 0 : options.groupItemIds;
257
313
  if (action === 'removeItem') {
258
314
  return (0, immutability_helper_1.default)(itemsStateAndParams, {
259
315
  $unset: [...unusedIds, initiatorId],
@@ -268,6 +324,17 @@ class UpdateManager {
268
324
  },
269
325
  });
270
326
  }
327
+ if ((0, shared_1.isItemWithGroup)(initiatorItem) && groupItemIds) {
328
+ return changeGroupParams({
329
+ initiatorId,
330
+ initiatorItem,
331
+ groupItemIds,
332
+ itemsStateAndParams,
333
+ stateAndParams,
334
+ config,
335
+ unusedIds,
336
+ });
337
+ }
271
338
  if ('params' in stateAndParams) {
272
339
  const allowableParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams);
273
340
  const allowableActionParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams, { type: 'actionParams', returnPrefix: true });