Merged PR 16: Transform every single class components into functional component
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

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:
Eric Nguyen 2022-08-09 15:15:56 +00:00
parent 1fc11adbaa
commit d9e06537e8
33 changed files with 1298 additions and 1261 deletions

View 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);
}