1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-02 07:27:04 +00:00

sysadmin reconstruct user page (#4030)

* sysadmin reconstruct user page

* [system admin] users: refactored it
This commit is contained in:
Leo
2019-10-28 10:29:20 +08:00
committed by Daniel Pan
parent 344f50cbda
commit 852fe1b8ee
35 changed files with 3254 additions and 40 deletions

View File

@@ -9,7 +9,7 @@ const propTypes = {
updateQuota: PropTypes.func.isRequired
};
class SysAdminOrgSetQuotaDialog extends React.Component {
class SetQuotaDialog extends React.Component {
constructor(props) {
super(props);
@@ -80,6 +80,6 @@ class SysAdminOrgSetQuotaDialog extends React.Component {
}
}
SysAdminOrgSetQuotaDialog.propTypes = propTypes;
SetQuotaDialog.propTypes = propTypes;
export default SysAdminOrgSetQuotaDialog;
export default SetQuotaDialog;

View File

@@ -21,6 +21,7 @@ class SysAdminAddUserDialog extends React.Component {
passwordAgain: '',
email: '',
name: '',
role: 'default',
isSubmitBtnActive: false
};
}
@@ -86,28 +87,40 @@ class SysAdminAddUserDialog extends React.Component {
});
}
updateRole = (role) => {
this.setState({
role: role
});
}
handleSubmit = () => {
const { email, password, passwordAgain, name } = this.state;
const { email, password, passwordAgain, name, role } = this.state;
if (password != passwordAgain) {
this.setState({errorMsg: gettext('Passwords do not match.')});
return;
}
const data = {
let data = {
email: email,
name: name,
password: password
};
if (this.props.showRole) {
data.role = role;
}
this.props.addUser(data);
this.toggle();
}
render() {
const { errorMsg, isPasswordVisible, password, passwordAgain, email, name,
const { dialogTitle, showRole } = this.props;
const {
errorMsg, isPasswordVisible,
email, name, role, password, passwordAgain,
isSubmitBtnActive
} = this.state;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Add Member')}</ModalHeader>
<ModalHeader toggle={this.toggle}>{dialogTitle || gettext('Add Member')}</ModalHeader>
<ModalBody>
<Form autoComplete="off">
<FormGroup>
@@ -116,8 +129,23 @@ class SysAdminAddUserDialog extends React.Component {
</FormGroup>
<FormGroup>
<Label>{gettext('Name(optional)')}</Label>
<Input autoComplete="new-password" value={name} onChange={this.inputName} />
<Input type="text" value={name} onChange={this.inputName} />
</FormGroup>
{showRole &&
<FormGroup>
<Label>
{gettext('Role')}
<span className="small text-secondary ml-1 fas fa-question-circle" title={gettext('You can also add a user as a guest, who will not be allowed to create libraries and groups.')}></span>
</Label>
<SysAdminUserRoleEditor
isTextMode={false}
isEditIconShow={false}
currentRole={role}
roleOptions={this.props.availableRoles}
onRoleChanged={this.updateRole}
/>
</FormGroup>
}
<FormGroup>
<Label>{gettext('Password')}</Label>
<InputGroup>

View File

@@ -0,0 +1,67 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
import UserSelect from '../../user-select';
import { gettext } from '../../../utils/constants';
const propTypes = {
toggle: PropTypes.func.isRequired,
addAdminInBatch: PropTypes.func.isRequired,
};
class SysAdminBatchAddAdminDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
options: null,
isSubmitBtnActive: false
};
}
toggle = () => {
this.props.toggle();
}
handleSelectChange = (options) => {
this.setState({
options: options,
isSubmitBtnActive: options.length > 0
});
}
handleSubmit = () => {
this.props.addAdminInBatch(this.state.options.map(item => item.email));
this.toggle();
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
e.preventDefault();
}
}
render() {
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Add Admin')}</ModalHeader>
<ModalBody>
<UserSelect
isMulti={true}
className="reviewer-select"
placeholder={gettext('Select users...')}
onSelectChange={this.handleSelectChange}
/>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
<Button color="primary" onClick={this.handleSubmit} disabled={!this.state.isSubmitBtnActive}>{gettext('Submit')}</Button>
</ModalFooter>
</Modal>
);
}
}
SysAdminBatchAddAdminDialog.propTypes = propTypes;
export default SysAdminBatchAddAdminDialog;

View File

