1
0
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:
Michael An
2024-11-29 22:03:59 +08:00
committed by GitHub
parent 51d5706aa6
commit d63b68e8ab
11 changed files with 185 additions and 48 deletions

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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;

View File

@@ -0,0 +1,5 @@
export const INSERT_POSITION = {
ABOVE: 'above',
BELOW: 'below',
INNER: 'inner',
};

View File

@@ -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 });
});
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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}