2019-09-25 17:24:23 +00:00
|
|
|
import React, { useState } from "react";
|
|
|
|
|
import { WidgetProps } from "../widgets/BaseWidget";
|
|
|
|
|
import { WidgetConfigProps } from "../reducers/entityReducers/widgetConfigReducer";
|
|
|
|
|
import { useDrop, XYCoord } from "react-dnd";
|
2019-09-17 10:09:00 +00:00
|
|
|
import { ContainerProps } from "./ContainerComponent";
|
|
|
|
|
import WidgetFactory from "../utils/WidgetFactory";
|
2019-09-19 22:25:37 +00:00
|
|
|
|
2019-09-25 17:24:23 +00:00
|
|
|
import { widgetOperationParams } from "../utils/WidgetPropsUtils";
|
|
|
|
|
import DragLayerComponent from "./DragLayerComponent";
|
|
|
|
|
import DropTargetMask from "./DropTargetMask";
|
2019-09-22 20:25:05 +00:00
|
|
|
|
2019-09-25 17:24:23 +00:00
|
|
|
/*TODO:
|
|
|
|
|
- Try to keep only component props, state and drop hook here - DONE
|
|
|
|
|
- Move all child components to their own file - DONE
|
|
|
|
|
- Provide Draglayer with the actual component size if exists
|
|
|
|
|
- else pull it from widgetConfig - DONE
|
|
|
|
|
- Provide Draglayer with rows, columns, rowHeight, columnWidth instead of width height pixels - DONE
|
|
|
|
|
- Return rows and columns to the drop handler (updateWidget) - DONE
|
2019-09-25 18:33:56 +00:00
|
|
|
- Update WidgetOperations to handle rows and columns - DONE
|
2019-09-25 17:24:23 +00:00
|
|
|
- Increase default canvas rowHeight
|
|
|
|
|
- Fix child container positioning
|
2019-09-25 18:33:56 +00:00
|
|
|
- Fix dropping into another component issue
|
|
|
|
|
|
2019-09-25 17:24:23 +00:00
|
|
|
*/
|
2019-09-19 22:25:37 +00:00
|
|
|
|
2019-09-17 15:09:55 +00:00
|
|
|
type DropTargetComponentProps = ContainerProps & {
|
2019-09-19 22:25:37 +00:00
|
|
|
updateWidget?: Function;
|
2019-09-25 17:24:23 +00:00
|
|
|
snapColumns?: number;
|
|
|
|
|
snapRows?: number;
|
|
|
|
|
snapColumnSpace: number;
|
|
|
|
|
snapRowSpace: number;
|
2019-09-17 15:09:55 +00:00
|
|
|
};
|
2019-09-19 22:25:37 +00:00
|
|
|
|
2019-09-25 17:24:23 +00:00
|
|
|
type DropTargetBounds = {
|
|
|
|
|
x: number;
|
|
|
|
|
y: number;
|
|
|
|
|
width: number;
|
|
|
|
|
height: number;
|
|
|
|
|
};
|
2019-09-19 22:25:37 +00:00
|
|
|
|
2019-09-17 10:09:00 +00:00
|
|
|
export const DropTargetComponent = (props: DropTargetComponentProps) => {
|
2019-09-25 17:24:23 +00:00
|
|
|
// Hook to keep the bounds of the drop target container in state
|
|
|
|
|
const [dropTargetOffset, setDropTargetOffset] = useState({ x: 0, y: 0 });
|
2019-09-19 22:25:37 +00:00
|
|
|
|
2019-09-25 17:24:23 +00:00
|
|
|
// Make this component a drop target
|
2019-09-21 01:52:38 +00:00
|
|
|
const [{ isOver }, drop] = useDrop({
|
2019-09-17 10:09:00 +00:00
|
|
|
accept: Object.values(WidgetFactory.getWidgetTypes()),
|
2019-09-25 17:24:23 +00:00
|
|
|
drop(widget: WidgetProps & Partial<WidgetConfigProps>, monitor) {
|
|
|
|
|
// Make sure we're dropping in this container.
|
|
|
|
|
if (isOver) {
|
|
|
|
|
props.updateWidget &&
|
|
|
|
|
props.updateWidget(
|
|
|
|
|
...widgetOperationParams(
|
|
|
|
|
widget,
|
|
|
|
|
monitor.getClientOffset() as XYCoord,
|
|
|
|
|
dropTargetOffset,
|
|
|
|
|
props.snapColumnSpace,
|
|
|
|
|
props.snapRowSpace,
|
|
|
|
|
props.widgetId,
|
|
|
|
|
),
|
2019-09-19 22:25:37 +00:00
|
|
|
);
|
2019-09-17 10:09:00 +00:00
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
},
|
2019-09-25 17:24:23 +00:00
|
|
|
// Collect isOver for ui transforms when hovering over this component
|
2019-09-19 22:25:37 +00:00
|
|
|
collect: monitor => ({
|
|
|
|
|
isOver: !!monitor.isOver({ shallow: true }),
|
|
|
|
|
}),
|
2019-09-25 18:33:56 +00:00
|
|
|
hover: (widget, monitor) => {
|
|
|
|
|
console.log(props.widgetId, monitor.isOver({ shallow: true }));
|
|
|
|
|
},
|
2019-09-25 17:24:23 +00:00
|
|
|
// Only allow drop if the drag object is directly over this component
|
|
|
|
|
// As opposed to the drag object being over a child component, or outside the component bounds
|
2019-09-24 12:36:03 +00:00
|
|
|
canDrop: (widget, monitor) => {
|
2019-09-19 22:25:37 +00:00
|
|
|
return monitor.isOver({ shallow: true });
|
2019-09-17 10:09:00 +00:00
|
|
|
},
|
|
|
|
|
});
|
2019-09-25 17:24:23 +00:00
|
|
|
|
|
|
|
|
const handleBoundsUpdate = (rect: DOMRect) => {
|
|
|
|
|
if (rect.x !== dropTargetOffset.x || rect.y !== dropTargetOffset.y) {
|
|
|
|
|
setDropTargetOffset({
|
|
|
|
|
x: rect.x,
|
|
|
|
|
y: rect.y,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-09-17 10:09:00 +00:00
|
|
|
return (
|
2019-09-25 17:24:23 +00:00
|
|
|
<div
|
2019-09-17 10:09:00 +00:00
|
|
|
ref={drop}
|
|
|
|
|
style={{
|
2019-09-25 17:24:23 +00:00
|
|
|
position: "relative",
|
2019-09-17 10:09:00 +00:00
|
|
|
left: props.style.xPosition + props.style.xPositionUnit,
|
2019-09-24 12:36:03 +00:00
|
|
|
height: props.style.componentHeight,
|
|
|
|
|
width: props.style.componentWidth,
|
2019-09-17 10:09:00 +00:00
|
|
|
top: props.style.yPosition + props.style.yPositionUnit,
|
|
|
|
|
}}
|
|
|
|
|
>
|
2019-09-25 17:24:23 +00:00
|
|
|
<DropTargetMask
|
|
|
|
|
rowHeight={props.snapRowSpace}
|
|
|
|
|
columnWidth={props.snapColumnSpace}
|
|
|
|
|
setBounds={handleBoundsUpdate}
|
|
|
|
|
/>
|
2019-09-21 01:52:38 +00:00
|
|
|
<DragLayerComponent
|
2019-09-25 17:24:23 +00:00
|
|
|
parentOffset={dropTargetOffset}
|
|
|
|
|
parentRowHeight={props.snapRowSpace}
|
|
|
|
|
parentColumnWidth={props.snapColumnSpace}
|
2019-09-19 22:25:37 +00:00
|
|
|
visible={isOver}
|
|
|
|
|
/>
|
|
|
|
|
{props.children}
|
2019-09-25 17:24:23 +00:00
|
|
|
</div>
|
2019-09-17 10:09:00 +00:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default DropTargetComponent;
|