Merge pull request 'Fix multiple bugs related to saving' (#8) from dev into master
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: https://git.siklos-chaneru.duckdns.org/Siklos/svg-layout-designer-react/pulls/8
This commit is contained in:
commit
288e3010ab
2 changed files with 58 additions and 30 deletions
11
src/App.tsx
11
src/App.tsx
|
@ -9,6 +9,7 @@ import { Configuration } from './Interfaces/Configuration';
|
||||||
export interface IHistoryState {
|
export interface IHistoryState {
|
||||||
MainContainer: IContainerModel | null,
|
MainContainer: IContainerModel | null,
|
||||||
SelectedContainer: IContainerModel | null,
|
SelectedContainer: IContainerModel | null,
|
||||||
|
SelectedContainerId: string,
|
||||||
TypeCounters: Record<string, number>
|
TypeCounters: Record<string, number>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,12 +158,11 @@ export async function fetchConfiguration(): Promise<Configuration> {
|
||||||
function Revive(editorState: IEditorState): void {
|
function Revive(editorState: IEditorState): void {
|
||||||
const history = editorState.history;
|
const history = editorState.history;
|
||||||
for (const state of history) {
|
for (const state of history) {
|
||||||
if (state.MainContainer === null) {
|
if (state.MainContainer === null || state.MainContainer === undefined) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const it = MakeIterator(state.MainContainer);
|
const it = MakeIterator(state.MainContainer);
|
||||||
state.SelectedContainer = state.MainContainer;
|
|
||||||
for (const container of it) {
|
for (const container of it) {
|
||||||
const parentId = container.properties.parentId;
|
const parentId = container.properties.parentId;
|
||||||
if (parentId === null) {
|
if (parentId === null) {
|
||||||
|
@ -175,5 +175,12 @@ function Revive(editorState: IEditorState): void {
|
||||||
}
|
}
|
||||||
container.parent = parent;
|
container.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selected = findContainerById(state.MainContainer, state.SelectedContainerId);
|
||||||
|
if (selected === undefined) {
|
||||||
|
state.SelectedContainer = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
state.SelectedContainer = selected;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ import { ElementsSidebar } from './Components/ElementsSidebar/ElementsSidebar';
|
||||||
import { Configuration } from './Interfaces/Configuration';
|
import { Configuration } from './Interfaces/Configuration';
|
||||||
import { SVG } from './Components/SVG/SVG';
|
import { SVG } from './Components/SVG/SVG';
|
||||||
import { History } from './Components/History/History';
|
import { History } from './Components/History/History';
|
||||||
import { ContainerModel, IContainerModel, MakeIterator } from './Components/SVG/Elements/ContainerModel';
|
import { ContainerModel, findContainerById, IContainerModel, MakeIterator } from './Components/SVG/Elements/ContainerModel';
|
||||||
import Properties from './Interfaces/Properties';
|
import Properties from './Interfaces/Properties';
|
||||||
import { IHistoryState } from './App';
|
import { IHistoryState } from './App';
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ interface IEditorProps {
|
||||||
|
|
||||||
export interface IEditorState {
|
export interface IEditorState {
|
||||||
isSidebarOpen: boolean,
|
isSidebarOpen: boolean,
|
||||||
isSVGSidebarOpen: boolean,
|
isElementsSidebarOpen: boolean,
|
||||||
isHistoryOpen: boolean,
|
isHistoryOpen: boolean,
|
||||||
history: Array<IHistoryState>,
|
history: Array<IHistoryState>,
|
||||||
historyCurrentStep: number,
|
historyCurrentStep: number,
|
||||||
|
@ -34,7 +34,7 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isSidebarOpen: true,
|
isSidebarOpen: true,
|
||||||
isSVGSidebarOpen: false,
|
isElementsSidebarOpen: false,
|
||||||
isHistoryOpen: false,
|
isHistoryOpen: false,
|
||||||
configuration: Object.assign({}, props.configuration),
|
configuration: Object.assign({}, props.configuration),
|
||||||
history: [...props.history],
|
history: [...props.history],
|
||||||
|
@ -59,7 +59,7 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
*/
|
*/
|
||||||
public ToggleElementsSidebar() {
|
public ToggleElementsSidebar() {
|
||||||
this.setState({
|
this.setState({
|
||||||
isSVGSidebarOpen: !this.state.isSVGSidebarOpen
|
isElementsSidebarOpen: !this.state.isElementsSidebarOpen
|
||||||
} as IEditorState);
|
} as IEditorState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,11 +79,24 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
public SelectContainer(container: ContainerModel) {
|
public SelectContainer(container: ContainerModel) {
|
||||||
const history = this.getCurrentHistory();
|
const history = this.getCurrentHistory();
|
||||||
const current = history[history.length - 1];
|
const current = history[history.length - 1];
|
||||||
|
|
||||||
|
if (current.MainContainer === null) {
|
||||||
|
throw new Error('[SelectContainer] Tried to select a container while there is no main container!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const mainContainerClone = structuredClone(current.MainContainer);
|
||||||
|
const SelectedContainer = findContainerById(mainContainerClone, container.properties.id);
|
||||||
|
|
||||||
|
if (SelectedContainer === undefined) {
|
||||||
|
throw new Error('[SelectContainer] Cannot find container among children of main container!');
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
history: history.concat([{
|
history: history.concat([{
|
||||||
MainContainer: current.MainContainer,
|
MainContainer: mainContainerClone,
|
||||||
TypeCounters: current.TypeCounters,
|
TypeCounters: Object.assign({}, current.TypeCounters),
|
||||||
SelectedContainer: container
|
SelectedContainer,
|
||||||
|
SelectedContainerId: SelectedContainer.properties.id
|
||||||
}]),
|
}]),
|
||||||
historyCurrentStep: history.length
|
historyCurrentStep: history.length
|
||||||
} as IEditorState);
|
} as IEditorState);
|
||||||
|
@ -110,30 +123,25 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent === null) {
|
if (parent === null) {
|
||||||
const clone: IContainerModel = structuredClone(current.SelectedContainer);
|
const selectedContainerClone: IContainerModel = structuredClone(current.SelectedContainer);
|
||||||
(clone.properties as any)[key] = value;
|
(selectedContainerClone.properties as any)[key] = value;
|
||||||
this.setState({
|
this.setState({
|
||||||
history: history.concat([{
|
history: history.concat([{
|
||||||
SelectedContainer: clone,
|
SelectedContainer: selectedContainerClone,
|
||||||
MainContainer: clone,
|
SelectedContainerId: selectedContainerClone.properties.id,
|
||||||
TypeCounters: current.TypeCounters
|
MainContainer: selectedContainerClone,
|
||||||
|
TypeCounters: Object.assign({}, current.TypeCounters)
|
||||||
}]),
|
}]),
|
||||||
historyCurrentStep: history.length
|
historyCurrentStep: history.length
|
||||||
} as IEditorState);
|
} as IEditorState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const clone: IContainerModel = structuredClone(current.MainContainer);
|
const mainContainerClone: IContainerModel = structuredClone(current.MainContainer);
|
||||||
const it = MakeIterator(clone);
|
const it = MakeIterator(mainContainerClone);
|
||||||
let container: ContainerModel | null = null;
|
const container: ContainerModel | undefined = findContainerById(current.MainContainer, current.SelectedContainer.properties.id);
|
||||||
for (const child of it) {
|
|
||||||
if (child.properties.id === current.SelectedContainer.properties.id) {
|
|
||||||
container = child as ContainerModel;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container === null) {
|
if (container === null || container === undefined) {
|
||||||
throw new Error('[OnPropertyChange] Container model was not found among children of the main container!');
|
throw new Error('[OnPropertyChange] Container model was not found among children of the main container!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,8 +151,9 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
{
|
{
|
||||||
history: history.concat([{
|
history: history.concat([{
|
||||||
SelectedContainer: container,
|
SelectedContainer: container,
|
||||||
MainContainer: clone,
|
SelectedContainerId: container.properties.id,
|
||||||
TypeCounters: current.TypeCounters
|
MainContainer: mainContainerClone,
|
||||||
|
TypeCounters: Object.assign({}, current.TypeCounters)
|
||||||
}]),
|
}]),
|
||||||
historyCurrentStep: history.length
|
historyCurrentStep: history.length
|
||||||
} as IEditorState);
|
} as IEditorState);
|
||||||
|
@ -230,7 +239,8 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
history: history.concat([{
|
history: history.concat([{
|
||||||
MainContainer: clone,
|
MainContainer: clone,
|
||||||
TypeCounters: newCounters,
|
TypeCounters: newCounters,
|
||||||
SelectedContainer: parent
|
SelectedContainer: parent,
|
||||||
|
SelectedContainerId: parent.properties.id
|
||||||
}]),
|
}]),
|
||||||
historyCurrentStep: history.length
|
historyCurrentStep: history.length
|
||||||
} as IEditorState);
|
} as IEditorState);
|
||||||
|
@ -259,6 +269,13 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const current = this.getCurrentHistoryState();
|
const current = this.getCurrentHistoryState();
|
||||||
|
let buttonRightOffsetClasses = 'right-12';
|
||||||
|
if (this.state.isElementsSidebarOpen || this.state.isHistoryOpen) {
|
||||||
|
buttonRightOffsetClasses = 'right-72';
|
||||||
|
}
|
||||||
|
if (this.state.isHistoryOpen && this.state.isElementsSidebarOpen) {
|
||||||
|
buttonRightOffsetClasses = 'right-[544px]';
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="App font-sans h-full">
|
<div className="App font-sans h-full">
|
||||||
<Sidebar
|
<Sidebar
|
||||||
|
@ -277,7 +294,7 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
<ElementsSidebar
|
<ElementsSidebar
|
||||||
MainContainer={current.MainContainer}
|
MainContainer={current.MainContainer}
|
||||||
SelectedContainer={current.SelectedContainer}
|
SelectedContainer={current.SelectedContainer}
|
||||||
isOpen={this.state.isSVGSidebarOpen}
|
isOpen={this.state.isElementsSidebarOpen}
|
||||||
isHistoryOpen={this.state.isHistoryOpen}
|
isHistoryOpen={this.state.isHistoryOpen}
|
||||||
onClick={() => this.ToggleElementsSidebar()}
|
onClick={() => this.ToggleElementsSidebar()}
|
||||||
onPropertyChange={(key: string, value: string) => this.OnPropertyChange(key, value)}
|
onPropertyChange={(key: string, value: string) => this.OnPropertyChange(key, value)}
|
||||||
|
@ -307,7 +324,7 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
{ current.MainContainer }
|
{ current.MainContainer }
|
||||||
</SVG>
|
</SVG>
|
||||||
<button
|
<button
|
||||||
className='fixed transition-all right-12 bottom-10 w-14 h-14 p-2 align-middle items-center justify-center rounded-full bg-blue-500 hover:bg-blue-800'
|
className={`fixed transition-all ${buttonRightOffsetClasses} bottom-10 w-14 h-14 p-2 align-middle items-center justify-center rounded-full bg-blue-500 hover:bg-blue-800`}
|
||||||
title='Export as JSON'
|
title='Export as JSON'
|
||||||
onClick={() => this.SaveEditor()}
|
onClick={() => this.SaveEditor()}
|
||||||
>
|
>
|
||||||
|
@ -321,6 +338,10 @@ class Editor extends React.Component<IEditorProps> {
|
||||||
const getCircularReplacer = () => {
|
const getCircularReplacer = () => {
|
||||||
const seen = new WeakSet();
|
const seen = new WeakSet();
|
||||||
return (key: any, value: object | null) => {
|
return (key: any, value: object | null) => {
|
||||||
|
if (key === 'parent') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof value === 'object' && value !== null) {
|
if (typeof value === 'object' && value !== null) {
|
||||||
if (seen.has(value)) {
|
if (seen.has(value)) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue