add appInfo to store, improve main panel and clean code
authorJanicki Artur <artur.janicki@contractors.roche.com>
Mon, 8 Oct 2018 08:46:02 +0000 (10:46 +0200)
committerJanicki Artur <artur.janicki@contractors.roche.com>
Mon, 8 Oct 2018 08:46:02 +0000 (10:46 +0200)
Feature #14307

Arvados-DCO-1.1-Signed-off-by: Janicki Artur <artur.janicki@contractors.roche.com>

src/common/app-info.ts [new file with mode: 0644]
src/index.tsx
src/store/app-info/app-info-actions.ts [new file with mode: 0644]
src/store/app-info/app-info-reducer.ts [new file with mode: 0644]
src/store/store.ts
src/views/main-panel/main-panel-root.tsx [new file with mode: 0644]
src/views/main-panel/main-panel.tsx

diff --git a/src/common/app-info.ts b/src/common/app-info.ts
new file mode 100644 (file)
index 0000000..cd27483
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+export const getBuildInfo = (): string => {
+    const getBuildNumber = "BN-" + (process.env.REACT_APP_BUILD_NUMBER || "dev");
+    const getGitCommit = "GIT-" + (process.env.REACT_APP_GIT_COMMIT || "latest").substr(0, 7);
+    return getBuildNumber + " / " + getGitCommit;
+};
\ No newline at end of file
index a4a5e366a26b1c93713e580c4ce717a1c4e4a117..b3f351e025710729faefdeb4431a9218edbfffea 100644 (file)
@@ -42,14 +42,10 @@ import { setUuidPrefix } from '~/store/workflow-panel/workflow-panel-actions';
 import { trashedCollectionActionSet } from '~/views-components/context-menu/action-sets/trashed-collection-action-set';
 import { ContainerRequestState } from '~/models/container-request';
 import { MountKind } from './models/mount-types';
+import { setBuildInfo } from '~/store/app-info/app-info-actions';
+import { getBuildInfo } from '~/common/app-info';
 
-const getBuildNumber = () => "BN-" + (process.env.REACT_APP_BUILD_NUMBER || "dev");
-const getGitCommit = () => "GIT-" + (process.env.REACT_APP_GIT_COMMIT || "latest").substr(0, 7);
-const getBuildInfo = () => getBuildNumber() + " / " + getGitCommit();
-
-const buildInfo = getBuildInfo();
-
-console.log(`Starting arvados [${buildInfo}]`);
+console.log(`Starting arvados [${getBuildInfo()}]`);
 
 addMenuActionSet(ContextMenuKind.ROOT_PROJECT, rootProjectActionSet);
 addMenuActionSet(ContextMenuKind.PROJECT, projectActionSet);
@@ -80,11 +76,12 @@ fetchConfig()
 
         store.subscribe(initListener(history, store, services, config));
         store.dispatch(initAuth());
+        store.dispatch(setBuildInfo());
         store.dispatch(setCurrentTokenDialogApiHost(apiHost));
         store.dispatch(setUuidPrefix(config.uuidPrefix));
 
         const TokenComponent = (props: any) => <ApiToken authService={services.authService} {...props} />;
-        const MainPanelComponent = (props: any) => <MainPanel buildInfo={buildInfo} {...props} />;
+        const MainPanelComponent = (props: any) => <MainPanel {...props} />;
 
         const App = () =>
             <MuiThemeProvider theme={CustomTheme}>
diff --git a/src/store/app-info/app-info-actions.ts b/src/store/app-info/app-info-actions.ts
new file mode 100644 (file)
index 0000000..cd32e03
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { unionize, ofType, UnionOf } from '~/common/unionize';
+import { Dispatch } from 'redux';
+import { RootState } from '~/store/store';
+import { ServiceRepository } from '~/services/services';
+import { getBuildInfo } from '~/common/app-info';
+
+export const appInfoActions = unionize({
+    SET_BUILD_INFO: ofType<string>()
+});
+
+export type AppInfoAction = UnionOf<typeof appInfoActions>;
+
+export const setBuildInfo = () => 
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) =>
+        dispatch(appInfoActions.SET_BUILD_INFO(getBuildInfo()));
+
+
+
diff --git a/src/store/app-info/app-info-reducer.ts b/src/store/app-info/app-info-reducer.ts
new file mode 100644 (file)
index 0000000..e52aa7c
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { appInfoActions, AppInfoAction } from "~/store/app-info/app-info-actions";
+
+export interface AppInfoState {
+    buildInfo: string;
+}
+
+const initialState = {
+    buildInfo: ''
+};
+
+export const appInfoReducer = (state: AppInfoState = initialState, action: AppInfoAction) =>
+    appInfoActions.match(action, {
+        SET_BUILD_INFO: buildInfo => ({ ...state, buildInfo }),
+        default: () => state
+    });
index 4c08a39c4b4a394ba1a8cde77249ab90c49bf7f1..ad1c8477693f3c2a052d1686f8caa8b4045fe1ed 100644 (file)
@@ -39,6 +39,7 @@ import { runProcessPanelReducer } from '~/store/run-process-panel/run-process-pa
 import { WorkflowMiddlewareService } from './workflow-panel/workflow-middleware-service';
 import { WORKFLOW_PANEL_ID } from './workflow-panel/workflow-panel-actions';
 import { fileTreePickerReducer } from './file-tree-picker/file-tree-picker-reducer';
+import { appInfoReducer } from '~/store/app-info/app-info-reducer';
 
 const composeEnhancers =
     (process.env.NODE_ENV === 'development' &&
@@ -101,5 +102,6 @@ const createRootReducer = (services: ServiceRepository) => combineReducers({
     processPanel: processPanelReducer,
     progressIndicator: progressIndicatorReducer,
     fileTreePicker: fileTreePickerReducer,
-    runProcessPanel: runProcessPanelReducer
+    runProcessPanel: runProcessPanelReducer,
+    appInfo: appInfoReducer
 });
diff --git a/src/views/main-panel/main-panel-root.tsx b/src/views/main-panel/main-panel-root.tsx
new file mode 100644 (file)
index 0000000..15149dc
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { StyleRulesCallback, WithStyles, withStyles, Grid, LinearProgress } from '@material-ui/core';
+import { User } from "~/models/user";
+import { ArvadosTheme } from '~/common/custom-theme';
+import { WorkbenchPanel } from '~/views/workbench/workbench';
+import { LoginPanel } from '~/views/login-panel/login-panel';
+import { WorkbenchLoadingScreen } from '~/views/workbench/workbench-loading-screen';
+import { MainAppBar } from '~/views-components/main-app-bar/main-app-bar';
+
+type CssRules = 'root';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+    root: {
+        overflow: 'hidden',
+        width: '100vw',
+        height: '100vh'
+    }
+});
+
+export interface MainPanelRootDataProps {
+    user?: User;
+    working: boolean;
+    loading: boolean;
+    buildInfo: string;
+}
+
+type MainPanelRootProps = MainPanelRootDataProps & WithStyles<CssRules>;
+
+export const MainPanelRoot = withStyles(styles)(
+    ({ classes, loading, working, user, buildInfo }: MainPanelRootProps) =>
+        loading 
+            ? <WorkbenchLoadingScreen />
+            : <>
+                <MainAppBar
+                    user={user}
+                    buildInfo={buildInfo}>
+                    {working ? <LinearProgress color="secondary" /> : null}
+                </MainAppBar>
+                <Grid container direction="column" className={classes.root}>
+                    {user ? <WorkbenchPanel /> : <LoginPanel />}
+                </Grid>
+            </>
+);
\ No newline at end of file
index 297a6214505a53628c3d6ec20d4f79cb455c27fa..7592afb388ec031e06a75faaf66abb58352c43f1 100644 (file)
@@ -2,83 +2,21 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import * as React from 'react';
-import { connect, DispatchProp } from 'react-redux';
-import { push } from 'react-router-redux';
-import { LinearProgress, Grid } from '@material-ui/core';
-import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
-import { ArvadosTheme } from '~/common/custom-theme';
 import { RootState } from '~/store/store';
-import { User } from '~/models/user';
-import { WorkbenchPanel } from '~/views/workbench/workbench';
-import { LoginPanel } from '~/views/login-panel/login-panel';
-import { MainAppBar } from '~/views-components/main-app-bar/main-app-bar';
+import { connect } from 'react-redux';
+import { MainPanelRoot, MainPanelRootDataProps } from '~/views/main-panel/main-panel-root';
 import { isSystemWorking } from '~/store/progress-indicator/progress-indicator-reducer';
-import { isWorkbenchLoading } from '../../store/workbench/workbench-actions';
-import { WorkbenchLoadingScreen } from '~/views/workbench/workbench-loading-screen';
+import { isWorkbenchLoading } from '~/store/workbench/workbench-actions';
 
-type CssRules = 'root';
+const mapStateToProps = (state: RootState): MainPanelRootDataProps => {
+    return {
+        user: state.auth.user,
+        working: isSystemWorking(state.progressIndicator),
+        loading: isWorkbenchLoading(state),
+        buildInfo: state.appInfo.buildInfo
+    };
+};
 
-const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
-    root: {
-        overflow: 'hidden',
-        width: '100vw',
-        height: '100vh'
-    }
-});
+const mapDispatchToProps = null;
 
-interface MainPanelDataProps {
-    user?: User;
-    working: boolean;
-    loading: boolean;
-}
-
-interface MainPanelGeneralProps {
-    buildInfo: string;
-}
-
-interface MainPanelState {
-    searchText: string;
-}
-
-type MainPanelProps = MainPanelDataProps & MainPanelGeneralProps & DispatchProp<any> & WithStyles<CssRules>;
-
-export const MainPanel = withStyles(styles)(
-    connect<MainPanelDataProps>(
-        (state: RootState) => ({
-            user: state.auth.user,
-            working: isSystemWorking(state.progressIndicator),
-            loading: isWorkbenchLoading(state)
-        })
-    )(
-        class extends React.Component<MainPanelProps, MainPanelState> {
-            state = {
-                searchText: "",
-            };
-
-            render() {
-                const { classes, user, buildInfo, working, loading } = this.props;
-                const { searchText } = this.state;
-                return loading
-                    ? <WorkbenchLoadingScreen />
-                    : <>
-                        <MainAppBar
-                            searchText={searchText}
-                            user={user}
-                            onSearch={this.onSearch}
-                            buildInfo={buildInfo}>
-                            {working ? <LinearProgress color="secondary" /> : null}
-                        </MainAppBar>
-                        <Grid container direction="column" className={classes.root}>
-                            {user ? <WorkbenchPanel /> : <LoginPanel />}
-                        </Grid>
-                    </>;
-            }
-
-            onSearch = (searchText: string) => {
-                this.setState({ searchText });
-                this.props.dispatch(push(`/search?q=${searchText}`));
-            }
-        }
-    )
-);
\ No newline at end of file
+export const MainPanel = connect(mapStateToProps, mapDispatchToProps)(MainPanelRoot);
\ No newline at end of file