client: fix client ui

pull/180/head
fantasticit 2022-08-29 11:39:28 +08:00
parent 4906703e40
commit f37e054a6e
7 changed files with 34 additions and 71 deletions

View File

@ -105,7 +105,7 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId, di
<AvatarGroup maxCount={2} renderMore={renderMore} size="extra-small"> <AvatarGroup maxCount={2} renderMore={renderMore} size="extra-small">
{collaborationUsers.map((user) => { {collaborationUsers.map((user) => {
return ( return (
<Tooltip key={user.id} content={`${user.name}-${user.clientId}`} position="bottom"> <Tooltip key={user.clientId} content={`${user.name}-${user.clientId}`} position="bottom">
<Avatar src={user.avatar} size="extra-small"> <Avatar src={user.avatar} size="extra-small">
{user.name && user.name.charAt(0)} {user.name && user.name.charAt(0)}
</Avatar> </Avatar>

View File

@ -4,20 +4,18 @@ import { IDocument } from '@think/domains';
import cls from 'classnames'; import cls from 'classnames';
import { DataRender } from 'components/data-render'; import { DataRender } from 'components/data-render';
import { IconOverview, IconSetting } from 'components/icons'; import { IconOverview, IconSetting } from 'components/icons';
import { findParents } from 'components/wiki/tocs/utils';
import { useStarDocumentsInWiki, useStarWikisInOrganization } from 'data/star'; import { useStarDocumentsInWiki, useStarWikisInOrganization } from 'data/star';
import { useWikiDetail, useWikiTocs } from 'data/wiki'; import { useWikiDetail, useWikiTocs } from 'data/wiki';
import { triggerCreateDocument } from 'event'; import { triggerCreateDocument } from 'event';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from 'react'; import { useMemo } from 'react';
import styles from './index.module.scss'; import styles from './index.module.scss';
import { Tree } from './tree'; import { Tree } from './tree';
interface IProps { interface IProps {
wikiId: string; wikiId: string;
documentId?: string;
docAsLink?: string; docAsLink?: string;
getDocLink?: (arg: IDocument) => string; getDocLink?: (arg: IDocument) => string;
} }
@ -26,7 +24,6 @@ const { Text } = Typography;
export const WikiTocs: React.FC<IProps> = ({ export const WikiTocs: React.FC<IProps> = ({
wikiId, wikiId,
documentId = null,
docAsLink = '/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]', docAsLink = '/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]',
getDocLink = (document) => `/app/org/${document.organizationId}/wiki/${document.wikiId}/doc/${document.id}`, getDocLink = (document) => `/app/org/${document.organizationId}/wiki/${document.wikiId}/doc/${document.id}`,
}) => { }) => {
@ -39,15 +36,8 @@ export const WikiTocs: React.FC<IProps> = ({
loading: starDocumentsLoading, loading: starDocumentsLoading,
error: starDocumentsError, error: starDocumentsError,
} = useStarDocumentsInWiki(query.organizationId, wikiId); } = useStarDocumentsInWiki(query.organizationId, wikiId);
const [parentIds, setParentIds] = useState<Array<string>>([]);
const otherStarWikis = useMemo(() => (starWikis || []).filter((wiki) => wiki.id !== wikiId), [starWikis, wikiId]); const otherStarWikis = useMemo(() => (starWikis || []).filter((wiki) => wiki.id !== wikiId), [starWikis, wikiId]);
useEffect(() => {
if (!tocs || !tocs.length) return;
const parentIds = findParents(tocs, documentId);
setParentIds(parentIds);
}, [tocs, documentId]);
return ( return (
<div className={styles.wrap}> <div className={styles.wrap}>
<header> <header>
@ -276,15 +266,7 @@ export const WikiTocs: React.FC<IProps> = ({
<DataRender <DataRender
loading={starDocumentsLoading} loading={starDocumentsLoading}
error={starDocumentsError} error={starDocumentsError}
normalContent={() => ( normalContent={() => <Tree data={starDocuments || []} docAsLink={docAsLink} getDocLink={getDocLink} />}
<Tree
data={starDocuments || []}
docAsLink={docAsLink}
getDocLink={getDocLink}
parentIds={parentIds}
activeId={documentId}
/>
)}
/> />
</div> </div>
@ -315,14 +297,7 @@ export const WikiTocs: React.FC<IProps> = ({
loading={tocsLoading} loading={tocsLoading}
error={tocsError} error={tocsError}
normalContent={() => ( normalContent={() => (
<Tree <Tree needAddDocument data={tocs || []} docAsLink={docAsLink} getDocLink={getDocLink} />
needAddDocument
data={tocs || []}
docAsLink={docAsLink}
getDocLink={getDocLink}
parentIds={parentIds}
activeId={documentId}
/>
)} )}
/> />
</div> </div>

View File

@ -5,10 +5,9 @@ import { DataRender } from 'components/data-render';
import { IconOverview } from 'components/icons'; import { IconOverview } from 'components/icons';
import { LogoImage, LogoText } from 'components/logo'; import { LogoImage, LogoText } from 'components/logo';
import { Seo } from 'components/seo'; import { Seo } from 'components/seo';
import { findParents } from 'components/wiki/tocs/utils';
import { usePublicWikiDetail, usePublicWikiTocs } from 'data/wiki'; import { usePublicWikiDetail, usePublicWikiTocs } from 'data/wiki';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react'; import React from 'react';
import styles from './index.module.scss'; import styles from './index.module.scss';
import { NavItem } from './nav-item'; import { NavItem } from './nav-item';
@ -16,7 +15,6 @@ import { Tree } from './tree';
interface IProps { interface IProps {
wikiId: string; wikiId: string;
documentId?: string;
docAsLink?: string; docAsLink?: string;
getDocLink?: (arg: IDocument) => string; getDocLink?: (arg: IDocument) => string;
pageTitle: string; pageTitle: string;
@ -27,20 +25,12 @@ const { Text } = Typography;
export const WikiPublicTocs: React.FC<IProps> = ({ export const WikiPublicTocs: React.FC<IProps> = ({
pageTitle, pageTitle,
wikiId, wikiId,
documentId = null,
docAsLink = '/share/wiki/[wikiId]/document/[documentId]', docAsLink = '/share/wiki/[wikiId]/document/[documentId]',
getDocLink = (document) => `/share/wiki/${document.wikiId}/document/${document.id}`, getDocLink = (document) => `/share/wiki/${document.wikiId}/document/${document.id}`,
}) => { }) => {
const { pathname } = useRouter(); const { pathname } = useRouter();
const { data: wiki, loading: wikiLoading, error: wikiError } = usePublicWikiDetail(wikiId); const { data: wiki, loading: wikiLoading, error: wikiError } = usePublicWikiDetail(wikiId);
const { data: tocs, loading: tocsLoading, error: tocsError } = usePublicWikiTocs(wikiId); const { data: tocs, loading: tocsLoading, error: tocsError } = usePublicWikiTocs(wikiId);
const [parentIds, setParentIds] = useState<Array<string>>([]);
useEffect(() => {
if (!tocs || !tocs.length) return;
const parentIds = findParents(tocs, documentId);
setParentIds(parentIds);
}, [tocs, documentId]);
return ( return (
<div className={styles.wrap}> <div className={styles.wrap}>
@ -131,16 +121,7 @@ export const WikiPublicTocs: React.FC<IProps> = ({
/> />
} }
error={tocsError} error={tocsError}
normalContent={() => ( normalContent={() => <Tree data={tocs || []} docAsLink={docAsLink} getDocLink={getDocLink} isShareMode />}
<Tree
data={tocs || []}
docAsLink={docAsLink}
getDocLink={getDocLink}
parentIds={parentIds}
activeId={documentId}
isShareMode
/>
)}
/> />
</div> </div>
</main> </main>

View File

@ -2,13 +2,16 @@ import { IconPlus } from '@douyinfe/semi-icons';
import { Button, Tree as SemiTree, Typography } from '@douyinfe/semi-ui'; import { Button, Tree as SemiTree, Typography } from '@douyinfe/semi-ui';
import { DocumentActions } from 'components/document/actions'; import { DocumentActions } from 'components/document/actions';
import { DocumentCreator as DocumenCreatorForm } from 'components/document/create'; import { DocumentCreator as DocumenCreatorForm } from 'components/document/create';
import deepEqual from 'deep-equal';
import { CREATE_DOCUMENT, event, triggerCreateDocument } from 'event'; import { CREATE_DOCUMENT, event, triggerCreateDocument } from 'event';
import { useToggle } from 'hooks/use-toggle'; import { useToggle } from 'hooks/use-toggle';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router';
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import scrollIntoView from 'scroll-into-view-if-needed'; import scrollIntoView from 'scroll-into-view-if-needed';
import styles from './index.module.scss'; import styles from './index.module.scss';
import { findParents } from './utils';
const Actions = ({ node }) => { const Actions = ({ node }) => {
return ( return (
@ -67,17 +70,16 @@ const AddDocument = () => {
let scrollTimer; let scrollTimer;
export const Tree = ({ export const _Tree = ({ data, docAsLink, getDocLink, isShareMode = false, needAddDocument = false }) => {
data, const { query } = useRouter();
docAsLink,
getDocLink,
parentIds,
activeId,
isShareMode = false,
needAddDocument = false,
}) => {
const $container = useRef<HTMLDivElement>(null); const $container = useRef<HTMLDivElement>(null);
const [expandedKeys, setExpandedKeys] = useState(parentIds); const [expandedKeys, setExpandedKeys] = useState([]);
useEffect(() => {
if (!data || !data.length) return;
const parentIds = findParents(data, query.documentId as string);
setExpandedKeys(parentIds);
}, [data, query.documentId]);
const renderBtn = useCallback((node) => <Actions key={node.id} node={node} />, []); const renderBtn = useCallback((node) => <Actions key={node.id} node={node} />, []);
@ -103,12 +105,7 @@ export const Tree = ({
); );
useEffect(() => { useEffect(() => {
if (!parentIds || !parentIds.length) return; const target = $container.current.querySelector(`#item-${query.documentId}`);
setExpandedKeys(parentIds);
}, [parentIds]);
useEffect(() => {
const target = $container.current.querySelector(`#item-${activeId}`);
if (!target) return; if (!target) return;
clearTimeout(scrollTimer); clearTimeout(scrollTimer);
scrollTimer = setTimeout(() => { scrollTimer = setTimeout(() => {
@ -121,15 +118,15 @@ export const Tree = ({
return () => { return () => {
clearTimeout(scrollTimer); clearTimeout(scrollTimer);
}; };
}, [activeId]); }, [query.documentId]);
return ( return (
<div className={styles.treeInnerWrap} ref={$container}> <div className={styles.treeInnerWrap} ref={$container}>
<SemiTree <SemiTree
treeData={data} treeData={data}
renderLabel={renderLabel} renderLabel={renderLabel}
value={activeId} value={query.documentId}
defaultExpandedKeys={parentIds} defaultExpandedKeys={expandedKeys}
expandedKeys={expandedKeys} expandedKeys={expandedKeys}
onExpand={(expandedKeys) => setExpandedKeys(expandedKeys)} onExpand={(expandedKeys) => setExpandedKeys(expandedKeys)}
/> />
@ -137,3 +134,11 @@ export const Tree = ({
</div> </div>
); );
}; };
export const Tree = React.memo(_Tree, (prevProps, nextProps) => {
if (deepEqual(prevProps.data, nextProps.data)) {
return true;
}
return false;
});

View File

@ -16,7 +16,7 @@ interface IProps {
const Page: NextPage<IProps> = ({ wikiId, documentId }) => { const Page: NextPage<IProps> = ({ wikiId, documentId }) => {
return ( return (
<AppDoubleColumnLayout <AppDoubleColumnLayout
leftNode={<WikiTocs wikiId={wikiId} documentId={documentId} />} leftNode={<WikiTocs wikiId={wikiId} />}
rightNode={<DocumentReader key={documentId} documentId={documentId} />} rightNode={<DocumentReader key={documentId} documentId={documentId} />}
/> />
); );

View File

@ -16,7 +16,7 @@ interface IProps {
const Page: NextPage<IProps> = ({ wikiId, documentId }) => { const Page: NextPage<IProps> = ({ wikiId, documentId }) => {
return ( return (
<PublicDoubleColumnLayout <PublicDoubleColumnLayout
leftNode={<WikiPublicTocs pageTitle="概览" wikiId={wikiId} documentId={documentId} />} leftNode={<WikiPublicTocs pageTitle="概览" wikiId={wikiId} />}
rightNode={<DocumentPublicReader key={documentId} documentId={documentId} hideLogo />} rightNode={<DocumentPublicReader key={documentId} documentId={documentId} hideLogo />}
></PublicDoubleColumnLayout> ></PublicDoubleColumnLayout>
); );

View File

@ -14,6 +14,7 @@ import { DocumentChildren } from 'tiptap/core/extensions/document-children';
import { DocumentReference } from 'tiptap/core/extensions/document-reference'; import { DocumentReference } from 'tiptap/core/extensions/document-reference';
import { Dropcursor } from 'tiptap/core/extensions/dropcursor'; import { Dropcursor } from 'tiptap/core/extensions/dropcursor';
import { Emoji } from 'tiptap/core/extensions/emoji'; import { Emoji } from 'tiptap/core/extensions/emoji';
import { Excalidraw } from 'tiptap/core/extensions/excalidraw';
import { Flow } from 'tiptap/core/extensions/flow'; import { Flow } from 'tiptap/core/extensions/flow';
import { Focus } from 'tiptap/core/extensions/focus'; import { Focus } from 'tiptap/core/extensions/focus';
import { FontSize } from 'tiptap/core/extensions/font-size'; import { FontSize } from 'tiptap/core/extensions/font-size';
@ -73,6 +74,7 @@ export const AllExtensions = [
Color, Color,
ColorHighlighter, ColorHighlighter,
Dropcursor, Dropcursor,
Excalidraw,
Focus, Focus,
FontSize, FontSize,
Gapcursor, Gapcursor,