import * as React from 'react'; import { ElementsList } from '../ElementsList/ElementsList'; import { History } from '../History/History'; import { IAvailableContainer } from '../../Interfaces/IAvailableContainer'; import { IContainerModel } from '../../Interfaces/IContainerModel'; import { IHistoryState } from '../../Interfaces/IHistoryState'; import { Bar } from '../Bar/Bar'; import { IAvailableSymbol } from '../../Interfaces/IAvailableSymbol'; import { Symbols } from '../Symbols/Symbols'; import { SymbolsSidebar } from '../SymbolsList/SymbolsList'; import { PropertyType } from '../../Enums/PropertyType'; import { Messages } from '../Messages/Messages'; import { ICategory } from '../../Interfaces/ICategory'; import { Sidebar } from '../Sidebar/Sidebar'; import { Components } from '../Components/Components'; import { Viewer } from '../Viewer/Viewer'; import { Settings } from '../Settings/Settings'; import { IMessage } from '../../Interfaces/IMessage'; import { DISABLE_API } from '../../utils/default'; import { UseWorker, UseAsync } from './UseWorker'; import { FindContainerById } from '../../utils/itertools'; export interface IUIProps { selectedContainer: IContainerModel | undefined current: IHistoryState history: IHistoryState[] historyCurrentStep: number availableContainers: IAvailableContainer[] availableSymbols: IAvailableSymbol[] categories: ICategory[] selectContainer: (containerId: string) => void deleteContainer: (containerId: string) => void onPropertyChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void addContainer: (type: string) => void addContainerAt: (index: number, type: string, parent: string) => void addSymbol: (type: string) => void onSymbolPropertyChange: (key: string, value: string | number | boolean) => void selectSymbol: (symbolId: string) => void deleteSymbol: (symbolId: string) => void saveEditorAsJSON: () => void saveEditorAsSVG: () => void loadState: (move: number) => void } export enum SidebarType { None, Components, Symbols, History, Messages, Settings } function UseSetOrToggleSidebar( selectedSidebar: SidebarType, setSelectedSidebar: React.Dispatch> ): (newSidebarType: SidebarType) => void { return (newSidebarType) => { if (newSidebarType === selectedSidebar) { setSelectedSidebar(SidebarType.None); return; } setSelectedSidebar(newSidebarType); }; } export function UI(props: IUIProps): JSX.Element { const [selectedSidebar, setSelectedSidebar] = React.useState(SidebarType.Components); const [messages, setMessages] = React.useState([]); // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (window.Worker && !DISABLE_API) { UseWorker( props.current, setMessages ); } else if (!DISABLE_API) { UseAsync( props.current, setMessages ); } // Please use setOrToggleSidebar rather than setSelectedSidebar so we can close the sidebar const setOrToggleSidebar = UseSetOrToggleSidebar(selectedSidebar, setSelectedSidebar); let leftSidebarTitle = ''; let rightSidebarTitle = ''; let leftChildren: JSX.Element = (<>); let rightChildren: JSX.Element = (<>); const mainContainer = FindContainerById(props.current.containers, props.current.mainContainer) if (mainContainer === undefined) { throw new Error('Tried to initialized UI but there is no main container!'); } switch (selectedSidebar) { case SidebarType.Components: leftSidebarTitle = 'Components'; leftChildren = ; rightSidebarTitle = 'Elements'; rightChildren = ; break; case SidebarType.Symbols: leftSidebarTitle = 'Symbols'; leftChildren = ; rightSidebarTitle = 'Symbols'; rightChildren = ; break; case SidebarType.History: leftSidebarTitle = 'Timeline'; leftChildren = ; break; case SidebarType.Messages: leftSidebarTitle = 'Messages'; leftChildren = setMessages([])} />; break; case SidebarType.Settings: leftSidebarTitle = 'Settings'; leftChildren = ; break; } const isLeftSidebarOpen = selectedSidebar !== SidebarType.None; const isRightSidebarOpen = selectedSidebar === SidebarType.Components || selectedSidebar === SidebarType.Symbols; let isLeftSidebarOpenClasses = new Set([ 'left-sidebar', 'left-16', '-bottom-full', 'md:-left-64', 'md:bottom-0' ]); let isRightSidebarOpenClasses = 'right-0 -bottom-full md:-right-80 md:bottom-0'; if (isLeftSidebarOpen) { isLeftSidebarOpenClasses.delete('-bottom-full'); isLeftSidebarOpenClasses.delete('md:-left-64'); isLeftSidebarOpenClasses.delete('md:bottom-0'); } if (isRightSidebarOpen) { isRightSidebarOpenClasses = 'right-0'; } else { isLeftSidebarOpenClasses.delete('left-sidebar'); isLeftSidebarOpenClasses.add('left-sidebar-single'); } return ( <> { setOrToggleSidebar(SidebarType.Components); } } toggleSymbols={() => { setOrToggleSidebar(SidebarType.Symbols); } } toggleTimeline={() => { setOrToggleSidebar(SidebarType.History); } } toggleMessages={() => { setOrToggleSidebar(SidebarType.Messages); } } toggleSettings={() => { setOrToggleSidebar(SidebarType.Settings); } } /> { leftChildren } { rightChildren } ); }