mirror of https://github.com/fantasticit/think.git
client: optimize render actions
parent
a3b2e3d97d
commit
eef782f096
|
@ -1,5 +1,5 @@
|
|||
import { IconMore, IconPlus, IconStar } from '@douyinfe/semi-icons';
|
||||
import { Button, Dropdown, Space, Typography } from '@douyinfe/semi-ui';
|
||||
import { Button, Dropdown, Popover, Space, Typography } from '@douyinfe/semi-ui';
|
||||
import { DocumentCreator } from 'components/document/create';
|
||||
import { DocumentDeletor } from 'components/document/delete';
|
||||
import { DocumentLinkCopyer } from 'components/document/link';
|
||||
|
@ -29,22 +29,40 @@ export const DocumentActions: React.FC<IProps> = ({
|
|||
showCreateDocument,
|
||||
children,
|
||||
}) => {
|
||||
const [visible, toggleVisible] = useToggle(false);
|
||||
const [popoverVisible, togglePopoverVisible] = useToggle(false);
|
||||
const [createVisible, toggleCreateVisible] = useToggle(false);
|
||||
|
||||
const prevent = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}, []);
|
||||
const create = useCallback(() => {
|
||||
togglePopoverVisible(false);
|
||||
toggleCreateVisible(true);
|
||||
}, [togglePopoverVisible, toggleCreateVisible]);
|
||||
|
||||
const wrapedOnDelete = useCallback(() => {
|
||||
togglePopoverVisible(false);
|
||||
onDelete && onDelete();
|
||||
}, [onDelete, togglePopoverVisible]);
|
||||
|
||||
const wrapOnVisibleChange = useCallback(
|
||||
(visible) => {
|
||||
togglePopoverVisible(visible);
|
||||
onVisibleChange && onVisibleChange();
|
||||
},
|
||||
[onVisibleChange, togglePopoverVisible]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dropdown
|
||||
onVisibleChange={onVisibleChange}
|
||||
render={
|
||||
<Popover
|
||||
showArrow
|
||||
style={{ padding: 0 }}
|
||||
trigger="click"
|
||||
visible={popoverVisible}
|
||||
onVisibleChange={wrapOnVisibleChange}
|
||||
content={
|
||||
<Dropdown.Menu>
|
||||
{showCreateDocument && (
|
||||
<Dropdown.Item onClick={prevent}>
|
||||
<Text onClick={toggleVisible}>
|
||||
<Dropdown.Item onClick={create}>
|
||||
<Text>
|
||||
<Space>
|
||||
<IconPlus />
|
||||
新建子文档
|
||||
|
@ -52,15 +70,16 @@ export const DocumentActions: React.FC<IProps> = ({
|
|||
</Text>
|
||||
</Dropdown.Item>
|
||||
)}
|
||||
<Dropdown.Item onClick={prevent}>
|
||||
|
||||
<DocumentStar
|
||||
documentId={documentId}
|
||||
render={({ star, toggleStar, text }) => (
|
||||
<Text
|
||||
<Dropdown.Item
|
||||
onClick={() => {
|
||||
toggleStar().then(onStar);
|
||||
}}
|
||||
>
|
||||
<Text>
|
||||
<Space>
|
||||
<IconStar
|
||||
style={{
|
||||
|
@ -70,27 +89,40 @@ export const DocumentActions: React.FC<IProps> = ({
|
|||
{text}
|
||||
</Space>
|
||||
</Text>
|
||||
</Dropdown.Item>
|
||||
)}
|
||||
/>
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Item onClick={prevent}>
|
||||
<DocumentLinkCopyer wikiId={wikiId} documentId={documentId} />
|
||||
</Dropdown.Item>
|
||||
|
||||
<DocumentLinkCopyer
|
||||
wikiId={wikiId}
|
||||
documentId={documentId}
|
||||
render={({ copy, children }) => {
|
||||
return <Dropdown.Item onClick={copy}>{children}</Dropdown.Item>;
|
||||
}}
|
||||
/>
|
||||
|
||||
<Dropdown.Divider />
|
||||
<Dropdown.Item onClick={prevent}>
|
||||
<DocumentDeletor wikiId={wikiId} documentId={documentId} onDelete={onDelete} />
|
||||
</Dropdown.Item>
|
||||
|
||||
<DocumentDeletor
|
||||
wikiId={wikiId}
|
||||
documentId={documentId}
|
||||
onDelete={wrapedOnDelete}
|
||||
render={({ children }) => {
|
||||
return <Dropdown.Item>{children}</Dropdown.Item>;
|
||||
}}
|
||||
/>
|
||||
</Dropdown.Menu>
|
||||
}
|
||||
>
|
||||
{children || <Button onClick={prevent} icon={<IconMore />} theme="borderless" type="tertiary" />}
|
||||
</Dropdown>
|
||||
{children || <Button icon={<IconMore />} theme="borderless" type="tertiary" />}
|
||||
</Popover>
|
||||
|
||||
{showCreateDocument && (
|
||||
<DocumentCreator
|
||||
wikiId={wikiId}
|
||||
parentDocumentId={documentId}
|
||||
visible={visible}
|
||||
toggleVisible={toggleVisible}
|
||||
visible={createVisible}
|
||||
toggleVisible={toggleCreateVisible}
|
||||
onCreate={onCreate}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -1,28 +1,25 @@
|
|||
import { IconDelete } from '@douyinfe/semi-icons';
|
||||
import { Modal, Space, Typography } from '@douyinfe/semi-ui';
|
||||
import { Modal, Popconfirm, Space, Typography } from '@douyinfe/semi-ui';
|
||||
import { useDeleteDocument } from 'data/document';
|
||||
import { useRouterQuery } from 'hooks/use-router-query';
|
||||
import Router from 'next/router';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
|
||||
interface IProps {
|
||||
wikiId: string;
|
||||
documentId: string;
|
||||
onDelete?: () => void;
|
||||
render?: (arg: { children: React.ReactNode }) => React.ReactNode;
|
||||
}
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
export const DocumentDeletor: React.FC<IProps> = ({ wikiId, documentId, onDelete }) => {
|
||||
export const DocumentDeletor: React.FC<IProps> = ({ wikiId, documentId, render, onDelete }) => {
|
||||
const { wikiId: currentWikiId, documentId: currentDocumentId } =
|
||||
useRouterQuery<{ wikiId?: string; documentId?: string }>();
|
||||
const { deleteDocument: api, loading } = useDeleteDocument(documentId);
|
||||
|
||||
const deleteAction = useCallback(() => {
|
||||
Modal.error({
|
||||
title: '确定删除吗?',
|
||||
content: <Text>文档删除后不可恢复!</Text>,
|
||||
onOk: () => {
|
||||
api().then(() => {
|
||||
const navigate = () => {
|
||||
if (wikiId !== currentWikiId || documentId !== currentDocumentId) {
|
||||
|
@ -35,18 +32,30 @@ export const DocumentDeletor: React.FC<IProps> = ({ wikiId, documentId, onDelete
|
|||
|
||||
onDelete ? onDelete() : navigate();
|
||||
});
|
||||
},
|
||||
okButtonProps: { loading, type: 'danger' },
|
||||
style: { maxWidth: '96vw' },
|
||||
});
|
||||
}, [wikiId, documentId, api, loading, onDelete, currentWikiId, currentDocumentId]);
|
||||
}, [wikiId, documentId, api, onDelete, currentWikiId, currentDocumentId]);
|
||||
|
||||
return (
|
||||
<Text type="danger" onClick={deleteAction}>
|
||||
const content = useMemo(
|
||||
() => (
|
||||
<Text type="danger">
|
||||
<Space>
|
||||
<IconDelete />
|
||||
删除
|
||||
</Space>
|
||||
</Text>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<Popconfirm
|
||||
title="确定删除吗?"
|
||||
content="文档删除后不可恢复!"
|
||||
onConfirm={deleteAction}
|
||||
okButtonProps={{ loading }}
|
||||
zIndex={1070}
|
||||
showArrow
|
||||
>
|
||||
{render ? render({ children: content }) : content}
|
||||
</Popconfirm>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -7,21 +7,28 @@ import React, { useCallback } from 'react';
|
|||
interface IProps {
|
||||
wikiId: string;
|
||||
documentId: string;
|
||||
render?: (arg: { copy: () => void; children: React.ReactNode }) => React.ReactNode;
|
||||
}
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
export const DocumentLinkCopyer: React.FC<IProps> = ({ wikiId, documentId }) => {
|
||||
export const DocumentLinkCopyer: React.FC<IProps> = ({ wikiId, documentId, render }) => {
|
||||
const handle = useCallback(() => {
|
||||
copy(buildUrl(`/wiki/${wikiId}/document/${documentId}`));
|
||||
}, [wikiId, documentId]);
|
||||
|
||||
return (
|
||||
<Text onClick={handle} style={{ cursor: 'pointer' }}>
|
||||
const content = (
|
||||
<Space>
|
||||
<IconLink />
|
||||
复制链接
|
||||
</Space>
|
||||
);
|
||||
|
||||
return render ? (
|
||||
<>{render({ copy: handle, children: content })}</>
|
||||
) : (
|
||||
<Text onClick={handle} style={{ cursor: 'pointer' }}>
|
||||
{content}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue