@gravity-ui/dashkit 8.2.0 → 8.3.0-beta.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 (35) hide show
  1. package/build/cjs/components/DashKit/DashKit.d.ts +3 -1
  2. package/build/cjs/components/DashKit/DashKit.js +1 -5
  3. package/build/cjs/components/GridLayout/GridLayout.d.ts +6 -3
  4. package/build/cjs/components/GridLayout/GridLayout.js +100 -13
  5. package/build/cjs/components/GridLayout/ReactGridLayout.js +17 -2
  6. package/build/cjs/constants/common.d.ts +1 -0
  7. package/build/cjs/constants/common.js +2 -1
  8. package/build/cjs/hocs/withContext.js +13 -9
  9. package/build/cjs/hooks/useCalcLayout.d.ts +1 -0
  10. package/build/cjs/shared/modules/state-and-params.d.ts +2 -1
  11. package/build/cjs/shared/modules/state-and-params.js +18 -4
  12. package/build/cjs/shared/types/config.d.ts +4 -1
  13. package/build/cjs/typings/common.d.ts +2 -1
  14. package/build/cjs/typings/config.d.ts +12 -1
  15. package/build/cjs/typings/plugin.d.ts +1 -10
  16. package/build/cjs/utils/update-manager.d.ts +8 -1
  17. package/build/cjs/utils/update-manager.js +30 -15
  18. package/build/esm/components/DashKit/DashKit.d.ts +3 -1
  19. package/build/esm/components/DashKit/DashKit.js +1 -5
  20. package/build/esm/components/GridLayout/GridLayout.d.ts +6 -3
  21. package/build/esm/components/GridLayout/GridLayout.js +101 -14
  22. package/build/esm/components/GridLayout/ReactGridLayout.js +17 -2
  23. package/build/esm/constants/common.d.ts +1 -0
  24. package/build/esm/constants/common.js +1 -0
  25. package/build/esm/hocs/withContext.js +13 -9
  26. package/build/esm/hooks/useCalcLayout.d.ts +1 -0
  27. package/build/esm/shared/modules/state-and-params.d.ts +2 -1
  28. package/build/esm/shared/modules/state-and-params.js +18 -4
  29. package/build/esm/shared/types/config.d.ts +4 -1
  30. package/build/esm/typings/common.d.ts +2 -1
  31. package/build/esm/typings/config.d.ts +12 -1
  32. package/build/esm/typings/plugin.d.ts +1 -10
  33. package/build/esm/utils/update-manager.d.ts +8 -1
  34. package/build/esm/utils/update-manager.js +28 -14
  35. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { Config, ConfigItem, GlobalParams, ItemDropProps, ItemsStateAndParams } from '../../shared';
3
- import { ContextProps, Plugin, SetConfigItem, SetNewItemOptions, Settings, SettingsProps } from '../../typings';
3
+ import { ContextProps, DashKiGroup, Plugin, SetConfigItem, SetNewItemOptions, Settings, SettingsProps } from '../../typings';
4
4
  import GridLayout from '../GridLayout/GridLayout';
5
5
  import { OverlayControlItem } from '../OverlayControls/OverlayControls';
6
6
  interface DashKitGeneralProps {
@@ -14,6 +14,7 @@ interface DashKitDefaultProps {
14
14
  onChange: (data: {
15
15
  config: Config;
16
16
  itemsStateAndParams: ItemsStateAndParams;
17
+ groups?: DashKiGroup[];
17
18
  }) => void;
18
19
  onDrop: (dropProps: ItemDropProps) => void;
19
20
  defaultGlobalParams: GlobalParams;
@@ -23,6 +24,7 @@ interface DashKitDefaultProps {
23
24
  context: ContextProps;
24
25
  noOverlay: boolean;
25
26
  focusable?: boolean;
27
+ groups?: DashKiGroup[];
26
28
  }
27
29
  export interface DashKitProps extends DashKitGeneralProps, Partial<DashKitDefaultProps> {
28
30
  }
@@ -44,11 +44,7 @@ class DashKit extends react_1.default.PureComponent {
44
44
  return utils_1.UpdateManager.removeItem({ id, config, itemsStateAndParams });
45
45
  }
46
46
  render() {
47
- return (react_1.default.createElement(DashKitView_1.default
48
- // @ts-ignore
49
- , Object.assign({
50
- // @ts-ignore
51
- registerManager: registerManager, ref: this.metaRef }, this.props)));
47
+ return react_1.default.createElement(DashKitView_1.default, Object.assign({ registerManager: registerManager, ref: this.metaRef }, this.props));
52
48
  }
53
49
  getItemsMeta() {
54
50
  var _a;
@@ -18,12 +18,15 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
18
18
  adjustedWidgetLayout: any;
19
19
  }) => void;
20
20
  getItemsMeta: () => any;
21
+ getActiveLayout(): any;
22
+ mergeGroupsLayout(group: any, newLayout: any, temporaryItem: any): any;
21
23
  reloadItems(): void;
22
24
  _onStart: () => void;
23
- _onStop: (newLayout: any) => void;
25
+ _onStop: (group: any, newLayout: any) => void;
24
26
  _onDropDragOver: (e: any) => any;
25
- _onDrop: (layout: any, item: any, e: any) => false | undefined;
27
+ _onDrop: (group: any, newLayout: any, item: any, e: any) => false | undefined;
26
28
  renderTemporaryPlaceholder(): JSX.Element | null;
27
- render(): JSX.Element;
29
+ renderGroup(group: any, renderLayout: any, renderItems: any, offset?: number): JSX.Element;
30
+ render(): any;
28
31
  }
