Skip to content

Commit

Permalink
Merge pull request #6195 from haiwen/wiki-link-shortcut
Browse files Browse the repository at this point in the history
feat: fix compatitablily to wiki shortcut
  • Loading branch information
shuntian authored Jun 17, 2024
2 parents 983b42b + b216db1 commit 523bc56
Show file tree
Hide file tree
Showing 23 changed files with 305 additions and 41 deletions.
84 changes: 84 additions & 0 deletions frontend/src/components/dialog/add-wiki-page-dialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
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;
39 changes: 33 additions & 6 deletions frontend/src/pages/wiki2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import toaster from '../../components/toast';
import SidePanel from './side-panel';
import MainPanel from './main-panel';
import PageUtils from './view-structure/page-utils';
import LocalStorage from '../../utils/local-storage-utils';

import '../../css/layout.css';
import '../../css/side-panel.css';
Expand All @@ -37,6 +38,7 @@ class Wiki extends Component {
repoId: '',
seadoc_access_token: '',
assets_url: '',
wikiRepoId: null,
};
}

Expand All @@ -56,14 +58,19 @@ class Wiki extends Component {

getWikiConfig = () => {
wikiAPI.getWiki2Config(wikiId).then(res => {
const { wiki_config, repo_id } = res.data.wiki;
const { wiki_config, repo_id, id: wikiRepoId } = res.data.wiki;
const config = new WikiConfig(wiki_config || {});
this.setState({
config,
isConfigLoading: false,
repoId: repo_id,
wikiRepoId,
}, () => {
const pageId = this.getFirstPageId(config);
let pageId = this.getFirstPageId(config);
// opened by url
const urlSearchParams = new URLSearchParams(location.search);
const urlPageId = urlSearchParams.get('page_id');
if (urlPageId) pageId = urlPageId;
if (pageId) {
this.setCurrentPage(pageId);
}
Expand Down Expand Up @@ -151,6 +158,27 @@ class Wiki extends Component {
window.history.pushState({ url: fileUrl, path: filePath }, filePath, fileUrl);
};

cacheHistoryFiles = (docUuid, name, pageId) => {
let arr = [];
const { wikiRepoId } = this.state; // different from repoId
const recentFiles = LocalStorage.getItem('wiki-recent-files', []);
const newFile = { doc_uuid: docUuid, name: name, wikiRepoId, pageId };
if (recentFiles.length) {
const isExist = recentFiles.find((item) => item.doc_uuid === docUuid);
if (isExist) return;
if (!isExist) {
let newRecentFiles = recentFiles.slice(0);
if (recentFiles.length === 10) {
newRecentFiles.shift();
}
arr = [newFile, ...newRecentFiles];
}
} else {
arr.push(newFile);
}
LocalStorage.setItem('wiki-recent-files', arr);
};

setCurrentPage = (pageId, callback) => {
const { currentPageId, config } = this.state;
if (pageId === currentPageId) {
Expand All @@ -159,17 +187,16 @@ class Wiki extends Component {
}
const { pages } = config;
const currentPage = PageUtils.getPageById(pages, pageId);
const path = currentPage.path;
if (path !== this.state.path) {
this.showPage(pageId, path);
}
const { path, id, name, docUuid } = currentPage;
if (path !== this.state.path) this.showPage(pageId, path);
this.onCloseSide();
this.setState({
currentPageId: pageId,
path: path,
}, () => {
callback && callback();
});
this.cacheHistoryFiles(docUuid,name,id);
};

onUpdatePage = (pageId, newPage) => {
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/pages/wiki2/main-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Utils } from '../../utils/utils';
import Account from '../../components/common/account';
import WikiTopNav from './top-nav';
import { getCurrentPageConfig } from './utils';
import WikiExternalOperations from './wiki-external-operations';

const propTypes = {
path: PropTypes.string.isRequired,
Expand All @@ -21,6 +22,7 @@ const propTypes = {
config: PropTypes.object,
currentPageId: PropTypes.string,
onUpdatePage: PropTypes.func,
onAddWikiPage: PropTypes.func,
};

class MainPanel extends Component {
Expand Down Expand Up @@ -65,8 +67,8 @@ class MainPanel extends Component {
};

render() {
const { permission, pathExist, isDataLoading, isViewFile, config } = this.props;
const { currentPageConfig } = this.state;
const { permission, pathExist, isDataLoading, isViewFile, config, onAddWikiPage } = this.props;
const { currentPageConfig = {}, } = this.state;
const isViewingFile = pathExist && !isDataLoading && isViewFile;
const isReadOnly = !(permission === 'rw');

Expand All @@ -88,14 +90,14 @@ class MainPanel extends Component {
}
{this.props.pathExist && this.props.isDataLoading && <Loading />}
{isViewingFile && Utils.isSdocFile(this.props.path) && (
<div>
<>
<SdocWikiViewer
document={this.props.editorContent}
docUuid={this.state.docUuid}
isWikiReadOnly={isReadOnly}
topSlot={<Input className='sf-wiki-title' onCompositionEnd={this.handleRenameDocument} bsSize="lg" onChange={this.handleRenameDocument} defaultValue={currentPageConfig.name} />}
/>
</div>
</>
)}
</div>
</div>
Expand Down
19 changes: 11 additions & 8 deletions frontend/src/pages/wiki2/side-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Page from './models/page';
import wikiAPI from '../../utils/wiki-api';
import { FOLDER } from './constant';
import { Utils } from '../../utils/utils';
import WikiExternalOperations from './wiki-external-operations';

import './side-panel.css';

Expand Down Expand Up @@ -65,12 +66,12 @@ class SidePanel extends Component {
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 navigation = config.navigation;
const pageId = generateUniqueId(navigation);
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) => {
Expand All @@ -88,15 +89,15 @@ class SidePanel extends Component {
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 navigation = config.navigation;
const pageId = page.id;
config.pages.push(page);
PageUtils.addPage(navigation, pageId, parentId);
config.navigation = navigation;
const onSuccess = () => {
this.props.setCurrentPage(pageId, successCallback);
jumpToNewPage && this.props.setCurrentPage(pageId, successCallback);
successCallback();
};
this.props.saveWikiConfig(config, onSuccess, errorCallback);
Expand Down Expand Up @@ -342,18 +343,19 @@ class SidePanel extends Component {
);
};

handleAddNewPage = () => {
const pageName = 'Untitled'; // default page name
// default page name
handleAddNewPage = (jumpToNewPage = true, pageName = 'Untitled') => {
const voidFn = () => void 0;
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({
name: page_name,
icon: '',
path: parent_dir === '/' ? `/${obj_name}` : `${parent_dir}/${obj_name}`,
docUuid: doc_uuid,
successCallback: voidFn,
errorCallback: voidFn,
jumpToNewPage,
});
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
Expand All @@ -368,7 +370,7 @@ class SidePanel extends Component {
<div className={`wiki2-side-panel${this.props.closeSideBar ? '' : ' left-zero'}`}>
<div className="wiki2-side-panel-top">
<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>
</div>
<UncontrolledTooltip target="wiki-add-new-page">
Expand All @@ -378,6 +380,7 @@ class SidePanel extends Component {
<div className="wiki2-side-nav">
{isLoading ? <Loading /> : (isObjectNotEmpty(config) ? this.renderFolderView() : this.renderNoFolder())}
</div>
<WikiExternalOperations onAddWikiPage={this.handleAddNewPage.bind(false)} />
</div>
);
}
Expand Down
60 changes: 60 additions & 0 deletions frontend/src/pages/wiki2/wiki-external-operations.js
Original file line number Diff line number Diff line change
@@ -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;
Loading

0 comments on commit 523bc56

Please sign in to comment.