@gravity-ui/dashkit 8.17.4 → 8.19.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 +15 -2
- package/build/cjs/components/DashKit/DashKit.d.ts +2 -2
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +2 -1
- package/build/cjs/components/DashKitDnDWrapper/DashKitDnDWrapper.js +8 -7
- package/build/cjs/components/GridItem/GridItem.css +5 -0
- package/build/cjs/components/GridLayout/GridLayout.d.ts +1 -1
- package/build/cjs/components/GridLayout/GridLayout.js +38 -30
- package/build/cjs/components/GridLayout/ReactGridLayout.js +19 -17
- package/build/cjs/components/OverlayControls/OverlayControls.d.ts +6 -3
- package/build/cjs/components/OverlayControls/OverlayControls.js +19 -9
- package/build/cjs/constants/common.d.ts +1 -0
- package/build/cjs/constants/common.js +2 -1
- package/build/cjs/hocs/withContext.js +27 -12
- package/build/cjs/shared/types/common.d.ts +4 -0
- package/build/cjs/typings/common.d.ts +4 -1
- package/build/cjs/typings/config.d.ts +2 -1
- package/build/esm/components/DashKit/DashKit.d.ts +2 -2
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.d.ts +2 -1
- package/build/esm/components/DashKitDnDWrapper/DashKitDnDWrapper.js +8 -7
- package/build/esm/components/GridItem/GridItem.css +5 -0
- package/build/esm/components/GridLayout/GridLayout.d.ts +1 -1
- package/build/esm/components/GridLayout/GridLayout.js +38 -30
- package/build/esm/components/GridLayout/ReactGridLayout.js +20 -18
- package/build/esm/components/OverlayControls/OverlayControls.d.ts +6 -3
- package/build/esm/components/OverlayControls/OverlayControls.js +19 -9
- package/build/esm/constants/common.d.ts +1 -0
- package/build/esm/constants/common.js +1 -0
- package/build/esm/hocs/withContext.js +27 -12
- package/build/esm/shared/types/common.d.ts +4 -0
- package/build/esm/typings/common.d.ts +4 -1
- package/build/esm/typings/config.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,18 +59,20 @@ interface DashKitProps {
|
|
|
59
59
|
noOverlay?: boolean;
|
|
60
60
|
focusable?: boolean;
|
|
61
61
|
draggableHandleClassName?: string;
|
|
62
|
+
getPreparedCopyItemOptions?: (options: PreparedCopyItemOptions) => PreparedCopyItemOptions;
|
|
63
|
+
onCopyFulfill?: (error: null | Error, data?: PreparedCopyItemOptions) => void;
|
|
62
64
|
}
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
- **config**: [сonfig](#Config).
|
|
66
68
|
- **editMode**: Whether edit mode is enabled.
|
|
67
69
|
- **onItemEdit**: Called when you click to edit a widget.
|
|
68
|
-
- **onChange**: Called when config or [itemsStateAndParams](#
|
|
70
|
+
- **onChange**: Called when config or [itemsStateAndParams](#itemsStateAndParams) are changed.
|
|
69
71
|
- **onDrop**: Called when item dropped from ActionPanel using (#DashKitDnDWrapper)
|
|
70
72
|
- **onItemMountChange**: Called when item mount state changed
|
|
71
73
|
- **onItemRender**: Called when item render complete
|
|
72
74
|
- **defaultGlobalParams**, **globalParams**: [Parameters](#Params) that affect all widgets. In DataLens, `defaultGlobalParams` are global parameters set in the dashboard settings. `globalParams` are globals parameters that can be set in the url.
|
|
73
|
-
- **itemsStateAndParams**: [itemsStateAndParams](#
|
|
75
|
+
- **itemsStateAndParams**: [itemsStateAndParams](#itemsStateAndParams).
|
|
74
76
|
- **settings**: DashKit settings.
|
|
75
77
|
- **context**: Object that will be propped up on all widgets.
|
|
76
78
|
- **overlayControls**: Object that overrides widget controls at the time of editing. If not transmitted, basic controls will be displayed. If `null` passed only close button or custom menu will be displayed.
|
|
@@ -84,6 +86,8 @@ interface DashKitProps {
|
|
|
84
86
|
- **onResizeStart**: ReactGridLayout called when item resize started
|
|
85
87
|
- **onResize**: ReactGridLayout called while item resizing
|
|
86
88
|
- **onResizeStop**: ReactGridLayout called when item resize stoped
|
|
89
|
+
- **getPreparedCopyItemOptions**: Called for converting copied item to serializable object before saving it to localstorage. It should be used instead of deprecated `context.getPreparedCopyItemOptions` prop
|
|
90
|
+
- **onCopyFulfill**: Called when item copy finished with `error=null` and defined `data` on successful operation done and with `error: Error` without `data` otherwise
|
|
87
91
|
|
|
88
92
|
## Usage
|
|
89
93
|
|
|
@@ -384,10 +388,19 @@ DashKit.setSettings({menu: [] as Array<MenuItem>});
|
|
|
384
388
|
#### DashKitDnDWrapper
|
|
385
389
|
|
|
386
390
|
```ts
|
|
391
|
+
type DraggedOverItem = {
|
|
392
|
+
h: number;
|
|
393
|
+
w: number;
|
|
394
|
+
type: string;
|
|
395
|
+
parent: string;
|
|
396
|
+
i?: number;
|
|
397
|
+
};
|
|
398
|
+
|
|
387
399
|
interface DashKitDnDWrapperProps {
|
|
388
400
|
dragImageSrc?: string;
|
|
389
401
|
onDragStart?: (dragProps: ItemDragProps) => void;
|
|
390
402
|
onDragEnd?: () => void;
|
|
403
|
+
onDropDragOver?: (draggedItem: DraggedOverItem, sharedItem: DraggedOverItem | null) => void | boolean;
|
|
391
404
|
}
|
|
392
405
|
```
|
|
393
406
|
|
|
@@ -2,8 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import type { Config, ConfigItem, ConfigLayout, GlobalParams, ItemDropProps, ItemsStateAndParams } from '../../shared';
|
|
3
3
|
import { AddNewItemOptions, ContextProps, DashKitGroup, ItemManipulationCallback, MenuItem, Plugin, SetConfigItem, Settings, SettingsProps } from '../../typings';
|
|
4
4
|
import GridLayout from '../GridLayout/GridLayout';
|
|
5
|
-
import { OverlayControlItem } from '../OverlayControls/OverlayControls';
|
|
6
|
-
interface DashKitGeneralProps {
|
|
5
|
+
import { OverlayControlItem, OverlayControlsCtxShape } from '../OverlayControls/OverlayControls';
|
|
6
|
+
interface DashKitGeneralProps extends Pick<OverlayControlsCtxShape, 'getPreparedCopyItemOptions' | 'onCopyFulfill'> {
|
|
7
7
|
config: Config;
|
|
8
8
|
editMode: boolean;
|
|
9
9
|
draggableHandleClassName?: string;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ItemDragProps } from '../../shared';
|
|
2
|
+
import type { DraggedOverItem, ItemDragProps } from '../../shared';
|
|
3
3
|
type DashKitDnDWrapperProps = {
|
|
4
4
|
dragImageSrc?: string;
|
|
5
|
+
onDropDragOver?: (draggedItem: DraggedOverItem, sharedItem: DraggedOverItem | null) => void | boolean;
|
|
5
6
|
onDragStart?: (dragProps: ItemDragProps) => void;
|
|
6
7
|
onDragEnd?: () => void;
|
|
7
8
|
children: React.ReactElement;
|
|
@@ -12,24 +12,25 @@ const DashKitDnDWrapper = (props) => {
|
|
|
12
12
|
img.src = props.dragImageSrc || defaultImageSrc;
|
|
13
13
|
return img;
|
|
14
14
|
}, [props.dragImageSrc]);
|
|
15
|
+
const onDragStartProp = props.onDragStart;
|
|
15
16
|
const onDragStart = react_1.default.useCallback((_, itemDragProps) => {
|
|
16
|
-
var _a;
|
|
17
17
|
setDragProps(itemDragProps);
|
|
18
|
-
|
|
19
|
-
}, [setDragProps,
|
|
18
|
+
onDragStartProp === null || onDragStartProp === void 0 ? void 0 : onDragStartProp(itemDragProps);
|
|
19
|
+
}, [setDragProps, onDragStartProp]);
|
|
20
|
+
const onDragEndProp = props.onDragEnd;
|
|
20
21
|
const onDragEnd = react_1.default.useCallback((_) => {
|
|
21
|
-
var _a;
|
|
22
22
|
setDragProps(null);
|
|
23
|
-
|
|
24
|
-
}, [setDragProps,
|
|
23
|
+
onDragEndProp === null || onDragEndProp === void 0 ? void 0 : onDragEndProp();
|
|
24
|
+
}, [setDragProps, onDragEndProp]);
|
|
25
25
|
const contextValue = react_1.default.useMemo(() => {
|
|
26
26
|
return {
|
|
27
27
|
dragProps,
|
|
28
28
|
dragImagePreview,
|
|
29
29
|
onDragStart,
|
|
30
30
|
onDragEnd,
|
|
31
|
+
onDropDragOver: props.onDropDragOver,
|
|
31
32
|
};
|
|
32
|
-
}, [dragProps, dragImagePreview, onDragStart, onDragEnd]);
|
|
33
|
+
}, [dragProps, dragImagePreview, onDragStart, onDragEnd, props.onDropDragOver]);
|
|
33
34
|
return (react_1.default.createElement(DashKitContext_1.DashKitDnDContext.Provider, { value: contextValue }, props.children));
|
|
34
35
|
};
|
|
35
36
|
exports.DashKitDnDWrapper = DashKitDnDWrapper;
|
|
@@ -4,10 +4,10 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
4
4
|
pluginsRefs: any[];
|
|
5
5
|
state: {
|
|
6
6
|
isDragging: boolean;
|
|
7
|
+
isDraggedOut: boolean;
|
|
7
8
|
isPageHidden: boolean;
|
|
8
9
|
currentDraggingElement: null;
|
|
9
10
|
draggedOverGroup: null;
|
|
10
|
-
draggedOut: boolean;
|
|
11
11
|
};
|
|
12
12
|
componentDidMount(): void;
|
|
13
13
|
componentDidUpdate(): void;
|
|
@@ -142,20 +142,27 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
142
142
|
if (currentDraggingElement) {
|
|
143
143
|
const { h, w, i } = currentDraggingElement.layoutItem;
|
|
144
144
|
const { type } = currentDraggingElement.item;
|
|
145
|
-
|
|
145
|
+
const sharedItem = {
|
|
146
|
+
h,
|
|
147
|
+
w,
|
|
148
|
+
i,
|
|
149
|
+
type,
|
|
150
|
+
parent: currentDraggingElement.group,
|
|
151
|
+
};
|
|
152
|
+
return onDropDragOver(e, group, properties, layout, sharedItem);
|
|
146
153
|
}
|
|
147
154
|
if (dragOverPlugin) {
|
|
148
|
-
return onDropDragOver(e, properties, layout);
|
|
155
|
+
return onDropDragOver(e, group, properties, layout);
|
|
149
156
|
}
|
|
150
157
|
return false;
|
|
151
158
|
};
|
|
152
159
|
this.pluginsRefs = [];
|
|
153
160
|
this.state = {
|
|
154
161
|
isDragging: false,
|
|
162
|
+
isDraggedOut: false,
|
|
155
163
|
isPageHidden: false,
|
|
156
164
|
currentDraggingElement: null,
|
|
157
165
|
draggedOverGroup: null,
|
|
158
|
-
draggedOut: false,
|
|
159
166
|
};
|
|
160
167
|
}
|
|
161
168
|
componentDidMount() {
|
|
@@ -291,7 +298,7 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
291
298
|
_initDragCoordinatesWatcher(element) {
|
|
292
299
|
if (!this._parendDragNode) {
|
|
293
300
|
this._parendDragNode = element.parentElement;
|
|
294
|
-
this.setState({
|
|
301
|
+
this.setState({ isDraggedOut: false });
|
|
295
302
|
}
|
|
296
303
|
}
|
|
297
304
|
// When element is going back and prointer-event: none is removed mouse enter event is not fired
|
|
@@ -317,19 +324,19 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
317
324
|
const parent = this._parendDragNode;
|
|
318
325
|
const parentRect = parent.getBoundingClientRect();
|
|
319
326
|
const { clientX, clientY } = e;
|
|
320
|
-
let
|
|
327
|
+
let isDraggedOut = this.state.isDraggedOut;
|
|
321
328
|
if (clientX < parentRect.left ||
|
|
322
329
|
clientX > parentRect.right ||
|
|
323
330
|
clientY < parentRect.top ||
|
|
324
331
|
clientY > parentRect.bottom) {
|
|
325
|
-
|
|
332
|
+
isDraggedOut = true;
|
|
326
333
|
}
|
|
327
334
|
else {
|
|
328
|
-
|
|
335
|
+
isDraggedOut = false;
|
|
329
336
|
}
|
|
330
|
-
if (
|
|
331
|
-
this.setState({
|
|
332
|
-
if (!
|
|
337
|
+
if (isDraggedOut !== this.state.isDraggedOut) {
|
|
338
|
+
this.setState({ isDraggedOut });
|
|
339
|
+
if (!isDraggedOut) {
|
|
333
340
|
this._forceCursorCapture(parent, {
|
|
334
341
|
top: clientY - parentRect.top,
|
|
335
342
|
left: clientX - parentRect.left,
|
|
@@ -339,23 +346,25 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
339
346
|
}
|
|
340
347
|
_resetDragWatcher() {
|
|
341
348
|
this._parendDragNode = null;
|
|
342
|
-
this.setState({
|
|
349
|
+
this.setState({ isDraggedOut: false });
|
|
343
350
|
}
|
|
344
351
|
_onDragStart(group, _newLayout, layoutItem, _newItem, _placeholder, e, element) {
|
|
345
352
|
var _a;
|
|
346
353
|
(_a = this.context.onDragStart) === null || _a === void 0 ? void 0 : _a.call(this, this.prepareDefaultArguments(group, _newLayout, layoutItem, _newItem, _placeholder, e, element));
|
|
347
|
-
this._initDragCoordinatesWatcher(element);
|
|
348
354
|
if (this.context.dragOverPlugin) {
|
|
349
355
|
this.setState({ isDragging: true });
|
|
350
356
|
}
|
|
351
357
|
else {
|
|
358
|
+
this._initDragCoordinatesWatcher(element);
|
|
352
359
|
this.updateDraggingElementState(group, layoutItem, e);
|
|
353
360
|
this.setState({ isDragging: true });
|
|
354
361
|
}
|
|
355
362
|
}
|
|
356
363
|
_onDrag(group, layout, oldItem, newItem, placeholder, e, element) {
|
|
357
364
|
var _a;
|
|
358
|
-
this.
|
|
365
|
+
if (!this.context.dragOverPlugin) {
|
|
366
|
+
this._updateDragCoordinates(e);
|
|
367
|
+
}
|
|
359
368
|
(_a = this.context.onDrag) === null || _a === void 0 ? void 0 : _a.call(this, this.prepareDefaultArguments(group, layout, oldItem, newItem, placeholder, e, element));
|
|
360
369
|
}
|
|
361
370
|
_onDragStop(group, layout, oldItem, newItem, placeholder, e, element) {
|
|
@@ -403,7 +412,8 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
403
412
|
renderGroup(group, renderLayout, renderItems, offset = 0, groupGridProperties) {
|
|
404
413
|
const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, onItemMountChange, onItemRender, } = this.context;
|
|
405
414
|
const { currentDraggingElement, draggedOverGroup } = this.state;
|
|
406
|
-
const
|
|
415
|
+
const hasOwnGroupProperties = typeof groupGridProperties === 'function';
|
|
416
|
+
const properties = hasOwnGroupProperties
|
|
407
417
|
? groupGridProperties(Object.assign({}, registerManager.gridLayout))
|
|
408
418
|
: registerManager.gridLayout;
|
|
409
419
|
let { compactType } = properties;
|
|
@@ -416,25 +426,22 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
416
426
|
group === currentDraggingElement.group &&
|
|
417
427
|
draggedOverGroup !== null &&
|
|
418
428
|
draggedOverGroup !== group;
|
|
419
|
-
return (react_1.default.createElement(ReactGridLayout_1.Layout
|
|
420
|
-
// Group properties
|
|
421
|
-
, Object.assign({}, properties, {
|
|
429
|
+
return (react_1.default.createElement(ReactGridLayout_1.Layout, Object.assign({ isDraggable: editMode, isResizable: editMode }, properties, { key: `group_${group}`,
|
|
422
430
|
// Layout props
|
|
423
|
-
compactType: compactType, layout: layout,
|
|
424
|
-
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
425
|
-
: null), {
|
|
431
|
+
compactType: compactType, layout: layout, draggableCancel: `.${constants_1.DRAGGABLE_CANCEL_CLASS_NAME}`, draggableHandle: draggableHandleClassName ? `.${draggableHandleClassName}` : null,
|
|
426
432
|
// Default callbacks
|
|
427
433
|
onDragStart: callbacks.onDragStart, onDrag: callbacks.onDrag, onDragStop: callbacks.onDragStop, onResizeStart: callbacks.onResizeStart, onResize: callbacks.onResize, onResizeStop: callbacks.onResizeStop,
|
|
428
434
|
// External Drag N Drop options
|
|
429
|
-
onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, sharedDragPosition: currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.cursorPosition, isDragCaptured: isDragCaptured
|
|
430
|
-
? {
|
|
431
|
-
isDroppable: true,
|
|
432
|
-
}
|
|
433
|
-
: null)),
|
|
435
|
+
onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, sharedDragPosition: currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.cursorPosition, isDragCaptured: isDragCaptured, isDroppable: Boolean(outerDnDEnable) && editMode }),
|
|
434
436
|
renderItems.map((item, i) => {
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
|
|
437
|
+
const keyId = item.id;
|
|
438
|
+
const isDragging = this.state.isDragging;
|
|
439
|
+
const isCurrentDraggedItem = (currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.item.id) === keyId;
|
|
440
|
+
const isDraggedOut = isCurrentDraggedItem && this.state.isDraggedOut;
|
|
441
|
+
const itemNoOverlay = hasOwnGroupProperties && 'noOverlay' in properties
|
|
442
|
+
? properties.noOverlay
|
|
443
|
+
: noOverlay;
|
|
444
|
+
return (react_1.default.createElement(GridItem_1.default, { forwardedPluginRef: this.getMemoForwardRefCallback(offset + i), key: keyId, id: keyId, item: item, layout: layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: isDragging, isDraggedOut: isDraggedOut, noOverlay: itemNoOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), onItemMountChange: onItemMountChange, onItemRender: onItemRender }));
|
|
438
445
|
}),
|
|
439
446
|
this.renderTemporaryPlaceholder()));
|
|
440
447
|
}
|
|
@@ -486,13 +493,14 @@ class GridLayout extends react_1.default.PureComponent {
|
|
|
486
493
|
const element = this.renderGroup(id, layout, items, offset, group.gridProperties);
|
|
487
494
|
offset += items.length;
|
|
488
495
|
if (group.render) {
|
|
489
|
-
|
|
496
|
+
const groupContext = {
|
|
490
497
|
config,
|
|
491
498
|
editMode,
|
|
492
499
|
items,
|
|
493
500
|
layout,
|
|
494
501
|
context,
|
|
495
|
-
}
|
|
502
|
+
};
|
|
503
|
+
return group.render(id, element, groupContext);
|
|
496
504
|
}
|
|
497
505
|
return element;
|
|
498
506
|
});
|
|
@@ -157,6 +157,20 @@ class DragOverLayout extends react_grid_layout_1.default {
|
|
|
157
157
|
var _a;
|
|
158
158
|
return ((_a = this.props.innerRef) === null || _a === void 0 ? void 0 : _a.current) || null;
|
|
159
159
|
}
|
|
160
|
+
calculateDroppingPosition(itemProps) {
|
|
161
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition } = itemProps;
|
|
162
|
+
const { sharedDragPosition } = this.props;
|
|
163
|
+
let offsetX, offsetY;
|
|
164
|
+
if (sharedDragPosition) {
|
|
165
|
+
offsetX = sharedDragPosition.offsetX;
|
|
166
|
+
offsetY = sharedDragPosition.offsetY;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
offsetX = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
170
|
+
offsetY = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
171
|
+
}
|
|
172
|
+
return Object.assign(Object.assign({}, droppingPosition), { left: droppingPosition.left - offsetX, top: droppingPosition.top - offsetY });
|
|
173
|
+
}
|
|
160
174
|
// Drop item from outside gets 0,0 droppingPosition
|
|
161
175
|
// centering cursor on newly creted grid item
|
|
162
176
|
// And cause grid-layout using it's own GridItem to make it look
|
|
@@ -167,26 +181,14 @@ class DragOverLayout extends react_grid_layout_1.default {
|
|
|
167
181
|
if (!gridItem) {
|
|
168
182
|
return gridItem;
|
|
169
183
|
}
|
|
170
|
-
const { props: itemProps } = gridItem;
|
|
171
184
|
if (isDroppingItem) {
|
|
172
|
-
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition, } = itemProps;
|
|
173
|
-
const { sharedDragPosition, hasSharedDragItem } = this.props;
|
|
174
|
-
let offsetX, offsetY;
|
|
175
|
-
if (sharedDragPosition) {
|
|
176
|
-
offsetX = sharedDragPosition.offsetX;
|
|
177
|
-
offsetY = sharedDragPosition.offsetY;
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
offsetX = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
181
|
-
offsetY = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
182
|
-
}
|
|
183
|
-
const style = gridItem.props.style || null;
|
|
184
185
|
// React.cloneElement is just cleaner then copy-paste whole processGridItem method
|
|
185
186
|
return react_1.default.cloneElement(gridItem, {
|
|
186
|
-
// hiding
|
|
187
|
-
style:
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
// hiding preview if dragging shared item
|
|
188
|
+
style: this.props.hasSharedDragItem
|
|
189
|
+
? Object.assign(Object.assign({}, gridItem.props.style), { opacity: 0 }) : gridItem.props.style,
|
|
190
|
+
className: `${constants_1.OVERLAY_CLASS_NAME} ${constants_1.DROPPING_ELEMENT_CLASS_NAME}`,
|
|
191
|
+
droppingPosition: this.calculateDroppingPosition(gridItem.props),
|
|
190
192
|
});
|
|
191
193
|
}
|
|
192
194
|
return gridItem;
|
|
@@ -50,7 +50,7 @@ type PreparedCopyItemOptionsArg = Pick<ConfigItem, 'data' | 'type' | 'defaults'
|
|
|
50
50
|
export type PreparedCopyItemOptions<C extends object = {}> = PreparedCopyItemOptionsArg & {
|
|
51
51
|
copyContext?: C;
|
|
52
52
|
};
|
|
53
|
-
|
|
53
|
+
export interface OverlayControlsCtxShape {
|
|
54
54
|
overlayControls?: Record<string, OverlayControlItem[]>;
|
|
55
55
|
context: Record<string, any>;
|
|
56
56
|
menu: MenuItem[];
|
|
@@ -59,11 +59,14 @@ type DashKitCtx = React.Context<{
|
|
|
59
59
|
editItem: (item: ConfigItem) => void;
|
|
60
60
|
removeItem: (id: string) => void;
|
|
61
61
|
getLayoutItem: (id: string) => ConfigLayout | void;
|
|
62
|
-
|
|
62
|
+
getPreparedCopyItemOptions?: (options: PreparedCopyItemOptions) => PreparedCopyItemOptions;
|
|
63
|
+
onCopyFulfill?: (error: null | Error, data?: PreparedCopyItemOptions) => void;
|
|
64
|
+
}
|
|
65
|
+
type OverlayControlsCtx = React.Context<OverlayControlsCtxShape>;
|
|
63
66
|
declare class OverlayControls extends React.Component<OverlayControlsProps> {
|
|
64
67
|
static contextType: React.Context<any>;
|
|
65
68
|
static defaultProps: OverlayControlsDefaultProps;
|
|
66
|
-
context: React.ContextType<
|
|
69
|
+
context: React.ContextType<OverlayControlsCtx>;
|
|
67
70
|
render(): JSX.Element;
|
|
68
71
|
private getItems;
|
|
69
72
|
private renderControlsItem;
|
|
@@ -32,7 +32,7 @@ class OverlayControls extends react_1.default.Component {
|
|
|
32
32
|
const { view, size, onItemClick } = this.props;
|
|
33
33
|
const { title, handler, icon, iconSize, qa } = item;
|
|
34
34
|
const onItemClickHandler = typeof handler === 'function' ? handler : noop_1.default;
|
|
35
|
-
return (react_1.default.createElement(uikit_1.Button, { key: index
|
|
35
|
+
return (react_1.default.createElement(uikit_1.Button, { key: `control_${index}`, view: view, size: size, title: title, pin: this.getControlItemPinStyle(index, length), onClick: () => {
|
|
36
36
|
onItemClickHandler(this.props.configItem);
|
|
37
37
|
onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick();
|
|
38
38
|
}, qa: qa },
|
|
@@ -43,7 +43,7 @@ class OverlayControls extends react_1.default.Component {
|
|
|
43
43
|
if (this.context.overlayControls === null) {
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
46
|
-
return (react_1.default.createElement(uikit_1.Button, { view: view, size: size, title: (0, i18n_1.i18n)('label_settings'), pin: "round-brick", onClick: this.onEditItem, qa: "dashkit-overlay-control-settings" },
|
|
46
|
+
return (react_1.default.createElement(uikit_1.Button, { key: 'control_default', view: view, size: size, title: (0, i18n_1.i18n)('label_settings'), pin: "round-brick", onClick: this.onEditItem, qa: "dashkit-overlay-control-settings" },
|
|
47
47
|
react_1.default.createElement(uikit_1.Icon, { data: icons_1.Gear, size: constants_1.OVERLAY_ICON_SIZE })));
|
|
48
48
|
};
|
|
49
49
|
this.getCustomLeftOverlayControls = () => {
|
|
@@ -79,7 +79,7 @@ class OverlayControls extends react_1.default.Component {
|
|
|
79
79
|
return controls;
|
|
80
80
|
};
|
|
81
81
|
this.onCopyItem = () => {
|
|
82
|
-
var _a, _b, _c;
|
|
82
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
83
83
|
const { configItem } = this.props;
|
|
84
84
|
const correspondedItemLayout = this.context.getLayoutItem(configItem.id);
|
|
85
85
|
let targetInnerId;
|
|
@@ -102,13 +102,24 @@ class OverlayControls extends react_1.default.Component {
|
|
|
102
102
|
targetId: this.props.configItem.id,
|
|
103
103
|
targetInnerId,
|
|
104
104
|
};
|
|
105
|
-
if (
|
|
105
|
+
if ((_a = this.context.context) === null || _a === void 0 ? void 0 : _a.getPreparedCopyItemOptions) {
|
|
106
|
+
(_b = console.warn) === null || _b === void 0 ? void 0 : _b.call(console, '`context.getPreparedCopyItemOptions` is deprecated. Please use `getPreparedCopyItemOptions` prop instead');
|
|
107
|
+
}
|
|
108
|
+
const getPreparedCopyItemOptions = (_d = (_c = this.context) === null || _c === void 0 ? void 0 : _c.getPreparedCopyItemOptions) !== null && _d !== void 0 ? _d : (_e = this.context.context) === null || _e === void 0 ? void 0 : _e.getPreparedCopyItemOptions;
|
|
109
|
+
if (typeof getPreparedCopyItemOptions === 'function') {
|
|
106
110
|
options = this.context.context.getPreparedCopyItemOptions(options);
|
|
107
111
|
}
|
|
108
|
-
|
|
112
|
+
try {
|
|
113
|
+
localStorage.setItem(constants_1.COPIED_WIDGET_STORE_KEY, JSON.stringify(options));
|
|
114
|
+
(_g = (_f = this.context).onCopyFulfill) === null || _g === void 0 ? void 0 : _g.call(_f, null, options);
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
const error = e instanceof Error ? e : new Error('Unknown error while copying item');
|
|
118
|
+
(_j = (_h = this.context).onCopyFulfill) === null || _j === void 0 ? void 0 : _j.call(_h, error);
|
|
119
|
+
}
|
|
109
120
|
// https://stackoverflow.com/questions/35865481/storage-event-not-firing
|
|
110
121
|
window.dispatchEvent(new Event('storage'));
|
|
111
|
-
(
|
|
122
|
+
(_l = (_k = this.props).onItemClick) === null || _l === void 0 ? void 0 : _l.call(_k);
|
|
112
123
|
};
|
|
113
124
|
this.onEditItem = () => {
|
|
114
125
|
var _a, _b;
|
|
@@ -161,10 +172,9 @@ class OverlayControls extends react_1.default.Component {
|
|
|
161
172
|
renderControls() {
|
|
162
173
|
const customLeftControls = this.getCustomLeftOverlayControls();
|
|
163
174
|
const hasCustomOverlayLeftControls = Boolean(customLeftControls.length);
|
|
164
|
-
const defaultControl = this.getDefaultControls();
|
|
165
175
|
const controls = hasCustomOverlayLeftControls
|
|
166
176
|
? customLeftControls.map((item, index, items) => this.renderControlsItem(item, index, items.length + 1))
|
|
167
|
-
:
|
|
177
|
+
: this.getDefaultControls();
|
|
168
178
|
const menu = this.renderMenu(controls === null);
|
|
169
179
|
return (react_1.default.createElement("div", { className: b('default-controls', {
|
|
170
180
|
'with-custom-left': hasCustomOverlayLeftControls,
|
|
@@ -231,7 +241,7 @@ class OverlayControls extends react_1.default.Component {
|
|
|
231
241
|
if (items.length === 0) {
|
|
232
242
|
return null;
|
|
233
243
|
}
|
|
234
|
-
return (react_1.default.createElement(uikit_1.DropdownMenu, { items: items, renderSwitcher: (props) => (react_1.default.createElement(uikit_1.Button, Object.assign({}, props, { view: view, size: size, pin: isOnlyOneItem ? 'round-round' : 'brick-round', qa: "dashkit-overlay-control-menu" }),
|
|
244
|
+
return (react_1.default.createElement(uikit_1.DropdownMenu, { key: 'controls_dropdown', items: items, renderSwitcher: (props) => (react_1.default.createElement(uikit_1.Button, Object.assign({}, props, { view: view, size: size, pin: isOnlyOneItem ? 'round-round' : 'brick-round', qa: "dashkit-overlay-control-menu" }),
|
|
235
245
|
react_1.default.createElement(uikit_1.Icon, { data: icons_1.Ellipsis, size: constants_1.OVERLAY_ICON_SIZE }))), popupProps: {
|
|
236
246
|
contentClassName: constants_1.DRAGGABLE_CANCEL_CLASS_NAME,
|
|
237
247
|
} }));
|
|
@@ -15,3 +15,4 @@ export declare const DEFAULT_GROUP = "__default";
|
|
|
15
15
|
export declare const COMPACT_TYPE_HORIZONTAL_NOWRAP = "horizontal-nowrap";
|
|
16
16
|
export declare const DRAGGABLE_CANCEL_CLASS_NAME = "dashkit_draggable_cancel";
|
|
17
17
|
export declare const FOCUSED_CLASS_NAME = "dashkit_focused";
|
|
18
|
+
export declare const DROPPING_ELEMENT_CLASS_NAME = "dropping";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FOCUSED_CLASS_NAME = exports.DRAGGABLE_CANCEL_CLASS_NAME = exports.COMPACT_TYPE_HORIZONTAL_NOWRAP = exports.DEFAULT_GROUP = exports.DEFAULT_WIDGET_WIDTH = exports.DEFAULT_WIDGET_HEIGHT = exports.MenuItems = exports.TEMPORARY_ITEM_ID = exports.OVERLAY_ICON_SIZE = exports.OVERLAY_CLASS_NAME = exports.OVERLAY_CONTROLS_CLASS_NAME = exports.DEFAULT_NAMESPACE = exports.COPIED_WIDGET_STORE_KEY = void 0;
|
|
3
|
+
exports.DROPPING_ELEMENT_CLASS_NAME = exports.FOCUSED_CLASS_NAME = exports.DRAGGABLE_CANCEL_CLASS_NAME = exports.COMPACT_TYPE_HORIZONTAL_NOWRAP = exports.DEFAULT_GROUP = exports.DEFAULT_WIDGET_WIDTH = exports.DEFAULT_WIDGET_HEIGHT = exports.MenuItems = exports.TEMPORARY_ITEM_ID = exports.OVERLAY_ICON_SIZE = exports.OVERLAY_CLASS_NAME = exports.OVERLAY_CONTROLS_CLASS_NAME = exports.DEFAULT_NAMESPACE = exports.COPIED_WIDGET_STORE_KEY = void 0;
|
|
4
4
|
exports.COPIED_WIDGET_STORE_KEY = 'dashCopiedItem';
|
|
5
5
|
exports.DEFAULT_NAMESPACE = 'default';
|
|
6
6
|
exports.OVERLAY_CONTROLS_CLASS_NAME = 'dashkit-overlay-controls';
|
|
@@ -18,3 +18,4 @@ exports.DEFAULT_GROUP = '__default';
|
|
|
18
18
|
exports.COMPACT_TYPE_HORIZONTAL_NOWRAP = 'horizontal-nowrap';
|
|
19
19
|
exports.DRAGGABLE_CANCEL_CLASS_NAME = 'dashkit_draggable_cancel';
|
|
20
20
|
exports.FOCUSED_CLASS_NAME = 'dashkit_focused';
|
|
21
|
+
exports.DROPPING_ELEMENT_CLASS_NAME = 'dropping';
|
|
@@ -232,12 +232,13 @@ function useMemoStateContext(props) {
|
|
|
232
232
|
const reloadItems = react_1.default.useCallback((pluginsRefs, data) => {
|
|
233
233
|
pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
|
|
234
234
|
}, []);
|
|
235
|
-
const
|
|
235
|
+
const dragPropsContext = dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragProps;
|
|
236
|
+
const onDropDragOverContext = dndContext === null || dndContext === void 0 ? void 0 : dndContext.onDropDragOver;
|
|
236
237
|
const dragOverPlugin = react_1.default.useMemo(() => {
|
|
237
|
-
if (!
|
|
238
|
+
if (!dragPropsContext) {
|
|
238
239
|
return null;
|
|
239
240
|
}
|
|
240
|
-
const pluginType =
|
|
241
|
+
const pluginType = dragPropsContext.type;
|
|
241
242
|
if (props.registerManager.check(pluginType)) {
|
|
242
243
|
return props.registerManager.getItem(pluginType);
|
|
243
244
|
}
|
|
@@ -246,8 +247,8 @@ function useMemoStateContext(props) {
|
|
|
246
247
|
console.error(`Uknown pluginType: ${pluginType}`);
|
|
247
248
|
return null;
|
|
248
249
|
}
|
|
249
|
-
}, [
|
|
250
|
-
const onDropDragOver = react_1.default.useCallback((_e, gridProps, groupLayout, sharedItem) => {
|
|
250
|
+
}, [dragPropsContext, props.registerManager]);
|
|
251
|
+
const onDropDragOver = react_1.default.useCallback((_e, group, gridProps, groupLayout, sharedItem) => {
|
|
251
252
|
if (temporaryLayout) {
|
|
252
253
|
resetTemporaryLayout();
|
|
253
254
|
return false;
|
|
@@ -275,20 +276,30 @@ function useMemoStateContext(props) {
|
|
|
275
276
|
maxH < defaultLayout.minH) {
|
|
276
277
|
return false;
|
|
277
278
|
}
|
|
278
|
-
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, } = (
|
|
279
|
-
|
|
279
|
+
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, } = (dragPropsContext === null || dragPropsContext === void 0 ? void 0 : dragPropsContext.layout) || {};
|
|
280
|
+
const itemLayout = {
|
|
280
281
|
h: maxH ? Math.min(h, maxH) : h,
|
|
281
282
|
w: maxW ? Math.min(w, maxW) : w,
|
|
282
283
|
};
|
|
283
|
-
|
|
284
|
+
if ((onDropDragOverContext === null || onDropDragOverContext === void 0 ? void 0 : onDropDragOverContext(Object.assign(Object.assign(Object.assign({}, sharedItem), itemLayout), { parent: group }), sharedItem !== null && sharedItem !== void 0 ? sharedItem : null)) === false) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
return itemLayout;
|
|
288
|
+
}, [
|
|
289
|
+
resetTemporaryLayout,
|
|
290
|
+
temporaryLayout,
|
|
291
|
+
dragOverPlugin,
|
|
292
|
+
dragPropsContext,
|
|
293
|
+
onDropDragOverContext,
|
|
294
|
+
]);
|
|
284
295
|
const onDropProp = props.onDrop;
|
|
285
296
|
const onDrop = react_1.default.useCallback((newLayout, item) => {
|
|
286
|
-
if (!
|
|
297
|
+
if (!dragPropsContext) {
|
|
287
298
|
return;
|
|
288
299
|
}
|
|
289
300
|
setTemporaryLayout({
|
|
290
301
|
data: [...newLayout, item],
|
|
291
|
-
dragProps,
|
|
302
|
+
dragProps: dragPropsContext,
|
|
292
303
|
});
|
|
293
304
|
onDropProp({
|
|
294
305
|
newLayout: newLayout.reduce((memo, l) => {
|
|
@@ -299,9 +310,9 @@ function useMemoStateContext(props) {
|
|
|
299
310
|
}, []),
|
|
300
311
|
itemLayout: (0, pick_1.default)(item, ITEM_PROPS),
|
|
301
312
|
commit: resetTemporaryLayout,
|
|
302
|
-
dragProps,
|
|
313
|
+
dragProps: dragPropsContext,
|
|
303
314
|
});
|
|
304
|
-
}, [
|
|
315
|
+
}, [dragPropsContext, onDropProp, setTemporaryLayout, resetTemporaryLayout]);
|
|
305
316
|
const dashkitContextValue = react_1.default.useMemo(() => ({
|
|
306
317
|
layout: resultLayout,
|
|
307
318
|
temporaryLayout,
|
|
@@ -383,11 +394,15 @@ function useMemoStateContext(props) {
|
|
|
383
394
|
editItem: props.onItemEdit,
|
|
384
395
|
removeItem: onItemRemove,
|
|
385
396
|
getLayoutItem: getLayoutItem,
|
|
397
|
+
getPreparedCopyItemOptions: props.getPreparedCopyItemOptions,
|
|
398
|
+
onCopyFulfill: props.onCopyFulfill,
|
|
386
399
|
}), [
|
|
387
400
|
props.overlayControls,
|
|
388
401
|
props.context,
|
|
389
402
|
props.itemsStateAndParams,
|
|
390
403
|
props.onItemEdit,
|
|
404
|
+
props.getPreparedCopyItemOptions,
|
|
405
|
+
props.onCopyFulfill,
|
|
391
406
|
overlayMenuItems,
|
|
392
407
|
itemsParams,
|
|
393
408
|
onItemRemove,
|
|
@@ -12,6 +12,10 @@ export type ItemDragProps = {
|
|
|
12
12
|
};
|
|
13
13
|
extra?: any;
|
|
14
14
|
};
|
|
15
|
+
export type DraggedOverItem = Omit<ConfigLayout, 'x' | 'y' | 'i'> & {
|
|
16
|
+
type: string;
|
|
17
|
+
i?: ConfigLayout['i'];
|
|
18
|
+
};
|
|
15
19
|
export type ItemDropProps = {
|
|
16
20
|
commit: () => void;
|
|
17
21
|
dragProps: ItemDragProps;
|
|
@@ -2,8 +2,11 @@ import type ReactGridLayout from 'react-grid-layout';
|
|
|
2
2
|
import type { OverlayCustomControlItem } from '../components/OverlayControls/OverlayControls';
|
|
3
3
|
import { MenuItems } from '../constants';
|
|
4
4
|
import { AdditionalWidgetLayout } from '../shared';
|
|
5
|
+
export type GridLayoutSettings = ReactGridLayout.ReactGridLayoutProps & {
|
|
6
|
+
noOverlay?: boolean;
|
|
7
|
+
};
|
|
5
8
|
export interface Settings {
|
|
6
|
-
gridLayout?:
|
|
9
|
+
gridLayout?: GridLayoutSettings;
|
|
7
10
|
theme?: string;
|
|
8
11
|
isMobile?: boolean;
|
|
9
12
|
menu?: Array<MenuItem>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { Layout, Layouts } from 'react-grid-layout';
|
|
3
3
|
import type { Config, ConfigItem, ConfigLayout } from '../shared';
|
|
4
|
+
import { GridLayoutSettings } from './common';
|
|
4
5
|
export interface AddConfigItem extends Omit<ConfigItem, 'id' | 'namespace'> {
|
|
5
6
|
id?: null;
|
|
6
7
|
namespace?: string;
|
|
@@ -31,7 +32,7 @@ export interface DashkitGroupRenderProps {
|
|
|
31
32
|
layout: ConfigLayout[];
|
|
32
33
|
context: any;
|
|
33
34
|
}
|
|
34
|
-
export type ReactGridLayoutProps = Omit<
|
|
35
|
+
export type ReactGridLayoutProps = Omit<GridLayoutSettings, 'children' | 'compactType' | 'innerRef' | 'key' | 'layout' | 'onDragStart' | 'onDragStop' | 'onResizeStart' | 'onResizeStop' | 'draggableHandle' | 'isDroppable' | 'onDropDragOver' | 'onDrop' | 'draggableCancel'> & {
|
|
35
36
|
compactType?: CompactType;
|
|
36
37
|
};
|
|
37
38
|
export interface DashKitGroup {
|
|
@@ -2,8 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import type { Config, ConfigItem, ConfigLayout, GlobalParams, ItemDropProps, ItemsStateAndParams } from '../../shared';
|
|
3
3
|
import { AddNewItemOptions, ContextProps, DashKitGroup, ItemManipulationCallback, MenuItem, Plugin, SetConfigItem, Settings, SettingsProps } from '../../typings';
|
|
4
4
|
import GridLayout from '../GridLayout/GridLayout';
|
|
5
|
-
import { OverlayControlItem } from '../OverlayControls/OverlayControls';
|
|
6
|
-
interface DashKitGeneralProps {
|
|
5
|
+
import { OverlayControlItem, OverlayControlsCtxShape } from '../OverlayControls/OverlayControls';
|
|
6
|
+
interface DashKitGeneralProps extends Pick<OverlayControlsCtxShape, 'getPreparedCopyItemOptions' | 'onCopyFulfill'> {
|
|
7
7
|
config: Config;
|
|
8
8
|
editMode: boolean;
|
|
9
9
|
draggableHandleClassName?: string;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ItemDragProps } from '../../shared';
|
|
2
|
+
import type { DraggedOverItem, ItemDragProps } from '../../shared';
|
|
3
3
|
type DashKitDnDWrapperProps = {
|
|
4
4
|
dragImageSrc?: string;
|
|
5
|
+
onDropDragOver?: (draggedItem: DraggedOverItem, sharedItem: DraggedOverItem | null) => void | boolean;
|
|
5
6
|
onDragStart?: (dragProps: ItemDragProps) => void;
|
|
6
7
|
onDragEnd?: () => void;
|
|
7
8
|
children: React.ReactElement;
|
|
@@ -8,23 +8,24 @@ export const DashKitDnDWrapper = (props) => {
|
|
|
8
8
|
img.src = props.dragImageSrc || defaultImageSrc;
|
|
9
9
|
return img;
|
|
10
10
|
}, [props.dragImageSrc]);
|
|
11
|
+
const onDragStartProp = props.onDragStart;
|
|
11
12
|
const onDragStart = React.useCallback((_, itemDragProps) => {
|
|
12
|
-
var _a;
|
|
13
13
|
setDragProps(itemDragProps);
|
|
14
|
-
|
|
15
|
-
}, [setDragProps,
|
|
14
|
+
onDragStartProp === null || onDragStartProp === void 0 ? void 0 : onDragStartProp(itemDragProps);
|
|
15
|
+
}, [setDragProps, onDragStartProp]);
|
|
16
|
+
const onDragEndProp = props.onDragEnd;
|
|
16
17
|
const onDragEnd = React.useCallback((_) => {
|
|
17
|
-
var _a;
|
|
18
18
|
setDragProps(null);
|
|
19
|
-
|
|
20
|
-
}, [setDragProps,
|
|
19
|
+
onDragEndProp === null || onDragEndProp === void 0 ? void 0 : onDragEndProp();
|
|
20
|
+
}, [setDragProps, onDragEndProp]);
|
|
21
21
|
const contextValue = React.useMemo(() => {
|
|
22
22
|
return {
|
|
23
23
|
dragProps,
|
|
24
24
|
dragImagePreview,
|
|
25
25
|
onDragStart,
|
|
26
26
|
onDragEnd,
|
|
27
|
+
onDropDragOver: props.onDropDragOver,
|
|
27
28
|
};
|
|
28
|
-
}, [dragProps, dragImagePreview, onDragStart, onDragEnd]);
|
|
29
|
+
}, [dragProps, dragImagePreview, onDragStart, onDragEnd, props.onDropDragOver]);
|
|
29
30
|
return (React.createElement(DashKitDnDContext.Provider, { value: contextValue }, props.children));
|
|
30
31
|
};
|
|
@@ -4,10 +4,10 @@ export default class GridLayout extends React.PureComponent<any, any, any> {
|
|
|
4
4
|
pluginsRefs: any[];
|
|
5
5
|
state: {
|
|
6
6
|
isDragging: boolean;
|
|
7
|
+
isDraggedOut: boolean;
|
|
7
8
|
isPageHidden: boolean;
|
|
8
9
|
currentDraggingElement: null;
|
|
9
10
|
draggedOverGroup: null;
|
|
10
|
-
draggedOut: boolean;
|
|
11
11
|
};
|
|
12
12
|
componentDidMount(): void;
|
|
13
13
|
componentDidUpdate(): void;
|
|
@@ -139,20 +139,27 @@ class GridLayout extends React.PureComponent {
|
|
|
139
139
|
if (currentDraggingElement) {
|
|
140
140
|
const { h, w, i } = currentDraggingElement.layoutItem;
|
|
141
141
|
const { type } = currentDraggingElement.item;
|
|
142
|
-
|
|
142
|
+
const sharedItem = {
|
|
143
|
+
h,
|
|
144
|
+
w,
|
|
145
|
+
i,
|
|
146
|
+
type,
|
|
147
|
+
parent: currentDraggingElement.group,
|
|
148
|
+
};
|
|
149
|
+
return onDropDragOver(e, group, properties, layout, sharedItem);
|
|
143
150
|
}
|
|
144
151
|
if (dragOverPlugin) {
|
|
145
|
-
return onDropDragOver(e, properties, layout);
|
|
152
|
+
return onDropDragOver(e, group, properties, layout);
|
|
146
153
|
}
|
|
147
154
|
return false;
|
|
148
155
|
};
|
|
149
156
|
this.pluginsRefs = [];
|
|
150
157
|
this.state = {
|
|
151
158
|
isDragging: false,
|
|
159
|
+
isDraggedOut: false,
|
|
152
160
|
isPageHidden: false,
|
|
153
161
|
currentDraggingElement: null,
|
|
154
162
|
draggedOverGroup: null,
|
|
155
|
-
draggedOut: false,
|
|
156
163
|
};
|
|
157
164
|
}
|
|
158
165
|
componentDidMount() {
|
|
@@ -288,7 +295,7 @@ class GridLayout extends React.PureComponent {
|
|
|
288
295
|
_initDragCoordinatesWatcher(element) {
|
|
289
296
|
if (!this._parendDragNode) {
|
|
290
297
|
this._parendDragNode = element.parentElement;
|
|
291
|
-
this.setState({
|
|
298
|
+
this.setState({ isDraggedOut: false });
|
|
292
299
|
}
|
|
293
300
|
}
|
|
294
301
|
// When element is going back and prointer-event: none is removed mouse enter event is not fired
|
|
@@ -314,19 +321,19 @@ class GridLayout extends React.PureComponent {
|
|
|
314
321
|
const parent = this._parendDragNode;
|
|
315
322
|
const parentRect = parent.getBoundingClientRect();
|
|
316
323
|
const { clientX, clientY } = e;
|
|
317
|
-
let
|
|
324
|
+
let isDraggedOut = this.state.isDraggedOut;
|
|
318
325
|
if (clientX < parentRect.left ||
|
|
319
326
|
clientX > parentRect.right ||
|
|
320
327
|
clientY < parentRect.top ||
|
|
321
328
|
clientY > parentRect.bottom) {
|
|
322
|
-
|
|
329
|
+
isDraggedOut = true;
|
|
323
330
|
}
|
|
324
331
|
else {
|
|
325
|
-
|
|
332
|
+
isDraggedOut = false;
|
|
326
333
|
}
|
|
327
|
-
if (
|
|
328
|
-
this.setState({
|
|
329
|
-
if (!
|
|
334
|
+
if (isDraggedOut !== this.state.isDraggedOut) {
|
|
335
|
+
this.setState({ isDraggedOut });
|
|
336
|
+
if (!isDraggedOut) {
|
|
330
337
|
this._forceCursorCapture(parent, {
|
|
331
338
|
top: clientY - parentRect.top,
|
|
332
339
|
left: clientX - parentRect.left,
|
|
@@ -336,23 +343,25 @@ class GridLayout extends React.PureComponent {
|
|
|
336
343
|
}
|
|
337
344
|
_resetDragWatcher() {
|
|
338
345
|
this._parendDragNode = null;
|
|
339
|
-
this.setState({
|
|
346
|
+
this.setState({ isDraggedOut: false });
|
|
340
347
|
}
|
|
341
348
|
_onDragStart(group, _newLayout, layoutItem, _newItem, _placeholder, e, element) {
|
|
342
349
|
var _a;
|
|
343
350
|
(_a = this.context.onDragStart) === null || _a === void 0 ? void 0 : _a.call(this, this.prepareDefaultArguments(group, _newLayout, layoutItem, _newItem, _placeholder, e, element));
|
|
344
|
-
this._initDragCoordinatesWatcher(element);
|
|
345
351
|
if (this.context.dragOverPlugin) {
|
|
346
352
|
this.setState({ isDragging: true });
|
|
347
353
|
}
|
|
348
354
|
else {
|
|
355
|
+
this._initDragCoordinatesWatcher(element);
|
|
349
356
|
this.updateDraggingElementState(group, layoutItem, e);
|
|
350
357
|
this.setState({ isDragging: true });
|
|
351
358
|
}
|
|
352
359
|
}
|
|
353
360
|
_onDrag(group, layout, oldItem, newItem, placeholder, e, element) {
|
|
354
361
|
var _a;
|
|
355
|
-
this.
|
|
362
|
+
if (!this.context.dragOverPlugin) {
|
|
363
|
+
this._updateDragCoordinates(e);
|
|
364
|
+
}
|
|
356
365
|
(_a = this.context.onDrag) === null || _a === void 0 ? void 0 : _a.call(this, this.prepareDefaultArguments(group, layout, oldItem, newItem, placeholder, e, element));
|
|
357
366
|
}
|
|
358
367
|
_onDragStop(group, layout, oldItem, newItem, placeholder, e, element) {
|
|
@@ -400,7 +409,8 @@ class GridLayout extends React.PureComponent {
|
|
|
400
409
|
renderGroup(group, renderLayout, renderItems, offset = 0, groupGridProperties) {
|
|
401
410
|
const { registerManager, editMode, noOverlay, focusable, draggableHandleClassName, outerDnDEnable, onItemMountChange, onItemRender, } = this.context;
|
|
402
411
|
const { currentDraggingElement, draggedOverGroup } = this.state;
|
|
403
|
-
const
|
|
412
|
+
const hasOwnGroupProperties = typeof groupGridProperties === 'function';
|
|
413
|
+
const properties = hasOwnGroupProperties
|
|
404
414
|
? groupGridProperties(Object.assign({}, registerManager.gridLayout))
|
|
405
415
|
: registerManager.gridLayout;
|
|
406
416
|
let { compactType } = properties;
|
|
@@ -413,25 +423,22 @@ class GridLayout extends React.PureComponent {
|
|
|
413
423
|
group === currentDraggingElement.group &&
|
|
414
424
|
draggedOverGroup !== null &&
|
|
415
425
|
draggedOverGroup !== group;
|
|
416
|
-
return (React.createElement(Layout
|
|
417
|
-
// Group properties
|
|
418
|
-
, Object.assign({}, properties, {
|
|
426
|
+
return (React.createElement(Layout, Object.assign({ isDraggable: editMode, isResizable: editMode }, properties, { key: `group_${group}`,
|
|
419
427
|
// Layout props
|
|
420
|
-
compactType: compactType, layout: layout,
|
|
421
|
-
? { draggableHandle: `.${draggableHandleClassName}` }
|
|
422
|
-
: null), {
|
|
428
|
+
compactType: compactType, layout: layout, draggableCancel: `.${DRAGGABLE_CANCEL_CLASS_NAME}`, draggableHandle: draggableHandleClassName ? `.${draggableHandleClassName}` : null,
|
|
423
429
|
// Default callbacks
|
|
424
430
|
onDragStart: callbacks.onDragStart, onDrag: callbacks.onDrag, onDragStop: callbacks.onDragStop, onResizeStart: callbacks.onResizeStart, onResize: callbacks.onResize, onResizeStop: callbacks.onResizeStop,
|
|
425
431
|
// External Drag N Drop options
|
|
426
|
-
onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, sharedDragPosition: currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.cursorPosition, isDragCaptured: isDragCaptured
|
|
427
|
-
? {
|
|
428
|
-
isDroppable: true,
|
|
429
|
-
}
|
|
430
|
-
: null)),
|
|
432
|
+
onDragTargetRestore: callbacks.onDragTargetRestore, onDropDragOver: callbacks.onDropDragOver, onDrop: callbacks.onDrop, hasSharedDragItem: hasSharedDragItem, sharedDragPosition: currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.cursorPosition, isDragCaptured: isDragCaptured, isDroppable: Boolean(outerDnDEnable) && editMode }),
|
|
431
433
|
renderItems.map((item, i) => {
|
|
432
|
-
const
|
|
433
|
-
const
|
|
434
|
-
|
|
434
|
+
const keyId = item.id;
|
|
435
|
+
const isDragging = this.state.isDragging;
|
|
436
|
+
const isCurrentDraggedItem = (currentDraggingElement === null || currentDraggingElement === void 0 ? void 0 : currentDraggingElement.item.id) === keyId;
|
|
437
|
+
const isDraggedOut = isCurrentDraggedItem && this.state.isDraggedOut;
|
|
438
|
+
const itemNoOverlay = hasOwnGroupProperties && 'noOverlay' in properties
|
|
439
|
+
? properties.noOverlay
|
|
440
|
+
: noOverlay;
|
|
441
|
+
return (React.createElement(GridItem, { forwardedPluginRef: this.getMemoForwardRefCallback(offset + i), key: keyId, id: keyId, item: item, layout: layout, adjustWidgetLayout: this.adjustWidgetLayout, isDragging: isDragging, isDraggedOut: isDraggedOut, noOverlay: itemNoOverlay, focusable: focusable, withCustomHandle: Boolean(draggableHandleClassName), onItemMountChange: onItemMountChange, onItemRender: onItemRender }));
|
|
435
442
|
}),
|
|
436
443
|
this.renderTemporaryPlaceholder()));
|
|
437
444
|
}
|
|
@@ -483,13 +490,14 @@ class GridLayout extends React.PureComponent {
|
|
|
483
490
|
const element = this.renderGroup(id, layout, items, offset, group.gridProperties);
|
|
484
491
|
offset += items.length;
|
|
485
492
|
if (group.render) {
|
|
486
|
-
|
|
493
|
+
const groupContext = {
|
|
487
494
|
config,
|
|
488
495
|
editMode,
|
|
489
496
|
items,
|
|
490
497
|
layout,
|
|
491
498
|
context,
|
|
492
|
-
}
|
|
499
|
+
};
|
|
500
|
+
return group.render(id, element, groupContext);
|
|
493
501
|
}
|
|
494
502
|
return element;
|
|
495
503
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ReactGridLayout, { WidthProvider, utils } from 'react-grid-layout';
|
|
3
|
-
import { OVERLAY_CLASS_NAME } from '../../constants';
|
|
3
|
+
import { DROPPING_ELEMENT_CLASS_NAME, OVERLAY_CLASS_NAME } from '../../constants';
|
|
4
4
|
class DragOverLayout extends ReactGridLayout {
|
|
5
5
|
constructor(...args) {
|
|
6
6
|
super(...args);
|
|
@@ -153,6 +153,20 @@ class DragOverLayout extends ReactGridLayout {
|
|
|
153
153
|
var _a;
|
|
154
154
|
return ((_a = this.props.innerRef) === null || _a === void 0 ? void 0 : _a.current) || null;
|
|
155
155
|
}
|
|
156
|
+
calculateDroppingPosition(itemProps) {
|
|
157
|
+
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition } = itemProps;
|
|
158
|
+
const { sharedDragPosition } = this.props;
|
|
159
|
+
let offsetX, offsetY;
|
|
160
|
+
if (sharedDragPosition) {
|
|
161
|
+
offsetX = sharedDragPosition.offsetX;
|
|
162
|
+
offsetY = sharedDragPosition.offsetY;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
offsetX = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
166
|
+
offsetY = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
167
|
+
}
|
|
168
|
+
return Object.assign(Object.assign({}, droppingPosition), { left: droppingPosition.left - offsetX, top: droppingPosition.top - offsetY });
|
|
169
|
+
}
|
|
156
170
|
// Drop item from outside gets 0,0 droppingPosition
|
|
157
171
|
// centering cursor on newly creted grid item
|
|
158
172
|
// And cause grid-layout using it's own GridItem to make it look
|
|
@@ -163,26 +177,14 @@ class DragOverLayout extends ReactGridLayout {
|
|
|
163
177
|
if (!gridItem) {
|
|
164
178
|
return gridItem;
|
|
165
179
|
}
|
|
166
|
-
const { props: itemProps } = gridItem;
|
|
167
180
|
if (isDroppingItem) {
|
|
168
|
-
const { containerWidth, cols, w, h, rowHeight, margin, transformScale, droppingPosition, } = itemProps;
|
|
169
|
-
const { sharedDragPosition, hasSharedDragItem } = this.props;
|
|
170
|
-
let offsetX, offsetY;
|
|
171
|
-
if (sharedDragPosition) {
|
|
172
|
-
offsetX = sharedDragPosition.offsetX;
|
|
173
|
-
offsetY = sharedDragPosition.offsetY;
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
offsetX = (((containerWidth / cols) * w) / 2 || 0) * transformScale;
|
|
177
|
-
offsetY = ((h * rowHeight + (h - 1) * margin[1]) / 2 || 0) * transformScale;
|
|
178
|
-
}
|
|
179
|
-
const style = gridItem.props.style || null;
|
|
180
181
|
// React.cloneElement is just cleaner then copy-paste whole processGridItem method
|
|
181
182
|
return React.cloneElement(gridItem, {
|
|
182
|
-
// hiding
|
|
183
|
-
style:
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
// hiding preview if dragging shared item
|
|
184
|
+
style: this.props.hasSharedDragItem
|
|
185
|
+
? Object.assign(Object.assign({}, gridItem.props.style), { opacity: 0 }) : gridItem.props.style,
|
|
186
|
+
className: `${OVERLAY_CLASS_NAME} ${DROPPING_ELEMENT_CLASS_NAME}`,
|
|
187
|
+
droppingPosition: this.calculateDroppingPosition(gridItem.props),
|
|
186
188
|
});
|
|
187
189
|
}
|
|
188
190
|
return gridItem;
|
|
@@ -51,7 +51,7 @@ type PreparedCopyItemOptionsArg = Pick<ConfigItem, 'data' | 'type' | 'defaults'
|
|
|
51
51
|
export type PreparedCopyItemOptions<C extends object = {}> = PreparedCopyItemOptionsArg & {
|
|
52
52
|
copyContext?: C;
|
|
53
53
|
};
|
|
54
|
-
|
|
54
|
+
export interface OverlayControlsCtxShape {
|
|
55
55
|
overlayControls?: Record<string, OverlayControlItem[]>;
|
|
56
56
|
context: Record<string, any>;
|
|
57
57
|
menu: MenuItem[];
|
|
@@ -60,11 +60,14 @@ type DashKitCtx = React.Context<{
|
|
|
60
60
|
editItem: (item: ConfigItem) => void;
|
|
61
61
|
removeItem: (id: string) => void;
|
|
62
62
|
getLayoutItem: (id: string) => ConfigLayout | void;
|
|
63
|
-
|
|
63
|
+
getPreparedCopyItemOptions?: (options: PreparedCopyItemOptions) => PreparedCopyItemOptions;
|
|
64
|
+
onCopyFulfill?: (error: null | Error, data?: PreparedCopyItemOptions) => void;
|
|
65
|
+
}
|
|
66
|
+
type OverlayControlsCtx = React.Context<OverlayControlsCtxShape>;
|
|
64
67
|
declare class OverlayControls extends React.Component<OverlayControlsProps> {
|
|
65
68
|
static contextType: React.Context<any>;
|
|
66
69
|
static defaultProps: OverlayControlsDefaultProps;
|
|
67
|
-
context: React.ContextType<
|
|
70
|
+
context: React.ContextType<OverlayControlsCtx>;
|
|
68
71
|
render(): JSX.Element;
|
|
69
72
|
private getItems;
|
|
70
73
|
private renderControlsItem;
|
|
@@ -29,7 +29,7 @@ class OverlayControls extends React.Component {
|
|
|
29
29
|
const { view, size, onItemClick } = this.props;
|
|
30
30
|
const { title, handler, icon, iconSize, qa } = item;
|
|
31
31
|
const onItemClickHandler = typeof handler === 'function' ? handler : noop;
|
|
32
|
-
return (React.createElement(Button, { key: index
|
|
32
|
+
return (React.createElement(Button, { key: `control_${index}`, view: view, size: size, title: title, pin: this.getControlItemPinStyle(index, length), onClick: () => {
|
|
33
33
|
onItemClickHandler(this.props.configItem);
|
|
34
34
|
onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick();
|
|
35
35
|
}, qa: qa },
|
|
@@ -40,7 +40,7 @@ class OverlayControls extends React.Component {
|
|
|
40
40
|
if (this.context.overlayControls === null) {
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
|
-
return (React.createElement(Button, { view: view, size: size, title: i18n('label_settings'), pin: "round-brick", onClick: this.onEditItem, qa: "dashkit-overlay-control-settings" },
|
|
43
|
+
return (React.createElement(Button, { key: 'control_default', view: view, size: size, title: i18n('label_settings'), pin: "round-brick", onClick: this.onEditItem, qa: "dashkit-overlay-control-settings" },
|
|
44
44
|
React.createElement(Icon, { data: Gear, size: OVERLAY_ICON_SIZE })));
|
|
45
45
|
};
|
|
46
46
|
this.getCustomLeftOverlayControls = () => {
|
|
@@ -76,7 +76,7 @@ class OverlayControls extends React.Component {
|
|
|
76
76
|
return controls;
|
|
77
77
|
};
|
|
78
78
|
this.onCopyItem = () => {
|
|
79
|
-
var _a, _b, _c;
|
|
79
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
80
80
|
const { configItem } = this.props;
|
|
81
81
|
const correspondedItemLayout = this.context.getLayoutItem(configItem.id);
|
|
82
82
|
let targetInnerId;
|
|
@@ -99,13 +99,24 @@ class OverlayControls extends React.Component {
|
|
|
99
99
|
targetId: this.props.configItem.id,
|
|
100
100
|
targetInnerId,
|
|
101
101
|
};
|
|
102
|
-
if (
|
|
102
|
+
if ((_a = this.context.context) === null || _a === void 0 ? void 0 : _a.getPreparedCopyItemOptions) {
|
|
103
|
+
(_b = console.warn) === null || _b === void 0 ? void 0 : _b.call(console, '`context.getPreparedCopyItemOptions` is deprecated. Please use `getPreparedCopyItemOptions` prop instead');
|
|
104
|
+
}
|
|
105
|
+
const getPreparedCopyItemOptions = (_d = (_c = this.context) === null || _c === void 0 ? void 0 : _c.getPreparedCopyItemOptions) !== null && _d !== void 0 ? _d : (_e = this.context.context) === null || _e === void 0 ? void 0 : _e.getPreparedCopyItemOptions;
|
|
106
|
+
if (typeof getPreparedCopyItemOptions === 'function') {
|
|
103
107
|
options = this.context.context.getPreparedCopyItemOptions(options);
|
|
104
108
|
}
|
|
105
|
-
|
|
109
|
+
try {
|
|
110
|
+
localStorage.setItem(COPIED_WIDGET_STORE_KEY, JSON.stringify(options));
|
|
111
|
+
(_g = (_f = this.context).onCopyFulfill) === null || _g === void 0 ? void 0 : _g.call(_f, null, options);
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
const error = e instanceof Error ? e : new Error('Unknown error while copying item');
|
|
115
|
+
(_j = (_h = this.context).onCopyFulfill) === null || _j === void 0 ? void 0 : _j.call(_h, error);
|
|
116
|
+
}
|
|
106
117
|
// https://stackoverflow.com/questions/35865481/storage-event-not-firing
|
|
107
118
|
window.dispatchEvent(new Event('storage'));
|
|
108
|
-
(
|
|
119
|
+
(_l = (_k = this.props).onItemClick) === null || _l === void 0 ? void 0 : _l.call(_k);
|
|
109
120
|
};
|
|
110
121
|
this.onEditItem = () => {
|
|
111
122
|
var _a, _b;
|
|
@@ -158,10 +169,9 @@ class OverlayControls extends React.Component {
|
|
|
158
169
|
renderControls() {
|
|
159
170
|
const customLeftControls = this.getCustomLeftOverlayControls();
|
|
160
171
|
const hasCustomOverlayLeftControls = Boolean(customLeftControls.length);
|
|
161
|
-
const defaultControl = this.getDefaultControls();
|
|
162
172
|
const controls = hasCustomOverlayLeftControls
|
|
163
173
|
? customLeftControls.map((item, index, items) => this.renderControlsItem(item, index, items.length + 1))
|
|
164
|
-
:
|
|
174
|
+
: this.getDefaultControls();
|
|
165
175
|
const menu = this.renderMenu(controls === null);
|
|
166
176
|
return (React.createElement("div", { className: b('default-controls', {
|
|
167
177
|
'with-custom-left': hasCustomOverlayLeftControls,
|
|
@@ -228,7 +238,7 @@ class OverlayControls extends React.Component {
|
|
|
228
238
|
if (items.length === 0) {
|
|
229
239
|
return null;
|
|
230
240
|
}
|
|
231
|
-
return (React.createElement(DropdownMenu, { items: items, renderSwitcher: (props) => (React.createElement(Button, Object.assign({}, props, { view: view, size: size, pin: isOnlyOneItem ? 'round-round' : 'brick-round', qa: "dashkit-overlay-control-menu" }),
|
|
241
|
+
return (React.createElement(DropdownMenu, { key: 'controls_dropdown', items: items, renderSwitcher: (props) => (React.createElement(Button, Object.assign({}, props, { view: view, size: size, pin: isOnlyOneItem ? 'round-round' : 'brick-round', qa: "dashkit-overlay-control-menu" }),
|
|
232
242
|
React.createElement(Icon, { data: Ellipsis, size: OVERLAY_ICON_SIZE }))), popupProps: {
|
|
233
243
|
contentClassName: DRAGGABLE_CANCEL_CLASS_NAME,
|
|
234
244
|
} }));
|
|
@@ -15,3 +15,4 @@ export declare const DEFAULT_GROUP = "__default";
|
|
|
15
15
|
export declare const COMPACT_TYPE_HORIZONTAL_NOWRAP = "horizontal-nowrap";
|
|
16
16
|
export declare const DRAGGABLE_CANCEL_CLASS_NAME = "dashkit_draggable_cancel";
|
|
17
17
|
export declare const FOCUSED_CLASS_NAME = "dashkit_focused";
|
|
18
|
+
export declare const DROPPING_ELEMENT_CLASS_NAME = "dropping";
|
|
@@ -15,3 +15,4 @@ export const DEFAULT_GROUP = '__default';
|
|
|
15
15
|
export const COMPACT_TYPE_HORIZONTAL_NOWRAP = 'horizontal-nowrap';
|
|
16
16
|
export const DRAGGABLE_CANCEL_CLASS_NAME = 'dashkit_draggable_cancel';
|
|
17
17
|
export const FOCUSED_CLASS_NAME = 'dashkit_focused';
|
|
18
|
+
export const DROPPING_ELEMENT_CLASS_NAME = 'dropping';
|
|
@@ -229,12 +229,13 @@ function useMemoStateContext(props) {
|
|
|
229
229
|
const reloadItems = React.useCallback((pluginsRefs, data) => {
|
|
230
230
|
pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
|
|
231
231
|
}, []);
|
|
232
|
-
const
|
|
232
|
+
const dragPropsContext = dndContext === null || dndContext === void 0 ? void 0 : dndContext.dragProps;
|
|
233
|
+
const onDropDragOverContext = dndContext === null || dndContext === void 0 ? void 0 : dndContext.onDropDragOver;
|
|
233
234
|
const dragOverPlugin = React.useMemo(() => {
|
|
234
|
-
if (!
|
|
235
|
+
if (!dragPropsContext) {
|
|
235
236
|
return null;
|
|
236
237
|
}
|
|
237
|
-
const pluginType =
|
|
238
|
+
const pluginType = dragPropsContext.type;
|
|
238
239
|
if (props.registerManager.check(pluginType)) {
|
|
239
240
|
return props.registerManager.getItem(pluginType);
|
|
240
241
|
}
|
|
@@ -243,8 +244,8 @@ function useMemoStateContext(props) {
|
|
|
243
244
|
console.error(`Uknown pluginType: ${pluginType}`);
|
|
244
245
|
return null;
|
|
245
246
|
}
|
|
246
|
-
}, [
|
|
247
|
-
const onDropDragOver = React.useCallback((_e, gridProps, groupLayout, sharedItem) => {
|
|
247
|
+
}, [dragPropsContext, props.registerManager]);
|
|
248
|
+
const onDropDragOver = React.useCallback((_e, group, gridProps, groupLayout, sharedItem) => {
|
|
248
249
|
if (temporaryLayout) {
|
|
249
250
|
resetTemporaryLayout();
|
|
250
251
|
return false;
|
|
@@ -272,20 +273,30 @@ function useMemoStateContext(props) {
|
|
|
272
273
|
maxH < defaultLayout.minH) {
|
|
273
274
|
return false;
|
|
274
275
|
}
|
|
275
|
-
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, } = (
|
|
276
|
-
|
|
276
|
+
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, } = (dragPropsContext === null || dragPropsContext === void 0 ? void 0 : dragPropsContext.layout) || {};
|
|
277
|
+
const itemLayout = {
|
|
277
278
|
h: maxH ? Math.min(h, maxH) : h,
|
|
278
279
|
w: maxW ? Math.min(w, maxW) : w,
|
|
279
280
|
};
|
|
280
|
-
|
|
281
|
+
if ((onDropDragOverContext === null || onDropDragOverContext === void 0 ? void 0 : onDropDragOverContext(Object.assign(Object.assign(Object.assign({}, sharedItem), itemLayout), { parent: group }), sharedItem !== null && sharedItem !== void 0 ? sharedItem : null)) === false) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
return itemLayout;
|
|
285
|
+
}, [
|
|
286
|
+
resetTemporaryLayout,
|
|
287
|
+
temporaryLayout,
|
|
288
|
+
dragOverPlugin,
|
|
289
|
+
dragPropsContext,
|
|
290
|
+
onDropDragOverContext,
|
|
291
|
+
]);
|
|
281
292
|
const onDropProp = props.onDrop;
|
|
282
293
|
const onDrop = React.useCallback((newLayout, item) => {
|
|
283
|
-
if (!
|
|
294
|
+
if (!dragPropsContext) {
|
|
284
295
|
return;
|
|
285
296
|
}
|
|
286
297
|
setTemporaryLayout({
|
|
287
298
|
data: [...newLayout, item],
|
|
288
|
-
dragProps,
|
|
299
|
+
dragProps: dragPropsContext,
|
|
289
300
|
});
|
|
290
301
|
onDropProp({
|
|
291
302
|
newLayout: newLayout.reduce((memo, l) => {
|
|
@@ -296,9 +307,9 @@ function useMemoStateContext(props) {
|
|
|
296
307
|
}, []),
|
|
297
308
|
itemLayout: pick(item, ITEM_PROPS),
|
|
298
309
|
commit: resetTemporaryLayout,
|
|
299
|
-
dragProps,
|
|
310
|
+
dragProps: dragPropsContext,
|
|
300
311
|
});
|
|
301
|
-
}, [
|
|
312
|
+
}, [dragPropsContext, onDropProp, setTemporaryLayout, resetTemporaryLayout]);
|
|
302
313
|
const dashkitContextValue = React.useMemo(() => ({
|
|
303
314
|
layout: resultLayout,
|
|
304
315
|
temporaryLayout,
|
|
@@ -380,11 +391,15 @@ function useMemoStateContext(props) {
|
|
|
380
391
|
editItem: props.onItemEdit,
|
|
381
392
|
removeItem: onItemRemove,
|
|
382
393
|
getLayoutItem: getLayoutItem,
|
|
394
|
+
getPreparedCopyItemOptions: props.getPreparedCopyItemOptions,
|
|
395
|
+
onCopyFulfill: props.onCopyFulfill,
|
|
383
396
|
}), [
|
|
384
397
|
props.overlayControls,
|
|
385
398
|
props.context,
|
|
386
399
|
props.itemsStateAndParams,
|
|
387
400
|
props.onItemEdit,
|
|
401
|
+
props.getPreparedCopyItemOptions,
|
|
402
|
+
props.onCopyFulfill,
|
|
388
403
|
overlayMenuItems,
|
|
389
404
|
itemsParams,
|
|
390
405
|
onItemRemove,
|
|
@@ -12,6 +12,10 @@ export type ItemDragProps = {
|
|
|
12
12
|
};
|
|
13
13
|
extra?: any;
|
|
14
14
|
};
|
|
15
|
+
export type DraggedOverItem = Omit<ConfigLayout, 'x' | 'y' | 'i'> & {
|
|
16
|
+
type: string;
|
|
17
|
+
i?: ConfigLayout['i'];
|
|
18
|
+
};
|
|
15
19
|
export type ItemDropProps = {
|
|
16
20
|
commit: () => void;
|
|
17
21
|
dragProps: ItemDragProps;
|
|
@@ -2,8 +2,11 @@ import type ReactGridLayout from 'react-grid-layout';
|
|
|
2
2
|
import type { OverlayCustomControlItem } from '../components/OverlayControls/OverlayControls';
|
|
3
3
|
import { MenuItems } from '../constants';
|
|
4
4
|
import { AdditionalWidgetLayout } from '../shared';
|
|
5
|
+
export type GridLayoutSettings = ReactGridLayout.ReactGridLayoutProps & {
|
|
6
|
+
noOverlay?: boolean;
|
|
7
|
+
};
|
|
5
8
|
export interface Settings {
|
|
6
|
-
gridLayout?:
|
|
9
|
+
gridLayout?: GridLayoutSettings;
|
|
7
10
|
theme?: string;
|
|
8
11
|
isMobile?: boolean;
|
|
9
12
|
menu?: Array<MenuItem>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { Layout, Layouts } from 'react-grid-layout';
|
|
3
3
|
import type { Config, ConfigItem, ConfigLayout } from '../shared';
|
|
4
|
+
import { GridLayoutSettings } from './common';
|
|
4
5
|
export interface AddConfigItem extends Omit<ConfigItem, 'id' | 'namespace'> {
|
|
5
6
|
id?: null;
|
|
6
7
|
namespace?: string;
|
|
@@ -31,7 +32,7 @@ export interface DashkitGroupRenderProps {
|
|
|
31
32
|
layout: ConfigLayout[];
|
|
32
33
|
context: any;
|
|
33
34
|
}
|
|
34
|
-
export type ReactGridLayoutProps = Omit<
|
|
35
|
+
export type ReactGridLayoutProps = Omit<GridLayoutSettings, 'children' | 'compactType' | 'innerRef' | 'key' | 'layout' | 'onDragStart' | 'onDragStop' | 'onResizeStart' | 'onResizeStop' | 'draggableHandle' | 'isDroppable' | 'onDropDragOver' | 'onDrop' | 'draggableCancel'> & {
|
|
35
36
|
compactType?: CompactType;
|
|
36
37
|
};
|
|
37
38
|
export interface DashKitGroup {
|