Dock savebar even if it's disabled

This commit is contained in:
dominik-zeglen 2020-10-14 10:17:23 +02:00
parent b7b5cb9d69
commit b2a8229dc0
3 changed files with 92 additions and 63 deletions

View file

@ -1,7 +1,15 @@
import React from "react";
const AppActionContext = React.createContext<React.RefObject<HTMLDivElement>>(
undefined
);
interface AppAction {
anchor: React.RefObject<HTMLDivElement>;
docked: boolean;
setDocked: (docked: boolean) => void;
}
const AppActionContext = React.createContext<AppAction>({
anchor: undefined,
docked: true,
setDocked: () => undefined
});
export const useAppAction = () => React.useContext(AppActionContext);
export default AppActionContext;

View file

@ -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<AppLayoutProps> = ({ 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<AppLayoutProps> = ({ children }) => {
setVisibility={setNavigatorVisibility}
/>
<AppHeaderContext.Provider value={appHeaderAnchor}>
<AppActionContext.Provider value={appActionAnchor}>
<AppActionContext.Provider
value={{
anchor: appActionAnchor,
docked,
setDocked
}}
>
<div className={classes.root}>
<div className={classes.sideBar}>
<ResponsiveDrawer
@ -533,7 +543,12 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
: children}
</main>
</div>
<div className={classes.appAction} ref={appActionAnchor} />
<div
className={classNames(classes.appAction, {
[classes.appActionDocked]: docked
})}
ref={appActionAnchor}
/>
</div>
</div>
</AppActionContext.Provider>

View file

@ -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<SaveButtonBarProps> = 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 (
<AppActionContext.Consumer>
{anchor =>
anchor ? (
<Portal container={anchor.current}>
{shouldDisplay && (
<div className={classes.root} {...rest}>
<Container>
<Card elevation={scrolledToBottom ? 0 : 16}>
<CardContent className={classes.content}>
{!!onDelete && (
<Button
variant="contained"
onClick={onDelete}
className={classes.deleteButton}
data-test="button-bar-delete"
>
{labels && labels.delete
? labels.delete
: intl.formatMessage(buttonMessages.delete)}
</Button>
)}
<div className={classes.spacer} />
<Button
className={classes.cancelButton}
variant="text"
onClick={onCancel}
data-test="button-bar-cancel"
>
{maybe(
() => labels.cancel,
intl.formatMessage(buttonMessages.back)
)}
</Button>
<ConfirmButton
disabled={disabled}
onClick={onSave}
transitionState={state}
data-test="button-bar-confirm"
>
{maybe(
() => labels.save,
intl.formatMessage(buttonMessages.save)
)}
</ConfirmButton>
</CardContent>
</Card>
</Container>
</div>
)}
</Portal>
) : null
}
</AppActionContext.Consumer>
);
return appAction.anchor ? (
<Portal container={appAction.anchor.current}>
<div className={classes.root} {...rest}>
<Container>
<Card
className={classes.paper}
elevation={!(appAction.docked || scrolledToBottom) ? 16 : 0}
>
<CardContent className={classes.content}>
{!!onDelete && (
<Button
variant="contained"
onClick={onDelete}
className={classes.deleteButton}
data-test="button-bar-delete"
>
{labels && labels.delete
? labels.delete
: intl.formatMessage(buttonMessages.delete)}
</Button>
)}
<div className={classes.spacer} />
<Button
className={classes.cancelButton}
variant="text"
onClick={onCancel}
data-test="button-bar-cancel"
>
{maybe(
() => labels.cancel,
intl.formatMessage(buttonMessages.back)
)}
</Button>
<ConfirmButton
disabled={disabled}
onClick={onSave}
transitionState={state}
data-test="button-bar-confirm"
>
{maybe(
() => labels.save,
intl.formatMessage(buttonMessages.save)
)}
</ConfirmButton>
</CardContent>
</Card>
</Container>
</div>
</Portal>
) : null;
};
SaveButtonBar.displayName = "SaveButtonBar";
export default SaveButtonBar;