@@ -17,7 +17,6 @@ class SysAdminCreateGroupDialog extends React.Component {
this.state = {
groupName: '',
ownerEmail: '',
disabled: true,
errMessage: '',
isSubmitBtnActive: false
};

View File

@@ -0,0 +1,68 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Alert, Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
import { gettext, siteRoot } from '../../../utils/constants';
const propTypes = {
toggle: PropTypes.func.isRequired,
importUserInBatch: PropTypes.func.isRequired,
};
class SysAdminImportUserDialog extends React.Component {
constructor(props) {
super(props);
this.fileInputRef = React.createRef();
this.state = {
errorMsg: ''
};
}
toggle = () => {
this.props.toggle();
}
openFileInput = () => {
this.fileInputRef.current.click();
}
uploadFile = (e) => {
// no file selected
if (!this.fileInputRef.current.files.length) {
return;
}
// check file extension
let fileName = this.fileInputRef.current.files[0].name;
if(fileName.substr(fileName.lastIndexOf('.') + 1) != 'xlsx') {
this.setState({
errorMsg: gettext('Please choose a .xlsx file.')
});
return;
}
const file = this.fileInputRef.current.files[0];
this.props.importUserInBatch(file);
}
render() {
let { errorMsg } = this.state;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Import users from a .xlsx file')}</ModalHeader>
<ModalBody>
<a href={`${siteRoot}useradmin/batchadduser/example/`}>{gettext('Download an example file')}</a>
<br/>
<button className="btn btn-outline-primary" onClick={this.openFileInput}>{gettext('Upload file')}</button>
<input className="d-none" type="file" onChange={this.uploadFile} ref={this.fileInputRef} />
{errorMsg && <Alert color="danger">{errorMsg}</Alert>}
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
</ModalFooter>
</Modal>
);
}
}
SysAdminImportUserDialog.propTypes = propTypes;
export default SysAdminImportUserDialog;

View File

@@ -0,0 +1,61 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { gettext } from '../../../utils/constants';
import UserSelect from '../../user-select';
const propTypes = {
repoName: PropTypes.string.isRequired,
toggle: PropTypes.func.isRequired,
submit: PropTypes.func.isRequired,
};
class SysAdminRepoTransferDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedOption: null,
errorMsg: [],
};
}
handleSelectChange = (option) => {
this.setState({selectedOption: option});
}
submit = () => {
let user = this.state.selectedOption;
this.props.submit(user);
}
render() {
const repoName = this.props.repoName;
const innerSpan = '<span class="op-target" title=' + repoName + '>' + repoName +'</span>';
let msg = gettext('Transfer Library {library_name}');
let message = msg.replace('{library_name}', innerSpan);
return (
<Modal isOpen={true}>
<ModalHeader toggle={this.props.toggle}>
<div dangerouslySetInnerHTML={{__html:message}} />
</ModalHeader>
<ModalBody>
<UserSelect
ref="userSelect"
isMulti={false}
className="reviewer-select"
placeholder={gettext('Search users')}
onSelectChange={this.handleSelectChange}
/>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.props.toggle}>{gettext('Cancel')}</Button>
<Button color="primary" onClick={this.submit}>{gettext('Submit')}</Button>
</ModalFooter>
</Modal>
);
}
}
SysAdminRepoTransferDialog.propTypes = propTypes;
export default SysAdminRepoTransferDialog;

View File

@@ -0,0 +1,79 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Alert, Modal, ModalHeader, ModalBody, ModalFooter, Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { gettext } from '../../../utils/constants';
import { Utils } from '../../../utils/utils';
const propTypes = {
toggle: PropTypes.func.isRequired,
onContactEmailChanged: PropTypes.func.isRequired
};
class SysAdminUserSetContactEmailDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
contactEmail: '',
isSubmitBtnActive: false,
errorMsg: '',
};
}
toggle = () => {
this.props.toggle();
}
handleContactEmailChange = (e) => {
this.setState({contactEmail: e.target.value.trim()});
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
e.preventDefault();
}
}
handleSubmit = () => {
let { contactEmail } = this.state;
if(Utils.isValidEmail(contactEmail) || contactEmail === '') {
this.props.onContactEmailChanged(contactEmail);
} else {
this.setState({
errorMsg: gettext('Contact email invalid.')
});
}
}
render() {
let { contactEmail, errorMsg } = this.state;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Set user contact email')}</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="repoName">{gettext('Name')}</Label>
<Input
id="repoName"
onKeyPress={this.handleKeyPress}
value={contactEmail}
onChange={this.handleContactEmailChange}
/>
</FormGroup>
</Form>
{errorMsg && <Alert color="danger">{errorMsg}</Alert>}
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
<Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button>
</ModalFooter>
</Modal>
);
}
}
SysAdminUserSetContactEmailDialog.propTypes = propTypes;
export default SysAdminUserSetContactEmailDialog;

View File

