Dock savebar even if it's disabled
This commit is contained in:
parent
b7b5cb9d69
commit
b2a8229dc0
3 changed files with 92 additions and 63 deletions
|
@ -1,7 +1,15 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const AppActionContext = React.createContext<React.RefObject<HTMLDivElement>>(
|
interface AppAction {
|
||||||
undefined
|
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;
|
export default AppActionContext;
|
||||||
|
|
|
@ -50,6 +50,9 @@ const useStyles = makeStyles(
|
||||||
position: "sticky",
|
position: "sticky",
|
||||||
zIndex: 10
|
zIndex: 10
|
||||||
},
|
},
|
||||||
|
appActionDocked: {
|
||||||
|
position: "static"
|
||||||
|
},
|
||||||
appLoader: {
|
appLoader: {
|
||||||
height: appLoaderHeight,
|
height: appLoaderHeight,
|
||||||
marginBottom: theme.spacing(2),
|
marginBottom: theme.spacing(2),
|
||||||
|
@ -313,6 +316,7 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
|
||||||
const [appState, dispatchAppState] = useAppState();
|
const [appState, dispatchAppState] = useAppState();
|
||||||
const { location } = useRouter();
|
const { location } = useRouter();
|
||||||
const [isNavigatorVisible, setNavigatorVisibility] = React.useState(false);
|
const [isNavigatorVisible, setNavigatorVisibility] = React.useState(false);
|
||||||
|
const [docked, setDocked] = React.useState(true);
|
||||||
|
|
||||||
const menuStructure = createMenuStructure(intl);
|
const menuStructure = createMenuStructure(intl);
|
||||||
const configurationMenu = createConfigurationMenu(intl);
|
const configurationMenu = createConfigurationMenu(intl);
|
||||||
|
@ -365,7 +369,13 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
|
||||||
setVisibility={setNavigatorVisibility}
|
setVisibility={setNavigatorVisibility}
|
||||||
/>
|
/>
|
||||||
<AppHeaderContext.Provider value={appHeaderAnchor}>
|
<AppHeaderContext.Provider value={appHeaderAnchor}>
|
||||||
<AppActionContext.Provider value={appActionAnchor}>
|
<AppActionContext.Provider
|
||||||
|
value={{
|
||||||
|
anchor: appActionAnchor,
|
||||||
|
docked,
|
||||||
|
setDocked
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<div className={classes.sideBar}>
|
<div className={classes.sideBar}>
|
||||||
<ResponsiveDrawer
|
<ResponsiveDrawer
|
||||||
|
@ -533,7 +543,12 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
|
||||||
: children}
|
: children}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.appAction} ref={appActionAnchor} />
|
<div
|
||||||
|
className={classNames(classes.appAction, {
|
||||||
|
[classes.appActionDocked]: docked
|
||||||
|
})}
|
||||||
|
ref={appActionAnchor}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AppActionContext.Provider>
|
</AppActionContext.Provider>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { maybe } from "../../misc";
|
import { maybe } from "../../misc";
|
||||||
import AppActionContext from "../AppLayout/AppActionContext";
|
import AppActionContext, { useAppAction } from "../AppLayout/AppActionContext";
|
||||||
import ConfirmButton, {
|
import ConfirmButton, {
|
||||||
ConfirmButtonTransitionState
|
ConfirmButtonTransitionState
|
||||||
} from "../ConfirmButton/ConfirmButton";
|
} from "../ConfirmButton/ConfirmButton";
|
||||||
|
@ -41,8 +41,12 @@ const useStyles = makeStyles(
|
||||||
backgroundColor: theme.palette.error.main,
|
backgroundColor: theme.palette.error.main,
|
||||||
color: theme.palette.error.contrastText
|
color: theme.palette.error.contrastText
|
||||||
},
|
},
|
||||||
|
paper: {
|
||||||
|
borderBottomLeftRadius: 0,
|
||||||
|
borderBottomRightRadius: 0
|
||||||
|
},
|
||||||
root: {
|
root: {
|
||||||
height: 120
|
height: 70
|
||||||
},
|
},
|
||||||
spacer: {
|
spacer: {
|
||||||
flex: "1"
|
flex: "1"
|
||||||
|
@ -76,67 +80,69 @@ export const SaveButtonBar: React.FC<SaveButtonBarProps> = props => {
|
||||||
} = props;
|
} = props;
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
|
const appAction = useAppAction();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const scrollPosition = useWindowScroll();
|
const scrollPosition = useWindowScroll();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
appAction.setDocked(disabled);
|
||||||
|
|
||||||
|
return () => appAction.setDocked(true);
|
||||||
|
}, [disabled]);
|
||||||
|
|
||||||
const scrolledToBottom =
|
const scrolledToBottom =
|
||||||
scrollPosition.y + window.innerHeight >= document.body.scrollHeight;
|
scrollPosition.y + window.innerHeight >= document.body.scrollHeight;
|
||||||
const shouldDisplay = onDelete || !disabled;
|
|
||||||
|
|
||||||
return (
|
return appAction.anchor ? (
|
||||||
<AppActionContext.Consumer>
|
<Portal container={appAction.anchor.current}>
|
||||||
{anchor =>
|
<div className={classes.root} {...rest}>
|
||||||
anchor ? (
|
<Container>
|
||||||
<Portal container={anchor.current}>
|
<Card
|
||||||
{shouldDisplay && (
|
className={classes.paper}
|
||||||
<div className={classes.root} {...rest}>
|
elevation={!(appAction.docked || scrolledToBottom) ? 16 : 0}
|
||||||
<Container>
|
>
|
||||||
<Card elevation={scrolledToBottom ? 0 : 16}>
|
<CardContent className={classes.content}>
|
||||||
<CardContent className={classes.content}>
|
{!!onDelete && (
|
||||||
{!!onDelete && (
|
<Button
|
||||||
<Button
|
variant="contained"
|
||||||
variant="contained"
|
onClick={onDelete}
|
||||||
onClick={onDelete}
|
className={classes.deleteButton}
|
||||||
className={classes.deleteButton}
|
data-test="button-bar-delete"
|
||||||
data-test="button-bar-delete"
|
>
|
||||||
>
|
{labels && labels.delete
|
||||||
{labels && labels.delete
|
? labels.delete
|
||||||
? labels.delete
|
: intl.formatMessage(buttonMessages.delete)}
|
||||||
: intl.formatMessage(buttonMessages.delete)}
|
</Button>
|
||||||
</Button>
|
)}
|
||||||
)}
|
<div className={classes.spacer} />
|
||||||
<div className={classes.spacer} />
|
<Button
|
||||||
<Button
|
className={classes.cancelButton}
|
||||||
className={classes.cancelButton}
|
variant="text"
|
||||||
variant="text"
|
onClick={onCancel}
|
||||||
onClick={onCancel}
|
data-test="button-bar-cancel"
|
||||||
data-test="button-bar-cancel"
|
>
|
||||||
>
|
{maybe(
|
||||||
{maybe(
|
() => labels.cancel,
|
||||||
() => labels.cancel,
|
intl.formatMessage(buttonMessages.back)
|
||||||
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"
|
>
|
||||||
>
|
{maybe(
|
||||||
{maybe(
|
() => labels.save,
|
||||||
() => labels.save,
|
intl.formatMessage(buttonMessages.save)
|
||||||
intl.formatMessage(buttonMessages.save)
|
)}
|
||||||
)}
|
</ConfirmButton>
|
||||||
</ConfirmButton>
|
</CardContent>
|
||||||
</CardContent>
|
</Card>
|
||||||
</Card>
|
</Container>
|
||||||
</Container>
|
</div>
|
||||||
</div>
|
</Portal>
|
||||||
)}
|
) : null;
|
||||||
</Portal>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
</AppActionContext.Consumer>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
SaveButtonBar.displayName = "SaveButtonBar";
|
SaveButtonBar.displayName = "SaveButtonBar";
|
||||||
export default SaveButtonBar;
|
export default SaveButtonBar;
|
||||||
|
|
Loading…
Reference in a new issue