@gravity-ui/dashkit 8.1.0 → 8.2.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 (76) hide show
  1. package/README.md +95 -0
  2. package/build/cjs/components/ActionPanel/ActionPanel.d.ts +4 -1
  3. package/build/cjs/components/ActionPanel/ActionPanel.js +10 -6
  4. package/build/cjs/components/ActionPanel/types.d.ts +3 -1
  5. package/build/cjs/components/DashKit/DashKit.d.ts +4 -3
  6. package/build/cjs/components/DashKit/DashKit.js +1 -0
  7. package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +10 -0
  8. package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.js +35 -0
  9. package/build/cjs/components/GridItem/GridItem.d.ts +2 -2
  10. package/build/cjs/components/GridItem/GridItem.js +8 -5
  11. package/build/cjs/components/GridLayout/GridLayout.d.ts +3 -0
  12. package/build/cjs/components/GridLayout/GridLayout.js +51 -11
  13. package/build/cjs/components/GridLayout/ReactGridLayout.d.ts +3 -0
  14. package/build/cjs/components/GridLayout/ReactGridLayout.js +49 -0
  15. package/build/cjs/components/Item/Item.css +1 -1
  16. package/build/cjs/components/Item/Item.d.ts +1 -0
  17. package/build/cjs/components/Item/Item.js +7 -1
  18. package/build/cjs/components/OverlayControls/OverlayControls.js +2 -2
  19. package/build/cjs/components/index.d.ts +1 -0
  20. package/build/cjs/components/index.js +1 -0
  21. package/build/cjs/constants/common.d.ts +4 -0
  22. package/build/cjs/constants/common.js +5 -1
  23. package/build/cjs/context/DashKitContext.d.ts +1 -0
  24. package/build/cjs/context/DashKitContext.js +3 -1
  25. package/build/cjs/hocs/prepareItem.d.ts +1 -0
  26. package/build/cjs/hocs/prepareItem.js +4 -2
  27. package/build/cjs/hocs/withContext.js +84 -6
  28. package/build/cjs/hooks/useDnDItemProps.d.ts +10 -0
  29. package/build/cjs/hooks/useDnDItemProps.js +30 -0
  30. package/build/cjs/shared/constants/common.d.ts +1 -0
  31. package/build/cjs/shared/constants/common.js +2 -1
  32. package/build/cjs/shared/modules/state-and-params.d.ts +2 -1
  33. package/build/cjs/shared/modules/state-and-params.js +18 -4
  34. package/build/cjs/shared/types/common.d.ts +15 -0
  35. package/build/cjs/typings/config.d.ts +3 -0
  36. package/build/cjs/typings/plugin.d.ts +1 -0
  37. package/build/cjs/utils/update-manager.d.ts +10 -3
  38. package/build/cjs/utils/update-manager.js +52 -20
  39. package/build/esm/components/ActionPanel/ActionPanel.d.ts +4 -1
  40. package/build/esm/components/ActionPanel/ActionPanel.js +8 -5
  41. package/build/esm/components/ActionPanel/types.d.ts +3 -1
  42. package/build/esm/components/DashKit/DashKit.d.ts +4 -3
  43. package/build/esm/components/DashKit/DashKit.js +1 -0
  44. package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +10 -0
  45. package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.js +30 -0
  46. package/build/esm/components/GridItem/GridItem.d.ts +2 -2
  47. package/build/esm/components/GridItem/GridItem.js +8 -5
  48. package/build/esm/components/GridLayout/GridLayout.d.ts +3 -0
  49. package/build/esm/components/GridLayout/GridLayout.js +52 -12
  50. package/build/esm/components/GridLayout/ReactGridLayout.d.ts +3 -0
  51. package/build/esm/components/GridLayout/ReactGridLayout.js +45 -0
  52. package/build/esm/components/Item/Item.css +1 -1
  53. package/build/esm/components/Item/Item.d.ts +1 -0
  54. package/build/esm/components/Item/Item.js +7 -1
  55. package/build/esm/components/OverlayControls/OverlayControls.js +2 -2
  56. package/build/esm/components/index.d.ts +1 -0
  57. package/build/esm/components/index.js +1 -0
  58. package/build/esm/constants/common.d.ts +4 -0
  59. package/build/esm/constants/common.js +4 -0
  60. package/build/esm/context/DashKitContext.d.ts +1 -0
  61. package/build/esm/context/DashKitContext.js +2 -1
  62. package/build/esm/hocs/prepareItem.d.ts +1 -0
  63. package/build/esm/hocs/prepareItem.js +4 -2
  64. package/build/esm/hocs/withContext.js +85 -7
  65. package/build/esm/hooks/useDnDItemProps.d.ts +10 -0
  66. package/build/esm/hooks/useDnDItemProps.js +25 -0
  67. package/build/esm/shared/constants/common.d.ts +1 -0
  68. package/build/esm/shared/constants/common.js +1 -0
  69. package/build/esm/shared/modules/state-and-params.d.ts +2 -1
  70. package/build/esm/shared/modules/state-and-params.js +18 -4
  71. package/build/esm/shared/types/common.d.ts +15 -0
  72. package/build/esm/typings/config.d.ts +3 -0
  73. package/build/esm/typings/plugin.d.ts +1 -0
  74. package/build/esm/utils/update-manager.d.ts +10 -3
  75. package/build/esm/utils/update-manager.js +50 -19
  76. package/package.json +1 -1
