Wait for notification to disappear

This commit is contained in:
dominik-zeglen 2020-11-02 13:20:52 +01:00
commit 6ee5038f6c
4 changed files with 49 additions and 46 deletions

View file

@ -7,6 +7,7 @@ import {
withStyles withStyles
} from "@material-ui/core/styles"; } from "@material-ui/core/styles";
import CheckIcon from "@material-ui/icons/Check"; import CheckIcon from "@material-ui/icons/Check";
import { DEFAULT_NOTIFICATION_SHOW_TIME } from "@saleor/config";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
@ -61,6 +62,7 @@ export interface ConfirmButtonProps
extends Omit<ButtonProps, "classes">, extends Omit<ButtonProps, "classes">,
WithStyles<typeof styles> { WithStyles<typeof styles> {
transitionState: ConfirmButtonTransitionState; transitionState: ConfirmButtonTransitionState;
onTransitionToDefault?: () => void;
} }
interface ConfirmButtonState { interface ConfirmButtonState {
@ -93,20 +95,21 @@ const ConfirmButton = withStyles(styles, { name: "ConfirmButton" })(
} }
componentDidUpdate(prevProps: ConfirmButtonProps) { componentDidUpdate(prevProps: ConfirmButtonProps) {
const { transitionState } = this.props; const { transitionState, onTransitionToDefault } = this.props;
if (prevProps.transitionState !== transitionState) { if (prevProps.transitionState !== transitionState) {
if ( if (
(["error", "success"] as ConfirmButtonTransitionState[]).includes( (["error", "success"] as ConfirmButtonTransitionState[]).includes(
transitionState transitionState
) )
) { ) {
this.timeout = setTimeout( this.timeout = setTimeout(() => {
() => this.setState({
this.setState({ displayCompletedActionState: false
displayCompletedActionState: false });
}), if (onTransitionToDefault) {
2000 onTransitionToDefault();
); }
}, DEFAULT_NOTIFICATION_SHOW_TIME);
} else if (transitionState === "loading") { } else if (transitionState === "loading") {
clearTimeout(this.timeout); clearTimeout(this.timeout);
} }
@ -125,6 +128,7 @@ const ConfirmButton = withStyles(styles, { name: "ConfirmButton" })(
disabled, disabled,
transitionState, transitionState,
onClick, onClick,
onTransitionToDefault: _,
...props ...props
} = this.props; } = this.props;
const { displayCompletedActionState } = this.state; const { displayCompletedActionState } = this.state;

View file

@ -8,7 +8,6 @@ import { buttonMessages } from "@saleor/intl";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { maybe } from "../../misc";
import { useAppAction } from "../AppLayout/AppActionContext"; import { useAppAction } from "../AppLayout/AppActionContext";
import ConfirmButton, { import ConfirmButton, {
ConfirmButtonTransitionState ConfirmButtonTransitionState
@ -85,10 +84,11 @@ export const SaveButtonBar: React.FC<SaveButtonBarProps> = props => {
const scrollPosition = useWindowScroll(); const scrollPosition = useWindowScroll();
React.useEffect(() => { React.useEffect(() => {
appAction.setDocked(disabled); if (!disabled && state !== "loading") {
appAction.setDocked(false);
return () => appAction.setDocked(true); }
}, [disabled]); }, [disabled]);
React.useEffect(() => () => appAction.setDocked(true), []);
const scrolledToBottom = const scrolledToBottom =
scrollPosition.y + window.innerHeight >= document.body.scrollHeight; scrollPosition.y + window.innerHeight >= document.body.scrollHeight;
@ -109,9 +109,7 @@ export const SaveButtonBar: React.FC<SaveButtonBarProps> = props => {
className={classes.deleteButton} className={classes.deleteButton}
data-test="button-bar-delete" data-test="button-bar-delete"
> >
{labels && labels.delete {labels?.delete || intl.formatMessage(buttonMessages.delete)}
? labels.delete
: intl.formatMessage(buttonMessages.delete)}
</Button> </Button>
)} )}
<div className={classes.spacer} /> <div className={classes.spacer} />
@ -121,21 +119,16 @@ export const SaveButtonBar: React.FC<SaveButtonBarProps> = props => {
onClick={onCancel} onClick={onCancel}
data-test="button-bar-cancel" data-test="button-bar-cancel"
> >
{maybe( {labels?.cancel || intl.formatMessage(buttonMessages.back)}
() => labels.cancel,
intl.formatMessage(buttonMessages.back)
)}
</Button> </Button>
<ConfirmButton <ConfirmButton
disabled={disabled} disabled={disabled}
onClick={onSave} onClick={onSave}
transitionState={state} transitionState={state}
data-test="button-bar-confirm" data-test="button-bar-confirm"
onTransitionToDefault={() => appAction.setDocked(true)}
> >
{maybe( {labels?.save || intl.formatMessage(buttonMessages.save)}
() => labels.save,
intl.formatMessage(buttonMessages.save)
)}
</ConfirmButton> </ConfirmButton>
</CardContent> </CardContent>
</Card> </Card>

View file

@ -1,3 +1,4 @@
import { DEFAULT_NOTIFICATION_SHOW_TIME } from "@saleor/config";
import React, { useCallback, useEffect, useRef, useState } from "react"; import React, { useCallback, useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import { TransitionGroup } from "react-transition-group"; import { TransitionGroup } from "react-transition-group";
@ -43,32 +44,35 @@ const MessageManagerProvider = ({ children }) => {
); );
}, []); }, []);
const show = useCallback((message = {}, timeout = 3000) => { const show = useCallback(
const id = Date.now(); (message = {}, timeout = DEFAULT_NOTIFICATION_SHOW_TIME) => {
const notification = { const id = Date.now();
close: () => remove(id), const notification = {
id, close: () => remove(id),
message, id,
timeout message,
}; timeout
if (timeout !== null) { };
const timeoutId = window.setTimeout(() => { if (timeout !== null) {
timerCallback(notification); const timeoutId = window.setTimeout(() => {
}, timeout); timerCallback(notification);
}, timeout);
timersArr.current.push({ timersArr.current.push({
id: notification.id, id: notification.id,
notification, notification,
remaining: timeout, remaining: timeout,
start: new Date().getTime(), start: new Date().getTime(),
timeoutId timeoutId
}); });
} }
setNotifications(state => [notification, ...state]); setNotifications(state => [notification, ...state]);
return notification; return notification;
}, []); },
[]
);
const getCurrentTimer = (notification: INotification) => { const getCurrentTimer = (notification: INotification) => {
const currentTimerIndex = timersArr.current.findIndex( const currentTimerIndex = timersArr.current.findIndex(

View file

@ -96,3 +96,5 @@ export const defaultListSettings: AppListViewSettings = {
export const APP_VERSION = packageInfo.version; export const APP_VERSION = packageInfo.version;
export const DEMO_MODE = process.env.DEMO_MODE === "true"; export const DEMO_MODE = process.env.DEMO_MODE === "true";
export const GTM_ID = process.env.GTM_ID; export const GTM_ID = process.env.GTM_ID;
export const DEFAULT_NOTIFICATION_SHOW_TIME = 3000;