@gravity-ui/dashkit 8.0.2 → 8.1.0-beta.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.
- package/README.md +1 -0
- package/build/cjs/components/ActionPanel/ActionPanel.d.ts +13 -1
- package/build/cjs/components/ActionPanel/ActionPanel.js +25 -6
- package/build/cjs/components/ActionPanel/types.d.ts +1 -0
- package/build/cjs/components/DashKit/DashKit.d.ts +10 -3
- package/build/cjs/components/DashKit/DashKit.js +2 -0
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +6 -0
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.js +24 -0
- package/build/cjs/components/GridItem/GridItem.css +7 -0
- package/build/cjs/components/GridItem/GridItem.d.ts +2 -2
- package/build/cjs/components/GridItem/GridItem.js +63 -4
- package/build/cjs/components/GridLayout/GridLayout.d.ts +3 -0
- package/build/cjs/components/GridLayout/GridLayout.js +90 -10
- package/build/cjs/components/Item/Item.css +1 -1
- package/build/cjs/components/Item/Item.d.ts +1 -0
- package/build/cjs/components/Item/Item.js +7 -1
- package/build/cjs/components/index.d.ts +1 -0
- package/build/cjs/components/index.js +1 -0
- package/build/cjs/constants/common.d.ts +2 -0
- package/build/cjs/constants/common.js +3 -1
- package/build/cjs/context/DashKitContext.d.ts +1 -0
- package/build/cjs/context/DashKitContext.js +3 -1
- package/build/cjs/hocs/prepareItem.d.ts +1 -0
- package/build/cjs/hocs/prepareItem.js +4 -2
- package/build/cjs/hocs/withContext.js +87 -6
- package/build/cjs/shared/constants/common.d.ts +1 -0
- package/build/cjs/shared/constants/common.js +2 -1
- package/build/cjs/typings/config.d.ts +3 -0
- package/build/cjs/typings/plugin.d.ts +1 -0
- package/build/cjs/utils/update-manager.d.ts +2 -2
- package/build/cjs/utils/update-manager.js +25 -7
- package/build/esm/components/ActionPanel/ActionPanel.d.ts +13 -1
- package/build/esm/components/ActionPanel/ActionPanel.js +23 -5
- package/build/esm/components/ActionPanel/types.d.ts +1 -0
- package/build/esm/components/DashKit/DashKit.d.ts +10 -3
- package/build/esm/components/DashKit/DashKit.js +2 -0
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +6 -0
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.js +19 -0
- package/build/esm/components/GridItem/GridItem.css +7 -0
- package/build/esm/components/GridItem/GridItem.d.ts +2 -2
- package/build/esm/components/GridItem/GridItem.js +63 -4
- package/build/esm/components/GridLayout/GridLayout.d.ts +3 -0
- package/build/esm/components/GridLayout/GridLayout.js +91 -11
- package/build/esm/components/Item/Item.css +1 -1
- package/build/esm/components/Item/Item.d.ts +1 -0
- package/build/esm/components/Item/Item.js +7 -1
- package/build/esm/components/index.d.ts +1 -0
- package/build/esm/components/index.js +1 -0
- package/build/esm/constants/common.d.ts +2 -0
- package/build/esm/constants/common.js +2 -0
- package/build/esm/context/DashKitContext.d.ts +1 -0
- package/build/esm/context/DashKitContext.js +2 -1
- package/build/esm/hocs/prepareItem.d.ts +1 -0
- package/build/esm/hocs/prepareItem.js +4 -2
- package/build/esm/hocs/withContext.js +88 -7
- package/build/esm/shared/constants/common.d.ts +1 -0
- package/build/esm/shared/constants/common.js +1 -0
- package/build/esm/typings/config.d.ts +3 -0
- package/build/esm/typings/plugin.d.ts +1 -0
- package/build/esm/utils/update-manager.d.ts +2 -2
- package/build/esm/utils/update-manager.js +25 -7
- package/package.json +1 -1
|
@@ -1,9 +1,47 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ReactGridLayout, { WidthProvider } from 'react-grid-layout';
|
|
3
|
-
import { OVERLAY_CONTROLS_CLASS_NAME } from '../../constants';
|
|
3
|
+
import { OVERLAY_CLASS_NAME, OVERLAY_CONTROLS_CLASS_NAME, TEMPORARY_ITEM_ID } from '../../constants';
|
|
4
4
|
import { DashKitContext } from '../../context/DashKitContext';
|
|
5
5
|
import GridItem from '../GridItem/GridItem';
|
|
6
|
-
|
|
6
|
+
class DragOverLayout extends ReactGridLayout {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.dragReset = () => {
|
|
10
|
+
if (this.dragEnterCounter) {
|
|
11
|
+
this.dragEnterCounter = 0;
|
|
12
|
+
this.removeDroppingPlaceholder();
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
componentDidMount() {
|
|
17
|
+
super.componentDidMount();
|
|
18
|
+
window.addEventListener('dragend', this.dragReset);
|
|
19
|
+
}
|
|
20
|
+
componentWillUnmount() {
|
|
21
|
+
window.removeEventListener('dragend', this.dragReset);
|
|
22
|
+
}
|
|
23
|
+
processGridItem(child, isDroppingItem) {
|
|
24
|
+
if (isDroppingItem) {
|
|
25
|
+
// Drop item from outside gets 0,0 droppingPosition
|
|
26
|
+
// centering cursor on newly creted grid item
|
|
27
|
+
// And cause grid-layout using it's own GridItem to make it look
|
|
28
|
+
// like overlay adding className
|
|
29
|
+
const gridItem = super.processGridItem(child, isDroppingItem);
|
|
30
|
+
if (!gridItem)
|
|
31
|
+
return null;
|
|
32
|
+
const { props } = gridItem;
|
|
33
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale } = props;
|
|
34
|
+
const leftOffset = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
35
|
+
const topOffset = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
36
|
+
return React.cloneElement(gridItem, {
|
|
37
|
+
className: OVERLAY_CLASS_NAME,
|
|
38
|
+
droppingPosition: Object.assign(Object.assign({}, props.droppingPosition), { left: props.droppingPosition.left - leftOffset, top: props.droppingPosition.top - topOffset }),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return super.processGridItem(child, isDroppingItem);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const Layout = WidthProvider(DragOverLayout); // eslint-disable-line new-cap
|
|
7
45
|
class GridLayout extends React.PureComponent {
|
|
8
46
|
constructor(props, context) {
|
|
9
47
|
super(props, context);
|
|
@@ -29,13 +67,38 @@ class GridLayout extends React.PureComponent {
|
|
|
29
67
|
return getItemsMeta(this.pluginsRefs);
|
|
30
68
|
};
|
|
31
69
|
this._onStart = () => {
|
|
70
|
+
if (this.temporaryLayout)
|
|
71
|
+
return;
|
|
32
72
|
this.setState({ isDragging: true });
|
|
33
73
|
};
|
|
34
74
|
this._onStop = (newLayout) => {
|
|
35
|
-
const { layoutChange } = this.context;
|
|
36
|
-
|
|
75
|
+
const { layoutChange, onDrop, temporaryLayout } = this.context;
|
|
76
|
+
if (temporaryLayout) {
|
|
77
|
+
onDrop === null || onDrop === void 0 ? void 0 : onDrop(newLayout, newLayout.find(({ i }) => i === TEMPORARY_ITEM_ID));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
layoutChange(newLayout);
|
|
81
|
+
}
|
|
37
82
|
this.setState({ isDragging: false });
|
|
38
83
|
};
|
|
84
|
+
this._onDropDragOver = (e) => {
|
|
85
|
+
const { editMode, onDropDragOver, temporaryLayout } = this.context;
|
|
86
|
+
if (!editMode) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
const result = onDropDragOver(e);
|
|
90
|
+
if (temporaryLayout) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
};
|
|
95
|
+
this._onDrop = (layout, item, e) => {
|
|
96
|
+
const { editMode, temporaryLayout, onDrop } = this.context;
|
|
97
|
+
if (!editMode && temporaryLayout) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
onDrop === null || onDrop === void 0 ? void 0 : onDrop(layout, item, e);
|
|
101
|
+
};
|
|
39
102
|
this.pluginsRefs = [];
|
|
40
103
|
this.state = {
|
|
41
104
|
isDragging: false,
|
|
@@ -68,16 +131,33 @@ class GridLayout extends React.PureComponent {
|
|
|
68
131
|
this._timeout = setTimeout(() => this.reloadItems(), reloadIntervalRemains <= 0 ? autoupdateIntervalMs : reloadIntervalRemains);
|
|
69
132
|
}
|
|
70
133
|
}
|
|
134
|
+
renderTemporaryPlaceholder() {
|
|
135
|
+
const { temporaryLayout, dragOverPlugin, noOverlay, draggableHandleClassName } = this.context;
|
|
136
|
+
if (!temporaryLayout) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
const id = TEMPORARY_ITEM_ID;
|
|
140
|
+
const type = dragOverPlugin.type;
|
|
141
|
+
return (React.createElement(GridItem, { key: id, id: id, item: { id, type, data: {} }, layout: temporaryLayout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, isPlaceholder: true, noOverlay: noOverlay, withCustomHandle: Boolean(draggableHandleClassName), overlayControls: this.props.overlayControls }));
|
|
142
|
+
}
|
|
71
143
|
render() {
|
|
72
|
-
const { layout, config, registerManager, editMode, noOverlay, draggableHandleClassName } = this.context;
|
|
144
|
+
const { layout, temporaryLayout, config, registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
|
|
73
145
|
this.pluginsRefs.length = config.items.length;
|
|
74
|
-
return (React.createElement(Layout, Object.assign({}, registerManager.gridLayout, { layout: layout, isDraggable: editMode, isResizable: editMode, onDragStart: this._onStart, onDragStop: this._onStop, onResizeStart: this._onStart, onResizeStop: this._onStop }, (draggableHandleClassName
|
|
146
|
+
return (React.createElement(Layout, Object.assign({}, registerManager.gridLayout, { layout: temporaryLayout || layout, isDraggable: editMode, isResizable: editMode, onDragStart: this._onStart, onDragStop: this._onStop, onResizeStart: this._onStart, onResizeStop: this._onStop }, (draggableHandleClassName
|
|
75
147
|
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
76
|
-
: null),
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
148
|
+
: null), (outerDnDEnable
|
|
149
|
+
? {
|
|
150
|
+
isDroppable: true,
|
|
151
|
+
onDropDragOver: this._onDropDragOver,
|
|
152
|
+
onDrop: this._onDrop,
|
|
153
|
+
}
|
|
154
|
+
: null), { draggableCancel: `.${OVERLAY_CONTROLS_CLASS_NAME}` }),
|
|
155
|
+
config.items.map((item, i) => {
|
|
156
|
+
return (React.createElement(GridItem, { forwardedPluginRef: (pluginRef) => {
|
|
157
|
+
this.pluginsRefs[i] = pluginRef;
|
|
158
|
+
}, key: item.id, id: item.id, item: item, layout: temporaryLayout || layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: this.state.isDragging, noOverlay: noOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), overlayControls: this.props.overlayControls }));
|
|
159
|
+
}),
|
|
160
|
+
this.renderTemporaryPlaceholder()));
|
|
81
161
|
}
|
|
82
162
|
}
|
|
83
163
|
GridLayout.contextType = DashKitContext;
|
|
@@ -56,6 +56,7 @@ declare const _default: {
|
|
|
56
56
|
width: PropTypes.Requireable<number>;
|
|
57
57
|
height: PropTypes.Requireable<number>;
|
|
58
58
|
transform: PropTypes.Requireable<string>;
|
|
59
|
+
isPlaceholder: PropTypes.Requireable<boolean>;
|
|
59
60
|
forwardedPluginRef: PropTypes.Requireable<any>;
|
|
60
61
|
};
|
|
61
62
|
contextType: React.Context<any>;
|
|
@@ -5,11 +5,16 @@ import { cn } from '../../utils/cn';
|
|
|
5
5
|
import './Item.css';
|
|
6
6
|
const b = cn('dashkit-item');
|
|
7
7
|
// TODO: getDerivedStateFromError и заглушка с ошибкой
|
|
8
|
-
const Item = ({ registerManager, rendererProps, type, forwardedPluginRef }) => {
|
|
8
|
+
const Item = ({ registerManager, rendererProps, type, isPlaceholder, forwardedPluginRef }) => {
|
|
9
|
+
var _a, _b;
|
|
9
10
|
if (!registerManager.check(type)) {
|
|
10
11
|
console.warn(`type [${type}] не зарегистрирован`);
|
|
11
12
|
return null;
|
|
12
13
|
}
|
|
14
|
+
if (isPlaceholder) {
|
|
15
|
+
return (React.createElement("div", { className: b('placeholder') }, ((_b = (_a = registerManager
|
|
16
|
+
.getItem(type)).placeholderRenderer) === null || _b === void 0 ? void 0 : _b.call(_a, rendererProps, forwardedPluginRef)) || null));
|
|
17
|
+
}
|
|
13
18
|
return (React.createElement("div", { className: b('renderer') }, registerManager.getItem(type).renderer(rendererProps, forwardedPluginRef)));
|
|
14
19
|
};
|
|
15
20
|
Item.propTypes = {
|
|
@@ -17,5 +22,6 @@ Item.propTypes = {
|
|
|
17
22
|
rendererProps: PropTypes.object,
|
|
18
23
|
registerManager: PropTypes.object,
|
|
19
24
|
type: PropTypes.string,
|
|
25
|
+
isPlaceholder: PropTypes.bool,
|
|
20
26
|
};
|
|
21
27
|
export default prepareItem(Item);
|
|
@@ -2,3 +2,4 @@ export * from './DashKit';
|
|
|
2
2
|
export type { OverlayControlItem, PreparedCopyItemOptions } from './OverlayControls/OverlayControls';
|
|
3
3
|
export * from './ActionPanel/ActionPanel';
|
|
4
4
|
export type { ActionPanelItem, ActionPanelProps } from './ActionPanel/types';
|
|
5
|
+
export * from './DashKitDnDWrapper/DashKitDnDWrapper';
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const COPIED_WIDGET_STORE_KEY = "dashCopiedItem";
|
|
2
2
|
export declare const DEFAULT_NAMESPACE = "default";
|
|
3
3
|
export declare const OVERLAY_CONTROLS_CLASS_NAME = "dashkit-overlay-controls";
|
|
4
|
+
export declare const OVERLAY_CLASS_NAME = "dashkit-grid-item__overlay";
|
|
5
|
+
export declare const TEMPORARY_ITEM_ID = "__dropping-elem__";
|
|
4
6
|
export declare const MenuItems: {
|
|
5
7
|
readonly Copy: "copy";
|
|
6
8
|
readonly Delete: "delete";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const COPIED_WIDGET_STORE_KEY = 'dashCopiedItem';
|
|
2
2
|
export const DEFAULT_NAMESPACE = 'default';
|
|
3
3
|
export const OVERLAY_CONTROLS_CLASS_NAME = 'dashkit-overlay-controls';
|
|
4
|
+
export const OVERLAY_CLASS_NAME = 'dashkit-grid-item__overlay';
|
|
5
|
+
export const TEMPORARY_ITEM_ID = '__dropping-elem__';
|
|
4
6
|
export const MenuItems = {
|
|
5
7
|
Copy: 'copy',
|
|
6
8
|
Delete: 'delete',
|
|
@@ -56,6 +56,7 @@ export function prepareItem(Component: any): {
|
|
|
56
56
|
width: PropTypes.Requireable<number>;
|
|
57
57
|
height: PropTypes.Requireable<number>;
|
|
58
58
|
transform: PropTypes.Requireable<string>;
|
|
59
|
+
isPlaceholder: PropTypes.Requireable<boolean>;
|
|
59
60
|
forwardedPluginRef: PropTypes.Requireable<any>;
|
|
60
61
|
};
|
|
61
62
|
contextType: React.Context<any>;
|
|
@@ -22,7 +22,7 @@ export function prepareItem(Component) {
|
|
|
22
22
|
return true;
|
|
23
23
|
}
|
|
24
24
|
render() {
|
|
25
|
-
const { id, width, height, item, adjustWidgetLayout, layout } = this.props;
|
|
25
|
+
const { id, width, height, item, adjustWidgetLayout, layout, isPlaceholder } = this.props;
|
|
26
26
|
const { itemsState, itemsParams, registerManager, settings, context, editMode } = this.context;
|
|
27
27
|
const { type, data, defaults, namespace } = item;
|
|
28
28
|
const rendererProps = {
|
|
@@ -41,8 +41,9 @@ export function prepareItem(Component) {
|
|
|
41
41
|
layout,
|
|
42
42
|
gridLayout: registerManager.gridLayout,
|
|
43
43
|
adjustWidgetLayout,
|
|
44
|
+
isPlaceholder,
|
|
44
45
|
};
|
|
45
|
-
return (React.createElement(Component, { forwardedPluginRef: this.props.forwardedPluginRef, rendererProps: rendererProps, registerManager: registerManager, type: type }));
|
|
46
|
+
return (React.createElement(Component, { forwardedPluginRef: this.props.forwardedPluginRef, rendererProps: rendererProps, registerManager: registerManager, type: type, isPlaceholder: isPlaceholder }));
|
|
46
47
|
}
|
|
47
48
|
},
|
|
48
49
|
_a.propTypes = {
|
|
@@ -54,6 +55,7 @@ export function prepareItem(Component) {
|
|
|
54
55
|
width: PropTypes.number,
|
|
55
56
|
height: PropTypes.number,
|
|
56
57
|
transform: PropTypes.string,
|
|
58
|
+
isPlaceholder: PropTypes.bool,
|
|
57
59
|
forwardedPluginRef: PropTypes.any,
|
|
58
60
|
},
|
|
59
61
|
_a.contextType = DashKitContext,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import isEqual from 'lodash/isEqual';
|
|
3
|
-
import {
|
|
3
|
+
import { TEMPORARY_ITEM_ID } from '../constants/common';
|
|
4
|
+
import { DashKitContext, DashKitDnDContext } from '../context/DashKitContext';
|
|
4
5
|
import { getItemsParams, getItemsState } from '../shared';
|
|
5
6
|
import { UpdateManager } from '../utils';
|
|
6
7
|
function useMemoStateContext(props) {
|
|
@@ -11,6 +12,10 @@ function useMemoStateContext(props) {
|
|
|
11
12
|
// (высота) из конфига будет запоминаться в originalLayouts, новое значение высоты в adjustedLayouts
|
|
12
13
|
const originalLayouts = React.useRef({});
|
|
13
14
|
const adjustedLayouts = React.useRef({});
|
|
15
|
+
const [temporaryLayout, setTemporaryLayout] = React.useState(null);
|
|
16
|
+
const resetTemporaryLayout = React.useCallback(() => setTemporaryLayout(null), [setTemporaryLayout]);
|
|
17
|
+
const dndContext = React.useContext(DashKitDnDContext);
|
|
18
|
+
const outerDnDEnable = Boolean(dndContext);
|
|
14
19
|
// TODO: need move originalLayouts, adjustedLayouts to state
|
|
15
20
|
const [layoutUpdateCounter, forceUpdateLayout] = React.useState(0);
|
|
16
21
|
const onChange = React.useCallback(({ config = props.config, itemsStateAndParams = props.itemsStateAndParams }) => {
|
|
@@ -41,12 +46,27 @@ function useMemoStateContext(props) {
|
|
|
41
46
|
}
|
|
42
47
|
}, [props.config, onChange]);
|
|
43
48
|
const onItemRemove = React.useCallback((id) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
if (id === TEMPORARY_ITEM_ID) {
|
|
50
|
+
resetTemporaryLayout();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
if (temporaryLayout) {
|
|
54
|
+
setTemporaryLayout(temporaryLayout.filter(({ i }) => i !== id));
|
|
55
|
+
}
|
|
56
|
+
onChange(UpdateManager.removeItem({
|
|
57
|
+
id,
|
|
58
|
+
config: props.config,
|
|
59
|
+
itemsStateAndParams: props.itemsStateAndParams,
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
}, [
|
|
63
|
+
props.config,
|
|
64
|
+
props.itemsStateAndParams,
|
|
65
|
+
temporaryLayout,
|
|
66
|
+
onChange,
|
|
67
|
+
setTemporaryLayout,
|
|
68
|
+
resetTemporaryLayout,
|
|
69
|
+
]);
|
|
50
70
|
const onItemStateAndParamsChange = React.useCallback((id, stateAndParams, options) => {
|
|
51
71
|
onChange({
|
|
52
72
|
itemsStateAndParams: UpdateManager.changeStateAndParams({
|
|
@@ -120,11 +140,62 @@ function useMemoStateContext(props) {
|
|
|
120
140
|
const reloadItems = React.useCallback((pluginsRefs, data) => {
|
|
121
141
|
pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
|
|
122
142
|
}, []);
|
|
143
|
+
const draggedPluginRef = React.useRef(dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragPluginType);
|
|
144
|
+
React.useEffect(() => {
|
|
145
|
+
if (!(dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragPluginType) && !temporaryLayout) {
|
|
146
|
+
draggedPluginRef.current = null;
|
|
147
|
+
}
|
|
148
|
+
else if (dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragPluginType) {
|
|
149
|
+
draggedPluginRef.current = dndContext.dragPluginType;
|
|
150
|
+
}
|
|
151
|
+
}, [draggedPluginRef, dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragPluginType, temporaryLayout]);
|
|
152
|
+
const dndPluginType = draggedPluginRef.current || (dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragPluginType);
|
|
153
|
+
const dragOverPlugin = React.useMemo(() => {
|
|
154
|
+
const pluginType = dndPluginType;
|
|
155
|
+
if (pluginType === null && temporaryLayout === null)
|
|
156
|
+
return null;
|
|
157
|
+
if (props.registerManager.check(pluginType)) {
|
|
158
|
+
return props.registerManager.getItem(pluginType);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// eslint-disable-next-line no-console
|
|
162
|
+
console.error(`Uknown pluginType: ${pluginType}`);
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}, [dndPluginType, props.registerManager, temporaryLayout]);
|
|
166
|
+
const onDropDragOver = React.useCallback(() => {
|
|
167
|
+
if (temporaryLayout) {
|
|
168
|
+
resetTemporaryLayout();
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
if (dragOverPlugin === null || dragOverPlugin === void 0 ? void 0 : dragOverPlugin.defaultLayout) {
|
|
172
|
+
const { h = 3, w = 3 } = dragOverPlugin.defaultLayout;
|
|
173
|
+
return { h, w };
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}, [resetTemporaryLayout, temporaryLayout, dragOverPlugin]);
|
|
177
|
+
const onDrop = React.useCallback((newLayout, item) => {
|
|
178
|
+
setTemporaryLayout(newLayout);
|
|
179
|
+
const { i, w, h, x, y } = item;
|
|
180
|
+
props.onDrop({
|
|
181
|
+
newLayout: newLayout.reduce((memo, l) => {
|
|
182
|
+
if (l.i !== i) {
|
|
183
|
+
memo.push({ i: l.i, w: l.w, h: l.h, x: l.x, y: l.y });
|
|
184
|
+
}
|
|
185
|
+
return memo;
|
|
186
|
+
}, []),
|
|
187
|
+
itemLayout: { w, h, x, y },
|
|
188
|
+
pluginType: dndPluginType,
|
|
189
|
+
commit: resetTemporaryLayout,
|
|
190
|
+
});
|
|
191
|
+
}, [dndPluginType, props.onDrop]);
|
|
123
192
|
return React.useMemo(() => ({
|
|
124
193
|
layout: resultLayout,
|
|
194
|
+
temporaryLayout,
|
|
125
195
|
config: props.config,
|
|
126
196
|
context: props.context,
|
|
127
197
|
noOverlay: props.noOverlay,
|
|
198
|
+
focusable: props.focusable,
|
|
128
199
|
defaultGlobalParams: props.globalParams,
|
|
129
200
|
globalParams: props.globalParams,
|
|
130
201
|
editMode: props.editMode,
|
|
@@ -134,6 +205,8 @@ function useMemoStateContext(props) {
|
|
|
134
205
|
registerManager: props.registerManager,
|
|
135
206
|
onItemStateAndParamsChange,
|
|
136
207
|
removeItem: onItemRemove,
|
|
208
|
+
onDrop,
|
|
209
|
+
onDropDragOver,
|
|
137
210
|
editItem: props.onItemEdit,
|
|
138
211
|
layoutChange: onLayoutChange,
|
|
139
212
|
getItemsMeta,
|
|
@@ -142,11 +215,15 @@ function useMemoStateContext(props) {
|
|
|
142
215
|
revertToOriginalLayout,
|
|
143
216
|
forwardedMetaRef: props.forwardedMetaRef,
|
|
144
217
|
draggableHandleClassName: props.draggableHandleClassName,
|
|
218
|
+
outerDnDEnable,
|
|
219
|
+
dragOverPlugin,
|
|
145
220
|
}), [
|
|
146
221
|
resultLayout,
|
|
222
|
+
temporaryLayout,
|
|
147
223
|
props.config,
|
|
148
224
|
props.context,
|
|
149
225
|
props.noOverlay,
|
|
226
|
+
props.focusable,
|
|
150
227
|
props.globalParams,
|
|
151
228
|
props.editMode,
|
|
152
229
|
props.settings,
|
|
@@ -155,6 +232,8 @@ function useMemoStateContext(props) {
|
|
|
155
232
|
props.registerManager,
|
|
156
233
|
onItemStateAndParamsChange,
|
|
157
234
|
onItemRemove,
|
|
235
|
+
onDrop,
|
|
236
|
+
onDropDragOver,
|
|
158
237
|
props.onItemEdit,
|
|
159
238
|
onLayoutChange,
|
|
160
239
|
getItemsMeta,
|
|
@@ -163,6 +242,8 @@ function useMemoStateContext(props) {
|
|
|
163
242
|
revertToOriginalLayout,
|
|
164
243
|
props.forwardedMetaRef,
|
|
165
244
|
props.draggableHandleClassName,
|
|
245
|
+
outerDnDEnable,
|
|
246
|
+
dragOverPlugin,
|
|
166
247
|
]);
|
|
167
248
|
}
|
|
168
249
|
export function withContext(Component) {
|
|
@@ -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
1
|
import type { Config, ConfigItem, ItemStateAndParams, ItemStateAndParamsChangeOptions, ItemsStateAndParams } from '../shared';
|
|
2
|
-
import type { AddConfigItem, SetItemOptions, WidgetLayout } from '../typings';
|
|
2
|
+
import type { AddConfigItem, SetItemOptions, SetNewItemOptions, WidgetLayout } from '../typings';
|
|
3
3
|
import { RegisterManagerPluginLayout } from './register-manager';
|
|
4
4
|
interface RemoveItemArg {
|
|
5
5
|
id: string;
|
|
@@ -19,7 +19,7 @@ export declare class UpdateManager {
|
|
|
19
19
|
namespace: string;
|
|
20
20
|
layout: RegisterManagerPluginLayout;
|
|
21
21
|
config: Config;
|
|
22
|
-
options:
|
|
22
|
+
options: SetNewItemOptions;
|
|
23
23
|
}): Config;
|
|
24
24
|
static editItem({ item, namespace, config, options, }: {
|
|
25
25
|
item: ConfigItem;
|
|
@@ -212,19 +212,37 @@ function changeGroupParams({ groupItemIds, initiatorId, initiatorItem, itemsStat
|
|
|
212
212
|
}
|
|
213
213
|
export class UpdateManager {
|
|
214
214
|
static addItem({ item, namespace = DEFAULT_NAMESPACE, layout, config, options, }) {
|
|
215
|
-
const layoutY = Math.max(0, ...config.layout.map(({ h, y }) => h + y));
|
|
216
|
-
const saveDefaultLayout = pick(layout, ['h', 'w', 'x', 'y']);
|
|
217
215
|
const salt = config.salt;
|
|
218
216
|
const newItemData = getNewItemData({ item, config, salt, counter: config.counter, options });
|
|
219
217
|
let counter = newItemData.counter;
|
|
220
218
|
const newIdData = getNewId({ config, salt, counter, excludeIds: newItemData.excludeIds });
|
|
221
219
|
counter = newIdData.counter;
|
|
222
220
|
const newItem = Object.assign(Object.assign({}, item), { id: newIdData.id, data: newItemData.data, namespace });
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
221
|
+
const saveDefaultLayout = pick(layout, ['h', 'w', 'x', 'y']);
|
|
222
|
+
if (options.updateLayout) {
|
|
223
|
+
const byId = options.updateLayout.reduce((memo, t) => {
|
|
224
|
+
memo[t.i] = t;
|
|
225
|
+
return memo;
|
|
226
|
+
}, {});
|
|
227
|
+
const newLayout = [
|
|
228
|
+
...config.layout.map((t) => (Object.assign(Object.assign({}, t), (byId[t.i] || {})))),
|
|
229
|
+
Object.assign(Object.assign({}, saveDefaultLayout), { i: newItem.id }),
|
|
230
|
+
];
|
|
231
|
+
return update(config, {
|
|
232
|
+
items: { $push: [newItem] },
|
|
233
|
+
layout: { $set: newLayout },
|
|
234
|
+
counter: { $set: counter },
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
const layoutY = Math.max(0, ...config.layout.map(({ h, y }) => h + y));
|
|
239
|
+
const newLayoutItem = Object.assign(Object.assign({}, saveDefaultLayout), { y: layoutY, i: newItem.id });
|
|
240
|
+
return update(config, {
|
|
241
|
+
items: { $push: [newItem] },
|
|
242
|
+
layout: { $push: [newLayoutItem] },
|
|
243
|
+
counter: { $set: counter },
|
|
244
|
+
});
|
|
245
|
+
}
|
|
228
246
|
}
|
|
229
247
|
static editItem({ item, namespace = DEFAULT_NAMESPACE, config, options, }) {
|
|
230
248
|
const itemIndex = config.items.findIndex(({ id }) => item.id === id);
|