@@ -0,0 +1,68 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button, Form, FormGroup, Input } from 'reactstrap';
import { gettext } from '../../../utils/constants';
const propTypes = {
toggle: PropTypes.func.isRequired,
onLoginIDChanged: PropTypes.func.isRequired
};
class SysAdminUserSetLoginIDDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
loginID: '',
};
}
toggle = () => {
this.props.toggle();
}
handleLoginIDChange = (e) => {
this.setState({loginID: e.target.value.trim()});
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
e.preventDefault();
}
}
handleSubmit = () => {
let { loginID } = this.state;
this.props.onLoginIDChanged(loginID);
}
render() {
let { loginID } = this.state;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Set user Login ID')}</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Input
id="repoName"
onKeyPress={this.handleKeyPress}
value={loginID}
onChange={this.handleLoginIDChange}
/>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
<Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button>
</ModalFooter>
</Modal>
);
}
}
SysAdminUserSetLoginIDDialog.propTypes = propTypes;
export default SysAdminUserSetLoginIDDialog;

View File

@@ -0,0 +1,68 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { gettext } from '../../../utils/constants';
const propTypes = {
toggle: PropTypes.func.isRequired,
onNameChanged: PropTypes.func.isRequired
};
class SysAdminUserSetNameDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
};
}
toggle = () => {
this.props.toggle();
}
handleNameChange = (e) => {
this.setState({name: e.target.value.trim()});
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
e.preventDefault();
}
}
handleSubmit = () => {
let { name } = this.state;
this.props.onNameChanged(name);
}
render() {
let { name } = this.state;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Set user name')}</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Input
id="repoName"
onKeyPress={this.handleKeyPress}
value={name}
onChange={this.handleNameChange}
/>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
<Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button>
</ModalFooter>
</Modal>
);
}
}
SysAdminUserSetNameDialog.propTypes = propTypes;
export default SysAdminUserSetNameDialog;

View File

@@ -0,0 +1,88 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Alert, Modal, ModalHeader, ModalBody, ModalFooter, Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { gettext } from '../../../utils/constants';
import { Utils } from '../../../utils/utils';
const propTypes = {
toggle: PropTypes.func.isRequired,
onQuotaChanged: PropTypes.func.isRequired
};
class SysAdminUserSetQuotaDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
quota: '',
isSubmitBtnActive: false,
errorMsg: '',
};
}
toggle = () => {
this.props.toggle();
}
handleQuotaChange = (e) => {
if (!e.target.value.trim()) {
this.setState({isSubmitBtnActive: false});
} else {
this.setState({
isSubmitBtnActive: true,
errorMsg: ''
});
}
this.setState({quota: e.target.value});
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
e.preventDefault();
}
}
handleSubmit = () => {
let { quota } = this.state;
if(Utils.isInteger(quota) && quota >= 0) {
this.props.onQuotaChanged(quota);
} else {
this.setState({
errorMsg: gettext('Invalid quota.')
});
}
}
render() {
let { quota, isSubmitBtnActive, errorMsg } = this.state;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Set quota')}</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="repoName">{gettext('Name')}</Label>
<Input
id="repoName"
onKeyPress={this.handleKeyPress}
value={quota}
onChange={this.handleQuotaChange}
/>
</FormGroup>
</Form>
<Alert color="light">{gettext('An integer that is greater than or equal to 0.')}{gettext('Tip: 0 means default limit')}</Alert>
{errorMsg && <Alert color="danger">{errorMsg}</Alert>}
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
<Button color="primary" onClick={this.handleSubmit} disabled={!isSubmitBtnActive}>{gettext('Submit')}</Button>
</ModalFooter>
</Modal>
);
}
}
SysAdminUserSetQuotaDialog.propTypes = propTypes;
export default SysAdminUserSetQuotaDialog;

View File

@@ -0,0 +1,71 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { gettext } from '../../../utils/constants';
const propTypes = {
toggle: PropTypes.func.isRequired,
onReferenceIDChanged: PropTypes.func.isRequired
};
class SysAdminUserSetReferenceIDDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
referenceID: '',
isSubmitBtnActive: false,
errorMsg: '',
};
}
toggle = () => {
this.props.toggle();
}
handleReferenceIDChange = (e) => {
this.setState({referenceID: e.target.value.trim()});
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
e.preventDefault();
}
}
handleSubmit = () => {
let { referenceID } = this.state;
this.props.onReferenceIDChanged(referenceID);
}
render() {
let { referenceID } = this.state;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Set user Reference ID')}</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="repoName">{gettext('Name')}</Label>
<Input
id="repoName"
onKeyPress={this.handleKeyPress}
value={referenceID}
onChange={this.handleReferenceIDChange}
/>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
<Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button>
</ModalFooter>
</Modal>
);
}
}
SysAdminUserSetReferenceIDDialog.propTypes = propTypes;
export default SysAdminUserSetReferenceIDDialog;