Merge pull request #180 from fantasticit/fix/0829

pull/183/head
fantasticit 2022-08-29 13:16:38 +08:00 committed by GitHub
commit bc1e8a5802
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 137 additions and 206 deletions

View File

@ -3,7 +3,7 @@
"private": true, "private": true,
"author": "fantasticit", "author": "fantasticit",
"scripts": { "scripts": {
"clean": "npx rimraf ./node_modules ./packages/**/node_modules", "clean": "npx rimraf ./node_modules ./packages/**/node_modules ./packages/**/.next",
"dev": "concurrently 'pnpm:dev:*'", "dev": "concurrently 'pnpm:dev:*'",
"dev:server": "pnpm run --dir packages/server dev", "dev:server": "pnpm run --dir packages/server dev",
"dev:client": "pnpm run --dir packages/client dev", "dev:client": "pnpm run --dir packages/client dev",

View File

@ -8,9 +8,9 @@
"pm2": "pm2 start npm --name @think/client -- start" "pm2": "pm2 start npm --name @think/client -- start"
}, },
"dependencies": { "dependencies": {
"@douyinfe/semi-icons": "^2.3.1", "@douyinfe/semi-icons": "^2.18.0",
"@douyinfe/semi-next": "^2.3.1", "@douyinfe/semi-next": "^2.18.0",
"@douyinfe/semi-ui": "^2.3.1", "@douyinfe/semi-ui": "^2.18.0",
"@excalidraw/excalidraw": "^0.12.0", "@excalidraw/excalidraw": "^0.12.0",
"@hocuspocus/provider": "^1.0.0-alpha.29", "@hocuspocus/provider": "^1.0.0-alpha.29",
"@react-pdf-viewer/core": "3.7.0", "@react-pdf-viewer/core": "3.7.0",
@ -63,10 +63,8 @@
"clone": "^2.1.2", "clone": "^2.1.2",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"deep-equal": "^2.0.5", "deep-equal": "^2.0.5",
"docx": "^7.3.0",
"dompurify": "^2.3.5", "dompurify": "^2.3.5",
"downloadjs": "^1.4.7", "downloadjs": "^1.4.7",
"html-to-docx": "^1.4.0",
"htmldiff-js": "^1.0.5", "htmldiff-js": "^1.0.5",
"interactjs": "^1.10.11", "interactjs": "^1.10.11",
"katex": "^0.15.2", "katex": "^0.15.2",

View File

@ -169,24 +169,6 @@ export const DocumentActions: React.FC<IProps> = ({
/> />
)} )}
{!hideDocumentVersion && (
<DocumentStyle
key="style"
render={({ onClick }) => {
return (
<Dropdown.Item onClick={onClick}>
<Text>
<Space>
<IconArticle />
</Space>
</Text>
</Dropdown.Item>
);
}}
/>
)}
{document && ( {document && (
<DocumentExporter <DocumentExporter
document={document} document={document}

View File

@ -1,12 +1,12 @@
import { IconUserAdd } from '@douyinfe/semi-icons'; import { IconUserAdd } from '@douyinfe/semi-icons';
import { Avatar, AvatarGroup, Button, Dropdown, Modal, Toast, Tooltip } from '@douyinfe/semi-ui'; import { Avatar, AvatarGroup, Button, Dropdown, Modal, Popover, Toast, Tooltip, Typography } from '@douyinfe/semi-ui';
import { Members } from 'components/members'; import { Members } from 'components/members';
import { useDoumentMembers } from 'data/document'; import { useDoumentMembers } from 'data/document';
import { useUser } from 'data/user'; import { useUser } from 'data/user';
import { event, JOIN_USER } from 'event'; import { event, JOIN_USER } from 'event';
import { IsOnMobile } from 'hooks/use-on-mobile'; import { IsOnMobile } from 'hooks/use-on-mobile';
import { useToggle } from 'hooks/use-toggle'; import { useToggle } from 'hooks/use-toggle';
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
interface IProps { interface IProps {
wikiId: string; wikiId: string;
@ -14,6 +14,8 @@ interface IProps {
disabled?: boolean; disabled?: boolean;
} }
const { Text } = Typography;
export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId, disabled = false }) => { export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId, disabled = false }) => {
const { isMobile } = IsOnMobile.useHook(); const { isMobile } = IsOnMobile.useHook();
const toastedUsersRef = useRef([]); const toastedUsersRef = useRef([]);
@ -42,6 +44,27 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId, di
[disabled, toggleVisible] [disabled, toggleVisible]
); );
const renderMore = useCallback((restNumber, restAvatars) => {
const content = restAvatars.map((avatar, index) => {
return (
<div style={{ paddingBottom: 12 }} key={index}>
{React.cloneElement(avatar, { size: 'extra-small' })}
<Text style={{ marginLeft: 8, fontSize: 14 }}>{avatar.props.content}</Text>
</div>
);
});
return (
<Popover
content={<div style={{ maxHeight: '50vh', overflow: 'auto' }}>{content}</div>}
autoAdjustOverflow={false}
position={'bottomRight'}
style={{ padding: '12px 8px', paddingBottom: 0 }}
>
<Avatar size="extra-small">{`+${restNumber}`}</Avatar>
</Popover>
);
}, []);
useEffect(() => { useEffect(() => {
const handler = (users) => { const handler = (users) => {
const joinUsers = users const joinUsers = users
@ -49,35 +72,40 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId, di
.filter((state) => state.user) .filter((state) => state.user)
.map((state) => ({ ...state.user, clientId: state.clientId })); .map((state) => ({ ...state.user, clientId: state.clientId }));
joinUsers const otherUsers = joinUsers
.filter(Boolean) .filter(Boolean)
.filter((joinUser) => { .filter((joinUser) => {
return joinUser.name !== currentUser.name; return joinUser.name !== currentUser.name;
}) })
.forEach((joinUser) => { .filter((joinUser) => {
if (!toastedUsersRef.current.includes(joinUser.clientId)) { return !toastedUsersRef.current.includes(joinUser.clientId);
Toast.info(`${joinUser.name}-${joinUser.clientId}加入文档`);
toastedUsersRef.current.push(joinUser.clientId);
}
}); });
if (otherUsers.length) {
Toast.info(`${otherUsers[0].name}${otherUsers.length}个用户加入文档`);
otherUsers.forEach((joinUser) => {
toastedUsersRef.current.push(joinUser.clientId);
});
}
setCollaborationUsers(joinUsers); setCollaborationUsers(joinUsers);
}; };
event.on(JOIN_USER, handler); event.on(JOIN_USER, handler);
return () => { return () => {
toastedUsersRef.current = [];
event.off(JOIN_USER, handler); event.off(JOIN_USER, handler);
toastedUsersRef.current = [];
}; };
}, [currentUser]); }, [currentUser]);
return ( return (
<> <>
<AvatarGroup maxCount={5} 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

@ -2,7 +2,6 @@ import { IconEdit } from '@douyinfe/semi-icons';
import { Button, Layout, Nav, Skeleton, Space, Spin, Tooltip, Typography } from '@douyinfe/semi-ui'; import { Button, Layout, Nav, Skeleton, Space, Spin, Tooltip, Typography } from '@douyinfe/semi-ui';
import { DataRender } from 'components/data-render'; import { DataRender } from 'components/data-render';
import { DocumentCollaboration } from 'components/document/collaboration'; import { DocumentCollaboration } from 'components/document/collaboration';
import { DocumentShare } from 'components/document/share';
import { DocumentStar } from 'components/document/star'; import { DocumentStar } from 'components/document/star';
import { DocumentStyle } from 'components/document/style'; import { DocumentStyle } from 'components/document/style';
import { DocumentVersion } from 'components/document/version'; import { DocumentVersion } from 'components/document/version';
@ -37,6 +36,7 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
const { user } = useUser(); const { user } = useUser();
const { data: documentAndAuth, loading: docAuthLoading, error: docAuthError } = useDocumentDetail(documentId); const { data: documentAndAuth, loading: docAuthLoading, error: docAuthError } = useDocumentDetail(documentId);
const { document, authority } = documentAndAuth || {}; const { document, authority } = documentAndAuth || {};
const [readable, editable] = useMemo(() => { const [readable, editable] = useMemo(() => {
if (!authority) return [false, false]; if (!authority) return [false, false];
return [authority.readable, authority.editable]; return [authority.readable, authority.editable];
@ -84,6 +84,7 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
documentId={documentId} documentId={documentId}
/> />
)} )}
<DocumentStyle key="style" />
<Tooltip key="edit" content="编辑" position="bottom"> <Tooltip key="edit" content="编辑" position="bottom">
<Button disabled={!editable} icon={<IconEdit />} onMouseDown={gotoEdit} /> <Button disabled={!editable} icon={<IconEdit />} onMouseDown={gotoEdit} />
</Tooltip> </Tooltip>

View File

@ -32,14 +32,8 @@ export const DocumentStyle: React.FC<IProps> = ({ render }) => {
position={isMobile ? 'topRight' : 'bottomLeft'} position={isMobile ? 'topRight' : 'bottomLeft'}
visible={visible} visible={visible}
onVisibleChange={toggleVisible} onVisibleChange={toggleVisible}
onClickOutSide={toggleVisible}
content={ content={
<div <div className={styles.wrap}>
className={styles.wrap}
onClick={(e) => {
e.stopPropagation();
}}
>
<div className={styles.item}> <div className={styles.item}>
<Text></Text> <Text></Text>
<Text style={{ fontSize: '0.8em' }}> {fontSize}px</Text> <Text style={{ fontSize: '0.8em' }}> {fontSize}px</Text>

View File

@ -48,6 +48,7 @@
font-size: 14px; font-size: 14px;
cursor: pointer; cursor: pointer;
align-items: center; align-items: center;
color: var(--semi-color-text-0);
> span { > span {
margin-right: 6px; margin-right: 6px;

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,

View File

@ -2,7 +2,6 @@ import { Spin, Typography } from '@douyinfe/semi-ui';
import { HocuspocusProvider } from '@hocuspocus/provider'; import { HocuspocusProvider } from '@hocuspocus/provider';
import { DataRender } from 'components/data-render'; import { DataRender } from 'components/data-render';
import deepEqual from 'deep-equal'; import deepEqual from 'deep-equal';
import { throttle } from 'helpers/throttle';
import { useToggle } from 'hooks/use-toggle'; import { useToggle } from 'hooks/use-toggle';
import { SecureDocumentIllustration } from 'illustrations/secure-document'; import { SecureDocumentIllustration } from 'illustrations/secure-document';
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
@ -49,14 +48,14 @@ export const CollaborationEditor = forwardRef((props: ICollaborationEditorProps,
editable, editable,
}, },
maxAttempts: 1, maxAttempts: 1,
onAwarenessUpdate: throttle(({ states }) => { onAwarenessUpdate: ({ states }) => {
const users = states.map((state) => ({ clientId: state.clientId, user: state.user })); const users = states.map((state) => ({ clientId: state.clientId, user: state.user }));
if (deepEqual(user, lastAwarenessRef.current)) { if (deepEqual(user, lastAwarenessRef.current)) {
return; return;
} }
onAwarenessUpdate && onAwarenessUpdate(users); onAwarenessUpdate && onAwarenessUpdate(users);
lastAwarenessRef.current = users; lastAwarenessRef.current = users;
}, 200), },
onAuthenticationFailed() { onAuthenticationFailed() {
toggleLoading(false); toggleLoading(false);
setError(new Error('鉴权失败!暂时无法提供服务')); setError(new Error('鉴权失败!暂时无法提供服务'));

View File

@ -41,9 +41,9 @@ importers:
packages/client: packages/client:
specifiers: specifiers:
'@douyinfe/semi-icons': ^2.3.1 '@douyinfe/semi-icons': ^2.18.0
'@douyinfe/semi-next': ^2.3.1 '@douyinfe/semi-next': ^2.18.0
'@douyinfe/semi-ui': ^2.3.1 '@douyinfe/semi-ui': ^2.18.0
'@excalidraw/excalidraw': ^0.12.0 '@excalidraw/excalidraw': ^0.12.0
'@hocuspocus/provider': ^1.0.0-alpha.29 '@hocuspocus/provider': ^1.0.0-alpha.29
'@react-pdf-viewer/core': 3.7.0 '@react-pdf-viewer/core': 3.7.0
@ -101,7 +101,6 @@ importers:
copy-webpack-plugin: 11.0.0 copy-webpack-plugin: 11.0.0
cross-env: ^7.0.3 cross-env: ^7.0.3
deep-equal: ^2.0.5 deep-equal: ^2.0.5
docx: ^7.3.0
dompurify: ^2.3.5 dompurify: ^2.3.5
downloadjs: ^1.4.7 downloadjs: ^1.4.7
eslint: ^8.14.0 eslint: ^8.14.0
@ -112,7 +111,6 @@ importers:
eslint-plugin-react-hooks: ^4.5.0 eslint-plugin-react-hooks: ^4.5.0
eslint-plugin-simple-import-sort: ^7.0.0 eslint-plugin-simple-import-sort: ^7.0.0
fs-extra: ^10.0.0 fs-extra: ^10.0.0
html-to-docx: ^1.4.0
htmldiff-js: ^1.0.5 htmldiff-js: ^1.0.5
interactjs: ^1.10.11 interactjs: ^1.10.11
katex: ^0.15.2 katex: ^0.15.2
@ -159,9 +157,9 @@ importers:
viewerjs: ^1.10.4 viewerjs: ^1.10.4
yjs: ^13.5.24 yjs: ^13.5.24
dependencies: dependencies:
'@douyinfe/semi-icons': 2.3.1_react@17.0.2 '@douyinfe/semi-icons': 2.18.0_react@17.0.2
'@douyinfe/semi-next': 2.3.1 '@douyinfe/semi-next': 2.18.0
'@douyinfe/semi-ui': 2.3.1_wnecvl2xit6hykxlpfa3byfhr4 '@douyinfe/semi-ui': 2.18.0_sfoxds7t5ydpegc3knd667wn6m
'@excalidraw/excalidraw': 0.12.0_sfoxds7t5ydpegc3knd667wn6m '@excalidraw/excalidraw': 0.12.0_sfoxds7t5ydpegc3knd667wn6m
'@hocuspocus/provider': 1.0.0-alpha.29 '@hocuspocus/provider': 1.0.0-alpha.29
'@react-pdf-viewer/core': 3.7.0_2vj3zozgbzfehrv2inzxxqn2wq '@react-pdf-viewer/core': 3.7.0_2vj3zozgbzfehrv2inzxxqn2wq
@ -214,10 +212,8 @@ importers:
clone: 2.1.2 clone: 2.1.2
cross-env: 7.0.3 cross-env: 7.0.3
deep-equal: 2.0.5 deep-equal: 2.0.5
docx: 7.3.0
dompurify: 2.3.5 dompurify: 2.3.5
downloadjs: 1.4.7 downloadjs: 1.4.7
html-to-docx: 1.4.0
htmldiff-js: 1.0.5 htmldiff-js: 1.0.5
interactjs: 1.10.11 interactjs: 1.10.11
katex: 0.15.2 katex: 0.15.2
@ -1814,39 +1810,33 @@ packages:
'@cspotcode/source-map-consumer': 0.8.0 '@cspotcode/source-map-consumer': 0.8.0
dev: true dev: true
/@douyinfe/semi-animation-react/2.3.1_sfoxds7t5ydpegc3knd667wn6m: /@douyinfe/semi-animation-react/2.18.0:
resolution: {integrity: sha512-7rXD60qnRbWQK9et1LfHmoDaL8icavO+gozAMVNYvIsJqz4UPsJdvqAz2tJ0aZRoYzWi39V5mxFnXdzzbcAzMQ==} resolution: {integrity: sha512-0Zg4QWnkjmssMilOppdC5NyE5CTeg7ws2VqHE+iCv02ps13ackdrmOp3FkluMfmUnUQ4ikqw5plagTBM576bqA==}
peerDependencies:
prop-types: 15.7.2
react: '>=16.0.0'
react-dom: '>=16.0.1'
dependencies: dependencies:
'@babel/runtime-corejs3': 7.16.8 '@babel/runtime-corejs3': 7.16.8
'@douyinfe/semi-animation': 2.3.1 '@douyinfe/semi-animation': 2.12.0
'@douyinfe/semi-animation-styled': 2.3.1 '@douyinfe/semi-animation-styled': 2.18.0
classnames: 2.3.1 classnames: 2.3.1
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
dev: false dev: false
/@douyinfe/semi-animation-styled/2.3.1: /@douyinfe/semi-animation-styled/2.18.0:
resolution: {integrity: sha512-++3ngSanf1NroWQoZ8ssDk55Wz1Ib6G7m+Ee/RmOnL5VzvhyhLnkgjZoaWz6oIHbk0TQ764+GoBzfF+ZsYtvrQ==} resolution: {integrity: sha512-UoPg50ITynIG1y3GgPmYhZ/1aMTVp2gDab7JkVP+44cggqSSyv5RdejyxVl0ZDnPgtUgqwLsAir1OYTIzx/lJQ==}
dependencies: dependencies:
'@babel/runtime-corejs3': 7.16.8 '@babel/runtime-corejs3': 7.16.8
dev: false dev: false
/@douyinfe/semi-animation/2.3.1: /@douyinfe/semi-animation/2.12.0:
resolution: {integrity: sha512-sDd9hSTGCvSb6JPls0XgrLXPMRjjjn1bWbW6Y1XJcdge/KPEyL7zYo216yq89YVUsbuhwtfzfcKCfK+aIE7F5g==} resolution: {integrity: sha512-OAfL9Nk38ZPqfdKm9k4cvVXXzm16ALI4LxGNZ0qfe2RCLLnYGB/hNzTctoTDjYD35dFv0yroh3qsXtZuP2xNdg==}
dependencies: dependencies:
'@babel/runtime-corejs3': 7.16.8 '@babel/runtime-corejs3': 7.16.8
bezier-easing: 2.1.0 bezier-easing: 2.1.0
dev: false dev: false
/@douyinfe/semi-foundation/2.3.1: /@douyinfe/semi-foundation/2.18.0:
resolution: {integrity: sha512-0EgaAnDFsesSSDHhyw1OfE/pgRKACvHUs3QIcax5V32t3bJ3q6C7BISHxHFxmP9oBTlYTZ5kZJCcJ+ECweYs2Q==} resolution: {integrity: sha512-SJ0iyuk1YDSZvChoQrIqslzmqjK8qFUEmwE3Thv+jU/dn8t6smQyKNfho6dQ/RtBSwq8FezsqVAT88RT72lKXw==}
dependencies: dependencies:
'@babel/runtime-corejs3': 7.16.8 '@babel/runtime-corejs3': 7.16.8
'@douyinfe/semi-animation': 2.3.1 '@douyinfe/semi-animation': 2.12.0
async-validator: 3.5.2 async-validator: 3.5.2
classnames: 2.3.1 classnames: 2.3.1
date-fns: 2.28.0 date-fns: 2.28.0
@ -1856,29 +1846,29 @@ packages:
scroll-into-view-if-needed: 2.2.29 scroll-into-view-if-needed: 2.2.29
dev: false dev: false
/@douyinfe/semi-icons/2.3.1_react@17.0.2: /@douyinfe/semi-icons/2.18.0_react@17.0.2:
resolution: {integrity: sha512-7WHegh5ESbgbLDJwx/H5Oa+ChXPUlVRw/cfkIUc0z9JdCVH7+L660w83mimLmvrSYOhR3YYB7nVUcrLfiuqG9A==} resolution: {integrity: sha512-r/Ji0XzYS3rI6rw/+TAZHdg/ayJe3EoeGul+LlDV29fIQXO8aOsV+Kkxg4AEa82uzWeZ4798d0W7XK4McLor4w==}
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies: dependencies:
'@babel/runtime-corejs3': 7.16.8 '@babel/runtime-corejs3': 7.16.8
classnames: 2.3.1 classnames: 2.3.1
react: 17.0.2 react: 17.0.2
dev: false dev: false
/@douyinfe/semi-illustrations/2.3.1_react@17.0.2: /@douyinfe/semi-illustrations/2.15.0_react@17.0.2:
resolution: {integrity: sha512-7cBQBVJneKEfnv7aMHDmED23oJ+3/vSnqXriZK2keQOyzOSrjt3AQ12wBsjIgNgcWIwg2FI+m03jM1LxSOgo3A==} resolution: {integrity: sha512-8gajbeKZwJTk7G79tK7qPg8s3V1UUxjg8oA8X/11kim+rt0vzRqCXclyR65JMWIayZIIj+VftqjCHcTc6ozI0A==}
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies: dependencies:
'@babel/runtime-corejs3': 7.16.8 '@babel/runtime-corejs3': 7.16.8
react: 17.0.2 react: 17.0.2
dev: false dev: false
/@douyinfe/semi-next/2.3.1: /@douyinfe/semi-next/2.18.0:
resolution: {integrity: sha512-y+d/SSDrvC7X1WOQ2t0l2+YbX2W8Ex1AgI4XeXl5b6liDEUWITZjDMQKMQwGGL0pizTsVJ2XOJL9dhWWbq8M+A==} resolution: {integrity: sha512-0LX7ScOriiX6btL4P24NeVrOERxYMI8atgqjv+DDMqYZ1pDXAQp7UFyhio2a8P1Mmyg7DpUuV51UpQAB5RY4Sg==}
dependencies: dependencies:
'@douyinfe/semi-webpack-plugin': 2.3.1 '@douyinfe/semi-webpack-plugin': 2.18.0
transitivePeerDependencies: transitivePeerDependencies:
- fibers - fibers
- node-sass - node-sass
@ -1886,53 +1876,50 @@ packages:
- webpack - webpack
dev: false dev: false
/@douyinfe/semi-theme-default/2.3.1: /@douyinfe/semi-theme-default/2.18.0:
resolution: {integrity: sha512-od/AjepcaxcQSkcC2YViUH9A1tL7Ve2QiFkd0Z2DG76zPG1K4yzMI5mFmB1sKQ3uVRzO5f1YOp7k0zub094NuQ==} resolution: {integrity: sha512-GPE/YjxKEyOD+lKyMCXVHdo4HCr3VzJ/IflELe5hsHQ/6n/g8bIJzEZ21I/9OpZ04nGK4xicjf5X68YojVMf/g==}
dependencies: dependencies:
glob: 7.2.0 glob: 7.2.0
dev: false dev: false
/@douyinfe/semi-ui/2.3.1_wnecvl2xit6hykxlpfa3byfhr4: /@douyinfe/semi-ui/2.18.0_sfoxds7t5ydpegc3knd667wn6m:
resolution: {integrity: sha512-2RlhndHE4J82QSMnioerWMDzlRe+Qe3kJKQo0/6U+LkY2gP9B2edMiTG5QiqQNJ8YeAwOCkKbuJPbgr/B2VdXA==} resolution: {integrity: sha512-KEno0gEWSauMLo49/D+zL2NIxvwix4vE7dXnxpbIxhrGJxLRDQyQGM2tdhGhn7o8qQvyIfVpanhGPI9vLKDgGA==}
peerDependencies: peerDependencies:
'@types/react': '>=16.0.0'
'@types/react-dom': '>=16.0.0'
prop-types: 15.7.2
react: '>=16.0.0' react: '>=16.0.0'
react-dom: '>=16.0.0' react-dom: '>=16.0.0'
dependencies: dependencies:
'@babel/runtime-corejs3': 7.16.8 '@babel/runtime-corejs3': 7.16.8
'@douyinfe/semi-animation-react': 2.3.1_sfoxds7t5ydpegc3knd667wn6m '@douyinfe/semi-animation': 2.12.0
'@douyinfe/semi-foundation': 2.3.1 '@douyinfe/semi-animation-react': 2.18.0
'@douyinfe/semi-icons': 2.3.1_react@17.0.2 '@douyinfe/semi-foundation': 2.18.0
'@douyinfe/semi-illustrations': 2.3.1_react@17.0.2 '@douyinfe/semi-icons': 2.18.0_react@17.0.2
'@douyinfe/semi-theme-default': 2.3.1 '@douyinfe/semi-illustrations': 2.15.0_react@17.0.2
'@types/react': 17.0.38 '@douyinfe/semi-theme-default': 2.18.0
'@types/react-window': 1.8.5
async-validator: 3.5.2 async-validator: 3.5.2
classnames: 2.3.1 classnames: 2.3.1
copy-text-to-clipboard: 2.2.0 copy-text-to-clipboard: 2.2.0
date-fns: 2.28.0 date-fns: 2.28.0
date-fns-tz: 1.2.2_date-fns@2.28.0 date-fns-tz: 1.2.2_date-fns@2.28.0
lodash: 4.17.21 lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2 react: 17.0.2
react-dom: 17.0.2_react@17.0.2 react-dom: 17.0.2_react@17.0.2
react-resizable: 1.11.1_sfoxds7t5ydpegc3knd667wn6m react-resizable: 1.11.1_sfoxds7t5ydpegc3knd667wn6m
react-sortable-hoc: 1.11.0_sfoxds7t5ydpegc3knd667wn6m react-sortable-hoc: 2.0.0_sfoxds7t5ydpegc3knd667wn6m
react-window: 1.8.6_sfoxds7t5ydpegc3knd667wn6m react-window: 1.8.6_sfoxds7t5ydpegc3knd667wn6m
resize-observer-polyfill: 1.5.1 resize-observer-polyfill: 1.5.1
scroll-into-view-if-needed: 2.2.29 scroll-into-view-if-needed: 2.2.29
utility-types: 3.10.0 utility-types: 3.10.0
dev: false dev: false
/@douyinfe/semi-webpack-plugin/2.3.1: /@douyinfe/semi-webpack-plugin/2.18.0:
resolution: {integrity: sha512-h+XJI28FU1v29VLO/LUIrL/qTA/1ky6wFS0TkrNtWUJnecvs3hi7J0/kDzubBWhsODZi2ut78iIyUytI3FC60w==} resolution: {integrity: sha512-hoYhbAoex80VNASliWIAZElZx3l3rXcYDZs0Qs/SeFL0F8WkCdKx6MnNr+9QUnex0icljvhVNt6eNYLtRkXDoA==}
peerDependencies: peerDependencies:
webpack: ^4 || ^5 webpack: ^4 || ^5
dependencies: dependencies:
'@babel/generator': 7.16.8 '@babel/generator': 7.17.12
'@babel/parser': 7.16.12 '@babel/parser': 7.17.12
'@babel/traverse': 7.16.10 '@babel/traverse': 7.17.12
css-loader: 4.3.0 css-loader: 4.3.0
enhanced-resolve: 5.8.3 enhanced-resolve: 5.8.3
loader-utils: 2.0.0 loader-utils: 2.0.0
@ -3633,6 +3620,7 @@ packages:
/@types/prop-types/15.7.4: /@types/prop-types/15.7.4:
resolution: {integrity: sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==} resolution: {integrity: sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==}
dev: true
/@types/prosemirror-commands/1.0.4: /@types/prosemirror-commands/1.0.4:
resolution: {integrity: sha512-utDNYB3EXLjAfYIcRWJe6pn3kcQ5kG4RijbT/0Y/TFOm6yhvYS/D9eJVnijdg9LDjykapcezchxGRqFD5LcyaQ==} resolution: {integrity: sha512-utDNYB3EXLjAfYIcRWJe6pn3kcQ5kG4RijbT/0Y/TFOm6yhvYS/D9eJVnijdg9LDjykapcezchxGRqFD5LcyaQ==}
@ -3713,18 +3701,13 @@ packages:
/@types/range-parser/1.2.4: /@types/range-parser/1.2.4:
resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
/@types/react-window/1.8.5:
resolution: {integrity: sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==}
dependencies:
'@types/react': 17.0.38
dev: false
/@types/react/17.0.38: /@types/react/17.0.38:
resolution: {integrity: sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==} resolution: {integrity: sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==}
dependencies: dependencies:
'@types/prop-types': 15.7.4 '@types/prop-types': 15.7.4
'@types/scheduler': 0.16.2 '@types/scheduler': 0.16.2
csstype: 3.0.10 csstype: 3.0.10
dev: true
/@types/resolve/1.17.1: /@types/resolve/1.17.1:
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
@ -3734,6 +3717,7 @@ packages:
/@types/scheduler/0.16.2: /@types/scheduler/0.16.2:
resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
dev: true
/@types/serve-static/1.13.10: /@types/serve-static/1.13.10:
resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==}
@ -4588,7 +4572,7 @@ packages:
dev: false dev: false
/bezier-easing/2.1.0: /bezier-easing/2.1.0:
resolution: {integrity: sha1-wE3+i5JtbsrKGBPWn/F5t8ICXYY=} resolution: {integrity: sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==}
dev: false dev: false
/big-integer/1.6.51: /big-integer/1.6.51:
@ -5227,6 +5211,7 @@ packages:
/core-js-pure/3.20.3: /core-js-pure/3.20.3:
resolution: {integrity: sha512-Q2H6tQ5MtPtcC7f3HxJ48i4Q7T9ybPKgvWyuH7JXIoNa2pm0KuBnycsET/qw1SLLZYfbsbrZQNMeIOClb+6WIA==} resolution: {integrity: sha512-Q2H6tQ5MtPtcC7f3HxJ48i4Q7T9ybPKgvWyuH7JXIoNa2pm0KuBnycsET/qw1SLLZYfbsbrZQNMeIOClb+6WIA==}
deprecated: core-js-pure@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js-pure.
requiresBuild: true requiresBuild: true
dev: false dev: false
@ -5354,6 +5339,7 @@ packages:
/csstype/3.0.10: /csstype/3.0.10:
resolution: {integrity: sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==} resolution: {integrity: sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==}
dev: true
/dashdash/1.14.1: /dashdash/1.14.1:
resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==}
@ -5636,17 +5622,6 @@ packages:
esutils: 2.0.3 esutils: 2.0.3
dev: true dev: true
/docx/7.3.0:
resolution: {integrity: sha512-OkSGlDNWMRFY07OEhUTx1ouuzYi8s1b67JDI6m5/5ek4xoshtP+/Rx8eRdY8LbhvpFkngvUantvTsxY4XW8Heg==}
engines: {node: '>=10'}
dependencies:
'@types/node': 17.0.35
jszip: 3.10.0
nanoid: 3.3.1
xml: 1.0.1
xml-js: 1.6.11
dev: false
/dom-serializer/0.2.2: /dom-serializer/0.2.2:
resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==}
dependencies: dependencies:
@ -10089,11 +10064,11 @@ packages:
react: 17.0.2 react: 17.0.2
dev: false dev: false
/react-sortable-hoc/1.11.0_sfoxds7t5ydpegc3knd667wn6m: /react-sortable-hoc/2.0.0_sfoxds7t5ydpegc3knd667wn6m:
resolution: {integrity: sha512-v1CDCvdfoR3zLGNp6qsBa4J1BWMEVH25+UKxF/RvQRh+mrB+emqtVHMgZ+WreUiKJoEaiwYoScaueIKhMVBHUg==} resolution: {integrity: sha512-JZUw7hBsAHXK7PTyErJyI7SopSBFRcFHDjWW5SWjcugY0i6iH7f+eJkY8cJmGMlZ1C9xz1J3Vjz0plFpavVeRg==}
peerDependencies: peerDependencies:
react: ^0.14.0 || ^15.0.0 || ^16.0.0 react: ^16.3.0 || ^17.0.0
react-dom: ^0.14.0 || ^15.0.0 || ^16.0.0 react-dom: ^16.3.0 || ^17.0.0
dependencies: dependencies:
'@babel/runtime': 7.16.7 '@babel/runtime': 7.16.7
invariant: 2.2.4 invariant: 2.2.4
@ -10530,6 +10505,7 @@ packages:
'@types/json-schema': 7.0.9 '@types/json-schema': 7.0.9
ajv: 6.12.6 ajv: 6.12.6
ajv-keywords: 3.5.2_ajv@6.12.6 ajv-keywords: 3.5.2_ajv@6.12.6
dev: true
/schema-utils/2.7.1: /schema-utils/2.7.1:
resolution: {integrity: sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==} resolution: {integrity: sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==}
@ -11040,7 +11016,7 @@ packages:
webpack: ^4.0.0 || ^5.0.0 webpack: ^4.0.0 || ^5.0.0
dependencies: dependencies:
loader-utils: 2.0.0 loader-utils: 2.0.0
schema-utils: 2.7.0 schema-utils: 2.7.1
dev: false dev: false
/style-search/0.1.0: /style-search/0.1.0:
@ -12468,21 +12444,10 @@ packages:
resolution: {integrity: sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==} resolution: {integrity: sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==}
dev: false dev: false
/xml-js/1.6.11:
resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==}
hasBin: true
dependencies:
sax: 1.2.4
dev: false
/xml-name-validator/3.0.0: /xml-name-validator/3.0.0:
resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==}
dev: true dev: true
/xml/1.0.1:
resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==}
dev: false
/xml2js/0.4.23: /xml2js/0.4.23:
resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==} resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==}
engines: {node: '>=4.0.0'} engines: {node: '>=4.0.0'}