22172: Merge branch 'main' into 22127-wb2-optimization
[arvados.git] / services / workbench2 / src / views / main-panel / main-panel-root.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React, { useEffect } from 'react';
6 import { CustomStyleRulesCallback } from 'common/custom-theme';
7 import { Grid, LinearProgress } from '@mui/material';
8 import { WithStyles } from '@mui/styles';
9 import withStyles from '@mui/styles/withStyles';
10 import { User } from "models/user";
11 import { ArvadosTheme } from 'common/custom-theme';
12 import { WorkbenchPanel } from 'views/workbench/workbench';
13 import { LoginPanel } from 'views/login-panel/login-panel';
14 import { InactivePanel } from 'views/inactive-panel/inactive-panel';
15 import { WorkbenchLoadingScreen } from 'views/workbench/workbench-loading-screen';
16 import { MainAppBar } from 'views-components/main-app-bar/main-app-bar';
17 import { Routes, matchLinkAccountRoute } from 'routes/routes';
18 import { RouterState } from "react-router-redux";
19 import parse from 'parse-duration';
20 import { Config } from 'common/config';
21 import { LinkAccountPanelState, LinkAccountPanelStatus } from 'store/link-account-panel/link-account-panel-reducer';
22 import { WORKBENCH_LOADING_SCREEN } from 'store/progress-indicator/progress-indicator-actions';
23
24 type CssRules = 'root';
25
26 const styles: CustomStyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
27     root: {
28         overflow: 'hidden',
29         width: '100vw',
30         height: '100vh'
31     }
32 });
33
34 export interface MainPanelRootDataProps {
35     user?: User;
36     progressIndicator: string[];
37     buildInfo: string;
38     uuidPrefix: string;
39     linkAccountPanel: LinkAccountPanelState;
40     config: Config;
41     sidePanelIsCollapsed: boolean;
42     isTransitioning: boolean;
43     isDetailsPanelOpen: boolean;
44     currentSideWidth: number;
45     router: RouterState;
46 }
47
48 interface MainPanelRootDispatchProps {
49     toggleSidePanel: () => void,
50     setCurrentRouteUuid: (uuid: string | null) => void;
51 }
52
53 type MainPanelRootProps = MainPanelRootDataProps & MainPanelRootDispatchProps & WithStyles<CssRules>;
54
55 export const MainPanelRoot = withStyles(styles)(
56     ({ classes, progressIndicator, user, buildInfo, uuidPrefix, config, linkAccountPanel,
57         sidePanelIsCollapsed, isTransitioning, isDetailsPanelOpen, currentSideWidth, setCurrentRouteUuid, router}: MainPanelRootProps) =>{
58
59             const working = progressIndicator.length > 0;
60             const loading = progressIndicator.includes(WORKBENCH_LOADING_SCREEN);
61             const isLinkingPath = router.location ? matchLinkAccountRoute(router.location.pathname) !== null : false;
62             const currentRoute = router.location ? router.location.pathname : '';
63             const isNotLinking = linkAccountPanel.status === LinkAccountPanelStatus.NONE || linkAccountPanel.status === LinkAccountPanelStatus.INITIAL;
64             const siteBanner = config.clusterConfig.Workbench.SiteName;
65             const sessionIdleTimeout = parse(config.clusterConfig.Workbench.IdleTimeout, 's') || 0;
66
67             useEffect(() => {
68                 const splitRoute = currentRoute.split('/');
69                 const uuid = splitRoute[splitRoute.length - 1];
70                 if(Object.values(Routes).includes(`/${uuid}`) === false) {
71                     setCurrentRouteUuid(uuid);
72                 } else {
73                     setCurrentRouteUuid(null);
74                 }
75                 // eslint-disable-next-line react-hooks/exhaustive-deps
76             }, [currentRoute]);
77
78         return loading
79             ? <WorkbenchLoadingScreen />
80             : <>
81             {isNotLinking && <MainAppBar
82                 user={user}
83                 buildInfo={buildInfo}
84                 uuidPrefix={uuidPrefix}
85                 siteBanner={siteBanner}
86                 >
87                 {working
88                     ? <LinearProgress color="secondary" data-cy="linear-progress" />
89                     : null}
90             </MainAppBar>}
91             <Grid container direction="column" className={classes.root}>
92                 {user
93                     ? (user.isActive || (!user.isActive && isLinkingPath)
94                     ? <WorkbenchPanel
95                         isNotLinking={isNotLinking}
96                         isUserActive={user.isActive}
97                         sessionIdleTimeout={sessionIdleTimeout}
98                         sidePanelIsCollapsed={sidePanelIsCollapsed}
99                         isTransitioning={isTransitioning}
100                         isDetailsPanelOpen={isDetailsPanelOpen}
101                         currentSideWidth={currentSideWidth}/>
102                     : <InactivePanel />)
103                     : <LoginPanel />}
104             </Grid>
105         </>
106     }
107 );