mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-03 07:55:36 +00:00
feat: fix compatitablily to wiki shortcut
This commit is contained in:
85
frontend/src/components/dialog/add-wiki-page-dialog.js
Normal file
85
frontend/src/components/dialog/add-wiki-page-dialog.js
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label, Alert } from 'reactstrap';
|
||||||
|
import { gettext } from '../../utils/constants';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
wikiPageName: PropTypes.string,
|
||||||
|
onAddPage: PropTypes.func,
|
||||||
|
handleClose: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddWikiPageDialog extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
const { wikiPageName = '' } = props;
|
||||||
|
this.state = {
|
||||||
|
wikiPageName,
|
||||||
|
errMessage: '',
|
||||||
|
isSubmitBtnActive: !!wikiPageName.length,
|
||||||
|
};
|
||||||
|
this.inputRef = React.createRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange = (e) => {
|
||||||
|
const isSubmitBtnActive = !!e.target.value.trim();
|
||||||
|
const wikiPageName = e.target.value;
|
||||||
|
this.setState({ isSubmitBtnActive, wikiPageName });
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSubmit = () => {
|
||||||
|
if (!this.state.isSubmitBtnActive) return;
|
||||||
|
|
||||||
|
// first param set false to prevent redirect to new page
|
||||||
|
this.props.onAddPage(false, this.state.wikiPageName);
|
||||||
|
this.props.handleClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
handleKeyDown = (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault();
|
||||||
|
this.handleSubmit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onDialogLoad = () => {
|
||||||
|
const input = this.inputRef.current;
|
||||||
|
if (!input) return;
|
||||||
|
|
||||||
|
input.focus();
|
||||||
|
const focusPosition = this.props.wikiPageName.length;
|
||||||
|
input.setSelectionRange(focusPosition,focusPosition);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { handleClose } = this.props;
|
||||||
|
return (
|
||||||
|
<Modal isOpen={true} toggle={handleClose} onOpened={this.onDialogLoad}>
|
||||||
|
<ModalHeader toggle={handleClose}>{gettext('New Wiki Page')}</ModalHeader>
|
||||||
|
<ModalBody>
|
||||||
|
<Form>
|
||||||
|
<FormGroup>
|
||||||
|
<Label for="pageName">{gettext('Name')}</Label>
|
||||||
|
<Input
|
||||||
|
id="pageName"
|
||||||
|
onKeyDown={this.handleKeyDown}
|
||||||
|
innerRef={this.inputRef}
|
||||||
|
value={this.state.wikiPageName}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
</Form>
|
||||||
|
{this.state.errMessage && <Alert color="danger" className="mt-2">{this.state.errMessage}</Alert>}
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button color="secondary" onClick={handleClose}>{gettext('Cancel')}</Button>
|
||||||
|
<Button color="primary" onClick={this.handleSubmit} disabled={!this.state.isSubmitBtnActive}>{gettext('Submit')}</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AddWikiPageDialog.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default AddWikiPageDialog;
|
@@ -38,6 +38,7 @@ class Wiki extends Component {
|
|||||||
seadoc_access_token: '',
|
seadoc_access_token: '',
|
||||||
assets_url: '',
|
assets_url: '',
|
||||||
};
|
};
|
||||||
|
this.addNewPageRef = React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillMount() {
|
UNSAFE_componentWillMount() {
|
||||||
@@ -201,6 +202,7 @@ class Wiki extends Component {
|
|||||||
setCurrentPage={this.setCurrentPage}
|
setCurrentPage={this.setCurrentPage}
|
||||||
currentPageId={this.state.currentPageId}
|
currentPageId={this.state.currentPageId}
|
||||||
onUpdatePage={this.onUpdatePage}
|
onUpdatePage={this.onUpdatePage}
|
||||||
|
addNewPageRef={this.addNewPageRef}
|
||||||
/>
|
/>
|
||||||
<MainPanel
|
<MainPanel
|
||||||
path={this.state.path}
|
path={this.state.path}
|
||||||
@@ -214,6 +216,7 @@ class Wiki extends Component {
|
|||||||
seadoc_access_token={this.state.seadoc_access_token}
|
seadoc_access_token={this.state.seadoc_access_token}
|
||||||
assets_url={this.state.assets_url}
|
assets_url={this.state.assets_url}
|
||||||
onUpdatePage={this.onUpdatePage}
|
onUpdatePage={this.onUpdatePage}
|
||||||
|
onAddWikiPage={this.addNewPageRef.current}
|
||||||
/>
|
/>
|
||||||
<MediaQuery query="(max-width: 767.8px)">
|
<MediaQuery query="(max-width: 767.8px)">
|
||||||
<Modal isOpen={!this.state.closeSideBar} toggle={this.onCloseSide} contentClassName="d-none"></Modal>
|
<Modal isOpen={!this.state.closeSideBar} toggle={this.onCloseSide} contentClassName="d-none"></Modal>
|
||||||
|
@@ -8,6 +8,7 @@ import { Utils } from '../../utils/utils';
|
|||||||
import Account from '../../components/common/account';
|
import Account from '../../components/common/account';
|
||||||
import WikiTopNav from './top-nav';
|
import WikiTopNav from './top-nav';
|
||||||
import { getCurrentPageConfig } from './utils';
|
import { getCurrentPageConfig } from './utils';
|
||||||
|
import WikiExternalOperations from './wiki-external-operations';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
@@ -21,6 +22,7 @@ const propTypes = {
|
|||||||
config: PropTypes.object,
|
config: PropTypes.object,
|
||||||
currentPageId: PropTypes.string,
|
currentPageId: PropTypes.string,
|
||||||
onUpdatePage: PropTypes.func,
|
onUpdatePage: PropTypes.func,
|
||||||
|
onAddWikiPage: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
class MainPanel extends Component {
|
class MainPanel extends Component {
|
||||||
@@ -65,8 +67,8 @@ class MainPanel extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { permission, pathExist, isDataLoading, isViewFile, config } = this.props;
|
const { permission, pathExist, isDataLoading, isViewFile, config, onAddWikiPage } = this.props;
|
||||||
const { currentPageConfig } = this.state;
|
const { currentPageConfig = {}, } = this.state;
|
||||||
const isViewingFile = pathExist && !isDataLoading && isViewFile;
|
const isViewingFile = pathExist && !isDataLoading && isViewFile;
|
||||||
const isReadOnly = !(permission === 'rw');
|
const isReadOnly = !(permission === 'rw');
|
||||||
|
|
||||||
@@ -88,14 +90,15 @@ class MainPanel extends Component {
|
|||||||
}
|
}
|
||||||
{this.props.pathExist && this.props.isDataLoading && <Loading />}
|
{this.props.pathExist && this.props.isDataLoading && <Loading />}
|
||||||
{isViewingFile && Utils.isSdocFile(this.props.path) && (
|
{isViewingFile && Utils.isSdocFile(this.props.path) && (
|
||||||
<div>
|
<>
|
||||||
<SdocWikiViewer
|
<SdocWikiViewer
|
||||||
document={this.props.editorContent}
|
document={this.props.editorContent}
|
||||||
docUuid={this.state.docUuid}
|
docUuid={this.state.docUuid}
|
||||||
isWikiReadOnly={isReadOnly}
|
isWikiReadOnly={isReadOnly}
|
||||||
topSlot={<Input className='sf-wiki-title' onCompositionEnd={this.handleRenameDocument} bsSize="lg" onChange={this.handleRenameDocument} defaultValue={currentPageConfig.name} />}
|
topSlot={<Input className='sf-wiki-title' onCompositionEnd={this.handleRenameDocument} bsSize="lg" onChange={this.handleRenameDocument} defaultValue={currentPageConfig.name} />}
|
||||||
/>
|
/>
|
||||||
</div>
|
<WikiExternalOperations onAddWikiPage={onAddWikiPage} />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -29,6 +29,7 @@ const propTypes = {
|
|||||||
setCurrentPage: PropTypes.func.isRequired,
|
setCurrentPage: PropTypes.func.isRequired,
|
||||||
currentPageId: PropTypes.string,
|
currentPageId: PropTypes.string,
|
||||||
onUpdatePage: PropTypes.func.isRequired,
|
onUpdatePage: PropTypes.func.isRequired,
|
||||||
|
addNewPageRef: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
class SidePanel extends Component {
|
class SidePanel extends Component {
|
||||||
@@ -39,6 +40,7 @@ class SidePanel extends Component {
|
|||||||
isShowNewFolderDialog: false,
|
isShowNewFolderDialog: false,
|
||||||
isShowAddNewPageDialog: false,
|
isShowAddNewPageDialog: false,
|
||||||
};
|
};
|
||||||
|
this.props.addNewPageRef.current = this.handleAddNewPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmDeletePage = (pageId) => {
|
confirmDeletePage = (pageId) => {
|
||||||
@@ -65,12 +67,12 @@ class SidePanel extends Component {
|
|||||||
this.addPage(newPage, parentPageId, successCallback, errorCallback);
|
this.addPage(newPage, parentPageId, successCallback, errorCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
onAddNewPage = async ({ name, icon, path, docUuid, successCallback, errorCallback }) => {
|
onAddNewPage = async ({ name, icon, path, docUuid, successCallback, errorCallback, jumpToNewPage = true }) => {
|
||||||
const { config } = this.props;
|
const { config } = this.props;
|
||||||
const navigation = config.navigation;
|
const navigation = config.navigation;
|
||||||
const pageId = generateUniqueId(navigation);
|
const pageId = generateUniqueId(navigation);
|
||||||
const newPage = new Page({ id: pageId, name, icon, path, docUuid });
|
const newPage = new Page({ id: pageId, name, icon, path, docUuid });
|
||||||
this.addPage(newPage, this.current_folder_id, successCallback, errorCallback);
|
this.addPage(newPage, this.current_folder_id, successCallback, errorCallback, jumpToNewPage);
|
||||||
};
|
};
|
||||||
|
|
||||||
duplicatePage = async (fromPageConfig, successCallback, errorCallback) => {
|
duplicatePage = async (fromPageConfig, successCallback, errorCallback) => {
|
||||||
@@ -88,7 +90,7 @@ class SidePanel extends Component {
|
|||||||
this.addPage(newPage, this.current_folder_id, successCallback, errorCallback);
|
this.addPage(newPage, this.current_folder_id, successCallback, errorCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
addPage = (page, parentId, successCallback, errorCallback) => {
|
addPage = (page, parentId, successCallback, errorCallback, jumpToNewPage = true) => {
|
||||||
const { config } = this.props;
|
const { config } = this.props;
|
||||||
const navigation = config.navigation;
|
const navigation = config.navigation;
|
||||||
const pageId = page.id;
|
const pageId = page.id;
|
||||||
@@ -96,7 +98,7 @@ class SidePanel extends Component {
|
|||||||
PageUtils.addPage(navigation, pageId, parentId);
|
PageUtils.addPage(navigation, pageId, parentId);
|
||||||
config.navigation = navigation;
|
config.navigation = navigation;
|
||||||
const onSuccess = () => {
|
const onSuccess = () => {
|
||||||
this.props.setCurrentPage(pageId, successCallback);
|
jumpToNewPage && this.props.setCurrentPage(pageId, successCallback);
|
||||||
successCallback();
|
successCallback();
|
||||||
};
|
};
|
||||||
this.props.saveWikiConfig(config, onSuccess, errorCallback);
|
this.props.saveWikiConfig(config, onSuccess, errorCallback);
|
||||||
@@ -342,11 +344,11 @@ class SidePanel extends Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleAddNewPage = () => {
|
// default page name
|
||||||
const pageName = 'Untitled'; // default page name
|
handleAddNewPage = (jumpToNewPage = true, pageName = 'Untitled') => {
|
||||||
const voidFn = () => void 0;
|
const voidFn = () => void 0;
|
||||||
wikiAPI.createWiki2Page(wikiId, pageName).then(res => {
|
wikiAPI.createWiki2Page(wikiId, pageName).then(res => {
|
||||||
const { obj_name, parent_dir, doc_uuid,page_name } = res.data;
|
const { obj_name, parent_dir, doc_uuid, page_name } = res.data;
|
||||||
this.onAddNewPage({
|
this.onAddNewPage({
|
||||||
name: page_name,
|
name: page_name,
|
||||||
icon: '',
|
icon: '',
|
||||||
@@ -354,6 +356,7 @@ class SidePanel extends Component {
|
|||||||
docUuid: doc_uuid,
|
docUuid: doc_uuid,
|
||||||
successCallback: voidFn,
|
successCallback: voidFn,
|
||||||
errorCallback: voidFn,
|
errorCallback: voidFn,
|
||||||
|
jumpToNewPage,
|
||||||
});
|
});
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
@@ -368,7 +371,7 @@ class SidePanel extends Component {
|
|||||||
<div className={`wiki2-side-panel${this.props.closeSideBar ? '' : ' left-zero'}`}>
|
<div className={`wiki2-side-panel${this.props.closeSideBar ? '' : ' left-zero'}`}>
|
||||||
<div className="wiki2-side-panel-top">
|
<div className="wiki2-side-panel-top">
|
||||||
<h4 className="text-truncate ml-0 mb-0" title={repoName}>{repoName}</h4>
|
<h4 className="text-truncate ml-0 mb-0" title={repoName}>{repoName}</h4>
|
||||||
<div id='wiki-add-new-page' className='add-new-page' onClick={this.handleAddNewPage}>
|
<div id='wiki-add-new-page' className='add-new-page' onClick={this.handleAddNewPage.bind(true)}>
|
||||||
<i className='sf3-font sf3-font-new-page'></i>
|
<i className='sf3-font sf3-font-new-page'></i>
|
||||||
</div>
|
</div>
|
||||||
<UncontrolledTooltip target="wiki-add-new-page">
|
<UncontrolledTooltip target="wiki-add-new-page">
|
||||||
|
60
frontend/src/pages/wiki2/wiki-external-operations.js
Normal file
60
frontend/src/pages/wiki2/wiki-external-operations.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { EventBus, EXTERNAL_EVENT } from '@seafile/sdoc-editor';
|
||||||
|
import AddWikiPageDialog from '../../components/dialog/add-wiki-page-dialog';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
onAddWikiPage: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
class WikiExternalOperations extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isShowAddWikiPageDialog: false,
|
||||||
|
wikiPageName: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const eventBus = EventBus.getInstance();
|
||||||
|
this.unsubscribeCreateWikiPage = eventBus.subscribe(EXTERNAL_EVENT.CREATE_WIKI_PAGE, this.onAddWikiPageDialogDisplayed);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.unsubscribeCreateWikiPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddWikiPageDialogDisplayed = ({ newFileName: wikiPageName = '' }) => {
|
||||||
|
this.setState({
|
||||||
|
wikiPageName,
|
||||||
|
isShowAddWikiPageDialog: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
changeAddWikiPageDialogDisplayed = () => {
|
||||||
|
this.setState({ isShowAddWikiPageDialog: !this.state.isShowAddWikiPageDialog });
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { onAddWikiPage } = this.props;
|
||||||
|
const { isShowAddWikiPageDialog, wikiPageName } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isShowAddWikiPageDialog && (
|
||||||
|
<AddWikiPageDialog
|
||||||
|
wikiPageName={wikiPageName}
|
||||||
|
onAddPage={onAddWikiPage}
|
||||||
|
handleClose={this.changeAddWikiPageDialogDisplayed}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WikiExternalOperations.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default WikiExternalOperations;
|
@@ -445,6 +445,7 @@
|
|||||||
"Recent_visited": "Recent visited",
|
"Recent_visited": "Recent visited",
|
||||||
"The_document_does_not_exist": "The document does not exist",
|
"The_document_does_not_exist": "The document does not exist",
|
||||||
"Create_a_new_sdoc_file": "Create a new sdoc file",
|
"Create_a_new_sdoc_file": "Create a new sdoc file",
|
||||||
|
"Create_a_new_wiki_page": "Create a new wiki page",
|
||||||
"Create": "Create",
|
"Create": "Create",
|
||||||
"Top_align": "Top",
|
"Top_align": "Top",
|
||||||
"Center_align": "Middle",
|
"Center_align": "Middle",
|
||||||
|
@@ -445,6 +445,7 @@
|
|||||||
"Recent_visited": "最近浏览",
|
"Recent_visited": "最近浏览",
|
||||||
"The_document_does_not_exist": "不存在该文档",
|
"The_document_does_not_exist": "不存在该文档",
|
||||||
"Create_a_new_sdoc_file": "新建 sdoc 文件",
|
"Create_a_new_sdoc_file": "新建 sdoc 文件",
|
||||||
|
"Create_a_new_wiki_page": "创建一个 Wiki 页面",
|
||||||
"Create": "创建",
|
"Create": "创建",
|
||||||
"Top_align": "顶端对齐",
|
"Top_align": "顶端对齐",
|
||||||
"Center_align": "居中对齐",
|
"Center_align": "居中对齐",
|
||||||
@@ -461,4 +462,4 @@
|
|||||||
"Enter_text_or_press_forward_slash_to_insert_element": "输入文本或按下 '/' 插入元素",
|
"Enter_text_or_press_forward_slash_to_insert_element": "输入文本或按下 '/' 插入元素",
|
||||||
"Vertical_align": "垂直对齐",
|
"Vertical_align": "垂直对齐",
|
||||||
"Horizontal_align": "水平对齐"
|
"Horizontal_align": "水平对齐"
|
||||||
}
|
}
|
Reference in New Issue
Block a user