mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 12:56:41 +07:00
removed all router-modals
This commit is contained in:
parent
85d20e5009
commit
ffce400398
15 changed files with 99 additions and 143 deletions
|
@ -1,30 +1,19 @@
|
|||
import React, { FC, useCallback, useMemo, useRef } from 'react';
|
||||
import { EMPTY_NODE, NODE_TYPES } from '~/constants/node';
|
||||
import { EditorDialog } from '~/containers/dialogs/EditorDialog';
|
||||
import { useHistory, useRouteMatch } from 'react-router';
|
||||
import { values } from 'ramda';
|
||||
import { INode } from '~/types';
|
||||
import { useCreateNode } from '~/hooks/node/useCreateNode';
|
||||
import { DialogComponentProps } from '~/types/modal';
|
||||
|
||||
const EditorCreateDialog: FC = () => {
|
||||
const history = useHistory();
|
||||
const {
|
||||
params: { type },
|
||||
url,
|
||||
} = useRouteMatch<{ type: string }>();
|
||||
|
||||
const backUrl = useMemo(() => {
|
||||
return (url && url.replace(/\/create\/(.*)$/, '')) || '/';
|
||||
}, [url]);
|
||||
|
||||
const goBack = useCallback(() => {
|
||||
history.replace(backUrl);
|
||||
}, [backUrl, history]);
|
||||
export interface EditorCreateDialogProps extends DialogComponentProps {
|
||||
type: typeof NODE_TYPES[keyof typeof NODE_TYPES];
|
||||
isInLab: boolean;
|
||||
}
|
||||
|
||||
const EditorCreateDialog: FC<EditorCreateDialogProps> = ({ type, isInLab, onRequestClose }) => {
|
||||
const isExist = useMemo(() => values(NODE_TYPES).some(el => el === type), [type]);
|
||||
|
||||
const isInLab = useMemo(() => !!url.match(/^\/lab/), [url]);
|
||||
|
||||
const data = useRef({ ...EMPTY_NODE, type, is_promoted: !isInLab });
|
||||
|
||||
const createNode = useCreateNode();
|
||||
|
@ -32,16 +21,16 @@ const EditorCreateDialog: FC = () => {
|
|||
const onSubmit = useCallback(
|
||||
async (node: INode) => {
|
||||
await createNode(node);
|
||||
goBack();
|
||||
onRequestClose();
|
||||
},
|
||||
[goBack, createNode]
|
||||
[onRequestClose, createNode]
|
||||
);
|
||||
|
||||
if (!type || !isExist) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <EditorDialog node={data.current} onRequestClose={goBack} onSubmit={onSubmit} />;
|
||||
return <EditorDialog node={data.current} onRequestClose={onRequestClose} onSubmit={onSubmit} />;
|
||||
};
|
||||
|
||||
export { EditorCreateDialog };
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { createElement, FC, useCallback, useMemo, useState } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { NODE_EDITORS } from '~/constants/node';
|
||||
import { BetterScrollDialog } from '../../../components/dialogs/BetterScrollDialog';
|
||||
import { BetterScrollDialog } from '~/components/dialogs/BetterScrollDialog';
|
||||
import { CoverBackdrop } from '~/components/containers/CoverBackdrop';
|
||||
import { prop } from 'ramda';
|
||||
import { useNodeFormFormik } from '~/hooks/node/useNodeFormFormik';
|
||||
|
@ -9,8 +9,6 @@ import { EditorButtons } from '~/components/editors/EditorButtons';
|
|||
import { UploadSubject, UploadTarget } from '~/constants/uploads';
|
||||
import { FormikProvider } from 'formik';
|
||||
import { INode } from '~/types';
|
||||
import { ModalWrapper } from '~/components/dialogs/ModalWrapper';
|
||||
import { useTranslatedError } from '~/hooks/data/useTranslatedError';
|
||||
import { useCloseOnEscape } from '~/hooks';
|
||||
import { EditorConfirmClose } from '~/components/editors/EditorConfirmClose';
|
||||
import { DialogComponentProps } from '~/types/modal';
|
||||
|
@ -50,8 +48,6 @@ const EditorDialog: FC<Props> = observer(({ node, onRequestClose, onSubmit }) =>
|
|||
setConfirmModalShown(true);
|
||||
}, [dirty, isConfirmModalShown, onRequestClose, closeConfirmModal]);
|
||||
|
||||
const error = useTranslatedError(status);
|
||||
|
||||
useCloseOnEscape(onClose);
|
||||
|
||||
if (!component) {
|
||||
|
@ -59,29 +55,26 @@ const EditorDialog: FC<Props> = observer(({ node, onRequestClose, onSubmit }) =>
|
|||
}
|
||||
|
||||
return (
|
||||
<ModalWrapper onOverlayClick={onClose}>
|
||||
<UploaderContextProvider value={uploader}>
|
||||
<FormikProvider value={formik}>
|
||||
<form onSubmit={handleSubmit} className={styles.form}>
|
||||
<BetterScrollDialog
|
||||
footer={<EditorButtons />}
|
||||
backdrop={<CoverBackdrop cover={values.cover} />}
|
||||
width={860}
|
||||
error={error}
|
||||
onClose={onClose}
|
||||
>
|
||||
<>
|
||||
{isConfirmModalShown && (
|
||||
<EditorConfirmClose onApprove={onRequestClose} onDecline={closeConfirmModal} />
|
||||
)}
|
||||
<UploaderContextProvider value={uploader}>
|
||||
<FormikProvider value={formik}>
|
||||
<form onSubmit={handleSubmit} className={styles.form}>
|
||||
<BetterScrollDialog
|
||||
footer={<EditorButtons />}
|
||||
backdrop={<CoverBackdrop cover={values.cover} />}
|
||||
width={860}
|
||||
onClose={onClose}
|
||||
>
|
||||
<>
|
||||
{isConfirmModalShown && (
|
||||
<EditorConfirmClose onApprove={onRequestClose} onDecline={closeConfirmModal} />
|
||||
)}
|
||||
|
||||
<div className={styles.editor}>{createElement(component)}</div>
|
||||
</>
|
||||
</BetterScrollDialog>
|
||||
</form>
|
||||
</FormikProvider>
|
||||
</UploaderContextProvider>
|
||||
</ModalWrapper>
|
||||
<div className={styles.editor}>{createElement(component)}</div>
|
||||
</>
|
||||
</BetterScrollDialog>
|
||||
</form>
|
||||
</FormikProvider>
|
||||
</UploaderContextProvider>
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { FC, useCallback, useMemo } from 'react';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import { EditorDialog } from '~/containers/dialogs/EditorDialog';
|
||||
import { useHistory, useRouteMatch } from 'react-router';
|
||||
import { ModalWrapper } from '~/components/dialogs/ModalWrapper';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import styles from './styles.module.scss';
|
||||
|
@ -8,37 +7,27 @@ import { useLoadNode } from '~/hooks/node/useLoadNode';
|
|||
import { useUpdateNode } from '~/hooks/node/useUpdateNode';
|
||||
import { INode } from '~/types';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { DialogComponentProps } from '~/types/modal';
|
||||
|
||||
const EditorEditDialog: FC = observer(() => {
|
||||
const history = useHistory();
|
||||
export interface EditorEditDialogProps extends DialogComponentProps {
|
||||
nodeId: number;
|
||||
}
|
||||
|
||||
const {
|
||||
params: { id },
|
||||
url,
|
||||
} = useRouteMatch<{ id: string }>();
|
||||
|
||||
const backUrl = useMemo(() => {
|
||||
return url.replace(/\/edit$/, '');
|
||||
}, [url]);
|
||||
|
||||
const goBack = useCallback(() => {
|
||||
history.replace(backUrl);
|
||||
}, [backUrl, history]);
|
||||
|
||||
const { node, isLoading } = useLoadNode(parseInt(id, 10));
|
||||
const updateNode = useUpdateNode(parseInt(id, 10));
|
||||
const EditorEditDialog: FC<EditorEditDialogProps> = observer(({ nodeId, onRequestClose }) => {
|
||||
const { node, isLoading } = useLoadNode(nodeId);
|
||||
const updateNode = useUpdateNode(nodeId);
|
||||
|
||||
const onSubmit = useCallback(
|
||||
async (node: INode) => {
|
||||
await updateNode(node);
|
||||
goBack();
|
||||
onRequestClose();
|
||||
},
|
||||
[updateNode, goBack]
|
||||
[updateNode, onRequestClose]
|
||||
);
|
||||
|
||||
if (isLoading || !node) {
|
||||
return (
|
||||
<ModalWrapper onOverlayClick={goBack}>
|
||||
<ModalWrapper onOverlayClick={onRequestClose}>
|
||||
<div className={styles.loader}>
|
||||
<LoaderCircle size={64} />
|
||||
</div>
|
||||
|
@ -46,7 +35,7 @@ const EditorEditDialog: FC = observer(() => {
|
|||
);
|
||||
}
|
||||
|
||||
return <EditorDialog node={node} onRequestClose={goBack} onSubmit={onSubmit} />;
|
||||
return <EditorDialog node={node} onRequestClose={onRequestClose} onSubmit={onSubmit} />;
|
||||
});
|
||||
|
||||
export { EditorEditDialog };
|
||||
|
|
|
@ -4,7 +4,6 @@ import { Route, Switch } from 'react-router';
|
|||
import { TagSidebar } from '~/containers/sidebars/TagSidebar';
|
||||
import { Authorized } from '~/components/containers/Authorized';
|
||||
import { SubmitBar } from '~/components/bars/SubmitBar';
|
||||
import { EditorCreateDialog } from '~/containers/dialogs/EditorCreateDialog';
|
||||
|
||||
interface IProps {
|
||||
prefix?: string;
|
||||
|
@ -13,16 +12,9 @@ interface IProps {
|
|||
|
||||
const SidebarRouter: FC<IProps> = ({ prefix = '', isLab }) => {
|
||||
return createPortal(
|
||||
<>
|
||||
<Switch>
|
||||
<Route path={`${prefix}/create/:type`} component={EditorCreateDialog} />
|
||||
<Route path={`${prefix}/tag/:tag`} component={TagSidebar} />
|
||||
</Switch>
|
||||
|
||||
<Authorized>
|
||||
<SubmitBar isLab={isLab} />
|
||||
</Authorized>
|
||||
</>,
|
||||
<Authorized>
|
||||
<SubmitBar isLab={isLab} />
|
||||
</Authorized>,
|
||||
document.body
|
||||
);
|
||||
};
|
||||
|
|
|
@ -20,13 +20,10 @@ const SidebarWrapper: FC<IProps> = ({ children, onClose }) => {
|
|||
return () => clearAllBodyScrollLocks();
|
||||
}, []);
|
||||
|
||||
return createPortal(
|
||||
return (
|
||||
<div className={styles.wrapper} ref={ref}>
|
||||
<div className={styles.clicker} onClick={onClose} />
|
||||
|
||||
{children}
|
||||
</div>,
|
||||
document.body
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -10,9 +10,6 @@
|
|||
}
|
||||
|
||||
.wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
@ -22,19 +19,7 @@
|
|||
overflow: hidden;
|
||||
animation: appear 0.25s forwards;
|
||||
|
||||
@include sidebar;
|
||||
|
||||
& > * {
|
||||
z-index: 4;
|
||||
}
|
||||
}
|
||||
|
||||
.clicker {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useCallback, useMemo, VFC } from 'react';
|
||||
import React, { useMemo, VFC } from 'react';
|
||||
import { SidebarWrapper } from '~/containers/sidebars/SidebarWrapper';
|
||||
import styles from './styles.module.scss';
|
||||
import { useHistory, useRouteMatch } from 'react-router';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { TagSidebarList } from '~/components/sidebar/TagSidebarList';
|
||||
|
@ -9,21 +8,18 @@ import { LoaderCircle } from '~/components/input/LoaderCircle';
|
|||
import { InfiniteScroll } from '~/components/containers/InfiniteScroll';
|
||||
import { Tag } from '~/components/tags/Tag';
|
||||
import { useTagNodes } from '~/hooks/tag/useTagNodes';
|
||||
import { DialogComponentProps } from '~/types/modal';
|
||||
|
||||
const TagSidebar: VFC = () => {
|
||||
const {
|
||||
params: { tag },
|
||||
url,
|
||||
} = useRouteMatch<{ tag: string }>();
|
||||
const history = useHistory();
|
||||
interface TagSidebarProps extends DialogComponentProps {
|
||||
tag: string;
|
||||
}
|
||||
|
||||
const basePath = url.replace(new RegExp(`/tag/${tag}$`), '');
|
||||
const onClose = useCallback(() => history.push(basePath), [basePath, history]);
|
||||
const TagSidebar: VFC<TagSidebarProps> = ({ tag, onRequestClose }) => {
|
||||
const { nodes, hasMore, isLoading, loadMore } = useTagNodes(tag);
|
||||
const title = useMemo(() => decodeURIComponent(tag), [tag]);
|
||||
|
||||
return (
|
||||
<SidebarWrapper onClose={onClose}>
|
||||
<SidebarWrapper onClose={onRequestClose}>
|
||||
<div className={styles.wrap}>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.head}>
|
||||
|
@ -38,9 +34,9 @@ const TagSidebar: VFC = () => {
|
|||
)}
|
||||
|
||||
<div className={styles.close}>
|
||||
<Link to={basePath}>
|
||||
<button onClick={onRequestClose}>
|
||||
<Icon icon="close" size={32} />
|
||||
</Link>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue