Merged PR 164: Clear the leftover TODOs
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
- Remove nullable type from container.properties.parentId - Add Swal when trying to delete main container - Moved default editor state to default.ts - Moved default symbol model to default.ts
This commit is contained in:
parent
66ea3b1b64
commit
29625dce28
6 changed files with 81 additions and 48 deletions
|
@ -1,10 +1,9 @@
|
||||||
import { Dispatch, SetStateAction } from 'react';
|
import { Dispatch, SetStateAction } from 'react';
|
||||||
import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||||
import { ContainerModel } from '../../../Interfaces/IContainerModel';
|
|
||||||
import { fetchConfiguration } from '../../API/api';
|
import { fetchConfiguration } from '../../API/api';
|
||||||
import { IEditorState } from '../../../Interfaces/IEditorState';
|
import { IEditorState } from '../../../Interfaces/IEditorState';
|
||||||
import { LoadState } from './Load';
|
import { LoadState } from './Load';
|
||||||
import { DEFAULT_MAINCONTAINER_PROPS } from '../../../utils/default';
|
import { GetDefaultEditorState } from '../../../utils/default';
|
||||||
|
|
||||||
export function NewEditor(
|
export function NewEditor(
|
||||||
setEditorState: Dispatch<SetStateAction<IEditorState>>,
|
setEditorState: Dispatch<SetStateAction<IEditorState>>,
|
||||||
|
@ -13,38 +12,12 @@ export function NewEditor(
|
||||||
// Fetch the configuration from the API
|
// Fetch the configuration from the API
|
||||||
fetchConfiguration()
|
fetchConfiguration()
|
||||||
.then((configuration: IConfiguration) => {
|
.then((configuration: IConfiguration) => {
|
||||||
// Set the main container from the given properties of the API
|
// Set the editor from the given properties of the API
|
||||||
const MainContainer = new ContainerModel(
|
const editorState: IEditorState = GetDefaultEditorState(configuration);
|
||||||
null,
|
|
||||||
{
|
|
||||||
...DEFAULT_MAINCONTAINER_PROPS,
|
|
||||||
width: Number(configuration.MainContainer.Width),
|
|
||||||
height: Number(configuration.MainContainer.Height)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Save the configuration and the new MainContainer
|
|
||||||
// and default the selected container to it
|
|
||||||
// TODO: Put this in default.ts
|
|
||||||
const editorState: IEditorState = {
|
|
||||||
configuration,
|
|
||||||
history:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
LastAction: '',
|
|
||||||
MainContainer,
|
|
||||||
SelectedContainerId: MainContainer.properties.id,
|
|
||||||
TypeCounters: {},
|
|
||||||
Symbols: new Map(),
|
|
||||||
SelectedSymbolId: ''
|
|
||||||
}
|
|
||||||
],
|
|
||||||
historyCurrentStep: 0
|
|
||||||
};
|
|
||||||
setEditorState(editorState);
|
setEditorState(editorState);
|
||||||
setLoaded(true);
|
setLoaded(true);
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
// TODO: Implement an alert component
|
|
||||||
console.warn('[NewEditor] Could not fetch resource from API. Using default.', error);
|
console.warn('[NewEditor] Could not fetch resource from API. Using default.', error);
|
||||||
setLoaded(true);
|
setLoaded(true);
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { IAvailableContainer } from '../../../Interfaces/IAvailableContainer';
|
||||||
import { GetDefaultContainerProps, DEFAULTCHILDTYPE_ALLOW_CYCLIC, DEFAULTCHILDTYPE_MAX_DEPTH } from '../../../utils/default';
|
import { GetDefaultContainerProps, DEFAULTCHILDTYPE_ALLOW_CYCLIC, DEFAULTCHILDTYPE_MAX_DEPTH } from '../../../utils/default';
|
||||||
import { ApplyBehaviors } from '../Behaviors/Behaviors';
|
import { ApplyBehaviors } from '../Behaviors/Behaviors';
|
||||||
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||||
|
import Swal from 'sweetalert2';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select a container
|
* Select a container
|
||||||
|
@ -64,7 +65,11 @@ export function DeleteContainer(
|
||||||
if (container === mainContainerClone ||
|
if (container === mainContainerClone ||
|
||||||
container.parent === undefined ||
|
container.parent === undefined ||
|
||||||
container.parent === null) {
|
container.parent === null) {
|
||||||
// TODO: Implement alert
|
Swal.fire({
|
||||||
|
title: 'Oops...',
|
||||||
|
text: 'Deleting the main container is not allowed!',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
throw new Error('[DeleteContainer] Tried to delete the main container! Deleting the main container is not allowed!');
|
throw new Error('[DeleteContainer] Tried to delete the main container! Deleting the main container is not allowed!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||||
import { IHistoryState } from '../../../Interfaces/IHistoryState';
|
import { IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||||
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||||
import { DEFAULT_SYMBOL_HEIGHT, DEFAULT_SYMBOL_WIDTH } from '../../../utils/default';
|
import { GetDefaultSymbolModel } from '../../../utils/default';
|
||||||
import { findContainerById } from '../../../utils/itertools';
|
import { findContainerById } from '../../../utils/itertools';
|
||||||
import { restoreX } from '../../../utils/svg';
|
import { restoreX } from '../../../utils/svg';
|
||||||
import { ApplyBehaviors } from '../Behaviors/Behaviors';
|
import { ApplyBehaviors } from '../Behaviors/Behaviors';
|
||||||
|
@ -31,16 +31,7 @@ export function AddSymbol(
|
||||||
UpdateCounters(newCounters, type);
|
UpdateCounters(newCounters, type);
|
||||||
|
|
||||||
const newSymbols = structuredClone(current.Symbols);
|
const newSymbols = structuredClone(current.Symbols);
|
||||||
// TODO: Put this in default.ts as GetDefaultConfig
|
const newSymbol: ISymbolModel = GetDefaultSymbolModel(name, newCounters, type, symbolConfig);
|
||||||
const newSymbol: ISymbolModel = {
|
|
||||||
id: `${name}-${newCounters[type]}`,
|
|
||||||
type: name,
|
|
||||||
config: structuredClone(symbolConfig),
|
|
||||||
x: 0,
|
|
||||||
width: symbolConfig.Width ?? DEFAULT_SYMBOL_WIDTH,
|
|
||||||
height: symbolConfig.Height ?? DEFAULT_SYMBOL_HEIGHT,
|
|
||||||
linkedContainers: new Set()
|
|
||||||
};
|
|
||||||
newSymbol.x = restoreX(newSymbol.x, newSymbol.width, newSymbol.config.XPositionReference);
|
newSymbol.x = restoreX(newSymbol.x, newSymbol.width, newSymbol.config.XPositionReference);
|
||||||
|
|
||||||
newSymbols.set(newSymbol.id, newSymbol);
|
newSymbols.set(newSymbol.id, newSymbol);
|
||||||
|
@ -114,7 +105,7 @@ export function DeleteSymbol(
|
||||||
setHistoryCurrentStep(history.length - 1);
|
setHistoryCurrentStep(history.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function UnlinkContainers(symbol: ISymbolModel, newMainContainer: IContainerModel) {
|
function UnlinkContainers(symbol: ISymbolModel, newMainContainer: IContainerModel): void {
|
||||||
symbol.linkedContainers.forEach((containerId) => {
|
symbol.linkedContainers.forEach((containerId) => {
|
||||||
const container = findContainerById(newMainContainer, containerId);
|
const container = findContainerById(newMainContainer, containerId);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ describe.concurrent('Elements sidebar', () => {
|
||||||
parent: null,
|
parent: null,
|
||||||
properties: {
|
properties: {
|
||||||
id: 'main',
|
id: 'main',
|
||||||
parentId: null,
|
parentId: '',
|
||||||
linkedSymbolId: '',
|
linkedSymbolId: '',
|
||||||
displayedText: 'main',
|
displayedText: 'main',
|
||||||
x: 0,
|
x: 0,
|
||||||
|
|
|
@ -8,9 +8,8 @@ export default interface IContainerProperties {
|
||||||
/** id of the container */
|
/** id of the container */
|
||||||
id: string
|
id: string
|
||||||
|
|
||||||
// TODO: replace null by empty string
|
|
||||||
/** id of the parent container (null when there is no parent) */
|
/** id of the parent container (null when there is no parent) */
|
||||||
parentId: string | null
|
parentId: string
|
||||||
|
|
||||||
/** id of the linked symbol ('' when there is no parent) */
|
/** id of the linked symbol ('' when there is no parent) */
|
||||||
linkedSymbolId: string
|
linkedSymbolId: string
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { XPositionReference } from '../Enums/XPositionReference';
|
import { XPositionReference } from '../Enums/XPositionReference';
|
||||||
import { IAvailableContainer } from '../Interfaces/IAvailableContainer';
|
import { IAvailableContainer } from '../Interfaces/IAvailableContainer';
|
||||||
|
import { IAvailableSymbol } from '../Interfaces/IAvailableSymbol';
|
||||||
import { IConfiguration } from '../Interfaces/IConfiguration';
|
import { IConfiguration } from '../Interfaces/IConfiguration';
|
||||||
import { IContainerModel } from '../Interfaces/IContainerModel';
|
import { ContainerModel, IContainerModel } from '../Interfaces/IContainerModel';
|
||||||
import IContainerProperties from '../Interfaces/IContainerProperties';
|
import IContainerProperties from '../Interfaces/IContainerProperties';
|
||||||
|
import { IEditorState } from '../Interfaces/IEditorState';
|
||||||
|
import { ISymbolModel } from '../Interfaces/ISymbolModel';
|
||||||
|
|
||||||
/// CONTAINER DEFAULTS ///
|
/// CONTAINER DEFAULTS ///
|
||||||
|
|
||||||
|
@ -29,6 +32,38 @@ export const ENABLE_SHORTCUTS = true;
|
||||||
export const MAX_HISTORY = 200;
|
export const MAX_HISTORY = 200;
|
||||||
export const APPLY_BEHAVIORS_ON_CHILDREN = true;
|
export const APPLY_BEHAVIORS_ON_CHILDREN = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default editor state given the configuration
|
||||||
|
*/
|
||||||
|
export const GetDefaultEditorState = (configuration: IConfiguration): IEditorState => {
|
||||||
|
const mainContainer = new ContainerModel(
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
...DEFAULT_MAINCONTAINER_PROPS,
|
||||||
|
width: Number(configuration.MainContainer.Width),
|
||||||
|
height: Number(configuration.MainContainer.Height)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
configuration,
|
||||||
|
history: [
|
||||||
|
{
|
||||||
|
LastAction: '',
|
||||||
|
MainContainer: mainContainer,
|
||||||
|
SelectedContainerId: mainContainer.properties.id,
|
||||||
|
TypeCounters: {},
|
||||||
|
Symbols: new Map(),
|
||||||
|
SelectedSymbolId: ''
|
||||||
|
}
|
||||||
|
],
|
||||||
|
historyCurrentStep: 0
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default config when the API is not available
|
||||||
|
*/
|
||||||
export const DEFAULT_CONFIG: IConfiguration = {
|
export const DEFAULT_CONFIG: IConfiguration = {
|
||||||
AvailableContainers: [
|
AvailableContainers: [
|
||||||
{
|
{
|
||||||
|
@ -53,9 +88,12 @@ export const DEFAULT_CONFIG: IConfiguration = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Main container properties
|
||||||
|
*/
|
||||||
export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = {
|
export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = {
|
||||||
id: 'main',
|
id: 'main',
|
||||||
parentId: 'null',
|
parentId: '',
|
||||||
linkedSymbolId: '',
|
linkedSymbolId: '',
|
||||||
displayedText: 'main',
|
displayedText: 'main',
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -72,6 +110,16 @@ export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default properties of a newly created container
|
||||||
|
* @param type Type of the container
|
||||||
|
* @param typeCount index of the container
|
||||||
|
* @param parent Parent of the container
|
||||||
|
* @param x horizontal offset
|
||||||
|
* @param y vertical offset
|
||||||
|
* @param containerConfig default config of the container sent by the API
|
||||||
|
* @returns {IContainerProperties} Default properties of a newly created container
|
||||||
|
*/
|
||||||
export const GetDefaultContainerProps = (
|
export const GetDefaultContainerProps = (
|
||||||
type: string,
|
type: string,
|
||||||
typeCount: number,
|
typeCount: number,
|
||||||
|
@ -96,3 +144,20 @@ export const GetDefaultContainerProps = (
|
||||||
style: structuredClone(containerConfig.Style),
|
style: structuredClone(containerConfig.Style),
|
||||||
userData: structuredClone(containerConfig.UserData)
|
userData: structuredClone(containerConfig.UserData)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const GetDefaultSymbolModel = (
|
||||||
|
name: string,
|
||||||
|
newCounters: Record<string, number>,
|
||||||
|
type: string,
|
||||||
|
symbolConfig: IAvailableSymbol
|
||||||
|
): ISymbolModel => {
|
||||||
|
return {
|
||||||
|
id: `${name}-${newCounters[type]}`,
|
||||||
|
type: name,
|
||||||
|
config: structuredClone(symbolConfig),
|
||||||
|
x: 0,
|
||||||
|
width: symbolConfig.Width ?? DEFAULT_SYMBOL_WIDTH,
|
||||||
|
height: symbolConfig.Height ?? DEFAULT_SYMBOL_HEIGHT,
|
||||||
|
linkedContainers: new Set()
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue