mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-13 05:39:59 +00:00
optimize wiki links (#7167)
* optimize wiki links * code optimize * fix inner bug
This commit is contained in:
@@ -14,7 +14,7 @@ import PageUtils from './wiki-nav/page-utils';
|
|||||||
import LocalStorage from '../../utils/local-storage-utils';
|
import LocalStorage from '../../utils/local-storage-utils';
|
||||||
import { DEFAULT_PAGE_NAME } from './constant';
|
import { DEFAULT_PAGE_NAME } from './constant';
|
||||||
import { eventBus } from '../../components/common/event-bus';
|
import { eventBus } from '../../components/common/event-bus';
|
||||||
import { throttle } from './utils';
|
import { throttle, getNamePaths } from './utils';
|
||||||
|
|
||||||
import '../../css/layout.css';
|
import '../../css/layout.css';
|
||||||
import '../../css/side-panel.css';
|
import '../../css/side-panel.css';
|
||||||
@@ -88,6 +88,23 @@ class Wiki extends Component {
|
|||||||
return isWiki2 ? 'wikis/' : 'published/';
|
return isWiki2 ? 'wikis/' : 'published/';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setNavConfig = (config, wikiRepoId) => {
|
||||||
|
const { pages } = config;
|
||||||
|
const newPages = JSON.parse(JSON.stringify(pages));
|
||||||
|
newPages.map((item) => {
|
||||||
|
const { path, isDir } = getNamePaths(config, item.id);
|
||||||
|
item['path'] = path;
|
||||||
|
item['doc_uuid'] = item['docUuid'];
|
||||||
|
item['pageId'] = item['id'];
|
||||||
|
item['wikiRepoId'] = wikiRepoId;
|
||||||
|
item['isDir'] = isDir;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
window.wiki.config['navConfig'] = {
|
||||||
|
pages: newPages
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
getWikiConfig = () => {
|
getWikiConfig = () => {
|
||||||
let wikiAPIConfig;
|
let wikiAPIConfig;
|
||||||
if (wikiPermission === 'public') {
|
if (wikiPermission === 'public') {
|
||||||
@@ -98,6 +115,7 @@ class Wiki extends Component {
|
|||||||
wikiAPIConfig.then(res => {
|
wikiAPIConfig.then(res => {
|
||||||
const { wiki_config, repo_id, id: wikiRepoId } = res.data.wiki;
|
const { wiki_config, repo_id, id: wikiRepoId } = res.data.wiki;
|
||||||
const config = new WikiConfig(wiki_config || {});
|
const config = new WikiConfig(wiki_config || {});
|
||||||
|
this.setNavConfig(config, wikiRepoId);
|
||||||
this.setState({
|
this.setState({
|
||||||
config,
|
config,
|
||||||
isConfigLoading: false,
|
isConfigLoading: false,
|
||||||
@@ -212,21 +230,31 @@ class Wiki extends Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
cacheHistoryFiles = (docUuid, name, pageId) => {
|
cacheHistoryFiles = (docUuid, name, pageId, icon) => {
|
||||||
let arr = [];
|
let arr = [];
|
||||||
const { wikiRepoId } = this.state; // different from repoId
|
const { wikiRepoId, config } = this.state; // different from repoId
|
||||||
|
const { path, isDir } = getNamePaths(config, pageId);
|
||||||
const recentFiles = LocalStorage.getItem('wiki-recent-files', []);
|
const recentFiles = LocalStorage.getItem('wiki-recent-files', []);
|
||||||
const newFile = { doc_uuid: docUuid, name: name, wikiRepoId, pageId };
|
const newFile = {
|
||||||
|
doc_uuid: docUuid,
|
||||||
|
name,
|
||||||
|
wikiRepoId,
|
||||||
|
pageId,
|
||||||
|
icon,
|
||||||
|
path,
|
||||||
|
isDir
|
||||||
|
};
|
||||||
if (recentFiles.length) {
|
if (recentFiles.length) {
|
||||||
const isExist = recentFiles.find((item) => item.doc_uuid === docUuid);
|
if (recentFiles.length === 50) {
|
||||||
if (isExist) return;
|
recentFiles.pop();
|
||||||
if (!isExist) {
|
}
|
||||||
|
|
||||||
|
const fileIndex = recentFiles.findIndex((item) => item.doc_uuid === docUuid);
|
||||||
|
if (fileIndex !== -1) {
|
||||||
|
recentFiles.splice(fileIndex, 1);
|
||||||
|
}
|
||||||
let newRecentFiles = recentFiles.slice(0);
|
let newRecentFiles = recentFiles.slice(0);
|
||||||
if (recentFiles.length === 10) {
|
|
||||||
newRecentFiles.shift();
|
|
||||||
}
|
|
||||||
arr = [newFile, ...newRecentFiles];
|
arr = [newFile, ...newRecentFiles];
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
arr.push(newFile);
|
arr.push(newFile);
|
||||||
}
|
}
|
||||||
@@ -245,7 +273,7 @@ class Wiki extends Component {
|
|||||||
callback && callback();
|
callback && callback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { path, id, name, docUuid } = currentPage;
|
const { path, id, name, docUuid, icon } = currentPage;
|
||||||
if (path !== this.state.path) {
|
if (path !== this.state.path) {
|
||||||
this.updateSdocPage(pageId, path);
|
this.updateSdocPage(pageId, path);
|
||||||
}
|
}
|
||||||
@@ -256,7 +284,7 @@ class Wiki extends Component {
|
|||||||
callback && callback();
|
callback && callback();
|
||||||
eventBus.dispatch('update-wiki-current-page');
|
eventBus.dispatch('update-wiki-current-page');
|
||||||
});
|
});
|
||||||
this.cacheHistoryFiles(docUuid, name, id);
|
this.cacheHistoryFiles(docUuid, name, id, icon);
|
||||||
this.updateDocumentTitle(name);
|
this.updateDocumentTitle(name);
|
||||||
|
|
||||||
if (viaPopstate) {
|
if (viaPopstate) {
|
||||||
|
@@ -193,6 +193,31 @@ class SidePanel extends PureComponent {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onAddWikiPage = (jumpToNewPage = true, pageName = DEFAULT_PAGE_NAME, insert_position) => {
|
||||||
|
if (this.isAddingPage === true) return;
|
||||||
|
this.isAddingPage = true;
|
||||||
|
const currentPageId = this.props.getCurrentPageId();
|
||||||
|
wikiAPI.createWiki2Page(wikiId, pageName, currentPageId, insert_position).then(res => {
|
||||||
|
this.isAddingPage = false;
|
||||||
|
const { page_id, obj_name, doc_uuid, parent_dir, page_name } = res.data.file_info;
|
||||||
|
this.addPageInside({
|
||||||
|
parentPageId: currentPageId,
|
||||||
|
page_id: page_id,
|
||||||
|
name: page_name,
|
||||||
|
icon: '',
|
||||||
|
path: parent_dir === '/' ? `/${obj_name}` : `${parent_dir}/${obj_name}`,
|
||||||
|
docUuid: doc_uuid,
|
||||||
|
successCallback: () => {},
|
||||||
|
errorCallback: () => {},
|
||||||
|
jumpToNewPage,
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
|
toaster.danger(errMessage);
|
||||||
|
this.isAddingPage = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isLoading, config } = this.props;
|
const { isLoading, config } = this.props;
|
||||||
return (
|
return (
|
||||||
@@ -209,7 +234,6 @@ class SidePanel extends PureComponent {
|
|||||||
<div className="wiki2-side-nav">
|
<div className="wiki2-side-nav">
|
||||||
{isLoading ? <Loading/> : this.renderWikiNav()}
|
{isLoading ? <Loading/> : this.renderWikiNav()}
|
||||||
</div>
|
</div>
|
||||||
<WikiExternalOperations onAddWikiPage={this.handleAddNewPage.bind(false)}/>
|
|
||||||
{this.state.isShowTrashDialog && (
|
{this.state.isShowTrashDialog && (
|
||||||
<WikiTrashDialog
|
<WikiTrashDialog
|
||||||
showTrashDialog={this.state.isShowTrashDialog}
|
showTrashDialog={this.state.isShowTrashDialog}
|
||||||
@@ -218,7 +242,7 @@ class SidePanel extends PureComponent {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{wikiPermission !== 'public' &&
|
{wikiPermission !== 'public' &&
|
||||||
<WikiExternalOperations onAddWikiPage={this.handleAddNewPage.bind(false)} />
|
<WikiExternalOperations onAddWikiPage={this.onAddWikiPage.bind(false)} />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -2,43 +2,10 @@ import React, { Fragment } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import NavItemIcon from '../common/nav-item-icon';
|
import NavItemIcon from '../common/nav-item-icon';
|
||||||
import CustomIcon from '../custom-icon';
|
import CustomIcon from '../custom-icon';
|
||||||
|
import { getPaths } from '../utils/index';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
// Find the path array from the root to the leaf based on the currentPageId (leaf)
|
|
||||||
function getPaths(navigation, currentPageId, pages) {
|
|
||||||
let idPageMap = {};
|
|
||||||
pages.forEach(page => idPageMap[page.id] = page);
|
|
||||||
navigation.forEach(item => {
|
|
||||||
if (!idPageMap[item.id]) {
|
|
||||||
idPageMap[item.id] = item;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let pathStr = null;
|
|
||||||
function runNode(node) {
|
|
||||||
const newPath = node._path ? (node._path + '-' + node.id) : node.id;
|
|
||||||
if (node.id === currentPageId) {
|
|
||||||
pathStr = newPath;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (node.children) {
|
|
||||||
node.children.forEach(child => {
|
|
||||||
if (child) {
|
|
||||||
child._path = newPath;
|
|
||||||
runNode(child);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let root = {};
|
|
||||||
root.id = '';
|
|
||||||
root._path = '';
|
|
||||||
root.children = navigation;
|
|
||||||
runNode(root);
|
|
||||||
if (!pathStr) return [];
|
|
||||||
return pathStr.split('-').map(id => idPageMap[id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function WikiTopNav({ config, currentPageId, setCurrentPage }) {
|
function WikiTopNav({ config, currentPageId, setCurrentPage }) {
|
||||||
const { navigation, pages } = config;
|
const { navigation, pages } = config;
|
||||||
const paths = getPaths(navigation, currentPageId, pages);
|
const paths = getPaths(navigation, currentPageId, pages);
|
||||||
|
@@ -68,6 +68,66 @@ const throttle = (fn, delay) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Find the path array from the root to the leaf based on the currentPageId (leaf)
|
||||||
|
const getPaths = (navigation, currentPageId, pages, isGetPathStr) => {
|
||||||
|
let idPageMap = {};
|
||||||
|
pages.forEach(page => idPageMap[page.id] = page);
|
||||||
|
navigation.forEach(item => {
|
||||||
|
if (!idPageMap[item.id]) {
|
||||||
|
idPageMap[item.id] = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let pathStr = null;
|
||||||
|
let curNode = null;
|
||||||
|
function runNode(node) {
|
||||||
|
const newPath = node._path ? (node._path + '-' + node.id) : node.id;
|
||||||
|
if (node.id === currentPageId) {
|
||||||
|
pathStr = newPath;
|
||||||
|
curNode = node;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (node.children) {
|
||||||
|
node.children.forEach(child => {
|
||||||
|
if (child) {
|
||||||
|
child._path = newPath;
|
||||||
|
runNode(child);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let root = {};
|
||||||
|
root.id = '';
|
||||||
|
root._path = '';
|
||||||
|
root.children = navigation;
|
||||||
|
runNode(root);
|
||||||
|
if (!pathStr) return [];
|
||||||
|
if (isGetPathStr) return {
|
||||||
|
paths: pathStr,
|
||||||
|
curNode
|
||||||
|
};
|
||||||
|
return pathStr.split('-').map(id => idPageMap[id]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNamePaths = (config, pageId) => {
|
||||||
|
const { navigation, pages } = config;
|
||||||
|
const { paths, curNode } = getPaths(navigation, pageId, pages, true);
|
||||||
|
const pathArr = paths.split('-');
|
||||||
|
const nameArr = [];
|
||||||
|
if (pathArr.length > 1) {
|
||||||
|
pathArr.forEach(pid => {
|
||||||
|
const page = pages.find((item) => item.id === pid);
|
||||||
|
if (page) {
|
||||||
|
const { name } = page;
|
||||||
|
nameArr.push(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
path: nameArr.length === 0 ? '' : nameArr.slice(0, -1).join(' / '),
|
||||||
|
isDir: curNode?.children?.length ? true : false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
generatorBase64Code,
|
generatorBase64Code,
|
||||||
@@ -77,4 +137,6 @@ export {
|
|||||||
getCurrentPageConfig,
|
getCurrentPageConfig,
|
||||||
getWikPageLink,
|
getWikPageLink,
|
||||||
throttle,
|
throttle,
|
||||||
|
getPaths,
|
||||||
|
getNamePaths
|
||||||
};
|
};
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { EventBus, EXTERNAL_EVENT } from '@seafile/sdoc-editor';
|
import { EventBus, EXTERNAL_EVENT } from '@seafile/sdoc-editor';
|
||||||
import AddWikiPageDialog from '../../components/dialog/add-wiki-page-dialog';
|
import AddWikiPageDialog from '../../components/dialog/add-wiki-page-dialog';
|
||||||
|
import { INSERT_POSITION } from './wiki-nav/constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
onAddWikiPage: PropTypes.func.isRequired,
|
onAddWikiPage: PropTypes.func.isRequired,
|
||||||
@@ -27,10 +28,7 @@ class WikiExternalOperations extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAddWikiPageDialogDisplayed = ({ newFileName: wikiPageName = '' }) => {
|
onAddWikiPageDialogDisplayed = ({ newFileName: wikiPageName = '' }) => {
|
||||||
this.setState({
|
this.props.onAddWikiPage(false, wikiPageName, INSERT_POSITION.INNER);
|
||||||
wikiPageName,
|
|
||||||
isShowAddWikiPageDialog: true,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
changeAddWikiPageDialogDisplayed = () => {
|
changeAddWikiPageDialogDisplayed = () => {
|
||||||
|
Reference in New Issue
Block a user