Add notification when merging changes into the tree

This commit is contained in:
Thomas Nordquist
2019-04-08 00:57:32 +02:00
parent 436b569e93
commit 8c5f708386
5 changed files with 47 additions and 13 deletions

View File

@@ -1,11 +1,15 @@
import { ActionTypes, AppState, CustomAction } from '../reducers' import { ActionTypes } from '../reducers'
import { Dispatch } from 'redux'
export const showError = (error?: string) => ({ export const showError = (error?: string) => ({
error, error,
type: ActionTypes.showError, type: ActionTypes.showError,
}) })
export const showNotification = (notification?: string) => ({
notification,
type: ActionTypes.showNotification,
})
export const didLaunch = () => ({ export const didLaunch = () => ({
type: ActionTypes.didLaunch, type: ActionTypes.didLaunch,
}) })

View File

@@ -5,6 +5,7 @@ import { AppState } from '../reducers'
import { batchActions } from 'redux-batched-actions' import { batchActions } from 'redux-batched-actions'
import { setTopic } from './Publish' import { setTopic } from './Publish'
import { TopicViewModel } from '../model/TopicViewModel' import { TopicViewModel } from '../model/TopicViewModel'
import { globalActions } from '.';
const debounce = require('lodash.debounce') const debounce = require('lodash.debounce')
export const selectTopic = (topic: q.TreeNode<TopicViewModel>) => (dispatch: Dispatch<any>, getState: () => AppState) => { export const selectTopic = (topic: q.TreeNode<TopicViewModel>) => (dispatch: Dispatch<any>, getState: () => AppState) => {
@@ -58,10 +59,20 @@ export const showTree = (tree?: q.Tree<TopicViewModel>) => (dispatch: Dispatch<a
}) })
} }
export const togglePause = (tree?: q.Tree<TopicViewModel>) => (dispatch: Dispatch<any>, getState: () => AppState): AnyAction => { export const togglePause = (tree?: q.Tree<TopicViewModel>) => (dispatch: Dispatch<any>, getState: () => AppState) => {
const paused = getState().tree.paused const paused = getState().tree.paused
const tree = getState().tree.tree
const changes = tree ? tree.unmergedChanges().length : 0
return dispatch({ if (paused && changes > 0) {
dispatch(globalActions.showNotification('Applying recorded changes.'))
}
dispatch({
type: paused ? ActionTypes.TREE_RESUME_UPDATES : ActionTypes.TREE_PAUSE_UPDATES, type: paused ? ActionTypes.TREE_RESUME_UPDATES : ActionTypes.TREE_PAUSE_UPDATES,
}) })
if (paused && changes > 0) {
dispatch(globalActions.showNotification(`Sucessfully applied ${changes} changes.`))
}
} }

View File

@@ -19,6 +19,7 @@ interface Props {
classes: any classes: any
settingsVisible: boolean settingsVisible: boolean
error?: string error?: string
notification?: string
actions: typeof globalActions actions: typeof globalActions
settingsActions: typeof settingsActions settingsActions: typeof settingsActions
launching: boolean launching: boolean
@@ -30,16 +31,22 @@ class App extends React.PureComponent<Props, {}> {
this.state = { } this.state = { }
} }
private renderError() { private renderNotification() {
if (this.props.error) { const message = this.props.error || this.props.notification
const error = typeof this.props.error === 'string' ? this.props.error : JSON.stringify(this.props.error) const isError = message === this.props.error
if (message) {
// Guard in case someone ever calls showError with an error instead of a string
const str = typeof message === 'string' ? message : JSON.stringify(message)
return ( return (
<Notification <Notification
message={error} message={str}
onClose={() => { this.props.actions.showError(undefined) }} type={isError ? 'error' : 'notification'}
onClose={() => { isError ? this.props.actions.showError(undefined) : this.props.actions.showNotification(undefined) }}
/> />
) )
} }
return null
} }
public componentDidMount() { public componentDidMount() {
@@ -58,7 +65,7 @@ class App extends React.PureComponent<Props, {}> {
<div className={centerContent}> <div className={centerContent}>
<CssBaseline /> <CssBaseline />
<ErrorBoundary> <ErrorBoundary>
{this.renderError()} {this.renderNotification()}
<React.Suspense fallback={<div>Loading...</div>}> <React.Suspense fallback={<div>Loading...</div>}>
<Settings /> <Settings />
</React.Suspense> </React.Suspense>
@@ -134,6 +141,7 @@ const mapStateToProps = (state: AppState) => {
settingsVisible: state.settings.get('visible'), settingsVisible: state.settings.get('visible'),
connectionId: state.connection.connectionId, connectionId: state.connection.connectionId,
error: state.globalState.error, error: state.globalState.error,
notification: state.globalState.notification,
highlightTopicUpdates: state.settings.get('highlightTopicUpdates'), highlightTopicUpdates: state.settings.get('highlightTopicUpdates'),
launching: state.globalState.launching, launching: state.globalState.launching,
} }

View File

@@ -6,6 +6,7 @@ import { green, red } from '@material-ui/core/colors'
interface Props { interface Props {
message?: string message?: string
type: 'error' | 'notification'
onClose: () => void onClose: () => void
classes: any classes: any
} }
@@ -16,7 +17,7 @@ class Notification extends React.Component<Props, {}> {
} }
public static styles = (theme: Theme) => ({ public static styles = (theme: Theme) => ({
success: { notification: {
backgroundColor: green[600], backgroundColor: green[600],
color: theme.typography.button.color, color: theme.typography.button.color,
}, },
@@ -40,7 +41,7 @@ class Notification extends React.Component<Props, {}> {
onClose={this.props.onClose} onClose={this.props.onClose}
> >
<SnackbarContent <SnackbarContent
className={this.props.classes.error} className={this.props.type === 'error' ? this.props.classes.error : this.props.classes.notification}
message={this.props.message} message={this.props.message}
/> />
</Snackbar> </Snackbar>

View File

@@ -11,6 +11,7 @@ export enum ActionTypes {
showUpdateNotification = 'SHOW_UPDATE_NOTIFICATION', showUpdateNotification = 'SHOW_UPDATE_NOTIFICATION',
showUpdateDetails = 'SHOW_UPDATE_DETAILS', showUpdateDetails = 'SHOW_UPDATE_DETAILS',
showError = 'SHOW_ERROR', showError = 'SHOW_ERROR',
showNotification = 'SHOW_NOTIFICATION',
didLaunch = 'DID_LAUNCH', didLaunch = 'DID_LAUNCH',
} }
@@ -19,6 +20,7 @@ export interface CustomAction extends Action {
showUpdateNotification?: boolean showUpdateNotification?: boolean
showUpdateDetails?: boolean showUpdateDetails?: boolean
error?: string error?: string
notification?: string
} }
export interface AppState { export interface AppState {
@@ -34,6 +36,7 @@ export interface GlobalState {
showUpdateNotification?: boolean showUpdateNotification?: boolean
showUpdateDetails: boolean showUpdateDetails: boolean
error?: string error?: string
notification?: string
launching: boolean launching: boolean
} }
@@ -61,6 +64,13 @@ const globalState: Reducer<GlobalState | undefined, CustomAction> = (state = ini
error: action.error, error: action.error,
} }
case ActionTypes.showNotification:
console.log(action)
return {
...state,
notification: action.notification,
}
case ActionTypes.didLaunch: case ActionTypes.didLaunch:
return { return {
...state, ...state,