You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.9 KiB
114 lines
3.9 KiB
import React, { useReducer, useState, Reducer } from 'react'; |
|
import { ThemeProvider, CssBaseline, createMuiTheme } from '@material-ui/core'; |
|
import { grey } from '@material-ui/core/colors'; |
|
import AppBar from './appbar/AppBar'; |
|
import QueryWindow, { QueryWindowReducer, QueryWindowState } from './windows/QueryWindow'; |
|
var _ = require('lodash'); |
|
|
|
const darkTheme = createMuiTheme({ |
|
palette: { |
|
type: 'dark', |
|
primary: { |
|
main: grey[100], |
|
} |
|
}, |
|
}); |
|
|
|
export interface MainWindowState { |
|
tabLabels: string[], |
|
tabStates: any[], |
|
tabReducers: Reducer<any, any>[], |
|
activeTab: number, |
|
} |
|
|
|
export enum MainWindowStateActions { |
|
SetActiveTab = "setActiveTab", |
|
DispatchToTab = "dispatchToTab", |
|
CloseTab = "closeTab", |
|
AddTab = "addTab", |
|
} |
|
|
|
export function MainWindowReducer(state: MainWindowState, action: any) { |
|
switch (action.type) { |
|
case MainWindowStateActions.SetActiveTab: |
|
return { ...state, activeTab: action.value } |
|
case MainWindowStateActions.CloseTab: |
|
const newSize = state.tabStates.length - 1; |
|
return { |
|
...state, |
|
tabStates: state.tabStates.filter((i: any, idx: number) => idx != action.idx), |
|
tabLabels: state.tabLabels.filter((i: any, idx: number) => idx != action.idx), |
|
tabReducers: state.tabReducers.filter((i: any, idx: number) => idx != action.idx), |
|
activeTab: state.activeTab >= (newSize-1) ? (newSize-1) : state.activeTab, |
|
} |
|
case MainWindowStateActions.AddTab: |
|
return { |
|
...state, |
|
tabStates: [...state.tabStates, action.tabState], |
|
tabLabels: [...state.tabLabels, action.tabLabel], |
|
tabReducers: [...state.tabReducers, action.tabReducer], |
|
} |
|
case MainWindowStateActions.DispatchToTab: |
|
return { |
|
...state, |
|
tabStates: state.tabStates.map((item: any, i: number) => { |
|
return i === action.idx ? |
|
state.tabReducers[i](item, action.tabAction) : |
|
item; |
|
}) |
|
} |
|
default: |
|
throw new Error("Unimplemented QueryWindow state update.") |
|
} |
|
} |
|
|
|
export default function MainWindow(props: any) { |
|
const [state, dispatch] = useReducer(MainWindowReducer, { |
|
tabLabels: ["Query"], |
|
tabStates: [ |
|
{ |
|
editingQuery: false, |
|
query: null, |
|
resultsForQuery: null, |
|
}, |
|
], |
|
tabReducers: [QueryWindowReducer, QueryWindowReducer], |
|
activeTab: 0 |
|
}) |
|
|
|
const queryWindows = state.tabStates.map((state: QueryWindowState, i: number) => { |
|
return <QueryWindow |
|
state={state} |
|
dispatch={(action: any) => { |
|
dispatch({ |
|
type: MainWindowStateActions.DispatchToTab, |
|
tabAction: action, |
|
idx: i |
|
}); |
|
}} |
|
/> |
|
}); |
|
|
|
return <ThemeProvider theme={darkTheme}> |
|
<CssBaseline /> |
|
<AppBar |
|
tabLabels={state.tabLabels} |
|
selectedTab={state.activeTab} |
|
setSelectedTab={(t: number) => dispatch({ type: MainWindowStateActions.SetActiveTab, value: t })} |
|
onCloseTab={(t: number) => dispatch({ type: MainWindowStateActions.CloseTab, idx: t })} |
|
onAddTab={() => { |
|
dispatch({ |
|
type: MainWindowStateActions.AddTab, |
|
tabState: { |
|
editingQuery: false, |
|
query: null, |
|
resultsForQuery: null, |
|
}, |
|
tabLabel: "Query", |
|
tabReducer: QueryWindowReducer, |
|
}) |
|
}} |
|
/> |
|
{queryWindows[state.activeTab]} |
|
</ThemeProvider> |
|
} |