refactor: lint code

This commit is contained in:
fantasticit 2022-05-01 22:07:22 +08:00
parent 1dac849b61
commit 76cdcff589
48 changed files with 955 additions and 137 deletions

6
.eslintignore Normal file
View File

@ -0,0 +1,6 @@
node_modules
**/.next/**
**/_next/**
**/dist/**
./packages/client/src/tiptap/next.config.js
./packages/client/src/tiptap/wrappers/mind/mind-elixir/iconfont/iconfont.js

47
.eslintrc.client.js Normal file
View File

@ -0,0 +1,47 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 8,
sourceType: 'module',
ecmaFeatures: {
impliedStrict: true,
experimentalObjectRestSpread: true,
},
allowImportExportEverywhere: true,
project: ['./packages/client/tsconfig.json'],
},
plugins: ['@typescript-eslint', 'react-hooks'],
extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
settings: {
react: {
version: 'detect',
},
},
env: {
es6: true,
browser: true,
node: true,
},
rules: {
'func-names': 0,
'no-shadow': 0,
'@typescript-eslint/no-shadow': 0,
'@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/no-unused-vars': [0, { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-use-before-define': 0,
'@typescript-eslint/ban-ts-ignore': 0,
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/ban-ts-comment': 0,
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-this-alias': 0,
'@typescript-eslint/explicit-module-boundary-types': 0,
'@typescript-eslint/ban-types': 0,
'react-hooks/rules-of-hooks': 2,
'react-hooks/exhaustive-deps': 1,
'react/prop-types': 0,
'testing-library/no-unnecessary-act': 0,
'react/react-in-jsx-scope': 0,
},
ignorePatterns: ['dist/', 'node_modules', 'scripts', 'examples'],
};

19
.eslintrc.server.js Normal file
View File

@ -0,0 +1,19 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: './packages/server/tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: ['plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
root: true,
env: {
node: true,
jest: true,
},
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};

View File

@ -20,8 +20,10 @@
"pm2": "pnpm run pm2:server && pnpm run pm2:client",
"pm2:server": "pnpm run --dir packages/server pm2",
"pm2:client": "pnpm run --dir packages/client pm2",
"lint:client": "eslint --fix './packages/client/**/*.{ts,tsx,js,jsx}' -c '.eslintrc.client.js'",
"lint:server": "eslint --fix './packages/server/src/*.{ts,js}' -c '.eslintrc.server.js'",
"format": "concurrently \"pnpm:format:*\"",
"format:ts": "prettier --write --parser typescript \"git status\"",
"format:ts": "prettier --write --parser typescript \"packages/**/*.{ts,tsx,js,jsx}\"",
"format:css": "stylelint --fix --formatter verbose --allow-empty-input \"packages/**/*.{css,scss,sass}\"",
"prepare": "husky install",
"precommit": "lint-staged"
@ -36,6 +38,16 @@
"node": ">=16.5.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"eslint": "^8.14.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.5.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"husky": "^7.0.4",
"lint-staged": "^12.4.1",
"prettier": "^2.3.2",

View File

