diff --git a/src/Components/ElementsSidebar/ElementsSidebar.test.tsx b/src/Components/ElementsSidebar/ElementsSidebar.test.tsx index bca12ba..0e58142 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.test.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.test.tsx @@ -12,8 +12,8 @@ describe.concurrent('Elements sidebar', () => { isHistoryOpen={false} SelectedContainer={null} onPropertyChange={() => {}} - SelectContainer={() => {}} - DeleteContainer={() => {}} + selectContainer={() => {}} + deleteContainer={() => {}} />); expect(screen.getByText(/Elements/i)); @@ -40,8 +40,8 @@ describe.concurrent('Elements sidebar', () => { isHistoryOpen={false} SelectedContainer={null} onPropertyChange={() => {}} - SelectContainer={() => {}} - DeleteContainer={() => {}} + selectContainer={() => {}} + deleteContainer={() => {}} />); expect(screen.getByText(/Elements/i)); @@ -70,8 +70,8 @@ describe.concurrent('Elements sidebar', () => { isHistoryOpen={false} SelectedContainer={MainContainer} onPropertyChange={() => {}} - SelectContainer={() => {}} - DeleteContainer={() => {}} + selectContainer={() => {}} + deleteContainer={() => {}} />); expect(screen.getByText(/Elements/i)); @@ -155,8 +155,8 @@ describe.concurrent('Elements sidebar', () => { isHistoryOpen={false} SelectedContainer={MainContainer} onPropertyChange={() => {}} - SelectContainer={() => {}} - DeleteContainer={() => {}} + selectContainer={() => {}} + deleteContainer={() => {}} />); expect(screen.getByText(/Elements/i)); @@ -208,8 +208,8 @@ describe.concurrent('Elements sidebar', () => { isHistoryOpen={false} SelectedContainer={SelectedContainer} onPropertyChange={() => {}} - SelectContainer={selectContainer} - DeleteContainer={() => {}} + selectContainer={selectContainer} + deleteContainer={() => {}} />); expect(screen.getByText(/Elements/i)); @@ -230,8 +230,8 @@ describe.concurrent('Elements sidebar', () => { isHistoryOpen={false} SelectedContainer={SelectedContainer} onPropertyChange={() => {}} - SelectContainer={selectContainer} - DeleteContainer={() => {}} + selectContainer={selectContainer} + deleteContainer={() => {}} />); expect((propertyId as HTMLInputElement).value === 'main').toBeFalsy(); diff --git a/src/Components/ElementsSidebar/ElementsSidebar.tsx b/src/Components/ElementsSidebar/ElementsSidebar.tsx index 47a2379..621316b 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { motion } from 'framer-motion'; import { Properties } from '../Properties/Properties'; import { IContainerModel } from '../../Interfaces/ContainerModel'; -import { findContainerById, getDepth, MakeIterator } from '../../utils/itertools'; +import { getDepth, MakeIterator } from '../../utils/itertools'; import { Menu } from '../Menu/Menu'; import { MenuItem } from '../Menu/MenuItem'; @@ -12,9 +12,8 @@ interface IElementsSidebarProps { isHistoryOpen: boolean SelectedContainer: IContainerModel | null onPropertyChange: (key: string, value: string) => void - SelectContainer: (container: IContainerModel) => void - DeleteContainer: (containerid: string) => void - AddContainer: (index: number, type: string, parent: string) => void + selectContainer: (container: IContainerModel) => void + deleteContainer: (containerid: string) => void } interface Point { @@ -85,68 +84,6 @@ export class ElementsSidebar extends React.PureComponent }); } - public handleDragOver(event: React.DragEvent): void { - event.preventDefault(); - } - - public handleOnDrop(event: React.DragEvent): void { - event.preventDefault(); - const type = event.dataTransfer.getData('type'); - const target: HTMLButtonElement = event.target as HTMLButtonElement; - - if (this.props.MainContainer === null) { - throw new Error('[handleOnDrop] Tried to drop into the tree without a required MainContainer!'); - } - - const targetContainer: IContainerModel | undefined = findContainerById( - this.props.MainContainer, - target.id - ); - - if (targetContainer === undefined) { - throw new Error('[handleOnDrop] Tried to drop onto a unknown container!'); - } - - if (targetContainer === this.props.MainContainer) { - // if the container is the root, only add type as child - this.props.AddContainer( - targetContainer.children.length, - type, - targetContainer.properties.id); - return; - } - - if (targetContainer.parent === null || - targetContainer.parent === undefined) { - throw new Error('[handleDrop] Tried to drop into a child container without a parent!'); - } - - const rect = target.getBoundingClientRect(); - const y = event.clientY - rect.top; // y position within the element. - - // locate the hitboxes - if (y < 12) { - const index = targetContainer.parent.children.indexOf(targetContainer); - this.props.AddContainer( - index, - type, - targetContainer.parent.properties.id - ); - } else if (y < 24) { - this.props.AddContainer( - targetContainer.children.length, - type, - targetContainer.properties.id); - } else { - const index = targetContainer.parent.children.indexOf(targetContainer); - this.props.AddContainer( - index + 1, - type, - targetContainer.parent.properties.id - ); - } - } - public iterateChilds(handleContainer: (container: IContainerModel) => void): React.ReactNode { if (this.props.MainContainer == null) { return null; @@ -191,9 +128,7 @@ export class ElementsSidebar extends React.PureComponent } id={key} key={key} - onDrop={(event) => this.handleOnDrop(event)} - onDragOver={(event) => this.handleDragOver(event)} - onClick={() => this.props.SelectContainer(container)}> + onClick={() => this.props.selectContainer(container)}> { text } ); @@ -213,7 +148,7 @@ export class ElementsSidebar extends React.PureComponent y={this.state.contextMenuPosition.y} isOpen={this.state.isContextMenuOpen} > - this.props.DeleteContainer(this.state.onClickContainerId)} /> + this.props.deleteContainer(this.state.onClickContainerId)} /> diff --git a/src/Components/Sidebar/Sidebar.tsx b/src/Components/Sidebar/Sidebar.tsx index de06e61..c50730e 100644 --- a/src/Components/Sidebar/Sidebar.tsx +++ b/src/Components/Sidebar/Sidebar.tsx @@ -8,21 +8,14 @@ interface ISidebarProps { buttonOnClick: (type: string) => void } -function handleDragStart(event: React.DragEvent): void { - event.dataTransfer.setData('type', (event.target as HTMLButtonElement).id); -} - export default class Sidebar extends React.PureComponent { public render(): JSX.Element { const listElements = this.props.componentOptions.map(componentOption => diff --git a/src/Components/UI/UI.tsx b/src/Components/UI/UI.tsx index e0d9b6c..46ae454 100644 --- a/src/Components/UI/UI.tsx +++ b/src/Components/UI/UI.tsx @@ -17,8 +17,7 @@ interface IUIProps { SelectContainer: (container: ContainerModel) => void DeleteContainer: (containerId: string) => void OnPropertyChange: (key: string, value: string) => void - AddContainerToSelectedContainer: (type: string) => void - AddContainer: (index: number, type: string, parentId: string) => void + AddContainer: (type: string) => void SaveEditorAsJSON: () => void SaveEditorAsSVG: () => void LoadState: (move: number) => void @@ -90,7 +89,7 @@ export class UI extends React.PureComponent { this.props.AddContainerToSelectedContainer(type)} + buttonOnClick={(type: string) => this.props.AddContainer(type)} /> { isOpen={this.state.isElementsSidebarOpen} isHistoryOpen={this.state.isHistoryOpen} onPropertyChange={this.props.OnPropertyChange} - SelectContainer={this.props.SelectContainer} - DeleteContainer={this.props.DeleteContainer} - AddContainer={this.props.AddContainer} + selectContainer={this.props.SelectContainer} + deleteContainer={this.props.DeleteContainer} /> { * @param type The type of container * @returns void */ - public AddContainerToSelectedContainer(type: string): void { + public AddContainer(type: string): void { const history = this.getCurrentHistory(); const current = history[history.length - 1]; @@ -204,22 +204,13 @@ class Editor extends React.Component { return; } - const parent = current.SelectedContainer; - this.AddContainer(parent.children.length, type, parent.properties.id); - } - - public AddContainer(index: number, type: string, parentId: string): void { - const history = this.getCurrentHistory(); - const current = history[history.length - 1]; - if (current.MainContainer === null || current.MainContainer === undefined) { return; } // Get the preset properties from the API - const properties = this.props.configuration.AvailableContainers - .find(option => option.Type === type); + const properties = this.props.configuration.AvailableContainers.find(option => option.Type === type); if (properties === undefined) { throw new Error(`[AddContainer] Object type not found. Found: ${type}`); @@ -239,30 +230,35 @@ class Editor extends React.Component { const clone: IContainerModel = structuredClone(current.MainContainer); // Find the parent - const parentClone: IContainerModel | undefined = findContainerById( - clone, parentId - ); + const it = MakeIterator(clone); + let parent: ContainerModel | null = null; + for (const child of it) { + if (child.properties.id === current.SelectedContainer.properties.id) { + parent = child as ContainerModel; + break; + } + } - if (parentClone === null || parentClone === undefined) { - throw new Error('[AddContainer] Container model was not found among children of the main container!'); + if (parent === null) { + throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); } let x = 0; - const lastChild: IContainerModel | undefined = parentClone.children.at(-1); + const lastChild: IContainerModel | undefined = parent.children.at(-1); if (lastChild !== undefined) { x = lastChild.properties.x + Number(lastChild.properties.width); } // Create the container const newContainer = new ContainerModel( - parentClone, + parent, { id: `${type}-${count}`, - parentId: parentClone.properties.id, + parentId: parent.properties.id, x, y: 0, width: properties?.Width, - height: parentClone.properties.height, + height: parent.properties.height, ...properties.Style }, [], @@ -272,19 +268,15 @@ class Editor extends React.Component { ); // And push it the the parent children - if (index === parentClone.children.length) { - parentClone.children.push(newContainer); - } else { - parentClone.children.splice(index, 0, newContainer); - } + parent.children.push(newContainer); // Update the state this.setState({ history: history.concat([{ MainContainer: clone, TypeCounters: newCounters, - SelectedContainer: parentClone, - SelectedContainerId: parentClone.properties.id + SelectedContainer: parent, + SelectedContainerId: parent.properties.id }]), historyCurrentStep: history.length }); @@ -339,8 +331,7 @@ class Editor extends React.Component { SelectContainer={(container) => this.SelectContainer(container)} DeleteContainer={(containerId: string) => this.DeleteContainer(containerId)} OnPropertyChange={(key, value) => this.OnPropertyChange(key, value)} - AddContainerToSelectedContainer={(type) => this.AddContainerToSelectedContainer(type)} - AddContainer={(index, type, parentId) => this.AddContainer(index, type, parentId)} + AddContainer={(type) => this.AddContainer(type)} SaveEditorAsJSON={() => this.SaveEditorAsJSON()} SaveEditorAsSVG={() => this.SaveEditorAsSVG()} LoadState={(move) => this.LoadState(move)}