From 17114eb2fc5e8f690ebcb4948e804c9c2ca6e027 Mon Sep 17 00:00:00 2001
From: Michael An <2331806369@qq.com>
Date: Wed, 3 Jul 2024 17:57:10 +0800
Subject: [PATCH] 12.0 refactor wiki folder (#6290)
* 01 remove wiki folder
* remove folder
* 03 remove wiki folder css
* 04 optimise codes
---
frontend/src/assets/icons/wiki-folder.svg | 24 --
frontend/src/pages/wiki2/constant.js | 4 -
frontend/src/pages/wiki2/css/wiki-nav.css | 145 +--------
frontend/src/pages/wiki2/index.js | 11 +-
frontend/src/pages/wiki2/models/folder.js | 8 -
.../src/pages/wiki2/models/wiki-config.js | 44 ++-
frontend/src/pages/wiki2/side-panel.js | 255 ++--------------
frontend/src/pages/wiki2/top-nav/index.jsx | 2 +-
.../wiki2/wiki-nav/add-page-dropdownmenu.js | 52 ----
frontend/src/pages/wiki2/wiki-nav/constant.js | 2 -
.../wiki-nav/folders/dragged-folder-item.js | 103 -------
.../wiki2/wiki-nav/folders/folder-item.js | 284 ------------------
.../folders/folder-operation-dropdownmenu.js | 75 -----
.../pages/wiki2/wiki-nav/new-folder-dialog.js | 98 ------
.../src/pages/wiki2/wiki-nav/page-utils.js | 169 +----------
.../wiki2/wiki-nav/pages/dragged-page-item.js | 42 +--
.../wiki2/wiki-nav/pages/page-dropdownmenu.js | 98 +-----
.../pages/wiki2/wiki-nav/pages/page-item.js | 46 +--
.../pages/wiki2/wiki-nav/wiki-nav-footer.js | 48 ---
frontend/src/pages/wiki2/wiki-nav/wiki-nav.js | 124 +-------
20 files changed, 119 insertions(+), 1515 deletions(-)
delete mode 100644 frontend/src/assets/icons/wiki-folder.svg
delete mode 100644 frontend/src/pages/wiki2/constant.js
delete mode 100644 frontend/src/pages/wiki2/models/folder.js
delete mode 100644 frontend/src/pages/wiki2/wiki-nav/add-page-dropdownmenu.js
delete mode 100644 frontend/src/pages/wiki2/wiki-nav/constant.js
delete mode 100644 frontend/src/pages/wiki2/wiki-nav/folders/dragged-folder-item.js
delete mode 100644 frontend/src/pages/wiki2/wiki-nav/folders/folder-item.js
delete mode 100644 frontend/src/pages/wiki2/wiki-nav/folders/folder-operation-dropdownmenu.js
delete mode 100644 frontend/src/pages/wiki2/wiki-nav/new-folder-dialog.js
delete mode 100644 frontend/src/pages/wiki2/wiki-nav/wiki-nav-footer.js
diff --git a/frontend/src/assets/icons/wiki-folder.svg b/frontend/src/assets/icons/wiki-folder.svg
deleted file mode 100644
index 2bb0e7eb9a..0000000000
--- a/frontend/src/assets/icons/wiki-folder.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
diff --git a/frontend/src/pages/wiki2/constant.js b/frontend/src/pages/wiki2/constant.js
deleted file mode 100644
index 1d1b537b08..0000000000
--- a/frontend/src/pages/wiki2/constant.js
+++ /dev/null
@@ -1,4 +0,0 @@
-const FOLDER = 'folder';
-const PAGE = 'page';
-
-export { FOLDER, PAGE };
diff --git a/frontend/src/pages/wiki2/css/wiki-nav.css b/frontend/src/pages/wiki2/css/wiki-nav.css
index 0516740bed..f3c134e548 100644
--- a/frontend/src/pages/wiki2/css/wiki-nav.css
+++ b/frontend/src/pages/wiki2/css/wiki-nav.css
@@ -15,14 +15,11 @@
padding-bottom: 0.5rem;
overflow: auto;
user-select: none;
+ max-height: 100%;
}
-.wiki-nav .page-folder {
- position: relative;
-}
-
-.wiki-nav .page-folder.can-drop::after,
-.wiki-nav .page-folder.can-drop-top::after {
+.wiki-nav .can-drop::after,
+.wiki-nav .can-drop-top::after {
content: '';
width: 100%;
height: 1px;
@@ -32,7 +29,16 @@
background-color: #666;
}
-.wiki-nav .page-folder .page-folder-children {
+.wiki-nav .can-drop::after {
+ top: unset;
+ bottom: 0;
+}
+
+.wiki-nav .can-drop-top::after {
+ top: 0;
+}
+
+.wiki-nav .page-children {
transition: height 0.25s ease-in-out 0s;
}
@@ -44,16 +50,6 @@
border-bottom: 1px solid #666;
}
-.wiki-nav .page-folder.can-drop::after {
- top: unset;
- bottom: 0;
-}
-
-.wiki-nav .page-folder.can-drop-top::after {
- top: 0;
-}
-
-.wiki-nav .page-folder-wrapper,
.wiki-nav .wiki-page-item {
position: relative;
display: flex;
@@ -72,7 +68,6 @@
background-color: #EDEDEA;
}
-.wiki-nav .page-folder-wrapper:hover,
.wiki-nav .wiki-page-item:hover {
background-color: #EFEFED;
}
@@ -81,7 +76,6 @@
background-color: #E6E6E4;
}
-.wiki-nav .folder-main,
.wiki-nav .wiki-page-item-main {
flex: 1;
display: flex;
@@ -90,15 +84,6 @@
overflow: hidden;
}
-.wiki-nav .icon-expand-folder {
- display: inline-block;
- font-size: 12px;
- transform: scale(0.8);
- color: #b5b5b5;
- cursor: pointer;
-}
-
-.wiki-nav .folder-content,
.wiki-nav .wiki-page-content {
height: 100%;
padding-right: 8px;
@@ -109,29 +94,25 @@
overflow: hidden;
}
-.wiki-nav .in-folder .wiki-page-content {
+.wiki-nav .wiki-page-content {
padding-left: calc(12 * 0.8px + 0.5rem);
}
-.wiki-nav .folder-content:hover,
.wiki-nav .wiki-page-content:hover {
cursor: pointer;
}
-.wiki-nav .folder-content .dtable-font,
.wiki-nav .wiki-page-content .dtable-font {
margin-right: 6px;
font-size: 14px;
}
-.wiki-nav .folder-content .folder-name,
.wiki-nav .wiki-page-content .wiki-page-title {
height: 40px;
line-height: 40px;
flex: 1;
}
-.wiki-nav .folder-operation-dropdownmenu,
.wiki-nav .more-wiki-page-operation {
width: 24px;
height: 24px;
@@ -141,37 +122,31 @@
}
.wiki-nav .wiki-add-page-btn:hover,
-.wiki-nav .folder-operation:hover,
.wiki-nav .more-wiki-page-operation:hover {
border-radius: 3px;
background-color: #DFDFDD;
}
.wiki-nav .wiki-page-item .sf3-font.sf3-font-enlarge,
-.wiki-nav .page-folder-wrapper .folder-operation-dropdownmenu .seafile-multicolor-icon-more-level,
.wiki-nav .wiki-page-item .more-wiki-page-operation .seafile-multicolor-icon-more-level {
cursor: pointer;
opacity: 0;
}
.wiki-nav .wiki-page-item:hover .sf3-font.sf3-font-enlarge,
-.wiki-nav .page-folder-wrapper:hover .folder-operation-dropdownmenu .seafile-multicolor-icon-more-level,
.wiki-nav .wiki-page-item:hover .more-wiki-page-operation .seafile-multicolor-icon-more-level {
opacity: 1;
}
-.wiki-nav .folder-operation-dropdownmenu:hover,
.wiki-nav .more-wiki-page-operation:hover {
cursor: pointer;
}
-.wiki-nav .folder-operation-dropdownmenu .dtable-font,
.wiki-nav .more-wiki-page-operation .dtable-font {
font-size: 14px;
margin-right: 10px;
}
-.wiki-nav .folder-list .page-folder.fold-freezed .btn-folder-operation,
.wiki-nav .wiki-page-item.wiki-page-freezed .sf3-font.sf3-font-enlarge,
.wiki-nav .wiki-page-item.wiki-page-freezed .seafile-multicolor-icon-more-level {
opacity: 1;
@@ -254,69 +229,6 @@
margin: 0.2rem 0;
}
-/* folders dropdown */
-.wiki-nav .more-wiki-page-operation .btn-move-to-folder {
- display: flex;
- align-items: center;
-}
-
-.wiki-nav .more-wiki-page-operation .move-to-folders-toggle {
- opacity: 0;
- width: 0;
- min-width: 0;
- margin-left: -12px;
- padding: 0;
-}
-
-.wiki-nav .more-wiki-page-operation .folders-dropdown-menu {
- margin-top: -16px;
- margin-left: 10px;
-}
-
-.wiki-nav .folders-dropdown-menu .dropdown-item {
- display: flex;
- align-items: center;
-}
-
-.wiki-nav .more-wiki-page-operation .btn-move-to-folder:focus .dtable-icon-insert-right {
- color: #fff;
-}
-
-.wiki-nav .folders-dropdown {
- width: 100%;
-}
-
-.wiki-nav .folders-dropdown-toggle {
- display: flex;
- align-items: center;
-}
-
-.wiki-nav .folders-dropdown .item-text {
- flex: 1;
-}
-
-.wiki-nav .folders-dropdown .dropdown-menu {
- max-height: 300px;
- overflow-y: auto;
-}
-
-.wiki-nav .folders-dropdown .dropdown-menu .folder-name {
- display: inline-block;
- width: 100%;
-}
-
-.wiki-nav .folders-dropdown .icon-dropdown-toggle {
- display: inline-flex;
- align-items: center;
- width: 12px;
- height: 12px;
- margin-right: 12px;
-}
-
-.wiki-nav .folders-dropdown .icon-dropdown-toggle .item-icon {
- transform: scale(0.8);
-}
-
.wiki-nav .wiki-page-item.page-can-drop::after,
.wiki-nav .wiki-page-item.page-can-drop-top::after {
content: '';
@@ -351,40 +263,15 @@
.wiki-nav,
.wiki-nav .wiki-page-item .sf3-font.sf3-font-enlarge:hover,
-.wiki-nav .wiki-page-item .seafile-multicolor-icon-more-level:hover,
-.wiki-nav .page-folder .seafile-multicolor-icon-more-level:hover,
-.wiki-nav .icon-expand-folder:hover {
+.wiki-nav .wiki-page-item .seafile-multicolor-icon-more-level:hover {
color: #212529;
}
.wiki-nav .wiki-page-item .sf3-font.sf3-font-enlarge,
-.wiki-nav .wiki-page-item .seafile-multicolor-icon-more-level,
-.wiki-nav .page-folder .seafile-multicolor-icon-more-level,
-.wiki-nav .icon-expand-folder {
+.wiki-nav .wiki-page-item .seafile-multicolor-icon-more-level {
color: #666;
}
-.wiki-nav .page-folder-wrapper.can-drop-top::before {
- content: '';
- width: 100%;
- height: 1px;
- position: absolute;
- left: 0;
- top: 0;
- background-color: #666;
-}
-
-.wiki-nav .page-folder-wrapper.can-drop::after {
- content: '';
- width: 100%;
- height: 1px;
- position: absolute;
- left: 0;
- background-color: #666;
- top: unset;
- bottom: 0;
-}
-
.svg-item {
width: 1em;
height: 1em;
diff --git a/frontend/src/pages/wiki2/index.js b/frontend/src/pages/wiki2/index.js
index d55a0a1af9..b61d42697e 100644
--- a/frontend/src/pages/wiki2/index.js
+++ b/frontend/src/pages/wiki2/index.js
@@ -103,15 +103,8 @@ class Wiki extends Component {
getFirstPageId = (config) => {
if (!config || !Array.isArray(config.navigation)) return '';
- for (let i = 0; i < config.navigation.length; i++) {
- const item = config.navigation[i] || {};
- if (item.type === 'page') {
- return item.id;
- }
- if (item.type === 'folder' && item.children[0]) {
- return item.children[0].id;
- }
- }
+ const firstPage = config.navigation[0] || {};
+ return firstPage.id;
};
getSdocFileContent = (docUuid, accessToken) => {
diff --git a/frontend/src/pages/wiki2/models/folder.js b/frontend/src/pages/wiki2/models/folder.js
deleted file mode 100644
index ade6d65d23..0000000000
--- a/frontend/src/pages/wiki2/models/folder.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default class Folder {
- constructor(object) {
- this.type = 'folder';
- this.id = object.id;
- this.name = object.name;
- this.children = Array.isArray(object.children) ? object.children : [];
- }
-}
diff --git a/frontend/src/pages/wiki2/models/wiki-config.js b/frontend/src/pages/wiki2/models/wiki-config.js
index cd814932c0..ba90a0c470 100644
--- a/frontend/src/pages/wiki2/models/wiki-config.js
+++ b/frontend/src/pages/wiki2/models/wiki-config.js
@@ -1,21 +1,37 @@
import Page from './page';
-import Folder from './folder';
export default class WikiConfig {
constructor(object) {
- this.version = object.version || 1;
- this.navigation = (Array.isArray(object.navigation) ? object.navigation : []).map(item => {
- if (item.type === 'folder') {
- return new Folder(item);
- } else if (item.type === 'page') {
- return {
- id: item.id,
- type: item.type,
- children: item.children || [],
- };
+ const { version = 1, pages = [], navigation = [] } = object;
+ this.version = version;
+ this.pages = pages.map(page => new Page(page));
+ this.navigation = navigation.filter(item => {
+ return item.type === 'page';
+ });
+ // Render pages in folder to navigation root
+ const page_id_map = {};
+ this.pages.forEach(page => {
+ page_id_map[page.id] = false;
+ });
+ function traversePage(node) {
+ if (!node) return;
+ if (node.id) {
+ page_id_map[node.id] = true;
}
- return null;
- }).filter(item => !!item);
- this.pages = Array.isArray(object.pages) ? object.pages.map(page => new Page(page)) : [];
+ if (Array.isArray(node.children)) {
+ node.children.forEach(child => traversePage(child));
+ }
+ }
+ traversePage({ children: this.navigation });
+ for (let key in page_id_map) {
+ if (page_id_map[key] === false) {
+ const page = this.pages.find(item => item.id === key);
+ this.navigation.push({
+ id: page.id,
+ type: 'page',
+ children: page.children || [],
+ });
+ }
+ }
}
}
diff --git a/frontend/src/pages/wiki2/side-panel.js b/frontend/src/pages/wiki2/side-panel.js
index 075e6f8f93..b724139c8a 100644
--- a/frontend/src/pages/wiki2/side-panel.js
+++ b/frontend/src/pages/wiki2/side-panel.js
@@ -7,14 +7,9 @@ import toaster from '../../components/toast';
import Loading from '../../components/loading';
import WikiNav from './wiki-nav/index';
import PageUtils from './wiki-nav/page-utils';
-import NewFolderDialog from './wiki-nav/new-folder-dialog';
-import AddNewPageDialog from './wiki-nav/add-new-page-dialog';
-import WikiNavFooter from './wiki-nav/wiki-nav-footer';
import { generateUniqueId, isObjectNotEmpty } from './utils';
-import Folder from './models/folder';
import Page from './models/page';
import wikiAPI from '../../utils/wiki-api';
-import { FOLDER } from './constant';
import { Utils } from '../../utils/utils';
import WikiExternalOperations from './wiki-external-operations';
@@ -37,10 +32,6 @@ class SidePanel extends Component {
constructor(props) {
super(props);
- this.state = {
- isShowNewFolderDialog: false,
- isShowAddNewPageDialog: false,
- };
}
confirmDeletePage = (pageId) => {
@@ -50,7 +41,7 @@ class SidePanel extends Component {
config.pages.splice(index, 1);
PageUtils.deletePage(navigation, pageId);
this.props.saveWikiConfig(config);
- // TODO: To delete a page, do you need to delete all subpages at once (requires a new API)
+ // TODO: delete a page, then delete all subpages
wikiAPI.deleteWiki2Page(wikiId, pageId);
if (config.pages.length > 0) {
this.props.setCurrentPage(config.pages[0].id);
@@ -72,7 +63,7 @@ class SidePanel extends Component {
const navigation = config.navigation;
const pageId = generateUniqueId(navigation);
const newPage = new Page({ id: pageId, name, icon, path, docUuid });
- this.addPage(newPage, this.current_folder_id, successCallback, errorCallback, jumpToNewPage);
+ this.addPage(newPage, '', successCallback, errorCallback, jumpToNewPage);
};
duplicatePage = async (fromPageConfig, successCallback, errorCallback) => {
@@ -102,240 +93,32 @@ class SidePanel extends Component {
this.props.saveWikiConfig(config, onSuccess, errorCallback);
};
- movePage = ({ moved_page_id, target_page_id, source_page_folder_id, target_page_folder_id, move_position }) => {
+ movePage = ({ moved_page_id, target_page_id, move_position }) => {
let config = deepCopy(this.props.config);
let { navigation } = config;
- PageUtils.movePage(navigation, moved_page_id, target_page_id, source_page_folder_id, target_page_folder_id, move_position);
+ PageUtils.movePage(navigation, moved_page_id, target_page_id, move_position);
config.navigation = navigation;
this.props.saveWikiConfig(config);
};
- movePageOut = (moved_page_id, source_id, target_id, move_position) => {
- let config = deepCopy(this.props.config);
- let { navigation } = config;
- PageUtils.movePageOut(navigation, moved_page_id, source_id, target_id, move_position);
- config.navigation = navigation;
- this.props.saveWikiConfig(config);
- };
-
- // Create a new folder in the root directory (not supported to create a new subfolder in the folder)
- addPageFolder = (folder_data, parent_folder_id) => {
- const { config } = this.props;
- const { navigation } = config;
- let folder_id = generateUniqueId(navigation);
- let newFolder = new Folder({ id: folder_id, ...folder_data });
- // No parent folder, directly add to the root directory
- if (!parent_folder_id) {
- config.navigation.push(newFolder);
- } else { // Recursively find the parent folder and add
- navigation.forEach(item => {
- if (item.type === FOLDER) {
- this._addFolder(item, newFolder, parent_folder_id);
- }
- });
- }
- this.props.saveWikiConfig(config);
- };
-
- _addFolder(folder, newFolder, parent_folder_id) {
- if (folder.id === parent_folder_id) {
- folder.children.push(newFolder);
- return;
- }
- folder.children.forEach(item => {
- if (item.type === FOLDER) {
- this._addFolder(item, newFolder, parent_folder_id);
- }
- });
- }
-
- onModifyFolder = (folder_id, folder_data) => {
- const { config } = this.props;
- const { navigation } = config;
- PageUtils.modifyFolder(navigation, folder_id, folder_data);
- config.navigation = navigation;
- this.props.saveWikiConfig(config);
- };
-
- onDeleteFolder = (page_folder_id) => {
- const { config } = this.props;
- const { navigation, pages } = config;
- PageUtils.deleteFolder(navigation, pages, page_folder_id);
- // TODO: delete all pages inside the folder, A new API is required
- config.navigation = navigation;
- this.props.saveWikiConfig(config);
- };
-
- // Drag a folder to the front and back of another folder
- onMoveFolder = (moved_folder_id, target_id, move_position) => {
- const { config } = this.props;
- const { navigation } = config;
- let updatedNavigation = deepCopy(navigation);
-
- // Get the moved folder first and delete the original location
- let moved_folder;
- let moved_folder_index = PageUtils.getFolderIndexById(updatedNavigation, moved_folder_id);
- if (moved_folder_index === -1) {
- updatedNavigation.forEach(item => {
- if (item.type === FOLDER) {
- moved_folder_index = PageUtils.getFolderIndexById(item.children, moved_folder_id);
- if (moved_folder_index > -1) {
- moved_folder = item.children[moved_folder_index];
- item.children.splice(moved_folder_index, 1);
- }
- }
- });
- } else {
- moved_folder = updatedNavigation[moved_folder_index];
- updatedNavigation.splice(moved_folder_index, 1);
- }
- let indexOffset = 0;
- if (move_position === 'move_below') {
- indexOffset++;
- }
- // Get the location of the release
- let target_folder_index = PageUtils.getFolderIndexById(updatedNavigation, target_id);
- if (target_folder_index === -1) {
- updatedNavigation.forEach(item => {
- if (item.type === FOLDER) {
- target_folder_index = PageUtils.getFolderIndexById(item.children, target_id);
- if (target_folder_index > -1) {
- item.children.splice(target_folder_index + indexOffset, 0, moved_folder);
- }
- } else {
- // not changed
- updatedNavigation = navigation;
- }
- });
- } else {
- updatedNavigation.splice(target_folder_index + indexOffset, 0, moved_folder);
- }
- config.navigation = updatedNavigation;
- this.props.saveWikiConfig(config);
- };
-
- // Not support yet: Move a folder into another folder
- moveFolderToFolder = (moved_folder_id, target_id) => {
- let { config } = this.props;
- let { navigation } = config;
-
- // Find the folder and move it to this new folder
- let target_folder = PageUtils.getFolderById(navigation, target_id);
- if (!target_folder) {
- toaster.danger('Only_support_two_level_folders');
- return;
- }
-
- let moved_folder;
- let moved_folder_index = PageUtils.getFolderIndexById(navigation, moved_folder_id);
-
- // The original directory is in the root directory
- if (moved_folder_index > -1) {
- moved_folder = PageUtils.getFolderById(navigation, moved_folder_id);
- // If moved folder There are other directories under the ID, and dragging is not supported
- if (moved_folder.children.some(item => item.type === FOLDER)) {
- toaster.danger('Only_support_two_level_folders');
- return;
- }
- target_folder.children.push(moved_folder);
- navigation.splice(moved_folder_index, 1);
- } else { // The original directory is not in the root directory
- navigation.forEach(item => {
- if (item.type === FOLDER) {
- let moved_folder_index = PageUtils.getFolderIndexById(item.children, moved_folder_id);
- if (moved_folder_index > -1) {
- moved_folder = item.children[moved_folder_index];
- target_folder.children.push(moved_folder);
- item.children.splice(moved_folder_index, 1);
- }
- }
- });
- }
- config.navigation = navigation;
- this.props.saveWikiConfig(config);
- };
-
- onToggleAddFolder = () => {
- this.setState({ isShowNewFolderDialog: !this.state.isShowNewFolderDialog });
- };
-
- openAddPageDialog = (folder_id) => {
- this.current_folder_id = folder_id;
- this.setState({ isShowAddNewPageDialog: true });
- };
-
- closeAddNewPageDialog = () => {
- this.current_folder_id = null;
- this.setState({ isShowAddNewPageDialog: false });
- };
-
- onSetFolderId = (folder_id) => {
- this.current_folder_id = folder_id;
- };
-
- renderFolderView = () => {
+ renderWikiNav = () => {
const { config, onUpdatePage } = this.props;
const { pages, navigation } = config;
return (
-
- {this.state.isShowNewFolderDialog &&
-
- }
- {this.state.isShowAddNewPageDialog &&
-
- }
-
- );
- };
-
- renderNoFolder = () => {
- return (
-
- {isWiki2 &&
-
- }
- {this.state.isShowNewFolderDialog &&
-
- }
- {this.state.isShowAddNewPageDialog &&
-
}
@@ -364,7 +147,7 @@ class SidePanel extends Component {
};
render() {
- const { isLoading, config } = this.props;
+ const { isLoading } = this.props;
return (
@@ -377,7 +160,7 @@ class SidePanel extends Component {
- {isLoading ? : (isObjectNotEmpty(config) ? this.renderFolderView() : this.renderNoFolder())}
+ {isLoading ? : this.renderWikiNav()}
diff --git a/frontend/src/pages/wiki2/top-nav/index.jsx b/frontend/src/pages/wiki2/top-nav/index.jsx
index 2e45cbd005..94ac31a68e 100644
--- a/frontend/src/pages/wiki2/top-nav/index.jsx
+++ b/frontend/src/pages/wiki2/top-nav/index.jsx
@@ -46,7 +46,7 @@ function WikiTopNav({ config, currentPageId }) {
return (
-
+
{item.name}
{index !== paths.length - 1 && /
}
diff --git a/frontend/src/pages/wiki2/wiki-nav/add-page-dropdownmenu.js b/frontend/src/pages/wiki2/wiki-nav/add-page-dropdownmenu.js
deleted file mode 100644
index 7a6ae73de5..0000000000
--- a/frontend/src/pages/wiki2/wiki-nav/add-page-dropdownmenu.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { Dropdown, DropdownMenu, DropdownItem, DropdownToggle } from 'reactstrap';
-import { gettext } from '../../../utils/constants';
-
-class AddPageDropdownMenu extends Component {
-
- toggle = event => {
- this.onStopPropagation(event);
- this.props.toggleDropdown();
- };
-
- addPage = event => {
- this.onStopPropagation(event);
- this.props.onToggleAddPage(null);
- };
-
- onToggleAddFolder = event => {
- this.onStopPropagation(event);
- this.props.onToggleAddFolder();
- };
-
- onStopPropagation = event => {
- event && event.nativeEvent && event.nativeEvent.stopImmediatePropagation();
- };
-
- render() {
- return (
-
-
-
-
-
- {gettext('Add page')}
-
-
-
- {gettext('Add folder')}
-
-
-
- );
- }
-}
-
-AddPageDropdownMenu.propTypes = {
- toggleDropdown: PropTypes.func,
- onToggleAddPage: PropTypes.func,
- onToggleAddFolder: PropTypes.func,
-};
-
-export default AddPageDropdownMenu;
diff --git a/frontend/src/pages/wiki2/wiki-nav/constant.js b/frontend/src/pages/wiki2/wiki-nav/constant.js
deleted file mode 100644
index 46f924a576..0000000000
--- a/frontend/src/pages/wiki2/wiki-nav/constant.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export const DRAGGED_FOLDER_MODE = 'wiki-folder';
-export const DRAGGED_PAGE_MODE = 'wiki-page';
diff --git a/frontend/src/pages/wiki2/wiki-nav/folders/dragged-folder-item.js b/frontend/src/pages/wiki2/wiki-nav/folders/dragged-folder-item.js
deleted file mode 100644
index 6052c04a31..0000000000
--- a/frontend/src/pages/wiki2/wiki-nav/folders/dragged-folder-item.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import { DragSource, DropTarget } from 'react-dnd';
-import { DRAGGED_FOLDER_MODE, DRAGGED_PAGE_MODE } from '../constant';
-import FolderItem from './folder-item';
-
-const dragSource = {
- beginDrag(props, monitor) {
- const { folderIndex, folder } = props;
- return {
- idx: folderIndex,
- data: folder,
- mode: DRAGGED_FOLDER_MODE,
- };
- },
- endDrag(props, monitor) {
- const sourceRow = monitor.getItem();
- const didDrop = monitor.didDrop();
- let targetRow = {};
- if (!didDrop) {
- return { sourceRow, targetRow };
- }
- },
- isDragging(props, monitor) {
- const { folderIndex: currentIndex, draggedPage } = props;
- const { idx } = draggedPage;
- return idx > currentIndex;
- },
-};
-
-const dropTarget = {
- drop(props, monitor) {
- const sourceRow = monitor.getItem();
- const { folder: targetFolder } = props;
- const targetFolderId = targetFolder.id;
- const className = props.getClassName();
- if (!className) return;
- let move_position;
- if (className.includes('can-drop')) {
- move_position = 'move_below';
- }
- if (className.includes('can-drop-top')) {
- move_position = 'move_above';
- }
- let moveInto = className.includes('dragged-page-over');
-
- // 1. drag source is page
- if (sourceRow.mode === DRAGGED_PAGE_MODE) {
- const sourceFolderId = sourceRow.folderId;
- const draggedPageId = sourceRow.data.id;
- // 1.1 move page into folder
- if (moveInto) {
- props.onMovePage({
- moved_page_id: draggedPageId,
- target_page_id: null,
- source_page_folder_id: sourceFolderId,
- target_page_folder_id: targetFolderId,
- move_position,
- });
- return;
- } else { // 1.2 Drag the page above or below the folder
- props.movePageOut(draggedPageId, sourceFolderId, targetFolderId, move_position);
- return;
- }
- }
- // 2. drag source is folder
- if (sourceRow.mode === DRAGGED_FOLDER_MODE) {
- const draggedFolderId = sourceRow.data.id;
- // 2.0 If dragged folder and target folder are the same folder, return
- if (targetFolderId === draggedFolderId) {
- return;
- }
- // 2.1 Do not support drag folder into another folder
- if (moveInto) {
- // props.moveFolderToFolder(draggedFolderId, targetFolderId);
- return;
- } else {
- // 2.2 Drag folder above or below another folder
- props.onMoveFolder(draggedFolderId, targetFolderId, move_position);
- }
- return;
- }
- // 3. Drag other dom
- return;
- }
-};
-
-const dragCollect = (connect, monitor) => ({
- connectDragSource: connect.dragSource(),
- connectDragPreview: connect.dragPreview(),
- isDragging: monitor.isDragging(),
-});
-
-const dropCollect = (connect, monitor) => ({
- connectDropTarget: connect.dropTarget(),
- isOver: monitor.isOver(),
- canDrop: monitor.canDrop(),
- draggedPage: monitor.getItem(),
- connect,
- monitor,
-});
-
-export default DropTarget('WikiNav', dropTarget, dropCollect)(
- DragSource('WikiNav', dragSource, dragCollect)(FolderItem)
-);
diff --git a/frontend/src/pages/wiki2/wiki-nav/folders/folder-item.js b/frontend/src/pages/wiki2/wiki-nav/folders/folder-item.js
deleted file mode 100644
index 4dbe611438..0000000000
--- a/frontend/src/pages/wiki2/wiki-nav/folders/folder-item.js
+++ /dev/null
@@ -1,284 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import classnames from 'classnames';
-import FolderOperationDropdownMenu from './folder-operation-dropdownmenu';
-import DraggedPageItem from '../pages/dragged-page-item';
-import DraggedFolderItem from './dragged-folder-item';
-import NameEditPopover from '../../common/name-edit-popover';
-import NavItemIcon from '../../common/nav-item-icon';
-
-class FolderItem extends Component {
-
- constructor(props) {
- super(props);
- const { name, icon } = props.folder;
- this.state = {
- isEditing: false,
- icon: icon || '',
- name: name || '',
- isMouseEnter: false,
- };
- }
-
- toggleExpand = (e) => {
- e.nativeEvent.stopImmediatePropagation();
- this.props.toggleExpand(this.props.folder.id);
- this.forceUpdate();
- };
-
- onClickFolderChildren = (e) => {
- e.stopPropagation();
- e.nativeEvent.stopImmediatePropagation();
- };
-
- openFolderEditor = () => {
- this.setState({ isEditing: true });
- };
-
- closeFolderEditor = () => {
- if (this.state.isEditing) {
- const { name, icon } = this.state;
- this.props.onModifyFolder(this.props.folder.id, { name, icon });
- this.setState({ isEditing: false });
- }
- };
-
- onChangeName = (name) => {
- this.setState({ name });
- };
-
- onChangeIcon = (icon) => {
- this.setState({ icon });
- };
-
- changeItemFreeze = (isFreeze) => {
- this.isFreeze = true;
- };
-
- renderFolder = (folder, index, pagesLength, isOnlyOnePage, id_page_map) => {
- const { isEditMode, pages, pathStr } = this.props;
- const { id: folderId } = folder;
- return (
-
- );
- };
-
- renderPage = (page, index, pagesLength, isOnlyOnePage) => {
- const { isEditMode, pages, folder, pathStr } = this.props;
- const id = page.id;
- if (!pages.find(item => item.id === id)) return;
- return (
- item.id === id), page)}
- pageIndex={index}
- folderId={folder.id}
- isEditMode={isEditMode}
- renderFolderMenuItems={this.props.renderFolderMenuItems}
- duplicatePage={this.props.duplicatePage}
- onSetFolderId={this.props.onSetFolderId}
- setCurrentPage={this.props.setCurrentPage}
- onUpdatePage={this.props.onUpdatePage}
- onDeletePage={this.props.onDeletePage}
- onMovePageToFolder={(targetFolderId) => {
- this.props.onMovePageToFolder(folder.id, page.id, targetFolderId);
- }}
- onMovePage={this.props.onMovePage}
- onMoveFolder={this.props.onMoveFolder}
- pages={pages}
- pathStr={pathStr + '-' + page.id}
- currentPageId={this.props.currentPageId}
- addPageInside={this.props.addPageInside}
- getFoldState={this.props.getFoldState}
- toggleExpand={this.props.toggleExpand}
- />
- );
- };
-
- getFolderClassName = (layerDragProps, state) => {
- if (!state || ! layerDragProps || !layerDragProps.clientOffset) {
- return 'page-folder-wrapper';
- }
- let y = layerDragProps.clientOffset.y;
- let top = this.foldWrapprRef.getBoundingClientRect().y;
- let className = '';
- // middle
- if (top + 10 < y && y < top + 30) {
- className += ' dragged-page-over ';
- }
- // top
- if (top + 10 > y) {
- className += ' can-drop-top ';
- }
- // bottom
- if (top + 30 < y) {
- className += ' can-drop ';
- }
- this.props.setClassName(className);
- return className + 'page-folder-wrapper';
- };
-
- getFolderChildrenHeight = () => {
- const folded = this.props.getFoldState(this.props.folder.id);
- if (folded) return 0;
- return 'auto';
- };
-
- onMouseEnter = () => {
- this.setState({ isMouseEnter: true });
- };
-
- onMouseLeave = () => {
- this.setState({ isMouseEnter: false });
- };
-
- render() {
- const {
- connectDropTarget, connectDragPreview, connectDragSource, isOver, canDrop,
- isEditMode, folder, pagesLength, id_page_map, isOnlyOnePage, layerDragProps,
- } = this.props;
- const { isEditing } = this.state;
- const { id: folderId, name, children } = folder;
- const folded = this.props.getFoldState(folderId);
- let navItemId = `folder-item-${folderId}`;
- let fn = isEditMode ? connectDragSource : (argu) => {argu;};
- return (
- this.foldRef = ref}
- onClick={this.toggleExpand}
- >
- {fn(connectDropTarget(
- connectDragPreview(
-
this.foldWrapprRef = ref}
- onMouseEnter={this.onMouseEnter}
- onMouseLeave={this.onMouseLeave}
- >
-
-
- {this.state.isMouseEnter ?
-
-
-
- :
-
- }
-
{name}
- {isEditing &&
-
- }
-
-
- {isEditMode &&
-
- }
-
- )
- ))
- }
-
- {!folded && children &&
- children.map((item, index) => {
- return item.type === 'folder' ? this.renderFolder(item, index, pagesLength, isOnlyOnePage, id_page_map) : this.renderPage(item, index, pagesLength, isOnlyOnePage);
- })
- }
-
-
- );
- }
-}
-
-FolderItem.propTypes = {
- isEditMode: PropTypes.bool,
- folder: PropTypes.object,
- folderIndex: PropTypes.number,
- pagesLength: PropTypes.number,
- id_page_map: PropTypes.object,
- isOver: PropTypes.bool,
- canDrop: PropTypes.bool,
- isDragging: PropTypes.bool,
- connectDropTarget: PropTypes.func,
- connectDragPreview: PropTypes.func,
- connectDragSource: PropTypes.func,
- renderFolderMenuItems: PropTypes.func,
- duplicatePage: PropTypes.func,
- onSetFolderId: PropTypes.func,
- toggleExpand: PropTypes.func,
- onToggleAddPage: PropTypes.func,
- onModifyFolder: PropTypes.func,
- onDeleteFolder: PropTypes.func,
- setCurrentPage: PropTypes.func,
- onUpdatePage: PropTypes.func,
- onDeletePage: PropTypes.func,
- onMovePageToFolder: PropTypes.func,
- onMovePage: PropTypes.func,
- isOnlyOnePage: PropTypes.bool,
- pages: PropTypes.array,
- onMoveFolder: PropTypes.func,
- moveFolderToFolder: PropTypes.func,
- pathStr: PropTypes.string,
- setClassName: PropTypes.func,
- getClassName: PropTypes.func,
- movePageOut: PropTypes.func,
- layerDragProps: PropTypes.object,
- getFoldState: PropTypes.func,
- currentPageId: PropTypes.string,
- addPageInside: PropTypes.func,
-};
-
-export default FolderItem;
diff --git a/frontend/src/pages/wiki2/wiki-nav/folders/folder-operation-dropdownmenu.js b/frontend/src/pages/wiki2/wiki-nav/folders/folder-operation-dropdownmenu.js
deleted file mode 100644
index e9372e0d75..0000000000
--- a/frontend/src/pages/wiki2/wiki-nav/folders/folder-operation-dropdownmenu.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
-import { gettext } from '../../../../utils/constants';
-import Icon from '../../../../components/icon';
-
-export default class FolderOperationDropdownMenu extends Component {
-
- static propTypes = {
- changeItemFreeze: PropTypes.func,
- openFolderEditor: PropTypes.func,
- onDeleteFolder: PropTypes.func,
- onToggleAddPage: PropTypes.func,
- folderId: PropTypes.string,
- };
-
- constructor(props) {
- super(props);
- this.state = {
- isMenuShow: false,
- };
- }
-
- onDropdownToggle = (e) => {
- e.stopPropagation();
- const isMenuShow = !this.state.isMenuShow;
- this.props.changeItemFreeze(isMenuShow);
- this.setState({ isMenuShow });
- };
-
- openFolderEditor = (evt) => {
- evt.nativeEvent.stopImmediatePropagation();
- this.props.openFolderEditor();
- };
-
- onDeleteFolder = (evt) => {
- evt.nativeEvent.stopImmediatePropagation();
- this.props.onDeleteFolder(this.props.folderId);
- };
-
- render() {
- return (
- <>
-
-
-
-
-
-
-
- {gettext('Add page')}
-
-
-
- {gettext('Modify name')}
-
-
-
- {gettext('Delete folder')}
-
-
-
- >
- );
- }
-}
diff --git a/frontend/src/pages/wiki2/wiki-nav/new-folder-dialog.js b/frontend/src/pages/wiki2/wiki-nav/new-folder-dialog.js
deleted file mode 100644
index 38f41b3ed4..0000000000
--- a/frontend/src/pages/wiki2/wiki-nav/new-folder-dialog.js
+++ /dev/null
@@ -1,98 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { Modal, ModalHeader, ModalBody, ModalFooter, Form, FormGroup, Label, Input, Button, Alert } from 'reactstrap';
-import { gettext } from '../../../utils/constants';
-
-export default class NewFolderDialog extends Component {
-
- static propTypes = {
- onAddFolder: PropTypes.func,
- onToggleAddFolderDialog: PropTypes.func,
- };
-
- constructor(props) {
- super(props);
- this.state = {
- folderName: '',
- errMessage: '',
- iconClassName: '',
- };
- }
-
- componentDidMount() {
- document.addEventListener('keydown', this.onHotKey);
- }
-
- componentWillUnmount() {
- document.removeEventListener('keydown', this.onHotKey);
- }
-
- onHotKey = (e) => {
- if (e.keyCode === 13) {
- e.preventDefault();
- this.handleSubmit();
- }
- };
-
- handleChange = (event) => {
- let { folderName } = this.state;
- let value = event.target.value;
- if (value === folderName) {
- return;
- }
- this.setState({ folderName: value });
- };
-
- handleSubmit = () => {
- let { folderName, iconClassName } = this.state;
- if (!folderName) {
- this.setState({ errMessage: gettext('Name_is_required') });
- return;
- }
- this.props.onAddFolder({ name: folderName, icon: iconClassName });
- this.props.onToggleAddFolderDialog();
- };
-
- toggle = () => {
- this.props.onToggleAddFolderDialog();
- };
-
- onIconChange = (className) => {
- this.setState({ iconClassName: className });
- };
-
- render() {
- const { folderName, errMessage } = this.state;
- return (
-
- {gettext('New folder')}
-
-
- {errMessage && {errMessage}}
-
-
-
-
-
-
- );
- }
-}
diff --git a/frontend/src/pages/wiki2/wiki-nav/page-utils.js b/frontend/src/pages/wiki2/wiki-nav/page-utils.js
index 4c1ee58b79..898af9237f 100644
--- a/frontend/src/pages/wiki2/wiki-nav/page-utils.js
+++ b/frontend/src/pages/wiki2/wiki-nav/page-utils.js
@@ -1,10 +1,16 @@
-import { FOLDER, PAGE } from '../constant';
+class NewPage {
+ constructor(id) {
+ this.id = id;
+ this.type = 'page';
+ this.children = [];
+ }
+}
export default class PageUtils {
static addPage(navigation, page_id, parentId) {
if (!parentId) {
- navigation.push({ id: page_id, type: PAGE });
+ navigation.push(new NewPage(page_id));
} else {
navigation.forEach(item => {
this._addPageRecursion(page_id, item, parentId);
@@ -17,10 +23,10 @@ export default class PageUtils {
item.children = [];
}
if (item.id === parentId) {
- item.children.push({ id: page_id, type: PAGE });
+ item.children.push(new NewPage(page_id));
return true;
}
- item.children.forEach(item => {
+ item.children && item.children.forEach(item => {
this._addPageRecursion(page_id, item, parentId);
});
}
@@ -43,7 +49,7 @@ export default class PageUtils {
item.children.splice(pageIndex, 1);
return true;
}
- item.children.forEach(item => {
+ item.children && item.children.forEach(item => {
this._deletePageRecursion(item, page_id);
});
}
@@ -57,76 +63,7 @@ export default class PageUtils {
return pages.findIndex(page => page.id === pageId);
};
- static getFolderById = (list, folder_id) => {
- if (!folder_id || !Array.isArray(list)) return null;
- return list.find(item => item.type === FOLDER && item.id === folder_id);
- };
-
- static getFolderIndexById = (list, folder_id) => {
- if (!folder_id || !Array.isArray(list)) return -1;
- return list.findIndex(folder => folder.id === folder_id);
- };
-
- static modifyFolder(navigation, folder_id, folder_data) {
- navigation.forEach(item => {
- if (item.type === FOLDER) {
- this._modifyFolder(item, folder_id, folder_data);
- }
- });
- }
-
- static _modifyFolder(folder, folder_id, folder_data) {
- if (folder.id === folder_id) {
- for (let key in folder_data) {
- folder[key] = folder_data[key];
- }
- return;
- }
- folder.children.forEach(item => {
- if (item.type === FOLDER) {
- this._modifyFolder(item, folder_id, folder_data);
- }
- });
- }
-
- static deleteFolder(navigation, pages, folder_id) {
- // delete folder and pages within it
- const folderIndex = this.getFolderIndexById(navigation, folder_id);
- if (folderIndex > -1) {
- this._deletePagesInFolder(pages, navigation[folderIndex]);
- navigation.splice(folderIndex, 1);
- return true;
- }
-
- // delete subfolder and pages within it
- navigation.forEach(item => {
- if (item.type === FOLDER) {
- const folderIndex = this.getFolderIndexById(item.children, folder_id);
- if (folderIndex > -1) {
- const subfolder = item.children[folderIndex];
- this._deletePagesInFolder(pages, subfolder);
- item.children.splice(folderIndex, 1);
- return true;
- }
- }
- });
- return false;
- }
-
- static _deletePagesInFolder(pages, folder) {
- folder.children.forEach(item => {
- if (item.type === FOLDER) {
- this._deletePagesInFolder(pages, item);
- }
- if (item.type === PAGE) {
- let index = this.getPageIndexById(item.id, pages);
- pages.splice(index, 1);
- }
- });
- }
-
static insertPage(navigation, page_id, target_page_id, target_id, move_position) {
- // 1. No folder, insert page in root directory
if (!target_id) {
let insertIndex = target_page_id ? navigation.findIndex(item => item.id === target_page_id) : -1;
if (insertIndex < 0) {
@@ -136,34 +73,12 @@ export default class PageUtils {
if (move_position === 'move_below') {
insertIndex++;
}
- navigation.splice(insertIndex, 0, { id: page_id, type: PAGE });
+ navigation.splice(insertIndex, 0, new NewPage(page_id));
return;
}
- // 2. If there is a folder, find it and insert it
- navigation.forEach(item => {
- if (item.type === FOLDER) {
- this._insertPageIntoFolder(item, page_id, target_page_id, target_id, move_position);
- }
- });
}
- static _insertPageIntoFolder(folder, page_id, target_page_id, target_id, move_position) {
- if (folder.id === target_id) {
- let insertIndex = target_page_id ? folder.children.findIndex(item => item.id === target_page_id) : -1;
- if (move_position === 'move_below') {
- insertIndex++;
- }
- folder.children.splice(insertIndex, 0, { id: page_id, type: PAGE });
- return;
- }
- folder.children.forEach(item => {
- if (item.type === FOLDER) {
- this._insertPageIntoFolder(item, page_id, target_page_id, target_id, move_position);
- }
- });
- }
-
- static movePage(navigation, moved_page_id, target_page_id, source_id, target_id, move_position) {
+ static movePage(navigation, moved_page_id, target_page_id, move_position) {
let movedPage = null;
function _cutPageRecursion(item, page_id) {
if (!item || !Array.isArray(item.children) || movedPage) return;
@@ -171,7 +86,7 @@ export default class PageUtils {
if (pageIndex > -1) {
movedPage = item.children.splice(pageIndex, 1)[0];
} else {
- item.children.forEach(item => {
+ item.children && item.children.forEach(item => {
_cutPageRecursion(item, page_id);
});
}
@@ -195,7 +110,7 @@ export default class PageUtils {
item.children.splice(insertIndex, 0, movedPage);
return;
}
- item.children.forEach(item => {
+ item.children && item.children.forEach(item => {
_insertPageRecursion(item, page_id, target_page_id, target_id, move_position);
});
}
@@ -217,58 +132,6 @@ export default class PageUtils {
});
}
_cutPage(navigation, moved_page_id);
- _insertPage(navigation, moved_page_id, target_page_id, target_id, move_position);
- }
-
- // move Page Outside Folder
- static movePageOut(navigation, moved_page_id, source_id, target_id, move_position) {
- let movedPage = null;
- function getFolderIndexById(list, folder_id) {
- if (!folder_id || !Array.isArray(list)) return -1;
- return list.findIndex(folder => folder.id === folder_id);
- }
- // Move the page to the top or bottom of the folder
- function _insertPage(navigation, page_id, target_id, move_position) {
- let indexOffset = 0;
- if (move_position === 'move_below') {
- indexOffset++;
- }
- let folder_index = getFolderIndexById(navigation, target_id);
- if (folder_index > -1) {
- navigation.splice(folder_index + indexOffset, 0, movedPage);
- } else {
- navigation.forEach((item) => {
- if (item.type === FOLDER) {
- let folder_index = getFolderIndexById(item.children, target_id);
- if (folder_index > -1) {
- item.children.splice(folder_index + indexOffset, 0, movedPage);
- }
- }
- });
- }
- }
- function _cutPageRecursion(item, page_id) {
- if (!item || !Array.isArray(item.children) || movedPage) return;
- let pageIndex = item.children.findIndex(item => item.id === page_id);
- if (pageIndex > -1) {
- movedPage = item.children.splice(pageIndex, 1)[0];
- } else {
- item.children.forEach(item => {
- _cutPageRecursion(item, page_id);
- });
- }
- }
- function _cutPage(navigation, page_id) {
- const pageIndex = navigation.findIndex(item => item.id === page_id);
- if (pageIndex > -1) {
- movedPage = navigation.splice(pageIndex, 1)[0];
- } else {
- navigation.forEach(item => {
- _cutPageRecursion(item, page_id);
- });
- }
- }
- _cutPage(navigation, moved_page_id, source_id);
- _insertPage(navigation, moved_page_id, target_id, move_position);
+ _insertPage(navigation, moved_page_id, target_page_id, target_page_id, move_position);
}
}
diff --git a/frontend/src/pages/wiki2/wiki-nav/pages/dragged-page-item.js b/frontend/src/pages/wiki2/wiki-nav/pages/dragged-page-item.js
index 9b5efb86f4..799c4576b6 100644
--- a/frontend/src/pages/wiki2/wiki-nav/pages/dragged-page-item.js
+++ b/frontend/src/pages/wiki2/wiki-nav/pages/dragged-page-item.js
@@ -1,5 +1,4 @@
import { DragSource, DropTarget } from 'react-dnd';
-import { DRAGGED_FOLDER_MODE, DRAGGED_PAGE_MODE } from '../constant';
import PageItem from './page-item';
const dragSource = {
@@ -7,8 +6,7 @@ const dragSource = {
return {
idx: props.pageIndex,
data: { ...props.page, index: props.pageIndex },
- folderId: props.folderId,
- mode: DRAGGED_PAGE_MODE,
+ mode: 'wiki-page',
};
},
endDrag(props, monitor) {
@@ -28,48 +26,22 @@ const dragSource = {
const dropTarget = {
drop(props, monitor) {
- const sourceRow = monitor.getItem();
- // 1 drag page
- if (sourceRow.mode === DRAGGED_PAGE_MODE) {
- const { infolder, pageIndex: targetIndex, page: targetPage, folderId: targetFolderId } = props;
- const sourceFolderId = sourceRow.folderId;
- const draggedPageId = sourceRow.data.id;
+ const dragSource = monitor.getItem();
+ if (dragSource.mode === 'wiki-page') {
+ const { pageIndex: targetIndex, page: targetPage } = props;
+ const draggedPageId = dragSource.data.id;
const targetPageId = targetPage.id;
-
if (draggedPageId !== targetPageId) {
- const sourceIndex = sourceRow.idx;
- let move_position;
- if (infolder) {
- move_position = 'move_below';
- } else {
- move_position = sourceIndex > targetIndex ? 'move_above' : 'move_below';
- }
-
+ const sourceIndex = dragSource.idx;
+ const move_position = sourceIndex > targetIndex ? 'move_above' : 'move_below';
props.onMovePage({
moved_page_id: draggedPageId,
target_page_id: targetPageId,
- source_page_folder_id: sourceFolderId,
- target_page_folder_id: targetFolderId,
move_position,
});
}
return;
}
- // 1 drag folder
- if (sourceRow.mode === DRAGGED_FOLDER_MODE) {
- const { pageIndex: targetIndex, page: targetPage } = props;
- const draggedFolderId = sourceRow.data.id;
- const targetPageId = targetPage.id;
- const sourceIndex = sourceRow.idx;
- // Drag the parent folder to the child page, return
- if (props.pathStr.split('-').includes(draggedFolderId)) return;
- props.onMoveFolder(
- draggedFolderId,
- targetPageId,
- sourceIndex > targetIndex ? 'move_above' : 'move_below',
- );
- return;
- }
}
};
diff --git a/frontend/src/pages/wiki2/wiki-nav/pages/page-dropdownmenu.js b/frontend/src/pages/wiki2/wiki-nav/pages/page-dropdownmenu.js
index 7da29da58d..f944c1c183 100644
--- a/frontend/src/pages/wiki2/wiki-nav/pages/page-dropdownmenu.js
+++ b/frontend/src/pages/wiki2/wiki-nav/pages/page-dropdownmenu.js
@@ -11,24 +11,15 @@ export default class PageDropdownMenu extends Component {
page: PropTypes.object.isRequired,
pages: PropTypes.array,
pagesLength: PropTypes.number,
- folderId: PropTypes.string,
- canDelete: PropTypes.bool,
- canDuplicate: PropTypes.bool,
- renderFolderMenuItems: PropTypes.func,
toggle: PropTypes.func,
toggleNameEditor: PropTypes.func,
duplicatePage: PropTypes.func,
- onSetFolderId: PropTypes.func,
onDeletePage: PropTypes.func,
- onMovePageToFolder: PropTypes.func,
isOnlyOnePage: PropTypes.bool,
};
constructor(props) {
super(props);
- this.state = {
- isShowMenu: false,
- };
this.pageNameMap = this.calculateNameMap();
}
@@ -41,9 +32,6 @@ export default class PageDropdownMenu extends Component {
};
onDropdownToggle = (evt) => {
- if (evt.target && this.foldersDropdownToggle && this.foldersDropdownToggle.contains(evt.target)) {
- return;
- }
evt.stopPropagation();
this.props.toggle();
};
@@ -58,22 +46,8 @@ export default class PageDropdownMenu extends Component {
this.props.onDeletePage();
};
- onMovePageToFolder = (targetFolderId) => {
- this.props.onMovePageToFolder(targetFolderId);
- };
-
- onRemoveFromFolder = (evt) => {
- evt.nativeEvent.stopImmediatePropagation();
- this.props.onMovePageToFolder(null);
- };
-
- onToggleFoldersMenu = () => {
- this.setState({ isShowMenu: !this.state.isShowMenu });
- };
-
duplicatePage = () => {
- const { page, folderId } = this.props;
- this.props.onSetFolderId(folderId);
+ const { page } = this.props;
this.props.duplicatePage({ from_page_id: page.id }, () => {}, this.duplicatePageFailure);
};
@@ -81,14 +55,6 @@ export default class PageDropdownMenu extends Component {
toaster.danger(gettext('Failed_to_duplicate_page'));
};
- showMenu = () => {
- this.setState({ isShowMenu: true });
- };
-
- hideMenu = () => {
- this.setState({ isShowMenu: false });
- };
-
handleCopyLink = () => {
const { page } = this.props;
const wikiLink = getWikPageLink(page.id);
@@ -109,10 +75,7 @@ export default class PageDropdownMenu extends Component {
};
render() {
- const {
- folderId, canDelete, canDuplicate, renderFolderMenuItems, pagesLength, isOnlyOnePage,
- } = this.props;
- const folderMenuItems = renderFolderMenuItems && renderFolderMenuItems({ currentFolderId: folderId, onMovePageToFolder: this.onMovePageToFolder });
+ const { pagesLength, isOnlyOnePage } = this.props;
return (
{gettext('Modify name')}
- {canDuplicate &&
-
-
- {gettext('Duplicate page')}
-
- }
- {(isOnlyOnePage || pagesLength === 1 || !canDelete) ? '' : (
+
+
+ {gettext('Duplicate page')}
+
+ {(isOnlyOnePage || pagesLength === 1) ? '' : (
{gettext('Delete page')}
)}
- {folderId &&
-
-
- {gettext('Remove from folder')}
-
- }
- {renderFolderMenuItems && folderMenuItems.length > 0 &&
- {
- evt.stopPropagation();
- evt.nativeEvent.stopImmediatePropagation();
- this.showMenu();
- }}
- onMouseEnter={this.showMenu}
- onMouseLeave={this.hideMenu}
- >
-
- this.foldersDropdownToggle = ref}>
-
- {gettext('Move to')}
-
-
-
-
-
- {this.state.isShowMenu &&
-
- {folderMenuItems}
-
- }
-
-
- }
< hr className='divider' />
diff --git a/frontend/src/pages/wiki2/wiki-nav/pages/page-item.js b/frontend/src/pages/wiki2/wiki-nav/pages/page-item.js
index 6df3b79b48..b51866b261 100644
--- a/frontend/src/pages/wiki2/wiki-nav/pages/page-item.js
+++ b/frontend/src/pages/wiki2/wiki-nav/pages/page-item.js
@@ -113,20 +113,20 @@ class PageItem extends Component {
window.seafile['docUuid'] = docUuid;
};
- getFolderChildrenHeight = () => {
+ getPageChildrenHeight = () => {
const folded = this.props.getFoldState(this.props.page.id);
if (folded) return 0;
return 'auto';
};
- onClickFolderChildren = (e) => {
+ onClickPageChildren = (e) => {
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
};
renderPage = (page, index, pagesLength, isOnlyOnePage) => {
if (!page) return;
- const { isEditMode, pages, folderId, pathStr } = this.props;
+ const { isEditMode, pages, pathStr } = this.props;
const id = page.id;
if (!pages.find(item => item.id === id)) return;
return (
@@ -134,22 +134,14 @@ class PageItem extends Component {
key={id}
pagesLength={pagesLength}
isOnlyOnePage={isOnlyOnePage}
- infolder={false}
page={Object.assign({}, pages.find(item => item.id === id), page)}
pageIndex={index}
- folderId={folderId}
isEditMode={isEditMode}
- renderFolderMenuItems={this.props.renderFolderMenuItems}
duplicatePage={this.props.duplicatePage}
- onSetFolderId={this.props.onSetFolderId}
setCurrentPage={this.props.setCurrentPage}
onUpdatePage={this.props.onUpdatePage}
onDeletePage={this.props.onDeletePage}
- onMovePageToFolder={(targetFolderId) => {
- this.props.onMovePageToFolder(folderId, page.id, targetFolderId);
- }}
onMovePage={this.props.onMovePage}
- onMoveFolder={this.props.onMoveFolder}
pages={pages}
pathStr={pathStr + '-' + page.id}
currentPageId={this.props.currentPageId}
@@ -173,21 +165,14 @@ class PageItem extends Component {
render() {
const {
connectDragSource, connectDragPreview, connectDropTarget, isOver, canDrop, isDragging,
- infolder, page, pagesLength, isEditMode, folderId, isOnlyOnePage, pathStr,
+ page, pagesLength, isEditMode, isOnlyOnePage, pathStr,
} = this.props;
const { isShowNameEditor, pageName, isSelected } = this.state;
const isOverPage = isOver && canDrop;
if (isSelected) this.setDocUuid(page.docUuid);
- let pageCanDropTop;
- let pageCanDrop;
- if (infolder) {
- pageCanDropTop = false;
- pageCanDrop = isOverPage;
- } else {
- pageCanDropTop = isOverPage && isDragging;
- pageCanDrop = isOverPage && !isDragging;
- }
+ let pageCanDropTop = isOverPage && isDragging;
+ let pageCanDrop = isOverPage && !isDragging;
let navItemId = `page-editor-${page.id}`;
let fn = isEditMode ? connectDragSource : (argu) => {argu;};
let childNumber = Array.isArray(page.children) ? page.children.length : 0;
@@ -246,16 +231,10 @@ class PageItem extends Component {
pages={this.props.pages}
pagesLength={pagesLength}
isOnlyOnePage={isOnlyOnePage}
- folderId={folderId}
- canDelete={true}
- canDuplicate={true}
toggle={this.toggleDropdown}
- renderFolderMenuItems={this.props.renderFolderMenuItems}
toggleNameEditor={this.toggleNameEditor}
duplicatePage={this.props.duplicatePage}
- onSetFolderId={this.props.onSetFolderId}
onDeletePage={this.openDeleteDialog}
- onMovePageToFolder={this.props.onMovePageToFolder}
/>
}
@@ -283,9 +262,9 @@ class PageItem extends Component {
))
}
{page.children &&
page.children.map((item, index) => {
@@ -304,26 +283,19 @@ PageItem.propTypes = {
isDragging: PropTypes.bool,
draggedPage: PropTypes.object,
isEditMode: PropTypes.bool,
- infolder: PropTypes.bool,
page: PropTypes.object,
- folder: PropTypes.object,
pages: PropTypes.array,
pageIndex: PropTypes.number,
- folderId: PropTypes.string,
pagesLength: PropTypes.number,
connectDragSource: PropTypes.func,
connectDragPreview: PropTypes.func,
connectDropTarget: PropTypes.func,
- renderFolderMenuItems: PropTypes.func,
duplicatePage: PropTypes.func,
- onSetFolderId: PropTypes.func,
setCurrentPage: PropTypes.func,
onUpdatePage: PropTypes.func,
onDeletePage: PropTypes.func,
- onMovePageToFolder: PropTypes.func,
onMovePage: PropTypes.func,
isOnlyOnePage: PropTypes.bool,
- onMoveFolder: PropTypes.func,
pathStr: PropTypes.string,
currentPageId: PropTypes.string,
addPageInside: PropTypes.func,
diff --git a/frontend/src/pages/wiki2/wiki-nav/wiki-nav-footer.js b/frontend/src/pages/wiki2/wiki-nav/wiki-nav-footer.js
deleted file mode 100644
index 376e80b288..0000000000
--- a/frontend/src/pages/wiki2/wiki-nav/wiki-nav-footer.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import CommonAddTool from '../../../components/common/common-add-tool';
-import AddPageDropdownMenu from './add-page-dropdownmenu';
-import { gettext } from '../../../utils/constants';
-
-class WikiNavFooter extends Component {
-
- constructor(props) {
- super(props);
- this.state = {
- isShowDropdownMenu: false,
- };
- }
-
- toggleDropdown = (event) => {
- event && event.stopPropagation();
- this.setState({ isShowDropdownMenu: !this.state.isShowDropdownMenu });
- };
-
- render() {
- return (
-
-
-
- {this.state.isShowDropdownMenu &&
-
- }
-
-
- );
- }
-}
-
-WikiNavFooter.propTypes = {
- onToggleAddPage: PropTypes.func,
- onToggleAddFolder: PropTypes.func,
-};
-
-export default WikiNavFooter;
diff --git a/frontend/src/pages/wiki2/wiki-nav/wiki-nav.js b/frontend/src/pages/wiki2/wiki-nav/wiki-nav.js
index de76f6ea70..c8d7ea7211 100644
--- a/frontend/src/pages/wiki2/wiki-nav/wiki-nav.js
+++ b/frontend/src/pages/wiki2/wiki-nav/wiki-nav.js
@@ -1,11 +1,8 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { DropdownItem } from 'reactstrap';
import { DropTarget, DragLayer } from 'react-dnd';
import html5DragDropContext from './html5DragDropContext';
-import DraggedFolderItem from './folders/dragged-folder-item';
import DraggedPageItem from './pages/dragged-page-item';
-import WikiNavFooter from './wiki-nav-footer';
import { repoID } from '../../../utils/constants';
import '../css/wiki-nav.css';
@@ -17,26 +14,17 @@ class WikiNav extends Component {
navigation: PropTypes.array,
pages: PropTypes.array,
onTogglePinViewList: PropTypes.func,
- onToggleAddPage: PropTypes.func,
- onToggleAddFolder: PropTypes.func,
- onModifyFolder: PropTypes.func,
- onDeleteFolder: PropTypes.func,
- onMoveFolder: PropTypes.func,
setCurrentPage: PropTypes.func,
onUpdatePage: PropTypes.func,
onDeletePage: PropTypes.func,
onMovePage: PropTypes.func,
- moveFolderToFolder: PropTypes.func,
- movePageOut: PropTypes.func,
duplicatePage: PropTypes.func,
- onSetFolderId: PropTypes.func,
currentPageId: PropTypes.string,
addPageInside: PropTypes.func,
};
constructor(props) {
super(props);
- this.folderClassNameCache = '';
this.idFoldedStatusMap = this.getFoldedFromLocal();
}
@@ -49,145 +37,63 @@ class WikiNav extends Component {
window.localStorage.setItem(`wiki-folded-${repoID}`, JSON.stringify(items));
};
- getFoldState = (folderId) => {
- return this.idFoldedStatusMap[folderId];
+ getFoldState = (pageId) => {
+ return this.idFoldedStatusMap[pageId];
};
- toggleExpand = (folderId) => {
+ toggleExpand = (pageId) => {
const idFoldedStatusMap = this.getFoldedFromLocal();
- if (idFoldedStatusMap[folderId]) {
- delete idFoldedStatusMap[folderId];
+ if (idFoldedStatusMap[pageId]) {
+ delete idFoldedStatusMap[pageId];
} else {
- idFoldedStatusMap[folderId] = true;
+ idFoldedStatusMap[pageId] = true;
}
this.saveFoldedToLocal(idFoldedStatusMap);
this.idFoldedStatusMap = idFoldedStatusMap;
};
- onMovePageToFolder = (source_page_folder_id, moved_page_id, target_page_folder_id) => {
- this.props.onMovePage({
- moved_page_id,
- source_page_folder_id,
- target_page_folder_id,
- target_page_id: null,
- move_position: 'move_below'
- });
- };
-
- renderFolderMenuItems = ({ currentFolderId, onMovePageToFolder }) => {
- // folder lists (in the root directory)
- const { navigation } = this.props;
- let renderFolders = navigation.filter(item => item.type === 'folder' && item.id !== currentFolderId);
- return renderFolders.map(folder => {
- const { id, name } = folder;
- return (
-
- {name}
-
- );
- });
- };
-
- setClassName = (name) => {
- this.folderClassNameCache = name;
- };
-
- getClassName = () => {
- return this.folderClassNameCache;
- };
-
- renderFolder = (folder, index, pagesLength, isOnlyOnePage, id_page_map, layerDragProps) => {
- const { isEditMode, pages } = this.props;
- const folderId = folder.id;
- return (
-
- );
- };
-
- renderPage = (page, index, pagesLength, isOnlyOnePage, id_page_map) => {
+ renderPage = (page, index, pagesLength, isOnlyOnePage, id_page_map, layerDragProps) => {
const { isEditMode, pages } = this.props;
const id = page.id;
if (!pages.find(item => item.id === id)) return;
- const folderId = null; // Pages in the root directory, no folders, use null
return (
item.id === id), page)}
pages={pages}
pageIndex={index}
- folderId={folderId}
isEditMode={isEditMode}
- renderFolderMenuItems={this.renderFolderMenuItems}
duplicatePage={this.props.duplicatePage}
- onSetFolderId={this.props.onSetFolderId}
setCurrentPage={this.props.setCurrentPage}
onUpdatePage={this.props.onUpdatePage}
onDeletePage={this.props.onDeletePage}
- onMovePageToFolder={(targetFolderId) => {
- this.onMovePageToFolder(folderId, page.id, targetFolderId);
- }}
onMovePage={this.props.onMovePage}
- onMoveFolder={this.props.onMoveFolder}
pathStr={page.id}
currentPageId={this.props.currentPageId}
addPageInside={this.props.addPageInside}
getFoldState={this.getFoldState}
toggleExpand={this.toggleExpand}
+ id_page_map={id_page_map}
+ layerDragProps={layerDragProps}
/>
);
};
// eslint-disable-next-line
renderStructureBody = React.forwardRef((layerDragProps, ref) => {
- const { navigation, pages, isEditMode } = this.props;
+ const { navigation, pages } = this.props;
let isOnlyOnePage = false;
if (pages.length === 1) {
isOnlyOnePage = true;
}
- const pagesLength = pages.length;
let id_page_map = {};
pages.forEach(page => id_page_map[page.id] = page);
- const style = { maxHeight: isEditMode ? 'calc(100% - 40px)' : '100%' };
return (
-
+
{navigation.map((item, index) => {
- return item.type === 'folder' ?
- this.renderFolder(item, index, pagesLength, isOnlyOnePage, id_page_map, layerDragProps) :
- this.renderPage(item, index, pagesLength, isOnlyOnePage, id_page_map);
+ return this.renderPage(item, index, pages.length, isOnlyOnePage, id_page_map, layerDragProps);
})}
);
@@ -211,12 +117,6 @@ class WikiNav extends Component {
return (
- {(this.props.isEditMode) &&
-
- }
);
}