mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-04 16:31:13 +00:00
Wiki add new page below or above (#7118)
* Wiki add new page below or above * change var name * remove sibling page * update create wiki page logic * fix page does not exist --------- Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com>
This commit is contained in:
@@ -132,7 +132,7 @@
|
||||
background-color: #DFDFDD;
|
||||
}
|
||||
|
||||
.wiki-nav .wiki-page-item .sf3-font.sf3-font-enlarge,
|
||||
.wiki-nav .wiki-page-item .wiki-add-page-btn .sf3-font.sf3-font-enlarge,
|
||||
.wiki-nav .wiki-page-item .more-wiki-page-operation .seafile-multicolor-icon-more-level {
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
@@ -270,13 +270,13 @@
|
||||
}
|
||||
|
||||
.wiki-nav,
|
||||
.wiki-nav .wiki-page-item .sf3-font.sf3-font-enlarge:hover,
|
||||
.wiki-nav .wiki-page-item .wiki-add-page-btn .sf3-font.sf3-font-enlarge:hover,
|
||||
.wiki-nav .wiki-page-item .seafile-multicolor-icon-more-level:hover {
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.wiki-nav .wiki2-trash .sf3-font,
|
||||
.wiki-nav .wiki-page-item .sf3-font.sf3-font-enlarge,
|
||||
.wiki-nav .wiki-page-item .wiki-add-page-btn .sf3-font.sf3-font-enlarge,
|
||||
.wiki-nav .wiki-page-item .seafile-multicolor-icon-more-level {
|
||||
color: #666;
|
||||
}
|
||||
|
@@ -83,16 +83,16 @@ class SidePanel extends PureComponent {
|
||||
});
|
||||
};
|
||||
|
||||
addPage = (page, parentId, successCallback, errorCallback, jumpToNewPage = true) => {
|
||||
addPage = (page, parent_id, successCallback, errorCallback, jumpToNewPage = true) => {
|
||||
const { config } = this.props;
|
||||
const navigation = config.navigation;
|
||||
const pageId = page.id;
|
||||
const page_id = page.id;
|
||||
config.pages.push(page);
|
||||
PageUtils.addPage(navigation, pageId, parentId);
|
||||
PageUtils.addPage({ navigation, page_id, parent_id });
|
||||
config.navigation = navigation;
|
||||
JSON.stringify(config);
|
||||
this.props.updateWikiConfig(config);
|
||||
jumpToNewPage && this.props.setCurrentPage(pageId, successCallback);
|
||||
jumpToNewPage && this.props.setCurrentPage(page_id, successCallback);
|
||||
successCallback && successCallback();
|
||||
};
|
||||
|
||||
@@ -104,6 +104,19 @@ class SidePanel extends PureComponent {
|
||||
this.props.updateWikiConfig(config);
|
||||
};
|
||||
|
||||
addSiblingPage = (page, parent_id, insert_position, sibling_page_id, successCallback) => {
|
||||
const { config } = this.props;
|
||||
const navigation = config.navigation;
|
||||
const page_id = page.page_id;
|
||||
config.pages.push(page);
|
||||
PageUtils.addPage({ navigation, page_id, parent_id, insert_position, sibling_page_id });
|
||||
config.navigation = navigation;
|
||||
JSON.stringify(config);
|
||||
this.props.updateWikiConfig(config);
|
||||
this.props.setCurrentPage(page_id, successCallback);
|
||||
successCallback && successCallback();
|
||||
};
|
||||
|
||||
toggleTrashDialog = () => {
|
||||
this.setState({ isShowTrashDialog: !this.state.isShowTrashDialog });
|
||||
};
|
||||
@@ -128,6 +141,7 @@ class SidePanel extends PureComponent {
|
||||
getCurrentPageId={this.props.getCurrentPageId}
|
||||
addPageInside={this.addPageInside}
|
||||
toggleTrashDialog={this.toggleTrashDialog}
|
||||
addSiblingPage={this.addSiblingPage}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
@@ -6,14 +6,16 @@ import { Utils } from '../../../utils/utils';
|
||||
import toaster from '../../../components/toast';
|
||||
import Loading from '../../../components/loading';
|
||||
import wikiAPI from '../../../utils/wiki-api';
|
||||
import { INSERT_POSITION } from './constants';
|
||||
|
||||
import '../css/add-new-page-dialog.css';
|
||||
|
||||
const propTypes = {
|
||||
page: PropTypes.object,
|
||||
title: PropTypes.node,
|
||||
toggle: PropTypes.func.isRequired,
|
||||
onAddNewPage: PropTypes.func,
|
||||
getCurrentPageId: PropTypes.func.isRequired,
|
||||
insertPosition: PropTypes.string,
|
||||
};
|
||||
|
||||
|
||||
@@ -71,9 +73,11 @@ class AddNewPageDialog extends React.Component {
|
||||
};
|
||||
|
||||
createPage = (pageName) => {
|
||||
wikiAPI.createWiki2Page(wikiId, pageName, this.props.getCurrentPageId()).then(res => {
|
||||
const { insertPosition, page } = this.props;
|
||||
wikiAPI.createWiki2Page(wikiId, pageName, page.id, insertPosition).then(res => {
|
||||
const { page_id, obj_name, doc_uuid, parent_dir } = res.data.file_info;
|
||||
this.props.onAddNewPage({
|
||||
id: page_id,
|
||||
page_id: page_id,
|
||||
name: pageName,
|
||||
icon: '',
|
||||
@@ -126,4 +130,8 @@ class AddNewPageDialog extends React.Component {
|
||||
|
||||
AddNewPageDialog.propTypes = propTypes;
|
||||
|
||||
AddNewPageDialog.defaultProps = {
|
||||
insertPosition: INSERT_POSITION.INNER,
|
||||
};
|
||||
|
||||
export default AddNewPageDialog;
|
||||
|
5
frontend/src/pages/wiki2/wiki-nav/constants.js
Normal file
5
frontend/src/pages/wiki2/wiki-nav/constants.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export const INSERT_POSITION = {
|
||||
ABOVE: 'above',
|
||||
BELOW: 'below',
|
||||
INNER: 'inner',
|
||||
};
|
@@ -1,3 +1,5 @@
|
||||
import { INSERT_POSITION } from './constants';
|
||||
|
||||
class NewPage {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
@@ -8,26 +10,52 @@ class NewPage {
|
||||
|
||||
export default class PageUtils {
|
||||
|
||||
static addPage(navigation, page_id, parentId) {
|
||||
if (!parentId) {
|
||||
navigation.push(new NewPage(page_id));
|
||||
static addPage({ navigation, page_id, parent_id, insert_position, sibling_page_id }) {
|
||||
if (!parent_id) {
|
||||
const newPage = new NewPage(page_id);
|
||||
if (sibling_page_id) {
|
||||
let insertIndex = navigation.findIndex(item => item.id === sibling_page_id);
|
||||
if (insertIndex > -1) {
|
||||
if (insert_position === INSERT_POSITION.ABOVE) {
|
||||
insertIndex -= 1;
|
||||
}
|
||||
navigation.splice(insertIndex + 1, 0, newPage);
|
||||
} else {
|
||||
navigation.push(newPage);
|
||||
}
|
||||
} else {
|
||||
navigation.push(newPage);
|
||||
}
|
||||
} else {
|
||||
navigation.forEach(item => {
|
||||
this._addPageRecursion(page_id, item, parentId);
|
||||
this._addPageRecursion({ page_id, item, parent_id, insert_position, sibling_page_id });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static _addPageRecursion(page_id, item, parentId) {
|
||||
static _addPageRecursion({ page_id, item, parent_id, insert_position, sibling_page_id }) {
|
||||
if (!Array.isArray(item.children)) {
|
||||
item.children = [];
|
||||
}
|
||||
if (item.id === parentId) {
|
||||
item.children.push(new NewPage(page_id));
|
||||
if (item.id === parent_id) {
|
||||
const newPage = new NewPage(page_id);
|
||||
if (sibling_page_id) {
|
||||
let insertIndex = item.children.findIndex(item => item.id === sibling_page_id);
|
||||
if (insertIndex > -1) {
|
||||
if (insert_position === INSERT_POSITION.ABOVE) {
|
||||
insertIndex -= 1;
|
||||
}
|
||||
item.children.splice(insertIndex + 1, 0, newPage);
|
||||
} else {
|
||||
item.children.push(newPage);
|
||||
}
|
||||
} else {
|
||||
item.children.push(newPage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
item.children && item.children.forEach(item => {
|
||||
this._addPageRecursion(page_id, item, parentId);
|
||||
this._addPageRecursion({ page_id, item, parent_id, insert_position, sibling_page_id });
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,7 @@ import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap
|
||||
import toaster from '../../../../components/toast';
|
||||
import { gettext } from '../../../../utils/constants';
|
||||
import { getWikPageLink } from '../../utils';
|
||||
import { INSERT_POSITION } from '../constants';
|
||||
|
||||
export default class PageDropdownMenu extends Component {
|
||||
|
||||
@@ -13,6 +14,7 @@ export default class PageDropdownMenu extends Component {
|
||||
pagesLength: PropTypes.number,
|
||||
toggle: PropTypes.func,
|
||||
toggleNameEditor: PropTypes.func,
|
||||
toggleInsertSiblingPage: PropTypes.func,
|
||||
duplicatePage: PropTypes.func,
|
||||
onDeletePage: PropTypes.func,
|
||||
isOnlyOnePage: PropTypes.bool,
|
||||
@@ -46,6 +48,14 @@ export default class PageDropdownMenu extends Component {
|
||||
this.props.onDeletePage();
|
||||
};
|
||||
|
||||
addPageAbove = () => {
|
||||
this.props.toggleInsertSiblingPage(INSERT_POSITION.ABOVE);
|
||||
};
|
||||
|
||||
addPageBelow = () => {
|
||||
this.props.toggleInsertSiblingPage(INSERT_POSITION.BELOW);
|
||||
};
|
||||
|
||||
duplicatePage = () => {
|
||||
const { page } = this.props;
|
||||
this.props.duplicatePage({ from_page_id: page.id }, () => {}, this.duplicatePageFailure);
|
||||
@@ -98,6 +108,14 @@ export default class PageDropdownMenu extends Component {
|
||||
<i className="sf3-font sf3-font-rename" />
|
||||
<span className="item-text">{gettext('Modify name')}</span>
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this.addPageAbove}>
|
||||
<i className="sf3-font sf3-font-enlarge" />
|
||||
<span className="item-text">{gettext('Add page above')}</span>
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this.addPageBelow}>
|
||||
<i className="sf3-font sf3-font-enlarge" />
|
||||
<span className="item-text">{gettext('Add page below')}</span>
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this.duplicatePage}>
|
||||
<i className="sf3-font sf3-font-copy1" />
|
||||
<span className="item-text">{gettext('Duplicate page')}</span>
|
||||
|
@@ -11,6 +11,7 @@ import Icon from '../../../../components/icon';
|
||||
import DraggedPageItem from './dragged-page-item';
|
||||
import CustomIcon from '../../custom-icon';
|
||||
import { eventBus } from '../../../../components/common/event-bus';
|
||||
import { INSERT_POSITION } from '../constants';
|
||||
|
||||
class PageItem extends Component {
|
||||
|
||||
@@ -21,6 +22,8 @@ class PageItem extends Component {
|
||||
isShowOperationDropdown: false,
|
||||
isShowDeleteDialog: false,
|
||||
isShowInsertPage: false,
|
||||
isShowAddSiblingPage: false,
|
||||
insertPosition: '',
|
||||
pageName: props.page.name || '',
|
||||
isSelected: props.getCurrentPageId() === props.page.id,
|
||||
isMouseEnter: false,
|
||||
@@ -73,6 +76,17 @@ class PageItem extends Component {
|
||||
this.setState({ isShowInsertPage: !this.state.isShowInsertPage });
|
||||
};
|
||||
|
||||
toggleInsertSiblingPage = (position) => {
|
||||
let insertPosition = null;
|
||||
if (position === INSERT_POSITION.BELOW || position === INSERT_POSITION.ABOVE) {
|
||||
insertPosition = position;
|
||||
}
|
||||
this.setState({
|
||||
insertPosition,
|
||||
isShowAddSiblingPage: !this.state.isShowAddSiblingPage,
|
||||
});
|
||||
};
|
||||
|
||||
savePageProperties = () => {
|
||||
const { name, id } = this.props.page;
|
||||
const pageName = this.state.pageName.trim();
|
||||
@@ -134,6 +148,7 @@ class PageItem extends Component {
|
||||
isOnlyOnePage={isOnlyOnePage}
|
||||
page={Object.assign({}, pages.find(item => item.id === id), page)}
|
||||
pageIndex={index}
|
||||
parentPageId={this.props.page.id}
|
||||
isEditMode={isEditMode}
|
||||
duplicatePage={this.props.duplicatePage}
|
||||
setCurrentPage={this.props.setCurrentPage}
|
||||
@@ -150,6 +165,7 @@ class PageItem extends Component {
|
||||
setClassName={this.props.setClassName}
|
||||
getClassName={this.props.getClassName}
|
||||
layerDragProps={this.props.layerDragProps}
|
||||
addSiblingPage={this.props.addSiblingPage}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -176,6 +192,11 @@ class PageItem extends Component {
|
||||
this.props.addPageInside(Object.assign({ parentPageId: this.props.page.id }, newPage));
|
||||
};
|
||||
|
||||
onAddSiblingPage = (newPage) => {
|
||||
const { page } = this.props;
|
||||
this.props.addSiblingPage(newPage, this.props.parentPageId, this.state.insertPosition, page.id, this.toggleInsertSiblingPage);
|
||||
};
|
||||
|
||||
getPageClassName = () => {
|
||||
const { isOver, canDrop, isEditMode, layerDragProps } = this.props;
|
||||
const isOverPage = isOver && canDrop;
|
||||
@@ -257,6 +278,7 @@ class PageItem extends Component {
|
||||
toggleNameEditor={this.toggleNameEditor}
|
||||
duplicatePage={this.props.duplicatePage}
|
||||
onDeletePage={this.openDeleteDialog}
|
||||
toggleInsertSiblingPage={this.toggleInsertSiblingPage}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
@@ -275,9 +297,18 @@ class PageItem extends Component {
|
||||
{this.state.isShowInsertPage &&
|
||||
<AddNewPageDialog
|
||||
toggle={this.toggleInsertPage}
|
||||
getCurrentPageId={this.props.getCurrentPageId}
|
||||
onAddNewPage={this.onAddNewPage}
|
||||
title={gettext('Add page inside')}
|
||||
page={this.props.page}
|
||||
/>
|
||||
}
|
||||
{this.state.isShowAddSiblingPage &&
|
||||
<AddNewPageDialog
|
||||
toggle={this.toggleInsertSiblingPage}
|
||||
onAddNewPage={this.onAddSiblingPage}
|
||||
title={gettext('Add page')}
|
||||
insertPosition={this.state.insertPosition}
|
||||
page={this.props.page}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
@@ -19,6 +19,7 @@ class WikiNav extends Component {
|
||||
onDeletePage: PropTypes.func,
|
||||
onMovePage: PropTypes.func,
|
||||
duplicatePage: PropTypes.func,
|
||||
addSiblingPage: PropTypes.func,
|
||||
getCurrentPageId: PropTypes.func,
|
||||
addPageInside: PropTypes.func,
|
||||
updateWikiConfig: PropTypes.func.isRequired,
|
||||
@@ -91,6 +92,7 @@ class WikiNav extends Component {
|
||||
pathStr={page.id}
|
||||
getCurrentPageId={this.props.getCurrentPageId}
|
||||
addPageInside={this.props.addPageInside}
|
||||
addSiblingPage={this.props.addSiblingPage}
|
||||
getFoldState={this.getFoldState}
|
||||
toggleExpand={this.toggleExpand}
|
||||
id_page_map={id_page_map}
|
||||
|
Reference in New Issue
Block a user