mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-19 01:44:13 +00:00
migrate old wiki to new wiki (#6987)
* migrate old wiki to new wiki * change style --------- Co-authored-by: Michael An <2331806369@qq.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import SeahubSelect from './seahub-select';
|
||||
import { NoGroupMessage } from './no-group-message';
|
||||
import { MenuSelectStyle, UserSelectStyle } from './seahub-select-style';
|
||||
import { MenuSelectStyle, UserSelectStyle, NoOptionsStyle } from './seahub-select-style';
|
||||
|
||||
export { SeahubSelect, NoGroupMessage, MenuSelectStyle, UserSelectStyle };
|
||||
export { SeahubSelect, NoGroupMessage, MenuSelectStyle, UserSelectStyle, NoOptionsStyle };
|
||||
|
@@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { gettext } from '../../../utils/constants';
|
||||
import { NoOptionsStyle } from './seahub-select-style';
|
||||
|
||||
const NoGroupMessage = (props) => {
|
||||
return (
|
||||
<div {...props.innerProps} style={{ margin: '6px 10px', textAlign: 'center', color: 'hsl(0,0%,50%)' }}>{gettext('Group not found')}</div>
|
||||
<div {...props.innerProps} style={NoOptionsStyle}>{gettext('Group not found')}</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -87,4 +87,10 @@ const UserSelectStyle = {
|
||||
},
|
||||
};
|
||||
|
||||
export { MenuSelectStyle, UserSelectStyle };
|
||||
const NoOptionsStyle = {
|
||||
margin: '6px 10px',
|
||||
textAlign: 'center',
|
||||
color: 'hsl(0, 0%, 50%)',
|
||||
};
|
||||
|
||||
export { MenuSelectStyle, UserSelectStyle, NoOptionsStyle };
|
||||
|
@@ -5,7 +5,7 @@ import { gettext, isPro } from '../../utils/constants';
|
||||
import wikiAPI from '../../utils/wiki-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import toaster from '../toast';
|
||||
import { SeahubSelect } from '../common/select';
|
||||
import { SeahubSelect, NoOptionsStyle } from '../common/select';
|
||||
|
||||
const propTypes = {
|
||||
toggleCancel: PropTypes.func.isRequired,
|
||||
@@ -97,7 +97,7 @@ class AddWikiDialog extends React.Component {
|
||||
maxMenuHeight={200}
|
||||
value={this.state.selectedOption}
|
||||
components={{ NoOptionsMessage: (
|
||||
<div style={{ margin: '6px 10px', textAlign: 'center', color: 'hsl(0,0%,50%)' }}>{gettext('No department')}</div>
|
||||
<div style={NoOptionsStyle}>{gettext('No department')}</div>
|
||||
) }}
|
||||
noOptionsMessage={() => {return gettext('No options available');}}
|
||||
/>
|
||||
|
114
frontend/src/components/dialog/convert-wiki-dialog.js
Normal file
114
frontend/src/components/dialog/convert-wiki-dialog.js
Normal file
@@ -0,0 +1,114 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Input, Label } from 'reactstrap';
|
||||
import { gettext, isPro } from '../../utils/constants';
|
||||
import wikiAPI from '../../utils/wiki-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import toaster from '../toast';
|
||||
import { SeahubSelect, NoOptionsStyle } from '../common/select';
|
||||
|
||||
const propTypes = {
|
||||
toggleCancel: PropTypes.func.isRequired,
|
||||
convertWiki: PropTypes.func.isRequired,
|
||||
wiki: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
class ConvertWikiDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
name: '',
|
||||
isSubmitBtnActive: false,
|
||||
selectedOption: null,
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!isPro) return;
|
||||
wikiAPI.listWikiDepartments().then(res => {
|
||||
const departments = res.data.sort((a, b) => {
|
||||
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
|
||||
});
|
||||
let options = [];
|
||||
for (let i = 0 ; i < departments.length; i++) {
|
||||
let obj = {};
|
||||
obj.value = departments[i].name;
|
||||
obj.id = departments[i].id;
|
||||
obj.email = departments[i].email;
|
||||
obj.label = departments[i].name;
|
||||
options.push(obj);
|
||||
}
|
||||
this.setState({ options });
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
}
|
||||
|
||||
inputNewName = (e) => {
|
||||
this.setState({
|
||||
name: e.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.handleSubmit(e);
|
||||
}
|
||||
};
|
||||
|
||||
handleSubmit = (e) => {
|
||||
const wikiName = this.state.name.trim();
|
||||
const departmentID = this.state.selectedOption ? this.state.selectedOption.id : null;
|
||||
if (!wikiName) return;
|
||||
this.props.convertWiki(this.props.wiki, wikiName, departmentID);
|
||||
this.props.toggleCancel(e);
|
||||
};
|
||||
|
||||
toggle = () => {
|
||||
this.props.toggleCancel();
|
||||
};
|
||||
|
||||
handleSelectChange = (option) => {
|
||||
this.setState({ selectedOption: option });
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal isOpen={true} autoFocus={false} toggle={this.toggle}>
|
||||
<ModalHeader toggle={this.toggle}>{gettext('Convert Wiki')}</ModalHeader>
|
||||
<ModalBody>
|
||||
<Label>{gettext('Name')}</Label>
|
||||
<Input onKeyDown={this.handleKeyDown} autoFocus={true} value={this.state.name} onChange={this.inputNewName}/>
|
||||
{isPro &&
|
||||
<>
|
||||
<Label className='mt-4'>{gettext('Wiki owner')} ({gettext('Optional')})</Label>
|
||||
<SeahubSelect
|
||||
onChange={this.handleSelectChange}
|
||||
options={this.state.options}
|
||||
hideSelectedOptions={true}
|
||||
placeholder={gettext('Select a department')}
|
||||
maxMenuHeight={200}
|
||||
value={this.state.selectedOption}
|
||||
components={{ NoOptionsMessage: (
|
||||
<div style={NoOptionsStyle}>{gettext('No department')}</div>
|
||||
) }}
|
||||
noOptionsMessage={() => {return gettext('No options available');}}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
|
||||
<Button color="primary" onClick={this.handleSubmit} disabled={!this.state.name.trim()}>{gettext('Submit')}</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ConvertWikiDialog.propTypes = propTypes;
|
||||
|
||||
export default ConvertWikiDialog;
|
@@ -3,7 +3,7 @@ import ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const propTypes = {
|
||||
children: PropTypes.object.isRequired,
|
||||
children: PropTypes.any.isRequired,
|
||||
};
|
||||
|
||||
const modalRoot = document.getElementById('modal-wrapper');
|
||||
|
@@ -5,7 +5,7 @@ import { seafileAPI } from '../utils/seafile-api';
|
||||
import { gettext, enableShowContactEmailWhenSearchUser, enableShowLoginIDWhenSearchUser } from '../utils/constants';
|
||||
import { Utils } from '../utils/utils';
|
||||
import toaster from './toast';
|
||||
import { UserSelectStyle } from './common/select';
|
||||
import { UserSelectStyle, NoOptionsStyle } from './common/select';
|
||||
|
||||
import '../css/user-select.css';
|
||||
|
||||
@@ -86,7 +86,6 @@ class UserSelect extends React.Component {
|
||||
|
||||
render() {
|
||||
const searchValue = this.state.searchValue;
|
||||
const style = { margin: '6px 10px', textAlign: 'center', color: 'hsl(0,0%,50%)' };
|
||||
return (
|
||||
<AsyncSelect
|
||||
isClearable
|
||||
@@ -94,7 +93,9 @@ class UserSelect extends React.Component {
|
||||
components={{
|
||||
NoOptionsMessage: (props) => {
|
||||
return (
|
||||
<div {...props.innerProps} style={style}>{searchValue ? gettext('User not found') : gettext('Enter characters to start searching')}</div>
|
||||
<div {...props.innerProps} style={NoOptionsStyle}>
|
||||
{searchValue ? gettext('User not found') : gettext('Enter characters to start searching')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}}
|
||||
|
@@ -14,6 +14,7 @@ const propTypes = {
|
||||
isDepartment: PropTypes.bool.isRequired,
|
||||
isShowAvatar: PropTypes.bool.isRequired,
|
||||
renameWiki: PropTypes.func.isRequired,
|
||||
convertWiki: PropTypes.func,
|
||||
toggelAddWikiDialog: PropTypes.func,
|
||||
sidePanelRate: PropTypes.number,
|
||||
isSidePanelFolded: PropTypes.bool,
|
||||
@@ -78,7 +79,10 @@ class WikiCardGroup extends Component {
|
||||
isDepartment={isDepartment}
|
||||
isShowAvatar={this.props.isShowAvatar}
|
||||
renameWiki={this.props.renameWiki}
|
||||
/> : <WikiCardItem
|
||||
convertWiki={this.props.convertWiki}
|
||||
/>
|
||||
:
|
||||
<WikiCardItem
|
||||
key={index + wiki.id + wiki.name}
|
||||
wiki={wiki}
|
||||
deleteWiki={this.props.deleteWiki}
|
||||
@@ -86,6 +90,7 @@ class WikiCardGroup extends Component {
|
||||
isDepartment={isDepartment}
|
||||
isShowAvatar={this.props.isShowAvatar}
|
||||
renameWiki={this.props.renameWiki}
|
||||
convertWiki={this.props.convertWiki}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@@ -11,6 +11,7 @@ import ShareWikiDialog from '../dialog/share-wiki-dialog';
|
||||
import PublishWikiDialog from '../dialog/publish-wiki-dialog';
|
||||
import wikiAPI from '../../utils/wiki-api';
|
||||
import toaster from '../toast';
|
||||
import ConvertWikiDialog from '../dialog/convert-wiki-dialog';
|
||||
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
@@ -20,6 +21,7 @@ const propTypes = {
|
||||
deleteWiki: PropTypes.func.isRequired,
|
||||
unshareGroupWiki: PropTypes.func.isRequired,
|
||||
renameWiki: PropTypes.func.isRequired,
|
||||
convertWiki: PropTypes.func,
|
||||
isDepartment: PropTypes.bool.isRequired,
|
||||
isShowAvatar: PropTypes.bool.isRequired,
|
||||
};
|
||||
@@ -33,6 +35,7 @@ class WikiCardItem extends Component {
|
||||
isItemMenuShow: false,
|
||||
isShowShareDialog: false,
|
||||
isShowPublishDialog: false,
|
||||
isShowConvertDialog: false,
|
||||
customUrl: '',
|
||||
};
|
||||
}
|
||||
@@ -56,6 +59,13 @@ class WikiCardItem extends Component {
|
||||
});
|
||||
};
|
||||
|
||||
onConvertToggle = (e) => {
|
||||
e && e.preventDefault();
|
||||
this.setState({
|
||||
isShowConvertDialog: !this.state.isShowConvertDialog,
|
||||
});
|
||||
};
|
||||
|
||||
onPublishToggle = (e) => {
|
||||
this.getPublishWikiLink();
|
||||
};
|
||||
@@ -176,6 +186,7 @@ class WikiCardItem extends Component {
|
||||
let showLeaveShare = false;
|
||||
let showDropdownMenu = false;
|
||||
let showPublish = false;
|
||||
let showWikiConvert = false;
|
||||
|
||||
if (isDepartment) {
|
||||
if (isAdmin) {
|
||||
@@ -184,6 +195,9 @@ class WikiCardItem extends Component {
|
||||
showShare = true;
|
||||
showRename = true;
|
||||
showPublish = true;
|
||||
if (isOldVersion) {
|
||||
showWikiConvert = true;
|
||||
}
|
||||
} else {
|
||||
showLeaveShare = true;
|
||||
}
|
||||
@@ -194,6 +208,9 @@ class WikiCardItem extends Component {
|
||||
showDelete = true;
|
||||
showRename = true;
|
||||
showPublish = true;
|
||||
if (isOldVersion) {
|
||||
showWikiConvert = true;
|
||||
}
|
||||
} else {
|
||||
showLeaveShare = true;
|
||||
}
|
||||
@@ -239,6 +256,9 @@ class WikiCardItem extends Component {
|
||||
{showDelete &&
|
||||
<DropdownItem onClick={this.onDeleteToggle}>{gettext('Delete')}</DropdownItem>
|
||||
}
|
||||
{showWikiConvert &&
|
||||
<DropdownItem onClick={this.onConvertToggle}>{gettext('Convert to new Wiki')}</DropdownItem>
|
||||
}
|
||||
{showLeaveShare &&
|
||||
<DropdownItem onClick={this.onDeleteToggle}>{gettext('Leave')}</DropdownItem>
|
||||
}
|
||||
@@ -327,6 +347,15 @@ class WikiCardItem extends Component {
|
||||
/>
|
||||
</ModalPortal>
|
||||
}
|
||||
{this.state.isShowConvertDialog &&
|
||||
<ModalPortal>
|
||||
<ConvertWikiDialog
|
||||
toggleCancel={this.onConvertToggle}
|
||||
convertWiki={this.props.convertWiki}
|
||||
wiki={this.props.wiki}
|
||||
/>
|
||||
</ModalPortal>
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ const propTypes = {
|
||||
renameWiki: PropTypes.func.isRequired,
|
||||
leaveSharedWiki: PropTypes.func.isRequired,
|
||||
unshareGroupWiki: PropTypes.func.isRequired,
|
||||
convertWiki: PropTypes.func.isRequired,
|
||||
toggelAddWikiDialog: PropTypes.func,
|
||||
sidePanelRate: PropTypes.number,
|
||||
isSidePanelFolded: PropTypes.bool,
|
||||
@@ -132,6 +133,7 @@ class WikiCardView extends Component {
|
||||
deleteWiki={this.props.deleteWiki}
|
||||
renameWiki={this.props.renameWiki}
|
||||
unshareGroupWiki={this.props.unshareGroupWiki}
|
||||
convertWiki={this.props.convertWiki}
|
||||
isSidePanelFolded={isSidePanelFolded}
|
||||
sidePanelRate={sidePanelRate}
|
||||
wikis={v1Wikis}
|
||||
|
@@ -249,6 +249,17 @@ class Wikis extends Component {
|
||||
}
|
||||
};
|
||||
|
||||
convertWiki = (wiki, wikiName, departmentID) => {
|
||||
wikiAPI.convertWiki(wiki.id, wikiName, departmentID).then((res) => {
|
||||
this.getWikis();
|
||||
}).catch((error) => {
|
||||
if (error.response) {
|
||||
let errorMsg = error.response.data.error_msg;
|
||||
toaster.danger(errorMsg);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
toggleDropdownMenu = (e) => {
|
||||
e.stopPropagation();
|
||||
this.setState({
|
||||
@@ -299,6 +310,7 @@ class Wikis extends Component {
|
||||
leaveSharedWiki={this.leaveSharedWiki}
|
||||
unshareGroupWiki={this.unshareGroupWiki}
|
||||
renameWiki={this.renameWiki}
|
||||
convertWiki={this.convertWiki}
|
||||
toggelAddWikiDialog={this.toggelAddWikiDialog}
|
||||
sidePanelRate={this.props.sidePanelRate}
|
||||
isSidePanelFolded={this.props.isSidePanelFolded}
|
||||
|
@@ -280,6 +280,16 @@ class WikiAPI {
|
||||
return this.req.delete(url);
|
||||
}
|
||||
|
||||
convertWiki(oldWikiId, wikiName, owner) {
|
||||
const url = this.server + '/api/v2.1/convert-wiki/';
|
||||
let form = new FormData();
|
||||
form.append('old_wiki_id', oldWikiId);
|
||||
form.append('name', wikiName);
|
||||
if (owner) {
|
||||
form.append('owner', owner);
|
||||
}
|
||||
return this._sendPostRequest(url, form);
|
||||
}
|
||||
}
|
||||
|
||||
let wikiAPI = new WikiAPI();
|
||||
|
Reference in New Issue
Block a user