@ -1,10 +1,9 @@
const semi = require('@douyinfe/semi-next').default({});
/* eslint-disable */
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const { getConfig } = require('@think/config');
const config = getConfig();
/** @type {import('next').NextConfig} */
const nextConfig = semi({
const nextConfig = require('@douyinfe/semi-next').default({})({
assetPrefix: config.assetPrefix,
env: {
SERVER_API_URL: config?.client?.apiUrl,

View File

@ -22,7 +22,7 @@ export const Banner: React.FC<IProps> = ({ type, description, duration = 0 }) =>
return () => {
clearTimeout(timer.current);
};
}, [duration]);
}, [duration, toggleVisible]);
if (!visible) return null;

View File

@ -47,7 +47,7 @@ const defaultEmpty = () => {
);
};
const runRender = (fn, ...args) => (typeof fn === 'function' ? fn.apply(null, args) : fn);
const runRender = (fn, ...args) => (typeof fn === 'function' ? fn(...args) : fn);
export const DataRender: React.FC<IProps> = ({
loading,

View File

@ -28,7 +28,7 @@ export const LoadingWrap: React.FC<IProps> = ({ loading, delay = 200, loadingCon
return () => {
clearTimeout(timer.current);
};
}, [delay, loading]);
}, [delay, loading, toggleShowLoading]);
if (loading) {
return showLoading ? loadingContent : null;

View File

@ -31,6 +31,7 @@ interface IProps {
const { Paragraph } = Typography;
const { Column } = Table;
// eslint-disable-next-line react/display-name
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, docAuth) => {
const handle = (evt) => {
const data = {
@ -67,8 +68,8 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
};
useEffect(() => {
const handler = (users) => {
const newCollaborationUsers = users
const handler = (mentionUsers) => {
const newCollaborationUsers = mentionUsers
.filter(Boolean)
.filter((state) => state.user)
.map((state) => ({ ...state.user, clientId: state.clientId }));
@ -90,6 +91,7 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
setCollaborationUsers(newCollaborationUsers);
};
event.on(JOIN_USER, handler);
return () => {

View File

@ -16,10 +16,11 @@ interface IProps {
const { Text } = Typography;
export const CommentItem: React.FC<IProps> = ({ comment, replyComment, editComment, deleteComment }) => {
if (!comment) return null;
const { user } = useUser();
const { createUser = {} } = comment;
if (!comment) return null;
return (
<div className={styles.wrap}>
<div className={styles.leftWrap}>

View File

@ -33,7 +33,7 @@ export const DocumentDeletor: React.FC<IProps> = ({ wikiId, documentId, onDelete
okButtonProps: { loading, type: 'danger' },
style: { maxWidth: '96vw' },
});
}, [wikiId, documentId, api, loading, onDelete]);
}, [wikiId, api, loading, onDelete]);
return (
<Text type="danger" onClick={deleteAction}>

View File

@ -15,6 +15,7 @@ interface IProps {
const { Text } = Typography;
const { Column } = Table;
// eslint-disable-next-line react/display-name
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, data) => {
const handle = (evt) => {
const ret = {

View File

@ -27,8 +27,6 @@ interface IProps {
}
export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
if (!documentId) return null;
const [container, setContainer] = useState<HTMLDivElement>();
const { width: windowWidth } = useWindowSize();
const { width, fontSize } = useDocumentStyle();
@ -43,6 +41,8 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
Router.push(`/wiki/${document.wikiId}/document/${document.id}/edit`);
}, [document]);
if (!documentId) return null;
return (
<div className={styles.wrap}>
<Header className={styles.headerWrap}>

View File

@ -12,7 +12,7 @@ interface IProps {
export const DocumentContent: React.FC<IProps> = ({ document, createUserContainerSelector }) => {
const c = safeJSONParse(document.content);
let json = c.default || c;
const json = c.default || c;
const editor = useEditor({
editable: false,

View File

@ -37,8 +37,6 @@ interface IProps {
}
export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo = true }) => {
if (!documentId) return null;
const { data, loading, error, query } = usePublicDocument(documentId);
const { width, fontSize } = useDocumentStyle();
const editorWrapClassNames = useMemo(() => {
@ -72,6 +70,8 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
});
}, [error, query]);
if (!documentId) return null;
return (
<Layout className={styles.wrap}>
<Header className={styles.headerWrap}>

View File

@ -32,7 +32,7 @@ export const DocumentVersion: React.FC<IProps> = ({ documentId, onSelect }) => {
const close = useCallback(() => {
toggleVisible(false);
setSelectedVersion(null);
}, []);
}, [toggleVisible]);
const select = useCallback(
(version) => {
@ -46,20 +46,20 @@ export const DocumentVersion: React.FC<IProps> = ({ documentId, onSelect }) => {
if (!selectedVersion || !onSelect) return;
onSelect(safeJSONParse(selectedVersion.data, { default: {} }).default);
close();
}, [selectedVersion]);
}, [selectedVersion, close, onSelect]);
useEffect(() => {
if (visible) {
refresh();
}
}, [visible]);
}, [visible, refresh]);
useEffect(() => {
if (!editor) return;
if (!data.length) return;
if (selectedVersion) return;
select(data[0]);
}, [editor, data, selectedVersion]);
}, [editor, data, selectedVersion, select]);
return (
<>

View File

@ -60,15 +60,12 @@ export const GridSelect = ({
[onSelect]
);
const onHover = useCallback(
debounce(({ x, y, isCellDisabled }) => {
if (isCellDisabled) {
return setHoverCell(null);
}
setHoverCell({ x, y });
}, 5),
[disabled]
);
const onHover = useCallback(({ x, y, isCellDisabled }) => {
if (isCellDisabled) {
return setHoverCell(null);
}
setHoverCell({ x, y });
}, []);
const cells = useMemo(() => {
const cells = [];

View File

@ -40,7 +40,7 @@ const MessagesRender = ({ messageData, loading, error, onClick = null, page = 1,
<>
{messages.map((msg) => {
return (
<div className={styles.itemWrap} onClick={() => handleRead(msg.id)}>
<div key={msg.id} className={styles.itemWrap} onClick={() => handleRead(msg.id)}>
<Link href={msg.url}>
<a className={styles.item}>
<div className={styles.leftWrap}>
@ -140,7 +140,7 @@ const MessageBox = () => {
readMessage(msg.id);
},
});
}, [unreadMsgs]);
}, [unreadMsgs, readMessage]);
return (
<Dropdown

View File

@ -112,7 +112,7 @@ export const Resizeable: React.FC<IProps> = ({
},
},
});
}, [maxWidth, isEditable]);
}, [maxWidth, isEditable, onChange, onChangeEnd]);
useEffect(() => {
Object.assign($container.current.style, {

View File

@ -40,7 +40,6 @@ interface IProps {
}
export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTemplate, deleteTemplate }) => {
if (!user) return null;
const { width: windowWidth } = useWindowSize();
const [title, setTitle] = useState(data.title);
const provider = useMemo(() => {
@ -51,7 +50,7 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
user,
docType: 'template',
});
}, [data, user.token]);
}, [data, user]);
const editor = useEditor({
editable: true,
extensions: [...BaseKit, DocumentWithTitle, getCollaborationExtension(provider)],
@ -59,7 +58,9 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
try {
const title = transaction.doc.content.firstChild.content.firstChild.textContent;
setTitle(title);
} catch (e) {}
} catch (e) {
//
}
},
});
const [isPublic, setPublic] = useState(false);
@ -76,7 +77,7 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
deleteTemplate().then(() => {
goback();
});
}, [deleteTemplate]);
}, [deleteTemplate, goback]);
useEffect(() => {
if (!data) return;
@ -99,6 +100,8 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
};
}, []);
if (!user) return null;
return (
<div className={styles.wrap}>
<header>

View File

@ -38,7 +38,7 @@ export const TemplateList: React.FC<IProps> = ({
const start = (page - 1) * pageSize;
const end = page * pageSize;
return arr.slice(start, end);
}, [data, page]);
}, [data, page, pageSize]);
return (
<DataRender

View File

@ -21,8 +21,6 @@ interface IProps {
}
export const Editor: React.FC<IProps> = ({ user, data, loading, error }) => {
if (!user) return null;
const c = safeJSONParse(data.content);
let json = c.default || c;
@ -44,6 +42,8 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error }) => {
return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth;
}, [width]);
if (!user) return null;
return (
<div className={styles.wrap}>
<Layout className={styles.contentWrap}>

View File

@ -26,7 +26,7 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
const [publicDocumentIds, setPublicDocumentIds] = useState([]); // 公开的
const privateDocumentIds = useMemo(() => {
return documents.filter((doc) => !publicDocumentIds.includes(doc.id)).map((doc) => doc.id);
}, [tocs, publicDocumentIds]);
}, [documents, publicDocumentIds]);
const submit = () => {
const data = { nextStatus, publicDocumentIds, privateDocumentIds };
@ -77,7 +77,7 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
if (!documents.length) return;
const activeIds = documents.filter((doc) => isPublicDocument(doc.status)).map((doc) => doc.id);
setPublicDocumentIds(activeIds);
}, [tocs]);
}, [tocs, documents]);
return (
<div className={styles.wrap}>
@ -115,7 +115,11 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
</Title>
<RadioGroup direction="vertical" value={nextStatus} onChange={(e) => setNextStatus(e.target.value)}>
{WIKI_STATUS_LIST.map((status) => {
return <Radio value={status.value}>{status.label}</Radio>;
return (
<Radio key={status.value} value={status.value}>
{status.label}
</Radio>
);
})}
</RadioGroup>
</div>

View File

@ -20,7 +20,7 @@ export const AddUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) => {
setUserName('');
toggleVisible(false);
});
}, [onOk, userName, userRole]);
}, [onOk, userName, userRole, toggleVisible]);
return (
<Modal
@ -40,7 +40,11 @@ export const AddUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) => {
<Space>
<Select value={userRole} onChange={setUserRole} style={{ width: 120 }}>
{WIKI_USER_ROLES.map((wikiStatus) => {
return <Select.Option value={wikiStatus.value}>{wikiStatus.label}</Select.Option>;
return (
<Select.Option key={wikiStatus.value} value={wikiStatus.value}>
{wikiStatus.label}
</Select.Option>
);
})}
</Select>
<Input

View File

@ -15,7 +15,7 @@ export const EditUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) =>
setUserRole(WikiUserRole.normal);
toggleVisible(false);
});
}, [onOk, userRole]);
}, [onOk, userRole, toggleVisible]);
return (
<Modal
@ -33,7 +33,11 @@ export const EditUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) =>
) : null}
<Select value={userRole} onChange={setUserRole} style={{ width: '100%' }}>
{WIKI_USER_ROLES.map((wikiStatus) => {
return <Select.Option value={wikiStatus.value}>{wikiStatus.label}</Select.Option>;
return (
<Select.Option key={wikiStatus.value} value={wikiStatus.value}>
{wikiStatus.label}
</Select.Option>
);
})}
</Select>
<Button theme="solid" block style={{ margin: '24px 0' }} onClick={handleOk}>

