Merged PR 16: Transform every single class components into functional component
This improve greatly the performance and the code cleaning. It allows us to separate the inseparable class methods into modules functions
This commit is contained in:
parent
1fc11adbaa
commit
d9e06537e8
33 changed files with 1298 additions and 1261 deletions
269
src/Components/Editor/ContainerOperations.ts
Normal file
269
src/Components/Editor/ContainerOperations.ts
Normal file
|
@ -0,0 +1,269 @@
|
|||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { HistoryState } from "../../Interfaces/HistoryState";
|
||||
import { Configuration } from '../../Interfaces/Configuration';
|
||||
import { ContainerModel, IContainerModel } from '../../Interfaces/ContainerModel';
|
||||
import { findContainerById } from '../../utils/itertools';
|
||||
import { getCurrentHistory } from './Editor';
|
||||
|
||||
/**
|
||||
* Select a container
|
||||
* @param container Selected container
|
||||
*/
|
||||
export function SelectContainer(
|
||||
container: ContainerModel,
|
||||
fullHistory: HistoryState[],
|
||||
historyCurrentStep: number,
|
||||
setHistory: Dispatch<SetStateAction<HistoryState[]>>,
|
||||
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
|
||||
): void {
|
||||
const history = getCurrentHistory(fullHistory, historyCurrentStep);
|
||||
const current = history[history.length - 1];
|
||||
|
||||
if (current.MainContainer === null) {
|
||||
throw new Error('[SelectContainer] Tried to select a container while there is no main container!');
|
||||
}
|
||||
|
||||
const mainContainerClone = structuredClone(current.MainContainer);
|
||||
const SelectedContainer = findContainerById(mainContainerClone, container.properties.id);
|
||||
|
||||
if (SelectedContainer === undefined) {
|
||||
throw new Error('[SelectContainer] Cannot find container among children of main container!');
|
||||
}
|
||||
|
||||
setHistory(history.concat([{
|
||||
MainContainer: mainContainerClone,
|
||||
TypeCounters: Object.assign({}, current.TypeCounters),
|
||||
SelectedContainer,
|
||||
SelectedContainerId: SelectedContainer.properties.id
|
||||
}]));
|
||||
setHistoryCurrentStep(history.length);
|
||||
}
|
||||
|
||||
export function DeleteContainer(
|
||||
containerId: string,
|
||||
fullHistory: HistoryState[],
|
||||
historyCurrentStep: number,
|
||||
setHistory: Dispatch<SetStateAction<HistoryState[]>>,
|
||||
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
|
||||
): void {
|
||||
const history = getCurrentHistory(fullHistory, historyCurrentStep);
|
||||
const current = history[historyCurrentStep];
|
||||
|
||||
if (current.MainContainer === null) {
|
||||
throw new Error('[DeleteContainer] Error: Tried to delete a container without a main container');
|
||||
}
|
||||
|
||||
const mainContainerClone: IContainerModel = structuredClone(current.MainContainer);
|
||||
const container = findContainerById(mainContainerClone, containerId);
|
||||
|
||||
if (container === undefined) {
|
||||
throw new Error(`[DeleteContainer] Tried to delete a container that is not present in the main container: ${containerId}`);
|
||||
}
|
||||
|
||||
if (container === mainContainerClone) {
|
||||
// TODO: Implement alert
|
||||
throw new Error('[DeleteContainer] Tried to delete the main container! Deleting the main container is not allowed !');
|
||||
}
|
||||
|
||||
if (container === null || container === undefined) {
|
||||
throw new Error('[OnPropertyChange] Container model was not found among children of the main container!');
|
||||
}
|
||||
|
||||
if (container.parent != null) {
|
||||
const index = container.parent.children.indexOf(container);
|
||||
if (index > -1) {
|
||||
container.parent.children.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
setHistory(history.concat([{
|
||||
SelectedContainer: null,
|
||||
SelectedContainerId: '',
|
||||
MainContainer: mainContainerClone,
|
||||
TypeCounters: Object.assign({}, current.TypeCounters)
|
||||
}]));
|
||||
setHistoryCurrentStep(history.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new container to a selected container
|
||||
* @param type The type of container
|
||||
* @returns void
|
||||
*/
|
||||
export function AddContainerToSelectedContainer(
|
||||
type: string,
|
||||
configuration: Configuration,
|
||||
fullHistory: HistoryState[],
|
||||
historyCurrentStep: number,
|
||||
setHistory: Dispatch<SetStateAction<HistoryState[]>>,
|
||||
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
|
||||
): void {
|
||||
const history = getCurrentHistory(fullHistory, historyCurrentStep);
|
||||
const current = history[history.length - 1];
|
||||
|
||||
if (current.SelectedContainer === null ||
|
||||
current.SelectedContainer === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parent = current.SelectedContainer;
|
||||
AddContainer(
|
||||
parent.children.length,
|
||||
type,
|
||||
parent.properties.id,
|
||||
configuration,
|
||||
fullHistory,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
);
|
||||
}
|
||||
|
||||
export function AddContainer(
|
||||
index: number,
|
||||
type: string,
|
||||
parentId: string,
|
||||
configuration: Configuration,
|
||||
fullHistory: HistoryState[],
|
||||
historyCurrentStep: number,
|
||||
setHistory: Dispatch<SetStateAction<HistoryState[]>>,
|
||||
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
|
||||
): void {
|
||||
const history = getCurrentHistory(fullHistory, historyCurrentStep);
|
||||
const current = history[history.length - 1];
|
||||
|
||||
if (current.MainContainer === null ||
|
||||
current.MainContainer === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the preset properties from the API
|
||||
const properties = configuration.AvailableContainers
|
||||
.find(option => option.Type === type);
|
||||
|
||||
if (properties === undefined) {
|
||||
throw new Error(`[AddContainer] Object type not found. Found: ${type}`);
|
||||
}
|
||||
|
||||
// Set the counter of the object type in order to assign an unique id
|
||||
const newCounters = Object.assign({}, current.TypeCounters);
|
||||
if (newCounters[type] === null ||
|
||||
newCounters[type] === undefined) {
|
||||
newCounters[type] = 0;
|
||||
} else {
|
||||
newCounters[type]++;
|
||||
}
|
||||
const count = newCounters[type];
|
||||
|
||||
// Create maincontainer model
|
||||
const clone: IContainerModel = structuredClone(current.MainContainer);
|
||||
|
||||
// Find the parent
|
||||
const parentClone: IContainerModel | undefined = findContainerById(
|
||||
clone, parentId
|
||||
);
|
||||
|
||||
if (parentClone === null || parentClone === undefined) {
|
||||
throw new Error('[AddContainer] Container model was not found among children of the main container!');
|
||||
}
|
||||
|
||||
let x = 0;
|
||||
if (index !== 0) {
|
||||
const lastChild: IContainerModel | undefined = parentClone.children.at(index - 1);
|
||||
if (lastChild !== undefined) {
|
||||
x = lastChild.properties.x + Number(lastChild.properties.width);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the container
|
||||
const newContainer = new ContainerModel(
|
||||
parentClone,
|
||||
{
|
||||
id: `${type}-${count}`,
|
||||
parentId: parentClone.properties.id,
|
||||
x,
|
||||
y: 0,
|
||||
width: properties?.Width,
|
||||
height: parentClone.properties.height,
|
||||
...properties.Style
|
||||
},
|
||||
[],
|
||||
{
|
||||
type
|
||||
}
|
||||
);
|
||||
|
||||
// And push it the the parent children
|
||||
if (index === parentClone.children.length) {
|
||||
parentClone.children.push(newContainer);
|
||||
} else {
|
||||
parentClone.children.splice(index, 0, newContainer);
|
||||
}
|
||||
|
||||
// Update the state
|
||||
setHistory(history.concat([{
|
||||
MainContainer: clone,
|
||||
TypeCounters: newCounters,
|
||||
SelectedContainer: parentClone,
|
||||
SelectedContainerId: parentClone.properties.id
|
||||
}]));
|
||||
setHistoryCurrentStep(history.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handled the property change event in the properties form
|
||||
* @param key Property name
|
||||
* @param value New value of the property
|
||||
* @returns void
|
||||
*/
|
||||
export function OnPropertyChange(
|
||||
key: string,
|
||||
value: string | number,
|
||||
fullHistory: HistoryState[],
|
||||
historyCurrentStep: number,
|
||||
setHistory: Dispatch<SetStateAction<HistoryState[]>>,
|
||||
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
|
||||
): void {
|
||||
const history = getCurrentHistory(fullHistory, historyCurrentStep);
|
||||
const current = history[history.length - 1];
|
||||
|
||||
if (current.SelectedContainer === null ||
|
||||
current.SelectedContainer === undefined) {
|
||||
throw new Error('[OnPropertyChange] Property was changed before selecting a Container');
|
||||
}
|
||||
|
||||
if (current.MainContainer === null ||
|
||||
current.MainContainer === undefined) {
|
||||
throw new Error('[OnPropertyChange] Property was changed before the main container was added');
|
||||
}
|
||||
|
||||
if (parent === null) {
|
||||
const selectedContainerClone: IContainerModel = structuredClone(current.SelectedContainer);
|
||||
(selectedContainerClone.properties as any)[key] = value;
|
||||
setHistory(history.concat([{
|
||||
SelectedContainer: selectedContainerClone,
|
||||
SelectedContainerId: selectedContainerClone.properties.id,
|
||||
MainContainer: selectedContainerClone,
|
||||
TypeCounters: Object.assign({}, current.TypeCounters)
|
||||
}]));
|
||||
setHistoryCurrentStep(history.length);
|
||||
return;
|
||||
}
|
||||
|
||||
const mainContainerClone: IContainerModel = structuredClone(current.MainContainer);
|
||||
const container: ContainerModel | undefined = findContainerById(mainContainerClone, current.SelectedContainer.properties.id);
|
||||
|
||||
if (container === null || container === undefined) {
|
||||
throw new Error('[OnPropertyChange] Container model was not found among children of the main container!');
|
||||
}
|
||||
|
||||
(container.properties as any)[key] = value;
|
||||
|
||||
setHistory(history.concat([{
|
||||
SelectedContainer: container,
|
||||
SelectedContainerId: container.properties.id,
|
||||
MainContainer: mainContainerClone,
|
||||
TypeCounters: Object.assign({}, current.TypeCounters)
|
||||
}]));
|
||||
setHistoryCurrentStep(history.length);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue