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 { IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { ContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { fetchConfiguration } from '../../API/api';
|
||||
import { IEditorState } from '../../../Interfaces/IEditorState';
|
||||
import { LoadState } from './Load';
|
||||
import { DEFAULT_MAINCONTAINER_PROPS } from '../../../utils/default';
|
||||
import { GetDefaultEditorState } from '../../../utils/default';
|
||||
|
||||
export function NewEditor(
|
||||
setEditorState: Dispatch<SetStateAction<IEditorState>>,
|
||||
|
@ -13,38 +12,12 @@ export function NewEditor(
|
|||
// Fetch the configuration from the API
|
||||
fetchConfiguration()
|
||||
.then((configuration: IConfiguration) => {
|
||||
// Set the main container from the given properties of the API
|
||||
const MainContainer = new ContainerModel(
|
||||
null,
|
||||
{
|
||||
...DEFAULT_MAINCONTAINER_PROPS,
|
||||
width: Number(configuration.MainContainer.Width),
|
||||
height: Number(configuration.MainContainer.Height)
|
||||
}
|
||||
);
|
||||
// Set the editor from the given properties of the API
|
||||
const editorState: IEditorState = GetDefaultEditorState(configuration);
|
||||
|
||||
// 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);
|
||||
setLoaded(true);
|
||||
}, (error) => {
|
||||
// TODO: Implement an alert component
|
||||
console.warn('[NewEditor] Could not fetch resource from API. Using default.', error);
|
||||
setLoaded(true);
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import { IAvailableContainer } from '../../../Interfaces/IAvailableContainer';
|
|||
import { GetDefaultContainerProps, DEFAULTCHILDTYPE_ALLOW_CYCLIC, DEFAULTCHILDTYPE_MAX_DEPTH } from '../../../utils/default';
|
||||
import { ApplyBehaviors } from '../Behaviors/Behaviors';
|
||||
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import Swal from 'sweetalert2';
|
||||
|
||||
/**
|
||||
* Select a container
|
||||
|
@ -64,7 +65,11 @@ export function DeleteContainer(
|
|||
if (container === mainContainerClone ||
|
||||
container.parent === undefined ||
|
||||
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!');
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
|||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
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 { restoreX } from '../../../utils/svg';
|
||||
import { ApplyBehaviors } from '../Behaviors/Behaviors';
|
||||
|
@ -31,16 +31,7 @@ export function AddSymbol(
|
|||
UpdateCounters(newCounters, type);
|
||||
|
||||
const newSymbols = structuredClone(current.Symbols);
|
||||
// TODO: Put this in default.ts as GetDefaultConfig
|
||||
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()
|
||||
};
|
||||
const newSymbol: ISymbolModel = GetDefaultSymbolModel(name, newCounters, type, symbolConfig);
|
||||
newSymbol.x = restoreX(newSymbol.x, newSymbol.width, newSymbol.config.XPositionReference);
|
||||
|
||||
newSymbols.set(newSymbol.id, newSymbol);
|
||||
|
@ -114,7 +105,7 @@ export function DeleteSymbol(
|
|||
setHistoryCurrentStep(history.length - 1);
|
||||
}
|
||||
|
||||
function UnlinkContainers(symbol: ISymbolModel, newMainContainer: IContainerModel) {
|
||||
function UnlinkContainers(symbol: ISymbolModel, newMainContainer: IContainerModel): void {
|
||||
symbol.linkedContainers.forEach((containerId) => {
|
||||
const container = findContainerById(newMainContainer, containerId);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ describe.concurrent('Elements sidebar', () => {
|
|||
parent: null,
|
||||
properties: {
|
||||
id: 'main',
|
||||
parentId: null,
|
||||
parentId: '',
|
||||
linkedSymbolId: '',
|
||||
displayedText: 'main',
|
||||
x: 0,
|
||||
|
|
|
@ -8,9 +8,8 @@ export default interface IContainerProperties {
|
|||
/** id of the container */
|
||||
id: string
|
||||
|
||||
// TODO: replace null by empty string
|
||||
/** 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) */
|
||||
linkedSymbolId: string
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { XPositionReference } from '../Enums/XPositionReference';
|
||||
import { IAvailableContainer } from '../Interfaces/IAvailableContainer';
|
||||
import { IAvailableSymbol } from '../Interfaces/IAvailableSymbol';
|
||||
import { IConfiguration } from '../Interfaces/IConfiguration';
|
||||
import { IContainerModel } from '../Interfaces/IContainerModel';
|
||||
import { ContainerModel, IContainerModel } from '../Interfaces/IContainerModel';
|
||||
import IContainerProperties from '../Interfaces/IContainerProperties';
|
||||
import { IEditorState } from '../Interfaces/IEditorState';
|
||||
import { ISymbolModel } from '../Interfaces/ISymbolModel';
|
||||
|
||||
/// CONTAINER DEFAULTS ///
|
||||
|
||||
|
@ -29,6 +32,38 @@ export const ENABLE_SHORTCUTS = true;
|
|||
export const MAX_HISTORY = 200;
|
||||
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 = {
|
||||
AvailableContainers: [
|
||||
{
|
||||
|
@ -53,9 +88,12 @@ export const DEFAULT_CONFIG: IConfiguration = {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Default Main container properties
|
||||
*/
|
||||
export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = {
|
||||
id: 'main',
|
||||
parentId: 'null',
|
||||
parentId: '',
|
||||
linkedSymbolId: '',
|
||||
displayedText: 'main',
|
||||
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 = (
|
||||
type: string,
|
||||
typeCount: number,
|
||||
|
@ -96,3 +144,20 @@ export const GetDefaultContainerProps = (
|
|||
style: structuredClone(containerConfig.Style),
|
||||
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