2024-05-15 03:57:30 +00:00
|
|
|
import React, { Component } from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import deepCopy from 'deep-copy';
|
2024-06-05 05:52:33 +00:00
|
|
|
import { UncontrolledTooltip } from 'reactstrap';
|
2024-09-12 06:32:00 +00:00
|
|
|
import { gettext, isWiki2, wikiId, wikiPermission } from '../../utils/constants';
|
2024-05-15 03:57:30 +00:00
|
|
|
import toaster from '../../components/toast';
|
|
|
|
import Loading from '../../components/loading';
|
2024-07-02 15:09:05 +00:00
|
|
|
import WikiNav from './wiki-nav/index';
|
|
|
|
import PageUtils from './wiki-nav/page-utils';
|
2024-05-15 03:57:30 +00:00
|
|
|
import Page from './models/page';
|
2024-07-15 05:46:05 +00:00
|
|
|
import { isObjectNotEmpty } from './utils';
|
2024-05-27 09:19:58 +00:00
|
|
|
import wikiAPI from '../../utils/wiki-api';
|
2024-06-05 05:52:33 +00:00
|
|
|
import { Utils } from '../../utils/utils';
|
2024-06-14 02:15:58 +00:00
|
|
|
import WikiExternalOperations from './wiki-external-operations';
|
2024-08-16 02:17:54 +00:00
|
|
|
import WikiTrashDialog from './wiki-trash-dialog';
|
2024-09-19 12:34:34 +00:00
|
|
|
import { DEFAULT_PAGE_NAME } from './constant';
|
2024-05-15 03:57:30 +00:00
|
|
|
|
2024-05-24 03:06:54 +00:00
|
|
|
import './side-panel.css';
|
2024-05-15 03:57:30 +00:00
|
|
|
|
2024-05-15 09:37:27 +00:00
|
|
|
const { repoName } = window.wiki.config;
|
|
|
|
|
2024-05-15 03:57:30 +00:00
|
|
|
const propTypes = {
|
|
|
|
closeSideBar: PropTypes.bool.isRequired,
|
|
|
|
isLoading: PropTypes.bool.isRequired,
|
|
|
|
config: PropTypes.object.isRequired,
|
2024-07-03 03:47:55 +00:00
|
|
|
updateWikiConfig: PropTypes.func.isRequired,
|
2024-08-16 02:17:54 +00:00
|
|
|
getWikiConfig: PropTypes.func.isRequired,
|
2024-05-15 03:57:30 +00:00
|
|
|
setCurrentPage: PropTypes.func.isRequired,
|
|
|
|
currentPageId: PropTypes.string,
|
2024-06-11 10:28:27 +00:00
|
|
|
onUpdatePage: PropTypes.func.isRequired,
|
2024-05-15 03:57:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class SidePanel extends Component {
|
2024-08-16 02:17:54 +00:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
isShowTrashDialog: false,
|
|
|
|
};
|
|
|
|
}
|
2024-05-15 03:57:30 +00:00
|
|
|
confirmDeletePage = (pageId) => {
|
|
|
|
const config = deepCopy(this.props.config);
|
2024-07-15 05:46:05 +00:00
|
|
|
const { pages } = config;
|
2024-05-15 03:57:30 +00:00
|
|
|
const index = PageUtils.getPageIndexById(pageId, pages);
|
|
|
|
config.pages.splice(index, 1);
|
2024-07-15 05:46:05 +00:00
|
|
|
wikiAPI.deleteWiki2Page(wikiId, pageId).then((res) => {
|
2024-07-16 08:08:53 +00:00
|
|
|
if (res.data.success === true) {
|
|
|
|
this.props.updateWikiConfig(config);
|
|
|
|
}
|
2024-07-15 05:46:05 +00:00
|
|
|
}).catch((error) => {
|
|
|
|
let errMessage = Utils.getErrorMsg(error);
|
|
|
|
toaster.danger(errMessage);
|
|
|
|
});
|
2024-05-15 03:57:30 +00:00
|
|
|
if (config.pages.length > 0) {
|
|
|
|
this.props.setCurrentPage(config.pages[0].id);
|
|
|
|
} else {
|
|
|
|
this.props.setCurrentPage('');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-07-18 03:58:42 +00:00
|
|
|
addPageInside = async ({ parentPageId, page_id, name, icon, path, docUuid, successCallback, errorCallback }) => {
|
2024-07-15 05:46:05 +00:00
|
|
|
const newPage = new Page({ id: page_id, name, icon, path, docUuid });
|
2024-06-07 01:45:05 +00:00
|
|
|
this.addPage(newPage, parentPageId, successCallback, errorCallback);
|
|
|
|
};
|
|
|
|
|
2024-07-15 05:46:05 +00:00
|
|
|
onAddNewPage = async ({ name, icon, path, page_id, docUuid, successCallback, errorCallback, jumpToNewPage = true }) => {
|
|
|
|
const newPage = new Page({ id: page_id, name, icon, path, docUuid });
|
2024-07-03 09:57:10 +00:00
|
|
|
this.addPage(newPage, '', successCallback, errorCallback, jumpToNewPage);
|
2024-05-15 03:57:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
duplicatePage = async (fromPageConfig, successCallback, errorCallback) => {
|
2024-07-03 03:47:55 +00:00
|
|
|
const { from_page_id } = fromPageConfig;
|
|
|
|
wikiAPI.duplicateWiki2Page(wikiId, from_page_id).then(res => {
|
|
|
|
const newConfig = JSON.parse(res.data.wiki_config);
|
|
|
|
this.props.updateWikiConfig(newConfig);
|
|
|
|
successCallback && successCallback();
|
|
|
|
}).catch((error) => {
|
|
|
|
let errMessage = Utils.getErrorMsg(error);
|
|
|
|
toaster.danger(errMessage);
|
|
|
|
errorCallback && errorCallback();
|
|
|
|
});
|
2024-05-15 03:57:30 +00:00
|
|
|
};
|
|
|
|
|
2024-06-13 02:20:59 +00:00
|
|
|
addPage = (page, parentId, successCallback, errorCallback, jumpToNewPage = true) => {
|
2024-05-15 03:57:30 +00:00
|
|
|
const { config } = this.props;
|
|
|
|
const navigation = config.navigation;
|
|
|
|
const pageId = page.id;
|
|
|
|
config.pages.push(page);
|
2024-06-07 01:45:05 +00:00
|
|
|
PageUtils.addPage(navigation, pageId, parentId);
|
2024-05-15 03:57:30 +00:00
|
|
|
config.navigation = navigation;
|
2024-07-15 05:46:05 +00:00
|
|
|
JSON.stringify(config);
|
|
|
|
this.props.updateWikiConfig(config);
|
|
|
|
jumpToNewPage && this.props.setCurrentPage(pageId, successCallback);
|
|
|
|
successCallback && successCallback();
|
2024-05-15 03:57:30 +00:00
|
|
|
};
|
|
|
|
|
2024-07-03 09:57:10 +00:00
|
|
|
movePage = ({ moved_page_id, target_page_id, move_position }) => {
|
2024-05-15 03:57:30 +00:00
|
|
|
let config = deepCopy(this.props.config);
|
|
|
|
let { navigation } = config;
|
2024-07-26 23:52:12 +00:00
|
|
|
config.navigation = PageUtils.movePage(navigation, moved_page_id, target_page_id, move_position);
|
2024-07-15 05:46:05 +00:00
|
|
|
JSON.stringify(config);
|
|
|
|
this.props.updateWikiConfig(config);
|
2024-05-15 03:57:30 +00:00
|
|
|
};
|
|
|
|
|
2024-08-16 02:17:54 +00:00
|
|
|
toggelTrashDialog = () => {
|
|
|
|
this.setState({ 'isShowTrashDialog': !this.state.isShowTrashDialog });
|
|
|
|
};
|
|
|
|
|
2024-07-03 09:57:10 +00:00
|
|
|
renderWikiNav = () => {
|
2024-06-11 10:28:27 +00:00
|
|
|
const { config, onUpdatePage } = this.props;
|
2024-05-15 03:57:30 +00:00
|
|
|
const { pages, navigation } = config;
|
|
|
|
return (
|
2024-05-24 03:06:54 +00:00
|
|
|
<div className="wiki2-pages-container">
|
2024-07-03 09:57:10 +00:00
|
|
|
{isObjectNotEmpty(config) &&
|
|
|
|
<WikiNav
|
|
|
|
isEditMode={isWiki2}
|
|
|
|
navigation={navigation}
|
|
|
|
pages={pages}
|
|
|
|
onDeletePage={this.confirmDeletePage}
|
|
|
|
onUpdatePage={onUpdatePage}
|
|
|
|
setCurrentPage={this.props.setCurrentPage}
|
|
|
|
onMovePage={this.movePage}
|
2024-07-15 05:46:05 +00:00
|
|
|
updateWikiConfig={this.props.updateWikiConfig}
|
2024-05-29 07:19:42 +00:00
|
|
|
onAddNewPage={this.onAddNewPage}
|
2024-07-03 09:57:10 +00:00
|
|
|
duplicatePage={this.duplicatePage}
|
|
|
|
currentPageId={this.props.currentPageId}
|
|
|
|
addPageInside={this.addPageInside}
|
2024-08-16 02:17:54 +00:00
|
|
|
toggelTrashDialog={this.toggelTrashDialog}
|
2024-05-29 07:19:42 +00:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
</div>
|
|
|
|
);
|
2024-05-15 03:57:30 +00:00
|
|
|
};
|
|
|
|
|
2024-06-13 02:20:59 +00:00
|
|
|
// default page name
|
2024-09-19 12:34:34 +00:00
|
|
|
handleAddNewPage = (jumpToNewPage = true, pageName = DEFAULT_PAGE_NAME) => {
|
2024-08-15 03:23:07 +00:00
|
|
|
if (this.isAddingPage === true) return;
|
|
|
|
this.isAddingPage = true;
|
2024-06-05 05:52:33 +00:00
|
|
|
wikiAPI.createWiki2Page(wikiId, pageName).then(res => {
|
2024-08-15 03:23:07 +00:00
|
|
|
this.isAddingPage = false;
|
2024-07-15 05:46:05 +00:00
|
|
|
const { page_id, obj_name, doc_uuid, parent_dir, page_name } = res.data.file_info;
|
2024-06-05 05:52:33 +00:00
|
|
|
this.onAddNewPage({
|
2024-07-15 05:46:05 +00:00
|
|
|
page_id: page_id,
|
2024-06-05 05:52:33 +00:00
|
|
|
name: page_name,
|
|
|
|
icon: '',
|
|
|
|
path: parent_dir === '/' ? `/${obj_name}` : `${parent_dir}/${obj_name}`,
|
|
|
|
docUuid: doc_uuid,
|
2024-08-15 03:23:07 +00:00
|
|
|
successCallback: () => {},
|
|
|
|
errorCallback: () => {},
|
2024-06-13 02:20:59 +00:00
|
|
|
jumpToNewPage,
|
2024-06-05 05:52:33 +00:00
|
|
|
});
|
|
|
|
}).catch((error) => {
|
|
|
|
let errMessage = Utils.getErrorMsg(error);
|
|
|
|
toaster.danger(errMessage);
|
2024-08-15 03:23:07 +00:00
|
|
|
this.isAddingPage = false;
|
2024-06-05 05:52:33 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2024-05-15 03:57:30 +00:00
|
|
|
render() {
|
2024-07-03 09:57:10 +00:00
|
|
|
const { isLoading } = this.props;
|
2024-05-15 03:57:30 +00:00
|
|
|
return (
|
2024-05-24 03:06:54 +00:00
|
|
|
<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>
|
2024-09-12 06:32:00 +00:00
|
|
|
{wikiPermission !== 'public' &&
|
|
|
|
<div>
|
|
|
|
<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 className='wiki-new-page-tooltip' target="wiki-add-new-page">
|
|
|
|
{gettext('New page')}
|
|
|
|
</UncontrolledTooltip>
|
|
|
|
</div>
|
|
|
|
}
|
2024-05-15 03:57:30 +00:00
|
|
|
</div>
|
2024-05-24 03:06:54 +00:00
|
|
|
<div className="wiki2-side-nav">
|
2024-08-16 02:17:54 +00:00
|
|
|
{isLoading ? <Loading/> : this.renderWikiNav()}
|
2024-05-15 03:57:30 +00:00
|
|
|
</div>
|
2024-08-16 02:17:54 +00:00
|
|
|
<WikiExternalOperations onAddWikiPage={this.handleAddNewPage.bind(false)}/>
|
|
|
|
{this.state.isShowTrashDialog && (
|
|
|
|
<WikiTrashDialog
|
|
|
|
showTrashDialog={this.state.isShowTrashDialog}
|
|
|
|
toggleTrashDialog={this.toggelTrashDialog}
|
|
|
|
getWikiConfig={this.props.getWikiConfig}
|
|
|
|
/>
|
|
|
|
)}
|
2024-09-12 06:32:00 +00:00
|
|
|
{wikiPermission !== 'public' &&
|
|
|
|
<WikiExternalOperations onAddWikiPage={this.handleAddNewPage.bind(false)} />
|
|
|
|
}
|
2024-05-15 03:57:30 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SidePanel.propTypes = propTypes;
|
|
|
|
|
|
|
|
export default SidePanel;
|