From fab40f5cf7bf0dc80457f7372fd572f8ced23736 Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 4 Aug 2022 10:23:48 +0200 Subject: [PATCH] Implement history --- src/App.tsx | 135 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 42 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index f7f74a9..875dfa0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,13 +10,18 @@ import { SVG } from './Components/SVG/SVG'; interface IAppProps { } +export interface IHistoryState { + MainContainer: Container | null, + SelectedContainer: Container | null, + TypeCounters: Record +} + interface IAppState { isSidebarOpen: boolean, isSVGSidebarOpen: boolean, configuration: Configuration, - MainContainer: Container | null, - SelectedContainer: Container | null - Counters: Record + history: Array, + historyCurrentStep: 0 } class App extends React.Component { @@ -32,12 +37,20 @@ class App extends React.Component { AvailableSymbols: [], MainContainer: {} as AvailableContainer }, - MainContainer: null, - SelectedContainer: null, - Counters: {} - }; + history: [ + { + MainContainer: null, + SelectedContainer: null, + TypeCounters: {} + } + ], + historyCurrentStep: 0 + } as IAppState; } + public getCurrentHistory = (): IHistoryState[] => this.state.history.slice(0, this.state.historyCurrentStep + 1); + public getCurrentHistoryState = (): IHistoryState => this.state.history[this.state.historyCurrentStep]; + componentDidMount() { // Fetch the configuration from the API fetchConfiguration().then((configuration: Configuration) => { @@ -58,14 +71,25 @@ class App extends React.Component { } ); + const history = this.getCurrentHistory(); + const current = history[history.length - 1]; + // Save the configuration and the new MainContainer // and default the selected container to it this.setState(prevState => ({ ...prevState, configuration, - MainContainer, - SelectedContainer: MainContainer - })); + history: history.concat( + [ + { + MainContainer, + SelectedContainer: MainContainer, + TypeCounters: current.TypeCounters + } + ] + ), + historyCurrentStep: history.length + } as IAppState)); }); } @@ -92,9 +116,16 @@ class App extends React.Component { * @param container Selected container */ public SelectContainer(container: Container) { + const history = this.getCurrentHistory(); + const current = history[history.length - 1]; this.setState({ - SelectedContainer: container - } as IAppProps); + history: history.concat([{ + MainContainer: current.MainContainer, + TypeCounters: current.TypeCounters, + SelectedContainer: container + }]), + historyCurrentStep: history.length + } as IAppState); } /** @@ -104,43 +135,55 @@ class App extends React.Component { * @returns void */ public OnPropertyChange(key: string, value: string | number): void { - if (this.state.SelectedContainer === null || - this.state.SelectedContainer === undefined) { + const history = this.getCurrentHistory(); + const current = history[history.length - 1]; + + if (current.SelectedContainer === null || + current.SelectedContainer === undefined) { throw new Error('Property was changed before selecting a Container'); } - if (this.state.MainContainer === null || - this.state.MainContainer === undefined) { + if (current.MainContainer === null || + current.MainContainer === undefined) { throw new Error('Property was changed before the main container was added'); } const pair = {} as Record; pair[key] = value; - const properties = Object.assign(this.state.SelectedContainer.props.properties, pair); + const properties = Object.assign(current.SelectedContainer.props.properties, pair); const props = { - ...this.state.SelectedContainer.props, + ...current.SelectedContainer.props, properties }; const newSelectedContainer = new Container(props); - const parent = this.state.SelectedContainer.props.parent; + const parent = current.SelectedContainer.props.parent; if (parent === null) { this.setState({ - SelectedContainer: newSelectedContainer, - MainContainer: newSelectedContainer - }); + history: history.concat([{ + SelectedContainer: newSelectedContainer, + MainContainer: newSelectedContainer, + TypeCounters: current.TypeCounters + }]), + historyCurrentStep: history.length + } as IAppState); return; } - const index = parent.props.children.indexOf(this.state.SelectedContainer); + const index = parent.props.children.indexOf(current.SelectedContainer); parent.props.children[index] = newSelectedContainer; - const newMainContainer = new Container(Object.assign({}, this.state.MainContainer.props)); - this.setState({ - SelectedContainer: newSelectedContainer, - MainContainer: newMainContainer - }); + const newMainContainer = new Container(Object.assign({}, current.MainContainer.props)); + this.setState( + { + history: history.concat([{ + SelectedContainer: newSelectedContainer, + MainContainer: newMainContainer, + TypeCounters: current.TypeCounters + }]), + historyCurrentStep: history.length + } as IAppState); } /** @@ -149,13 +192,16 @@ class App extends React.Component { * @returns void */ public AddContainer(type: string): void { - if (this.state.SelectedContainer === null || - this.state.SelectedContainer === undefined) { + const history = this.getCurrentHistory(); + const current = history[history.length - 1]; + + if (current.SelectedContainer === null || + current.SelectedContainer === undefined) { return; } - if (this.state.MainContainer === null || - this.state.MainContainer === undefined) { + if (current.MainContainer === null || + current.MainContainer === undefined) { return; } @@ -167,7 +213,7 @@ class App extends React.Component { } // Set the counter of the object type in order to assign an unique id - const newCounters = Object.assign({}, this.state.Counters); + const newCounters = Object.assign({}, current.TypeCounters); if (newCounters[type] === null || newCounters[type] === undefined) { newCounters[type] = 0; @@ -176,7 +222,7 @@ class App extends React.Component { } // Create the container - const parent = this.state.SelectedContainer; + const parent = current.SelectedContainer; const count = newCounters[type]; const container = new Container({ parent, @@ -198,11 +244,15 @@ class App extends React.Component { parent.props.children.push(container); // Update the state - const newMainContainer = new Container(Object.assign({}, this.state.MainContainer.props)); + const newMainContainer = new Container(Object.assign({}, current.MainContainer.props)); this.setState({ - MainContainer: newMainContainer, - Counters: newCounters - }); + history: history.concat([{ + MainContainer: newMainContainer, + TypeCounters: newCounters, + SelectedContainer: current.SelectedContainer + }]), + historyCurrentStep: history.length + } as IAppState); } /** @@ -210,6 +260,7 @@ class App extends React.Component { * @returns {JSX.Element} Rendered JSX element */ render() { + const current = this.getCurrentHistoryState(); return (
{ /> this.ToggleElementsSidebar()} onPropertyChange={(key: string, value: string) => this.OnPropertyChange(key, value)} selectContainer={(container: Container) => this.SelectContainer(container)} /> - - { this.state.MainContainer } + + { current.MainContainer }
);