mirror of https://github.com/fantasticit/think.git
client: fix client ui
parent
4906703e40
commit
f37e054a6e
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
});
|
||||||
|
|
|
@ -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} />}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue