mirror of
https://github.com/haiwen/seahub.git
synced 2025-10-21 19:00:12 +00:00
12.0 feature edit wiki page (#6033)
* 01 add static media files * 02 edit wiki page * 03 remove useless icons and support edit name and icon * 04 support wiki nav * delete useless codes * optimize feature edit wiki * 05 add wiki-api and save config * 06 change some UI * delete useless codes * delete useless codes * fix edit wiki url * change js path * change icon size * fix * fix fn name and do not show tree view * fix edit url * save config to index.json * fix new file name check * hide icon and library name * remove useless svgs * remove useless svgs --------- Co-authored-by: ‘JoinTyang’ <yangtong1009@163.com> Co-authored-by: JoinTyang <41655440+JoinTyang@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
||||
import toaster from '../../../../components/toast';
|
||||
import { gettext } from '../../../../utils/constants';
|
||||
import Icon from '../../../../components/icon';
|
||||
|
||||
export default class PageDropdownMenu extends Component {
|
||||
|
||||
static propTypes = {
|
||||
view: PropTypes.object.isRequired,
|
||||
views: PropTypes.array,
|
||||
tableGridsLength: PropTypes.number,
|
||||
folderId: PropTypes.string,
|
||||
canDelete: PropTypes.bool,
|
||||
canDuplicate: PropTypes.bool,
|
||||
renderFolderMenuItems: PropTypes.func,
|
||||
toggle: PropTypes.func,
|
||||
toggleViewEditor: PropTypes.func,
|
||||
duplicatePage: PropTypes.func,
|
||||
onSetFolderId: PropTypes.func,
|
||||
onDeleteView: PropTypes.func,
|
||||
onModifyViewType: PropTypes.func,
|
||||
onMoveViewToFolder: PropTypes.func,
|
||||
isOnlyOneView: PropTypes.bool,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isShowMenu: false,
|
||||
};
|
||||
this.pageNameMap = this.calculateNameMap();
|
||||
}
|
||||
|
||||
calculateNameMap = () => {
|
||||
const { views } = this.props;
|
||||
return views.reduce((map, view) => {
|
||||
map[view.name] = true;
|
||||
return map;
|
||||
}, {});
|
||||
};
|
||||
|
||||
onDropdownToggle = (evt) => {
|
||||
if (evt.target && this.foldersDropdownToggle && this.foldersDropdownToggle.contains(evt.target)) {
|
||||
return;
|
||||
}
|
||||
evt.stopPropagation();
|
||||
this.props.toggle();
|
||||
};
|
||||
|
||||
onRenameView = (event) => {
|
||||
event.nativeEvent.stopImmediatePropagation();
|
||||
this.props.toggleViewEditor();
|
||||
};
|
||||
|
||||
onDeleteView = (event) => {
|
||||
event.nativeEvent.stopImmediatePropagation();
|
||||
this.props.onDeleteView();
|
||||
};
|
||||
|
||||
onModifyViewType = (event) => {
|
||||
event.nativeEvent.stopImmediatePropagation();
|
||||
this.props.onModifyViewType();
|
||||
};
|
||||
|
||||
onMoveViewToFolder = (targetFolderId) => {
|
||||
this.props.onMoveViewToFolder(targetFolderId);
|
||||
};
|
||||
|
||||
onRemoveFromFolder = (evt) => {
|
||||
evt.nativeEvent.stopImmediatePropagation();
|
||||
this.props.onMoveViewToFolder(null);
|
||||
};
|
||||
|
||||
onToggleFoldersMenu = () => {
|
||||
this.setState({ isShowMenu: !this.state.isShowMenu });
|
||||
};
|
||||
|
||||
duplicatePage = () => {
|
||||
const { view, folderId } = this.props;
|
||||
const { id: from_page_id, name } = view;
|
||||
let duplicateCount = 1;
|
||||
let newName = name + '(copy)';
|
||||
while (this.pageNameMap[newName]) {
|
||||
newName = `${name}(copy${duplicateCount})`;
|
||||
duplicateCount++;
|
||||
}
|
||||
const onsuccess = () => {};
|
||||
this.props.onSetFolderId(folderId);
|
||||
this.props.duplicatePage({ name: newName, from_page_id }, onsuccess, this.duplicatePageFailure);
|
||||
};
|
||||
|
||||
duplicatePageFailure = () => {
|
||||
toaster.danger(gettext('Failed_to_duplicate_page'));
|
||||
};
|
||||
|
||||
showMenu = () => {
|
||||
this.setState({ isShowMenu: true });
|
||||
};
|
||||
|
||||
hideMenu = () => {
|
||||
this.setState({ isShowMenu: false });
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
folderId, canDelete, canDuplicate, renderFolderMenuItems, tableGridsLength, isOnlyOneView,
|
||||
} = this.props;
|
||||
const folderMenuItems = renderFolderMenuItems && renderFolderMenuItems({ currentFolderId: folderId, onMoveViewToFolder: this.onMoveViewToFolder });
|
||||
return (
|
||||
<Dropdown
|
||||
isOpen={true}
|
||||
toggle={this.onDropdownToggle}
|
||||
className="view-operation-dropdown"
|
||||
>
|
||||
<DropdownToggle className="view-operation-dropdown-toggle" tag="span" data-toggle="dropdown"></DropdownToggle>
|
||||
<DropdownMenu
|
||||
className="view-operation-dropdown-menu dtable-dropdown-menu large"
|
||||
flip={false}
|
||||
modifiers={{ preventOverflow: { boundariesElement: document.body } }}
|
||||
positionFixed={true}
|
||||
style={{ zIndex: 1051 }}
|
||||
>
|
||||
<DropdownItem onClick={this.onRenameView}>
|
||||
<Icon symbol={'edit'}/>
|
||||
<span className="item-text">{gettext('Modify name')}</span>
|
||||
</DropdownItem>
|
||||
{canDuplicate &&
|
||||
<DropdownItem onClick={this.duplicatePage}>
|
||||
<Icon symbol={'copy'}/>
|
||||
<span className="item-text">{gettext('Duplicate page')}</span>
|
||||
</DropdownItem>
|
||||
}
|
||||
{(isOnlyOneView || tableGridsLength === 1 || !canDelete) ? '' : (
|
||||
<DropdownItem onClick={this.onDeleteView}>
|
||||
<Icon symbol={'delete'}/>
|
||||
<span className="item-text">{gettext('Delete page')}</span>
|
||||
</DropdownItem>
|
||||
)}
|
||||
{folderId &&
|
||||
<DropdownItem onClick={this.onRemoveFromFolder}>
|
||||
<Icon symbol={'remove-from-folder'}/>
|
||||
<span className="item-text">{gettext('Remove from folder')}</span>
|
||||
</DropdownItem>
|
||||
}
|
||||
{renderFolderMenuItems && folderMenuItems.length > 0 &&
|
||||
<DropdownItem
|
||||
className="pr-2 btn-move-to-folder"
|
||||
tag="div"
|
||||
onClick={(evt) => {
|
||||
evt.stopPropagation();
|
||||
evt.nativeEvent.stopImmediatePropagation();
|
||||
this.showMenu();
|
||||
}}
|
||||
onMouseEnter={this.showMenu}
|
||||
onMouseLeave={this.hideMenu}
|
||||
>
|
||||
<Dropdown
|
||||
className="folders-dropdown"
|
||||
direction="right"
|
||||
isOpen={this.state.isShowMenu}
|
||||
toggle={this.onToggleFoldersMenu}
|
||||
>
|
||||
<div className="folders-dropdown-toggle" ref={ref => this.foldersDropdownToggle = ref}>
|
||||
<Icon symbol={'move-to'}/>
|
||||
<span className="item-text">{gettext('Move to')}</span>
|
||||
<span className="icon-dropdown-toggle">
|
||||
<Icon className="mr-0" symbol={'right-slide'}/>
|
||||
</span>
|
||||
<DropdownToggle className="move-to-folders-toggle"></DropdownToggle>
|
||||
</div>
|
||||
{this.state.isShowMenu &&
|
||||
<DropdownMenu
|
||||
className="folders-dropdown-menu"
|
||||
flip={false}
|
||||
modifiers={{ preventOverflow: { boundariesElement: document.body } }}
|
||||
positionFixed={true}
|
||||
>
|
||||
{folderMenuItems}
|
||||
</DropdownMenu>
|
||||
}
|
||||
</Dropdown>
|
||||
</DropdownItem>
|
||||
}
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user