@@ -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 common_1 = require("../constants/common");
7
8
  const DashKitContext_1 = require("../context/DashKitContext");
8
9
  const shared_1 = require("../shared");
9
10
  const utils_1 = require("../utils");
@@ -15,6 +16,10 @@ function useMemoStateContext(props) {
15
16
  // (высота) из конфига будет запоминаться в originalLayouts, новое значение высоты в adjustedLayouts
16
17
  const originalLayouts = react_1.default.useRef({});
17
18
  const adjustedLayouts = react_1.default.useRef({});
19
+ const [temporaryLayout, setTemporaryLayout] = react_1.default.useState(null);
20
+ const resetTemporaryLayout = react_1.default.useCallback(() => setTemporaryLayout(null), [setTemporaryLayout]);
21
+ const dndContext = react_1.default.useContext(DashKitContext_1.DashKitDnDContext);
22
+ const outerDnDEnable = Boolean(dndContext);
18
23
  // TODO: need move originalLayouts, adjustedLayouts to state
19
24
  const [layoutUpdateCounter, forceUpdateLayout] = react_1.default.useState(0);
20
25
  const onChange = react_1.default.useCallback(({ config = props.config, itemsStateAndParams = props.itemsStateAndParams }) => {
@@ -45,12 +50,27 @@ function useMemoStateContext(props) {
45
50
  }
46
51
  }, [props.config, onChange]);
47
52
  const onItemRemove = react_1.default.useCallback((id) => {
48
- onChange(utils_1.UpdateManager.removeItem({
49
- id,
50
- config: props.config,
51
- itemsStateAndParams: props.itemsStateAndParams,
52
- }));
53
- }, [props.config, props.itemsStateAndParams, onChange]);
53
+ if (id === common_1.TEMPORARY_ITEM_ID) {
54
+ resetTemporaryLayout();
55
+ }
56
+ else {
57
+ if (temporaryLayout) {
58
+ setTemporaryLayout(Object.assign(Object.assign({}, temporaryLayout), { data: temporaryLayout.data.filter(({ i }) => i !== id) }));
59
+ }
60
+ onChange(utils_1.UpdateManager.removeItem({
61
+ id,
62
+ config: props.config,
63
+ itemsStateAndParams: props.itemsStateAndParams,
64
+ }));
65
+ }
66
+ }, [
67
+ props.config,
68
+ props.itemsStateAndParams,
69
+ temporaryLayout,
70
+ onChange,
71
+ setTemporaryLayout,
72
+ resetTemporaryLayout,
73
+ ]);
54
74
  const onItemStateAndParamsChange = react_1.default.useCallback((id, stateAndParams, options) => {
55
75
  onChange({
56
76
  itemsStateAndParams: utils_1.UpdateManager.changeStateAndParams({
@@ -124,8 +144,57 @@ function useMemoStateContext(props) {
124
144
  const reloadItems = react_1.default.useCallback((pluginsRefs, data) => {
125
145
  pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
126
146
  }, []);
147
+ const dragProps = dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragProps;
148
+ const dragOverPlugin = react_1.default.useMemo(() => {
149
+ if (!dragProps) {
150
+ return null;
151
+ }
152
+ const pluginType = dragProps.type;
153
+ if (props.registerManager.check(pluginType)) {
154
+ return props.registerManager.getItem(pluginType);
155
+ }
156
+ else {
157
+ // eslint-disable-next-line no-console
158
+ console.error(`Uknown pluginType: ${pluginType}`);
159
+ return null;
160
+ }
161
+ }, [dragProps, props.registerManager]);
162
+ const onDropDragOver = react_1.default.useCallback(() => {
163
+ if (temporaryLayout) {
164
+ resetTemporaryLayout();
165
+ return false;
166
+ }
167
+ if (dragOverPlugin) {
168
+ const { defaultLayout } = dragOverPlugin;
169
+ const { h = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.h) || common_1.DEFAULT_WIDGET_HEIGHT, w = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.w) || common_1.DEFAULT_WIDGET_WIDTH, } = dragProps.layout || {};
170
+ return { h, w };
171
+ }
172
+ return false;
173
+ }, [resetTemporaryLayout, temporaryLayout, dragOverPlugin, dragProps]);
174
+ const onDrop = react_1.default.useCallback((newLayout, item) => {
175
+ if (!dragProps) {
176
+ return;
177
+ }
178
+ setTemporaryLayout({
179
+ data: newLayout,
180
+ dragProps,
181
+ });
182
+ const { i, w, h, x, y } = item;
183
+ props.onDrop({
184
+ 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
+ }
188
+ return memo;
189
+ }, []),
190
+ itemLayout: { w, h, x, y },
191
+ commit: resetTemporaryLayout,
192
+ dragProps,
193
+ });
194
+ }, [dragProps, props.onDrop, setTemporaryLayout, resetTemporaryLayout]);
127
195
  return react_1.default.useMemo(() => ({
128
196
  layout: resultLayout,
197
+ temporaryLayout,
129
198
  config: props.config,
130
199
  context: props.context,
131
200
  noOverlay: props.noOverlay,
@@ -139,6 +208,8 @@ function useMemoStateContext(props) {
139
208
  registerManager: props.registerManager,
140
209
  onItemStateAndParamsChange,
141
210
  removeItem: onItemRemove,
211
+ onDrop,
212
+ onDropDragOver,
142
213
  editItem: props.onItemEdit,
143
214
  layoutChange: onLayoutChange,
144
215
  getItemsMeta,
@@ -147,8 +218,11 @@ function useMemoStateContext(props) {
147
218
  revertToOriginalLayout,
148
219
  forwardedMetaRef: props.forwardedMetaRef,
149
220
  draggableHandleClassName: props.draggableHandleClassName,
221
+ outerDnDEnable,
222
+ dragOverPlugin,
150
223
  }), [
151
224
  resultLayout,
225
+ temporaryLayout,
152
226
  props.config,
153
227
  props.context,
154
228
  props.noOverlay,
@@ -161,6 +235,8 @@ function useMemoStateContext(props) {
161
235
  props.registerManager,
162
236
  onItemStateAndParamsChange,
163
237
  onItemRemove,
238
+ onDrop,
239
+ onDropDragOver,
164
240
  props.onItemEdit,
165
241
  onLayoutChange,
166
242
  getItemsMeta,
@@ -169,6 +245,8 @@ function useMemoStateContext(props) {
169
245
  revertToOriginalLayout,
170
246
  props.forwardedMetaRef,
171
247
  props.draggableHandleClassName,
248
+ outerDnDEnable,
249
+ dragOverPlugin,
172
250
  ]);
173
251
  }
174
252
  function withContext(Component) {
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { ActionPanelItem } from '../components';
3
+ type DndProps = null | {
4
+ draggable: true;
5
+ unselectable: 'on';
6
+ onDragStart: React.DragEventHandler<HTMLDivElement>;
7
+ onDragEnd: React.DragEventHandler<HTMLDivElement>;
8
+ };
9
+ export declare const useDnDItemProps: (item: ActionPanelItem) => DndProps;
10
+ export {};
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useDnDItemProps = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ const DashKitContext_1 = require("../context/DashKitContext");
7
+ const useDnDItemProps = (item) => {
8
+ const dragContext = react_1.default.useContext(DashKitContext_1.DashKitDnDContext);
9
+ const onDragStart = react_1.default.useCallback((e) => {
10
+ if (dragContext && item.dragProps) {
11
+ dragContext.onDragStart(e, item.dragProps);
12
+ e.dataTransfer.setDragImage(dragContext.dragImagePreview, 0, 0);
13
+ }
14
+ }, [dragContext, item.dragProps]);
15
+ const onDragEnd = react_1.default.useCallback((e) => {
16
+ if (dragContext) {
17
+ dragContext.onDragEnd(e);
18
+ }
19
+ }, [dragContext]);
20
+ if (dragContext && item.dragProps) {
21
+ return {
22
+ draggable: true,
23
+ unselectable: 'on',
24
+ onDragStart,
25
+ onDragEnd,
26
+ };
27
+ }
28
+ return null;
29
+ };
30
+ exports.useDnDItemProps = useDnDItemProps;
@@ -1,3 +1,4 @@
1
1
  export declare const CURRENT_VERSION = 2;
2
2
  export declare const META_KEY = "__meta__";
3
3
  export declare const ACTION_PARAM_PREFIX = "_ap_";
4
+ export declare const TERMORARY_ITEM_ID = "__dropping-elem__";
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ACTION_PARAM_PREFIX = exports.META_KEY = exports.CURRENT_VERSION = void 0;
3
+ exports.TERMORARY_ITEM_ID = exports.ACTION_PARAM_PREFIX = exports.META_KEY = exports.CURRENT_VERSION = void 0;
4
4
  exports.CURRENT_VERSION = 2;
5
5
  exports.META_KEY = '__meta__';
6
6
  exports.ACTION_PARAM_PREFIX = '_ap_';
7
+ exports.TERMORARY_ITEM_ID = '__dropping-elem__';
@@ -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,20 @@
1
+ import { ConfigLayout } from './config';
1
2
  export type Dictionary<T = unknown> = Record<string, T>;
2
3
  export interface StringParams extends Dictionary<string | string[]> {
3
4
  }
4
5
  export interface GlobalParams extends StringParams {
5
6
  }
7
+ export type ItemDragProps = {
8
+ type: string;
9
+ layout?: {
10
+ w?: number;
11
+ h?: number;
12
+ };
13
+ extra?: any;
14
+ };
15
+ export type ItemDropProps = {
16
+ commit: () => void;
17
+ dragProps: ItemDragProps;
18
+ itemLayout: ConfigLayout;
19
+ newLayout: ConfigLayout[];
20
+ };
@@ -8,3 +8,6 @@ export type SetConfigItem = ConfigItem | AddConfigItem;
8
8
  export type SetItemOptions = {
9
9
  excludeIds?: string[];
10
10
  };
11
+ export type SetNewItemOptions = SetItemOptions & {
12
+ updateLayout?: ConfigLayout[];
13
+ };
@@ -36,4 +36,5 @@ export interface PluginDefaultLayout {
36
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
+ placeholderRenderer?: (props: P, forwardedRef: React.RefObject<any>) => React.ReactNode;
39
40
  }
@@ -1,5 +1,5 @@
1
- import type { Config, ConfigItem, ItemStateAndParams, ItemStateAndParamsChangeOptions, ItemsStateAndParams } from '../shared';
2
- import type { AddConfigItem, SetItemOptions, WidgetLayout } from '../typings';
1
+ import type { Config, ConfigItem, ConfigItemGroup, ItemStateAndParams, ItemStateAndParamsChangeOptions, ItemsStateAndParams } from '../shared';
2
+ import type { AddConfigItem, SetItemOptions, SetNewItemOptions, WidgetLayout } from '../typings';
3
3
  import { RegisterManagerPluginLayout } from './register-manager';
4
4
  interface RemoveItemArg {
5
5
  id: string;
@@ -13,13 +13,20 @@ 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;
19
26
  namespace: string;
20
27
  layout: RegisterManagerPluginLayout;
21
28
  config: Config;
22
- options: SetItemOptions;
29
+ options: SetNewItemOptions;
23
30
  }): Config;
24
31
  static editItem({ item, namespace, config, options, }: {
25
32
  item: ConfigItem;
@@ -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,11 @@ 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
+ !Array.isArray(stateParamsConf === null || stateParamsConf === void 0 ? void 0 : stateParamsConf[item.id]);
81
86
  if ((0, shared_1.isItemWithTabs)(item)) {
82
87
  let tab;
83
88
  if ('state' in stateAndParams && ((_a = stateAndParams.state) === null || _a === void 0 ? void 0 : _a.tabId)) {
@@ -90,14 +95,11 @@ function getAllowableChangedParams(item, stateAndParams, itemsStateAndParams, pa
90
95
  allowedParams = (0, pick_1.default)(stateParamsConf, Object.keys((tab === null || tab === void 0 ? void 0 : tab.params) || {}));
91
96
  }
92
97
  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;
98
+ const paramsConf = isGroupParamsApply ? stateParamsConf[item.id] : stateParamsConf;
98
99
  allowedParams = (0, pick_1.default)(paramsConf, Object.keys(item.defaults || {}));
99
100
  }
100
- if (Object.keys(allowedParams || {}).length !== Object.keys(stateParamsConf || {}).length) {
101
+ if (!isGroupParamsApply &&
102
+ Object.keys(allowedParams || {}).length !== Object.keys(stateParamsConf || {}).length) {
101
103
  console.warn('Параметры, которых нет в defaults, будут проигнорированы!');
102
104
  }
103
105
  return allowedParams;
@@ -180,6 +182,12 @@ function getNewItemData({ item, config, counter: argsCounter, salt, options }) {
180
182
  }
181
183
  return { data, counter, excludeIds };
182
184
  }
185
+ const getChangedParams = ({ initiatorItem, stateAndParams, itemsStateAndParams, }) => {
186
+ const allowableParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams);
187
+ const allowableActionParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams, { type: 'actionParams', returnPrefix: true });
188
+ return Object.assign(Object.assign({}, allowableParams), allowableActionParams);
189
+ };
190
+ exports.getChangedParams = getChangedParams;
183
191
  function changeGroupParams({ groupItemIds, initiatorId, initiatorItem, itemsStateAndParams, stateAndParams, config, unusedIds, }) {
184
192
  var _a;
185
193
  const meta = (0, shared_1.addGroupToQueue)({
@@ -192,9 +200,12 @@ function changeGroupParams({ groupItemIds, initiatorId, initiatorItem, itemsStat
192
200
  const currentItemParams = (_a = itemsStateAndParams[initiatorId]) === null || _a === void 0 ? void 0 : _a.params;
193
201
  for (const groupItem of initiatorItem.data.group) {
194
202
  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);
203
+ const changedParams = (0, exports.getChangedParams)({
204
+ initiatorItem: groupItem,
205
+ stateAndParams,
206
+ itemsStateAndParams,
207
+ });
208
+ updatedItems[groupItem.id] = changedParams;
198
209
  continue;
199
210
  }
200
211
  if (currentItemParams && currentItemParams[groupItem.id]) {
@@ -216,19 +227,37 @@ function changeGroupParams({ groupItemIds, initiatorId, initiatorItem, itemsStat
216
227
  }
217
228
  class UpdateManager {
218
229
  static addItem({ item, namespace = constants_1.DEFAULT_NAMESPACE, layout, config, options, }) {
219
- const layoutY = Math.max(0, ...config.layout.map(({ h, y }) => h + y));
220
- const saveDefaultLayout = (0, pick_1.default)(layout, ['h', 'w', 'x', 'y']);
221
230
  const salt = config.salt;
222
231
  const newItemData = getNewItemData({ item, config, salt, counter: config.counter, options });
223
232
  let counter = newItemData.counter;
224
233
  const newIdData = (0, get_new_id_1.getNewId)({ config, salt, counter, excludeIds: newItemData.excludeIds });
225
234
  counter = newIdData.counter;
226
235
  const newItem = Object.assign(Object.assign({}, item), { id: newIdData.id, data: newItemData.data, namespace });
227
- return (0, immutability_helper_1.default)(config, {
228
- items: { $push: [newItem] },
229
- layout: { $push: [Object.assign(Object.assign({}, saveDefaultLayout), { y: layoutY, i: newItem.id })] },
230
- counter: { $set: counter },
231
- });
236
+ const saveDefaultLayout = (0, pick_1.default)(layout, ['h', 'w', 'x', 'y']);
237
+ if (options.updateLayout) {
238
+ const byId = options.updateLayout.reduce((memo, t) => {
239
+ memo[t.i] = t;
240
+ return memo;
241
+ }, {});
242
+ const newLayout = [
243
+ ...config.layout.map((t) => (Object.assign(Object.assign({}, t), (byId[t.i] || {})))),
244
+ Object.assign(Object.assign({}, saveDefaultLayout), { i: newItem.id }),
245
+ ];
246
+ return (0, immutability_helper_1.default)(config, {
247
+ items: { $push: [newItem] },
248
+ layout: { $set: newLayout },
249
+ counter: { $set: counter },
250
+ });
251
+ }
252
+ else {
253
+ const layoutY = Math.max(0, ...config.layout.map(({ h, y }) => h + y));
254
+ const newLayoutItem = Object.assign(Object.assign({}, saveDefaultLayout), { y: layoutY, i: newItem.id });
255
+ return (0, immutability_helper_1.default)(config, {
256
+ items: { $push: [newItem] },
257
+ layout: { $push: [newLayoutItem] },
258
+ counter: { $set: counter },
259
+ });
260
+ }
232
261
  }
233
262
  static editItem({ item, namespace = constants_1.DEFAULT_NAMESPACE, config, options, }) {
234
263
  const itemIndex = config.items.findIndex(({ id }) => item.id === id);
@@ -336,8 +365,11 @@ class UpdateManager {
336
365
  });
337
366
  }
338
367
  if ('params' in stateAndParams) {
339
- const allowableParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams);
340
- const allowableActionParams = getAllowableChangedParams(initiatorItem, stateAndParams, itemsStateAndParams, { type: 'actionParams', returnPrefix: true });
368
+ const changedParams = (0, exports.getChangedParams)({
369
+ initiatorItem,
370
+ stateAndParams,
371
+ itemsStateAndParams,
372
+ });
341
373
  const tabId = (0, shared_1.isItemWithTabs)(initiatorItem)
342
374
  ? newTabId || (0, shared_1.resolveItemInnerId)({ item: initiatorItem, itemsStateAndParams })
343
375
  : undefined;
@@ -352,7 +384,7 @@ class UpdateManager {
352
384
  $unset: unusedIds,
353
385
  [initiatorId]: {
354
386
  $auto: Object.assign({ params: {
355
- [commandUpdateParams]: Object.assign(Object.assign({}, allowableParams), allowableActionParams),
387
+ [commandUpdateParams]: changedParams,
356
388
  } }, (hasState ? { state: { $set: stateAndParams.state } } : {})),
357
389
  },
358
390
  [shared_1.META_KEY]: { $set: meta },
@@ -1,4 +1,7 @@
1
1
  /// <reference types="react" />
2
- import { ActionPanelProps } from './types';
2
+ import { ActionPanelItem, ActionPanelProps } from './types';
3
3
  import './ActionPanel.css';
4
+ export declare const ActionPanelItemContainer: ({ item }: {
5
+ item: ActionPanelItem;
6
+ }) => JSX.Element;
4
7
  export declare const ActionPanel: (props: ActionPanelProps) => JSX.Element | null;
@@ -1,18 +1,21 @@
1
1
  import React from 'react';
2
2
  import { CSSTransition } from 'react-transition-group';
3
+ import { useDnDItemProps } from '../../hooks/useDnDItemProps';
3
4
  import { cn } from '../../utils/cn';
4
5
  import './ActionPanel.css';
5
6
  const b = cn('dashkit-action-panel');
7
+ export const ActionPanelItemContainer = ({ item }) => {
8
+ const dndProps = useDnDItemProps(item);
9
+ return (React.createElement("div", Object.assign({ role: "button", className: b('item', { draggable: Boolean(dndProps) }, item.className), onClick: item.onClick, "data-qa": item.qa }, dndProps),
10
+ React.createElement("div", { className: b('icon') }, item.icon),
11
+ React.createElement("div", { className: b('title'), title: item.title }, item.title)));
12
+ };
6
13
  export const ActionPanel = (props) => {
7
14
  var _a, _b;
8
15
  const isDisabled = (_a = props.disable) !== null && _a !== void 0 ? _a : false;
9
16
  const isAnimated = (_b = props.toggleAnimation) !== null && _b !== void 0 ? _b : false;
10
17
  const nodeRef = React.useRef(null);
11
- const content = (React.createElement("div", { ref: nodeRef, className: b(null, props.className) }, props.items.map((item) => {
12
- return (React.createElement("div", { role: "button", className: b('item', item.className), key: `dk-action-panel-${item.id}`, onClick: item.onClick, "data-qa": item.qa },
13
- React.createElement("div", { className: b('icon') }, item.icon),
14
- React.createElement("div", { className: b('title'), title: item.title }, item.title)));
15
- })));
18
+ const content = (React.createElement("div", { ref: nodeRef, className: b(null, props.className) }, props.items.map((item) => (React.createElement(ActionPanelItemContainer, { key: `dk-action-panel-${item.id}`, item: item })))));
16
19
  if (isAnimated) {
17
20
  return (React.createElement(CSSTransition, { in: !isDisabled, nodeRef: nodeRef, classNames: b(null), timeout: 300, unmountOnExit: true }, content));
18
21
  }
@@ -1,11 +1,13 @@
1
1
  import React from 'react';
2
+ import type { ItemDragProps } from '../../shared';
2
3
  export type ActionPanelItem = {
3
4
  id: string;
4
5
  icon: React.ReactNode;
5
6
  title: string;
6
- onClick?: () => void;
7
7
  className?: string;
8
8
  qa?: string;
9
+ onClick?: () => void;
10
+ dragProps?: ItemDragProps;
9
11
  };
10
12
  export type ActionPanelProps = {
11
13
  items: ActionPanelItem[];
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import type { Config, ConfigItem, GlobalParams, ItemsStateAndParams } from '../../shared';
3
- import { ContextProps, Plugin, SetConfigItem, SetItemOptions, Settings, SettingsProps } from '../../typings';
2
+ import type { Config, ConfigItem, GlobalParams, ItemDropProps, ItemsStateAndParams } from '../../shared';
3
+ import { ContextProps, 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 {
@@ -15,6 +15,7 @@ interface DashKitDefaultProps {
15
15
  config: Config;
16
16
  itemsStateAndParams: ItemsStateAndParams;
17
17
  }) => void;
18
+ onDrop: (dropProps: ItemDropProps) => void;
18
19
  defaultGlobalParams: GlobalParams;
19
20
  globalParams: GlobalParams;
20
21
  itemsStateAndParams: ItemsStateAndParams;
@@ -34,7 +35,7 @@ export declare class DashKit extends React.PureComponent<DashKitInnerProps> {
34
35
  item: SetConfigItem;
35
36
  namespace?: string;
36
37
  config: Config;
37
- options?: SetItemOptions;
38
+ options?: SetNewItemOptions;
38
39
  }): Config;
39
40
  static removeItem({ id, config, itemsStateAndParams, }: {
40
41
  id: string;
@@ -54,6 +54,7 @@ export class DashKit extends React.PureComponent {
54
54
  DashKit.defaultProps = {
55
55
  onItemEdit: noop,
56
56
  onChange: noop,
57
+ onDrop: noop,
57
58
  defaultGlobalParams: {},
58
59
  globalParams: {},
59
60
  itemsStateAndParams: {},
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { ItemDragProps } from '../../shared';
3
+ type DashKitDnDWrapperProps = {
4
+ dragImageSrc?: string;
5
+ onDragStart?: (dragProps: ItemDragProps) => void;
6
+ onDragEnd?: () => void;
7
+ children: React.ReactElement;
8
+ };
9
+ export declare const DashKitDnDWrapper: React.FC<DashKitDnDWrapperProps>;
10
+ export {};
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { DashKitDnDContext } from '../../context/DashKitContext';
3
+ const defaultImageSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
4
+ export const DashKitDnDWrapper = (props) => {
5
+ const [dragProps, setDragProps] = React.useState(null);
6
+ const dragImagePreview = React.useMemo(() => {
7
+ const img = new Image();
8
+ img.src = props.dragImageSrc || defaultImageSrc;
9
+ return img;
10
+ }, [props.dragImageSrc]);
11
+ const onDragStart = React.useCallback((_, itemDragProps) => {
12
+ var _a;
13
+ setDragProps(itemDragProps);
14
+ (_a = props.onDragStart) === null || _a === void 0 ? void 0 : _a.call(props, itemDragProps);
15
+ }, [setDragProps, props.onDragStart]);
16
+ const onDragEnd = React.useCallback((_) => {
17
+ var _a;
18
+ setDragProps(null);
19
+ (_a = props.onDragEnd) === null || _a === void 0 ? void 0 : _a.call(props);
20
+ }, [setDragProps, props.onDragEnd]);
21
+ const contextValue = React.useMemo(() => {
22
+ return {
23
+ dragProps,
24
+ dragImagePreview,
25
+ onDragStart,
26
+ onDragEnd,
27
+ };
28
+ }, [dragProps, dragImagePreview, onDragStart, onDragEnd]);
29
+ return (React.createElement(DashKitDnDContext.Provider, { value: contextValue }, props.children));
30
+ };
@@ -1,3 +1,3 @@
1
- declare const _default: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
2
- export default _default;
1
+ export default GridItemForwarderRef;
2
+ declare const GridItemForwarderRef: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
3
3
  import React from 'react';