From 6d5feaa5d8ab29f14efd5d6d60154248a1c14c73 Mon Sep 17 00:00:00 2001 From: Michal Klobukowski Date: Tue, 24 Jul 2018 15:08:45 +0200 Subject: [PATCH] Create simple snackbar actinos, reducer and component Feature #13886 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- src/store/snackbar/snackbar-actions.ts | 12 ++++++++++ src/store/snackbar/snackbar-reducer.ts | 27 ++++++++++++++++++++++ src/store/store.ts | 3 +++ src/views-components/snackbar/snackbar.tsx | 25 ++++++++++++++++++++ src/views/workbench/workbench.tsx | 2 ++ 5 files changed, 69 insertions(+) create mode 100644 src/store/snackbar/snackbar-actions.ts create mode 100644 src/store/snackbar/snackbar-reducer.ts create mode 100644 src/views-components/snackbar/snackbar.tsx diff --git a/src/store/snackbar/snackbar-actions.ts b/src/store/snackbar/snackbar-actions.ts new file mode 100644 index 0000000000..2f6175ad68 --- /dev/null +++ b/src/store/snackbar/snackbar-actions.ts @@ -0,0 +1,12 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { unionize, ofType, UnionOf } from "unionize"; + +export const snackbarActions = unionize({ + OPEN_SNACKBAR: ofType<{message: string; hideDuration?: number}>(), + CLOSE_SNACKBAR: ofType<{}>() +}, { tag: 'type', value: 'payload' }); + +export type SnackbarAction = UnionOf; diff --git a/src/store/snackbar/snackbar-reducer.ts b/src/store/snackbar/snackbar-reducer.ts new file mode 100644 index 0000000000..403c19f007 --- /dev/null +++ b/src/store/snackbar/snackbar-reducer.ts @@ -0,0 +1,27 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { SnackbarAction, snackbarActions } from "./snackbar-actions"; + +export interface SnackbarState { + message: string; + open: boolean; + hideDuration: number; +} + +const DEFAULT_HIDE_DURATION = 3000; + +const initialState: SnackbarState = { + message: "", + open: false, + hideDuration: DEFAULT_HIDE_DURATION +}; + +export const snackbarReducer = (state = initialState, action: SnackbarAction) => { + return snackbarActions.match(action, { + OPEN_SNACKBAR: data => ({ ...data, open: true }), + CLOSE_SNACKBAR: () => initialState, + default: () => state, + }); +}; diff --git a/src/store/store.ts b/src/store/store.ts index a5e22e8eec..ae07744219 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -17,6 +17,7 @@ import { contextMenuReducer, ContextMenuState } from './context-menu/context-men import { favoritePanelMiddleware } from "./favorite-panel/favorite-panel-middleware"; import { reducer as formReducer } from 'redux-form'; import { FavoritesState, favoritesReducer } from './favorites/favorites-reducer'; +import { snackbarReducer, SnackbarState } from './snackbar/snackbar-reducer'; const composeEnhancers = (process.env.NODE_ENV === 'development' && @@ -32,6 +33,7 @@ export interface RootState { detailsPanel: DetailsPanelState; contextMenu: ContextMenuState; favorites: FavoritesState; + snackbar: SnackbarState; } const rootReducer = combineReducers({ @@ -44,6 +46,7 @@ const rootReducer = combineReducers({ contextMenu: contextMenuReducer, form: formReducer, favorites: favoritesReducer, + snackbar: snackbarReducer, }); diff --git a/src/views-components/snackbar/snackbar.tsx b/src/views-components/snackbar/snackbar.tsx new file mode 100644 index 0000000000..d83d70145d --- /dev/null +++ b/src/views-components/snackbar/snackbar.tsx @@ -0,0 +1,25 @@ +// 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"; +import MaterialSnackbar, { SnackbarProps } from "@material-ui/core/Snackbar"; +import { Dispatch } from "redux"; +import { snackbarActions } from "../../store/snackbar/snackbar-actions"; + +const mapStateToProps = (state: RootState): SnackbarProps => ({ + anchorOrigin: { vertical: "bottom", horizontal: "left" }, + open: state.snackbar.open, + message: {state.snackbar.message}, + autoHideDuration: state.snackbar.hideDuration +}); + +const mapDispatchToProps = (dispatch: Dispatch): Pick => ({ + onClose: () => { + dispatch(snackbarActions.CLOSE_SNACKBAR()); + } +}); + +export const Snackbar = connect(mapStateToProps, mapDispatchToProps)(MaterialSnackbar); diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx index ef9b4903b0..8e2cb57836 100644 --- a/src/views/workbench/workbench.tsx +++ b/src/views/workbench/workbench.tsx @@ -35,6 +35,7 @@ import { ContextMenu, ContextMenuKind } from "../../views-components/context-men import { FavoritePanel, FAVORITE_PANEL_ID } from "../favorite-panel/favorite-panel"; import { CurrentTokenDialog } from '../../views-components/current-token-dialog/current-token-dialog'; import { dataExplorerActions } from '../../store/data-explorer/data-explorer-action'; +import { Snackbar } from '../../views-components/snackbar/snackbar'; const drawerWidth = 240; const appBarHeight = 100; @@ -216,6 +217,7 @@ export const Workbench = withStyles(styles)( {user && } +