Fix eslint errors
This commit is contained in:
parent
5b3ab651e6
commit
4e41fda93a
87 changed files with 1003 additions and 702 deletions
|
@ -2,14 +2,14 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { AddMethod } from '../../Enums/AddMethod';
|
||||
import { PositionReference } from '../../Enums/PositionReference';
|
||||
import { IAction } from '../../Interfaces/IAction';
|
||||
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
|
||||
import { IAvailableSymbol } from '../../Interfaces/IAvailableSymbol';
|
||||
import { ICategory } from '../../Interfaces/ICategory';
|
||||
import { IConfiguration } from '../../Interfaces/IConfiguration';
|
||||
import { IContainerModel, ContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { IPattern } from '../../Interfaces/IPattern';
|
||||
import { type IAction } from '../../Interfaces/IAction';
|
||||
import { type IAvailableContainer } from '../../Interfaces/IAvailableContainer';
|
||||
import { type IAvailableSymbol } from '../../Interfaces/IAvailableSymbol';
|
||||
import { type ICategory } from '../../Interfaces/ICategory';
|
||||
import { type IConfiguration } from '../../Interfaces/IConfiguration';
|
||||
import { type IContainerModel, ContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { type IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { type IPattern } from '../../Interfaces/IPattern';
|
||||
import { DEFAULT_DIMENSION_OPTION, DEFAULT_MAINCONTAINER_PROPS, GetDefaultContainerProps } from '../../utils/default';
|
||||
import { FetchConfiguration } from './api';
|
||||
|
||||
|
@ -95,9 +95,7 @@ describe.concurrent('Models test suite', () => {
|
|||
expect(res4).toBe(true);
|
||||
});
|
||||
|
||||
const mainContainer = new ContainerModel(
|
||||
DEFAULT_MAINCONTAINER_PROPS
|
||||
);
|
||||
const mainContainer = new ContainerModel(DEFAULT_MAINCONTAINER_PROPS);
|
||||
|
||||
const containers = new Map<string, IContainerModel>();
|
||||
const historyState: IHistoryState = {
|
||||
|
@ -244,7 +242,12 @@ describe.concurrent('Models test suite', () => {
|
|||
'container',
|
||||
0,
|
||||
null,
|
||||
0, 0, 0, 0, availableContainerModel);
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
availableContainerModel
|
||||
);
|
||||
|
||||
it('ContainerModel', async() => {
|
||||
const model: IContainerModel = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { IConfiguration } from '../../Interfaces/IConfiguration';
|
||||
import { ISetContainerListRequest } from '../../Interfaces/ISetContainerListRequest';
|
||||
import { ISetContainerListResponse } from '../../Interfaces/ISetContainerListResponse';
|
||||
import { type IConfiguration } from '../../Interfaces/IConfiguration';
|
||||
import { type ISetContainerListRequest } from '../../Interfaces/ISetContainerListRequest';
|
||||
import { type ISetContainerListResponse } from '../../Interfaces/ISetContainerListResponse';
|
||||
import { GetCircularReplacer } from '../../utils/saveload';
|
||||
|
||||
/**
|
||||
|
@ -9,16 +9,14 @@ import { GetCircularReplacer } from '../../utils/saveload';
|
|||
*/
|
||||
export async function FetchConfiguration(): Promise<IConfiguration> {
|
||||
const url = import.meta.env.VITE_API_FETCH_URL;
|
||||
// The test library cannot use the Fetch API
|
||||
// @ts-expect-error
|
||||
// @ts-expect-error The test library cannot use the Fetch API
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
if (window.fetch) {
|
||||
return await fetch(url, {
|
||||
method: 'POST'
|
||||
})
|
||||
.then(async(response) =>
|
||||
await response.json()
|
||||
) as IConfiguration;
|
||||
await response.json()) as IConfiguration;
|
||||
}
|
||||
return await new Promise((resolve) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
@ -33,11 +31,13 @@ export async function FetchConfiguration(): Promise<IConfiguration> {
|
|||
});
|
||||
}
|
||||
|
||||
export async function SetContainerList(request: ISetContainerListRequest, configurationUrl?: string): Promise<ISetContainerListResponse> {
|
||||
export async function SetContainerList(
|
||||
request: ISetContainerListRequest,
|
||||
configurationUrl?: string
|
||||
): Promise<ISetContainerListResponse> {
|
||||
const url = configurationUrl ?? import.meta.env.VITE_API_SET_CONTAINER_LIST_URL;
|
||||
const dataParsed = JSON.stringify(request, GetCircularReplacer());
|
||||
// The test library cannot use the Fetch API
|
||||
// @ts-expect-error
|
||||
// @ts-expect-error The test library cannot use the Fetch API
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
if (window.fetch) {
|
||||
return await fetch(url, {
|
||||
|
@ -49,8 +49,7 @@ export async function SetContainerList(request: ISetContainerListRequest, config
|
|||
body: dataParsed
|
||||
})
|
||||
.then(async(response) =>
|
||||
await response.json()
|
||||
) as ISetContainerListResponse;
|
||||
await response.json()) as ISetContainerListResponse;
|
||||
}
|
||||
return await new Promise((resolve) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { type Dispatch, type SetStateAction } from 'react';
|
||||
import { AppState } from '../../../Enums/AppState';
|
||||
import { IEditorState } from '../../../Interfaces/IEditorState';
|
||||
import { type IEditorState } from '../../../Interfaces/IEditorState';
|
||||
import { Revive } from '../../../utils/saveload';
|
||||
|
||||
export function LoadState(
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { type Dispatch, type SetStateAction } from 'react';
|
||||
import { type IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { FetchConfiguration } from '../../API/api';
|
||||
import { IEditorState } from '../../../Interfaces/IEditorState';
|
||||
import { LoadState } from './Load';
|
||||
import { type IEditorState } from '../../../Interfaces/IEditorState';
|
||||
import { DISABLE_API, GetDefaultEditorState } from '../../../utils/default';
|
||||
import { AppState } from '../../../Enums/AppState';
|
||||
import { type AppState } from '../../../Enums/AppState';
|
||||
import { LoadState } from './Load';
|
||||
|
||||
export function NewEditor(
|
||||
editorState: IEditorState,
|
||||
|
|
|
@ -2,16 +2,14 @@ import * as React from 'react';
|
|||
import { beforeEach, describe, it } from 'vitest';
|
||||
import { AppState } from '../../Enums/AppState';
|
||||
import { FAST_BOOT } from '../../utils/default';
|
||||
import { fireEvent, render, RenderResult } from '../../utils/test-utils';
|
||||
import { fireEvent, render, type RenderResult } from '../../utils/test-utils';
|
||||
import { App } from './App';
|
||||
|
||||
describe.concurrent('App', () => {
|
||||
let app: RenderResult;
|
||||
|
||||
beforeEach(() => {
|
||||
app = render(
|
||||
<App root={document} />
|
||||
);
|
||||
app = render(<App root={document} />);
|
||||
});
|
||||
|
||||
it('New editor', async() => {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import React, { Dispatch, SetStateAction, useContext, useEffect, useRef, useState } from 'react';
|
||||
import React, { type Dispatch, type SetStateAction, useContext, useEffect, useRef, useState } from 'react';
|
||||
import { UseCustomEvents } from '../../Events/AppEvents';
|
||||
import { MainMenu } from '../MainMenu/MainMenu';
|
||||
import { ContainerModel, IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { ContainerModel, type IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { Editor } from '../Editor/Editor';
|
||||
import { IEditorState } from '../../Interfaces/IEditorState';
|
||||
import { LoadState } from './Actions/Load';
|
||||
import { LoadEditor, NewEditor } from './Actions/MenuActions';
|
||||
import { type IEditorState } from '../../Interfaces/IEditorState';
|
||||
import { DEFAULT_CONFIG, DEFAULT_MAINCONTAINER_PROPS, FAST_BOOT } from '../../utils/default';
|
||||
import { AppState } from '../../Enums/AppState';
|
||||
import { Loader } from '../Loader/Loader';
|
||||
import { LanguageContext } from '../LanguageProvider/LanguageProvider';
|
||||
import { LoadEditor, NewEditor } from './Actions/MenuActions';
|
||||
import { LoadState } from './Actions/Load';
|
||||
|
||||
// App will never have props
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
|
@ -49,9 +49,7 @@ export function App(props: IAppProps): JSX.Element {
|
|||
const appRef = useRef<HTMLDivElement>(null);
|
||||
const languageContext = useContext(LanguageContext);
|
||||
|
||||
const defaultMainContainer = new ContainerModel(
|
||||
DEFAULT_MAINCONTAINER_PROPS
|
||||
);
|
||||
const defaultMainContainer = new ContainerModel(DEFAULT_MAINCONTAINER_PROPS);
|
||||
const containers = new Map<string, IContainerModel>();
|
||||
containers.set(defaultMainContainer.properties.id, defaultMainContainer);
|
||||
|
||||
|
@ -116,15 +114,17 @@ export function App(props: IAppProps): JSX.Element {
|
|||
setAppState(AppState.Loading);
|
||||
NewEditor(
|
||||
editorState,
|
||||
(newEditor) => setEditorState(newEditor),
|
||||
() => setAppState(AppState.Loaded)
|
||||
(newEditor) => { setEditorState(newEditor); },
|
||||
() => { setAppState(AppState.Loaded); }
|
||||
);
|
||||
}}
|
||||
loadEditor={(files: FileList | null) => {
|
||||
LoadEditor(
|
||||
files,
|
||||
setEditorState,
|
||||
setAppState
|
||||
);
|
||||
}}
|
||||
loadEditor={(files: FileList | null) => LoadEditor(
|
||||
files,
|
||||
setEditorState,
|
||||
setAppState
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -13,8 +13,8 @@ import {
|
|||
EnvelopeIcon as EnvolopeIconS,
|
||||
Cog8ToothIcon as Cog8ToothIconS
|
||||
} from '@heroicons/react/24/solid';
|
||||
import { BarIcon } from './BarIcon';
|
||||
import { Text } from '../Text/Text';
|
||||
import { BarIcon } from './BarIcon';
|
||||
|
||||
interface IBarProps {
|
||||
className: string
|
||||
|
@ -38,7 +38,7 @@ export function Bar(props: IBarProps): JSX.Element {
|
|||
<BarIcon
|
||||
isActive={props.isComponentsOpen}
|
||||
title={Text({ textId: '@Components' })}
|
||||
onClick={() => props.toggleComponents()}>
|
||||
onClick={() => { props.toggleComponents(); }}>
|
||||
{
|
||||
props.isComponentsOpen
|
||||
? <CubeIconS className='heroicon' />
|
||||
|
@ -48,7 +48,7 @@ export function Bar(props: IBarProps): JSX.Element {
|
|||
<BarIcon
|
||||
isActive={props.isSymbolsOpen}
|
||||
title={Text({ textId: '@Symbols' })}
|
||||
onClick={() => props.toggleSymbols()}>
|
||||
onClick={() => { props.toggleSymbols(); }}>
|
||||
{
|
||||
props.isSymbolsOpen
|
||||
? <LinkIconS className='heroicon' />
|
||||
|
@ -58,7 +58,7 @@ export function Bar(props: IBarProps): JSX.Element {
|
|||
<BarIcon
|
||||
isActive={props.isMessagesOpen}
|
||||
title={Text({ textId: '@Messages' })}
|
||||
onClick={() => props.toggleMessages()}>
|
||||
onClick={() => { props.toggleMessages(); }}>
|
||||
{
|
||||
props.isMessagesOpen
|
||||
? <EnvolopeIconS className='heroicon' />
|
||||
|
@ -69,7 +69,7 @@ export function Bar(props: IBarProps): JSX.Element {
|
|||
<BarIcon
|
||||
isActive={props.isHistoryOpen}
|
||||
title={Text({ textId: '@Timeline' })}
|
||||
onClick={() => props.toggleTimeline()}>
|
||||
onClick={() => { props.toggleTimeline(); }}>
|
||||
{
|
||||
props.isHistoryOpen
|
||||
? <ClockIconS className='heroicon' />
|
||||
|
@ -79,7 +79,7 @@ export function Bar(props: IBarProps): JSX.Element {
|
|||
<BarIcon
|
||||
isActive={props.isSettingsOpen}
|
||||
title={Text({ textId: '@Settings' })}
|
||||
onClick={() => props.toggleSettings()}>
|
||||
onClick={() => { props.toggleSettings(); }}>
|
||||
{
|
||||
props.isSettingsOpen
|
||||
? <Cog8ToothIconS className='heroicon' />
|
||||
|
|
|
@ -8,12 +8,14 @@ interface IBarIconProps {
|
|||
}
|
||||
|
||||
export function BarIcon(props: IBarIconProps): JSX.Element {
|
||||
const isActiveClasses = props.isActive ? 'border-l-4 border-blue-500 bg-slate-200' : '';
|
||||
const isActiveClasses = props.isActive
|
||||
? 'border-l-4 border-blue-500 bg-slate-200'
|
||||
: '';
|
||||
return (
|
||||
<button type="button"
|
||||
className={`bar-btn group ${isActiveClasses}`}
|
||||
title={props.title}
|
||||
onClick={() => props.onClick()}
|
||||
onClick={() => { props.onClick(); }}
|
||||
>
|
||||
<span className='sidebar-tooltip group-hover:scale-100'>{props.title}</span>
|
||||
{props.children}
|
||||
|
|
|
@ -48,7 +48,12 @@ function Draw(
|
|||
ctx,
|
||||
mainContainer,
|
||||
containers,
|
||||
leftDim, bottomDim, topDim, rightDim, scale);
|
||||
leftDim,
|
||||
bottomDim,
|
||||
topDim,
|
||||
rightDim,
|
||||
scale
|
||||
);
|
||||
|
||||
// Draw symbols and symbol dimensions
|
||||
RenderSymbols(ctx, symbols, scale);
|
||||
|
@ -74,12 +79,10 @@ function Draw(
|
|||
ctx.restore();
|
||||
}
|
||||
|
||||
function UseCanvas(
|
||||
draw: (context: CanvasRenderingContext2D,
|
||||
frameCount: number,
|
||||
scale: number,
|
||||
translatePos: IPoint) => void
|
||||
): React.RefObject<HTMLCanvasElement> {
|
||||
function UseCanvas(draw: (context: CanvasRenderingContext2D,
|
||||
frameCount: number,
|
||||
scale: number,
|
||||
translatePos: IPoint) => void): React.RefObject<HTMLCanvasElement> {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
const frameCount = useRef(0);
|
||||
const translatePos = useRef({
|
||||
|
@ -169,9 +172,7 @@ function UseCanvas(
|
|||
return canvasRef;
|
||||
}
|
||||
|
||||
function UseSVGAutoResizer(
|
||||
setViewer: React.Dispatch<React.SetStateAction<Viewer>>
|
||||
): void {
|
||||
function UseSVGAutoResizer(setViewer: React.Dispatch<React.SetStateAction<Viewer>>): void {
|
||||
React.useEffect(() => {
|
||||
function OnResize(): void {
|
||||
setViewer({
|
||||
|
@ -199,9 +200,7 @@ export function Canvas({
|
|||
style,
|
||||
drawParams
|
||||
}: ICanvasProps): JSX.Element {
|
||||
const canvasRef = UseCanvas((
|
||||
...CanvasProps
|
||||
) => {
|
||||
const canvasRef = UseCanvas((...CanvasProps) => {
|
||||
Draw(
|
||||
...CanvasProps,
|
||||
drawParams
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { NOTCHES_LENGTH } from '../../utils/default';
|
||||
import { IDimensionStyle } from '../SVG/Elements/Dimension';
|
||||
import { type IDimensionStyle } from '../SVG/Elements/Dimension';
|
||||
|
||||
interface IDimensionProps {
|
||||
id: string
|
||||
|
|
|
@ -169,11 +169,13 @@ function AddHorizontalChildrenDimension(
|
|||
let xChildrenStart = TransformX(
|
||||
lastChild.properties.x,
|
||||
lastChild.properties.width,
|
||||
lastChild.properties.positionReference);
|
||||
lastChild.properties.positionReference
|
||||
);
|
||||
let xChildrenEnd = TransformX(
|
||||
lastChild.properties.x,
|
||||
lastChild.properties.width,
|
||||
lastChild.properties.positionReference);
|
||||
lastChild.properties.positionReference
|
||||
);
|
||||
|
||||
// Find the min and max
|
||||
for (let i = container.children.length - 2; i >= 0; i--) {
|
||||
|
@ -237,7 +239,8 @@ function AddVerticalChildrenDimension(
|
|||
let yChildrenStart = TransformY(
|
||||
lastChild.properties.y,
|
||||
lastChild.properties.height,
|
||||
lastChild.properties.positionReference);
|
||||
lastChild.properties.positionReference
|
||||
);
|
||||
let yChildrenEnd = yChildrenStart;
|
||||
|
||||
// Find the min and max
|
||||
|
@ -313,9 +316,7 @@ function AddHorizontalBorrowerDimension(
|
|||
|
||||
const restoredX = x + childCurrentTransform[0];
|
||||
|
||||
marks.push(
|
||||
restoredX
|
||||
);
|
||||
marks.push(restoredX);
|
||||
}
|
||||
|
||||
const restoredX = container.properties.x + currentTransform[0];
|
||||
|
@ -373,9 +374,7 @@ function AddVerticalBorrowerDimension(
|
|||
|
||||
const restoredy = y + childCurrentTransform[1];
|
||||
|
||||
marks.push(
|
||||
restoredy
|
||||
);
|
||||
marks.push(restoredy);
|
||||
}
|
||||
|
||||
const restoredY = container.properties.y + currentTransform[1];
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { type IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { type IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { DIMENSION_MARGIN } from '../../utils/default';
|
||||
import { MakeRecursionDFSIterator } from '../../utils/itertools';
|
||||
import { RenderContainer } from './Container';
|
||||
|
|
|
@ -25,7 +25,11 @@ export function RenderContainerSelector(
|
|||
props.selected.properties.height
|
||||
];
|
||||
|
||||
({ x, y, width, height } = RemoveMargin(x, y, width, height,
|
||||
({ x, y, width, height } = RemoveMargin(
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
props.selected.properties.margin.left,
|
||||
props.selected.properties.margin.bottom,
|
||||
props.selected.properties.margin.top,
|
||||
|
|
|
@ -5,7 +5,8 @@ const IMAGE_CACHE = new Map<string, HTMLImageElement>();
|
|||
|
||||
export function RenderSymbol(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
symbol: ISymbolModel): void {
|
||||
symbol: ISymbolModel
|
||||
): void {
|
||||
const href = symbol.config.Image.Base64Image ?? symbol.config.Image.Url;
|
||||
|
||||
if (href === undefined) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ChevronRightIcon } from '@heroicons/react/24/outline';
|
||||
import React, { useState } from 'react';
|
||||
import { ICategory } from '../../Interfaces/ICategory';
|
||||
import { type ICategory } from '../../Interfaces/ICategory';
|
||||
import { TruncateString } from '../../utils/stringtools';
|
||||
|
||||
interface ICategoryProps {
|
||||
|
@ -20,23 +20,40 @@ export function Category(props: ICategoryProps): JSX.Element {
|
|||
|
||||
return (
|
||||
<div
|
||||
className={` transition-all text-center ${isOpen ? 'overflow-hidden h-full' : `overflow-visible ${heightClass}`}`}
|
||||
className={` transition-all text-center ${isOpen
|
||||
? 'overflow-hidden h-full'
|
||||
: `overflow-visible ${heightClass}`}`}
|
||||
key={categoryType}
|
||||
id={categoryType}
|
||||
title={categoryDisplayedText}
|
||||
>
|
||||
<div
|
||||
className={`flex flex-row group cursor-pointer ${heightClass}`}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
onClick={() => { setIsOpen(!isOpen); }}
|
||||
>
|
||||
<span className={`transition-all flex-1 h-full justify-center sidebar-component-left ${isOpen ? 'rounded-b-none bg-slate-400/80 group-hover:bg-blue-600' : ''}`}>
|
||||
<span className={
|
||||
`transition-all flex-1 h-full
|
||||
justify-center sidebar-component-left
|
||||
${isOpen
|
||||
? 'rounded-b-none bg-slate-400/80 group-hover:bg-blue-600'
|
||||
: ''}`}
|
||||
>
|
||||
{TruncateString(categoryDisplayedText, 25)}
|
||||
</span>
|
||||
<span className={`flex-none h-full justify-center sidebar-component-right ${isOpen ? 'rounded-b-none' : ''}`}>
|
||||
<ChevronRightIcon className={`transition-all w-5 ${isOpen ? 'rotate-90' : ''}`} />
|
||||
<span className={`flex-none h-full justify-center sidebar-component-right ${isOpen
|
||||
? 'rounded-b-none'
|
||||
: ''}`}>
|
||||
<ChevronRightIcon className={`transition-all w-5 ${isOpen
|
||||
? 'rotate-90'
|
||||
: ''}`} />
|
||||
</span>
|
||||
</div>
|
||||
<div className={`transition-all grid gap-2 p-2 rounded-b-lg ${isOpen ? 'visible overflow-auto bg-slate-400/80' : 'hidden overflow-hidden'}`}>
|
||||
<div className={
|
||||
`transition-all grid gap-2 p-2 rounded-b-lg
|
||||
${isOpen
|
||||
? 'visible overflow-auto bg-slate-400/80'
|
||||
: 'hidden overflow-hidden'}`}
|
||||
>
|
||||
{ props.children }
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -80,7 +80,9 @@ export function CheckboxGroupButtons(props: ICheckboxGroupButtonsProps): JSX.Ele
|
|||
* @returns The new selected values
|
||||
*/
|
||||
function SetChecked(selectedValue: number, isChecked: boolean): number[] {
|
||||
isChecked ? selectedOptions.add(selectedValue) : selectedOptions.delete(selectedValue);
|
||||
isChecked
|
||||
? selectedOptions.add(selectedValue)
|
||||
: selectedOptions.delete(selectedValue);
|
||||
return [...selectedOptions];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { ChevronUpDownIcon } from '@heroicons/react/20/solid';
|
||||
import { CheckboxGroupButtons } from './CheckboxGroupButtons';
|
||||
import { Orientation } from '../../Enums/Orientation';
|
||||
import { CheckboxGroupButtons } from './CheckboxGroupButtons';
|
||||
|
||||
interface IOrientationCheckboxesProps {
|
||||
id: string
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { EyeIcon, EyeSlashIcon, XCircleIcon } from '@heroicons/react/24/outline';
|
||||
import * as React from 'react';
|
||||
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
|
||||
import { ICategory } from '../../Interfaces/ICategory';
|
||||
import { IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { type Dispatch } from 'react';
|
||||
import { type IAvailableContainer } from '../../Interfaces/IAvailableContainer';
|
||||
import { type ICategory } from '../../Interfaces/ICategory';
|
||||
import { type IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { TruncateString } from '../../utils/stringtools';
|
||||
import { Category } from '../Category/Category';
|
||||
import { Text } from '../Text/Text';
|
||||
import { IReplaceContainer } from '../../Interfaces/IReplaceContainer';
|
||||
import { Dispatch } from 'react';
|
||||
import { type IReplaceContainer } from '../../Interfaces/IReplaceContainer';
|
||||
|
||||
interface IComponentsProps {
|
||||
selectedContainer: IContainerModel | undefined
|
||||
|
@ -29,7 +29,9 @@ interface SidebarCategory {
|
|||
|
||||
export function Components(props: IComponentsProps): JSX.Element {
|
||||
const [hideDisabled, setHideDisabled] = React.useState<boolean>(false);
|
||||
const disabledTitle = hideDisabled ? Text({ textId: '@ShowDisabledComponents' }) : Text({ textId: '@HideDisabledComponents' });
|
||||
const disabledTitle = hideDisabled
|
||||
? Text({ textId: '@ShowDisabledComponents' })
|
||||
: Text({ textId: '@HideDisabledComponents' });
|
||||
|
||||
const rootElements: Array<JSX.Element | undefined> = [];
|
||||
const categories = new Map<string, SidebarCategory>(props.categories.map(category => [
|
||||
|
@ -42,13 +44,12 @@ export function Components(props: IComponentsProps): JSX.Element {
|
|||
|
||||
// build the categories (sorted with categories first)
|
||||
categories.forEach((categoryWrapper, categoryName) => {
|
||||
rootElements.push(
|
||||
<Category
|
||||
key={categoryName}
|
||||
category={categoryWrapper.category}
|
||||
>
|
||||
{ categoryWrapper.children }
|
||||
</Category>);
|
||||
rootElements.push(<Category
|
||||
key={categoryName}
|
||||
category={categoryWrapper.category}
|
||||
>
|
||||
{ categoryWrapper.children }
|
||||
</Category>);
|
||||
});
|
||||
|
||||
const selectedContainer = props.selectedContainer;
|
||||
|
@ -80,9 +81,9 @@ export function Components(props: IComponentsProps): JSX.Element {
|
|||
className='w-full justify-center h-16 transition-all sidebar-component'
|
||||
id={componentOption.Type}
|
||||
title={componentOption.Type}
|
||||
onClick={() => props.buttonOnClick(componentOption.Type)}
|
||||
onClick={() => { props.buttonOnClick(componentOption.Type); }}
|
||||
draggable={true}
|
||||
onDragStart={(event) => HandleDragStart(event)}
|
||||
onDragStart={(event) => { HandleDragStart(event); }}
|
||||
disabled={disabled}
|
||||
>
|
||||
{TruncateString(componentOption.DisplayedText ?? componentOption.Type, 25)}
|
||||
|
|
|
@ -192,13 +192,17 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={props.properties.minWidth}
|
||||
max={props.properties.maxWidth}
|
||||
value={(RemoveWidthMargin(props.properties.width,
|
||||
value={(RemoveWidthMargin(
|
||||
props.properties.width,
|
||||
props.properties.margin.left,
|
||||
props.properties.margin.right)).toString()}
|
||||
props.properties.margin.right
|
||||
)).toString()}
|
||||
onChange={(value) => {
|
||||
props.onChange('width', ApplyWidthMargin(Number(value),
|
||||
props.onChange('width', ApplyWidthMargin(
|
||||
Number(value),
|
||||
props.properties.margin.left,
|
||||
props.properties.margin.right));
|
||||
props.properties.margin.right
|
||||
));
|
||||
}}
|
||||
isDisabled={props.properties.isFlex}/>
|
||||
<TextInputGroup
|
||||
|
@ -231,13 +235,17 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={props.properties.minHeight}
|
||||
max={props.properties.maxHeight}
|
||||
value={(RemoveWidthMargin(props.properties.height,
|
||||
value={(RemoveWidthMargin(
|
||||
props.properties.height,
|
||||
props.properties.margin.top,
|
||||
props.properties.margin.bottom)).toString()}
|
||||
props.properties.margin.bottom
|
||||
)).toString()}
|
||||
onChange={(value) => {
|
||||
props.onChange('height', ApplyWidthMargin(Number(value),
|
||||
props.onChange('height', ApplyWidthMargin(
|
||||
Number(value),
|
||||
props.properties.margin.top,
|
||||
props.properties.margin.bottom));
|
||||
props.properties.margin.bottom
|
||||
));
|
||||
}}
|
||||
isDisabled={props.properties.isFlex}
|
||||
/>
|
||||
|
@ -270,7 +278,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.margin.left ?? 0).toString()}
|
||||
onChange={(value) => { props.onChange('left', Number(value), PropertyType.Margin); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('left', Number(value), PropertyType.Margin);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-mb`}
|
||||
labelText={Text({ textId: '@ContainerMarginBottom' })}
|
||||
|
@ -280,7 +290,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.margin.bottom ?? 0).toString()}
|
||||
onChange={(value) => { props.onChange('bottom', Number(value), PropertyType.Margin); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('bottom', Number(value), PropertyType.Margin);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-mt`}
|
||||
labelText={Text({ textId: '@ContainerMarginTop' })}
|
||||
|
@ -290,7 +302,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.margin.top ?? 0).toString()}
|
||||
onChange={(value) => { props.onChange('top', Number(value), PropertyType.Margin); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('top', Number(value), PropertyType.Margin);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-mr`}
|
||||
labelText={Text({ textId: '@ContainerMarginRight' })}
|
||||
|
@ -300,7 +314,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.margin.right ?? 0).toString()}
|
||||
onChange={(value) => { props.onChange('right', Number(value), PropertyType.Margin); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('right', Number(value), PropertyType.Margin);
|
||||
}}/>
|
||||
</div>
|
||||
</Category>
|
||||
|
||||
|
@ -377,7 +393,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
name='ShowSelfDimensions'
|
||||
labelText={Text({ textId: '@ContainerShowDimension' })}
|
||||
value={props.properties.dimensionOptions.selfDimensions.positions}
|
||||
onChange={(key, value) => { props.onChange(key, value, PropertyType.SelfDimension); }}
|
||||
onChange={(key, value) => {
|
||||
props.onChange(key, value, PropertyType.SelfDimension);
|
||||
}}
|
||||
/>
|
||||
<InputGroup
|
||||
labelText={Text({ textId: '@StyleStrokeColor' })}
|
||||
|
@ -386,7 +404,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='color'
|
||||
value={props.properties.dimensionOptions.selfDimensions.color ?? '#000000'}
|
||||
onChange={(e) => { props.onChange('color', e.target.value, PropertyType.SelfDimension); }}/>
|
||||
onChange={(e) => {
|
||||
props.onChange('color', e.target.value, PropertyType.SelfDimension);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-selfDimensions-width`}
|
||||
labelText={Text({ textId: '@StyleStrokeWidth' })}
|
||||
|
@ -396,7 +416,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.dimensionOptions.selfDimensions.width ?? 0).toString()}
|
||||
onChange={(value) => { props.onChange('width', Number(value), PropertyType.SelfDimension); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('width', Number(value), PropertyType.SelfDimension);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-selfDimensions-dasharray`}
|
||||
labelText={Text({ textId: '@StyleStrokeDashArray' })}
|
||||
|
@ -405,7 +427,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='text'
|
||||
value={props.properties.dimensionOptions.selfDimensions.dashArray ?? ''}
|
||||
onChange={(value) => { props.onChange('dashArray', value, PropertyType.SelfDimension); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('dashArray', value, PropertyType.SelfDimension);
|
||||
}}/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
|
@ -417,7 +441,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
name='ShowSelfMarginsDimensions'
|
||||
labelText={Text({ textId: '@ContainerShowMarginsDimension' })}
|
||||
value={props.properties.dimensionOptions.selfMarginsDimensions.positions}
|
||||
onChange={(key, value) => { props.onChange(key, value, PropertyType.SelfMarginDimension); }}
|
||||
onChange={(key, value) => {
|
||||
props.onChange(key, value, PropertyType.SelfMarginDimension);
|
||||
}}
|
||||
/>
|
||||
<InputGroup
|
||||
labelText={Text({ textId: '@StyleStrokeColor' })}
|
||||
|
@ -426,7 +452,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='color'
|
||||
value={props.properties.dimensionOptions.selfMarginsDimensions.color ?? '#000000'}
|
||||
onChange={(e) => { props.onChange('color', e.target.value, PropertyType.SelfMarginDimension); }}/>
|
||||
onChange={(e) => {
|
||||
props.onChange('color', e.target.value, PropertyType.SelfMarginDimension);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-selfMarginsDimensions-width`}
|
||||
labelText={Text({ textId: '@StyleStrokeWidth' })}
|
||||
|
@ -436,7 +464,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.dimensionOptions.selfMarginsDimensions.width ?? 0).toString()}
|
||||
onChange={(value) => { props.onChange('width', Number(value), PropertyType.SelfMarginDimension); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('width', Number(value), PropertyType.SelfMarginDimension);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-selfMarginsDimensions-dasharray`}
|
||||
labelText={Text({ textId: '@StyleStrokeDashArray' })}
|
||||
|
@ -445,7 +475,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='text'
|
||||
value={props.properties.dimensionOptions.selfMarginsDimensions.dashArray ?? ''}
|
||||
onChange={(value) => { props.onChange('dashArray', value, PropertyType.SelfMarginDimension); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('dashArray', value, PropertyType.SelfMarginDimension);
|
||||
}}/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
|
@ -457,7 +489,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
name='ShowChildrenDimensions'
|
||||
labelText={Text({ textId: '@ContainerShowChildrenDimension' })}
|
||||
value={props.properties.dimensionOptions.childrenDimensions.positions}
|
||||
onChange={(key, value) => { props.onChange(key, value, PropertyType.ChildrenDimensions); }}
|
||||
onChange={(key, value) => {
|
||||
props.onChange(key, value, PropertyType.ChildrenDimensions);
|
||||
}}
|
||||
/>
|
||||
<InputGroup
|
||||
labelText={Text({ textId: '@StyleStrokeColor' })}
|
||||
|
@ -466,7 +500,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='color'
|
||||
value={props.properties.dimensionOptions.childrenDimensions.color ?? '#000000'}
|
||||
onChange={(e) => { props.onChange('color', e.target.value, PropertyType.ChildrenDimensions); }}/>
|
||||
onChange={(e) => {
|
||||
props.onChange('color', e.target.value, PropertyType.ChildrenDimensions);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-childrenDimensions-width`}
|
||||
labelText={Text({ textId: '@StyleStrokeWidth' })}
|
||||
|
@ -476,7 +512,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.dimensionOptions.childrenDimensions.width ?? 0).toString()}
|
||||
onChange={(value) => { props.onChange('width', Number(value), PropertyType.ChildrenDimensions); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('width', Number(value), PropertyType.ChildrenDimensions);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-childrenDimensions-dasharray`}
|
||||
labelText={Text({ textId: '@StyleStrokeDashArray' })}
|
||||
|
@ -485,7 +523,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='text'
|
||||
value={props.properties.dimensionOptions.childrenDimensions.dashArray ?? ''}
|
||||
onChange={(value) => { props.onChange('dashArray', value, PropertyType.ChildrenDimensions); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('dashArray', value, PropertyType.ChildrenDimensions);
|
||||
}}/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
|
@ -497,7 +537,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
name='MarkPosition'
|
||||
value={props.properties.dimensionOptions.markPosition}
|
||||
labelText={Text({ textId: '@ContainerMarkPosition' })}
|
||||
onChange={(key, value) => { props.onChange(key, value, PropertyType.DimensionOptions); }}
|
||||
onChange={(key, value) => {
|
||||
props.onChange(key, value, PropertyType.DimensionOptions);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='grid grid-cols-1 gap-2'>
|
||||
|
@ -507,7 +549,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
name='ShowDimensionWithMarks'
|
||||
labelText={Text({ textId: '@ContainerShowDimensionWithMarks' })}
|
||||
value={props.properties.dimensionOptions.dimensionWithMarks.positions}
|
||||
onChange={(key, value) => { props.onChange(key, value, PropertyType.DimensionWithMarks); }}
|
||||
onChange={(key, value) => {
|
||||
props.onChange(key, value, PropertyType.DimensionWithMarks);
|
||||
}}
|
||||
/>
|
||||
<InputGroup
|
||||
labelText={Text({ textId: '@StyleStrokeColor' })}
|
||||
|
@ -516,7 +560,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='color'
|
||||
value={props.properties.dimensionOptions.dimensionWithMarks.color ?? '#000000'}
|
||||
onChange={(e) => { props.onChange('color', e.target.value, PropertyType.DimensionWithMarks); }}/>
|
||||
onChange={(e) => {
|
||||
props.onChange('color', e.target.value, PropertyType.DimensionWithMarks);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-dimensionWithMarks-width`}
|
||||
labelText={Text({ textId: '@StyleStrokeWidth' })}
|
||||
|
@ -526,7 +572,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
type='number'
|
||||
min={0}
|
||||
value={(props.properties.dimensionOptions.dimensionWithMarks.width ?? 0).toString()}
|
||||
onChange={(value) => { props.onChange('width', Number(value), PropertyType.DimensionWithMarks); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('width', Number(value), PropertyType.DimensionWithMarks);
|
||||
}}/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-dimensionWithMarks-dasharray`}
|
||||
labelText={Text({ textId: '@StyleStrokeDashArray' })}
|
||||
|
@ -535,7 +583,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName=''
|
||||
type='text'
|
||||
value={props.properties.dimensionOptions.dimensionWithMarks.dashArray ?? ''}
|
||||
onChange={(value) => { props.onChange('dashArray', value, PropertyType.DimensionWithMarks); }}/>
|
||||
onChange={(value) => {
|
||||
props.onChange('dashArray', value, PropertyType.DimensionWithMarks);
|
||||
}}/>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
@ -557,7 +607,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName='col-span-3'
|
||||
type='color'
|
||||
value={props.properties.style.stroke ?? '#000000'}
|
||||
onChange={(e) => { props.onChange('stroke', e.target.value, PropertyType.Style); }}/>
|
||||
onChange={(e) => {
|
||||
props.onChange('stroke', e.target.value, PropertyType.Style);
|
||||
}}/>
|
||||
<InputGroup
|
||||
labelKey={`${props.properties.id}-strokeOpacity`}
|
||||
labelText={Text({ textId: '@StyleStrokeOpacity' })}
|
||||
|
@ -569,7 +621,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
max={1}
|
||||
step={0.01}
|
||||
value={(props.properties.style.strokeOpacity ?? 1).toString()}
|
||||
onChange={(event) => { props.onChange('strokeOpacity', Number(event.target.value), PropertyType.Style); }}
|
||||
onChange={(event) => {
|
||||
props.onChange('strokeOpacity', Number(event.target.value), PropertyType.Style);
|
||||
}}
|
||||
/>
|
||||
<TextInputGroup
|
||||
id={`${props.properties.id}-strokeWidth`}
|
||||
|
@ -579,7 +633,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName='col-span-3'
|
||||
type='number'
|
||||
value={(props.properties.style.strokeWidth ?? 1).toString()}
|
||||
onChange={(value) => { props.onChange('strokeWidth', Number(value), PropertyType.Style); }}
|
||||
onChange={(value) => {
|
||||
props.onChange('strokeWidth', Number(value), PropertyType.Style);
|
||||
}}
|
||||
/>
|
||||
<InputGroup
|
||||
labelText={Text({ textId: '@StyleFill' })}
|
||||
|
@ -588,7 +644,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
inputClassName='col-span-3'
|
||||
type='color'
|
||||
value={props.properties.style.fill ?? '#000000'}
|
||||
onChange={(e) => { props.onChange('fill', e.target.value, PropertyType.Style); }}/>
|
||||
onChange={(e) => {
|
||||
props.onChange('fill', e.target.value, PropertyType.Style);
|
||||
}}/>
|
||||
<InputGroup
|
||||
labelKey={`${props.properties.id}-fillOpacity`}
|
||||
labelText={Text({ textId: '@StyleFillOpacity' })}
|
||||
|
@ -600,7 +658,9 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
|||
max={1}
|
||||
step={0.01}
|
||||
value={(props.properties.style.fillOpacity ?? 1).toString()}
|
||||
onChange={(event) => { props.onChange('fillOpacity', Number(event.target.value), PropertyType.Style); }}
|
||||
onChange={(event) => {
|
||||
props.onChange('fillOpacity', Number(event.target.value), PropertyType.Style);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Category>
|
||||
|
|
|
@ -2,10 +2,10 @@ import { fireEvent, render, screen } from '@testing-library/react';
|
|||
import * as React from 'react';
|
||||
import { expect, describe, it, vi } from 'vitest';
|
||||
import { PositionReference } from '../../Enums/PositionReference';
|
||||
import { IContainerProperties } from '../../Interfaces/IContainerProperties';
|
||||
import { type IContainerProperties } from '../../Interfaces/IContainerProperties';
|
||||
import { Orientation } from '../../Enums/Orientation';
|
||||
import { ContainerProperties } from './ContainerProperties';
|
||||
import { DEFAULT_DIMENSION_OPTION } from '../../utils/default';
|
||||
import { ContainerProperties } from './ContainerProperties';
|
||||
|
||||
describe.concurrent('Properties', () => {
|
||||
it('No properties', () => {
|
||||
|
|
|
@ -2,8 +2,8 @@ import React from 'react';
|
|||
import { type PropertyType } from '../../Enums/PropertyType';
|
||||
import { type IContainerProperties } from '../../Interfaces/IContainerProperties';
|
||||
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { ContainerForm } from './ContainerForm';
|
||||
import { type IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { ContainerForm } from './ContainerForm';
|
||||
|
||||
interface IPropertiesProps {
|
||||
containers: Map<string, IContainerModel>
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
*/
|
||||
|
||||
import { AddMethod } from '../../../Enums/AddMethod';
|
||||
import { IAvailableContainer } from '../../../Interfaces/IAvailableContainer';
|
||||
import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { IPattern, GetPattern, ContainerOrPattern } from '../../../Interfaces/IPattern';
|
||||
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { type IAvailableContainer } from '../../../Interfaces/IAvailableContainer';
|
||||
import { type IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { type IPattern, GetPattern, type ContainerOrPattern } from '../../../Interfaces/IPattern';
|
||||
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { Orientation } from '../../../Enums/Orientation';
|
||||
import { GetDefaultContainerProps } from '../../../utils/default';
|
||||
import { FindContainerById } from '../../../utils/itertools';
|
||||
|
@ -69,9 +69,7 @@ export function AddContainers(
|
|||
const containers = structuredClone(current.containers);
|
||||
|
||||
// Find the parent in the clone
|
||||
const parentClone: IContainerModel | undefined = FindContainerById(
|
||||
containers, parentId
|
||||
);
|
||||
const parentClone: IContainerModel | undefined = FindContainerById(containers, parentId);
|
||||
|
||||
if (parentClone === null || parentClone === undefined) {
|
||||
throw new Error('[AddContainer] Container model was not found among children of the main container!');
|
||||
|
@ -144,8 +142,14 @@ function AddNewContainerToParent(
|
|||
const right: number = containerConfig.Margin?.right ?? 0;
|
||||
|
||||
// Default coordinates
|
||||
let width = containerConfig.Width ?? containerConfig.MaxWidth ?? containerConfig.MinWidth ?? parentClone.properties.width;
|
||||
let height = containerConfig.Height ?? containerConfig.MaxHeight ?? containerConfig.MinHeight ?? parentClone.properties.height;
|
||||
let width = containerConfig.Width ??
|
||||
containerConfig.MaxWidth ??
|
||||
containerConfig.MinWidth ??
|
||||
parentClone.properties.width;
|
||||
let height = containerConfig.Height ??
|
||||
containerConfig.MaxHeight ??
|
||||
containerConfig.MinHeight ??
|
||||
parentClone.properties.height;
|
||||
let x = RestoreX(containerConfig.X ?? 0, width, containerConfig.PositionReference);
|
||||
let y = RestoreY(containerConfig.Y ?? 0, height, containerConfig.PositionReference);
|
||||
|
||||
|
@ -288,7 +292,8 @@ function InitializeDefaultChild(
|
|||
configuration,
|
||||
containers,
|
||||
parent,
|
||||
0, 0,
|
||||
0,
|
||||
0,
|
||||
newCounters,
|
||||
symbols
|
||||
);
|
||||
|
@ -308,12 +313,17 @@ function InitializeChildrenWithPattern(
|
|||
return;
|
||||
}
|
||||
|
||||
const configs: Map<string, IAvailableContainer> = new Map(configuration.AvailableContainers.map(config => [config.Type, config]));
|
||||
const patterns: Map<string, IPattern> = new Map(configuration.Patterns.map(pattern => [pattern.id, pattern]));
|
||||
const configs = new Map<string, IAvailableContainer>(
|
||||
configuration.AvailableContainers.map(config => [config.Type, config])
|
||||
);
|
||||
const patterns = new Map<string, IPattern>(
|
||||
configuration.Patterns.map(pattern => [pattern.id, pattern])
|
||||
);
|
||||
const containerOrPattern = GetPattern(patternId, configs, patterns);
|
||||
|
||||
if (containerOrPattern === undefined) {
|
||||
console.warn(`[InitializeChildrenWithPattern] PatternId ${patternId} was neither found as Pattern nor as IAvailableContainer`);
|
||||
console.warn('[InitializeChildrenWithPattern]' +
|
||||
`PatternId ${patternId} was neither found as Pattern nor as IAvailableContainer`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -356,7 +366,16 @@ function BuildPatterns(
|
|||
while (levelSize-- !== 0) {
|
||||
const node = queue.shift() as Node;
|
||||
|
||||
const newParent = AddContainerInLevel(node, maxLevelSize, levelSize, configuration, containers, newCounters, symbols, configs);
|
||||
const newParent = AddContainerInLevel(
|
||||
node,
|
||||
maxLevelSize,
|
||||
levelSize,
|
||||
configuration,
|
||||
containers,
|
||||
newCounters,
|
||||
symbols,
|
||||
configs
|
||||
);
|
||||
|
||||
if (newParent === undefined) {
|
||||
// node.pattern is not a IPattern, there is no children to iterate
|
||||
|
@ -411,7 +430,8 @@ function AddContainerInLevel(
|
|||
configuration,
|
||||
containers,
|
||||
node.parent,
|
||||
index, 0,
|
||||
index,
|
||||
0,
|
||||
newCounters,
|
||||
symbols
|
||||
);
|
||||
|
@ -429,8 +449,9 @@ function AddContainerInLevel(
|
|||
// and set the new parent as the child of this parent
|
||||
const container = configs.get(pattern.wrapper);
|
||||
if (container === undefined) {
|
||||
console.warn(`[InitializeChildrenFromPattern] IAvailableContainer from pattern was not found in the configuration: ${pattern.wrapper}.
|
||||
Process will ignore the container.`);
|
||||
console.warn('[InitializeChildrenFromPattern]' +
|
||||
` IAvailableContainer from pattern was not found in the configuration: ${pattern.wrapper}.
|
||||
Process will ignore the container.`);
|
||||
return { parent, pattern };
|
||||
}
|
||||
|
||||
|
@ -439,7 +460,8 @@ function AddContainerInLevel(
|
|||
configuration,
|
||||
containers,
|
||||
parent,
|
||||
0, 0,
|
||||
0,
|
||||
0,
|
||||
newCounters,
|
||||
symbols,
|
||||
false
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import Swal from 'sweetalert2';
|
||||
import { type IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { FindContainerById, MakeDFSIterator } from '../../../utils/itertools';
|
||||
import { GetCurrentHistory } from '../Editor';
|
||||
import { ApplyBehaviors, ApplyBehaviorsOnSiblings, ApplyBehaviorsOnSiblingsChildren } from '../Behaviors/Behaviors';
|
||||
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import Swal from 'sweetalert2';
|
||||
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { PropertyType } from '../../../Enums/PropertyType';
|
||||
import { TransformX, TransformY } from '../../../utils/svg';
|
||||
import { Orientation } from '../../../Enums/Orientation';
|
||||
import { type IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { AddContainers } from './AddContainer';
|
||||
import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
|
||||
/**
|
||||
* Select a container
|
||||
|
@ -82,7 +82,8 @@ export function DeleteContainer(
|
|||
const container = FindContainerById(containers, containerId);
|
||||
|
||||
if (container === undefined) {
|
||||
throw new Error(`[DeleteContainer] Tried to delete a container that is not present in the main container: ${containerId}`);
|
||||
throw new Error('[DeleteContainer]' +
|
||||
`Tried to delete a container that is not present in the main container: ${containerId}`);
|
||||
}
|
||||
|
||||
const parent = FindContainerById(containers, container.properties.parentId);
|
||||
|
@ -94,7 +95,8 @@ export function DeleteContainer(
|
|||
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!');
|
||||
}
|
||||
|
||||
if (container === null || container === undefined) {
|
||||
|
@ -168,7 +170,9 @@ export function ReplaceByContainer(
|
|||
containerParent.children.indexOf(containerId),
|
||||
[{ Type: newContainerId }],
|
||||
containerParent.properties.id,
|
||||
configuration, fullHistory, historyCurrentStep
|
||||
configuration,
|
||||
fullHistory,
|
||||
historyCurrentStep
|
||||
);
|
||||
|
||||
const historyDelete = DeleteContainer(containerId, historyAdd.history, historyCurrentStep + 1);
|
||||
|
@ -294,34 +298,7 @@ export function SortChildren(
|
|||
const children = parent.children;
|
||||
|
||||
if (!isHorizontal) {
|
||||
parent.children.sort(
|
||||
(aId, bId) => {
|
||||
const a = FindContainerById(containers, aId);
|
||||
const b = FindContainerById(containers, bId);
|
||||
|
||||
if (a === undefined || b === undefined) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const yA = TransformY(a.properties.y, a.properties.height, a.properties.positionReference);
|
||||
const yB = TransformY(b.properties.y, b.properties.height, b.properties.positionReference);
|
||||
if (yA < yB) {
|
||||
return -1;
|
||||
}
|
||||
if (yB < yA) {
|
||||
return 1;
|
||||
}
|
||||
// xA = xB
|
||||
const indexA = children.indexOf(aId);
|
||||
const indexB = children.indexOf(bId);
|
||||
return indexA - indexB;
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
parent.children.sort(
|
||||
(aId, bId) => {
|
||||
parent.children.sort((aId, bId) => {
|
||||
const a = FindContainerById(containers, aId);
|
||||
const b = FindContainerById(containers, bId);
|
||||
|
||||
|
@ -329,20 +306,43 @@ export function SortChildren(
|
|||
return 0;
|
||||
}
|
||||
|
||||
const xA = TransformX(a.properties.x, a.properties.width, a.properties.positionReference);
|
||||
const xB = TransformX(b.properties.x, b.properties.width, b.properties.positionReference);
|
||||
if (xA < xB) {
|
||||
const yA = TransformY(a.properties.y, a.properties.height, a.properties.positionReference);
|
||||
const yB = TransformY(b.properties.y, b.properties.height, b.properties.positionReference);
|
||||
if (yA < yB) {
|
||||
return -1;
|
||||
}
|
||||
if (xB < xA) {
|
||||
if (yB < yA) {
|
||||
return 1;
|
||||
}
|
||||
// xA = xB
|
||||
const indexA = children.indexOf(aId);
|
||||
const indexB = children.indexOf(bId);
|
||||
return indexA - indexB;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
parent.children.sort((aId, bId) => {
|
||||
const a = FindContainerById(containers, aId);
|
||||
const b = FindContainerById(containers, bId);
|
||||
|
||||
if (a === undefined || b === undefined) {
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
|
||||
const xA = TransformX(a.properties.x, a.properties.width, a.properties.positionReference);
|
||||
const xB = TransformX(b.properties.x, b.properties.width, b.properties.positionReference);
|
||||
if (xA < xB) {
|
||||
return -1;
|
||||
}
|
||||
if (xB < xA) {
|
||||
return 1;
|
||||
}
|
||||
// xA = xB
|
||||
const indexA = children.indexOf(aId);
|
||||
const indexB = children.indexOf(bId);
|
||||
return indexA - indexB;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -357,7 +357,8 @@ export function SortChildren(
|
|||
function SetContainer(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel,
|
||||
key: string, value: string | number | boolean | number[],
|
||||
key: string,
|
||||
value: string | number | boolean | number[],
|
||||
type: PropertyType,
|
||||
symbols: Map<string, ISymbolModel>
|
||||
): void {
|
||||
|
@ -396,7 +397,12 @@ function SetContainer(
|
|||
* @param value Value of the property
|
||||
* @param type Type of the property
|
||||
*/
|
||||
function AssignProperty(container: IContainerModel, key: string, value: string | number | boolean | number[], type: PropertyType): void {
|
||||
function AssignProperty(
|
||||
container: IContainerModel,
|
||||
key: string,
|
||||
value: string | number | boolean | number[],
|
||||
type: PropertyType
|
||||
): void {
|
||||
switch (type) {
|
||||
case PropertyType.Style:
|
||||
(container.properties.style as any)[key] = value;
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import Swal from 'sweetalert2';
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { type Dispatch, type SetStateAction } from 'react';
|
||||
import { AddMethod } from '../../../Enums/AddMethod';
|
||||
import { IAction } from '../../../Interfaces/IAction';
|
||||
import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { ISetContainerListRequest } from '../../../Interfaces/ISetContainerListRequest';
|
||||
import { ISetContainerListResponse } from '../../../Interfaces/ISetContainerListResponse';
|
||||
import { type IAction } from '../../../Interfaces/IAction';
|
||||
import { type IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { type ISetContainerListRequest } from '../../../Interfaces/ISetContainerListRequest';
|
||||
import { type ISetContainerListResponse } from '../../../Interfaces/ISetContainerListResponse';
|
||||
import { DISABLE_API } from '../../../utils/default';
|
||||
import { FindContainerById } from '../../../utils/itertools';
|
||||
import { SetContainerList } from '../../API/api';
|
||||
import { IMenuAction } from '../../Menu/Menu';
|
||||
import { type IMenuAction } from '../../Menu/Menu';
|
||||
import { GetCurrentHistoryState } from '../Editor';
|
||||
import { Text } from '../../Text/Text';
|
||||
import { type IReplaceContainer } from '../../../Interfaces/IReplaceContainer';
|
||||
import { AddContainers } from './AddContainer';
|
||||
import { DeleteContainer } from './ContainerOperations';
|
||||
import { DeleteSymbol } from './SymbolOperations';
|
||||
import { Text } from '../../Text/Text';
|
||||
import { IReplaceContainer } from '../../../Interfaces/IReplaceContainer';
|
||||
|
||||
export function InitActions(
|
||||
menuActions: Map<string, IMenuAction[]>,
|
||||
|
@ -63,7 +63,9 @@ export function InitActions(
|
|||
shortcut: '<kbd>R</kbd>',
|
||||
action: (target: HTMLElement) => {
|
||||
const targetContainer = FindContainerById(history[historyCurrentStep].containers, target.id);
|
||||
const targetAvailableContainer = configuration.AvailableContainers.find((availableContainer) => availableContainer.Type === targetContainer?.properties.type);
|
||||
const targetAvailableContainer = configuration.AvailableContainers.find(
|
||||
(availableContainer) => availableContainer.Type === targetContainer?.properties.type
|
||||
);
|
||||
|
||||
if (targetAvailableContainer === undefined) {
|
||||
return;
|
||||
|
@ -188,7 +190,10 @@ function GetAction(
|
|||
};
|
||||
}
|
||||
|
||||
function GetPreviousAndNextSiblings(containers: Map<string, IContainerModel>, container: IContainerModel): { prev: IContainerModel | undefined, next: IContainerModel | undefined } {
|
||||
function GetPreviousAndNextSiblings(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel
|
||||
): { prev: IContainerModel | undefined, next: IContainerModel | undefined } {
|
||||
let prev;
|
||||
let next;
|
||||
const parent = FindContainerById(containers, container.properties.parentId);
|
||||
|
@ -230,22 +235,21 @@ function HandleSetContainerList(
|
|||
selectedContainer.properties.id,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep);
|
||||
historyCurrentStep
|
||||
);
|
||||
|
||||
setNewHistory(newHistory);
|
||||
break;
|
||||
}
|
||||
case AddMethod.Replace:
|
||||
setNewHistory(
|
||||
HandleReplace(
|
||||
containers,
|
||||
selectedContainer,
|
||||
response,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
)
|
||||
);
|
||||
setNewHistory(HandleReplace(
|
||||
containers,
|
||||
selectedContainer,
|
||||
response,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
break;
|
||||
case AddMethod.ReplaceParent: {
|
||||
const parent = FindContainerById(containers, selectedContainer.properties.parentId);
|
||||
|
@ -257,16 +261,14 @@ function HandleSetContainerList(
|
|||
});
|
||||
return;
|
||||
}
|
||||
setNewHistory(
|
||||
HandleReplace(
|
||||
containers,
|
||||
parent,
|
||||
response,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
)
|
||||
);
|
||||
setNewHistory(HandleReplace(
|
||||
containers,
|
||||
parent,
|
||||
response,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { type IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { type IConfiguration } from '../../../Interfaces/IConfiguration';
|
||||
import { GetCircularReplacer } from '../../../utils/saveload';
|
||||
import { ID } from '../../SVG/SVG';
|
||||
import { IEditorState } from '../../../Interfaces/IEditorState';
|
||||
import { type IEditorState } from '../../../Interfaces/IEditorState';
|
||||
import { SHOW_SELECTOR_TEXT } from '../../../utils/default';
|
||||
|
||||
export function SaveEditorAsJSON(
|
||||
|
@ -11,7 +11,9 @@ export function SaveEditorAsJSON(
|
|||
configuration: IConfiguration
|
||||
): void {
|
||||
const exportName = 'state.json';
|
||||
const spaces = import.meta.env.DEV ? 4 : 0;
|
||||
const spaces = import.meta.env.DEV
|
||||
? 4
|
||||
: 0;
|
||||
const editorState: IEditorState = {
|
||||
history,
|
||||
historyCurrentStep,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { type Dispatch, type SetStateAction } from 'react';
|
||||
import { type IHistoryState } from '../../../Interfaces/IHistoryState';
|
||||
import { ENABLE_SHORTCUTS } from '../../../utils/default';
|
||||
|
||||
export function OnKey(
|
||||
|
|
|
@ -4,7 +4,7 @@ import { type IHistoryState } from '../../../Interfaces/IHistoryState';
|
|||
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { GetDefaultSymbolModel } from '../../../utils/default';
|
||||
import { FindContainerById } from '../../../utils/itertools';
|
||||
import {RestoreX, RestoreY} from '../../../utils/svg';
|
||||
import { RestoreX, RestoreY } from '../../../utils/svg';
|
||||
import { ApplyBehaviors, ApplyBehaviorsOnSiblingsChildren } from '../Behaviors/Behaviors';
|
||||
import { GetCurrentHistory, GetCurrentHistoryState, UpdateCounters } from '../Editor';
|
||||
import { AddContainers } from './AddContainer';
|
||||
|
@ -212,5 +212,7 @@ function LinkContainer(
|
|||
): void {
|
||||
const oldSymbol = symbols.get(container.properties.linkedSymbolId);
|
||||
LinkSymbol(container.properties.id, oldSymbol, symbol);
|
||||
container.properties.linkedSymbolId = symbol !== undefined ? symbol.id : '';
|
||||
container.properties.linkedSymbolId = symbol !== undefined
|
||||
? symbol.id
|
||||
: '';
|
||||
}
|
||||
|
|
|
@ -13,31 +13,34 @@
|
|||
* or make them lose their property as a rigid body
|
||||
*/
|
||||
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { Orientation } from '../../../Enums/Orientation';
|
||||
import { ConstraintBodyInsideUnallocatedWidth } from './RigidBodyBehaviors';
|
||||
import { FindContainerById } from '../../../utils/itertools';
|
||||
import { ConstraintBodyInsideUnallocatedWidth } from './RigidBodyBehaviors';
|
||||
|
||||
/**
|
||||
* Impose the container position to its siblings
|
||||
* Apply the following modification to the overlapping rigid body container :
|
||||
* @param container Container to impose its position
|
||||
*/
|
||||
export function ApplyAnchor(containers: Map<string, IContainerModel>, container: IContainerModel, parent: IContainerModel): IContainerModel {
|
||||
export function ApplyAnchor(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel,
|
||||
parent: IContainerModel
|
||||
): IContainerModel {
|
||||
const rigidBodies: IContainerModel[] = [];
|
||||
parent.children.forEach(
|
||||
childId => {
|
||||
const child = FindContainerById(containers, childId);
|
||||
parent.children.forEach(childId => {
|
||||
const child = FindContainerById(containers, childId);
|
||||
|
||||
if (child === undefined) {
|
||||
return;
|
||||
}
|
||||
if (child === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (child.properties.isAnchor) {
|
||||
return;
|
||||
}
|
||||
rigidBodies.push(child);
|
||||
});
|
||||
if (child.properties.isAnchor) {
|
||||
return;
|
||||
}
|
||||
rigidBodies.push(child);
|
||||
});
|
||||
|
||||
const isHorizontal = parent.properties.orientation === Orientation.Horizontal;
|
||||
const overlappingContainers = isHorizontal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { APPLY_BEHAVIORS_ON_CHILDREN, ENABLE_RIGID, ENABLE_SWAP } from '../../../utils/default';
|
||||
import { FindContainerById, MakeChildrenIterator } from '../../../utils/itertools';
|
||||
import { ApplyAnchor, GetOverlappingContainers } from './AnchorBehaviors';
|
||||
|
@ -14,7 +14,11 @@ import { ApplySymbol } from './SymbolBehaviors';
|
|||
* @param container Container to recalculate its positions
|
||||
* @returns Updated container
|
||||
*/
|
||||
export function ApplyBehaviors(containers: Map<string, IContainerModel>, container: IContainerModel, symbols: Map<string, ISymbolModel>): IContainerModel {
|
||||
export function ApplyBehaviors(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel,
|
||||
symbols: Map<string, ISymbolModel>
|
||||
): IContainerModel {
|
||||
try {
|
||||
const symbol = symbols.get(container.properties.linkedSymbolId);
|
||||
if (container.properties.linkedSymbolId !== '' && symbol !== undefined) {
|
||||
|
@ -67,7 +71,8 @@ export function ApplyBehaviors(containers: Map<string, IContainerModel>, contain
|
|||
export function ApplyBehaviorsOnSiblingsChildren(
|
||||
containers: Map<string, IContainerModel>,
|
||||
newContainer: IContainerModel,
|
||||
symbols: Map<string, ISymbolModel>): void {
|
||||
symbols: Map<string, ISymbolModel>
|
||||
): void {
|
||||
const parent = FindContainerById(containers, newContainer.properties.parentId);
|
||||
if (parent === null || parent === undefined) {
|
||||
return;
|
||||
|
@ -102,7 +107,11 @@ export function ApplyBehaviorsOnSiblingsChildren(
|
|||
* @param symbols
|
||||
* @returns
|
||||
*/
|
||||
export function ApplyBehaviorsOnSiblings(containers: Map<string, IContainerModel>, newContainer: IContainerModel, symbols: Map<string, ISymbolModel>): void {
|
||||
export function ApplyBehaviorsOnSiblings(
|
||||
containers: Map<string, IContainerModel>,
|
||||
newContainer: IContainerModel,
|
||||
symbols: Map<string, ISymbolModel>
|
||||
): void {
|
||||
const parent = FindContainerById(containers, newContainer.properties.parentId);
|
||||
if (parent === null || parent === undefined) {
|
||||
return;
|
||||
|
@ -132,7 +141,11 @@ export function ApplyBehaviorsOnSiblings(containers: Map<string, IContainerModel
|
|||
}
|
||||
});
|
||||
}
|
||||
function UpdateWarning(containers: Map<string, IContainerModel>, container: IContainerModel, parent: IContainerModel): void {
|
||||
function UpdateWarning(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel,
|
||||
parent: IContainerModel
|
||||
): void {
|
||||
const targetContainers: IContainerModel[] = [];
|
||||
|
||||
parent.children.forEach((child) => {
|
||||
|
@ -146,7 +159,8 @@ function UpdateWarning(containers: Map<string, IContainerModel>, container: ICon
|
|||
});
|
||||
const overlappingContainers = GetOverlappingContainers(container, targetContainers);
|
||||
if (overlappingContainers.length > 0) {
|
||||
container.properties.warning = `There are overlapping containers: ${overlappingContainers.map(c => c.properties.id).join(' ')}`;
|
||||
container.properties.warning = 'There are overlapping containers: ' +
|
||||
`${overlappingContainers.map(c => c.properties.id).join(' ')}`;
|
||||
} else {
|
||||
container.properties.warning = '';
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { Orientation } from '../../../Enums/Orientation';
|
||||
import { Simplex } from '../../../utils/simplex';
|
||||
import { ApplyWidthMargin, ApplyXMargin } from '../../../utils/svg';
|
||||
|
@ -14,12 +14,20 @@ interface IFlexibleGroup {
|
|||
* Flex the container and its siblings (mutate)
|
||||
* @returns Flexed container
|
||||
*/
|
||||
export function Flex(containers: Map<string, IContainerModel>, container: IContainerModel, parent: IContainerModel): void {
|
||||
export function Flex(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel,
|
||||
parent: IContainerModel
|
||||
): void {
|
||||
const isVertical = parent.properties.orientation === Orientation.Vertical;
|
||||
|
||||
if (isVertical) {
|
||||
const wantedWidth = Math.min(container.properties.maxWidth, parent.properties.width);
|
||||
container.properties.width = ApplyWidthMargin(wantedWidth, container.properties.margin.left, container.properties.margin.right);
|
||||
container.properties.width = ApplyWidthMargin(
|
||||
wantedWidth,
|
||||
container.properties.margin.left,
|
||||
container.properties.margin.right
|
||||
);
|
||||
const flexibleGroups = GetVerticalFlexibleGroups(containers, parent);
|
||||
for (const flexibleGroup of flexibleGroups) {
|
||||
FlexGroupVertically(flexibleGroup);
|
||||
|
@ -28,7 +36,11 @@ export function Flex(containers: Map<string, IContainerModel>, container: IConta
|
|||
}
|
||||
|
||||
const wantedHeight = Math.min(container.properties.maxHeight, parent.properties.height);
|
||||
container.properties.height = ApplyWidthMargin(wantedHeight, container.properties.margin.top, container.properties.margin.bottom);
|
||||
container.properties.height = ApplyWidthMargin(
|
||||
wantedHeight,
|
||||
container.properties.margin.top,
|
||||
container.properties.margin.bottom
|
||||
);
|
||||
const flexibleGroups = GetHorizontalFlexibleGroups(containers, parent);
|
||||
for (const flexibleGroup of flexibleGroups) {
|
||||
FlexGroupHorizontally(flexibleGroup);
|
||||
|
@ -40,7 +52,10 @@ export function Flex(containers: Map<string, IContainerModel>, container: IConta
|
|||
* @param parent Parent in which the flexible children will be set in groups
|
||||
* @returns a list of groups of flexible containers
|
||||
*/
|
||||
export function GetHorizontalFlexibleGroups(containers: Map<string, IContainerModel>, parent: IContainerModel): IFlexibleGroup[] {
|
||||
export function GetHorizontalFlexibleGroups(
|
||||
containers: Map<string, IContainerModel>,
|
||||
parent: IContainerModel
|
||||
): IFlexibleGroup[] {
|
||||
const flexibleGroups: IFlexibleGroup[] = [];
|
||||
let group: IContainerModel[] = [];
|
||||
let offset = 0;
|
||||
|
@ -158,7 +173,11 @@ function FlexGroupHorizontally(flexibleGroup: IFlexibleGroup): void {
|
|||
continue;
|
||||
}
|
||||
sibling.properties.x = ApplyXMargin(right, sibling.properties.margin.left);
|
||||
sibling.properties.width = ApplyWidthMargin(wantedWidth, sibling.properties.margin.left, sibling.properties.margin.right);
|
||||
sibling.properties.width = ApplyWidthMargin(
|
||||
wantedWidth,
|
||||
sibling.properties.margin.left,
|
||||
sibling.properties.margin.right
|
||||
);
|
||||
right += wantedWidth;
|
||||
}
|
||||
|
||||
|
@ -174,7 +193,11 @@ function FlexGroupHorizontally(flexibleGroup: IFlexibleGroup): void {
|
|||
|
||||
// apply the solutions
|
||||
for (let i = 0; i < flexibleContainers.length; i++) {
|
||||
flexibleContainers[i].properties.width = ApplyWidthMargin(solutions[i], flexibleContainers[i].properties.margin.left, flexibleContainers[i].properties.margin.right);
|
||||
flexibleContainers[i].properties.width = ApplyWidthMargin(
|
||||
solutions[i],
|
||||
flexibleContainers[i].properties.margin.left,
|
||||
flexibleContainers[i].properties.margin.right
|
||||
);
|
||||
}
|
||||
|
||||
// move the containers
|
||||
|
@ -229,7 +252,11 @@ function FlexGroupVertically(flexibleGroup: IFlexibleGroup): void {
|
|||
continue;
|
||||
}
|
||||
sibling.properties.y = ApplyXMargin(right, sibling.properties.margin.top);
|
||||
sibling.properties.height = ApplyWidthMargin(wantedHeight, sibling.properties.margin.top, sibling.properties.margin.bottom);
|
||||
sibling.properties.height = ApplyWidthMargin(
|
||||
wantedHeight,
|
||||
sibling.properties.margin.top,
|
||||
sibling.properties.margin.bottom
|
||||
);
|
||||
right += wantedHeight;
|
||||
}
|
||||
|
||||
|
@ -245,7 +272,11 @@ function FlexGroupVertically(flexibleGroup: IFlexibleGroup): void {
|
|||
|
||||
// apply the solutions
|
||||
for (let i = 0; i < flexibleContainers.length; i++) {
|
||||
flexibleContainers[i].properties.height = ApplyWidthMargin(solutions[i], flexibleContainers[i].properties.margin.top, flexibleContainers[i].properties.margin.bottom);
|
||||
flexibleContainers[i].properties.height = ApplyWidthMargin(
|
||||
solutions[i],
|
||||
flexibleContainers[i].properties.margin.top,
|
||||
flexibleContainers[i].properties.margin.bottom
|
||||
);
|
||||
}
|
||||
|
||||
// move the containers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { Orientation } from '../../../Enums/Orientation';
|
||||
import { MakeChildrenIterator, ReversePairwise } from '../../../utils/itertools';
|
||||
import { Flex } from './FlexBehaviors';
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* If the contraints fails, an error message will be returned
|
||||
*/
|
||||
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { ISizePointer } from '../../../Interfaces/ISizePointer';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type ISizePointer } from '../../../Interfaces/ISizePointer';
|
||||
import { Orientation } from '../../../Enums/Orientation';
|
||||
import { ENABLE_HARD_RIGID } from '../../../utils/default';
|
||||
import { FindContainerById, MakeChildrenIterator } from '../../../utils/itertools';
|
||||
|
@ -141,9 +141,7 @@ export function ConstraintBodyInsideUnallocatedWidth(
|
|||
|
||||
// Check if there is still some space
|
||||
if (availableWidths.length === 0) {
|
||||
throw new Error(
|
||||
'No available space found on the parent container. Try to free the parent a bit.'
|
||||
);
|
||||
throw new Error('No available space found on the parent container. Try to free the parent a bit.');
|
||||
}
|
||||
|
||||
const containerId = container.properties.id;
|
||||
|
@ -158,8 +156,7 @@ export function ConstraintBodyInsideUnallocatedWidth(
|
|||
// Check if the container actually fit inside
|
||||
// It will usually fit if it was alrady fitting
|
||||
const availableWidthFound = availableWidths.find((width) =>
|
||||
IsFitting(containerHeight, width)
|
||||
);
|
||||
IsFitting(containerHeight, width));
|
||||
|
||||
if (availableWidthFound === undefined) {
|
||||
const { x, width } = TrySqueeze(containerY, containerHeight, containerMinHeight, containerId, availableWidths);
|
||||
|
@ -189,8 +186,7 @@ export function ConstraintBodyInsideUnallocatedWidth(
|
|||
// Check if the container actually fit inside
|
||||
// It will usually fit if it was alrady fitting
|
||||
const availableWidthFound = availableWidths.find((width) =>
|
||||
IsFitting(containerWidth, width)
|
||||
);
|
||||
IsFitting(containerWidth, width));
|
||||
|
||||
if (availableWidthFound === undefined) {
|
||||
const { x, width } = TrySqueeze(containerX, containerWidth, containerMinWidth, containerId, availableWidths);
|
||||
|
@ -242,24 +238,26 @@ function TrySqueeze(
|
|||
};
|
||||
}
|
||||
|
||||
function SortAvailableWidthsByClosest(containerX: number, containerWidth: number, availableWidths: ISizePointer[]): void {
|
||||
function SortAvailableWidthsByClosest(
|
||||
containerX: number,
|
||||
containerWidth: number,
|
||||
availableWidths: ISizePointer[]
|
||||
): void {
|
||||
const middle = containerX + containerWidth / 2;
|
||||
// Sort the available width to find the space with the closest position
|
||||
availableWidths.sort(
|
||||
(width1, width2) => {
|
||||
let compared1X = width1.x;
|
||||
if (width1.x < containerX) {
|
||||
compared1X = width1.x + width1.width - containerWidth;
|
||||
}
|
||||
|
||||
let compared2X = width2.x;
|
||||
if (width2.x < containerX) {
|
||||
compared2X = width2.x + width2.width - containerWidth;
|
||||
}
|
||||
|
||||
return Math.abs(compared1X - middle) - Math.abs(compared2X - middle);
|
||||
availableWidths.sort((width1, width2) => {
|
||||
let compared1X = width1.x;
|
||||
if (width1.x < containerX) {
|
||||
compared1X = width1.x + width1.width - containerWidth;
|
||||
}
|
||||
);
|
||||
|
||||
let compared2X = width2.x;
|
||||
if (width2.x < containerX) {
|
||||
compared2X = width2.x + width2.width - containerWidth;
|
||||
}
|
||||
|
||||
return Math.abs(compared1X - middle) - Math.abs(compared2X - middle);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,8 +266,10 @@ function SortAvailableWidthsByClosest(containerX: number, containerWidth: number
|
|||
* @param sizePointer Size space to check
|
||||
* @returns
|
||||
*/
|
||||
function IsFitting(containerWidth: number,
|
||||
sizePointer: ISizePointer): boolean {
|
||||
function IsFitting(
|
||||
containerWidth: number,
|
||||
sizePointer: ISizePointer
|
||||
): boolean {
|
||||
return containerWidth <= sizePointer.width;
|
||||
}
|
||||
|
||||
|
@ -280,7 +280,8 @@ function IsFitting(containerWidth: number,
|
|||
* (except the fact that disk space is divided by block).
|
||||
* @param container Container where to find an available width
|
||||
* @param exception Container to exclude of the widths (since a container will be moved, it might need to be excluded)
|
||||
* @returns {ISizePointer[]} Array of unallocated widths (x=position of the unallocated space, width=size of the allocated space)
|
||||
* @returns {ISizePointer[]} Array of unallocated widths
|
||||
* (x=position of the unallocated space, width=size of the allocated space)
|
||||
*/
|
||||
function GetAvailableWidths(
|
||||
x: number,
|
||||
|
@ -303,8 +304,12 @@ function GetAvailableWidths(
|
|||
if (child === exception) {
|
||||
continue;
|
||||
}
|
||||
const childX = isHorizontal ? child.properties.x : child.properties.y;
|
||||
const childWidth = isHorizontal ? child.properties.width : child.properties.height;
|
||||
const childX = isHorizontal
|
||||
? child.properties.x
|
||||
: child.properties.y;
|
||||
const childWidth = isHorizontal
|
||||
? child.properties.width
|
||||
: child.properties.height;
|
||||
|
||||
// get the space of the child that is inside the parent
|
||||
let newUnallocatedSpace: ISizePointer[] = [];
|
||||
|
|
|
@ -2,15 +2,16 @@
|
|||
* Swap two flex container when one is overlapping another
|
||||
*/
|
||||
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { Orientation } from '../../../Enums/Orientation';
|
||||
import { GetHorizontallyOverlappingContainers, GetVerticallyOverlappingContainers } from './AnchorBehaviors';
|
||||
import { MakeChildrenIterator } from '../../../utils/itertools';
|
||||
import { GetHorizontallyOverlappingContainers, GetVerticallyOverlappingContainers } from './AnchorBehaviors';
|
||||
|
||||
export function ApplySwap(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel,
|
||||
parent: IContainerModel): void {
|
||||
parent: IContainerModel
|
||||
): void {
|
||||
const children = [...MakeChildrenIterator(containers, parent.children)];
|
||||
|
||||
const isVertical = parent.properties.orientation === Orientation.Vertical;
|
||||
|
@ -36,7 +37,10 @@ export function SwapHorizontally(container: IContainerModel, children: IContaine
|
|||
}
|
||||
|
||||
// swap positions
|
||||
[overlappingContainer.properties.x, container.properties.x] = [container.properties.x, overlappingContainer.properties.x];
|
||||
[
|
||||
overlappingContainer.properties.x,
|
||||
container.properties.x
|
||||
] = [container.properties.x, overlappingContainer.properties.x];
|
||||
const indexContainer = children.indexOf(container);
|
||||
const indexOverlapping = children.indexOf(overlappingContainer);
|
||||
[children[indexContainer], children[indexOverlapping]] = [children[indexOverlapping], children[indexContainer]];
|
||||
|
@ -56,7 +60,10 @@ export function SwapVertically(container: IContainerModel, children: IContainerM
|
|||
}
|
||||
|
||||
// swap positions
|
||||
[overlappingContainer.properties.y, container.properties.y] = [container.properties.y, overlappingContainer.properties.y];
|
||||
[
|
||||
overlappingContainer.properties.y,
|
||||
container.properties.y
|
||||
] = [container.properties.y, overlappingContainer.properties.y];
|
||||
const indexContainer = children.indexOf(container);
|
||||
const indexOverlapping = children.indexOf(overlappingContainer);
|
||||
[children[indexContainer], children[indexOverlapping]] = [children[indexOverlapping], children[indexContainer]];
|
||||
|
|
|
@ -3,16 +3,22 @@ import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
|||
import { ApplyParentTransform, FindContainerById } from '../../../utils/itertools';
|
||||
import { RestoreX, RestoreY, TransformX, TransformY } from '../../../utils/svg';
|
||||
|
||||
export function ApplySymbol(containers: Map<string, IContainerModel>,
|
||||
export function ApplySymbol(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel,
|
||||
symbol: ISymbolModel): IContainerModel {
|
||||
symbol: ISymbolModel
|
||||
): IContainerModel {
|
||||
if (symbol.isVertical) {
|
||||
container.properties.y = TransformY(symbol.offset,
|
||||
container.properties.y = TransformY(
|
||||
symbol.offset,
|
||||
symbol.height,
|
||||
symbol.config.PositionReference);
|
||||
container.properties.y = RestoreY(container.properties.y,
|
||||
symbol.config.PositionReference
|
||||
);
|
||||
container.properties.y = RestoreY(
|
||||
container.properties.y,
|
||||
container.properties.height,
|
||||
container.properties.positionReference);
|
||||
container.properties.positionReference
|
||||
);
|
||||
const parent = FindContainerById(containers, container.properties.parentId);
|
||||
let y = 0;
|
||||
if (parent !== undefined && parent !== null) {
|
||||
|
@ -24,10 +30,13 @@ export function ApplySymbol(containers: Map<string, IContainerModel>,
|
|||
container.properties.x = TransformX(
|
||||
symbol.offset,
|
||||
symbol.width,
|
||||
symbol.config.PositionReference);
|
||||
container.properties.x = RestoreX(container.properties.x,
|
||||
symbol.config.PositionReference
|
||||
);
|
||||
container.properties.x = RestoreX(
|
||||
container.properties.x,
|
||||
container.properties.width,
|
||||
container.properties.positionReference);
|
||||
container.properties.positionReference
|
||||
);
|
||||
const parent = FindContainerById(containers, container.properties.parentId);
|
||||
let x = 0;
|
||||
if (parent !== undefined && parent !== null) {
|
||||
|
|
|
@ -3,17 +3,22 @@ import './Editor.scss';
|
|||
import { type IConfiguration } from '../../Interfaces/IConfiguration';
|
||||
import { type IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { UI } from '../UI/UI';
|
||||
import { UseCustomEvents, UseEditorListener } from '../../Events/EditorEvents';
|
||||
import { MAX_HISTORY } from '../../utils/default';
|
||||
import { FindContainerById } from '../../utils/itertools';
|
||||
import { Menu } from '../Menu/Menu';
|
||||
import { type IReplaceContainer } from '../../Interfaces/IReplaceContainer';
|
||||
import { SelectContainer, DeleteContainer, OnPropertyChange, ReplaceByContainer } from './Actions/ContainerOperations';
|
||||
import { SaveEditorAsJSON, SaveEditorAsSVG } from './Actions/Save';
|
||||
import { OnKey } from './Actions/Shortcuts';
|
||||
import { UseCustomEvents, UseEditorListener } from '../../Events/EditorEvents';
|
||||
import { MAX_HISTORY } from '../../utils/default';
|
||||
import { AddSymbol, OnPropertyChange as OnSymbolPropertyChange, DeleteSymbol, SelectSymbol } from './Actions/SymbolOperations';
|
||||
import { FindContainerById } from '../../utils/itertools';
|
||||
import { Menu } from '../Menu/Menu';
|
||||
import {
|
||||
AddSymbol,
|
||||
OnPropertyChange as OnSymbolPropertyChange,
|
||||
DeleteSymbol,
|
||||
SelectSymbol
|
||||
} from './Actions/SymbolOperations';
|
||||
import { InitActions } from './Actions/ContextMenuActions';
|
||||
import { AddContainerToSelectedContainer, AddContainer } from './Actions/AddContainer';
|
||||
import { type IReplaceContainer } from '../../Interfaces/IReplaceContainer';
|
||||
|
||||
interface IEditorProps {
|
||||
root: Element | Document
|
||||
|
@ -61,16 +66,20 @@ function UseNewHistoryState(
|
|||
): (newHistory: IHistoryState[], historyCurrentStep?: number) => void {
|
||||
return (newHistory, historyCurrentStep?: number) => {
|
||||
setHistory(newHistory);
|
||||
setHistoryCurrentStep(historyCurrentStep !== undefined && historyCurrentStep !== null ? historyCurrentStep : newHistory.length - 1);
|
||||
setHistoryCurrentStep(historyCurrentStep !== undefined && historyCurrentStep !== null
|
||||
? historyCurrentStep
|
||||
: newHistory.length - 1);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export function Editor(props: IEditorProps): JSX.Element {
|
||||
// States
|
||||
const [history, setHistory] = React.useState<IHistoryState[]>(structuredClone(props.history));
|
||||
const [historyCurrentStep, setHistoryCurrentStep] = React.useState<number>(props.historyCurrentStep);
|
||||
const [replaceContainer, setReplaceContainer] = React.useState<IReplaceContainer>({ isReplacing: false, id: undefined, category: undefined });
|
||||
const [
|
||||
replaceContainer,
|
||||
setReplaceContainer
|
||||
] = React.useState<IReplaceContainer>({ isReplacing: false, id: undefined, category: undefined });
|
||||
|
||||
const editorRef = useRef<HTMLDivElement>(null);
|
||||
const setNewHistory = UseNewHistoryState(setHistory, setHistoryCurrentStep);
|
||||
|
@ -86,9 +95,7 @@ export function Editor(props: IEditorProps): JSX.Element {
|
|||
setHistoryCurrentStep,
|
||||
() => {
|
||||
const current = GetCurrentHistoryState(history, historyCurrentStep);
|
||||
setNewHistory(
|
||||
DeleteContainer(current.selectedContainerId, history, historyCurrentStep)
|
||||
);
|
||||
setNewHistory(DeleteContainer(current.selectedContainerId, history, historyCurrentStep));
|
||||
},
|
||||
ResetState
|
||||
);
|
||||
|
@ -134,29 +141,28 @@ export function Editor(props: IEditorProps): JSX.Element {
|
|||
}}
|
||||
replaceContainer={replaceContainer}
|
||||
selectContainer={(container) => {
|
||||
setNewHistory(
|
||||
SelectContainer(
|
||||
container,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
setNewHistory(SelectContainer(
|
||||
container,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
}}
|
||||
deleteContainer={(containerId: string) => {
|
||||
setNewHistory(
|
||||
DeleteContainer(
|
||||
containerId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
setNewHistory(DeleteContainer(
|
||||
containerId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
}}
|
||||
onPropertyChange={(key, value, type) => {
|
||||
setNewHistory(
|
||||
OnPropertyChange(
|
||||
key, value, type,
|
||||
selected,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
setNewHistory(OnPropertyChange(
|
||||
key,
|
||||
value,
|
||||
type,
|
||||
selected,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
}}
|
||||
addOrReplaceContainer={(type) => {
|
||||
if (selected === null || selected === undefined) {
|
||||
|
@ -183,49 +189,44 @@ export function Editor(props: IEditorProps): JSX.Element {
|
|||
}
|
||||
}}
|
||||
addContainerAt={(index, type, parent) => {
|
||||
setNewHistory(
|
||||
AddContainer(
|
||||
index,
|
||||
type,
|
||||
parent,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
)
|
||||
);
|
||||
setNewHistory(AddContainer(
|
||||
index,
|
||||
type,
|
||||
parent,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
}}
|
||||
addSymbol={(type) => {
|
||||
setNewHistory(
|
||||
AddSymbol(
|
||||
type,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
setNewHistory(AddSymbol(
|
||||
type,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
}}
|
||||
onSymbolPropertyChange={(key, value) => {
|
||||
setNewHistory(
|
||||
OnSymbolPropertyChange(
|
||||
key, value,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
setNewHistory(OnSymbolPropertyChange(
|
||||
key,
|
||||
value,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
}}
|
||||
selectSymbol={(symbolId) => {
|
||||
setNewHistory(
|
||||
SelectSymbol(
|
||||
symbolId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
setNewHistory(SelectSymbol(
|
||||
symbolId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
}}
|
||||
deleteSymbol={(symbolId) => {
|
||||
setNewHistory(
|
||||
DeleteSymbol(
|
||||
symbolId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
setNewHistory(DeleteSymbol(
|
||||
symbolId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
));
|
||||
}}
|
||||
saveEditorAsJSON={() => {
|
||||
SaveEditorAsJSON(
|
||||
|
|
|
@ -88,7 +88,8 @@ function HandleOnDrop(
|
|||
addContainer(
|
||||
targetContainer.children.length,
|
||||
type,
|
||||
targetContainer.properties.id);
|
||||
targetContainer.properties.id
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -113,7 +114,8 @@ function HandleOnDrop(
|
|||
addContainer(
|
||||
targetContainer.children.length,
|
||||
type,
|
||||
targetContainer.properties.id);
|
||||
targetContainer.properties.id
|
||||
);
|
||||
} else {
|
||||
const index = parent.children.indexOf(targetContainer.properties.id);
|
||||
addContainer(
|
||||
|
@ -219,12 +221,10 @@ function ElementsListRow(
|
|||
? 'border-l-blue-400 group-hover:border-l-blue-300'
|
||||
: 'border-l-slate-400 group-hover:border-l-slate-300';
|
||||
for (let i = 0; i < depth; i++) {
|
||||
verticalBars.push(
|
||||
<span
|
||||
key={`${key}-${i}`}
|
||||
className={`h-full border-l-2 pr-2 ${verticalBarSelectedClass}`}
|
||||
></span>
|
||||
);
|
||||
verticalBars.push(<span
|
||||
key={`${key}-${i}`}
|
||||
className={`h-full border-l-2 pr-2 ${verticalBarSelectedClass}`}
|
||||
></span>);
|
||||
}
|
||||
|
||||
const buttonSelectedClass: string = isSelected
|
||||
|
@ -241,7 +241,9 @@ function ElementsListRow(
|
|||
style={style}
|
||||
title={container.properties.warning}
|
||||
onClick={() => { selectContainer(container.properties.id); }}
|
||||
onDrop={(event) => { HandleOnDrop(event, containers, mainContainer, addContainer); }}
|
||||
onDrop={(event) => {
|
||||
HandleOnDrop(event, containers, mainContainer, addContainer);
|
||||
}}
|
||||
onDragOver={(event) => { HandleDragOver(event, mainContainer); }}
|
||||
onDragLeave={(event) => { HandleDragLeave(event); }}
|
||||
>
|
||||
|
|
|
@ -6,14 +6,18 @@ interface IFloatingButtonProps {
|
|||
className: string
|
||||
}
|
||||
|
||||
function ToggleState(isHidden: boolean,
|
||||
setHidden: React.Dispatch<React.SetStateAction<boolean>>): void {
|
||||
function ToggleState(
|
||||
isHidden: boolean,
|
||||
setHidden: React.Dispatch<React.SetStateAction<boolean>>
|
||||
): void {
|
||||
setHidden(!isHidden);
|
||||
}
|
||||
|
||||
export function FloatingButton(props: IFloatingButtonProps): JSX.Element {
|
||||
const [isHidden, setHidden] = React.useState(true);
|
||||
const buttonListClasses = isHidden ? 'invisible opacity-0' : 'visible opacity-100';
|
||||
const buttonListClasses = isHidden
|
||||
? 'invisible opacity-0'
|
||||
: 'visible opacity-100';
|
||||
const icon = isHidden
|
||||
? <Bars3Icon className="floating-btn" />
|
||||
: <XMarkIcon className="floating-btn" />;
|
||||
|
@ -24,9 +28,10 @@ export function FloatingButton(props: IFloatingButtonProps): JSX.Element {
|
|||
{props.children}
|
||||
</div>
|
||||
<button type="button"
|
||||
className={'transition-all w-14 h-14 p-2 align-middle items-center justify-center rounded-full bg-blue-500 hover:bg-blue-800'}
|
||||
className={'transition-all w-14 h-14 p-2 align-middle' +
|
||||
' items-center justify-center rounded-full bg-blue-500 hover:bg-blue-800'}
|
||||
title='Open menu'
|
||||
onClick={() => ToggleState(isHidden, setHidden)}
|
||||
onClick={() => { ToggleState(isHidden, setHidden); }}
|
||||
>
|
||||
{icon}
|
||||
</button>
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
import * as React from 'react';
|
||||
import { CameraIcon, ArrowUpOnSquareIcon } from '@heroicons/react/24/outline';
|
||||
import { type IUIProps } from '../UI/UI';
|
||||
import { FloatingButton } from './FloatingButton';
|
||||
import { IUIProps } from '../UI/UI';
|
||||
|
||||
export function MenuButton(props: IUIProps): JSX.Element {
|
||||
return <FloatingButton className={'fixed z-10 flex flex-col gap-2 items-center bottom-12 right-12'}>
|
||||
<button type="button"
|
||||
className={'transition-all w-10 h-10 p-2 align-middle items-center justify-center rounded-full bg-blue-500 hover:bg-blue-800'}
|
||||
className={'transition-all w-10 h-10 p-2' +
|
||||
' align-middle items-center justify-center' +
|
||||
' rounded-full bg-blue-500 hover:bg-blue-800'}
|
||||
title='Export as JSON'
|
||||
onClick={props.saveEditorAsJSON}
|
||||
>
|
||||
<ArrowUpOnSquareIcon className="heroicon text-white" />
|
||||
</button>
|
||||
<button type="button"
|
||||
className={'transition-all w-10 h-10 p-2 align-middle items-center justify-center rounded-full bg-blue-500 hover:bg-blue-800'}
|
||||
className={'transition-all w-10 h-10 p-2' +
|
||||
' align-middle items-center justify-center' +
|
||||
' rounded-full bg-blue-500 hover:bg-blue-800'}
|
||||
title='Export as SVG'
|
||||
onClick={props.saveEditorAsSVG}
|
||||
>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import { FixedSizeList as List } from 'react-window';
|
||||
import { IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { type IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { TITLE_BAR_HEIGHT } from '../Sidebar/Sidebar';
|
||||
|
||||
interface IHistoryProps {
|
||||
|
@ -23,7 +23,7 @@ export function History(props: IHistoryProps): JSX.Element {
|
|||
<button type="button"
|
||||
key={reversedIndex}
|
||||
style={style}
|
||||
onClick={() => props.jumpTo(reversedIndex)}
|
||||
onClick={() => { props.jumpTo(reversedIndex); }}
|
||||
title={step.lastAction}
|
||||
className={`w-full elements-sidebar-row border-blue-500 whitespace-pre overflow-hidden
|
||||
text-left text-sm font-medium transition-all ${selectedClass}`}
|
||||
|
|
|
@ -37,7 +37,9 @@ export function TextInputGroup(props: ITextInputGroupProps): JSX.Element {
|
|||
}
|
||||
}
|
||||
|
||||
const warningClass = props.value !== value ? 'focus:border-yellow-300 border-yellow-300 focus:ring-yellow-300 ring-yellow-300' : '';
|
||||
const warningClass = props.value !== value
|
||||
? 'focus:border-yellow-300 border-yellow-300 focus:ring-yellow-300 ring-yellow-300'
|
||||
: '';
|
||||
|
||||
return <>
|
||||
<label
|
||||
|
@ -53,7 +55,7 @@ export function TextInputGroup(props: ITextInputGroupProps): JSX.Element {
|
|||
className={`${className} ${props.inputClassName} ${warningClass}`}
|
||||
type={props.type}
|
||||
value={value}
|
||||
onChange={(event) => setValue(event.target.value)}
|
||||
onChange={(event) => { setValue(event.target.value); }}
|
||||
onKeyUp={OnKeyUp}
|
||||
min={props.min}
|
||||
max={props.max}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import { createContext, useState } from 'react';
|
||||
import { ILanguage } from '../../Interfaces/ILanguage';
|
||||
import { type ILanguage } from '../../Interfaces/ILanguage';
|
||||
import { languageOptions, translations } from '../../Translations/Translations';
|
||||
import { DEFAULT_LANGUAGE } from '../../utils/default';
|
||||
|
||||
|
@ -10,13 +10,17 @@ export const LanguageContext = createContext<ILanguage>({
|
|||
dictionary: translations.en
|
||||
});
|
||||
|
||||
export function LanguageProvider({ children }: { children: React.ReactNode | React.ReactNode[] | undefined }): JSX.Element {
|
||||
export function LanguageProvider(
|
||||
{ children }: { children: React.ReactNode | React.ReactNode[] | undefined }
|
||||
): JSX.Element {
|
||||
const [language, setLanguage] = useState(DEFAULT_LANGUAGE);
|
||||
const provider = {
|
||||
language,
|
||||
dictionary: translations[language],
|
||||
languageChange: (selected: string) => {
|
||||
const newLanguage = languageOptions[selected] !== undefined ? selected : DEFAULT_LANGUAGE;
|
||||
const newLanguage = languageOptions[selected] !== undefined
|
||||
? selected
|
||||
: DEFAULT_LANGUAGE;
|
||||
setLanguage(newLanguage);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -45,7 +45,7 @@ export function MainMenu(props: IMainMenuProps): JSX.Element {
|
|||
</label>
|
||||
</form>
|
||||
<button type="button"
|
||||
onClick={() => setWindowState(WindowState.Main)}
|
||||
onClick={() => { setWindowState(WindowState.Main); }}
|
||||
className='normal-btn block
|
||||
mt-8 '
|
||||
>
|
||||
|
@ -70,7 +70,7 @@ export function MainMenu(props: IMainMenuProps): JSX.Element {
|
|||
<button
|
||||
type="button"
|
||||
className='mainmenu-btn'
|
||||
onClick={() => setWindowState(WindowState.Load)}
|
||||
onClick={() => { setWindowState(WindowState.Load); }}
|
||||
>
|
||||
{Text({ textId: '@LoadConfigFile' })}
|
||||
</button>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import useSize from '@react-hook/size';
|
||||
import * as React from 'react';
|
||||
import { IPoint } from '../../Interfaces/IPoint';
|
||||
import { type IPoint } from '../../Interfaces/IPoint';
|
||||
import { MenuItem } from './MenuItem';
|
||||
|
||||
interface IMenuProps {
|
||||
|
@ -97,15 +97,22 @@ export function Menu(props: IMenuProps): JSX.Element {
|
|||
AddUniversalActions(props, children, count, target);
|
||||
}
|
||||
|
||||
const visible = isOpen && children.length > 0 ? 'visible opacity-1' : 'invisible opacity-0';
|
||||
const visible = isOpen && children.length > 0
|
||||
? 'visible opacity-1'
|
||||
: 'invisible opacity-0';
|
||||
const isOutOfBoundHorizontally = contextMenuPosition.x + menuWidth > window.innerWidth;
|
||||
const isOutOfBoundVertically = contextMenuPosition.y + menuHeight > window.innerHeight;
|
||||
const finalHorizontalPosition = isOutOfBoundHorizontally ? contextMenuPosition.x - menuWidth : contextMenuPosition.x;
|
||||
const finalVerticalPosition = isOutOfBoundVertically ? contextMenuPosition.y - menuWidth : contextMenuPosition.y;
|
||||
const finalHorizontalPosition = isOutOfBoundHorizontally
|
||||
? contextMenuPosition.x - menuWidth
|
||||
: contextMenuPosition.x;
|
||||
const finalVerticalPosition = isOutOfBoundVertically
|
||||
? contextMenuPosition.y - menuWidth
|
||||
: contextMenuPosition.y;
|
||||
return (
|
||||
<div
|
||||
ref={menuRef}
|
||||
className={`fixed context-menu ${MENU_VERTICAL_PADDING_CLASS} ${MENU_WIDTH_CLASS} ${props.className ?? ''} ${visible}`}
|
||||
className={'fixed context-menu' +
|
||||
`${MENU_VERTICAL_PADDING_CLASS} ${MENU_WIDTH_CLASS} ${props.className ?? ''} ${visible}`}
|
||||
style={{
|
||||
left: finalHorizontalPosition,
|
||||
top: finalVerticalPosition
|
||||
|
@ -137,7 +144,7 @@ function AddClassSpecificActions(
|
|||
text={action.text}
|
||||
title={action.title}
|
||||
shortcut={action.shortcut}
|
||||
onClick={() => action.action(target)} />);
|
||||
onClick={() => { action.action(target); }} />);
|
||||
});
|
||||
children.push(<hr key={`contextmenu-hr-${count}`} className='border-slate-400' />);
|
||||
}
|
||||
|
@ -156,7 +163,7 @@ function AddUniversalActions(props: IMenuProps, children: JSX.Element[], count:
|
|||
text={action.text}
|
||||
title={action.title}
|
||||
shortcut={action.shortcut}
|
||||
onClick={() => action.action(target)} />);
|
||||
onClick={() => { action.action(target); }} />);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ export function MenuItem(props: IMenuItemProps): JSX.Element {
|
|||
<button type="button"
|
||||
className={`flex place-content-between ${props.className ?? ''}`}
|
||||
title={props.title}
|
||||
onClick={() => props.onClick()}>
|
||||
onClick={() => { props.onClick(); }}>
|
||||
{props.text}
|
||||
<span dangerouslySetInnerHTML={{ __html: props.shortcut ?? '' }} />
|
||||
</button>
|
||||
|
|
|
@ -2,8 +2,8 @@ import { TrashIcon } from '@heroicons/react/24/outline';
|
|||
import * as React from 'react';
|
||||
import { FixedSizeList as List } from 'react-window';
|
||||
import { MessageType } from '../../Enums/MessageType';
|
||||
import { IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { IMessage } from '../../Interfaces/IMessage';
|
||||
import { type IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { type IMessage } from '../../Interfaces/IMessage';
|
||||
import { TITLE_BAR_HEIGHT } from '../Sidebar/Sidebar';
|
||||
import { Text } from '../Text/Text';
|
||||
|
||||
|
@ -14,7 +14,7 @@ interface IMessagesProps {
|
|||
}
|
||||
|
||||
export function Messages(props: IMessagesProps): JSX.Element {
|
||||
function Row({ index, style }: {index: number, style: React.CSSProperties}): JSX.Element {
|
||||
function Row({ index, style }: { index: number, style: React.CSSProperties }): JSX.Element {
|
||||
const reversedIndex = (props.messages.length - 1) - index;
|
||||
const message = props.messages[reversedIndex];
|
||||
let classType = '';
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import React from 'react';
|
||||
import { Bars3BottomLeftIcon, Bars3CenterLeftIcon, Bars3Icon, Bars3BottomRightIcon, Bars2Icon } from '@heroicons/react/24/outline';
|
||||
import {
|
||||
Bars3BottomLeftIcon,
|
||||
Bars3CenterLeftIcon,
|
||||
Bars3Icon,
|
||||
Bars3BottomRightIcon,
|
||||
Bars2Icon
|
||||
} from '@heroicons/react/24/outline';
|
||||
import { PositionReference } from '../../Enums/PositionReference';
|
||||
import { RadioGroupButtons } from './RadioGroupButtons';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from 'react';
|
||||
import { IInputGroup } from '../../Interfaces/IInputGroup';
|
||||
import { type IInputGroup } from '../../Interfaces/IInputGroup';
|
||||
|
||||
interface IRadioGroupButtonsProps {
|
||||
name: string
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as React from 'react';
|
||||
import { Interweave, Node } from 'interweave';
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { IContainerProperties } from '../../../Interfaces/IContainerProperties';
|
||||
import { Interweave, type Node } from 'interweave';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type IContainerProperties } from '../../../Interfaces/IContainerProperties';
|
||||
import { Camelize } from '../../../utils/stringtools';
|
||||
import { SHOW_TEXT } from '../../../utils/default';
|
||||
import { FindContainerById } from '../../../utils/itertools';
|
||||
|
@ -19,23 +19,22 @@ interface IContainerProps {
|
|||
* @returns Render the container
|
||||
*/
|
||||
export function Container(props: IContainerProps): JSX.Element {
|
||||
const containersElements = props.model.children.map(
|
||||
childId => {
|
||||
const child = FindContainerById(props.containers, childId);
|
||||
const containersElements = props.model.children.map(childId => {
|
||||
const child = FindContainerById(props.containers, childId);
|
||||
|
||||
if (child === undefined) {
|
||||
return <></>;
|
||||
}
|
||||
if (child === undefined) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return <Container
|
||||
key={`container-${child.properties.id}`}
|
||||
containers={props.containers}
|
||||
model={child}
|
||||
depth={props.depth + 1}
|
||||
scale={props.scale}
|
||||
selectContainer={props.selectContainer}
|
||||
/>;
|
||||
});
|
||||
return <Container
|
||||
key={`container-${child.properties.id}`}
|
||||
containers={props.containers}
|
||||
model={child}
|
||||
depth={props.depth + 1}
|
||||
scale={props.scale}
|
||||
selectContainer={props.selectContainer}
|
||||
/>;
|
||||
});
|
||||
|
||||
const width: number = props.model.properties.width;
|
||||
const height: number = props.model.properties.height;
|
||||
|
@ -67,7 +66,7 @@ export function Container(props: IContainerProps): JSX.Element {
|
|||
width={width}
|
||||
height={height}
|
||||
style={style}
|
||||
onClick={() => props.selectContainer(props.model.properties.id)}
|
||||
onClick={() => { props.selectContainer(props.model.properties.id); }}
|
||||
>
|
||||
</rect>);
|
||||
|
||||
|
@ -108,7 +107,7 @@ function CreateReactCustomSVG(customSVG: string, properties: IContainerPropertie
|
|||
function Transform(node: HTMLElement, children: Node[], properties: IContainerProperties): React.ReactNode {
|
||||
const supportedTags = ['line', 'path', 'rect'];
|
||||
if (supportedTags.includes(node.tagName.toLowerCase())) {
|
||||
const attributes: { [att: string]: string | object | null } = {};
|
||||
const attributes: Record<string, string | object | null> = {};
|
||||
node.getAttributeNames().forEach(attName => {
|
||||
const attributeValue = node.getAttribute(attName);
|
||||
if (attributeValue === null) {
|
||||
|
|
|
@ -11,9 +11,9 @@ import {
|
|||
} from '../../../utils/default';
|
||||
import { FindContainerById, MakeRecursionDFSIterator, Pairwise } from '../../../utils/itertools';
|
||||
import { TransformX, TransformY } from '../../../utils/svg';
|
||||
import { Dimension } from './Dimension';
|
||||
import { type IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { Dimension } from './Dimension';
|
||||
|
||||
interface IDimensionLayerProps {
|
||||
containers: Map<string, IContainerModel>
|
||||
|
@ -160,7 +160,8 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps):
|
|||
return dimensions;
|
||||
}
|
||||
|
||||
function AddHorizontalSymbolDimension(symbol: ISymbolModel,
|
||||
function AddHorizontalSymbolDimension(
|
||||
symbol: ISymbolModel,
|
||||
dimensions: React.ReactNode[],
|
||||
scale: number,
|
||||
depth: number
|
||||
|
@ -173,22 +174,21 @@ function AddHorizontalSymbolDimension(symbol: ISymbolModel,
|
|||
const text = width
|
||||
.toFixed(0)
|
||||
.toString();
|
||||
dimensions.push(
|
||||
<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={0}
|
||||
yStart={-offset}
|
||||
xEnd={width}
|
||||
yEnd={-offset}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={DEFAULT_DIMENSION_SYMBOL_STYLE}/>
|
||||
);
|
||||
dimensions.push(<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={0}
|
||||
yStart={-offset}
|
||||
xEnd={width}
|
||||
yEnd={-offset}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={DEFAULT_DIMENSION_SYMBOL_STYLE}/>);
|
||||
}
|
||||
}
|
||||
|
||||
function AddVerticalSymbolDimension(symbol: ISymbolModel,
|
||||
function AddVerticalSymbolDimension(
|
||||
symbol: ISymbolModel,
|
||||
dimensions: React.ReactNode[],
|
||||
scale: number,
|
||||
depth: number
|
||||
|
@ -201,18 +201,16 @@ function AddVerticalSymbolDimension(symbol: ISymbolModel,
|
|||
const text = height
|
||||
.toFixed(0)
|
||||
.toString();
|
||||
dimensions.push(
|
||||
<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={-offset}
|
||||
yStart={height}
|
||||
xEnd={-offset}
|
||||
yEnd={0}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={DEFAULT_DIMENSION_SYMBOL_STYLE}/>
|
||||
);
|
||||
dimensions.push(<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={-offset}
|
||||
yStart={height}
|
||||
xEnd={-offset}
|
||||
yEnd={0}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={DEFAULT_DIMENSION_SYMBOL_STYLE}/>);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,12 +247,16 @@ function AddHorizontalChildrenDimension(
|
|||
return;
|
||||
}
|
||||
|
||||
let xChildrenStart = TransformX(lastChild.properties.x,
|
||||
let xChildrenStart = TransformX(
|
||||
lastChild.properties.x,
|
||||
lastChild.properties.width,
|
||||
lastChild.properties.positionReference);
|
||||
let xChildrenEnd = TransformX(lastChild.properties.x,
|
||||
lastChild.properties.positionReference
|
||||
);
|
||||
let xChildrenEnd = TransformX(
|
||||
lastChild.properties.x,
|
||||
lastChild.properties.width,
|
||||
lastChild.properties.positionReference);
|
||||
lastChild.properties.positionReference
|
||||
);
|
||||
|
||||
// Find the min and max
|
||||
for (let i = container.children.length - 2; i >= 0; i--) {
|
||||
|
@ -316,12 +318,16 @@ function AddVerticalChildrenDimension(
|
|||
return;
|
||||
}
|
||||
|
||||
let yChildrenStart = TransformY(lastChild.properties.y,
|
||||
let yChildrenStart = TransformY(
|
||||
lastChild.properties.y,
|
||||
lastChild.properties.height,
|
||||
lastChild.properties.positionReference);
|
||||
let yChildrenEnd = TransformY(lastChild.properties.y,
|
||||
lastChild.properties.positionReference
|
||||
);
|
||||
let yChildrenEnd = TransformY(
|
||||
lastChild.properties.y,
|
||||
lastChild.properties.height,
|
||||
lastChild.properties.positionReference);
|
||||
lastChild.properties.positionReference
|
||||
);
|
||||
|
||||
// Find the min and max
|
||||
for (let i = container.children.length - 2; i >= 0; i--) {
|
||||
|
@ -398,9 +404,7 @@ function AddHorizontalBorrowerDimension(
|
|||
|
||||
const restoredX = x + childCurrentTransform[0];
|
||||
|
||||
marks.push(
|
||||
restoredX
|
||||
);
|
||||
marks.push(restoredX);
|
||||
}
|
||||
|
||||
const restoredX = container.properties.x + currentTransform[0];
|
||||
|
@ -458,9 +462,7 @@ function AddVerticalBorrowerDimension(
|
|||
|
||||
const restoredy = y + childCurrentTransform[1];
|
||||
|
||||
marks.push(
|
||||
restoredy
|
||||
);
|
||||
marks.push(restoredy);
|
||||
}
|
||||
|
||||
const restoredY = container.properties.y + currentTransform[1];
|
||||
|
@ -515,18 +517,16 @@ function AddVerticalSelfDimension(
|
|||
[yStart, yEnd] = [yEnd, yStart];
|
||||
}
|
||||
|
||||
dimensions.push(
|
||||
<Dimension
|
||||
key={idVert}
|
||||
id={idVert}
|
||||
xStart={xDim}
|
||||
yStart={yStart}
|
||||
xEnd={xDim}
|
||||
yEnd={yEnd}
|
||||
text={textVert}
|
||||
scale={scale}
|
||||
style={style}/>
|
||||
);
|
||||
dimensions.push(<Dimension
|
||||
key={idVert}
|
||||
id={idVert}
|
||||
xStart={xDim}
|
||||
yStart={yStart}
|
||||
xEnd={xDim}
|
||||
yEnd={yEnd}
|
||||
text={textVert}
|
||||
scale={scale}
|
||||
style={style}/>);
|
||||
}
|
||||
|
||||
function AddHorizontalSelfDimension(
|
||||
|
@ -544,18 +544,16 @@ function AddHorizontalSelfDimension(
|
|||
const text = width
|
||||
.toFixed(0)
|
||||
.toString();
|
||||
dimensions.push(
|
||||
<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={xStart}
|
||||
yStart={yDim}
|
||||
xEnd={xEnd}
|
||||
yEnd={yDim}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={style}/>
|
||||
);
|
||||
dimensions.push(<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={xStart}
|
||||
yStart={yDim}
|
||||
xEnd={xEnd}
|
||||
yEnd={yDim}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={style}/>);
|
||||
}
|
||||
|
||||
function AddHorizontalSelfMarginsDimension(
|
||||
|
@ -574,18 +572,16 @@ function AddHorizontalSelfMarginsDimension(
|
|||
const text = left
|
||||
.toFixed(0)
|
||||
.toString();
|
||||
dimensions.push(
|
||||
<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={xStart}
|
||||
yStart={yDim}
|
||||
xEnd={xEnd}
|
||||
yEnd={yDim}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={style}/>
|
||||
);
|
||||
dimensions.push(<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={xStart}
|
||||
yStart={yDim}
|
||||
xEnd={xEnd}
|
||||
yEnd={yDim}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={style}/>);
|
||||
}
|
||||
|
||||
const right = container.properties.margin.right;
|
||||
|
@ -596,18 +592,16 @@ function AddHorizontalSelfMarginsDimension(
|
|||
const text = right
|
||||
.toFixed(0)
|
||||
.toString();
|
||||
dimensions.push(
|
||||
<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={xStart}
|
||||
yStart={yDim}
|
||||
xEnd={xEnd}
|
||||
yEnd={yDim}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={style}/>
|
||||
);
|
||||
dimensions.push(<Dimension
|
||||
key={id}
|
||||
id={id}
|
||||
xStart={xStart}
|
||||
yStart={yDim}
|
||||
xEnd={xEnd}
|
||||
yEnd={yDim}
|
||||
text={text}
|
||||
scale={scale}
|
||||
style={style}/>);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,18 +627,16 @@ function AddVerticalSelfMarginDimension(
|
|||
[yStart, yEnd] = [yEnd, yStart];
|
||||
}
|
||||
|
||||
dimensions.push(
|
||||
<Dimension
|
||||
key={idVert}
|
||||
id={idVert}
|
||||
xStart={xDim}
|
||||
yStart={yStart}
|
||||
xEnd={xDim}
|
||||
yEnd={yEnd}
|
||||
text={textVert}
|
||||
scale={scale}
|
||||
style={style}/>
|
||||
);
|
||||
dimensions.push(<Dimension
|
||||
key={idVert}
|
||||
id={idVert}
|
||||
xStart={xDim}
|
||||
yStart={yStart}
|
||||
xEnd={xDim}
|
||||
yEnd={yEnd}
|
||||
text={textVert}
|
||||
scale={scale}
|
||||
style={style}/>);
|
||||
}
|
||||
const bottom = container.properties.margin.bottom;
|
||||
if (bottom != null && bottom > 0) {
|
||||
|
@ -659,17 +651,15 @@ function AddVerticalSelfMarginDimension(
|
|||
[yStart, yEnd] = [yEnd, yStart];
|
||||
}
|
||||
|
||||
dimensions.push(
|
||||
<Dimension
|
||||
key={idVert}
|
||||
id={idVert}
|
||||
xStart={xDim}
|
||||
yStart={yStart}
|
||||
xEnd={xDim}
|
||||
yEnd={yEnd}
|
||||
text={textVert}
|
||||
scale={scale}
|
||||
style={style}/>
|
||||
);
|
||||
dimensions.push(<Dimension
|
||||
key={idVert}
|
||||
id={idVert}
|
||||
xStart={xDim}
|
||||
yStart={yStart}
|
||||
xEnd={xDim}
|
||||
yEnd={yEnd}
|
||||
text={textVert}
|
||||
scale={scale}
|
||||
style={style}/>);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,11 @@ export function SelectorContainer(props: ISelectorContainerProps): JSX.Element {
|
|||
props.selected.properties.height
|
||||
];
|
||||
|
||||
({ x, y, width, height } = RemoveMargin(x, y, width, height,
|
||||
({ x, y, width, height } = RemoveMargin(
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
props.selected.properties.margin.left,
|
||||
props.selected.properties.margin.bottom,
|
||||
props.selected.properties.margin.top,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import '../Selector.scss';
|
||||
import * as React from 'react';
|
||||
import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../../../utils/default';
|
||||
import { SYMBOL_MARGIN } from '../../../../utils/default';
|
||||
import { type ISymbolModel } from '../../../../Interfaces/ISymbolModel';
|
||||
import { Selector } from '../Selector/Selector';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from 'react';
|
||||
import { ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||
import { Symbol } from './Symbol';
|
||||
|
||||
interface ISymbolLayerProps {
|
||||
|
@ -10,13 +10,11 @@ interface ISymbolLayerProps {
|
|||
export function SymbolLayer(props: ISymbolLayerProps): JSX.Element {
|
||||
const symbols: JSX.Element[] = [];
|
||||
props.symbols.forEach((symbol) => {
|
||||
symbols.push(
|
||||
<Symbol
|
||||
key={`symbol-${symbol.id}`}
|
||||
model={symbol}
|
||||
scale={props.scale}
|
||||
/>
|
||||
);
|
||||
symbols.push(<Symbol
|
||||
key={`symbol-${symbol.id}`}
|
||||
model={symbol}
|
||||
scale={props.scale}
|
||||
/>);
|
||||
});
|
||||
return (
|
||||
<g>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import * as React from 'react';
|
||||
import { ReactSVGPanZoom, type Tool, TOOL_PAN, type Value, ALIGN_CENTER } from 'react-svg-pan-zoom';
|
||||
import { MAX_FRAMERATE } from '../../utils/default';
|
||||
import { type DrawParams } from '../Viewer/Viewer';
|
||||
import { Container } from './Elements/Container';
|
||||
import { SelectorContainer } from './Elements/SelectorContainer/SelectorContainer';
|
||||
import { MAX_FRAMERATE } from '../../utils/default';
|
||||
import { SymbolLayer } from './Elements/SymbolLayer';
|
||||
import { DimensionLayer } from './Elements/DimensionLayer';
|
||||
import { SelectorSymbol } from './Elements/SelectorSymbol/SelectorSymbol';
|
||||
import { type IToolbarProps, Toolbar } from './SVGReactPanZoom/ui-toolbar/toolbar';
|
||||
import { type DrawParams } from '../Viewer/Viewer';
|
||||
|
||||
interface ISVGProps {
|
||||
className?: string
|
||||
|
|
|
@ -47,8 +47,12 @@ export class ToolbarButton extends React.Component<IToolbarButtonProps, IToolbar
|
|||
display: 'block',
|
||||
width: '24px',
|
||||
height: '24px',
|
||||
margin: [POSITION_TOP, POSITION_BOTTOM].includes(this.props.toolbarPosition) ? '2px 1px' : '1px 2px',
|
||||
color: this.props.active || this.state.hover ? this.props.activeColor : '#FFF',
|
||||
margin: [POSITION_TOP, POSITION_BOTTOM].includes(this.props.toolbarPosition)
|
||||
? '2px 1px'
|
||||
: '1px 2px',
|
||||
color: this.props.active || this.state.hover
|
||||
? this.props.activeColor
|
||||
: '#FFF',
|
||||
transition: 'color 200ms ease',
|
||||
background: 'none',
|
||||
padding: '0px',
|
||||
|
|
|
@ -118,18 +118,34 @@ export function Toolbar({
|
|||
const style: React.CSSProperties = {
|
||||
// position
|
||||
position: 'absolute',
|
||||
transform: [POSITION_TOP, POSITION_BOTTOM].includes(position) ? 'translate(-50%, 0px)' : 'none',
|
||||
top: [POSITION_LEFT, POSITION_RIGHT, POSITION_TOP].includes(position) ? '5px' : 'unset',
|
||||
left: [POSITION_TOP, POSITION_BOTTOM].includes(position) ? '50%' : (POSITION_LEFT === position ? '5px' : 'unset'),
|
||||
right: [POSITION_RIGHT].includes(position) ? '5px' : 'unset',
|
||||
bottom: [POSITION_BOTTOM].includes(position) ? '5px' : 'unset',
|
||||
transform: [POSITION_TOP, POSITION_BOTTOM].includes(position)
|
||||
? 'translate(-50%, 0px)'
|
||||
: 'none',
|
||||
top: [POSITION_LEFT, POSITION_RIGHT, POSITION_TOP].includes(position)
|
||||
? '5px'
|
||||
: 'unset',
|
||||
left: [POSITION_TOP, POSITION_BOTTOM].includes(position)
|
||||
? '50%'
|
||||
: (POSITION_LEFT === position
|
||||
? '5px'
|
||||
: 'unset'),
|
||||
right: [POSITION_RIGHT].includes(position)
|
||||
? '5px'
|
||||
: 'unset',
|
||||
bottom: [POSITION_BOTTOM].includes(position)
|
||||
? '5px'
|
||||
: 'unset',
|
||||
|
||||
// inner styling
|
||||
backgroundColor: 'rgba(19, 20, 22, 0.90)',
|
||||
borderRadius: '2px',
|
||||
display: 'flex',
|
||||
flexDirection: isHorizontal ? 'row' : 'column',
|
||||
padding: isHorizontal ? '1px 2px' : '2px 1px'
|
||||
flexDirection: isHorizontal
|
||||
? 'row'
|
||||
: 'column',
|
||||
padding: isHorizontal
|
||||
? '1px 2px'
|
||||
: '2px 1px'
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from 'react';
|
||||
import { IInputGroup } from '../../Interfaces/IInputGroup';
|
||||
import { type IInputGroup } from '../../Interfaces/IInputGroup';
|
||||
|
||||
interface ISelectProps {
|
||||
labelKey?: string
|
||||
|
|
|
@ -9,7 +9,9 @@ interface IToggleSidebarProps {
|
|||
|
||||
export function ToggleSideBar({ title, checked, onClick }: IToggleSidebarProps): JSX.Element {
|
||||
return (
|
||||
<div className={`${(checked ? 'bg-slate-400 hover:bg-slate-500' : 'bg-slate-300 hover:bg-slate-400')}`}>
|
||||
<div className={`${(checked
|
||||
? 'bg-slate-400 hover:bg-slate-500'
|
||||
: 'bg-slate-300 hover:bg-slate-400')}`}>
|
||||
<button
|
||||
className={'w-full py-2'}
|
||||
type='button'
|
||||
|
|
|
@ -13,22 +13,26 @@ interface ISymbolFormProps {
|
|||
onChange: (key: string, value: string | number | boolean) => void
|
||||
}
|
||||
|
||||
function Restore(offset: number,
|
||||
function Restore(
|
||||
offset: number,
|
||||
isVertical: boolean,
|
||||
height: number,
|
||||
width: number,
|
||||
position: PositionReference | undefined): number {
|
||||
position: PositionReference | undefined
|
||||
): number {
|
||||
if (isVertical) {
|
||||
return RestoreY(offset, height, position);
|
||||
} else {
|
||||
return RestoreX(offset, width, position);
|
||||
}
|
||||
}
|
||||
function Transform(offset: number,
|
||||
function Transform(
|
||||
offset: number,
|
||||
isVertical: boolean,
|
||||
height: number,
|
||||
width: number,
|
||||
position: PositionReference | undefined): number {
|
||||
position: PositionReference | undefined
|
||||
): number {
|
||||
if (isVertical) {
|
||||
return TransformY(offset, height, position);
|
||||
} else {
|
||||
|
@ -63,18 +67,24 @@ export function SymbolForm(props: ISymbolFormProps): JSX.Element {
|
|||
labelClassName=''
|
||||
inputClassName=''
|
||||
type='number'
|
||||
value={Transform(props.symbol.offset,
|
||||
value={Transform(
|
||||
props.symbol.offset,
|
||||
props.symbol.isVertical,
|
||||
props.symbol.height,
|
||||
props.symbol.width,
|
||||
props.symbol.config.PositionReference).toString()}
|
||||
props.symbol.config.PositionReference
|
||||
).toString()}
|
||||
onChange={(value) => {
|
||||
props.onChange('offset',
|
||||
Restore(Number(value),
|
||||
props.onChange(
|
||||
'offset',
|
||||
Restore(
|
||||
Number(value),
|
||||
props.symbol.isVertical,
|
||||
props.symbol.height,
|
||||
props.symbol.width,
|
||||
props.symbol.config.PositionReference));
|
||||
props.symbol.config.PositionReference
|
||||
)
|
||||
);
|
||||
}} />
|
||||
<ToggleButton
|
||||
labelText={Text({ textId: '@IsVertical' })}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
import { SymbolForm } from './SymbolForm';
|
||||
|
||||
interface ISymbolPropertiesProps {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from 'react';
|
||||
import { IAvailableSymbol } from '../../Interfaces/IAvailableSymbol';
|
||||
import { type IAvailableSymbol } from '../../Interfaces/IAvailableSymbol';
|
||||
import { TruncateString } from '../../utils/stringtools';
|
||||
|
||||
interface ISymbolsProps {
|
||||
|
@ -20,9 +20,9 @@ export function Symbols(props: ISymbolsProps): JSX.Element {
|
|||
key={componentOption.Name}
|
||||
id={componentOption.Name}
|
||||
title={componentOption.Name}
|
||||
onClick={() => props.buttonOnClick(componentOption.Name)}
|
||||
onClick={() => { props.buttonOnClick(componentOption.Name); }}
|
||||
draggable={true}
|
||||
onDragStart={(event) => HandleDragStart(event)}
|
||||
onDragStart={(event) => { HandleDragStart(event); }}
|
||||
>
|
||||
<div>
|
||||
<img
|
||||
|
@ -41,9 +41,9 @@ export function Symbols(props: ISymbolsProps): JSX.Element {
|
|||
key={componentOption.Name}
|
||||
id={componentOption.Name}
|
||||
title={componentOption.Name}
|
||||
onClick={() => props.buttonOnClick(componentOption.Name)}
|
||||
onClick={() => { props.buttonOnClick(componentOption.Name); }}
|
||||
draggable={true}
|
||||
onDragStart={(event) => HandleDragStart(event)}
|
||||
onDragStart={(event) => { HandleDragStart(event); }}
|
||||
>
|
||||
|
||||
{TruncateString(componentOption.Name, 5)}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as React from 'react';
|
||||
import { type Dispatch } from 'react';
|
||||
import { ElementsSidebar } from '../ElementsSidebar/ElementsSidebar';
|
||||
import { History } from '../History/History';
|
||||
import { Bar, BAR_WIDTH } from '../Bar/Bar';
|
||||
|
@ -12,13 +13,12 @@ import { Viewer } from '../Viewer/Viewer';
|
|||
import { Settings } from '../Settings/Settings';
|
||||
import { type IMessage } from '../../Interfaces/IMessage';
|
||||
import { DISABLE_API } from '../../utils/default';
|
||||
import { UseWorker, UseAsync } from './UseWorker';
|
||||
import { FindContainerById } from '../../utils/itertools';
|
||||
import { type IEditorState } from '../../Interfaces/IEditorState';
|
||||
import { GetCurrentHistoryState } from '../Editor/Editor';
|
||||
import { Text } from '../Text/Text';
|
||||
import { type IReplaceContainer } from '../../Interfaces/IReplaceContainer';
|
||||
import { type Dispatch } from 'react';
|
||||
import { UseWorker, UseAsync } from './UseWorker';
|
||||
|
||||
export interface IUIProps {
|
||||
editorState: IEditorState
|
||||
|
@ -223,7 +223,9 @@ export function UI({ editorState, replaceContainer, setReplaceContainer, ...meth
|
|||
isLeftSidebarOpenClasses.add('left-sidebar-single');
|
||||
}
|
||||
|
||||
const clickRestrictionsClasses = replaceContainer.isReplacing ? 'pointer-events-none opacity-50' : '';
|
||||
const clickRestrictionsClasses = replaceContainer.isReplacing
|
||||
? 'pointer-events-none opacity-50'
|
||||
: '';
|
||||
const isComponentsOpen = selectedSidebar === SidebarType.Components;
|
||||
const isSymbolsOpen = selectedSidebar === SidebarType.Symbols;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import * as React from 'react';
|
||||
import { IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { IGetFeedbackRequest } from '../../Interfaces/IGetFeedbackRequest';
|
||||
import { IGetFeedbackResponse } from '../../Interfaces/IGetFeedbackResponse';
|
||||
import { IMessage } from '../../Interfaces/IMessage';
|
||||
import { type IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { type IGetFeedbackRequest } from '../../Interfaces/IGetFeedbackRequest';
|
||||
import { type IGetFeedbackResponse } from '../../Interfaces/IGetFeedbackResponse';
|
||||
import { type IMessage } from '../../Interfaces/IMessage';
|
||||
import { GetCircularReplacer } from '../../utils/saveload';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
|
@ -11,7 +11,8 @@ const myWorker = window.Worker && new Worker('workers/message_worker.js');
|
|||
export function UseWorker(
|
||||
state: IHistoryState,
|
||||
configurationUrl: string | undefined,
|
||||
setMessages: React.Dispatch<React.SetStateAction<IMessage[]>>): void {
|
||||
setMessages: React.Dispatch<React.SetStateAction<IMessage[]>>
|
||||
): void {
|
||||
React.useEffect(() => {
|
||||
// use webworker for the stringify to avoid freezing
|
||||
myWorker.postMessage({
|
||||
|
@ -32,7 +33,8 @@ export function UseWorker(
|
|||
export function UseAsync(
|
||||
state: IHistoryState,
|
||||
configurationUrl: string | undefined,
|
||||
setMessages: React.Dispatch<React.SetStateAction<IMessage[]>>): void {
|
||||
setMessages: React.Dispatch<React.SetStateAction<IMessage[]>>
|
||||
): void {
|
||||
React.useEffect(() => {
|
||||
const request: IGetFeedbackRequest = {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
|
@ -48,8 +50,7 @@ export function UseAsync(
|
|||
}),
|
||||
body: dataParsed
|
||||
})
|
||||
.then(async(response) => await response.json()
|
||||
)
|
||||
.then(async(response) => await response.json())
|
||||
.then(async(json: IGetFeedbackResponse) => {
|
||||
setMessages(json.messages);
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as React from 'react';
|
||||
import { useState } from 'react';
|
||||
import { type IContainerModel } from '../../Interfaces/IContainerModel';
|
||||
import { type IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { USE_EXPERIMENTAL_CANVAS_API } from '../../utils/default';
|
||||
|
@ -6,7 +7,6 @@ import { FindContainerById } from '../../utils/itertools';
|
|||
import { BAR_WIDTH } from '../Bar/Bar';
|
||||
import { Canvas } from '../Canvas/Canvas';
|
||||
import { SelectorMode, SVG } from '../SVG/SVG';
|
||||
import { useState } from 'react';
|
||||
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||
|
||||
interface IViewerProps {
|
||||
|
@ -30,7 +30,9 @@ export interface DrawParams {
|
|||
}
|
||||
|
||||
function computeWidth(margin: number): number {
|
||||
return window.innerWidth - (window.innerWidth < 768 ? BAR_WIDTH : margin);
|
||||
return window.innerWidth - (window.innerWidth < 768
|
||||
? BAR_WIDTH
|
||||
: margin);
|
||||
}
|
||||
|
||||
export function Viewer({
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { useEffect } from 'react';
|
||||
import { AppState } from '../Enums/AppState';
|
||||
import { IConfiguration } from '../Interfaces/IConfiguration';
|
||||
import { IEditorState } from '../Interfaces/IEditorState';
|
||||
import { IHistoryState } from '../Interfaces/IHistoryState';
|
||||
import { ILanguage } from '../Interfaces/ILanguage';
|
||||
import { type IConfiguration } from '../Interfaces/IConfiguration';
|
||||
import { type IEditorState } from '../Interfaces/IEditorState';
|
||||
import { type IHistoryState } from '../Interfaces/IHistoryState';
|
||||
import { type ILanguage } from '../Interfaces/ILanguage';
|
||||
import { languageOptions, translations } from '../Translations/Translations';
|
||||
import { GetDefaultEditorState as GetDefaultEditorStateAction } from '../utils/default';
|
||||
import { Revive, ReviveHistory as ReviveHistoryAction } from '../utils/saveload';
|
||||
|
@ -49,7 +49,7 @@ export function UseCustomEvents(
|
|||
const funcs = new Map<string, () => void>();
|
||||
for (const event of events) {
|
||||
function Func(eventInitDict?: CustomEventInit): void {
|
||||
return event.func({
|
||||
event.func({
|
||||
root,
|
||||
languageContext,
|
||||
setEditor,
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
import { useEffect } from 'react';
|
||||
import { AddContainer as AddContainerAction, AddContainerToSelectedContainer as AddContainerToSelectedContainerAction } from '../Components/Editor/Actions/AddContainer';
|
||||
import { DeleteContainer as DeleteContainerAction, SelectContainer as SelectContainerAction } from '../Components/Editor/Actions/ContainerOperations';
|
||||
import { AddSymbol as AddSymbolAction, DeleteSymbol as DeleteSymbolAction, SelectSymbol as SelectSymbolAction } from '../Components/Editor/Actions/SymbolOperations';
|
||||
import {
|
||||
AddContainer as AddContainerAction,
|
||||
AddContainerToSelectedContainer as AddContainerToSelectedContainerAction
|
||||
} from '../Components/Editor/Actions/AddContainer';
|
||||
import {
|
||||
DeleteContainer as DeleteContainerAction,
|
||||
SelectContainer as SelectContainerAction
|
||||
} from '../Components/Editor/Actions/ContainerOperations';
|
||||
import {
|
||||
AddSymbol as AddSymbolAction,
|
||||
DeleteSymbol as DeleteSymbolAction,
|
||||
SelectSymbol as SelectSymbolAction
|
||||
} from '../Components/Editor/Actions/SymbolOperations';
|
||||
import { GetCurrentHistory } from '../Components/Editor/Editor';
|
||||
import { IConfiguration } from '../Interfaces/IConfiguration';
|
||||
import { IEditorState } from '../Interfaces/IEditorState';
|
||||
import { IHistoryState } from '../Interfaces/IHistoryState';
|
||||
import { type IConfiguration } from '../Interfaces/IConfiguration';
|
||||
import { type IEditorState } from '../Interfaces/IEditorState';
|
||||
import { type IHistoryState } from '../Interfaces/IHistoryState';
|
||||
import { FindContainerById } from '../utils/itertools';
|
||||
import { GetCircularReplacer } from '../utils/saveload';
|
||||
|
||||
|
@ -61,7 +71,7 @@ export function UseCustomEvents(
|
|||
|
||||
for (const event of events) {
|
||||
function Func(eventInitDict?: CustomEventInit): void {
|
||||
return event.func({
|
||||
event.func({
|
||||
root,
|
||||
editorState,
|
||||
setNewHistory,
|
||||
|
@ -112,7 +122,9 @@ function GetEditorStateAsString({
|
|||
root,
|
||||
editorState
|
||||
}: IEditorEventParams): void {
|
||||
const spaces = import.meta.env.DEV ? 4 : 0;
|
||||
const spaces = import.meta.env.DEV
|
||||
? 4
|
||||
: 0;
|
||||
const data = JSON.stringify(editorState, GetCircularReplacer(), spaces);
|
||||
const customEvent = new CustomEvent<string>('getEditorStateAsString', { detail: data });
|
||||
root.dispatchEvent(customEvent);
|
||||
|
@ -137,7 +149,8 @@ function GetCurrentHistoryState({
|
|||
}: IEditorEventParams): void {
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'getCurrentHistoryState',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -155,7 +168,8 @@ function AppendNewState({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'appendNewState',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -184,7 +198,8 @@ function AddContainer({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'addContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -214,7 +229,8 @@ function AddContainerToSelectedContainer({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'addContainerToSelectedContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -246,7 +262,8 @@ function AppendContainer({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'appendContainerToSelectedContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -277,7 +294,8 @@ function AppendContainerToSelectedContainer({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'appendContainerToSelectedContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -302,7 +320,8 @@ function SelectContainer({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'selectContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -327,7 +346,8 @@ function DeleteContainer({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'deleteContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -353,7 +373,8 @@ function AddSymbol({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'AddSymbol',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -378,7 +399,8 @@ function SelectSymbol({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'SelectSymbol',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -402,6 +424,7 @@ function DeleteSymbol({
|
|||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'DeleteSymbol',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
|
||||
);
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { AddMethod } from '../Enums/AddMethod';
|
||||
import { IImage } from './IImage';
|
||||
import { type AddMethod } from '../Enums/AddMethod';
|
||||
import { type IImage } from './IImage';
|
||||
|
||||
export interface IAction {
|
||||
Id: string
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { type AddMethod } from '../Enums/AddMethod';
|
||||
import { type PositionReference } from '../Enums/PositionReference';
|
||||
import { type Orientation } from '../Enums/Orientation';
|
||||
import { type IAction } from './IAction';
|
||||
import { type IMargin } from './IMargin';
|
||||
import { type Orientation } from '../Enums/Orientation';
|
||||
import { type IKeyValue } from './IKeyValue';
|
||||
import { type IStyle } from './IStyle';
|
||||
import { type IDimensions } from './IDimensions';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { IAPIConfiguration } from './IAPIConfiguration';
|
||||
import { IAvailableContainer } from './IAvailableContainer';
|
||||
import { IAvailableSymbol } from './IAvailableSymbol';
|
||||
import { ICategory } from './ICategory';
|
||||
import { IPattern } from './IPattern';
|
||||
import { type IAPIConfiguration } from './IAPIConfiguration';
|
||||
import { type IAvailableContainer } from './IAvailableContainer';
|
||||
import { type IAvailableSymbol } from './IAvailableSymbol';
|
||||
import { type ICategory } from './ICategory';
|
||||
import { type IPattern } from './IPattern';
|
||||
|
||||
/** Model of configuration for the application to configure it */
|
||||
export interface IConfiguration {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { IContainerProperties } from './IContainerProperties';
|
||||
import { type IContainerProperties } from './IContainerProperties';
|
||||
|
||||
export interface IContainerModel {
|
||||
children: string[]
|
||||
|
@ -18,7 +18,8 @@ export class ContainerModel implements IContainerModel {
|
|||
constructor(
|
||||
properties: IContainerProperties,
|
||||
children: string[] = [],
|
||||
userData = {}) {
|
||||
userData = {}
|
||||
) {
|
||||
this.properties = properties;
|
||||
this.children = children;
|
||||
this.userData = userData;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { PositionReference } from '../Enums/PositionReference';
|
||||
import { IMargin } from './IMargin';
|
||||
import { Orientation } from '../Enums/Orientation';
|
||||
import { IKeyValue } from './IKeyValue';
|
||||
import { IStyle } from './IStyle';
|
||||
import { IDimensions } from './IDimensions';
|
||||
import { type PositionReference } from '../Enums/PositionReference';
|
||||
import { type Orientation } from '../Enums/Orientation';
|
||||
import { type IMargin } from './IMargin';
|
||||
import { type IKeyValue } from './IKeyValue';
|
||||
import { type IStyle } from './IStyle';
|
||||
import { type IDimensions } from './IDimensions';
|
||||
|
||||
/**
|
||||
* Properties of a container
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
import { IDimensionOptions } from './IDimensionOptions';
|
||||
import { Orientation } from '../Enums/Orientation';
|
||||
import { type Orientation } from '../Enums/Orientation';
|
||||
import { type IDimensionOptions } from './IDimensionOptions';
|
||||
|
||||
export interface IDimensions {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IConfiguration } from './IConfiguration';
|
||||
import { IHistoryState } from './IHistoryState';
|
||||
import { type IConfiguration } from './IConfiguration';
|
||||
import { type IHistoryState } from './IHistoryState';
|
||||
|
||||
export interface IEditorState {
|
||||
history: IHistoryState[]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { IHistoryState } from './IHistoryState';
|
||||
import { type IHistoryState } from './IHistoryState';
|
||||
|
||||
export interface IGetFeedbackRequest {
|
||||
/** Current application state */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
|
||||
import { IMessage } from './IMessage';
|
||||
import { type IMessage } from './IMessage';
|
||||
|
||||
export interface IGetFeedbackResponse {
|
||||
messages: IMessage[]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IContainerModel } from './IContainerModel';
|
||||
import { ISymbolModel } from './ISymbolModel';
|
||||
import { type IContainerModel } from './IContainerModel';
|
||||
import { type ISymbolModel } from './ISymbolModel';
|
||||
|
||||
export interface IHistoryState {
|
||||
/** Last editor action */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import type React from 'react';
|
||||
|
||||
export interface IInputGroup {
|
||||
key: string
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MessageType } from '../Enums/MessageType';
|
||||
import { type MessageType } from '../Enums/MessageType';
|
||||
|
||||
export interface IMessage {
|
||||
text: string
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { IAvailableContainer } from './IAvailableContainer';
|
||||
import { type IAvailableContainer } from './IAvailableContainer';
|
||||
|
||||
export interface IPattern {
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { IAction } from './IAction';
|
||||
import { IContainerModel } from './IContainerModel';
|
||||
import { IHistoryState } from './IHistoryState';
|
||||
import { type IAction } from './IAction';
|
||||
import { type IContainerModel } from './IContainerModel';
|
||||
import { type IHistoryState } from './IHistoryState';
|
||||
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
export interface ISetContainerListRequest {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { AddMethod } from '../Enums/AddMethod';
|
||||
import { IAvailableContainer } from './IAvailableContainer';
|
||||
import { type AddMethod } from '../Enums/AddMethod';
|
||||
import { type IAvailableContainer } from './IAvailableContainer';
|
||||
|
||||
export interface ISetContainerListResponse {
|
||||
Containers: IAvailableContainer[]
|
||||
|
|
12
src/main.tsx
12
src/main.tsx
|
@ -5,13 +5,11 @@ import { LanguageProvider } from './Components/LanguageProvider/LanguageProvider
|
|||
import './index.scss';
|
||||
|
||||
function RenderRoot(root: Element | Document): void {
|
||||
ReactDOM.createRoot(root.querySelector('#root') as HTMLDivElement).render(
|
||||
<React.StrictMode>
|
||||
<LanguageProvider>
|
||||
<App root={root}/>
|
||||
</LanguageProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
ReactDOM.createRoot(root.querySelector('#root') as HTMLDivElement).render(<React.StrictMode>
|
||||
<LanguageProvider>
|
||||
<App root={root}/>
|
||||
</LanguageProvider>
|
||||
</React.StrictMode>);
|
||||
}
|
||||
|
||||
// Specific for Modeler apps
|
||||
|
|
|
@ -14,7 +14,9 @@ import { type IDimensionStyle } from '../Components/SVG/Elements/Dimension';
|
|||
/// EDITOR DEFAULTS ///
|
||||
|
||||
/** Enable fast boot and disable main menu (0 = disabled, 1 = loading, 2 = loaded) */
|
||||
export const FAST_BOOT = import.meta.env.PROD ? AppState.Loaded : AppState.MainMenu;
|
||||
export const FAST_BOOT = import.meta.env.PROD
|
||||
? AppState.Loaded
|
||||
: AppState.MainMenu;
|
||||
|
||||
/** Disable any call to the API (default = false) */
|
||||
export const DISABLE_API = false;
|
||||
|
@ -89,7 +91,9 @@ export function GetDefaultEditorState(configuration: IConfiguration): IEditorSta
|
|||
throw new Error('Cannot initialize project! Main container has an undefined size');
|
||||
}
|
||||
|
||||
const containerConfig = configuration.AvailableContainers.find(config => config.Type === configuration.MainContainer.Type);
|
||||
const containerConfig = configuration.AvailableContainers.find(
|
||||
config => config.Type === configuration.MainContainer.Type
|
||||
);
|
||||
|
||||
let mainContainerConfig: IContainerProperties;
|
||||
if (containerConfig !== undefined) {
|
||||
|
@ -128,9 +132,7 @@ export function GetDefaultEditorState(configuration: IConfiguration): IEditorSta
|
|||
configuration.MainContainer
|
||||
);
|
||||
}
|
||||
const mainContainer = new ContainerModel(
|
||||
mainContainerConfig
|
||||
);
|
||||
const mainContainer = new ContainerModel(mainContainerConfig);
|
||||
const containers = new Map<string, IContainerModel>();
|
||||
containers.set(mainContainer.properties.id, mainContainer);
|
||||
|
||||
|
@ -244,14 +246,16 @@ export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = {
|
|||
* @param containerConfig default config of the container sent by the API
|
||||
* @returns {IContainerProperties} Default properties of a newly created container
|
||||
*/
|
||||
export function GetDefaultContainerProps(type: string,
|
||||
export function GetDefaultContainerProps(
|
||||
type: string,
|
||||
typeCount: number,
|
||||
parent: IContainerModel | undefined | null,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
containerConfig: IAvailableContainer): IContainerProperties {
|
||||
containerConfig: IAvailableContainer
|
||||
): IContainerProperties {
|
||||
const orientation = containerConfig.Orientation ?? Orientation.Horizontal;
|
||||
return ({
|
||||
id: `${type}-${typeCount}`,
|
||||
|
@ -299,10 +303,12 @@ export function GetDefaultContainerProps(type: string,
|
|||
});
|
||||
}
|
||||
|
||||
export function GetDefaultSymbolModel(name: string,
|
||||
export function GetDefaultSymbolModel(
|
||||
name: string,
|
||||
newCounters: Record<string, number>,
|
||||
type: string,
|
||||
symbolConfig: IAvailableSymbol): ISymbolModel {
|
||||
symbolConfig: IAvailableSymbol
|
||||
): ISymbolModel {
|
||||
const id = `${name}-${newCounters[type]}`;
|
||||
return {
|
||||
id,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { IContainerModel } from '../Interfaces/IContainerModel';
|
||||
import { type IContainerModel } from '../Interfaces/IContainerModel';
|
||||
|
||||
export function * MakeChildrenIterator(containers: Map<string, IContainerModel>, childrenIds: string[]): Generator<IContainerModel, void, unknown> {
|
||||
export function * MakeChildrenIterator(
|
||||
containers: Map<string, IContainerModel>,
|
||||
childrenIds: string[]
|
||||
): Generator<IContainerModel, void, unknown> {
|
||||
for (const childId of childrenIds) {
|
||||
const child = FindContainerById(containers, childId);
|
||||
|
||||
|
@ -15,7 +18,11 @@ export function * MakeChildrenIterator(containers: Map<string, IContainerModel>,
|
|||
/**
|
||||
* Returns a Generator iterating of over the children depth-first
|
||||
*/
|
||||
export function * MakeDFSIterator(root: IContainerModel, containers: Map<string, IContainerModel>, enableHideChildrenInTreeview = false): Generator<IContainerModel, void, unknown> {
|
||||
export function * MakeDFSIterator(
|
||||
root: IContainerModel,
|
||||
containers: Map<string, IContainerModel>,
|
||||
enableHideChildrenInTreeview = false
|
||||
): Generator<IContainerModel, void, unknown> {
|
||||
const queue: IContainerModel[] = [root];
|
||||
const visited = new Set<IContainerModel>(queue);
|
||||
while (queue.length > 0) {
|
||||
|
@ -51,7 +58,10 @@ export interface ContainerAndDepthAndTransform extends ContainerAndDepth {
|
|||
/**
|
||||
* Returns a Generator iterating of over the children depth-first
|
||||
*/
|
||||
export function * MakeBFSIterator(root: IContainerModel, containers: Map<string, IContainerModel>): Generator<ContainerAndDepth, void, unknown> {
|
||||
export function * MakeBFSIterator(
|
||||
root: IContainerModel,
|
||||
containers: Map<string, IContainerModel>
|
||||
): Generator<ContainerAndDepth, void, unknown> {
|
||||
const queue: IContainerModel[] = [root];
|
||||
let depth = 0;
|
||||
while (queue.length > 0) {
|
||||
|
@ -141,7 +151,10 @@ export function GetDepth(containers: Map<string, IContainerModel>, parent: ICont
|
|||
* Returns the absolute position by iterating to the parent
|
||||
* @returns The absolute position of the container
|
||||
*/
|
||||
export function GetAbsolutePosition(containers: Map<string, IContainerModel>, container: IContainerModel): [number, number] {
|
||||
export function GetAbsolutePosition(
|
||||
containers: Map<string, IContainerModel>,
|
||||
container: IContainerModel
|
||||
): [number, number] {
|
||||
const x = container.properties.x;
|
||||
const y = container.properties.y;
|
||||
const parent = FindContainerById(containers, container.properties.parentId) ?? null;
|
||||
|
@ -230,7 +243,11 @@ export function ApplyParentTransform(
|
|||
* @param id Id of the container to find
|
||||
* @returns The container found or undefined if not found
|
||||
*/
|
||||
export function FindContainerByIdDFS(root: IContainerModel, containers: Map<string, IContainerModel>, id: string): IContainerModel | undefined {
|
||||
export function FindContainerByIdDFS(
|
||||
root: IContainerModel,
|
||||
containers: Map<string, IContainerModel>,
|
||||
id: string
|
||||
): IContainerModel | undefined {
|
||||
const it = MakeDFSIterator(root, containers);
|
||||
for (const container of it) {
|
||||
if (container.properties.id === id) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { IEditorState } from '../Interfaces/IEditorState';
|
||||
import { IHistoryState } from '../Interfaces/IHistoryState';
|
||||
import { IContainerModel } from '../Interfaces/IContainerModel';
|
||||
import { ISymbolModel } from '../Interfaces/ISymbolModel';
|
||||
import { type IEditorState } from '../Interfaces/IEditorState';
|
||||
import { type IHistoryState } from '../Interfaces/IHistoryState';
|
||||
import { type IContainerModel } from '../Interfaces/IContainerModel';
|
||||
import { type ISymbolModel } from '../Interfaces/ISymbolModel';
|
||||
|
||||
/**
|
||||
* Revive the Editor state
|
||||
|
@ -37,7 +37,10 @@ export function ReviveState(state: IHistoryState): void {
|
|||
state.containers = new Map(containers.map(({ Key, Value }) => [Key, Value]));
|
||||
}
|
||||
|
||||
export function GetCircularReplacer(): (key: any, value: object | Map<string, any> | null) => object | null | undefined {
|
||||
export function GetCircularReplacer(): (
|
||||
key: any,
|
||||
value: object | Map<string, any> | null
|
||||
) => object | null | undefined {
|
||||
return (key: any, value: object | null) => {
|
||||
if (key === 'containers') {
|
||||
return [...(value as Map<string, any>).entries()]
|
||||
|
|
|
@ -112,7 +112,8 @@ function GetAllIndexes(arr: number[], val: number): number[] {
|
|||
* - 4) the selected column must have 1 in the pivot and zeroes in the other rows
|
||||
* - 5) in the selected rows other columns (other than the selected column)
|
||||
* must be divided by that pivot: coef / pivot
|
||||
* - 6) for the others cells, apply the pivot: new value = (-coefficient in the old col) * (coefficient in the new row) + old value
|
||||
* - 6) for the others cells, apply the pivot:
|
||||
* new value = (-coefficient in the old col) * (coefficient in the new row) + old value
|
||||
* - 7) if in the new matrix there are still negative values in the last row,
|
||||
* redo the algorithm with the new matrix as the base matrix
|
||||
* - 8) otherwise returns the basic variable such as
|
||||
|
@ -135,7 +136,9 @@ function ApplyMainLoop(oldMatrix: number[][], rowlength: number): number[][] {
|
|||
// to avoid infinite loop try to select the least used selected index
|
||||
const pivotColIndex = GetLeastUsedIndex(indexes, indexesTried);
|
||||
// record the usage of index by incrementing
|
||||
indexesTried[pivotColIndex] = indexesTried[pivotColIndex] !== undefined ? indexesTried[pivotColIndex] + 1 : 1;
|
||||
indexesTried[pivotColIndex] = indexesTried[pivotColIndex] !== undefined
|
||||
? indexesTried[pivotColIndex] + 1
|
||||
: 1;
|
||||
|
||||
// 2) find the smallest non negative non null ratio bi/xij (O(m))
|
||||
const ratios = [];
|
||||
|
@ -210,7 +213,9 @@ function GetSolutions(nCols: number, finalMatrix: number[][]): number[] {
|
|||
const col: number[] = [];
|
||||
for (let j = 0; j < finalMatrix.length; j++) {
|
||||
const row = finalMatrix[j];
|
||||
counts[row[i]] = counts[row[i]] !== undefined ? counts[row[i]] + 1 : 1;
|
||||
counts[row[i]] = counts[row[i]] !== undefined
|
||||
? counts[row[i]] + 1
|
||||
: 1;
|
||||
col.push(row[i]);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,5 +6,7 @@ export function TruncateString(str: string, num: number): string {
|
|||
}
|
||||
|
||||
export function Camelize(str: string): any {
|
||||
return str.split('-').map((word, index) => index > 0 ? word.charAt(0).toUpperCase() + word.slice(1) : word).join('');
|
||||
return str.split('-').map((word, index) => index > 0
|
||||
? word.charAt(0).toUpperCase() + word.slice(1)
|
||||
: word).join('');
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable import/export */
|
||||
import * as React from 'react';
|
||||
import { cleanup, render, RenderResult } from '@testing-library/react';
|
||||
import type * as React from 'react';
|
||||
import { cleanup, render, type RenderResult } from '@testing-library/react';
|
||||
import { afterEach } from 'vitest';
|
||||
|
||||
afterEach(() => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue