--- /dev/null
+// 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
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);
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}>
--- /dev/null
+// 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()));
+
+
+
--- /dev/null
+// 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
+ });
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' &&
processPanel: processPanelReducer,
progressIndicator: progressIndicatorReducer,
fileTreePicker: fileTreePickerReducer,
- runProcessPanel: runProcessPanelReducer
+ runProcessPanel: runProcessPanelReducer,
+ appInfo: appInfoReducer
});
--- /dev/null
+// 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
//
// 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