progress-indicator-store-and-HOC
authorPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Thu, 13 Sep 2018 10:00:48 +0000 (12:00 +0200)
committerPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Thu, 13 Sep 2018 10:00:48 +0000 (12:00 +0200)
Feature #14186

Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>

src/store/progress-indicator/progress-indicator-actions.ts [new file with mode: 0644]
src/store/progress-indicator/progress-indicator-reducer.ts [new file with mode: 0644]
src/store/progress-indicator/with-progress.ts [new file with mode: 0644]
src/store/store.ts
src/views-components/progress/content-progress.tsx [new file with mode: 0644]
src/views-components/progress/detail-panel-progress.tsx [new file with mode: 0644]
src/views-components/progress/workbench-progress.tsx [new file with mode: 0644]
src/views/workbench/workbench.tsx

diff --git a/src/store/progress-indicator/progress-indicator-actions.ts b/src/store/progress-indicator/progress-indicator-actions.ts
new file mode 100644 (file)
index 0000000..5f824e4
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { unionize, ofType, UnionOf } from "~/common/unionize";
+
+export const progressIndicatorActions = unionize({
+    START_SUBMIT: ofType<{ id: string }>(),
+    STOP_SUBMIT: ofType<{ id: string }>()
+});
+
+export type ProgressIndicatorAction = UnionOf<typeof progressIndicatorActions>;
\ No newline at end of file
diff --git a/src/store/progress-indicator/progress-indicator-reducer.ts b/src/store/progress-indicator/progress-indicator-reducer.ts
new file mode 100644 (file)
index 0000000..7e1c236
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ProgressIndicatorAction, progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
+
+export interface ProgressIndicatorState {
+    'workbenchProgress': { started: boolean };
+    'contentProgress': { started: boolean };
+    'detailsProgress': { started: boolean };
+}
+
+const initialState: ProgressIndicatorState = {
+    'workbenchProgress': { started: false },
+    'contentProgress': { started: false },
+    'detailsProgress': { started: false }
+};
+
+export enum ProgressIndicatorData {
+    WORKBENCH_PROGRESS = 'workbenchProgress',
+    CONTENT_PROGRESS = 'contentProgress',
+    DETAILS_PROGRESS = 'detailsProgress'
+}
+
+export const progressIndicatorReducer = (state: ProgressIndicatorState = initialState, action: ProgressIndicatorAction) => {
+    return progressIndicatorActions.match(action, {
+        START_SUBMIT: ({ id }) => ({ ...state, [id]: { started: true } }),
+        STOP_SUBMIT: ({ id }) => ({
+            ...state,
+            [id]: state[id] ? { ...state[id], started: false } : { started: false }
+        }),
+        default: () => state,
+    });
+};
diff --git a/src/store/progress-indicator/with-progress.ts b/src/store/progress-indicator/with-progress.ts
new file mode 100644 (file)
index 0000000..b91c05d
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { connect } from 'react-redux';
+import { RootState } from '~/store/store';
+
+export type WithProgressStateProps = {
+    started: boolean;
+};
+
+export const withProgress = (id: string) =>
+    (component: React.ComponentType<WithProgressStateProps>) =>
+        connect(mapStateToProps(id))(component);
+
+export const mapStateToProps = (id: string) => (state: RootState): WithProgressStateProps => {
+    const progress = state.progressIndicator[id];
+    return progress;
+};
\ No newline at end of file
index 9b4f42b84fc81d8d64b2177c0187a6ee94fb60c9..205a21e16c8caf97897fc9e665e426b5f6e5f927 100644 (file)
@@ -32,6 +32,7 @@ import { TrashPanelMiddlewareService } from "~/store/trash-panel/trash-panel-mid
 import { TRASH_PANEL_ID } from "~/store/trash-panel/trash-panel-action";
 import { processLogsPanelReducer } from './process-logs-panel/process-logs-panel-reducer';
 import { processPanelReducer } from '~/store/process-panel/process-panel-reducer';
+import { progressIndicatorReducer } from './progress-indicator/progress-indicator-reducer';
 
 const composeEnhancers =
     (process.env.NODE_ENV === 'development' &&
@@ -83,5 +84,6 @@ const createRootReducer = (services: ServiceRepository) => combineReducers({
     snackbar: snackbarReducer,
     treePicker: treePickerReducer,
     fileUploader: fileUploaderReducer,
-    processPanel: processPanelReducer
+    processPanel: processPanelReducer,
+    progressIndicator: progressIndicatorReducer
 });
diff --git a/src/views-components/progress/content-progress.tsx b/src/views-components/progress/content-progress.tsx
new file mode 100644 (file)
index 0000000..0d291f4
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { CircularProgress } from '@material-ui/core';
+import { withProgress } from '~/store/progress-indicator/with-progress';
+import { WithProgressStateProps } from '~/store/progress-indicator/with-progress';
+import { ProgressIndicatorData } from '~/store/progress-indicator/progress-indicator-reducer';
+
+export const ContentProgress = withProgress(ProgressIndicatorData.CONTENT_PROGRESS)((props: WithProgressStateProps) => 
+    props.started ? <CircularProgress /> : null
+);
diff --git a/src/views-components/progress/detail-panel-progress.tsx b/src/views-components/progress/detail-panel-progress.tsx
new file mode 100644 (file)
index 0000000..d5d566e
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { CircularProgress } from '@material-ui/core';
+import { withProgress } from '~/store/progress-indicator/with-progress';
+import { WithProgressStateProps } from '~/store/progress-indicator/with-progress';
+import { ProgressIndicatorData } from '~/store/progress-indicator/progress-indicator-reducer';
+
+export const DetailsPanelProgress = withProgress(ProgressIndicatorData.DETAILS_PROGRESS)((props: WithProgressStateProps) => 
+    props.started ? <CircularProgress /> : null
+);
diff --git a/src/views-components/progress/workbench-progress.tsx b/src/views-components/progress/workbench-progress.tsx
new file mode 100644 (file)
index 0000000..35bfd7a
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { CircularProgress } from '@material-ui/core';
+import { withProgress } from '~/store/progress-indicator/with-progress';
+import { WithProgressStateProps } from '~/store/progress-indicator/with-progress';
+import { ProgressIndicatorData } from '~/store/progress-indicator/progress-indicator-reducer';
+
+export const WorkbenchProgress = withProgress(ProgressIndicatorData.WORKBENCH_PROGRESS)((props: WithProgressStateProps) => 
+    props.started ? <CircularProgress /> : null
+);
index 0e85ca3e8488bde391901ababc45f7a53523f518..e5d26a281bc88848d6b2cb4bdd17cc5519b82af2 100644 (file)
@@ -41,6 +41,7 @@ import { PartialCopyCollectionDialog } from '~/views-components/dialog-forms/par
 import { TrashPanel } from "~/views/trash-panel/trash-panel";
 import { MainContentBar } from '../../views-components/main-content-bar/main-content-bar';
 import { Grid } from '@material-ui/core';
+import { WorkbenchProgress } from '~/views-components/progress/workbench-progress';
 
 type CssRules = 'root' | 'contentWrapper' | 'content' | 'appBar';
 
@@ -124,6 +125,7 @@ export const Workbench = withStyles(styles)(
                                     direction="column"
                                     className={this.props.classes.contentWrapper}>
                                     <Grid item>
+                                        <WorkbenchProgress />
                                         <MainContentBar />
                                     </Grid>
                                     <Grid item xs className={this.props.classes.content}>