From b2a8229dc05885de63de413e95c56b953c52c82d Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Wed, 14 Oct 2020 10:17:23 +0200 Subject: [PATCH 1/3] Dock savebar even if it's disabled --- src/components/AppLayout/AppActionContext.tsx | 14 +- src/components/AppLayout/AppLayout.tsx | 19 ++- .../SaveButtonBar/SaveButtonBar.tsx | 122 +++++++++--------- 3 files changed, 92 insertions(+), 63 deletions(-) diff --git a/src/components/AppLayout/AppActionContext.tsx b/src/components/AppLayout/AppActionContext.tsx index 6083d883b..ad7e71990 100644 --- a/src/components/AppLayout/AppActionContext.tsx +++ b/src/components/AppLayout/AppActionContext.tsx @@ -1,7 +1,15 @@ import React from "react"; -const AppActionContext = React.createContext>( - undefined -); +interface AppAction { + anchor: React.RefObject; + docked: boolean; + setDocked: (docked: boolean) => void; +} +const AppActionContext = React.createContext({ + anchor: undefined, + docked: true, + setDocked: () => undefined +}); +export const useAppAction = () => React.useContext(AppActionContext); export default AppActionContext; diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index 128c20a95..c5fdf190d 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -50,6 +50,9 @@ const useStyles = makeStyles( position: "sticky", zIndex: 10 }, + appActionDocked: { + position: "static" + }, appLoader: { height: appLoaderHeight, marginBottom: theme.spacing(2), @@ -313,6 +316,7 @@ const AppLayout: React.FC = ({ children }) => { const [appState, dispatchAppState] = useAppState(); const { location } = useRouter(); const [isNavigatorVisible, setNavigatorVisibility] = React.useState(false); + const [docked, setDocked] = React.useState(true); const menuStructure = createMenuStructure(intl); const configurationMenu = createConfigurationMenu(intl); @@ -365,7 +369,13 @@ const AppLayout: React.FC = ({ children }) => { setVisibility={setNavigatorVisibility} /> - +
= ({ children }) => { : children}
-
+
diff --git a/src/components/SaveButtonBar/SaveButtonBar.tsx b/src/components/SaveButtonBar/SaveButtonBar.tsx index d741cae2f..61c37c94b 100644 --- a/src/components/SaveButtonBar/SaveButtonBar.tsx +++ b/src/components/SaveButtonBar/SaveButtonBar.tsx @@ -9,7 +9,7 @@ import React from "react"; import { useIntl } from "react-intl"; import { maybe } from "../../misc"; -import AppActionContext from "../AppLayout/AppActionContext"; +import AppActionContext, { useAppAction } from "../AppLayout/AppActionContext"; import ConfirmButton, { ConfirmButtonTransitionState } from "../ConfirmButton/ConfirmButton"; @@ -41,8 +41,12 @@ const useStyles = makeStyles( backgroundColor: theme.palette.error.main, color: theme.palette.error.contrastText }, + paper: { + borderBottomLeftRadius: 0, + borderBottomRightRadius: 0 + }, root: { - height: 120 + height: 70 }, spacer: { flex: "1" @@ -76,67 +80,69 @@ export const SaveButtonBar: React.FC = props => { } = props; const classes = useStyles(props); + const appAction = useAppAction(); const intl = useIntl(); const scrollPosition = useWindowScroll(); + + React.useEffect(() => { + appAction.setDocked(disabled); + + return () => appAction.setDocked(true); + }, [disabled]); + const scrolledToBottom = scrollPosition.y + window.innerHeight >= document.body.scrollHeight; - const shouldDisplay = onDelete || !disabled; - return ( - - {anchor => - anchor ? ( - - {shouldDisplay && ( -
- - - - {!!onDelete && ( - - )} -
- - - {maybe( - () => labels.save, - intl.formatMessage(buttonMessages.save) - )} - - - - -
- )} - - ) : null - } - - ); + return appAction.anchor ? ( + +
+ + + + {!!onDelete && ( + + )} +
+ + + {maybe( + () => labels.save, + intl.formatMessage(buttonMessages.save) + )} + + + + +
+ + ) : null; }; SaveButtonBar.displayName = "SaveButtonBar"; export default SaveButtonBar; From dbdb93445b478a47247f62cedbf4836e54c1796e Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Wed, 14 Oct 2020 10:19:30 +0200 Subject: [PATCH 2/3] Remove unused import --- src/components/SaveButtonBar/SaveButtonBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SaveButtonBar/SaveButtonBar.tsx b/src/components/SaveButtonBar/SaveButtonBar.tsx index 61c37c94b..64f57e492 100644 --- a/src/components/SaveButtonBar/SaveButtonBar.tsx +++ b/src/components/SaveButtonBar/SaveButtonBar.tsx @@ -9,7 +9,7 @@ import React from "react"; import { useIntl } from "react-intl"; import { maybe } from "../../misc"; -import AppActionContext, { useAppAction } from "../AppLayout/AppActionContext"; +import { useAppAction } from "../AppLayout/AppActionContext"; import ConfirmButton, { ConfirmButtonTransitionState } from "../ConfirmButton/ConfirmButton"; From 952dd37747dff10d8f69260cea2b9c0a77a48e79 Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Thu, 15 Oct 2020 10:00:31 +0200 Subject: [PATCH 3/3] wip --- .../ConfirmButton/ConfirmButton.tsx | 20 +++++--- .../SaveButtonBar/SaveButtonBar.tsx | 23 +++------ .../messages/MessageManagerProvider.tsx | 50 ++++++++++--------- src/config.ts | 2 + 4 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/components/ConfirmButton/ConfirmButton.tsx b/src/components/ConfirmButton/ConfirmButton.tsx index 8a6d2f812..981131dbb 100644 --- a/src/components/ConfirmButton/ConfirmButton.tsx +++ b/src/components/ConfirmButton/ConfirmButton.tsx @@ -7,6 +7,7 @@ import { withStyles } from "@material-ui/core/styles"; import CheckIcon from "@material-ui/icons/Check"; +import { DEFAULT_NOTIFICATION_SHOW_TIME } from "@saleor/config"; import { buttonMessages } from "@saleor/intl"; import classNames from "classnames"; import React from "react"; @@ -61,6 +62,7 @@ export interface ConfirmButtonProps extends Omit, WithStyles { transitionState: ConfirmButtonTransitionState; + onTransitionToDefault?: () => void; } interface ConfirmButtonState { @@ -93,20 +95,21 @@ const ConfirmButton = withStyles(styles, { name: "ConfirmButton" })( } componentDidUpdate(prevProps: ConfirmButtonProps) { - const { transitionState } = this.props; + const { transitionState, onTransitionToDefault } = this.props; if (prevProps.transitionState !== transitionState) { if ( (["error", "success"] as ConfirmButtonTransitionState[]).includes( transitionState ) ) { - this.timeout = setTimeout( - () => - this.setState({ - displayCompletedActionState: false - }), - 2000 - ); + this.timeout = setTimeout(() => { + this.setState({ + displayCompletedActionState: false + }); + if (onTransitionToDefault) { + onTransitionToDefault(); + } + }, DEFAULT_NOTIFICATION_SHOW_TIME); } else if (transitionState === "loading") { clearTimeout(this.timeout); } @@ -125,6 +128,7 @@ const ConfirmButton = withStyles(styles, { name: "ConfirmButton" })( disabled, transitionState, onClick, + onTransitionToDefault: _, ...props } = this.props; const { displayCompletedActionState } = this.state; diff --git a/src/components/SaveButtonBar/SaveButtonBar.tsx b/src/components/SaveButtonBar/SaveButtonBar.tsx index 64f57e492..279436b79 100644 --- a/src/components/SaveButtonBar/SaveButtonBar.tsx +++ b/src/components/SaveButtonBar/SaveButtonBar.tsx @@ -8,7 +8,6 @@ import { buttonMessages } from "@saleor/intl"; import React from "react"; import { useIntl } from "react-intl"; -import { maybe } from "../../misc"; import { useAppAction } from "../AppLayout/AppActionContext"; import ConfirmButton, { ConfirmButtonTransitionState @@ -85,10 +84,11 @@ export const SaveButtonBar: React.FC = props => { const scrollPosition = useWindowScroll(); React.useEffect(() => { - appAction.setDocked(disabled); - - return () => appAction.setDocked(true); + if (!disabled && state !== "loading") { + appAction.setDocked(false); + } }, [disabled]); + React.useEffect(() => () => appAction.setDocked(true), []); const scrolledToBottom = scrollPosition.y + window.innerHeight >= document.body.scrollHeight; @@ -109,9 +109,7 @@ export const SaveButtonBar: React.FC = props => { className={classes.deleteButton} data-test="button-bar-delete" > - {labels && labels.delete - ? labels.delete - : intl.formatMessage(buttonMessages.delete)} + {labels?.delete || intl.formatMessage(buttonMessages.delete)} )}
@@ -121,21 +119,16 @@ export const SaveButtonBar: React.FC = props => { onClick={onCancel} data-test="button-bar-cancel" > - {maybe( - () => labels.cancel, - intl.formatMessage(buttonMessages.back) - )} + {labels?.cancel || intl.formatMessage(buttonMessages.back)} appAction.setDocked(true)} > - {maybe( - () => labels.save, - intl.formatMessage(buttonMessages.save) - )} + {labels?.save || intl.formatMessage(buttonMessages.save)} diff --git a/src/components/messages/MessageManagerProvider.tsx b/src/components/messages/MessageManagerProvider.tsx index 4f20b8af3..280ff0a5b 100644 --- a/src/components/messages/MessageManagerProvider.tsx +++ b/src/components/messages/MessageManagerProvider.tsx @@ -1,3 +1,4 @@ +import { DEFAULT_NOTIFICATION_SHOW_TIME } from "@saleor/config"; import React, { useCallback, useEffect, useRef, useState } from "react"; import { createPortal } from "react-dom"; import { TransitionGroup } from "react-transition-group"; @@ -43,32 +44,35 @@ const MessageManagerProvider = ({ children }) => { ); }, []); - const show = useCallback((message = {}, timeout = 3000) => { - const id = Date.now(); - const notification = { - close: () => remove(id), - id, - message, - timeout - }; - if (timeout !== null) { - const timeoutId = window.setTimeout(() => { - timerCallback(notification); - }, timeout); + const show = useCallback( + (message = {}, timeout = DEFAULT_NOTIFICATION_SHOW_TIME) => { + const id = Date.now(); + const notification = { + close: () => remove(id), + id, + message, + timeout + }; + if (timeout !== null) { + const timeoutId = window.setTimeout(() => { + timerCallback(notification); + }, timeout); - timersArr.current.push({ - id: notification.id, - notification, - remaining: timeout, - start: new Date().getTime(), - timeoutId - }); - } + timersArr.current.push({ + id: notification.id, + notification, + remaining: timeout, + start: new Date().getTime(), + timeoutId + }); + } - setNotifications(state => [notification, ...state]); + setNotifications(state => [notification, ...state]); - return notification; - }, []); + return notification; + }, + [] + ); const getCurrentTimer = (notification: INotification) => { const currentTimerIndex = timersArr.current.findIndex( diff --git a/src/config.ts b/src/config.ts index 7a9e4ef0c..fb0bd87d4 100644 --- a/src/config.ts +++ b/src/config.ts @@ -96,3 +96,5 @@ export const defaultListSettings: AppListViewSettings = { export const APP_VERSION = packageInfo.version; export const DEMO_MODE = process.env.DEMO_MODE === "true"; export const GTM_ID = process.env.GTM_ID; + +export const DEFAULT_NOTIFICATION_SHOW_TIME = 3000;