29
32
  import React from 'react';
@@ -35,13 +35,14 @@ class GridLayout extends react_1.default.PureComponent {
35
35
  return;
36
36
  this.setState({ isDragging: true });
37
37
  };
38
- this._onStop = (newLayout) => {
38
+ this._onStop = (group, newLayout) => {
39
39
  const { layoutChange, onDrop, temporaryLayout } = this.context;
40
+ const groupedLayout = this.mergeGroupsLayout(group, newLayout);
40
41
  if (temporaryLayout) {
41
- onDrop === null || onDrop === void 0 ? void 0 : onDrop(newLayout, newLayout.find(({ i }) => i === constants_1.TEMPORARY_ITEM_ID));
42
+ onDrop === null || onDrop === void 0 ? void 0 : onDrop(groupedLayout, groupedLayout.find(({ i }) => i === constants_1.TEMPORARY_ITEM_ID));
42
43
  }
43
44
  else {
44
- layoutChange(newLayout);
45
+ layoutChange(groupedLayout);
45
46
  }
46
47
  this.setState({ isDragging: false });
47
48
  };
@@ -52,7 +53,7 @@ class GridLayout extends react_1.default.PureComponent {
52
53
  }
53
54
  return onDropDragOver(e);
54
55
  };
55
- this._onDrop = (layout, item, e) => {
56
+ this._onDrop = (group, newLayout, item, e) => {
56
57
  if (!item) {
57
58
  return false;
58
59
  }
@@ -60,7 +61,11 @@ class GridLayout extends react_1.default.PureComponent {
60
61
  if (!editMode) {
61
62
  return false;
62
63
  }
63
- onDrop === null || onDrop === void 0 ? void 0 : onDrop(layout, item, e);
64
+ if (group !== constants_1.DEFAULT_GROUP) {
65
+ item.parent = group;
66
+ }
67
+ const groupedLayout = this.mergeGroupsLayout(group, newLayout, item);
68
+ onDrop === null || onDrop === void 0 ? void 0 : onDrop(groupedLayout, item, e);
64
69
  };
65
70
  this.pluginsRefs = [];
66
71
  this.state = {
@@ -80,6 +85,29 @@ class GridLayout extends react_1.default.PureComponent {
80
85
  clearTimeout(this._timeout);
81
86
  document.removeEventListener('visibilitychange', this.onVisibilityChange);
82
87
  }
88
+ getActiveLayout() {
89
+ const { layout, temporaryLayout } = this.context;
90
+ return (temporaryLayout === null || temporaryLayout === void 0 ? void 0 : temporaryLayout.data) || layout;
91
+ }
92
+ mergeGroupsLayout(group, newLayout, temporaryItem) {
93
+ const renderLayout = this.getActiveLayout();
94
+ const itemsByGroup = renderLayout.reduce((memo, item) => {
95
+ memo[item.i] = item;
96
+ return memo;
97
+ }, temporaryItem ? { [temporaryItem.i]: temporaryItem } : {});
98
+ const newItemsLayoutById = newLayout.reduce((memo, item) => {
99
+ const parent = itemsByGroup[item.i].parent;
100
+ memo[item.i] = Object.assign(Object.assign({}, item), { parent });
101
+ return memo;
102
+ }, {});
103
+ return renderLayout.map((currentItem) => {
104
+ const itemParent = itemsByGroup[currentItem.i].parent || constants_1.DEFAULT_GROUP;
105
+ if (itemParent === group) {
106
+ return newItemsLayoutById[currentItem.i];
107
+ }
108
+ return currentItem;
109
+ });
110
+ }
83
111
  reloadItems() {
84
112
  const { editMode, settings: { autoupdateInterval, silentLoading } = {}, reloadItems, } = this.context;
85
113
  const { isPageHidden } = this.state;
@@ -103,25 +131,84 @@ class GridLayout extends react_1.default.PureComponent {
103
131
  const { type } = temporaryLayout.dragProps;
104
132
  return (react_1.default.createElement(GridItem_1.default, { key: id, id: id, item: { id, type, data: {} }, layout: temporaryLayout.data, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, isPlaceholder: true, noOverlay: noOverlay, withCustomHandle: Boolean(draggableHandleClassName), overlayControls: this.props.overlayControls }));
105
133
  }
106
- render() {
107
- const { layout, temporaryLayout, config, registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
108
- this.pluginsRefs.length = config.items.length;
109
- return (react_1.default.createElement(ReactGridLayout_1.Layout, Object.assign({}, registerManager.gridLayout, { layout: (temporaryLayout === null || temporaryLayout === void 0 ? void 0 : temporaryLayout.data) || layout, isDraggable: editMode, isResizable: editMode, onDragStart: this._onStart, onDragStop: this._onStop, onResizeStart: this._onStart, onResizeStop: this._onStop }, (draggableHandleClassName
134
+ renderGroup(group, renderLayout, renderItems, offset = 0) {
135
+ const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
136
+ return (react_1.default.createElement(ReactGridLayout_1.Layout, Object.assign({}, registerManager.gridLayout, { key: `group_${group}`, layout: renderLayout, isDraggable: editMode, isResizable: editMode, onDragStart: this._onStart, onDragStop: (...args) => this._onStop(group, ...args), onResizeStart: this._onStart, onResizeStop: (...args) => this._onStop(group, ...args) }, (draggableHandleClassName
110
137
  ? { draggableHandle: `.${draggableHandleClassName}` }
111
138
  : null), (outerDnDEnable
112
139
  ? {
113
140
  isDroppable: true,
114
141
  onDropDragOver: this._onDropDragOver,
115
- onDrop: this._onDrop,
142
+ onDrop: (...args) => this._onDrop(group, ...args),
116
143
  }
117
144
  : null), { draggableCancel: `.${constants_1.OVERLAY_CONTROLS_CLASS_NAME}` }),
118
- config.items.map((item, i) => {
145
+ renderItems.map((item, i) => {
119
146
  return (react_1.default.createElement(GridItem_1.default, { forwardedPluginRef: (pluginRef) => {
120
- this.pluginsRefs[i] = pluginRef;
121
- }, key: item.id, id: item.id, item: item, layout: (temporaryLayout === null || temporaryLayout === void 0 ? void 0 : temporaryLayout.data) || layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, noOverlay: noOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), overlayControls: this.props.overlayControls }));
147
+ this.pluginsRefs[offset + i] = pluginRef;
148
+ }, key: item.id, id: item.id, item: item, layout: renderLayout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, noOverlay: noOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), overlayControls: this.props.overlayControls }));
122
149
  }),
123
150
  this.renderTemporaryPlaceholder()));
124
151
  }
152
+ render() {
153
+ const { config, groups, editMode } = this.context;
154
+ this.pluginsRefs.length = config.items.length;
155
+ const defaultRenderLayout = [];
156
+ const defaultRenderItems = [];
157
+ const layoutMap = {};
158
+ const groupedLayout = this.getActiveLayout().reduce((memo, item) => {
159
+ if (item.parent) {
160
+ if (!memo[item.parent]) {
161
+ memo[item.parent] = [];
162
+ }
163
+ memo[item.parent].push(item);
164
+ layoutMap[item.i] = item.parent;
165
+ }
166
+ else {
167
+ defaultRenderLayout.push(item);
168
+ }
169
+ return memo;
170
+ }, []);
171
+ const itemsByGroup = config.items.reduce((memo, item) => {
172
+ const group = layoutMap[item.id];
173
+ if (group) {
174
+ if (!memo[group]) {
175
+ memo[group] = [];
176
+ }
177
+ memo[group].push(item);
178
+ }
179
+ else {
180
+ defaultRenderItems.push(item);
181
+ }
182
+ return memo;
183
+ }, {});
184
+ let offset = 0;
185
+ if (groups) {
186
+ return groups.map((group) => {
187
+ const id = group.id || constants_1.DEFAULT_GROUP;
188
+ let element;
189
+ if (id === constants_1.DEFAULT_GROUP) {
190
+ element = this.renderGroup(constants_1.DEFAULT_GROUP, defaultRenderLayout, defaultRenderItems, offset);
191
+ offset += defaultRenderItems.length;
192
+ }
193
+ else {
194
+ element = this.renderGroup(id, groupedLayout[id], itemsByGroup[id], offset);
195
+ offset += itemsByGroup[id].length;
196
+ }
197
+ if (group.render) {
198
+ return group.render(id, element, {
199
+ config,
200
+ editMode,
201
+ items: itemsByGroup[id],
202
+ layout: groupedLayout[id],
203
+ });
204
+ }
205
+ return element;
206
+ });
207
+ }
208
+ else {
209
+ return this.renderGroup(constants_1.DEFAULT_GROUP, defaultRenderLayout, defaultRenderItems, offset);
210
+ }
211
+ }
125
212
  }
126
213
  GridLayout.contextType = DashKitContext_1.DashKitContext;
127
214
  exports.default = GridLayout;
@@ -6,14 +6,29 @@ const react_1 = tslib_1.__importDefault(require("react"));
6
6
  const react_grid_layout_1 = tslib_1.__importStar(require("react-grid-layout"));
7
7
  const constants_1 = require("../../constants");
8
8
  class DragOverLayout extends react_grid_layout_1.default {
9
- constructor() {
10
- super(...arguments);
9
+ constructor(...args) {
10
+ super(...args);
11
11
  this.dragReset = () => {
12
12
  if (this.dragEnterCounter) {
13
13
  this.dragEnterCounter = 0;
14
14
  this.removeDroppingPlaceholder();
15
15
  }
16
16
  };
17
+ this.mouseLeaveHandler = (e) => {
18
+ var _a;
19
+ const rect = ((_a = this.props.innerRef) === null || _a === void 0 ? void 0 : _a.current.getBoundingClientRect()) || {};
20
+ if (rect.bottom <= e.clientY ||
21
+ rect.top >= e.clientY ||
22
+ rect.left >= e.clientX ||
23
+ rect.right <= e.clientX) {
24
+ this.dragReset();
25
+ }
26
+ };
27
+ const oldonDrag = this.onDrag;
28
+ this.onDrag = (i, x, y, sintE) => {
29
+ oldonDrag(i, x, y, sintE);
30
+ this.mouseLeaveHandler(sintE.e);
31
+ };
17
32
  }
18
33
  componentDidMount() {
19
34
  var _a;
@@ -10,3 +10,4 @@ export declare const MenuItems: {
10
10
  };
11
11
  export declare const DEFAULT_WIDGET_HEIGHT = 3;
12
12
  export declare const DEFAULT_WIDGET_WIDTH = 3;
13
+ export declare const DEFAULT_GROUP = "__default";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_WIDGET_WIDTH = exports.DEFAULT_WIDGET_HEIGHT = exports.MenuItems = exports.TEMPORARY_ITEM_ID = exports.OVERLAY_CLASS_NAME = exports.OVERLAY_CONTROLS_CLASS_NAME = exports.DEFAULT_NAMESPACE = exports.COPIED_WIDGET_STORE_KEY = void 0;
3
+ exports.DEFAULT_GROUP = exports.DEFAULT_WIDGET_WIDTH = exports.DEFAULT_WIDGET_HEIGHT = exports.MenuItems = exports.TEMPORARY_ITEM_ID = exports.OVERLAY_CLASS_NAME = exports.OVERLAY_CONTROLS_CLASS_NAME = exports.DEFAULT_NAMESPACE = exports.COPIED_WIDGET_STORE_KEY = void 0;
4
4
  exports.COPIED_WIDGET_STORE_KEY = 'dashCopiedItem';
5
5
  exports.DEFAULT_NAMESPACE = 'default';
6
6
  exports.OVERLAY_CONTROLS_CLASS_NAME = 'dashkit-overlay-controls';
@@ -13,3 +13,4 @@ exports.MenuItems = {
13
13
  };
14
14
  exports.DEFAULT_WIDGET_HEIGHT = 3;
15
15
  exports.DEFAULT_WIDGET_WIDTH = 3;
16
+ exports.DEFAULT_GROUP = '__default';
@@ -4,6 +4,7 @@ exports.withContext = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
6
  const isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
7
+ const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
7
8
  const common_1 = require("../constants/common");
8
9
  const DashKitContext_1 = require("../context/DashKitContext");
9
10
  const shared_1 = require("../shared");
@@ -22,10 +23,11 @@ function useMemoStateContext(props) {
22
23
  const outerDnDEnable = Boolean(dndContext);
23
24
  // TODO: need move originalLayouts, adjustedLayouts to state
24
25
  const [layoutUpdateCounter, forceUpdateLayout] = react_1.default.useState(0);
25
- const onChange = react_1.default.useCallback(({ config = props.config, itemsStateAndParams = props.itemsStateAndParams }) => {
26
+ const onChange = react_1.default.useCallback(({ config = props.config, itemsStateAndParams = props.itemsStateAndParams, groups = props.groups, }) => {
26
27
  if (!((0, isEqual_1.default)(config, props.config) &&
27
- (0, isEqual_1.default)(itemsStateAndParams, props.itemsStateAndParams))) {
28
- props.onChange({ config, itemsStateAndParams });
28
+ (0, isEqual_1.default)(itemsStateAndParams, props.itemsStateAndParams) &&
29
+ (0, isEqual_1.default)(groups, props.groups))) {
30
+ props.onChange({ config, itemsStateAndParams, groups });
29
31
  }
30
32
  }, [props.config, props.itemsStateAndParams, props.onChange]);
31
33
  // каллбэк вызывающийся при изменение лэйаута сетки, первым аргументом приходит актуальный конфиг лэйаута,
@@ -171,6 +173,7 @@ function useMemoStateContext(props) {
171
173
  }
172
174
  return false;
173
175
  }, [resetTemporaryLayout, temporaryLayout, dragOverPlugin, dragProps]);
176
+ const onDropProp = props.onDrop;
174
177
  const onDrop = react_1.default.useCallback((newLayout, item) => {
175
178
  if (!dragProps) {
176
179
  return;
@@ -179,23 +182,23 @@ function useMemoStateContext(props) {
179
182
  data: newLayout,
180
183
  dragProps,
181
184
  });
182
- const { i, w, h, x, y } = item;
183
- props.onDrop({
185
+ onDropProp({
184
186
  newLayout: newLayout.reduce((memo, l) => {
185
- if (l.i !== i) {
186
- memo.push({ i: l.i, w: l.w, h: l.h, x: l.x, y: l.y });
187
+ if (l.i !== item.i) {
188
+ memo.push((0, pick_1.default)(l, ['i', 'h', 'w', 'x', 'y', 'parent']));
187
189
  }
188
190
  return memo;
189
191
  }, []),
190
- itemLayout: { w, h, x, y },
192
+ itemLayout: (0, pick_1.default)(item, ['i', 'h', 'w', 'x', 'y', 'parent']),
191
193
  commit: resetTemporaryLayout,
192
194
  dragProps,
193
195
  });
194
- }, [dragProps, props.onDrop, setTemporaryLayout, resetTemporaryLayout]);
196
+ }, [dragProps, onDropProp, setTemporaryLayout, resetTemporaryLayout]);
195
197
  return react_1.default.useMemo(() => ({
196
198
  layout: resultLayout,
197
199
  temporaryLayout,
198
200
  config: props.config,
201
+ groups: props.groups,
199
202
  context: props.context,
200
203
  noOverlay: props.noOverlay,
201
204
  focusable: props.focusable,
@@ -224,6 +227,7 @@ function useMemoStateContext(props) {
224
227
  resultLayout,
225
228
  temporaryLayout,
226
229
  props.config,
230
+ props.groups,
227
231
  props.context,
228
232
  props.noOverlay,
229
233
  props.focusable,
@@ -6,6 +6,7 @@ export declare const useCalcPropsLayout: (config: Config, registerManager: Regis
6
6
  w: number;
7
7
  x: number;
8
8
  y: number;
9
+ parent?: string | undefined;
9
10
  minW: number;
10
11
  minH: number;
11
12
  maxW?: number | undefined;
@@ -5,9 +5,10 @@ export interface GetItemsParamsArg {
5
5
  config: Config;
6
6
  itemsStateAndParams: ItemsStateAndParams;
7
7
  plugins: PluginBase[];
8
+ useStateAsInitial?: boolean;
8
9
  }
9
10
  type GetItemsParamsReturn = Record<string, StringParams | Record<string, StringParams>>;
10
- export declare function getItemsParams({ defaultGlobalParams, globalParams, config, itemsStateAndParams, plugins, }: GetItemsParamsArg): GetItemsParamsReturn;
11
+ export declare function getItemsParams({ defaultGlobalParams, globalParams, config, itemsStateAndParams, plugins, useStateAsInitial, }: GetItemsParamsArg): GetItemsParamsReturn;
11
12
  export declare function getItemsState({ config, itemsStateAndParams, }: {
12
13
  config: Config;
13
14
  itemsStateAndParams: ItemsStateAndParams;
@@ -5,7 +5,18 @@ 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, }) {
8
+ const getParamsFromStateAndParams = ({ itemsStateAndParams, parentItemId, item, }) => {
9
+ const widgetId = parentItemId || item.id;
10
+ if (!(widgetId in itemsStateAndParams)) {
11
+ return {};
12
+ }
13
+ const stateAndParams = itemsStateAndParams;
14
+ const itemParams = parentItemId
15
+ ? Object.assign({}, stateAndParams[widgetId].params[item.id])
16
+ : Object.assign({}, stateAndParams[widgetId].params);
17
+ return itemParams;
18
+ };
19
+ function getItemParams({ item, itemsStateAndParams, mapItemsIgnores, itemsWithDefaultsByNamespace, getMergedParams, defaultGlobalParams, globalParams, isFirstVersion, queueData, parentItemId, useStateAsInitial, }) {
9
20
  var _a, _b;
10
21
  const { id, namespace } = item;
11
22
  let defaultWidgetParams = {};
@@ -24,7 +35,9 @@ function getItemParams({ item, itemsStateAndParams, mapItemsIgnores, itemsWithDe
24
35
  // default parameters to begin with
25
36
  affectingItemsWithDefaults.reduceRight((defaultParams, itemWithDefaults) => {
26
37
  return Object.assign(Object.assign({}, defaultParams), getMergedParams(itemWithDefaults.defaults || {}));
27
- }, {}), getMergedParams(globalParams));
38
+ }, {}), getMergedParams(globalParams), useStateAsInitial
39
+ ? getParamsFromStateAndParams({ parentItemId, item, itemsStateAndParams })
40
+ : {});
28
41
  if (isFirstVersion) {
29
42
  itemParams = Object.assign(itemParams, ((_b = itemsStateAndParams === null || itemsStateAndParams === void 0 ? void 0 : itemsStateAndParams[id]) === null || _b === void 0 ? void 0 : _b.params) || {});
30
43
  }
@@ -49,7 +62,7 @@ function getItemParams({ item, itemsStateAndParams, mapItemsIgnores, itemsWithDe
49
62
  }
50
63
  return Object.assign(Object.assign({}, defaultWidgetParams), itemParams);
51
64
  }
52
- function getItemsParams({ defaultGlobalParams = {}, globalParams = {}, config, itemsStateAndParams, plugins, }) {
65
+ function getItemsParams({ defaultGlobalParams = {}, globalParams = {}, config, itemsStateAndParams, plugins, useStateAsInitial, }) {
53
66
  const { aliases, connections } = config;
54
67
  const items = (0, helpers_1.prerenderItems)({ items: config.items, plugins });
55
68
  const isFirstVersion = (0, helpers_1.getCurrentVersion)(itemsStateAndParams) === 1;
@@ -92,10 +105,11 @@ function getItemsParams({ defaultGlobalParams = {}, globalParams = {}, config, i
92
105
  globalParams,
93
106
  isFirstVersion,
94
107
  queueData,
108
+ useStateAsInitial,
95
109
  };
96
110
  if ((0, helpers_1.isItemWithGroup)(item)) {
97
111
  const groupParams = item.data.group.reduce((groupItemParams, groupItem) => {
98
- groupItemParams[groupItem.id] = getItemParams(Object.assign({ item: groupItem }, paramsOptions));
112
+ groupItemParams[groupItem.id] = getItemParams(Object.assign({ item: groupItem, parentItemId: item.id }, paramsOptions));
99
113
  return groupItemParams;
100
114
  }, {});
101
115
  return Object.assign(Object.assign({}, itemsParams), { [id]: groupParams });
@@ -1,5 +1,8 @@
1
1
  import { StringParams } from './common';
2
- export interface ConfigLayout {
2
+ export interface AdditionalWidgetLayout {
3
+ parent?: string;
4
+ }
5
+ export interface ConfigLayout extends AdditionalWidgetLayout {
3
6
  i: string;
4
7
  h: number;
5
8
  w: number;
@@ -1,6 +1,7 @@
1
1
  import type ReactGridLayout from 'react-grid-layout';
2
2
  import type { OverlayCustomControlItem } from '../components/OverlayControls/OverlayControls';
3
3
  import { MenuItems } from '../constants';
4
+ import { AdditionalWidgetLayout } from '../shared';
4
5
  export interface Settings {
5
6
  gridLayout?: ReactGridLayout.ReactGridLayoutProps;
6
7
  theme?: string;
@@ -15,7 +16,7 @@ export interface SettingsProps {
15
16
  export interface ContextProps {
16
17
  [key: string]: any;
17
18
  }
18
- export interface WidgetLayout {
19
+ export interface WidgetLayout extends AdditionalWidgetLayout {
19
20
  i: string;
20
21
  w: number;
21
22
  h: number;
@@ -1,4 +1,5 @@
1
- import type { ConfigItem, ConfigLayout } from '../shared';
1
+ /// <reference types="react" />
2
+ import type { Config, ConfigItem, ConfigLayout } from '../shared';
2
3
  export interface AddConfigItem extends Omit<ConfigItem, 'id' | 'namespace'> {
3
4
  id?: null;
4
5
  namespace?: string;
@@ -11,3 +12,13 @@ export type SetItemOptions = {
11
12
  export type SetNewItemOptions = SetItemOptions & {
12
13
  updateLayout?: ConfigLayout[];
13
14
  };
15
+ export interface DashkitGroupRenderProps {
16
+ config: Config;
17
+ editMode: boolean;
18
+ items: ConfigItem[];
19
+ layout: ConfigLayout[];
20
+ }
21
+ export interface DashKiGroup {
22
+ id?: string;
23
+ render?: (id: string, children: React.ReactNode, props: DashkitGroupRenderProps) => React.ReactNode;
24
+ }
@@ -23,16 +23,7 @@ export interface PluginWidgetProps<T = StringParams> {
23
23
  adjustedWidgetLayout?: WidgetLayout;
24
24
  }) => void;
25
25
  }
26
- export interface PluginDefaultLayout {
27
- w?: number;
28
- h?: number;
29
- x?: number;
30
- y?: number;
31
- minW?: number;
32
- maxW?: number;
33
- minH?: number;
34
- maxH?: number;
35
- }
26
+ export type PluginDefaultLayout = Partial<Omit<WidgetLayout, 'i'>>;
36
27
  export interface Plugin<P extends PluginWidgetProps<T> = any, T = StringParams> extends PluginBase {
37
28
  defaultLayout?: PluginDefaultLayout;
38
29
  renderer: (props: P, forwardedRef: React.RefObject<any>) => React.ReactNode;
@@ -1,4 +1,4 @@
1
- import type { Config, ConfigItem, ItemStateAndParams, ItemStateAndParamsChangeOptions, ItemsStateAndParams } from '../shared';
1
+ import type { Config, ConfigItem, ConfigItemGroup, ItemStateAndParams, ItemStateAndParamsChangeOptions, ItemsStateAndParams } from '../shared';
2
2
  import type { AddConfigItem, SetItemOptions, SetNewItemOptions, WidgetLayout } from '../typings';
3
3
  import { RegisterManagerPluginLayout } from './register-manager';
4
4
  interface RemoveItemArg {
@@ -13,6 +13,13 @@ interface ChangeStateAndParamsArg {
13
13
  stateAndParams: ItemStateAndParams;
14
14
  options?: ItemStateAndParamsChangeOptions;
15
15
  }
16
+ export declare const getChangedParams: ({ initiatorItem, stateAndParams, itemsStateAndParams, }: {
17
+ initiatorItem: ConfigItem | ConfigItemGroup;
18
+ stateAndParams: ItemStateAndParams;
19
+ itemsStateAndParams: ItemsStateAndParams;
20
+ }) => {
21
+ [x: string]: string | string[];
22
+ };
16
23
  export declare class UpdateManager {
17
24
  static addItem({ item, namespace, layout, config, options, }: {
18
25
  item: AddConfigItem;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UpdateManager = void 0;
3
+ exports.UpdateManager = exports.getChangedParams = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const immutability_helper_1 = tslib_1.__importStar(require("immutability-helper"));
6
6
  const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
@@ -78,6 +78,12 @@ function getAllowableChangedParams(item, stateAndParams, itemsStateAndParams, pa
78
78
  : allowedParams;
79
79
  }
80
80
  const stateParamsConf = stateAndParams.params;
81
+ // check if structure is StringParams or Record<string, StringParams>
82
+ // if it's Record<string, StringParams>, then this is a group application of params
83
+ // and checking for comparison of allowedParams and stateParamsConf is not necessary
84
+ const isGroupParamsApply = typeof (stateParamsConf === null || stateParamsConf === void 0 ? void 0 : stateParamsConf[item.id]) === 'object' &&
85
+ (stateParamsConf === null || stateParamsConf === void 0 ? void 0 : stateParamsConf[item.id]) !== null &&
86
+ !Array.isArray(stateParamsConf === null || stateParamsConf === void 0 ? void 0 : stateParamsConf[item.id]);
81
87
  if ((0, shared_1.isItemWithTabs)(item)) {
82
88
  let tab;
83
89
  if ('state' in stateAndParams && ((_a = stateAndParams.state) === null || _a === void 0 ? void 0 : _a.tabId)) {
@@ -90,14 +96,11 @@ function getAllowableChangedParams(item, stateAndParams, itemsStateAndParams, pa
90
96
  allowedParams = (0, pick_1.default)(stateParamsConf, Object.keys((tab === null || tab === void 0 ? void 0 : tab.params) || {}));
91
97
  }
92
98
  else {
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;
99
+ const paramsConf = isGroupParamsApply ? stateParamsConf[item.id] : stateParamsConf;
98
100
  allowedParams = (0, pick_1.default)(paramsConf, Object.keys(item.defaults || {}));
99
101
  }
100
- if (Object.keys(allowedParams || {}).length !== Object.keys(stateParamsConf || {}).length) {
102
+ if (!isGroupParamsApply &&
103
+ Object.keys(allowedParams || {}).length !== Object.keys(stateParamsConf || {}).length) {
101
104
  console.warn('Параметры, которых нет в defaults, будут проигнорированы!');
102
105
  }
103
106
  return allowedParams;
@@ -180,6 +183,12 @@ function getNewItemData({ item, config, counter: argsCounter, salt, options }) {
180
183
  }
181
184
  return { data, counter, excludeIds };
182
185
  }
186
+ const getChangedParams = ({ initiatorItem, stateAndParams, itemsStateAndParams, }) => {
187
+ const allowableParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams);
188
+ const allowableActionParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams, { type: 'actionParams', returnPrefix: true });
189
+ return Object.assign(Object.assign({}, allowableParams), allowableActionParams);
190
+ };
191
+ exports.getChangedParams = getChangedParams;
183
192
  function changeGroupParams({ groupItemIds, initiatorId, initiatorItem, itemsStateAndParams, stateAndParams, config, unusedIds, }) {
184
193
  var _a;
185
194
  const meta = (0, shared_1.addGroupToQueue)({
@@ -192,9 +201,12 @@ function changeGroupParams({ groupItemIds, initiatorId, initiatorItem, itemsStat
192
201
  const currentItemParams = (_a = itemsStateAndParams[initiatorId]) === null || _a === void 0 ? void 0 : _a.params;
193
202
  for (const groupItem of initiatorItem.data.group) {
194
203
  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);
204
+ const changedParams = (0, exports.getChangedParams)({
205
+ initiatorItem: groupItem,
206
+ stateAndParams,
207
+ itemsStateAndParams,
208
+ });
209
+ updatedItems[groupItem.id] = changedParams;
198
210
  continue;
199
211
  }
200
212
  if (currentItemParams && currentItemParams[groupItem.id]) {
@@ -222,7 +234,7 @@ class UpdateManager {
222
234
  const newIdData = (0, get_new_id_1.getNewId)({ config, salt, counter, excludeIds: newItemData.excludeIds });
223
235
  counter = newIdData.counter;
224
236
  const newItem = Object.assign(Object.assign({}, item), { id: newIdData.id, data: newItemData.data, namespace });
225
- const saveDefaultLayout = (0, pick_1.default)(layout, ['h', 'w', 'x', 'y']);
237
+ const saveDefaultLayout = (0, pick_1.default)(layout, ['h', 'w', 'x', 'y', 'parent']);
226
238
  if (options.updateLayout) {
227
239
  const byId = options.updateLayout.reduce((memo, t) => {
228
240
  memo[t.i] = t;
@@ -303,7 +315,7 @@ class UpdateManager {
303
315
  static updateLayout({ layout, config }) {
304
316
  return (0, immutability_helper_1.default)(config, {
305
317
  layout: {
306
- $set: layout.map(({ x, y, w, h, i }) => ({ x, y, w, h, i })),
318
+ $set: layout.map((item) => (0, pick_1.default)(item, ['i', 'h', 'w', 'x', 'y', 'parent'])),
307
319
  },
308
320
  });
309
321
  }
@@ -354,8 +366,11 @@ class UpdateManager {
354
366
  });
355
367
  }
356
368
  if ('params' in stateAndParams) {
357
- const allowableParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams);
358
- const allowableActionParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams, { type: 'actionParams', returnPrefix: true });
369
+ const changedParams = (0, exports.getChangedParams)({
370
+ initiatorItem,
371
+ stateAndParams,
372
+ itemsStateAndParams,
373
+ });
359
374
  const tabId = (0, shared_1.isItemWithTabs)(initiatorItem)
360
375
  ? newTabId || (0, shared_1.resolveItemInnerId)({ item: initiatorItem, itemsStateAndParams })
361
376
  : undefined;
@@ -370,7 +385,7 @@ class UpdateManager {
370
385
  $unset: unusedIds,
371
386
  [initiatorId]: {
372
387
  $auto: Object.assign({ params: {
373
- [commandUpdateParams]: Object.assign(Object.assign({}, allowableParams), allowableActionParams),
388
+ [commandUpdateParams]: changedParams,
374
389
  } }, (hasState ? { state: { $set: stateAndParams.state } } : {})),
375
390
  },
376
391
  [shared_1.META_KEY]: { $set: meta },
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { Config, ConfigItem, GlobalParams, ItemDropProps, ItemsStateAndParams } from '../../shared';
3
- import { ContextProps, Plugin, SetConfigItem, SetNewItemOptions, Settings, SettingsProps } from '../../typings';
3
+ import { ContextProps, DashKiGroup, Plugin, SetConfigItem, SetNewItemOptions, Settings, SettingsProps } from '../../typings';
4
4
  import GridLayout from '../GridLayout/GridLayout';
5
5
  import { OverlayControlItem } from '../OverlayControls/OverlayControls';
6
6
  interface DashKitGeneralProps {
@@ -14,6 +14,7 @@ interface DashKitDefaultProps {
14
14
  onChange: (data: {
15
15
  config: Config;
16
16
  itemsStateAndParams: ItemsStateAndParams;
17
+ groups?: DashKiGroup[];
17
18
  }) => void;
18
19
  onDrop: (dropProps: ItemDropProps) => void;
19
20
  defaultGlobalParams: GlobalParams;
@@ -23,6 +24,7 @@ interface DashKitDefaultProps {
23
24
  context: ContextProps;
24
25
  noOverlay: boolean;
25
26
  focusable?: boolean;
27
+ groups?: DashKiGroup[];
26
28
  }
27
29
  export interface DashKitProps extends DashKitGeneralProps, Partial<DashKitDefaultProps> {
28
30
  }