mirror of https://github.com/fantasticit/think.git
refactor: lint code
This commit is contained in:
parent
1dac849b61
commit
76cdcff589
|
@ -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
|
|
@ -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'],
|
||||||
|
};
|
|
@ -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',
|
||||||
|
},
|
||||||
|
};
|
14
package.json
14
package.json
|
@ -20,8 +20,10 @@
|
||||||
"pm2": "pnpm run pm2:server && pnpm run pm2:client",
|
"pm2": "pnpm run pm2:server && pnpm run pm2:client",
|
||||||
"pm2:server": "pnpm run --dir packages/server pm2",
|
"pm2:server": "pnpm run --dir packages/server pm2",
|
||||||
"pm2:client": "pnpm run --dir packages/client 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": "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}\"",
|
"format:css": "stylelint --fix --formatter verbose --allow-empty-input \"packages/**/*.{css,scss,sass}\"",
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"precommit": "lint-staged"
|
"precommit": "lint-staged"
|
||||||
|
@ -36,6 +38,16 @@
|
||||||
"node": ">=16.5.0"
|
"node": ">=16.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"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",
|
"husky": "^7.0.4",
|
||||||
"lint-staged": "^12.4.1",
|
"lint-staged": "^12.4.1",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
const semi = require('@douyinfe/semi-next').default({});
|
/* eslint-disable */
|
||||||
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
|
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
|
||||||
const { getConfig } = require('@think/config');
|
const { getConfig } = require('@think/config');
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
|
|
||||||
/** @type {import('next').NextConfig} */
|
const nextConfig = require('@douyinfe/semi-next').default({})({
|
||||||
const nextConfig = semi({
|
|
||||||
assetPrefix: config.assetPrefix,
|
assetPrefix: config.assetPrefix,
|
||||||
env: {
|
env: {
|
||||||
SERVER_API_URL: config?.client?.apiUrl,
|
SERVER_API_URL: config?.client?.apiUrl,
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const Banner: React.FC<IProps> = ({ type, description, duration = 0 }) =>
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timer.current);
|
clearTimeout(timer.current);
|
||||||
};
|
};
|
||||||
}, [duration]);
|
}, [duration, toggleVisible]);
|
||||||
|
|
||||||
if (!visible) return null;
|
if (!visible) return null;
|
||||||
|
|
||||||
|
|
|
@ -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> = ({
|
export const DataRender: React.FC<IProps> = ({
|
||||||
loading,
|
loading,
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const LoadingWrap: React.FC<IProps> = ({ loading, delay = 200, loadingCon
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timer.current);
|
clearTimeout(timer.current);
|
||||||
};
|
};
|
||||||
}, [delay, loading]);
|
}, [delay, loading, toggleShowLoading]);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return showLoading ? loadingContent : null;
|
return showLoading ? loadingContent : null;
|
||||||
|
|
|
@ -31,6 +31,7 @@ interface IProps {
|
||||||
const { Paragraph } = Typography;
|
const { Paragraph } = Typography;
|
||||||
const { Column } = Table;
|
const { Column } = Table;
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, docAuth) => {
|
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, docAuth) => {
|
||||||
const handle = (evt) => {
|
const handle = (evt) => {
|
||||||
const data = {
|
const data = {
|
||||||
|
@ -67,8 +68,8 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handler = (users) => {
|
const handler = (mentionUsers) => {
|
||||||
const newCollaborationUsers = users
|
const newCollaborationUsers = mentionUsers
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.filter((state) => state.user)
|
.filter((state) => state.user)
|
||||||
.map((state) => ({ ...state.user, clientId: state.clientId }));
|
.map((state) => ({ ...state.user, clientId: state.clientId }));
|
||||||
|
@ -90,6 +91,7 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
|
||||||
|
|
||||||
setCollaborationUsers(newCollaborationUsers);
|
setCollaborationUsers(newCollaborationUsers);
|
||||||
};
|
};
|
||||||
|
|
||||||
event.on(JOIN_USER, handler);
|
event.on(JOIN_USER, handler);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
|
|
@ -16,10 +16,11 @@ interface IProps {
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
export const CommentItem: React.FC<IProps> = ({ comment, replyComment, editComment, deleteComment }) => {
|
export const CommentItem: React.FC<IProps> = ({ comment, replyComment, editComment, deleteComment }) => {
|
||||||
if (!comment) return null;
|
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
const { createUser = {} } = comment;
|
const { createUser = {} } = comment;
|
||||||
|
|
||||||
|
if (!comment) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
<div className={styles.leftWrap}>
|
<div className={styles.leftWrap}>
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const DocumentDeletor: React.FC<IProps> = ({ wikiId, documentId, onDelete
|
||||||
okButtonProps: { loading, type: 'danger' },
|
okButtonProps: { loading, type: 'danger' },
|
||||||
style: { maxWidth: '96vw' },
|
style: { maxWidth: '96vw' },
|
||||||
});
|
});
|
||||||
}, [wikiId, documentId, api, loading, onDelete]);
|
}, [wikiId, api, loading, onDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text type="danger" onClick={deleteAction}>
|
<Text type="danger" onClick={deleteAction}>
|
||||||
|
|
|
@ -15,6 +15,7 @@ interface IProps {
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
const { Column } = Table;
|
const { Column } = Table;
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, data) => {
|
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, data) => {
|
||||||
const handle = (evt) => {
|
const handle = (evt) => {
|
||||||
const ret = {
|
const ret = {
|
||||||
|
|
|
@ -27,8 +27,6 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
|
export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
|
||||||
if (!documentId) return null;
|
|
||||||
|
|
||||||
const [container, setContainer] = useState<HTMLDivElement>();
|
const [container, setContainer] = useState<HTMLDivElement>();
|
||||||
const { width: windowWidth } = useWindowSize();
|
const { width: windowWidth } = useWindowSize();
|
||||||
const { width, fontSize } = useDocumentStyle();
|
const { width, fontSize } = useDocumentStyle();
|
||||||
|
@ -43,6 +41,8 @@ export const DocumentReader: React.FC<IProps> = ({ documentId }) => {
|
||||||
Router.push(`/wiki/${document.wikiId}/document/${document.id}/edit`);
|
Router.push(`/wiki/${document.wikiId}/document/${document.id}/edit`);
|
||||||
}, [document]);
|
}, [document]);
|
||||||
|
|
||||||
|
if (!documentId) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
<Header className={styles.headerWrap}>
|
<Header className={styles.headerWrap}>
|
||||||
|
|
|
@ -12,7 +12,7 @@ interface IProps {
|
||||||
|
|
||||||
export const DocumentContent: React.FC<IProps> = ({ document, createUserContainerSelector }) => {
|
export const DocumentContent: React.FC<IProps> = ({ document, createUserContainerSelector }) => {
|
||||||
const c = safeJSONParse(document.content);
|
const c = safeJSONParse(document.content);
|
||||||
let json = c.default || c;
|
const json = c.default || c;
|
||||||
|
|
||||||
const editor = useEditor({
|
const editor = useEditor({
|
||||||
editable: false,
|
editable: false,
|
||||||
|
|
|
@ -37,8 +37,6 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo = true }) => {
|
export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo = true }) => {
|
||||||
if (!documentId) return null;
|
|
||||||
|
|
||||||
const { data, loading, error, query } = usePublicDocument(documentId);
|
const { data, loading, error, query } = usePublicDocument(documentId);
|
||||||
const { width, fontSize } = useDocumentStyle();
|
const { width, fontSize } = useDocumentStyle();
|
||||||
const editorWrapClassNames = useMemo(() => {
|
const editorWrapClassNames = useMemo(() => {
|
||||||
|
@ -72,6 +70,8 @@ export const DocumentPublicReader: React.FC<IProps> = ({ documentId, hideLogo =
|
||||||
});
|
});
|
||||||
}, [error, query]);
|
}, [error, query]);
|
||||||
|
|
||||||
|
if (!documentId) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout className={styles.wrap}>
|
<Layout className={styles.wrap}>
|
||||||
<Header className={styles.headerWrap}>
|
<Header className={styles.headerWrap}>
|
||||||
|
|
|
@ -32,7 +32,7 @@ export const DocumentVersion: React.FC<IProps> = ({ documentId, onSelect }) => {
|
||||||
const close = useCallback(() => {
|
const close = useCallback(() => {
|
||||||
toggleVisible(false);
|
toggleVisible(false);
|
||||||
setSelectedVersion(null);
|
setSelectedVersion(null);
|
||||||
}, []);
|
}, [toggleVisible]);
|
||||||
|
|
||||||
const select = useCallback(
|
const select = useCallback(
|
||||||
(version) => {
|
(version) => {
|
||||||
|
@ -46,20 +46,20 @@ export const DocumentVersion: React.FC<IProps> = ({ documentId, onSelect }) => {
|
||||||
if (!selectedVersion || !onSelect) return;
|
if (!selectedVersion || !onSelect) return;
|
||||||
onSelect(safeJSONParse(selectedVersion.data, { default: {} }).default);
|
onSelect(safeJSONParse(selectedVersion.data, { default: {} }).default);
|
||||||
close();
|
close();
|
||||||
}, [selectedVersion]);
|
}, [selectedVersion, close, onSelect]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
}, [visible]);
|
}, [visible, refresh]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!editor) return;
|
if (!editor) return;
|
||||||
if (!data.length) return;
|
if (!data.length) return;
|
||||||
if (selectedVersion) return;
|
if (selectedVersion) return;
|
||||||
select(data[0]);
|
select(data[0]);
|
||||||
}, [editor, data, selectedVersion]);
|
}, [editor, data, selectedVersion, select]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -60,15 +60,12 @@ export const GridSelect = ({
|
||||||
[onSelect]
|
[onSelect]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onHover = useCallback(
|
const onHover = useCallback(({ x, y, isCellDisabled }) => {
|
||||||
debounce(({ x, y, isCellDisabled }) => {
|
if (isCellDisabled) {
|
||||||
if (isCellDisabled) {
|
return setHoverCell(null);
|
||||||
return setHoverCell(null);
|
}
|
||||||
}
|
setHoverCell({ x, y });
|
||||||
setHoverCell({ x, y });
|
}, []);
|
||||||
}, 5),
|
|
||||||
[disabled]
|
|
||||||
);
|
|
||||||
|
|
||||||
const cells = useMemo(() => {
|
const cells = useMemo(() => {
|
||||||
const cells = [];
|
const cells = [];
|
||||||
|
|
|
@ -40,7 +40,7 @@ const MessagesRender = ({ messageData, loading, error, onClick = null, page = 1,
|
||||||
<>
|
<>
|
||||||
{messages.map((msg) => {
|
{messages.map((msg) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.itemWrap} onClick={() => handleRead(msg.id)}>
|
<div key={msg.id} className={styles.itemWrap} onClick={() => handleRead(msg.id)}>
|
||||||
<Link href={msg.url}>
|
<Link href={msg.url}>
|
||||||
<a className={styles.item}>
|
<a className={styles.item}>
|
||||||
<div className={styles.leftWrap}>
|
<div className={styles.leftWrap}>
|
||||||
|
@ -140,7 +140,7 @@ const MessageBox = () => {
|
||||||
readMessage(msg.id);
|
readMessage(msg.id);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}, [unreadMsgs]);
|
}, [unreadMsgs, readMessage]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
|
|
|
@ -112,7 +112,7 @@ export const Resizeable: React.FC<IProps> = ({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}, [maxWidth, isEditable]);
|
}, [maxWidth, isEditable, onChange, onChangeEnd]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Object.assign($container.current.style, {
|
Object.assign($container.current.style, {
|
||||||
|
|
|
@ -40,7 +40,6 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTemplate, deleteTemplate }) => {
|
export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTemplate, deleteTemplate }) => {
|
||||||
if (!user) return null;
|
|
||||||
const { width: windowWidth } = useWindowSize();
|
const { width: windowWidth } = useWindowSize();
|
||||||
const [title, setTitle] = useState(data.title);
|
const [title, setTitle] = useState(data.title);
|
||||||
const provider = useMemo(() => {
|
const provider = useMemo(() => {
|
||||||
|
@ -51,7 +50,7 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
|
||||||
user,
|
user,
|
||||||
docType: 'template',
|
docType: 'template',
|
||||||
});
|
});
|
||||||
}, [data, user.token]);
|
}, [data, user]);
|
||||||
const editor = useEditor({
|
const editor = useEditor({
|
||||||
editable: true,
|
editable: true,
|
||||||
extensions: [...BaseKit, DocumentWithTitle, getCollaborationExtension(provider)],
|
extensions: [...BaseKit, DocumentWithTitle, getCollaborationExtension(provider)],
|
||||||
|
@ -59,7 +58,9 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
|
||||||
try {
|
try {
|
||||||
const title = transaction.doc.content.firstChild.content.firstChild.textContent;
|
const title = transaction.doc.content.firstChild.content.firstChild.textContent;
|
||||||
setTitle(title);
|
setTitle(title);
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const [isPublic, setPublic] = useState(false);
|
const [isPublic, setPublic] = useState(false);
|
||||||
|
@ -76,7 +77,7 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
|
||||||
deleteTemplate().then(() => {
|
deleteTemplate().then(() => {
|
||||||
goback();
|
goback();
|
||||||
});
|
});
|
||||||
}, [deleteTemplate]);
|
}, [deleteTemplate, goback]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
@ -99,6 +100,8 @@ export const Editor: React.FC<IProps> = ({ user, data, loading, error, updateTem
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
if (!user) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
<header>
|
<header>
|
||||||
|
|
|
@ -38,7 +38,7 @@ export const TemplateList: React.FC<IProps> = ({
|
||||||
const start = (page - 1) * pageSize;
|
const start = (page - 1) * pageSize;
|
||||||
const end = page * pageSize;
|
const end = page * pageSize;
|
||||||
return arr.slice(start, end);
|
return arr.slice(start, end);
|
||||||
}, [data, page]);
|
}, [data, page, pageSize]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DataRender
|
<DataRender
|
||||||
|
|
|
@ -21,8 +21,6 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Editor: React.FC<IProps> = ({ user, data, loading, error }) => {
|
export const Editor: React.FC<IProps> = ({ user, data, loading, error }) => {
|
||||||
if (!user) return null;
|
|
||||||
|
|
||||||
const c = safeJSONParse(data.content);
|
const c = safeJSONParse(data.content);
|
||||||
let json = c.default || c;
|
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;
|
return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth;
|
||||||
}, [width]);
|
}, [width]);
|
||||||
|
|
||||||
|
if (!user) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
<Layout className={styles.contentWrap}>
|
<Layout className={styles.contentWrap}>
|
||||||
|
|
|
@ -26,7 +26,7 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
|
||||||
const [publicDocumentIds, setPublicDocumentIds] = useState([]); // 公开的
|
const [publicDocumentIds, setPublicDocumentIds] = useState([]); // 公开的
|
||||||
const privateDocumentIds = useMemo(() => {
|
const privateDocumentIds = useMemo(() => {
|
||||||
return documents.filter((doc) => !publicDocumentIds.includes(doc.id)).map((doc) => doc.id);
|
return documents.filter((doc) => !publicDocumentIds.includes(doc.id)).map((doc) => doc.id);
|
||||||
}, [tocs, publicDocumentIds]);
|
}, [documents, publicDocumentIds]);
|
||||||
|
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
const data = { nextStatus, publicDocumentIds, privateDocumentIds };
|
const data = { nextStatus, publicDocumentIds, privateDocumentIds };
|
||||||
|
@ -77,7 +77,7 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
|
||||||
if (!documents.length) return;
|
if (!documents.length) return;
|
||||||
const activeIds = documents.filter((doc) => isPublicDocument(doc.status)).map((doc) => doc.id);
|
const activeIds = documents.filter((doc) => isPublicDocument(doc.status)).map((doc) => doc.id);
|
||||||
setPublicDocumentIds(activeIds);
|
setPublicDocumentIds(activeIds);
|
||||||
}, [tocs]);
|
}, [tocs, documents]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
|
@ -115,7 +115,11 @@ export const Documents: React.FC<IProps> = ({ wikiId }) => {
|
||||||
</Title>
|
</Title>
|
||||||
<RadioGroup direction="vertical" value={nextStatus} onChange={(e) => setNextStatus(e.target.value)}>
|
<RadioGroup direction="vertical" value={nextStatus} onChange={(e) => setNextStatus(e.target.value)}>
|
||||||
{WIKI_STATUS_LIST.map((status) => {
|
{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>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -20,7 +20,7 @@ export const AddUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) => {
|
||||||
setUserName('');
|
setUserName('');
|
||||||
toggleVisible(false);
|
toggleVisible(false);
|
||||||
});
|
});
|
||||||
}, [onOk, userName, userRole]);
|
}, [onOk, userName, userRole, toggleVisible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -40,7 +40,11 @@ export const AddUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) => {
|
||||||
<Space>
|
<Space>
|
||||||
<Select value={userRole} onChange={setUserRole} style={{ width: 120 }}>
|
<Select value={userRole} onChange={setUserRole} style={{ width: 120 }}>
|
||||||
{WIKI_USER_ROLES.map((wikiStatus) => {
|
{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>
|
</Select>
|
||||||
<Input
|
<Input
|
||||||
|
|
|
@ -15,7 +15,7 @@ export const EditUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) =>
|
||||||
setUserRole(WikiUserRole.normal);
|
setUserRole(WikiUserRole.normal);
|
||||||
toggleVisible(false);
|
toggleVisible(false);
|
||||||
});
|
});
|
||||||
}, [onOk, userRole]);
|
}, [onOk, userRole, toggleVisible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -33,7 +33,11 @@ export const EditUser: React.FC<IProps> = ({ visible, toggleVisible, onOk }) =>
|
||||||
) : null}
|
) : null}
|
||||||
<Select value={userRole} onChange={setUserRole} style={{ width: '100%' }}>
|
<Select value={userRole} onChange={setUserRole} style={{ width: '100%' }}>
|
||||||
{WIKI_USER_ROLES.map((wikiStatus) => {
|
{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>
|
</Select>
|
||||||
<Button theme="solid" block style={{ margin: '24px 0' }} onClick={handleOk}>
|
<Button theme="solid" block style={{ margin: '24px 0' }} onClick={handleOk}>
|
||||||
|
|
|
@ -47,7 +47,7 @@ export const WikiTocs: React.FC<IProps> = ({
|
||||||
return () => {
|
return () => {
|
||||||
event.off(REFRESH_TOCS, handler);
|
event.off(REFRESH_TOCS, handler);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [refresh]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
|
|
|
@ -56,7 +56,7 @@ const AddDocument = () => {
|
||||||
return () => {
|
return () => {
|
||||||
event.off(CREATE_DOCUMENT, handler);
|
event.off(CREATE_DOCUMENT, handler);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [toggleVisible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DocumenCreatorForm wikiId={wikiId} parentDocumentId={documentId} visible={visible} toggleVisible={toggleVisible} />
|
<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)}
|
{isShareMode ? null : renderBtn(item)}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
[isShareMode]
|
[isShareMode, docAsLink, getDocLink, renderBtn]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -148,12 +148,12 @@ export const usePublicDocument = (documentId: string) => {
|
||||||
})
|
})
|
||||||
.catch(setError);
|
.catch(setError);
|
||||||
},
|
},
|
||||||
[documentId, error]
|
[fetch, documentId]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
queryData();
|
queryData();
|
||||||
}, [documentId]);
|
}, [documentId, queryData]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: document,
|
data: document,
|
||||||
|
|
|
@ -14,18 +14,21 @@ export const useUser = () => {
|
||||||
window.localStorage.removeItem('token');
|
window.localStorage.removeItem('token');
|
||||||
mutate(null);
|
mutate(null);
|
||||||
Router.replace('/login');
|
Router.replace('/login');
|
||||||
}, []);
|
}, [mutate]);
|
||||||
|
|
||||||
const login = useCallback((data) => {
|
const login = useCallback(
|
||||||
HttpClient.post<IUser>('/user/login', data).then((res) => {
|
(data) => {
|
||||||
const user = res as unknown as ILoginUser;
|
HttpClient.post<IUser>('/user/login', data).then((res) => {
|
||||||
mutate(user);
|
const user = res as unknown as ILoginUser;
|
||||||
setStorage('user', JSON.stringify(user));
|
mutate(user);
|
||||||
user.token && setStorage('token', user.token);
|
setStorage('user', JSON.stringify(user));
|
||||||
const next = router.query?.redirect || '/';
|
user.token && setStorage('token', user.token);
|
||||||
Router.replace(next as string);
|
const next = router.query?.redirect || '/';
|
||||||
});
|
Router.replace(next as string);
|
||||||
}, []);
|
});
|
||||||
|
},
|
||||||
|
[mutate, router.query?.redirect]
|
||||||
|
);
|
||||||
|
|
||||||
const updateUser = async (patch: Pick<IUser, 'email' | 'avatar'>) => {
|
const updateUser = async (patch: Pick<IUser, 'email' | 'avatar'>) => {
|
||||||
const res = await HttpClient.patch('/user/update', patch);
|
const res = await HttpClient.patch('/user/update', patch);
|
||||||
|
@ -36,7 +39,7 @@ export const useUser = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mutate();
|
mutate();
|
||||||
}, []);
|
}, [mutate]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
user: data,
|
user: data,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var deselectCurrent = require('toggle-selection');
|
var deselectCurrent = require('toggle-selection');
|
||||||
|
@ -59,7 +60,7 @@ function copy(text, options) {
|
||||||
window.clipboardData.clearData();
|
window.clipboardData.clearData();
|
||||||
var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting['default'];
|
var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting['default'];
|
||||||
if (Array.isArray(text)) {
|
if (Array.isArray(text)) {
|
||||||
text.forEach((item) => {
|
text.forEach(function (item) {
|
||||||
if (typeof item === 'string') {
|
if (typeof item === 'string') {
|
||||||
window.clipboardData.setData(item, item);
|
window.clipboardData.setData(item, item);
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,7 +74,7 @@ function copy(text, options) {
|
||||||
// all other browsers
|
// all other browsers
|
||||||
e.clipboardData.clearData();
|
e.clipboardData.clearData();
|
||||||
if (Array.isArray(text)) {
|
if (Array.isArray(text)) {
|
||||||
text.forEach((item) => {
|
text.forEach(function (item) {
|
||||||
if (typeof item === 'string') {
|
if (typeof item === 'string') {
|
||||||
e.clipboardData.setData(item, item);
|
e.clipboardData.setData(item, item);
|
||||||
} else {
|
} else {
|
||||||
|
@ -106,7 +107,7 @@ function copy(text, options) {
|
||||||
debug && console.warn('trying IE specific stuff');
|
debug && console.warn('trying IE specific stuff');
|
||||||
try {
|
try {
|
||||||
if (Array.isArray(text)) {
|
if (Array.isArray(text)) {
|
||||||
text.forEach((item) => {
|
text.forEach(function (item) {
|
||||||
if (typeof item === 'string') {
|
if (typeof item === 'string') {
|
||||||
window.clipboardData.setData(item, item);
|
window.clipboardData.setData(item, item);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -39,7 +39,7 @@ export const useDocumentStyle = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mutate();
|
mutate();
|
||||||
}, []);
|
}, [mutate]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
width: (data && data.width) || DEFAULT_WIDTH,
|
width: (data && data.width) || DEFAULT_WIDTH,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useRef } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { useWindowSize } from 'hooks/use-window-size';
|
import { useWindowSize } from 'hooks/use-window-size';
|
||||||
import { setStorage, getStorage } from 'helpers/storage';
|
import { setStorage, getStorage } from 'helpers/storage';
|
||||||
|
@ -21,14 +21,17 @@ export const useDragableWidth = () => {
|
||||||
runTimeWidthRef.current = size;
|
runTimeWidthRef.current = size;
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleCollapsed = (collapsed = null) => {
|
const toggleCollapsed = useCallback(
|
||||||
const isBool = typeof collapsed === 'boolean';
|
(collapsed = null) => {
|
||||||
const nextCollapsed = isBool ? collapsed : !isCollapsed;
|
const isBool = typeof collapsed === 'boolean';
|
||||||
let nextWidth = nextCollapsed ? COLLAPSED_WIDTH : MIN_WIDTH;
|
const nextCollapsed = isBool ? collapsed : !isCollapsed;
|
||||||
setStorage(key, nextWidth);
|
const nextWidth = nextCollapsed ? COLLAPSED_WIDTH : MIN_WIDTH;
|
||||||
mutate();
|
setStorage(key, nextWidth);
|
||||||
runTimeWidthRef.current = nextWidth;
|
mutate();
|
||||||
};
|
runTimeWidthRef.current = nextWidth;
|
||||||
|
},
|
||||||
|
[isCollapsed, mutate]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mutate();
|
mutate();
|
||||||
|
@ -36,14 +39,14 @@ export const useDragableWidth = () => {
|
||||||
return () => {
|
return () => {
|
||||||
runTimeWidthRef.current = null;
|
runTimeWidthRef.current = null;
|
||||||
};
|
};
|
||||||
}, []);
|
}, [mutate]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!windowSize.width) return;
|
if (!windowSize.width) return;
|
||||||
if (windowSize.width <= 765) {
|
if (windowSize.width <= 765) {
|
||||||
toggleCollapsed(true);
|
toggleCollapsed(true);
|
||||||
}
|
}
|
||||||
}, [windowSize.width]);
|
}, [windowSize.width, toggleCollapsed]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
width: data,
|
width: data,
|
||||||
|
|
|
@ -34,7 +34,7 @@ export const Recent = () => {
|
||||||
{recentDocs.length ? (
|
{recentDocs.length ? (
|
||||||
recentDocs.map((doc) => {
|
recentDocs.map((doc) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.itemWrap}>
|
<div className={styles.itemWrap} key={doc.id}>
|
||||||
<Link
|
<Link
|
||||||
href={{
|
href={{
|
||||||
pathname: '/wiki/[wikiId]/document/[documentId]',
|
pathname: '/wiki/[wikiId]/document/[documentId]',
|
||||||
|
|
|
@ -88,7 +88,7 @@ export const Wiki = () => {
|
||||||
{starWikis.length ? (
|
{starWikis.length ? (
|
||||||
starWikis.map((wiki) => {
|
starWikis.map((wiki) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.itemWrap}>
|
<div className={styles.itemWrap} key={wiki.id}>
|
||||||
<Link
|
<Link
|
||||||
href={{
|
href={{
|
||||||
pathname: '/wiki/[wikiId]',
|
pathname: '/wiki/[wikiId]',
|
||||||
|
|
|
@ -34,7 +34,7 @@ export const Recent = () => {
|
||||||
{recentDocs.length ? (
|
{recentDocs.length ? (
|
||||||
recentDocs.map((doc) => {
|
recentDocs.map((doc) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.itemWrap}>
|
<div className={styles.itemWrap} key={doc.id}>
|
||||||
<Link
|
<Link
|
||||||
href={{
|
href={{
|
||||||
pathname: '/wiki/[wikiId]/document/[documentId]',
|
pathname: '/wiki/[wikiId]/document/[documentId]',
|
||||||
|
|
|
@ -88,7 +88,7 @@ export const Wiki = () => {
|
||||||
{starWikis.length ? (
|
{starWikis.length ? (
|
||||||
starWikis.map((wiki) => {
|
starWikis.map((wiki) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.itemWrap}>
|
<div className={styles.itemWrap} key={wiki.id}>
|
||||||
<Link
|
<Link
|
||||||
href={{
|
href={{
|
||||||
pathname: '/wiki/[wikiId]',
|
pathname: '/wiki/[wikiId]',
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type { AppProps } from 'next/app';
|
import type { AppProps } from 'next/app';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
import React from 'react';
|
||||||
import { useTheme } from 'hooks/use-theme';
|
import { useTheme } from 'hooks/use-theme';
|
||||||
import 'viewerjs/dist/viewer.css';
|
import 'viewerjs/dist/viewer.css';
|
||||||
import 'styles/globals.scss';
|
import 'styles/globals.scss';
|
||||||
|
|
|
@ -67,7 +67,7 @@ const RecentDocs = () => {
|
||||||
)}
|
)}
|
||||||
/>,
|
/>,
|
||||||
],
|
],
|
||||||
[]
|
[refresh]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import React from 'react';
|
||||||
import { Form, Button, Layout, Space, Typography } from '@douyinfe/semi-ui';
|
import { Form, Button, Layout, Space, Typography } from '@douyinfe/semi-ui';
|
||||||
import { useUser } from 'data/user';
|
import { useUser } from 'data/user';
|
||||||
import { Seo } from 'components/seo';
|
import { Seo } from 'components/seo';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import React from 'react';
|
||||||
import Router from 'next/router';
|
import Router from 'next/router';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Form, Button, Layout, Space, Typography, Modal } from '@douyinfe/semi-ui';
|
import { Form, Button, Layout, Space, Typography, Modal } from '@douyinfe/semi-ui';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import React from 'react';
|
||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
import { DocumentPublicReader } from 'components/document/reader/public';
|
import { DocumentPublicReader } from 'components/document/reader/public';
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import React from 'react';
|
||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
import { PublicDoubleColumnLayout } from 'layouts/public-double-column';
|
import { PublicDoubleColumnLayout } from 'layouts/public-double-column';
|
||||||
import { WikiPublicTocs } from 'components/wiki/tocs/public';
|
import { WikiPublicTocs } from 'components/wiki/tocs/public';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import React from 'react';
|
||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
import { PublicDoubleColumnLayout } from 'layouts/public-double-column';
|
import { PublicDoubleColumnLayout } from 'layouts/public-double-column';
|
||||||
import { usePublicWikiHomeDoc } from 'data/wiki';
|
import { usePublicWikiHomeDoc } from 'data/wiki';
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
|
import React from 'react';
|
||||||
import { DocumentEditor } from 'components/document/editor';
|
import { DocumentEditor } from 'components/document/editor';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
|
import React from 'react';
|
||||||
import { DoubleColumnLayout } from 'layouts/double-column';
|
import { DoubleColumnLayout } from 'layouts/double-column';
|
||||||
import { WikiTocs } from 'components/wiki/tocs';
|
import { WikiTocs } from 'components/wiki/tocs';
|
||||||
import { DocumentReader } from 'components/document/reader';
|
import { DocumentReader } from 'components/document/reader';
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
|
import React from 'react';
|
||||||
import { DoubleColumnLayout } from 'layouts/double-column';
|
import { DoubleColumnLayout } from 'layouts/double-column';
|
||||||
import { useWikiHomeDoc } from 'data/wiki';
|
import { useWikiHomeDoc } from 'data/wiki';
|
||||||
import { DataRender } from 'components/data-render';
|
import { DataRender } from 'components/data-render';
|
||||||
|
@ -14,7 +15,7 @@ const Page: NextPage<IProps> = ({ wikiId }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoubleColumnLayout
|
<DoubleColumnLayout
|
||||||
leftNode={<WikiTocs pageTitle="概览" wikiId={wikiId} />}
|
leftNode={<WikiTocs wikiId={wikiId} />}
|
||||||
rightNode={
|
rightNode={
|
||||||
<DataRender
|
<DataRender
|
||||||
loading={loading}
|
loading={loading}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
import Router, { useRouter } from 'next/router';
|
import Router, { useRouter } from 'next/router';
|
||||||
import { DoubleColumnLayout } from 'layouts/double-column';
|
import { DoubleColumnLayout } from 'layouts/double-column';
|
||||||
|
@ -15,14 +15,17 @@ const Page: NextPage<IProps> = ({ wikiId }) => {
|
||||||
tab?: string;
|
tab?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const navigate = useCallback((tab = 'base') => {
|
const navigate = useCallback(
|
||||||
return () => {
|
(tab = 'base') => {
|
||||||
Router.push({
|
return () => {
|
||||||
pathname: `/wiki/${wikiId}/setting`,
|
Router.push({
|
||||||
query: { tab },
|
pathname: `/wiki/${wikiId}/setting`,
|
||||||
});
|
query: { tab },
|
||||||
};
|
});
|
||||||
}, []);
|
};
|
||||||
|
},
|
||||||
|
[wikiId]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoubleColumnLayout
|
<DoubleColumnLayout
|
||||||
|
|
788
pnpm-lock.yaml
788
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue