mirror of https://github.com/fantasticit/think.git
fix #117
This commit is contained in:
parent
4161d5fd2d
commit
1626e1764a
|
@ -0,0 +1,41 @@
|
||||||
|
import { Spin, Typography } from '@douyinfe/semi-ui';
|
||||||
|
import { Empty } from 'illustrations/empty';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
|
||||||
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
export const defaultLoading = <Spin />;
|
||||||
|
|
||||||
|
export const defaultRenderError = (error) => {
|
||||||
|
return <Text>{(error && error.message) || '未知错误'}</Text>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const defaultEmpty = (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flexDirection: 'column',
|
||||||
|
position: 'relative',
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<Empty />
|
||||||
|
</div>
|
||||||
|
<Text type="tertiary">暂无数据</Text>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Render: React.FC<{ fn: ((arg: unknown) => React.ReactNode) | React.ReactNode; args?: unknown[] }> = ({
|
||||||
|
fn,
|
||||||
|
args = [],
|
||||||
|
}) => {
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
const content = useMemo(() => (typeof fn === 'function' ? fn.apply(null, ...args) : fn), [args]);
|
||||||
|
|
||||||
|
return <>{content}</>;
|
||||||
|
};
|
|
@ -1,7 +1,6 @@
|
||||||
import { Spin, Typography } from '@douyinfe/semi-ui';
|
|
||||||
import { Empty } from 'illustrations/empty';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { defaultEmpty, defaultLoading, defaultRenderError, Render } from './constant';
|
||||||
import { LoadingWrap } from './loading';
|
import { LoadingWrap } from './loading';
|
||||||
|
|
||||||
type RenderProps = React.ReactNode | (() => React.ReactNode);
|
type RenderProps = React.ReactNode | (() => React.ReactNode);
|
||||||
|
@ -16,40 +15,6 @@ interface IProps {
|
||||||
normalContent: RenderProps;
|
normalContent: RenderProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { Text } = Typography;
|
|
||||||
|
|
||||||
const defaultLoading = () => {
|
|
||||||
return <Spin />;
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultRenderError = (error) => {
|
|
||||||
return <Text>{(error && error.message) || '未知错误'}</Text>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultEmpty = () => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
flexDirection: 'column',
|
|
||||||
position: 'relative',
|
|
||||||
top: '50%',
|
|
||||||
left: '50%',
|
|
||||||
transform: 'translate(-50%, -50%)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<Empty />
|
|
||||||
</div>
|
|
||||||
<Text type="tertiary">暂无数据</Text>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const runRender = (fn, ...args) => (typeof fn === 'function' ? fn(...args) : fn);
|
|
||||||
|
|
||||||
export const DataRender: React.FC<IProps> = ({
|
export const DataRender: React.FC<IProps> = ({
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
|
@ -60,19 +25,14 @@ export const DataRender: React.FC<IProps> = ({
|
||||||
normalContent,
|
normalContent,
|
||||||
}) => {
|
}) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return runRender(errorContent, error);
|
return <Render fn={errorContent} args={[error]} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
return runRender(emptyContent);
|
return <Render fn={emptyContent} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoadingWrap
|
<LoadingWrap loading={loading} loadingContent={loadingContent} normalContent={loading ? null : normalContent} />
|
||||||
loading={loading}
|
|
||||||
runRender={runRender}
|
|
||||||
loadingContent={loadingContent}
|
|
||||||
normalContent={loading ? null : normalContent}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
import { useToggle } from 'hooks/use-toggle';
|
import { useToggle } from 'hooks/use-toggle';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
// interface IProps {
|
import { Render } from './constant';
|
||||||
// loading: boolean;
|
|
||||||
// delay?: number;
|
|
||||||
// runRender
|
|
||||||
// loadingContent: React.ReactElement;
|
|
||||||
// normalContent: React.ReactElement;
|
|
||||||
// }
|
|
||||||
|
|
||||||
export const LoadingWrap = ({ loading, delay = 200, runRender, loadingContent, normalContent }) => {
|
export const LoadingWrap = ({ loading, delay = 200, loadingContent, normalContent }) => {
|
||||||
const timer = useRef<ReturnType<typeof setTimeout>>(null);
|
const timer = useRef<ReturnType<typeof setTimeout>>(null);
|
||||||
const [showLoading, toggleShowLoading] = useToggle(false);
|
const [showLoading, toggleShowLoading] = useToggle(false);
|
||||||
|
|
||||||
|
@ -32,8 +26,8 @@ export const LoadingWrap = ({ loading, delay = 200, runRender, loadingContent, n
|
||||||
}, [delay, loading, toggleShowLoading]);
|
}, [delay, loading, toggleShowLoading]);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return showLoading ? runRender(loadingContent) : null;
|
return showLoading ? <Render fn={loadingContent} /> : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return runRender(normalContent);
|
return <Render fn={normalContent} />;
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,13 +122,25 @@ export const DocumentEditor: React.FC<IProps> = ({ documentId }) => {
|
||||||
{isMobile && <div className={styles.mobileToolbar}>{actions}</div>}
|
{isMobile && <div className={styles.mobileToolbar}>{actions}</div>}
|
||||||
</header>
|
</header>
|
||||||
<main className={styles.contentWrap}>
|
<main className={styles.contentWrap}>
|
||||||
{docAuthError && (
|
<DataRender
|
||||||
<div style={{ margin: '10vh', textAlign: 'center' }}>
|
loading={docAuthLoading}
|
||||||
<SecureDocumentIllustration />
|
error={docAuthError}
|
||||||
</div>
|
errorContent={() => {
|
||||||
)}
|
return (
|
||||||
{document && <Seo title={document.title} />}
|
<div style={{ margin: '10vh', textAlign: 'center' }}>
|
||||||
<Editor user={user} documentId={documentId} authority={authority} />
|
<SecureDocumentIllustration />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
normalContent={() => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{document && <Seo title={document.title} />}
|
||||||
|
{user && <Editor user={user} documentId={documentId} authority={authority} />}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -90,6 +90,8 @@ export class CollaborationService {
|
||||||
async onAuthenticate({ connection, token, requestParameters }: onAuthenticatePayload) {
|
async onAuthenticate({ connection, token, requestParameters }: onAuthenticatePayload) {
|
||||||
const targetId = requestParameters.get('targetId');
|
const targetId = requestParameters.get('targetId');
|
||||||
const docType = requestParameters.get('docType');
|
const docType = requestParameters.get('docType');
|
||||||
|
const userId = requestParameters.get('userId');
|
||||||
|
|
||||||
const user = token ? await this.userService.decodeToken(token) : null;
|
const user = token ? await this.userService.decodeToken(token) : null;
|
||||||
|
|
||||||
switch (docType) {
|
switch (docType) {
|
||||||
|
@ -99,8 +101,13 @@ export class CollaborationService {
|
||||||
if (!document || document.status !== DocumentStatus.public) {
|
if (!document || document.status !== DocumentStatus.public) {
|
||||||
throw new HttpException('您无权查看此文档', HttpStatus.FORBIDDEN);
|
throw new HttpException('您无权查看此文档', HttpStatus.FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
connection.readOnly = true;
|
||||||
return { user: { name: '匿名用户' } };
|
return { user: { name: '匿名用户' } };
|
||||||
} else {
|
} else {
|
||||||
|
if (user.id !== userId) {
|
||||||
|
throw new HttpException('用户信息不匹配', HttpStatus.FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
const authority = await this.documentService.getDocumentUserAuth(user.id, targetId);
|
const authority = await this.documentService.getDocumentUserAuth(user.id, targetId);
|
||||||
|
|
||||||
if (!authority.readable) {
|
if (!authority.readable) {
|
||||||
|
|
Loading…
Reference in New Issue