View File

@ -47,7 +47,7 @@ export const WikiTocs: React.FC<IProps> = ({
return () => {
event.off(REFRESH_TOCS, handler);
};
}, []);
}, [refresh]);
return (
<div className={styles.wrap}>

View File

@ -56,7 +56,7 @@ const AddDocument = () => {
return () => {
event.off(CREATE_DOCUMENT, handler);
};
}, []);
}, [toggleVisible]);
return (
<DocumenCreatorForm wikiId={wikiId} parentDocumentId={documentId} visible={visible} toggleVisible={toggleVisible} />
@ -85,7 +85,7 @@ export const Tree = ({ data, docAsLink, getDocLink, parentIds, activeId, isShare
{isShareMode ? null : renderBtn(item)}
</div>
),
[isShareMode]
[isShareMode, docAsLink, getDocLink, renderBtn]
);
useEffect(() => {

View File

@ -148,12 +148,12 @@ export const usePublicDocument = (documentId: string) => {
})
.catch(setError);
},
[documentId, error]
[fetch, documentId]
);
useEffect(() => {
queryData();
}, [documentId]);
}, [documentId, queryData]);
return {
data: document,

View File

@ -14,18 +14,21 @@ export const useUser = () => {
window.localStorage.removeItem('token');
mutate(null);
Router.replace('/login');
}, []);
}, [mutate]);
const login = useCallback((data) => {
HttpClient.post<IUser>('/user/login', data).then((res) => {
const user = res as unknown as ILoginUser;
mutate(user);
setStorage('user', JSON.stringify(user));
user.token && setStorage('token', user.token);
const next = router.query?.redirect || '/';
Router.replace(next as string);
});
}, []);
const login = useCallback(
(data) => {
HttpClient.post<IUser>('/user/login', data).then((res) => {
const user = res as unknown as ILoginUser;
mutate(user);
setStorage('user', JSON.stringify(user));
user.token && setStorage('token', user.token);
const next = router.query?.redirect || '/';
Router.replace(next as string);
});
},
[mutate, router.query?.redirect]
);
const updateUser = async (patch: Pick<IUser, 'email' | 'avatar'>) => {
const res = await HttpClient.patch('/user/update', patch);
@ -36,7 +39,7 @@ export const useUser = () => {
useEffect(() => {
mutate();
}, []);
}, [mutate]);
return {
user: data,

View File

@ -1,3 +1,4 @@
/* eslint-disable */
'use strict';
var deselectCurrent = require('toggle-selection');
@ -59,7 +60,7 @@ function copy(text, options) {
window.clipboardData.clearData();
var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting['default'];
if (Array.isArray(text)) {
text.forEach((item) => {
text.forEach(function (item) {
if (typeof item === 'string') {
window.clipboardData.setData(item, item);
} else {
@ -73,7 +74,7 @@ function copy(text, options) {
// all other browsers
e.clipboardData.clearData();
if (Array.isArray(text)) {
text.forEach((item) => {
text.forEach(function (item) {
if (typeof item === 'string') {
e.clipboardData.setData(item, item);
} else {
@ -106,7 +107,7 @@ function copy(text, options) {
debug && console.warn('trying IE specific stuff');
try {
if (Array.isArray(text)) {
text.forEach((item) => {
text.forEach(function (item) {
if (typeof item === 'string') {
window.clipboardData.setData(item, item);
} else {

View File

@ -39,7 +39,7 @@ export const useDocumentStyle = () => {
useEffect(() => {
mutate();
}, []);
}, [mutate]);
return {
width: (data && data.width) || DEFAULT_WIDTH,

View File

@ -1,4 +1,4 @@
import { useEffect, useRef } from 'react';
import { useCallback, useEffect, useRef } from 'react';
import useSWR from 'swr';
import { useWindowSize } from 'hooks/use-window-size';
import { setStorage, getStorage } from 'helpers/storage';
@ -21,14 +21,17 @@ export const useDragableWidth = () => {
runTimeWidthRef.current = size;
};
const toggleCollapsed = (collapsed = null) => {
const isBool = typeof collapsed === 'boolean';
const nextCollapsed = isBool ? collapsed : !isCollapsed;
let nextWidth = nextCollapsed ? COLLAPSED_WIDTH : MIN_WIDTH;
setStorage(key, nextWidth);
mutate();
runTimeWidthRef.current = nextWidth;
};
const toggleCollapsed = useCallback(
(collapsed = null) => {
const isBool = typeof collapsed === 'boolean';
const nextCollapsed = isBool ? collapsed : !isCollapsed;
const nextWidth = nextCollapsed ? COLLAPSED_WIDTH : MIN_WIDTH;
setStorage(key, nextWidth);
mutate();
runTimeWidthRef.current = nextWidth;
},
[isCollapsed, mutate]
);
useEffect(() => {
mutate();
@ -36,14 +39,14 @@ export const useDragableWidth = () => {
return () => {
runTimeWidthRef.current = null;
};
}, []);
}, [mutate]);
useEffect(() => {
if (!windowSize.width) return;
if (windowSize.width <= 765) {
toggleCollapsed(true);
}
}, [windowSize.width]);
}, [windowSize.width, toggleCollapsed]);
return {
width: data,

View File

@ -34,7 +34,7 @@ export const Recent = () => {
{recentDocs.length ? (
recentDocs.map((doc) => {
return (
<div className={styles.itemWrap}>
<div className={styles.itemWrap} key={doc.id}>
<Link
href={{
pathname: '/wiki/[wikiId]/document/[documentId]',

View File

@ -88,7 +88,7 @@ export const Wiki = () => {
{starWikis.length ? (
starWikis.map((wiki) => {
return (
<div className={styles.itemWrap}>
<div className={styles.itemWrap} key={wiki.id}>
<Link
href={{
pathname: '/wiki/[wikiId]',

View File

@ -34,7 +34,7 @@ export const Recent = () => {
{recentDocs.length ? (
recentDocs.map((doc) => {
return (
<div className={styles.itemWrap}>
<div className={styles.itemWrap} key={doc.id}>
<Link
href={{
pathname: '/wiki/[wikiId]/document/[documentId]',

View File

@ -88,7 +88,7 @@ export const Wiki = () => {
{starWikis.length ? (
starWikis.map((wiki) => {
return (
<div className={styles.itemWrap}>
<div className={styles.itemWrap} key={wiki.id}>
<Link
href={{
pathname: '/wiki/[wikiId]',

View File

@ -1,5 +1,6 @@
import type { AppProps } from 'next/app';
import Head from 'next/head';
import React from 'react';
import { useTheme } from 'hooks/use-theme';
import 'viewerjs/dist/viewer.css';
import 'styles/globals.scss';

View File

@ -67,7 +67,7 @@ const RecentDocs = () => {
)}
/>,
],
[]
[refresh]
);
return (

View File

@ -1,4 +1,5 @@
import Link from 'next/link';
import React from 'react';
import { Form, Button, Layout, Space, Typography } from '@douyinfe/semi-ui';
import { useUser } from 'data/user';
import { Seo } from 'components/seo';

View File

@ -1,3 +1,4 @@
import React from 'react';
import Router from 'next/router';
import Link from 'next/link';
import { Form, Button, Layout, Space, Typography, Modal } from '@douyinfe/semi-ui';

View File

@ -1,3 +1,4 @@
import React from 'react';
import { NextPage } from 'next';
import { DocumentPublicReader } from 'components/document/reader/public';

View File

@ -1,3 +1,4 @@
import React from 'react';
import { NextPage } from 'next';
import { PublicDoubleColumnLayout } from 'layouts/public-double-column';
import { WikiPublicTocs } from 'components/wiki/tocs/public';

View File

@ -1,3 +1,4 @@
import React from 'react';
import { NextPage } from 'next';
import { PublicDoubleColumnLayout } from 'layouts/public-double-column';
import { usePublicWikiHomeDoc } from 'data/wiki';

View File

@ -1,4 +1,5 @@
import { NextPage } from 'next';
import React from 'react';
import { DocumentEditor } from 'components/document/editor';
interface IProps {

View File

@ -1,4 +1,5 @@
import { NextPage } from 'next';
import React from 'react';
import { DoubleColumnLayout } from 'layouts/double-column';
import { WikiTocs } from 'components/wiki/tocs';
import { DocumentReader } from 'components/document/reader';

View File

@ -1,4 +1,5 @@
import { NextPage } from 'next';
import React from 'react';
import { DoubleColumnLayout } from 'layouts/double-column';
import { useWikiHomeDoc } from 'data/wiki';
import { DataRender } from 'components/data-render';
@ -14,7 +15,7 @@ const Page: NextPage<IProps> = ({ wikiId }) => {
return (
<DoubleColumnLayout
leftNode={<WikiTocs pageTitle="概览" wikiId={wikiId} />}
leftNode={<WikiTocs wikiId={wikiId} />}
rightNode={
<DataRender
loading={loading}

View File

@ -1,4 +1,4 @@
import { useCallback } from 'react';
import React, { useCallback } from 'react';
import { NextPage } from 'next';
import Router, { useRouter } from 'next/router';
import { DoubleColumnLayout } from 'layouts/double-column';
@ -15,14 +15,17 @@ const Page: NextPage<IProps> = ({ wikiId }) => {
tab?: string;
};
const navigate = useCallback((tab = 'base') => {
return () => {
Router.push({
pathname: `/wiki/${wikiId}/setting`,
query: { tab },
});
};
}, []);
const navigate = useCallback(
(tab = 'base') => {
return () => {
Router.push({
pathname: `/wiki/${wikiId}/setting`,
query: { tab },
});
};
},
[wikiId]
);
return (
<DoubleColumnLayout

File diff suppressed because it is too large Load Diff