diff --git a/frontend/src/pages/wiki2/view-structure/views/delete-dialog.js b/frontend/src/pages/wiki2/common/delete-dialog.js similarity index 94% rename from frontend/src/pages/wiki2/view-structure/views/delete-dialog.js rename to frontend/src/pages/wiki2/common/delete-dialog.js index bf69f5e9c1..4644aa6dcb 100644 --- a/frontend/src/pages/wiki2/view-structure/views/delete-dialog.js +++ b/frontend/src/pages/wiki2/common/delete-dialog.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; -import { gettext } from '../../../../utils/constants'; +import { gettext } from '../../../utils/constants'; export default class DeleteDialog extends React.Component { diff --git a/frontend/src/pages/wiki2/common/name-edit-popover.js b/frontend/src/pages/wiki2/common/name-edit-popover.js new file mode 100644 index 0000000000..0c2915b860 --- /dev/null +++ b/frontend/src/pages/wiki2/common/name-edit-popover.js @@ -0,0 +1,78 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { PopoverBody } from 'reactstrap'; +import SeahubPopover from '../../../components/common/seahub-popover'; +import { gettext } from '../../../utils/constants'; + +import '../css/name-edit-popover.css'; + + +class NameEditPopover extends Component { + + constructor(props) { + super(props); + this.inputRef = React.createRef(); + } + + componentDidMount() { + const txtLength = this.props.oldName.length; + this.inputRef.current.setSelectionRange(0, txtLength); + } + + onChangeName = (e) => { + this.props.onChangeName(e.target.value); + }; + + onEnter = (e) => { + e.preventDefault(); + this.props.toggleEditor(); + }; + + handleKeyDown = (e) => { + if (e.keyCode === 13) { + e.preventDefault(); + this.props.toggleEditor(); + } + }; + + render() { + return ( + +
+ {gettext('Modify Name')} +
+ +
+ +
+
+
+ ); + } +} + +NameEditPopover.propTypes = { + oldName: PropTypes.string, + onChangeName: PropTypes.func, + toggleEditor: PropTypes.func, + targetId: PropTypes.string, +}; + +export default NameEditPopover; diff --git a/frontend/src/pages/wiki2/view-structure/nav-item-icon.jsx b/frontend/src/pages/wiki2/common/nav-item-icon.js similarity index 94% rename from frontend/src/pages/wiki2/view-structure/nav-item-icon.jsx rename to frontend/src/pages/wiki2/common/nav-item-icon.js index 0171b3574b..f80f0fa3aa 100644 --- a/frontend/src/pages/wiki2/view-structure/nav-item-icon.jsx +++ b/frontend/src/pages/wiki2/common/nav-item-icon.js @@ -2,7 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import Icon from '../../../components/icon'; import classNames from 'classnames'; -import './nav-item-icon.css'; + +import '../css/nav-item-icon.css'; function NavItemIcon({ symbol, className, disable, onClick }) { return ( diff --git a/frontend/src/pages/wiki2/css/name-edit-popover.css b/frontend/src/pages/wiki2/css/name-edit-popover.css new file mode 100644 index 0000000000..2dd22c3fff --- /dev/null +++ b/frontend/src/pages/wiki2/css/name-edit-popover.css @@ -0,0 +1,31 @@ +.name-edit-popover .popover { + max-width: 460px; + width: 460px; + left: 140px !important; +} + +.name-edit-popover .name-edit-content { + padding: 8px 12px; +} + +.name-edit-popover .item-name-editor { + margin-bottom: 7px; +} + +.name-edit-popover .item-name-editor-input { + height: 36px; +} + +.name-edit-popover-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 12px; + border-bottom: 1px solid rgba(0, 40, 100, 0.12); + height: 40px; + font-size: 14px; +} + +.name-edit-popover-header .header-text { + color: #212529; +} diff --git a/frontend/src/pages/wiki2/view-structure/nav-item-icon.css b/frontend/src/pages/wiki2/css/nav-item-icon.css similarity index 100% rename from frontend/src/pages/wiki2/view-structure/nav-item-icon.css rename to frontend/src/pages/wiki2/css/nav-item-icon.css diff --git a/frontend/src/pages/wiki2/css/view-edit-popover.css b/frontend/src/pages/wiki2/css/view-edit-popover.css deleted file mode 100644 index 89df24146d..0000000000 --- a/frontend/src/pages/wiki2/css/view-edit-popover.css +++ /dev/null @@ -1,76 +0,0 @@ -.view-edit-popover .popover { - max-width: 460px; - width: 460px; - left: 140px !important; -} - -.view-edit-popover .view-edit-content { - padding: 8px 12px; -} - -.view-edit-popover .view-name-editor { - margin-bottom: 7px; -} - -.view-edit-popover .view-name-editor-input { - height: 36px; -} - -.view-edit-popover .view-icon-editor { - display: flex; - flex-wrap: wrap; - margin-left: 1px; -} - -.view-edit-popover .view-icon-item-editor { - overflow: hidden; - height: 36px; - width: 36px; - border-radius: 6px; -} - -.view-edit-popover .view-icon-item-editor .svg-item { - width: 1em; - height: 1em; - font-size: 16px; - color: #999; -} - -.view-edit-popover .view-icon-item-editor .view-icon-color-white { - color: #ffffff !important; -} - -.view-edit-popover .view-icon-item-editor:hover { - background-color: #f5f5f5; -} - -.view-edit-popover .view-icon-item-editor .view-icon-item-container { - display: flex; - justify-content: center; - align-items: center; - height: 100%; - width: 100%; - cursor: pointer; -} - -.view-edit-popover-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0 12px; - border-bottom: 1px solid rgba(0, 40, 100, 0.12); - height: 40px; - font-size: 14px; -} - -.view-edit-popover-header .header-text { - color: #212529; -} - -.view-edit-popover-header .remove-icon-button { - color: #ff8000; -} - -.view-edit-popover-header .remove-icon-button:hover { - cursor: pointer; -} diff --git a/frontend/src/pages/wiki2/css/view-structure.css b/frontend/src/pages/wiki2/css/view-structure.css deleted file mode 100644 index bcd54178b7..0000000000 --- a/frontend/src/pages/wiki2/css/view-structure.css +++ /dev/null @@ -1,401 +0,0 @@ -.view-structure { - height: 100%; - display: flex; - flex-direction: column; -} - -.views-structure-header { - height: 30px; - min-height: 30px; - padding: 0.25rem 10px; - display: flex; -} - -.view-structure-body { - padding-bottom: 0.5rem; - overflow: auto; - user-select: none; -} - -.view-structure .view-folder { - position: relative; -} - -.view-structure .view-folder.can-drop::after, -.view-structure .view-folder.can-drop-top::after { - content: ''; - width: 100%; - height: 1px; - position: absolute; - left: 0; - top: 40px; - background-color: #666; -} - -.view-structure .view-folder .view-folder-children { - transition: height 0.25s ease-in-out 0s; -} - -.view-structure .view-drop-target { - position: absolute; - left: 0; - width: 100%; - z-index: 1; - border-bottom: 1px solid #666; -} - -.view-structure .view-folder.can-drop::after { - top: unset; - bottom: 0; -} - -.view-structure .view-folder.can-drop-top::after { - top: 0; -} - -.view-structure .view-folder-wrapper, -.view-structure .view-item { - position: relative; - display: flex; - width: 100%; - height: 40px; - padding: 0 8px 0 0; - font-size: 14px; - font-weight: 500; - align-items: center; - justify-content: center; - border-radius: 3px; - background-color: #F7F7F5; -} - -.view-structure .view-item.selected-view { - background-color: #EDEDEA; -} - -.view-structure .view-folder-wrapper:hover, -.view-structure .view-item:hover { - background-color: #EFEFED; -} - -.view-structure .view-item.selected-view:hover { - background-color: #E6E6E4; -} - -.view-structure .folder-main, -.view-structure .view-item-main { - flex: 1; - display: flex; - align-items: center; - height: 100%; - overflow: hidden; -} - -.view-structure .more-views .folder-main { - padding-left: 20px; -} - -.view-structure .icon-expand-folder { - display: inline-block; - font-size: 12px; - transform: scale(0.8); - color: #b5b5b5; - cursor: pointer; -} - -.view-structure .folder-content, -.view-structure .view-content { - height: 100%; - padding-right: 8px; - line-height: 1; - display: flex; - align-items: center; - flex: 1; - overflow: hidden; -} - -.view-structure .in-folder .view-content { - padding-left: calc(12 * 0.8px + 0.5rem); -} - -.view-structure .folder-content:hover, -.view-structure .view-content:hover { - cursor: pointer; -} - -.view-structure .folder-content .dtable-font, -.view-structure .view-content .dtable-font { - margin-right: 6px; - font-size: 14px; -} - -.view-structure .folder-content .folder-name, -.view-structure .view-content .view-title { - height: 40px; - line-height: 40px; - flex: 1; -} - -.view-structure .more-view-folder-operation, -.view-structure .more-view-operation { - width: 24px; - height: 24px; - display: flex; - align-items: center; - justify-content: center; -} - -.view-structure .wiki-add-page-btn:hover, -.view-structure .more-view-folder-operation:hover, -.view-structure .more-view-operation:hover { - border-radius: 3px; - background-color: #DFDFDD; -} - -.view-structure .view-folder-wrapper .more-view-folder-operation .seafile-multicolor-icon-more-level, -.view-structure .view-item .sf3-font.sf3-font-enlarge, -.view-structure .view-item .more-view-operation .seafile-multicolor-icon-more-level { - cursor: pointer; - opacity: 0; -} - -.view-structure .view-item:hover .sf3-font.sf3-font-enlarge, -.view-structure .view-folder-wrapper:hover .more-view-folder-operation .seafile-multicolor-icon-more-level, -.view-structure .view-item:hover .more-view-operation .seafile-multicolor-icon-more-level { - opacity: 1; -} - -.view-structure .more-view-folder-operation:hover, -.view-structure .more-view-operation:hover { - cursor: pointer; -} - -.view-structure .more-view-folder-operation .dtable-font, -.view-structure .more-view-operation .dtable-font { - font-size: 14px; - margin-right: 10px; -} - -.view-structure .folder-list .view-folder.fold-freezed .btn-folder-operation, -.view-structure .view-item.view-freezed .sf3-font.sf3-font-enlarge, -.view-structure .view-item.view-freezed .seafile-multicolor-icon-more-level { - opacity: 1; -} - -.view-structure-footer { - user-select: none; -} - -.view-structure-footer:hover { - background-color: #EFEFED; -} - -.view-structure-footer.return-to-app { - position: absolute; - width: 100%; - bottom: 0; -} - -.add-view-wrapper { - position: relative; -} - -.view-structure-footer .dropdown { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} - -.view-structure-footer .dropdown button { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - border: none; - background-color: transparent !important; -} - -.view-structure-footer .dropdown button::after { - display: none !important; -} - -.view-structure-footer .dropdown button:focus { - box-shadow: none !important; -} - -.view-structure-footer .add-view-btn { - padding: 0 12px; - height: 40px; - border-top: none; - background-color: transparent; -} - -.view-structure-footer .add-view-btn .dtable-icon-add-table { - margin-left: 1px; - margin-right: 0.5rem; - transform: unset; -} - -.view-sidebar .view-structure-footer .add-view-btn { - border-top: none; -} - -/* view operation dropdown */ -.view-structure .view-operation-dropdown-toggle { - display: inline-block; - width: 0; - height: 0; - opacity: 0; -} - -.view-structure .view-operation-dropdown .view-operation-dropdown-menu { - margin-left: -15px; - margin-top: 4px; -} - -.view-operation-dropdown-menu .divider { - margin: 0.2rem 0; -} - -/* folders dropdown */ -.view-structure .more-view-operation .btn-move-to-folder { - display: flex; - align-items: center; -} - -.view-structure .more-view-operation .move-to-folders-toggle { - opacity: 0; - width: 0; - min-width: 0; - margin-left: -12px; - padding: 0; -} - -.view-structure .more-view-operation .folders-dropdown-menu { - margin-top: -16px; - margin-left: 10px; -} - -.view-structure .folders-dropdown-menu .dropdown-item { - display: flex; - align-items: center; -} - -.view-structure .more-view-operation .btn-move-to-folder:focus .dtable-icon-insert-right { - color: #fff; -} - -.view-structure .folders-dropdown { - width: 100%; -} - -.view-structure .folders-dropdown-toggle { - display: flex; - align-items: center; -} - -.view-structure .folders-dropdown .item-text { - flex: 1; -} - -.view-structure .folders-dropdown .dropdown-menu { - max-height: 300px; - overflow-y: auto; -} - -.view-structure .folders-dropdown .dropdown-menu .folder-name { - display: inline-block; - width: 100%; -} - -.view-structure .folders-dropdown .icon-dropdown-toggle { - display: inline-flex; - align-items: center; - width: 12px; - height: 12px; - margin-right: 12px; -} - -.view-structure .folders-dropdown .icon-dropdown-toggle .item-icon { - transform: scale(0.8); -} - -.view-structure .view-item.view-can-drop::after, -.view-structure .view-item.view-can-drop-top::after { - content: ''; - width: 100%; - height: 1px; - position: absolute; - left: 0; - top: 39px; - background-color: #666 !important; -} - -.view-structure .view-item.view-can-drop-top::after { - top: 0; -} - -.dtable-dropdown-menu .dropdown-item .sf3-font { - font-size: 14px; - margin-right: 10px; - color: #8c8c8c; -} - -.dtable-dropdown-menu .dropdown-item:hover .sf3-font { - color: #fff; -} - -.dtable-dropdown-menu.large .dropdown-item { - min-height: 32px; - padding: 3px 12px; - display: flex; - align-items: center; -} - -/* dark mode */ -.view-structure-dark.view-structure, -.view-structure-dark.view-structure .icon-expand-folder { - color: #fff; -} - -/* light mode */ -.view-structure-light.view-structure, -.view-structure-light.view-structure .icon-expand-folder:hover { - color: #212529; -} - -.view-structure-light.view-structure .view-item .sf3-font.sf3-font-enlarge, -.view-structure-light.view-structure .view-item .seafile-multicolor-icon-more-level, -.view-structure-light.view-structure .view-folder .seafile-multicolor-icon-more-level, -.view-structure-light.view-structure .icon-expand-folder { - color: #666; -} - -.view-structure .view-folder-wrapper.can-drop-top::before { - content: ''; - width: 100%; - height: 1px; - position: absolute; - left: 0; - top: 0; - background-color: #666; -} - -.view-structure .view-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; - font-size: 16px; -} diff --git a/frontend/src/pages/wiki2/css/wiki-nav.css b/frontend/src/pages/wiki2/css/wiki-nav.css new file mode 100644 index 0000000000..0516740bed --- /dev/null +++ b/frontend/src/pages/wiki2/css/wiki-nav.css @@ -0,0 +1,392 @@ +.wiki-nav { + height: 100%; + display: flex; + flex-direction: column; +} + +.wiki-nav-header { + height: 30px; + min-height: 30px; + padding: 0.25rem 10px; + display: flex; +} + +.wiki-nav-body { + padding-bottom: 0.5rem; + overflow: auto; + user-select: none; +} + +.wiki-nav .page-folder { + position: relative; +} + +.wiki-nav .page-folder.can-drop::after, +.wiki-nav .page-folder.can-drop-top::after { + content: ''; + width: 100%; + height: 1px; + position: absolute; + left: 0; + top: 40px; + background-color: #666; +} + +.wiki-nav .page-folder .page-folder-children { + transition: height 0.25s ease-in-out 0s; +} + +.wiki-nav .page-drop-target { + position: absolute; + left: 0; + width: 100%; + z-index: 1; + 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; + width: 100%; + height: 40px; + padding: 0 8px 0 0; + font-size: 14px; + font-weight: 500; + align-items: center; + justify-content: center; + border-radius: 3px; + background-color: #F7F7F5; +} + +.wiki-nav .wiki-page-item.selected-page { + background-color: #EDEDEA; +} + +.wiki-nav .page-folder-wrapper:hover, +.wiki-nav .wiki-page-item:hover { + background-color: #EFEFED; +} + +.wiki-nav .wiki-page-item.selected-page:hover { + background-color: #E6E6E4; +} + +.wiki-nav .folder-main, +.wiki-nav .wiki-page-item-main { + flex: 1; + display: flex; + align-items: center; + height: 100%; + 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; + line-height: 1; + display: flex; + align-items: center; + flex: 1; + overflow: hidden; +} + +.wiki-nav .in-folder .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; + display: flex; + align-items: center; + justify-content: center; +} + +.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; +} + +.wiki-nav-footer { + user-select: none; +} + +.wiki-nav-footer:hover { + background-color: #EFEFED; +} + +.wiki-nav-footer.return-to-app { + position: absolute; + width: 100%; + bottom: 0; +} + +.add-wiki-page-wrapper { + position: relative; +} + +.wiki-nav-footer .dropdown { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.wiki-nav-footer .dropdown button { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: none; + background-color: transparent !important; +} + +.wiki-nav-footer .dropdown button::after { + display: none !important; +} + +.wiki-nav-footer .dropdown button:focus { + box-shadow: none !important; +} + +.wiki-nav-footer .add-wiki-page-btn { + padding: 0 12px; + height: 40px; + border-top: none; + background-color: transparent; +} + +.wiki-nav-footer .add-wiki-page-btn .dtable-icon-add-table { + margin-left: 1px; + margin-right: 0.5rem; + transform: unset; +} + +.wiki-sidebar .wiki-nav-footer .add-wiki-page-btn { + border-top: none; +} + +.wiki-nav .page-operation-dropdown-toggle { + display: inline-block; + width: 0; + height: 0; + opacity: 0; +} + +.wiki-nav .page-operation-dropdown .page-operation-dropdown-menu { + margin-left: -15px; + margin-top: 4px; +} + +.page-operation-dropdown-menu .divider { + 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: ''; + width: 100%; + height: 1px; + position: absolute; + left: 0; + top: 39px; + background-color: #666 !important; +} + +.wiki-nav .wiki-page-item.page-can-drop-top::after { + top: 0; +} + +.dtable-dropdown-menu .dropdown-item .sf3-font { + font-size: 14px; + margin-right: 10px; + color: #8c8c8c; +} + +.dtable-dropdown-menu .dropdown-item:hover .sf3-font { + color: #fff; +} + +.dtable-dropdown-menu.large .dropdown-item { + min-height: 32px; + padding: 3px 12px; + display: flex; + align-items: center; +} + +.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 { + 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 { + 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; + font-size: 16px; +} diff --git a/frontend/src/pages/wiki2/index.js b/frontend/src/pages/wiki2/index.js index 9c315c801a..f3d192acea 100644 --- a/frontend/src/pages/wiki2/index.js +++ b/frontend/src/pages/wiki2/index.js @@ -10,7 +10,7 @@ import WikiConfig from './models/wiki-config'; import toaster from '../../components/toast'; import SidePanel from './side-panel'; import MainPanel from './main-panel'; -import PageUtils from './view-structure/page-utils'; +import PageUtils from './wiki-nav/page-utils'; import LocalStorage from '../../utils/local-storage-utils'; import '../../css/layout.css'; diff --git a/frontend/src/pages/wiki2/side-panel.js b/frontend/src/pages/wiki2/side-panel.js index fdf7ac4954..0851635270 100644 --- a/frontend/src/pages/wiki2/side-panel.js +++ b/frontend/src/pages/wiki2/side-panel.js @@ -5,11 +5,11 @@ import { UncontrolledTooltip } from 'reactstrap'; import { gettext, isWiki2, wikiId } from '../../utils/constants'; import toaster from '../../components/toast'; import Loading from '../../components/loading'; -import ViewStructure from './view-structure'; -import PageUtils from './view-structure/page-utils'; -import NewFolderDialog from './view-structure/new-folder-dialog'; -import AddNewPageDialog from './view-structure/add-new-page-dialog'; -import ViewStructureFooter from './view-structure/view-structure-footer'; +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'; @@ -103,10 +103,10 @@ class SidePanel extends Component { this.props.saveWikiConfig(config, onSuccess, errorCallback); }; - movePage = ({ moved_view_id, target_view_id, source_view_folder_id, target_view_folder_id, move_position }) => { + movePage = ({ moved_page_id, target_page_id, source_page_folder_id, target_page_folder_id, move_position }) => { let config = deepCopy(this.props.config); let { navigation } = config; - PageUtils.movePage(navigation, moved_view_id, target_view_id, source_view_folder_id, target_view_folder_id, move_position); + PageUtils.movePage(navigation, moved_page_id, target_page_id, source_page_folder_id, target_page_folder_id, move_position); config.navigation = navigation; this.props.saveWikiConfig(config); }; @@ -279,15 +279,15 @@ class SidePanel extends Component { const { pages, navigation } = config; return (
- {isWiki2 && - } diff --git a/frontend/src/pages/wiki2/top-nav/index.jsx b/frontend/src/pages/wiki2/top-nav/index.jsx index ba7256827c..2c3708b701 100644 --- a/frontend/src/pages/wiki2/top-nav/index.jsx +++ b/frontend/src/pages/wiki2/top-nav/index.jsx @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import NavItemIcon from '../view-structure/nav-item-icon'; +import NavItemIcon from '../common/nav-item-icon'; import './index.css'; // Find the path array from the root to the leaf based on the currentPageId (leaf) diff --git a/frontend/src/pages/wiki2/view-structure/index.js b/frontend/src/pages/wiki2/view-structure/index.js deleted file mode 100644 index e05d8b40e9..0000000000 --- a/frontend/src/pages/wiki2/view-structure/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import ViewStructure from './view-structure'; - -export default ViewStructure; diff --git a/frontend/src/pages/wiki2/view-structure/views/view-edit-popover.js b/frontend/src/pages/wiki2/view-structure/views/view-edit-popover.js deleted file mode 100644 index 414207b99c..0000000000 --- a/frontend/src/pages/wiki2/view-structure/views/view-edit-popover.js +++ /dev/null @@ -1,86 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { PopoverBody } from 'reactstrap'; -import SeahubPopover from '../../../../components/common/seahub-popover'; -import { gettext } from '../../../../utils/constants'; - -import '../../css/view-edit-popover.css'; - - -class ViewEditPopover extends Component { - - constructor(props) { - super(props); - this.viewInputRef = React.createRef(); - } - - componentDidMount() { - const txtLength = this.props.viewName.length; - this.viewInputRef.current.setSelectionRange(0, txtLength); - } - - onChangeName = (e) => { - let name = e.target.value; - this.props.onChangeName(name); - }; - - onEnter = (e) => { - e.preventDefault(); - this.props.toggleViewEditor(); - }; - - handleKeyDown = (e) => { - if (e.keyCode === 13) { - e.preventDefault(); - this.props.toggleViewEditor(); - } - }; - - renderViewName = () => { - const { viewName } = this.props; - return ( -
- -
- ); - }; - - render() { - return ( - -
- {gettext('Modify Name')} -
- - {this.renderViewName()} - -
- ); - } -} - -ViewEditPopover.propTypes = { - viewName: PropTypes.string, - onChangeName: PropTypes.func, - toggleViewEditor: PropTypes.func, - viewEditorId: PropTypes.string, -}; - -export default ViewEditPopover; diff --git a/frontend/src/pages/wiki2/view-structure/add-new-page-dialog.js b/frontend/src/pages/wiki2/wiki-nav/add-new-page-dialog.js similarity index 100% rename from frontend/src/pages/wiki2/view-structure/add-new-page-dialog.js rename to frontend/src/pages/wiki2/wiki-nav/add-new-page-dialog.js diff --git a/frontend/src/pages/wiki2/view-structure/add-view-dropdownmenu.js b/frontend/src/pages/wiki2/wiki-nav/add-page-dropdownmenu.js similarity index 87% rename from frontend/src/pages/wiki2/view-structure/add-view-dropdownmenu.js rename to frontend/src/pages/wiki2/wiki-nav/add-page-dropdownmenu.js index 2fdf827e78..7a6ae73de5 100644 --- a/frontend/src/pages/wiki2/view-structure/add-view-dropdownmenu.js +++ b/frontend/src/pages/wiki2/wiki-nav/add-page-dropdownmenu.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { Dropdown, DropdownMenu, DropdownItem, DropdownToggle } from 'reactstrap'; import { gettext } from '../../../utils/constants'; -class AddViewDropdownMenu extends Component { +class AddPageDropdownMenu extends Component { toggle = event => { this.onStopPropagation(event); @@ -12,7 +12,7 @@ class AddViewDropdownMenu extends Component { addPage = event => { this.onStopPropagation(event); - this.props.onToggleAddView(null); + this.props.onToggleAddPage(null); }; onToggleAddFolder = event => { @@ -43,10 +43,10 @@ class AddViewDropdownMenu extends Component { } } -AddViewDropdownMenu.propTypes = { +AddPageDropdownMenu.propTypes = { toggleDropdown: PropTypes.func, - onToggleAddView: PropTypes.func, + onToggleAddPage: PropTypes.func, onToggleAddFolder: PropTypes.func, }; -export default AddViewDropdownMenu; +export default AddPageDropdownMenu; diff --git a/frontend/src/pages/wiki2/view-structure/constant.js b/frontend/src/pages/wiki2/wiki-nav/constant.js similarity index 100% rename from frontend/src/pages/wiki2/view-structure/constant.js rename to frontend/src/pages/wiki2/wiki-nav/constant.js diff --git a/frontend/src/pages/wiki2/view-structure/folders/dragged-folder-item.js b/frontend/src/pages/wiki2/wiki-nav/folders/dragged-folder-item.js similarity index 83% rename from frontend/src/pages/wiki2/view-structure/folders/dragged-folder-item.js rename to frontend/src/pages/wiki2/wiki-nav/folders/dragged-folder-item.js index 917099925e..6052c04a31 100644 --- a/frontend/src/pages/wiki2/view-structure/folders/dragged-folder-item.js +++ b/frontend/src/pages/wiki2/wiki-nav/folders/dragged-folder-item.js @@ -40,24 +40,24 @@ const dropTarget = { if (className.includes('can-drop-top')) { move_position = 'move_above'; } - let moveInto = className.includes('dragged-view-over'); + let moveInto = className.includes('dragged-page-over'); // 1. drag source is page if (sourceRow.mode === DRAGGED_PAGE_MODE) { const sourceFolderId = sourceRow.folderId; - const draggedViewId = sourceRow.data.id; + const draggedPageId = sourceRow.data.id; // 1.1 move page into folder if (moveInto) { - props.onMoveView({ - moved_view_id: draggedViewId, - target_view_id: null, - source_view_folder_id: sourceFolderId, - target_view_folder_id: targetFolderId, + 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(draggedViewId, sourceFolderId, targetFolderId, move_position); + props.movePageOut(draggedPageId, sourceFolderId, targetFolderId, move_position); return; } } @@ -98,6 +98,6 @@ const dropCollect = (connect, monitor) => ({ monitor, }); -export default DropTarget('ViewStructure', dropTarget, dropCollect)( - DragSource('ViewStructure', dragSource, dragCollect)(FolderItem) +export default DropTarget('WikiNav', dropTarget, dropCollect)( + DragSource('WikiNav', dragSource, dragCollect)(FolderItem) ); diff --git a/frontend/src/pages/wiki2/view-structure/folders/folder-item.js b/frontend/src/pages/wiki2/wiki-nav/folders/folder-item.js similarity index 72% rename from frontend/src/pages/wiki2/view-structure/folders/folder-item.js rename to frontend/src/pages/wiki2/wiki-nav/folders/folder-item.js index 6ba24baef1..4dbe611438 100644 --- a/frontend/src/pages/wiki2/view-structure/folders/folder-item.js +++ b/frontend/src/pages/wiki2/wiki-nav/folders/folder-item.js @@ -2,10 +2,10 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import FolderOperationDropdownMenu from './folder-operation-dropdownmenu'; -import DraggedViewItem from '../views/dragged-view-item'; +import DraggedPageItem from '../pages/dragged-page-item'; import DraggedFolderItem from './dragged-folder-item'; -import ViewEditPopover from '../../view-structure/views/view-edit-popover'; -import NavItemIcon from '../nav-item-icon'; +import NameEditPopover from '../../common/name-edit-popover'; +import NavItemIcon from '../../common/nav-item-icon'; class FolderItem extends Component { @@ -53,40 +53,35 @@ class FolderItem extends Component { changeItemFreeze = (isFreeze) => { this.isFreeze = true; - // if (isFreeze) { - // this.foldRef.classList.add('fold-freezed'); - // } else { - // this.foldRef.classList.remove('fold-freezed'); - // } }; - renderFolder = (folder, index, pagesLength, isOnlyOneView, id_view_map) => { - const { isEditMode, views, pathStr } = this.props; + renderFolder = (folder, index, pagesLength, isOnlyOnePage, id_page_map) => { + const { isEditMode, pages, pathStr } = this.props; const { id: folderId } = folder; return ( { - const { isEditMode, views, folder, pathStr } = this.props; - const id = view.id; - if (!views.find(item => item.id === id)) 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), view)} - viewIndex={index} + page={Object.assign({}, pages.find(item => item.id === id), page)} + pageIndex={index} folderId={folder.id} isEditMode={isEditMode} renderFolderMenuItems={this.props.renderFolderMenuItems} duplicatePage={this.props.duplicatePage} onSetFolderId={this.props.onSetFolderId} - onSelectView={this.props.onSelectView} + setCurrentPage={this.props.setCurrentPage} onUpdatePage={this.props.onUpdatePage} - onDeleteView={this.props.onDeleteView} - onMoveViewToFolder={(targetFolderId) => { - this.props.onMoveViewToFolder(folder.id, view.id, targetFolderId); + onDeletePage={this.props.onDeletePage} + onMovePageToFolder={(targetFolderId) => { + this.props.onMovePageToFolder(folder.id, page.id, targetFolderId); }} - onMoveView={this.props.onMoveView} + onMovePage={this.props.onMovePage} onMoveFolder={this.props.onMoveFolder} - views={views} - pathStr={pathStr + '-' + view.id} + pages={pages} + pathStr={pathStr + '-' + page.id} currentPageId={this.props.currentPageId} addPageInside={this.props.addPageInside} getFoldState={this.props.getFoldState} @@ -136,14 +131,14 @@ class FolderItem extends Component { getFolderClassName = (layerDragProps, state) => { if (!state || ! layerDragProps || !layerDragProps.clientOffset) { - return 'view-folder-wrapper'; + 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-view-over '; + className += ' dragged-page-over '; } // top if (top + 10 > y) { @@ -154,7 +149,7 @@ class FolderItem extends Component { className += ' can-drop '; } this.props.setClassName(className); - return className + 'view-folder-wrapper'; + return className + 'page-folder-wrapper'; }; getFolderChildrenHeight = () => { @@ -174,16 +169,16 @@ class FolderItem extends Component { render() { const { connectDropTarget, connectDragPreview, connectDragSource, isOver, canDrop, - isEditMode, folder, pagesLength, id_view_map, isOnlyOneView, layerDragProps, + 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 viewEditorId = `folder-item-${folderId}`; + let navItemId = `folder-item-${folderId}`; let fn = isEditMode ? connectDragSource : (argu) => {argu;}; return (
this.foldRef = ref} onClick={this.toggleExpand} > @@ -199,7 +194,7 @@ class FolderItem extends Component {
{this.state.isMouseEnter ?
@@ -210,13 +205,11 @@ class FolderItem extends Component { } {name} {isEditing && - }
@@ -226,7 +219,7 @@ class FolderItem extends Component { changeItemFreeze={this.changeItemFreeze} openFolderEditor={this.openFolderEditor} onDeleteFolder={this.props.onDeleteFolder} - onToggleAddView={this.props.onToggleAddView} + onToggleAddPage={this.props.onToggleAddPage} folderId={folderId} /> } @@ -235,13 +228,13 @@ class FolderItem extends Component { )) }
{!folded && children && children.map((item, index) => { - return item.type === 'folder' ? this.renderFolder(item, index, pagesLength, isOnlyOneView, id_view_map) : this.renderView(item, index, pagesLength, isOnlyOneView); + return item.type === 'folder' ? this.renderFolder(item, index, pagesLength, isOnlyOnePage, id_page_map) : this.renderPage(item, index, pagesLength, isOnlyOnePage); }) }
@@ -255,7 +248,7 @@ FolderItem.propTypes = { folder: PropTypes.object, folderIndex: PropTypes.number, pagesLength: PropTypes.number, - id_view_map: PropTypes.object, + id_page_map: PropTypes.object, isOver: PropTypes.bool, canDrop: PropTypes.bool, isDragging: PropTypes.bool, @@ -266,16 +259,16 @@ FolderItem.propTypes = { duplicatePage: PropTypes.func, onSetFolderId: PropTypes.func, toggleExpand: PropTypes.func, - onToggleAddView: PropTypes.func, + onToggleAddPage: PropTypes.func, onModifyFolder: PropTypes.func, onDeleteFolder: PropTypes.func, - onSelectView: PropTypes.func, + setCurrentPage: PropTypes.func, onUpdatePage: PropTypes.func, - onDeleteView: PropTypes.func, - onMoveViewToFolder: PropTypes.func, - onMoveView: PropTypes.func, - isOnlyOneView: PropTypes.bool, - views: PropTypes.array, + onDeletePage: PropTypes.func, + onMovePageToFolder: PropTypes.func, + onMovePage: PropTypes.func, + isOnlyOnePage: PropTypes.bool, + pages: PropTypes.array, onMoveFolder: PropTypes.func, moveFolderToFolder: PropTypes.func, pathStr: PropTypes.string, diff --git a/frontend/src/pages/wiki2/view-structure/folders/folder-operation-dropdownmenu.js b/frontend/src/pages/wiki2/wiki-nav/folders/folder-operation-dropdownmenu.js similarity index 92% rename from frontend/src/pages/wiki2/view-structure/folders/folder-operation-dropdownmenu.js rename to frontend/src/pages/wiki2/wiki-nav/folders/folder-operation-dropdownmenu.js index 913c2620d6..e9372e0d75 100644 --- a/frontend/src/pages/wiki2/view-structure/folders/folder-operation-dropdownmenu.js +++ b/frontend/src/pages/wiki2/wiki-nav/folders/folder-operation-dropdownmenu.js @@ -10,8 +10,7 @@ export default class FolderOperationDropdownMenu extends Component { changeItemFreeze: PropTypes.func, openFolderEditor: PropTypes.func, onDeleteFolder: PropTypes.func, - onToggleAddView: PropTypes.func, - onToggleAddArchiveView: PropTypes.func, + onToggleAddPage: PropTypes.func, folderId: PropTypes.string, }; @@ -45,7 +44,7 @@ export default class FolderOperationDropdownMenu extends Component { @@ -56,7 +55,7 @@ export default class FolderOperationDropdownMenu extends Component { modifiers={{ preventOverflow: { boundariesElement: document.body } }} positionFixed={true} > - + {gettext('Add page')} diff --git a/frontend/src/pages/wiki2/view-structure/html5DragDropContext.js b/frontend/src/pages/wiki2/wiki-nav/html5DragDropContext.js similarity index 100% rename from frontend/src/pages/wiki2/view-structure/html5DragDropContext.js rename to frontend/src/pages/wiki2/wiki-nav/html5DragDropContext.js diff --git a/frontend/src/pages/wiki2/wiki-nav/index.js b/frontend/src/pages/wiki2/wiki-nav/index.js new file mode 100644 index 0000000000..00064308a8 --- /dev/null +++ b/frontend/src/pages/wiki2/wiki-nav/index.js @@ -0,0 +1,3 @@ +import WikiNav from './wiki-nav'; + +export default WikiNav; diff --git a/frontend/src/pages/wiki2/view-structure/new-folder-dialog.js b/frontend/src/pages/wiki2/wiki-nav/new-folder-dialog.js similarity index 100% rename from frontend/src/pages/wiki2/view-structure/new-folder-dialog.js rename to frontend/src/pages/wiki2/wiki-nav/new-folder-dialog.js diff --git a/frontend/src/pages/wiki2/view-structure/page-utils.js b/frontend/src/pages/wiki2/wiki-nav/page-utils.js similarity index 100% rename from frontend/src/pages/wiki2/view-structure/page-utils.js rename to frontend/src/pages/wiki2/wiki-nav/page-utils.js diff --git a/frontend/src/pages/wiki2/view-structure/views/dragged-view-item.js b/frontend/src/pages/wiki2/wiki-nav/pages/dragged-page-item.js similarity index 69% rename from frontend/src/pages/wiki2/view-structure/views/dragged-view-item.js rename to frontend/src/pages/wiki2/wiki-nav/pages/dragged-page-item.js index d127e35248..9b5efb86f4 100644 --- a/frontend/src/pages/wiki2/view-structure/views/dragged-view-item.js +++ b/frontend/src/pages/wiki2/wiki-nav/pages/dragged-page-item.js @@ -1,12 +1,12 @@ import { DragSource, DropTarget } from 'react-dnd'; import { DRAGGED_FOLDER_MODE, DRAGGED_PAGE_MODE } from '../constant'; -import ViewItem from './view-item'; +import PageItem from './page-item'; const dragSource = { beginDrag: props => { return { - idx: props.viewIndex, - data: { ...props.view, index: props.viewIndex }, + idx: props.pageIndex, + data: { ...props.page, index: props.pageIndex }, folderId: props.folderId, mode: DRAGGED_PAGE_MODE, }; @@ -20,7 +20,7 @@ const dragSource = { } }, isDragging(props) { - const { draggedPage, viewIndex: targetIndex } = props; + const { draggedPage, pageIndex: targetIndex } = props; const { idx } = draggedPage; return idx > targetIndex; } @@ -31,12 +31,12 @@ const dropTarget = { const sourceRow = monitor.getItem(); // 1 drag page if (sourceRow.mode === DRAGGED_PAGE_MODE) { - const { infolder, viewIndex: targetIndex, view: targetView, folderId: targetFolderId } = props; + const { infolder, pageIndex: targetIndex, page: targetPage, folderId: targetFolderId } = props; const sourceFolderId = sourceRow.folderId; - const draggedViewId = sourceRow.data.id; - const targetViewId = targetView.id; + const draggedPageId = sourceRow.data.id; + const targetPageId = targetPage.id; - if (draggedViewId !== targetViewId) { + if (draggedPageId !== targetPageId) { const sourceIndex = sourceRow.idx; let move_position; if (infolder) { @@ -45,11 +45,11 @@ const dropTarget = { move_position = sourceIndex > targetIndex ? 'move_above' : 'move_below'; } - props.onMoveView({ - moved_view_id: draggedViewId, - target_view_id: targetViewId, - source_view_folder_id: sourceFolderId, - target_view_folder_id: targetFolderId, + props.onMovePage({ + moved_page_id: draggedPageId, + target_page_id: targetPageId, + source_page_folder_id: sourceFolderId, + target_page_folder_id: targetFolderId, move_position, }); } @@ -57,15 +57,15 @@ const dropTarget = { } // 1 drag folder if (sourceRow.mode === DRAGGED_FOLDER_MODE) { - const { viewIndex: targetIndex, view: targetView } = props; + const { pageIndex: targetIndex, page: targetPage } = props; const draggedFolderId = sourceRow.data.id; - const targetViewId = targetView.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, - targetViewId, + targetPageId, sourceIndex > targetIndex ? 'move_above' : 'move_below', ); return; @@ -86,6 +86,6 @@ const dropCollect = (connect, monitor) => ({ draggedPage: monitor.getItem() }); -export default DropTarget('ViewStructure', dropTarget, dropCollect)( - DragSource('ViewStructure', dragSource, dragCollect)(ViewItem) +export default DropTarget('WikiNav', dropTarget, dropCollect)( + DragSource('WikiNav', dragSource, dragCollect)(PageItem) ); diff --git a/frontend/src/pages/wiki2/view-structure/views/page-dropdownmenu.js b/frontend/src/pages/wiki2/wiki-nav/pages/page-dropdownmenu.js similarity index 80% rename from frontend/src/pages/wiki2/view-structure/views/page-dropdownmenu.js rename to frontend/src/pages/wiki2/wiki-nav/pages/page-dropdownmenu.js index 2fbd5fb7dd..a9e1ea50ca 100644 --- a/frontend/src/pages/wiki2/view-structure/views/page-dropdownmenu.js +++ b/frontend/src/pages/wiki2/wiki-nav/pages/page-dropdownmenu.js @@ -8,21 +8,20 @@ import { getWikPageLink } from '../../utils'; export default class PageDropdownMenu extends Component { static propTypes = { - view: PropTypes.object.isRequired, - views: PropTypes.array, + 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, - toggleViewEditor: PropTypes.func, + toggleNameEditor: PropTypes.func, duplicatePage: PropTypes.func, onSetFolderId: PropTypes.func, - onDeleteView: PropTypes.func, - onModifyViewType: PropTypes.func, - onMoveViewToFolder: PropTypes.func, - isOnlyOneView: PropTypes.bool, + onDeletePage: PropTypes.func, + onMovePageToFolder: PropTypes.func, + isOnlyOnePage: PropTypes.bool, }; constructor(props) { @@ -34,9 +33,9 @@ export default class PageDropdownMenu extends Component { } calculateNameMap = () => { - const { views } = this.props; - return views.reduce((map, view) => { - map[view.name] = true; + const { pages } = this.props; + return pages.reduce((map, page) => { + map[page.name] = true; return map; }, {}); }; @@ -49,28 +48,23 @@ export default class PageDropdownMenu extends Component { this.props.toggle(); }; - onRenameView = (event) => { + onRename = (event) => { event.nativeEvent.stopImmediatePropagation(); - this.props.toggleViewEditor(); + this.props.toggleNameEditor(); }; - onDeleteView = (event) => { + onDeletePage = (event) => { event.nativeEvent.stopImmediatePropagation(); - this.props.onDeleteView(); + this.props.onDeletePage(); }; - onModifyViewType = (event) => { - event.nativeEvent.stopImmediatePropagation(); - this.props.onModifyViewType(); - }; - - onMoveViewToFolder = (targetFolderId) => { - this.props.onMoveViewToFolder(targetFolderId); + onMovePageToFolder = (targetFolderId) => { + this.props.onMovePageToFolder(targetFolderId); }; onRemoveFromFolder = (evt) => { evt.nativeEvent.stopImmediatePropagation(); - this.props.onMoveViewToFolder(null); + this.props.onMovePageToFolder(null); }; onToggleFoldersMenu = () => { @@ -78,8 +72,8 @@ export default class PageDropdownMenu extends Component { }; duplicatePage = () => { - const { view, folderId } = this.props; - const { id: from_page_id, name } = view; + const { page, folderId } = this.props; + const { id: from_page_id, name } = page; let duplicateCount = 1; let newName = name + '(copy)'; while (this.pageNameMap[newName]) { @@ -104,8 +98,8 @@ export default class PageDropdownMenu extends Component { }; handleCopyLink = () => { - const { view } = this.props; - const wikiLink = getWikPageLink(view.id); + const { page } = this.props; + const wikiLink = getWikPageLink(page.id); const successText = gettext('Copied link to clipboard'); const failedText = gettext('Copy failed'); @@ -117,26 +111,26 @@ export default class PageDropdownMenu extends Component { }; handleOpenInNewTab = () => { - const { view } = this.props; - const wikiLink = getWikPageLink(view.id); + const { page } = this.props; + const wikiLink = getWikPageLink(page.id); window.open(wikiLink); }; render() { const { - folderId, canDelete, canDuplicate, renderFolderMenuItems, pagesLength, isOnlyOneView, + folderId, canDelete, canDuplicate, renderFolderMenuItems, pagesLength, isOnlyOnePage, } = this.props; - const folderMenuItems = renderFolderMenuItems && renderFolderMenuItems({ currentFolderId: folderId, onMoveViewToFolder: this.onMoveViewToFolder }); + const folderMenuItems = renderFolderMenuItems && renderFolderMenuItems({ currentFolderId: folderId, onMovePageToFolder: this.onMovePageToFolder }); return ( - + {gettext('Copy link')} - + {gettext('Modify name')} @@ -155,8 +149,8 @@ export default class PageDropdownMenu extends Component { {gettext('Duplicate page')} } - {(isOnlyOneView || pagesLength === 1 || !canDelete) ? '' : ( - + {(isOnlyOnePage || pagesLength === 1 || !canDelete) ? '' : ( + {gettext('Delete page')} diff --git a/frontend/src/pages/wiki2/view-structure/views/view-item.js b/frontend/src/pages/wiki2/wiki-nav/pages/page-item.js similarity index 53% rename from frontend/src/pages/wiki2/view-structure/views/view-item.js rename to frontend/src/pages/wiki2/wiki-nav/pages/page-item.js index ff6fce21ab..f83ce30342 100644 --- a/frontend/src/pages/wiki2/view-structure/views/view-item.js +++ b/frontend/src/pages/wiki2/wiki-nav/pages/page-item.js @@ -1,30 +1,30 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import ViewEditPopover from './view-edit-popover'; +import NameEditPopover from '../../common/name-edit-popover'; +import NavItemIcon from '../../common/nav-item-icon'; import PageDropdownMenu from './page-dropdownmenu'; -import DeleteDialog from './delete-dialog'; +import DeleteDialog from '../../common/delete-dialog'; import { gettext } from '../../../../utils/constants'; import AddNewPageDialog from '../add-new-page-dialog'; import Icon from '../../../../components/icon'; -import NavItemIcon from '../nav-item-icon'; -import DraggedViewItem from '../views/dragged-view-item'; +import DraggedPageItem from './dragged-page-item'; -class ViewItem extends Component { +class PageItem extends Component { constructor(props) { super(props); this.state = { - isShowViewEditor: false, - isShowViewOperationDropdown: false, + isShowNameEditor: false, + isShowOperationDropdown: false, isShowDeleteDialog: false, isShowInsertPage: false, - viewName: props.view.name || '', - viewIcon: props.view.icon, - isSelected: props.currentPageId === props.view.id, + pageName: props.page.name || '', + pageIcon: props.page.icon, + isSelected: props.currentPageId === props.page.id, isMouseEnter: false, }; - this.viewItemRef = React.createRef(); + this.pageItemRef = React.createRef(); } onMouseEnter = () => { @@ -43,18 +43,18 @@ class ViewItem extends Component { onCurrentPageChanged = (currentPageId) => { const { isSelected } = this.state; - if (currentPageId === this.props.view.id && isSelected === false) { + if (currentPageId === this.props.page.id && isSelected === false) { this.setState({ isSelected: true }); - } else if (currentPageId !== this.props.view.id && isSelected === true) { + } else if (currentPageId !== this.props.page.id && isSelected === true) { this.setState({ isSelected: false }); } }; - toggleViewEditor = (e) => { + toggleNameEditor = (e) => { if (e) e.stopPropagation(); - this.setState({ isShowViewEditor: !this.state.isShowViewEditor }, () => { - if (!this.state.isShowViewEditor) { - this.saveViewProperties(); + this.setState({ isShowNameEditor: !this.state.isShowNameEditor }, () => { + if (!this.state.isShowNameEditor) { + this.savePageProperties(); } }); }; @@ -63,28 +63,28 @@ class ViewItem extends Component { this.setState({ isShowInsertPage: !this.state.isShowInsertPage }); }; - saveViewProperties = () => { - const { name, icon, id } = this.props.view; - const { viewIcon } = this.state; - let viewName = this.state.viewName.trim(); - if (viewIcon !== icon || viewName !== name) { + savePageProperties = () => { + const { name, icon, id } = this.props.page; + const { pageIcon } = this.state; + let pageName = this.state.pageName.trim(); + if (pageIcon !== icon || pageName !== name) { let newView = {}; - if (viewName !== name) { - newView.name = viewName; + if (pageName !== name) { + newView.name = pageName; } - if (viewIcon !== icon) { - newView.icon = viewIcon; + if (pageIcon !== icon) { + newView.icon = pageIcon; } this.props.onUpdatePage(id, newView); } }; - onChangeName = (newViewName) => { - this.setState({ viewName: newViewName }); + onChangeName = (newName) => { + this.setState({ pageName: newName }); }; - onChangeIcon = (newViewIcon) => { - this.setState({ viewIcon: newViewIcon }); + onChangeIcon = (newIcon) => { + this.setState({ pageIcon: newIcon }); }; openDeleteDialog = () => { @@ -95,28 +95,17 @@ class ViewItem extends Component { this.setState({ isShowDeleteDialog: false }); }; - onViewOperationDropdownToggle = () => { - const isShowViewOperationDropdown = !this.state.isShowViewOperationDropdown; - this.setState({ isShowViewOperationDropdown }); - this.changeItemFreeze(isShowViewOperationDropdown); + toggleDropdown = () => { + const isShowOperationDropdown = !this.state.isShowOperationDropdown; + this.setState({ isShowOperationDropdown }); + this.changeItemFreeze(isShowOperationDropdown); }; changeItemFreeze = (isFreeze) => { if (isFreeze) { - this.viewItemRef.classList.add('view-freezed'); + this.pageItemRef.classList.add('wiki-page-freezed'); } else { - this.viewItemRef.classList.remove('view-freezed'); - } - }; - - renderIcon = (icon) => { - if (!icon) { - return null; - } - if (icon.includes('dtable-icon')) { - return ; - } else { - return ; + this.pageItemRef.classList.remove('wiki-page-freezed'); } }; @@ -125,7 +114,7 @@ class ViewItem extends Component { }; getFolderChildrenHeight = () => { - const folded = this.props.getFoldState(this.props.view.id); + const folded = this.props.getFoldState(this.props.page.id); if (folded) return 0; return 'auto'; }; @@ -135,33 +124,33 @@ class ViewItem extends Component { e.nativeEvent.stopImmediatePropagation(); }; - renderView = (view, index, pagesLength, isOnlyOneView) => { - const { isEditMode, views, folderId, pathStr } = this.props; - const id = view.id; - if (!views.find(item => item.id === id)) return; + renderPage = (page, index, pagesLength, isOnlyOnePage) => { + const { isEditMode, pages, folderId, pathStr } = this.props; + const id = page.id; + if (!pages.find(item => item.id === id)) return; return ( - item.id === id), view)} - viewIndex={index} + 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} - onSelectView={this.props.onSelectView} + setCurrentPage={this.props.setCurrentPage} onUpdatePage={this.props.onUpdatePage} - onDeleteView={this.props.onDeleteView} - onMoveViewToFolder={(targetFolderId) => { - this.props.onMoveViewToFolder(folderId, view.id, targetFolderId); + onDeletePage={this.props.onDeletePage} + onMovePageToFolder={(targetFolderId) => { + this.props.onMovePageToFolder(folderId, page.id, targetFolderId); }} - onMoveView={this.props.onMoveView} + onMovePage={this.props.onMovePage} onMoveFolder={this.props.onMoveFolder} - views={views} - pathStr={pathStr + '-' + view.id} + pages={pages} + pathStr={pathStr + '-' + page.id} currentPageId={this.props.currentPageId} addPageInside={this.props.addPageInside} getFoldState={this.props.getFoldState} @@ -172,58 +161,57 @@ class ViewItem extends Component { toggleExpand = (e) => { e.nativeEvent.stopImmediatePropagation(); - this.props.toggleExpand(this.props.view.id); + this.props.toggleExpand(this.props.page.id); this.forceUpdate(); }; onAddNewPage = (newPage) => { - const { view } = this.props; - this.props.addPageInside(Object.assign({ parentPageId: view.id }, newPage)); + this.props.addPageInside(Object.assign({ parentPageId: this.props.page.id }, newPage)); }; render() { const { connectDragSource, connectDragPreview, connectDropTarget, isOver, canDrop, isDragging, - infolder, view, pagesLength, isEditMode, folderId, isOnlyOneView, pathStr, + infolder, page, pagesLength, isEditMode, folderId, isOnlyOnePage, pathStr, } = this.props; - const { isShowViewEditor, viewName, viewIcon, isSelected } = this.state; - const isOverView = isOver && canDrop; - if (isSelected) this.setDocUuid(view.docUuid); + const { isShowNameEditor, pageName, isSelected } = this.state; + const isOverPage = isOver && canDrop; + if (isSelected) this.setDocUuid(page.docUuid); - let viewCanDropTop; - let viewCanDrop; + let pageCanDropTop; + let pageCanDrop; if (infolder) { - viewCanDropTop = false; - viewCanDrop = isOverView; + pageCanDropTop = false; + pageCanDrop = isOverPage; } else { - viewCanDropTop = isOverView && isDragging; - viewCanDrop = isOverView && !isDragging; + pageCanDropTop = isOverPage && isDragging; + pageCanDrop = isOverPage && !isDragging; } - let viewEditorId = `view-editor-${view.id}`; + let navItemId = `page-editor-${page.id}`; let fn = isEditMode ? connectDragSource : (argu) => {argu;}; - let childNumber = Array.isArray(view.children) ? view.children.length : 0; + let childNumber = Array.isArray(page.children) ? page.children.length : 0; - const folded = this.props.getFoldState(view.id); + const folded = this.props.getFoldState(page.id); return (
{ fn(connectDropTarget( connectDragPreview(
this.viewItemRef = ref} + ref={ref => this.pageItemRef = ref} onMouseEnter={this.onMouseEnter} onMouseMove={this.onMouseMove} onMouseLeave={this.onMouseLeave} - id={viewEditorId} + id={navItemId} > -
{} : (e) => this.props.onSelectView(view.id)}> -
+
{} : (e) => this.props.setCurrentPage(page.id)}> +
{childNumber === 0 && } @@ -235,16 +223,13 @@ class ViewItem extends Component {
} - {/* {this.renderIcon(view.icon)} */} - {view.name} - {isShowViewEditor && ( - {page.name} + {isShowNameEditor && ( + )}
@@ -252,24 +237,24 @@ class ViewItem extends Component {
{isEditMode && <> -
+
- {this.state.isShowViewOperationDropdown && + {this.state.isShowOperationDropdown && }
@@ -282,7 +267,7 @@ class ViewItem extends Component { {this.state.isShowDeleteDialog && } {this.state.isShowInsertPage && @@ -297,13 +282,13 @@ class ViewItem extends Component { )) }
- {view.children && - view.children.map((item, index) => { - return this.renderView(item, index, pagesLength, isOnlyOneView); + {page.children && + page.children.map((item, index) => { + return this.renderPage(item, index, pagesLength, isOnlyOnePage); }) }
@@ -312,17 +297,17 @@ class ViewItem extends Component { } } -ViewItem.propTypes = { +PageItem.propTypes = { isOver: PropTypes.bool, canDrop: PropTypes.bool, isDragging: PropTypes.bool, draggedPage: PropTypes.object, isEditMode: PropTypes.bool, infolder: PropTypes.bool, - view: PropTypes.object, + page: PropTypes.object, folder: PropTypes.object, - views: PropTypes.array, - viewIndex: PropTypes.number, + pages: PropTypes.array, + pageIndex: PropTypes.number, folderId: PropTypes.string, pagesLength: PropTypes.number, connectDragSource: PropTypes.func, @@ -331,12 +316,12 @@ ViewItem.propTypes = { renderFolderMenuItems: PropTypes.func, duplicatePage: PropTypes.func, onSetFolderId: PropTypes.func, - onSelectView: PropTypes.func, + setCurrentPage: PropTypes.func, onUpdatePage: PropTypes.func, - onDeleteView: PropTypes.func, - onMoveViewToFolder: PropTypes.func, - onMoveView: PropTypes.func, - isOnlyOneView: PropTypes.bool, + onDeletePage: PropTypes.func, + onMovePageToFolder: PropTypes.func, + onMovePage: PropTypes.func, + isOnlyOnePage: PropTypes.bool, onMoveFolder: PropTypes.func, pathStr: PropTypes.string, currentPageId: PropTypes.string, @@ -345,4 +330,4 @@ ViewItem.propTypes = { toggleExpand: PropTypes.func, }; -export default ViewItem; +export default PageItem; diff --git a/frontend/src/pages/wiki2/view-structure/view-structure-footer.js b/frontend/src/pages/wiki2/wiki-nav/wiki-nav-footer.js similarity index 67% rename from frontend/src/pages/wiki2/view-structure/view-structure-footer.js rename to frontend/src/pages/wiki2/wiki-nav/wiki-nav-footer.js index a580a9e0c2..376e80b288 100644 --- a/frontend/src/pages/wiki2/view-structure/view-structure-footer.js +++ b/frontend/src/pages/wiki2/wiki-nav/wiki-nav-footer.js @@ -1,10 +1,10 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import CommonAddTool from '../../../components/common/common-add-tool'; -import AddViewDropdownMenu from './add-view-dropdownmenu'; +import AddPageDropdownMenu from './add-page-dropdownmenu'; import { gettext } from '../../../utils/constants'; -class ViewStructureFooter extends Component { +class WikiNavFooter extends Component { constructor(props) { super(props); @@ -20,17 +20,17 @@ class ViewStructureFooter extends Component { render() { return ( -
-
+
+
{this.state.isShowDropdownMenu && - } @@ -40,9 +40,9 @@ class ViewStructureFooter extends Component { } } -ViewStructureFooter.propTypes = { - onToggleAddView: PropTypes.func, +WikiNavFooter.propTypes = { + onToggleAddPage: PropTypes.func, onToggleAddFolder: PropTypes.func, }; -export default ViewStructureFooter; +export default WikiNavFooter; diff --git a/frontend/src/pages/wiki2/view-structure/view-structure.js b/frontend/src/pages/wiki2/wiki-nav/wiki-nav.js similarity index 66% rename from frontend/src/pages/wiki2/view-structure/view-structure.js rename to frontend/src/pages/wiki2/wiki-nav/wiki-nav.js index a5fc1c3b62..de76f6ea70 100644 --- a/frontend/src/pages/wiki2/view-structure/view-structure.js +++ b/frontend/src/pages/wiki2/wiki-nav/wiki-nav.js @@ -4,28 +4,28 @@ import { DropdownItem } from 'reactstrap'; import { DropTarget, DragLayer } from 'react-dnd'; import html5DragDropContext from './html5DragDropContext'; import DraggedFolderItem from './folders/dragged-folder-item'; -import DraggedViewItem from './views/dragged-view-item'; -import ViewStructureFooter from './view-structure-footer'; +import DraggedPageItem from './pages/dragged-page-item'; +import WikiNavFooter from './wiki-nav-footer'; import { repoID } from '../../../utils/constants'; -import '../css/view-structure.css'; +import '../css/wiki-nav.css'; -class ViewStructure extends Component { +class WikiNav extends Component { static propTypes = { isEditMode: PropTypes.bool, navigation: PropTypes.array, - views: PropTypes.array, + pages: PropTypes.array, onTogglePinViewList: PropTypes.func, - onToggleAddView: PropTypes.func, + onToggleAddPage: PropTypes.func, onToggleAddFolder: PropTypes.func, onModifyFolder: PropTypes.func, onDeleteFolder: PropTypes.func, onMoveFolder: PropTypes.func, - onSelectView: PropTypes.func, + setCurrentPage: PropTypes.func, onUpdatePage: PropTypes.func, - onDeleteView: PropTypes.func, - onMoveView: PropTypes.func, + onDeletePage: PropTypes.func, + onMovePage: PropTypes.func, moveFolderToFolder: PropTypes.func, movePageOut: PropTypes.func, duplicatePage: PropTypes.func, @@ -64,24 +64,24 @@ class ViewStructure extends Component { this.idFoldedStatusMap = idFoldedStatusMap; }; - onMoveViewToFolder = (source_view_folder_id, moved_view_id, target_view_folder_id) => { - this.props.onMoveView({ - moved_view_id, - source_view_folder_id, - target_view_folder_id, - target_view_id: null, + 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, onMoveViewToFolder }) => { + 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} ); @@ -96,31 +96,31 @@ class ViewStructure extends Component { return this.folderClassNameCache; }; - renderFolder = (folder, index, pagesLength, isOnlyOneView, id_view_map, layerDragProps) => { - const { isEditMode, views } = this.props; + renderFolder = (folder, index, pagesLength, isOnlyOnePage, id_page_map, layerDragProps) => { + const { isEditMode, pages } = this.props; const folderId = folder.id; return ( { - const { isEditMode, views } = this.props; - const id = view.id; - if (!views.find(item => item.id === id)) return; + renderPage = (page, index, pagesLength, isOnlyOnePage, id_page_map) => { + 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), view)} - views={views} - viewIndex={index} + page={Object.assign({}, pages.find(item => item.id === id), page)} + pages={pages} + pageIndex={index} folderId={folderId} isEditMode={isEditMode} renderFolderMenuItems={this.renderFolderMenuItems} duplicatePage={this.props.duplicatePage} onSetFolderId={this.props.onSetFolderId} - onSelectView={this.props.onSelectView} + setCurrentPage={this.props.setCurrentPage} onUpdatePage={this.props.onUpdatePage} - onDeleteView={this.props.onDeleteView} - onMoveViewToFolder={(targetFolderId) => { - this.onMoveViewToFolder(folderId, view.id, targetFolderId); + onDeletePage={this.props.onDeletePage} + onMovePageToFolder={(targetFolderId) => { + this.onMovePageToFolder(folderId, page.id, targetFolderId); }} - onMoveView={this.props.onMoveView} + onMovePage={this.props.onMovePage} onMoveFolder={this.props.onMoveFolder} - pathStr={view.id} + pathStr={page.id} currentPageId={this.props.currentPageId} addPageInside={this.props.addPageInside} getFoldState={this.getFoldState} @@ -173,21 +173,21 @@ class ViewStructure extends Component { // eslint-disable-next-line renderStructureBody = React.forwardRef((layerDragProps, ref) => { - const { navigation, views, isEditMode } = this.props; - let isOnlyOneView = false; - if (views.length === 1) { - isOnlyOneView = true; + const { navigation, pages, isEditMode } = this.props; + let isOnlyOnePage = false; + if (pages.length === 1) { + isOnlyOnePage = true; } - const pagesLength = views.length; - let id_view_map = {}; - views.forEach(view => id_view_map[view.id] = view); + 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, isOnlyOneView, id_view_map, layerDragProps) : - this.renderView(item, index, pagesLength, isOnlyOneView, id_view_map); + this.renderFolder(item, index, pagesLength, isOnlyOnePage, id_page_map, layerDragProps) : + this.renderPage(item, index, pagesLength, isOnlyOnePage, id_page_map); })}
); @@ -204,16 +204,16 @@ class ViewStructure extends Component { render() { const StructureBody = html5DragDropContext( - DropTarget('ViewStructure', {}, connect => ({ + DropTarget('WikiNav', {}, connect => ({ connectDropTarget: connect.dropTarget() }))(DragLayer(this.collect)(this.renderStructureBody)) ); return ( -
+
{(this.props.isEditMode) && - } @@ -222,4 +222,4 @@ class ViewStructure extends Component { } } -export default ViewStructure; +export default WikiNav;