Devdoc App.tsx

This commit is contained in:
Siklos 2022-08-03 00:23:02 +02:00
parent 06ab515e71
commit 081d65b62b

View file

@ -39,7 +39,9 @@ class App extends React.Component<IAppProps> {
} }
componentDidMount() { componentDidMount() {
// Fetch the configuration from the API
fetchConfiguration().then((configuration: Configuration) => { fetchConfiguration().then((configuration: Configuration) => {
// Set the main container from the given properties of the API
const MainContainer = new Container( const MainContainer = new Container(
{ {
parent: null, parent: null,
@ -55,6 +57,9 @@ class App extends React.Component<IAppProps> {
children: [] children: []
} }
); );
// Save the configuration and the new MainContainer
// and default the selected container to it
this.setState(prevState => ({ this.setState(prevState => ({
...prevState, ...prevState,
configuration, configuration,
@ -64,25 +69,41 @@ class App extends React.Component<IAppProps> {
}); });
} }
/**
* Toggle the components sidebar
*/
public ToggleSidebar() { public ToggleSidebar() {
this.setState({ this.setState({
isSidebarOpen: !this.state.isSidebarOpen isSidebarOpen: !this.state.isSidebarOpen
} as IAppState); } as IAppState);
} }
public ToggleSVGSidebar() { /**
* Toggle the elements
*/
public ToggleElementsSidebar() {
this.setState({ this.setState({
isSVGSidebarOpen: !this.state.isSVGSidebarOpen isSVGSidebarOpen: !this.state.isSVGSidebarOpen
} as IAppState); } as IAppState);
} }
/**
* Select a container
* @param container Selected container
*/
public SelectContainer(container: Container) { public SelectContainer(container: Container) {
this.setState({ this.setState({
SelectedContainer: container SelectedContainer: container
} as IAppProps); } as IAppProps);
} }
public OnPropertyChange(key: string, value: string | number) { /**
* Handled the property change event in the properties form
* @param key Property name
* @param value New value of the property
* @returns void
*/
public OnPropertyChange(key: string, value: string | number): void {
if (this.state.SelectedContainer === null || if (this.state.SelectedContainer === null ||
this.state.SelectedContainer === undefined) { this.state.SelectedContainer === undefined) {
throw new Error('Property was changed before selecting a Container'); throw new Error('Property was changed before selecting a Container');
@ -122,6 +143,11 @@ class App extends React.Component<IAppProps> {
}); });
} }
/**
* Add a new container to a selected container
* @param type The type of container
* @returns void
*/
public AddContainer(type: string): void { public AddContainer(type: string): void {
if (this.state.SelectedContainer === null || if (this.state.SelectedContainer === null ||
this.state.SelectedContainer === undefined) { this.state.SelectedContainer === undefined) {
@ -133,12 +159,14 @@ class App extends React.Component<IAppProps> {
return; return;
} }
// Get the preset properties from the API
const properties = this.state.configuration.AvailableContainers.find(option => option.Type === type); const properties = this.state.configuration.AvailableContainers.find(option => option.Type === type);
if (properties === undefined) { if (properties === undefined) {
throw new Error(`[AddContainer] Object type not found. Found: ${type}`); throw new Error(`[AddContainer] Object type not found. Found: ${type}`);
} }
// 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({}, this.state.Counters);
if (newCounters[type] === null || if (newCounters[type] === null ||
newCounters[type] === undefined) { newCounters[type] === undefined) {
@ -147,6 +175,7 @@ class App extends React.Component<IAppProps> {
newCounters[type]++; newCounters[type]++;
} }
// Create the container
const parent = this.state.SelectedContainer; const parent = this.state.SelectedContainer;
const count = newCounters[type]; const count = newCounters[type];
const container = new Container({ const container = new Container({
@ -165,16 +194,21 @@ class App extends React.Component<IAppProps> {
} }
}); });
// And push it the the parent children
parent.props.children.push(container); parent.props.children.push(container);
// Update the state
const newMainContainer = new Container(Object.assign({}, this.state.MainContainer.props)); const newMainContainer = new Container(Object.assign({}, this.state.MainContainer.props));
this.setState({ this.setState({
MainContainer: newMainContainer, MainContainer: newMainContainer,
Counters: newCounters Counters: newCounters
}); });
} }
/**
* Render the application
* @returns {JSX.Element} Rendered JSX element
*/
render() { render() {
return ( return (
<div className="App font-sans h-full"> <div className="App font-sans h-full">
@ -189,11 +223,11 @@ class App extends React.Component<IAppProps> {
MainContainer={this.state.MainContainer} MainContainer={this.state.MainContainer}
SelectedContainer={this.state.SelectedContainer} SelectedContainer={this.state.SelectedContainer}
isOpen={this.state.isSVGSidebarOpen} isOpen={this.state.isSVGSidebarOpen}
onClick={() => this.ToggleSVGSidebar()} onClick={() => this.ToggleElementsSidebar()}
onPropertyChange={(key: string, value: string) => this.OnPropertyChange(key, value)} onPropertyChange={(key: string, value: string) => this.OnPropertyChange(key, value)}
selectContainer={(container: Container) => this.SelectContainer(container)} selectContainer={(container: Container) => this.SelectContainer(container)}
/> />
<button className='fixed z-10 top-4 right-12 text-lg bg-slate-200 hover:bg-slate-300 transition-all drop-shadow-md hover:drop-shadow-lg py-2 px-3 rounded-lg' onClick={() => this.ToggleSVGSidebar()}>&#9776; Menu</button> <button className='fixed z-10 top-4 right-12 text-lg bg-slate-200 hover:bg-slate-300 transition-all drop-shadow-md hover:drop-shadow-lg py-2 px-3 rounded-lg' onClick={() => this.ToggleElementsSidebar()}>&#9776; Menu</button>
<SVG> <SVG>
{ this.state.MainContainer } { this.state.MainContainer }
</SVG> </SVG>
@ -202,6 +236,10 @@ class App extends React.Component<IAppProps> {
} }
} }
/**
* Fetch the configuration from the API
* @returns {Configation} The model of the configuration for the application
*/
async function fetchConfiguration(): Promise<Configuration> { async function fetchConfiguration(): Promise<Configuration> {
const url = `${import.meta.env.VITE_API_URL}`; const url = `${import.meta.env.VITE_API_URL}`;