@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.
- package/README.md +95 -0
- package/build/cjs/components/ActionPanel/ActionPanel.d.ts +4 -1
- package/build/cjs/components/ActionPanel/ActionPanel.js +10 -6
- package/build/cjs/components/ActionPanel/types.d.ts +3 -1
- package/build/cjs/components/DashKit/DashKit.d.ts +4 -3
- package/build/cjs/components/DashKit/DashKit.js +1 -0
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +10 -0
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.js +35 -0
- package/build/cjs/components/GridItem/GridItem.d.ts +2 -2
- package/build/cjs/components/GridItem/GridItem.js +8 -5
- package/build/cjs/components/GridLayout/GridLayout.d.ts +3 -0
- package/build/cjs/components/GridLayout/GridLayout.js +51 -11
- package/build/cjs/components/GridLayout/ReactGridLayout.d.ts +3 -0
- package/build/cjs/components/GridLayout/ReactGridLayout.js +49 -0
- 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/OverlayControls/OverlayControls.js +2 -2
- package/build/cjs/components/index.d.ts +1 -0
- package/build/cjs/components/index.js +1 -0
- package/build/cjs/constants/common.d.ts +4 -0
- package/build/cjs/constants/common.js +5 -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 +84 -6
- package/build/cjs/hooks/useDnDItemProps.d.ts +10 -0
- package/build/cjs/hooks/useDnDItemProps.js +30 -0
- package/build/cjs/shared/constants/common.d.ts +1 -0
- package/build/cjs/shared/constants/common.js +2 -1
- package/build/cjs/shared/modules/state-and-params.d.ts +2 -1
- package/build/cjs/shared/modules/state-and-params.js +18 -4
- package/build/cjs/shared/types/common.d.ts +15 -0
- 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 +10 -3
- package/build/cjs/utils/update-manager.js +52 -20
- package/build/esm/components/ActionPanel/ActionPanel.d.ts +4 -1
- package/build/esm/components/ActionPanel/ActionPanel.js +8 -5
- package/build/esm/components/ActionPanel/types.d.ts +3 -1
- package/build/esm/components/DashKit/DashKit.d.ts +4 -3
- package/build/esm/components/DashKit/DashKit.js +1 -0
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +10 -0
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.js +30 -0
- package/build/esm/components/GridItem/GridItem.d.ts +2 -2
- package/build/esm/components/GridItem/GridItem.js +8 -5
- package/build/esm/components/GridLayout/GridLayout.d.ts +3 -0
- package/build/esm/components/GridLayout/GridLayout.js +52 -12
- package/build/esm/components/GridLayout/ReactGridLayout.d.ts +3 -0
- package/build/esm/components/GridLayout/ReactGridLayout.js +45 -0
- 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/OverlayControls/OverlayControls.js +2 -2
- package/build/esm/components/index.d.ts +1 -0
- package/build/esm/components/index.js +1 -0
- package/build/esm/constants/common.d.ts +4 -0
- package/build/esm/constants/common.js +4 -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 +85 -7
- package/build/esm/hooks/useDnDItemProps.d.ts +10 -0
- package/build/esm/hooks/useDnDItemProps.js +25 -0
- package/build/esm/shared/constants/common.d.ts +1 -0
- package/build/esm/shared/constants/common.js +1 -0
- package/build/esm/shared/modules/state-and-params.d.ts +2 -1
- package/build/esm/shared/modules/state-and-params.js +18 -4
- package/build/esm/shared/types/common.d.ts +15 -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 +10 -3
- package/build/esm/utils/update-manager.js +50 -19
- package/package.json +1 -1
|
@@ -56,9 +56,9 @@ class GridItem extends React.PureComponent {
|
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
renderOverlay() {
|
|
59
|
-
const { overlayControls } = this.props;
|
|
59
|
+
const { overlayControls, isPlaceholder } = this.props;
|
|
60
60
|
const { editMode } = this.context;
|
|
61
|
-
if (!editMode || this.props.item.data._editActive) {
|
|
61
|
+
if (!editMode || this.props.item.data._editActive || isPlaceholder) {
|
|
62
62
|
return null;
|
|
63
63
|
}
|
|
64
64
|
const { item } = this.props;
|
|
@@ -70,7 +70,7 @@ class GridItem extends React.PureComponent {
|
|
|
70
70
|
render() {
|
|
71
71
|
// из-за бага, что Grid Items unmounts при изменении static, isDraggable, isResaizable
|
|
72
72
|
// https://github.com/STRML/react-grid-layout/issues/721
|
|
73
|
-
const { style, onMouseDown, onMouseUp, onTouchEnd, onTouchStart, children, className, isDragging, noOverlay, focusable, withCustomHandle, } = this.props;
|
|
73
|
+
const { style, onMouseDown, onMouseUp, onTouchEnd, onTouchStart, children, className, isDragging, noOverlay, focusable, withCustomHandle, isPlaceholder, } = this.props;
|
|
74
74
|
const { editMode } = this.context;
|
|
75
75
|
const width = Number.parseInt(style.width, 10);
|
|
76
76
|
const height = Number.parseInt(style.height, 10);
|
|
@@ -95,7 +95,7 @@ class GridItem extends React.PureComponent {
|
|
|
95
95
|
}
|
|
96
96
|
: {})),
|
|
97
97
|
React.createElement("div", { className: b('item', { editMode: editMode && !_editActive && !noOverlay }) },
|
|
98
|
-
React.createElement(Item, { id: this.props.id, item: this.props.item, shouldItemUpdate: !isDragging, width: width, height: height, transform: transform, adjustWidgetLayout: this.props.adjustWidgetLayout, layout: this.props.layout, forwardedPluginRef: this.props.forwardedPluginRef })),
|
|
98
|
+
React.createElement(Item, { id: this.props.id, item: this.props.item, shouldItemUpdate: !isDragging, width: width, height: height, transform: transform, isPlaceholder: isPlaceholder, adjustWidgetLayout: this.props.adjustWidgetLayout, layout: this.props.layout, forwardedPluginRef: this.props.forwardedPluginRef })),
|
|
99
99
|
!noOverlay && this.renderOverlay(),
|
|
100
100
|
preparedChildren));
|
|
101
101
|
}
|
|
@@ -109,6 +109,7 @@ GridItem.propTypes = {
|
|
|
109
109
|
overlayControls: PropTypes.object,
|
|
110
110
|
forwardedRef: PropTypes.any,
|
|
111
111
|
forwardedPluginRef: PropTypes.any,
|
|
112
|
+
isPlaceholder: PropTypes.bool,
|
|
112
113
|
// from react-grid-layout:
|
|
113
114
|
children: PropTypes.node,
|
|
114
115
|
className: PropTypes.string,
|
|
@@ -122,6 +123,8 @@ GridItem.propTypes = {
|
|
|
122
123
|
onTouchStart: PropTypes.func,
|
|
123
124
|
};
|
|
124
125
|
GridItem.contextType = DashKitContext;
|
|
125
|
-
|
|
126
|
+
const GridItemForwarderRef = React.forwardRef((props, ref) => {
|
|
126
127
|
return React.createElement(GridItem, Object.assign({}, props, { forwardedRef: ref }));
|
|
127
128
|
});
|
|
129
|
+
GridItemForwarderRef.displayName = 'forwardRef(GridItem)';
|
|
130
|
+
export default GridItemForwarderRef;
|
|
@@ -21,6 +21,9 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
21
21
|
reloadItems(): void;
|
|
22
22
|
_onStart: () => void;
|
|
23
23
|
_onStop: (newLayout: any) => void;
|
|
24
|
+
_onDropDragOver: (e: any) => any;
|
|
25
|
+
_onDrop: (layout: any, item: any, e: any) => false | undefined;
|
|
26
|
+
renderTemporaryPlaceholder(): JSX.Element | null;
|
|
24
27
|
render(): JSX.Element;
|
|
25
28
|
}
|
|
26
29
|
import React from 'react';
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import
|
|
3
|
-
import { OVERLAY_CONTROLS_CLASS_NAME } from '../../constants';
|
|
2
|
+
import { OVERLAY_CONTROLS_CLASS_NAME, TEMPORARY_ITEM_ID } from '../../constants';
|
|
4
3
|
import { DashKitContext } from '../../context/DashKitContext';
|
|
5
4
|
import GridItem from '../GridItem/GridItem';
|
|
6
|
-
|
|
5
|
+
import { Layout } from './ReactGridLayout';
|
|
7
6
|
class GridLayout extends React.PureComponent {
|
|
8
7
|
constructor(props, context) {
|
|
9
8
|
super(props, context);
|
|
@@ -29,13 +28,37 @@ class GridLayout extends React.PureComponent {
|
|
|
29
28
|
return getItemsMeta(this.pluginsRefs);
|
|
30
29
|
};
|
|
31
30
|
this._onStart = () => {
|
|
31
|
+
if (this.temporaryLayout)
|
|
32
|
+
return;
|
|
32
33
|
this.setState({ isDragging: true });
|
|
33
34
|
};
|
|
34
35
|
this._onStop = (newLayout) => {
|
|
35
|
-
const { layoutChange } = this.context;
|
|
36
|
-
|
|
36
|
+
const { layoutChange, onDrop, temporaryLayout } = this.context;
|
|
37
|
+
if (temporaryLayout) {
|
|
38
|
+
onDrop === null || onDrop === void 0 ? void 0 : onDrop(newLayout, newLayout.find(({ i }) => i === TEMPORARY_ITEM_ID));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
layoutChange(newLayout);
|
|
42
|
+
}
|
|
37
43
|
this.setState({ isDragging: false });
|
|
38
44
|
};
|
|
45
|
+
this._onDropDragOver = (e) => {
|
|
46
|
+
const { editMode, dragOverPlugin, onDropDragOver } = this.context;
|
|
47
|
+
if (!editMode || !dragOverPlugin) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return onDropDragOver(e);
|
|
51
|
+
};
|
|
52
|
+
this._onDrop = (layout, item, e) => {
|
|
53
|
+
if (!item) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
const { editMode, onDrop } = this.context;
|
|
57
|
+
if (!editMode) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
onDrop === null || onDrop === void 0 ? void 0 : onDrop(layout, item, e);
|
|
61
|
+
};
|
|
39
62
|
this.pluginsRefs = [];
|
|
40
63
|
this.state = {
|
|
41
64
|
isDragging: false,
|
|
@@ -68,16 +91,33 @@ class GridLayout extends React.PureComponent {
|
|
|
68
91
|
this._timeout = setTimeout(() => this.reloadItems(), reloadIntervalRemains <= 0 ? autoupdateIntervalMs : reloadIntervalRemains);
|
|
69
92
|
}
|
|
70
93
|
}
|
|
94
|
+
renderTemporaryPlaceholder() {
|
|
95
|
+
const { temporaryLayout, noOverlay, draggableHandleClassName } = this.context;
|
|
96
|
+
if (!temporaryLayout || !temporaryLayout.dragProps) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
const id = TEMPORARY_ITEM_ID;
|
|
100
|
+
const { type } = temporaryLayout.dragProps;
|
|
101
|
+
return (React.createElement(GridItem, { 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 }));
|
|
102
|
+
}
|
|
71
103
|
render() {
|
|
72
|
-
const { layout, config, registerManager, editMode, noOverlay, focusable, draggableHandleClassName, } = this.context;
|
|
104
|
+
const { layout, temporaryLayout, config, registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, } = this.context;
|
|
73
105
|
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
|
|
106
|
+
return (React.createElement(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
|
|
75
107
|
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
76
|
-
: null),
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
108
|
+
: null), (outerDnDEnable
|
|
109
|
+
? {
|
|
110
|
+
isDroppable: true,
|
|
111
|
+
onDropDragOver: this._onDropDragOver,
|
|
112
|
+
onDrop: this._onDrop,
|
|
113
|
+
}
|
|
114
|
+
: null), { draggableCancel: `.${OVERLAY_CONTROLS_CLASS_NAME}` }),
|
|
115
|
+
config.items.map((item, i) => {
|
|
116
|
+
return (React.createElement(GridItem, { forwardedPluginRef: (pluginRef) => {
|
|
117
|
+
this.pluginsRefs[i] = pluginRef;
|
|
118
|
+
}, 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 }));
|
|
119
|
+
}),
|
|
120
|
+
this.renderTemporaryPlaceholder()));
|
|
81
121
|
}
|
|
82
122
|
}
|
|
83
123
|
GridLayout.contextType = DashKitContext;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactGridLayout, { WidthProvider } from 'react-grid-layout';
|
|
3
|
+
import { OVERLAY_CLASS_NAME } from '../../constants';
|
|
4
|
+
class DragOverLayout extends ReactGridLayout {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.dragReset = () => {
|
|
8
|
+
if (this.dragEnterCounter) {
|
|
9
|
+
this.dragEnterCounter = 0;
|
|
10
|
+
this.removeDroppingPlaceholder();
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
componentDidMount() {
|
|
15
|
+
var _a;
|
|
16
|
+
(_a = super.componentDidMount) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
17
|
+
window.addEventListener('dragend', this.dragReset);
|
|
18
|
+
}
|
|
19
|
+
componentWillUnmount() {
|
|
20
|
+
window.removeEventListener('dragend', this.dragReset);
|
|
21
|
+
}
|
|
22
|
+
processGridItem(child, isDroppingItem) {
|
|
23
|
+
var _a;
|
|
24
|
+
const gridItem = (_a = super.processGridItem) === null || _a === void 0 ? void 0 : _a.call(this, child, isDroppingItem);
|
|
25
|
+
if (isDroppingItem) {
|
|
26
|
+
// Drop item from outside gets 0,0 droppingPosition
|
|
27
|
+
// centering cursor on newly creted grid item
|
|
28
|
+
// And cause grid-layout using it's own GridItem to make it look
|
|
29
|
+
// like overlay adding className
|
|
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 gridItem;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// eslint-disable-next-line new-cap
|
|
45
|
+
export const Layout = WidthProvider(DragOverLayout);
|
|
@@ -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);
|
|
@@ -180,8 +180,8 @@ class OverlayControls extends React.Component {
|
|
|
180
180
|
};
|
|
181
181
|
});
|
|
182
182
|
items = items.filter(Boolean);
|
|
183
|
-
return (React.createElement(DropdownMenu, { items: items,
|
|
184
|
-
React.createElement(Icon, { data: DotsIcon, size: "16" })) }));
|
|
183
|
+
return (React.createElement(DropdownMenu, { items: items, renderSwitcher: (props) => (React.createElement(Button, Object.assign({}, props, { view: view, size: size, pin: "brick-round", qa: "dashkit-overlay-control-menu" }),
|
|
184
|
+
React.createElement(Icon, { data: DotsIcon, size: "16" }))) }));
|
|
185
185
|
}
|
|
186
186
|
getControlItemPinStyle(index, itemsLength) {
|
|
187
187
|
const isOnlyOneItem = itemsLength === 1;
|
|
@@ -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,8 +1,12 @@
|
|
|
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";
|
|
7
9
|
readonly Settings: "settings";
|
|
8
10
|
};
|
|
11
|
+
export declare const DEFAULT_WIDGET_HEIGHT = 3;
|
|
12
|
+
export declare const DEFAULT_WIDGET_WIDTH = 3;
|
|
@@ -1,8 +1,12 @@
|
|
|
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',
|
|
7
9
|
Settings: 'settings',
|
|
8
10
|
};
|
|
11
|
+
export const DEFAULT_WIDGET_HEIGHT = 3;
|
|
12
|
+
export const DEFAULT_WIDGET_WIDTH = 3;
|
|
@@ -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 { DEFAULT_WIDGET_HEIGHT, DEFAULT_WIDGET_WIDTH, 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(Object.assign(Object.assign({}, temporaryLayout), { data: temporaryLayout.data.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,8 +140,57 @@ 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 dragProps = dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragProps;
|
|
144
|
+
const dragOverPlugin = React.useMemo(() => {
|
|
145
|
+
if (!dragProps) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
const pluginType = dragProps.type;
|
|
149
|
+
if (props.registerManager.check(pluginType)) {
|
|
150
|
+
return props.registerManager.getItem(pluginType);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
// eslint-disable-next-line no-console
|
|
154
|
+
console.error(`Uknown pluginType: ${pluginType}`);
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}, [dragProps, props.registerManager]);
|
|
158
|
+
const onDropDragOver = React.useCallback(() => {
|
|
159
|
+
if (temporaryLayout) {
|
|
160
|
+
resetTemporaryLayout();
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (dragOverPlugin) {
|
|
164
|
+
const { defaultLayout } = dragOverPlugin;
|
|
165
|
+
const { h = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.h) || DEFAULT_WIDGET_HEIGHT, w = (defaultLayout === null || defaultLayout === void 0 ? void 0 : defaultLayout.w) || DEFAULT_WIDGET_WIDTH, } = dragProps.layout || {};
|
|
166
|
+
return { h, w };
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}, [resetTemporaryLayout, temporaryLayout, dragOverPlugin, dragProps]);
|
|
170
|
+
const onDrop = React.useCallback((newLayout, item) => {
|
|
171
|
+
if (!dragProps) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
setTemporaryLayout({
|
|
175
|
+
data: newLayout,
|
|
176
|
+
dragProps,
|
|
177
|
+
});
|
|
178
|
+
const { i, w, h, x, y } = item;
|
|
179
|
+
props.onDrop({
|
|
180
|
+
newLayout: newLayout.reduce((memo, l) => {
|
|
181
|
+
if (l.i !== i) {
|
|
182
|
+
memo.push({ i: l.i, w: l.w, h: l.h, x: l.x, y: l.y });
|
|
183
|
+
}
|
|
184
|
+
return memo;
|
|
185
|
+
}, []),
|
|
186
|
+
itemLayout: { w, h, x, y },
|
|
187
|
+
commit: resetTemporaryLayout,
|
|
188
|
+
dragProps,
|
|
189
|
+
});
|
|
190
|
+
}, [dragProps, props.onDrop, setTemporaryLayout, resetTemporaryLayout]);
|
|
123
191
|
return React.useMemo(() => ({
|
|
124
192
|
layout: resultLayout,
|
|
193
|
+
temporaryLayout,
|
|
125
194
|
config: props.config,
|
|
126
195
|
context: props.context,
|
|
127
196
|
noOverlay: props.noOverlay,
|
|
@@ -135,6 +204,8 @@ function useMemoStateContext(props) {
|
|
|
135
204
|
registerManager: props.registerManager,
|
|
136
205
|
onItemStateAndParamsChange,
|
|
137
206
|
removeItem: onItemRemove,
|
|
207
|
+
onDrop,
|
|
208
|
+
onDropDragOver,
|
|
138
209
|
editItem: props.onItemEdit,
|
|
139
210
|
layoutChange: onLayoutChange,
|
|
140
211
|
getItemsMeta,
|
|
@@ -143,8 +214,11 @@ function useMemoStateContext(props) {
|
|
|
143
214
|
revertToOriginalLayout,
|
|
144
215
|
forwardedMetaRef: props.forwardedMetaRef,
|
|
145
216
|
draggableHandleClassName: props.draggableHandleClassName,
|
|
217
|
+
outerDnDEnable,
|
|
218
|
+
dragOverPlugin,
|
|
146
219
|
}), [
|
|
147
220
|
resultLayout,
|
|
221
|
+
temporaryLayout,
|
|
148
222
|
props.config,
|
|
149
223
|
props.context,
|
|
150
224
|
props.noOverlay,
|
|
@@ -157,6 +231,8 @@ function useMemoStateContext(props) {
|
|
|
157
231
|
props.registerManager,
|
|
158
232
|
onItemStateAndParamsChange,
|
|
159
233
|
onItemRemove,
|
|
234
|
+
onDrop,
|
|
235
|
+
onDropDragOver,
|
|
160
236
|
props.onItemEdit,
|
|
161
237
|
onLayoutChange,
|
|
162
238
|
getItemsMeta,
|
|
@@ -165,6 +241,8 @@ function useMemoStateContext(props) {
|
|
|
165
241
|
revertToOriginalLayout,
|
|
166
242
|
props.forwardedMetaRef,
|
|
167
243
|
props.draggableHandleClassName,
|
|
244
|
+
outerDnDEnable,
|
|
245
|
+
dragOverPlugin,
|
|
168
246
|
]);
|
|
169
247
|
}
|
|
170
248
|
export 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,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DashKitDnDContext } from '../context/DashKitContext';
|
|
3
|
+
export const useDnDItemProps = (item) => {
|
|
4
|
+
const dragContext = React.useContext(DashKitDnDContext);
|
|
5
|
+
const onDragStart = React.useCallback((e) => {
|
|
6
|
+
if (dragContext && item.dragProps) {
|
|
7
|
+
dragContext.onDragStart(e, item.dragProps);
|
|
8
|
+
e.dataTransfer.setDragImage(dragContext.dragImagePreview, 0, 0);
|
|
9
|
+
}
|
|
10
|
+
}, [dragContext, item.dragProps]);
|
|
11
|
+
const onDragEnd = React.useCallback((e) => {
|
|
12
|
+
if (dragContext) {
|
|
13
|
+
dragContext.onDragEnd(e);
|
|
14
|
+
}
|
|
15
|
+
}, [dragContext]);
|
|
16
|
+
if (dragContext && item.dragProps) {
|
|
17
|
+
return {
|
|
18
|
+
draggable: true,
|
|
19
|
+
unselectable: 'on',
|
|
20
|
+
onDragStart,
|
|
21
|
+
onDragEnd,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
@@ -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;
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import groupBy from 'lodash/groupBy';
|
|
2
2
|
import { META_KEY } from '../constants';
|
|
3
3
|
import { formQueueData, getCurrentVersion, getMapItemsIgnores, hasActionParam, isItemWithGroup, isItemWithTabs, mergeParamsWithAliases, pickActionParamsFromParams, pickExceptActionParamsFromParams, prerenderItems, resolveItemInnerId, } from './helpers';
|
|
4
|
-
|
|
4
|
+
const getParamsFromStateAndParams = ({ itemsStateAndParams, parentItemId, item, }) => {
|
|
5
|
+
const widgetId = parentItemId || item.id;
|
|
6
|
+
if (!(widgetId in itemsStateAndParams)) {
|
|
7
|
+
return {};
|
|
8
|
+
}
|
|
9
|
+
const stateAndParams = itemsStateAndParams;
|
|
10
|
+
const itemParams = parentItemId
|
|
11
|
+
? Object.assign({}, stateAndParams[widgetId].params[item.id])
|
|
12
|
+
: Object.assign({}, stateAndParams[widgetId].params);
|
|
13
|
+
return itemParams;
|
|
14
|
+
};
|
|
15
|
+
function getItemParams({ item, itemsStateAndParams, mapItemsIgnores, itemsWithDefaultsByNamespace, getMergedParams, defaultGlobalParams, globalParams, isFirstVersion, queueData, parentItemId, useStateAsInitial, }) {
|
|
5
16
|
var _a, _b;
|
|
6
17
|
const { id, namespace } = item;
|
|
7
18
|
let defaultWidgetParams = {};
|
|
@@ -20,7 +31,9 @@ function getItemParams({ item, itemsStateAndParams, mapItemsIgnores, itemsWithDe
|
|
|
20
31
|
// default parameters to begin with
|
|
21
32
|
affectingItemsWithDefaults.reduceRight((defaultParams, itemWithDefaults) => {
|
|
22
33
|
return Object.assign(Object.assign({}, defaultParams), getMergedParams(itemWithDefaults.defaults || {}));
|
|
23
|
-
}, {}), getMergedParams(globalParams)
|
|
34
|
+
}, {}), getMergedParams(globalParams), useStateAsInitial
|
|
35
|
+
? getParamsFromStateAndParams({ parentItemId, item, itemsStateAndParams })
|
|
36
|
+
: {});
|
|
24
37
|
if (isFirstVersion) {
|
|
25
38
|
itemParams = Object.assign(itemParams, ((_b = itemsStateAndParams === null || itemsStateAndParams === void 0 ? void 0 : itemsStateAndParams[id]) === null || _b === void 0 ? void 0 : _b.params) || {});
|
|
26
39
|
}
|
|
@@ -45,7 +58,7 @@ function getItemParams({ item, itemsStateAndParams, mapItemsIgnores, itemsWithDe
|
|
|
45
58
|
}
|
|
46
59
|
return Object.assign(Object.assign({}, defaultWidgetParams), itemParams);
|
|
47
60
|
}
|
|
48
|
-
export function getItemsParams({ defaultGlobalParams = {}, globalParams = {}, config, itemsStateAndParams, plugins, }) {
|
|
61
|
+
export function getItemsParams({ defaultGlobalParams = {}, globalParams = {}, config, itemsStateAndParams, plugins, useStateAsInitial, }) {
|
|
49
62
|
const { aliases, connections } = config;
|
|
50
63
|
const items = prerenderItems({ items: config.items, plugins });
|
|
51
64
|
const isFirstVersion = getCurrentVersion(itemsStateAndParams) === 1;
|
|
@@ -88,10 +101,11 @@ export function getItemsParams({ defaultGlobalParams = {}, globalParams = {}, co
|
|
|
88
101
|
globalParams,
|
|
89
102
|
isFirstVersion,
|
|
90
103
|
queueData,
|
|
104
|
+
useStateAsInitial,
|
|
91
105
|
};
|
|
92
106
|
if (isItemWithGroup(item)) {
|
|
93
107
|
const groupParams = item.data.group.reduce((groupItemParams, groupItem) => {
|
|
94
|
-
groupItemParams[groupItem.id] = getItemParams(Object.assign({ item: groupItem }, paramsOptions));
|
|
108
|
+
groupItemParams[groupItem.id] = getItemParams(Object.assign({ item: groupItem, parentItemId: item.id }, paramsOptions));
|
|
95
109
|
return groupItemParams;
|
|
96
110
|
}, {});
|
|
97
111
|
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
|
+
};
|
|
@@ -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
|
}
|