diff --git a/src/canvas/canvas.js b/src/canvas/canvas.js index 09ffa5d..9accaab 100644 --- a/src/canvas/canvas.js +++ b/src/canvas/canvas.js @@ -25,6 +25,7 @@ import { ActiveWidgetContext, ActiveWidgetProvider, withActiveWidget } from "./a import { DragWidgetProvider } from "./widgets/draggableWidgetContext" import { PosType } from "./constants/layouts" import WidgetContainer from "./constants/containers" +import { isSubClassOfWidget } from "../utils/widget" // const DotsBackground = require("../assets/background/dots.svg") @@ -106,6 +107,8 @@ class Canvas extends React.Component { this.clearSelections = this.clearSelections.bind(this) this.clearCanvas = this.clearCanvas.bind(this) + this.createWidget = this.createWidget.bind(this) + // this.updateCanvasDimensions = this.updateCanvasDimensions.bind(this) } @@ -625,19 +628,20 @@ class Canvas extends React.Component { * @param {object} dragElement * @param {boolean} create - if create is set to true the widget will be created before adding to the child tree */ - handleAddWidgetChild = ({ parentWidgetId, dragElementID, create = false, swap = false }) => { - + handleAddWidgetChild = ({ parentWidgetId, dragElementID, swap = false }) => { + // TODO: creation of the child widget if its not created // widgets data structure { id, widgetType: widgetComponentType, children: [], parent: "" } const dropWidgetObj = this.findWidgetFromListById(parentWidgetId) // Find the dragged widget object let dragWidgetObj = this.findWidgetFromListById(dragElementID) + console.log("Drag widget obj: ", dragWidgetObj) + if (dropWidgetObj && dragWidgetObj) { const dragWidget = this.widgetRefs[dragWidgetObj.id] const dragData = dragWidget.current.serialize() - if (swap) { // If swapping, we need to find the common parent const grandParentWidgetObj = this.findWidgetFromListById(dropWidgetObj.parent) @@ -704,6 +708,11 @@ class Canvas extends React.Component { * @param {Widget} widgetComponentType - don't pass instead pass Widget object/class */ createWidget(widgetComponentType, callback) { + + if (!isSubClassOfWidget(widgetComponentType)){ + throw new Error("widgetComponentType must be a subclass of Widget class") + } + const widgetRef = React.createRef() const id = `${widgetComponentType.widgetType}_${UID()}` @@ -933,6 +942,7 @@ class Canvas extends React.Component { canvasRef={this.canvasContainerRef} onWidgetUpdate={this.onActiveWidgetUpdate} onAddChildWidget={this.handleAddWidgetChild} + onCreateWidgetRequest={this.createWidget} // create widget when dropped from sidebar onWidgetResizing={(resizeSide) => this.setState({ widgetResizing: resizeSide })} > {/* Render children inside the parent with layout applied */} diff --git a/src/canvas/widgets/base.js b/src/canvas/widgets/base.js index 4553b28..51761fa 100644 --- a/src/canvas/widgets/base.js +++ b/src/canvas/widgets/base.js @@ -187,7 +187,7 @@ class Widget extends React.Component { updateState = (newState, callback) => { - // FIXME: maximum recursion error when updating size + // FIXME: maximum recursion error when updating size, color etc this.setState(newState, () => { const { onWidgetUpdate } = this.props @@ -368,23 +368,22 @@ class Widget extends React.Component { * @param {any} value */ setAttrValue(path, value) { - this.setState((prevState) => { - // Split the path to access the nested property (e.g., "styling.backgroundColor") - const keys = path.split('.') - const lastKey = keys.pop() - // Traverse the state and update the nested value immutably - let newAttrs = { ...prevState.attrs } - let nestedObject = newAttrs + const keys = path.split('.') + const lastKey = keys.pop() - keys.forEach(key => { - nestedObject[key] = { ...nestedObject[key] } // Ensure immutability - nestedObject = nestedObject[key] - }) - nestedObject[lastKey].value = value - - return { attrs: newAttrs } + // Traverse the state and update the nested value immutably + let newAttrs = { ...this.state.attrs } + let nestedObject = newAttrs + + keys.forEach(key => { + nestedObject[key] = { ...nestedObject[key] } // Ensure immutability + nestedObject = nestedObject[key] }) + + nestedObject[lastKey].value = value + + this.updateState({attrs: newAttrs}) } /** @@ -677,7 +676,7 @@ class Widget extends React.Component { } - handleDropEvent = (e, draggedElement) => { + handleDropEvent = (e, draggedElement, widgetClass=null) => { e.preventDefault() e.stopPropagation() // FIXME: sometimes the elements showDroppableStyle is not gone, when dropping on the same widget @@ -731,7 +730,9 @@ class Widget extends React.Component { }else if (container === WidgetContainer.SIDEBAR){ // console.log("Dropped on Sidebar: ", this.__id) - this.props.onAddChildWidget({parentWidgetId: this.__id, create: true}) // if dragged from the sidebar create the widget first + this.props.onCreateWidgetRequest(widgetClass, ({id, widgetRef}) => { + this.props.onAddChildWidget({parentWidgetId: this.__id, dragElementID: id}) // if dragged from the sidebar create the widget first + }) } @@ -802,7 +803,7 @@ class Widget extends React.Component { { - ({draggedElement, onDragStart, onDragEnd, setOverElement}) => ( + ({draggedElement, widgetClass, onDragStart, onDragEnd, setOverElement}) => (
this.handleDragOver(e, draggedElement)} - onDrop={(e) => this.handleDropEvent(e, draggedElement)} + onDrop={(e) => this.handleDropEvent(e, draggedElement, widgetClass)} onDragEnter={(e) => this.handleDragEnter(e, draggedElement, setOverElement)} onDragLeave={(e) => this.handleDragLeave(e, draggedElement)}