diff --git a/frontend/src/pages/org-admin/index.js b/frontend/src/pages/org-admin/index.js index 96f7ccd996..83711b75a6 100644 --- a/frontend/src/pages/org-admin/index.js +++ b/frontend/src/pages/org-admin/index.js @@ -4,6 +4,7 @@ import { Router } from '@reach/router'; import { siteRoot } from '../../utils/constants'; import SidePanel from './side-panel'; import OrgUsers from './org-users-users'; +import OrgUsersSearchUsers from './org-users-search-users'; import OrgAdmins from './org-users-admins'; import OrgUserProfile from './org-user-profile'; import OrgUserRepos from './org-user-repos'; @@ -68,6 +69,7 @@ class Org extends React.Component { + diff --git a/frontend/src/pages/org-admin/main-panel-topbar.js b/frontend/src/pages/org-admin/main-panel-topbar.js index 2c0acc636f..792d9e1d05 100644 --- a/frontend/src/pages/org-admin/main-panel-topbar.js +++ b/frontend/src/pages/org-admin/main-panel-topbar.js @@ -18,6 +18,7 @@ class MainPanelTopbar extends Component {
+ {this.props.search && this.props.search}
diff --git a/frontend/src/pages/org-admin/org-users-search-users.js b/frontend/src/pages/org-admin/org-users-search-users.js new file mode 100644 index 0000000000..03c860345d --- /dev/null +++ b/frontend/src/pages/org-admin/org-users-search-users.js @@ -0,0 +1,186 @@ +import React, { Component, Fragment } from 'react'; +import { Button, Form, FormGroup, Input, Col } from 'reactstrap'; +import { Utils } from '../../utils/utils'; +import { seafileAPI } from '../../utils/seafile-api'; +import { gettext, orgID } from '../../utils/constants'; +import toaster from '../../components/toast'; +import UserItem from './org-user-item'; +import OrgUserInfo from '../../models/org-user'; + +class OrgUsersSearchUsersResult extends React.Component { + + constructor(props) { + super(props); + this.state = { + isItemFreezed: false + }; + } + + onFreezedItem = () => { + this.setState({isItemFreezed: true}); + } + + onUnfreezedItem = () => { + this.setState({isItemFreezed: false}); + } + + render() { + let { orgUsers } = this.props; + return ( +
+ + + + + + + + + + + + {orgUsers.map((item, index) => { + return ( + + );})} + +
{gettext('Name')}{gettext('Status')} + {gettext('Space Used')} / {gettext('Quota')} + {gettext('Created At')} / {gettext('Last Login')}{/*Operations*/}
+
+ ); + } +} + +class OrgUsersSearchUsers extends Component { + + constructor(props) { + super(props); + this.state = { + query: '', + orgUsers: [], + org_id: '', + isSubmitBtnActive: false, + loading: true, + errorMsg: '', + }; + } + + componentDidMount () { + let params = (new URL(document.location)).searchParams; + this.setState({ + query: params.get('query') || '', + }, () => {this.getItems();}); + } + + getItems = () => { + seafileAPI.orgAdminSearchUser(1, this.state.query.trim()).then(res => { + let userList = res.data.user_list.map(item => { + return new OrgUserInfo(item); + }); + this.setState({ + orgUsers: userList, + loading: false, + }); + }).catch((error) => { + this.setState({ + loading: false, + errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 + }); + }); + } + + deleteUser = (email) => { + seafileAPI.orgAdminDeleteOrgUser(orgID, email).then(res => { + let newUserList = this.state.orgUsers.filter(item => { + return item.email != email; + }); + this.setState({orgUsers: newUserList}); + toaster.success(gettext('Successfully deleted 1 item.')); + }).catch((error) => { + let errMessage = Utils.getErrorMsg(error); + toaster.danger(errMessage); + }); + } + + updateUser = (email, key, value) => { + seafileAPI.sysAdminUpdateUser(email, key, value).then(res => { + let newUserList = this.state.orgUsers.map(item => { + if (item.email == email) { + item[key]= res.data[key]; + } + return item; + }); + this.setState({orgUsers: newUserList}); + const msg = (key == 'is_active' && value) ? + res.data.update_status_tip : gettext('Edit succeeded'); + toaster.success(msg); + }).catch((error) => { + let errMessage = Utils.getErrorMsg(error); + toaster.danger(errMessage); + }); + } + + handleInputChange = (e) => { + this.setState({ + query: e.target.value + }, this.checkSubmitBtnActive); + } + + checkSubmitBtnActive = () => { + const { query } = this.state; + this.setState({ + isSubmitBtnActive: query.trim() + }); + } + + render() { + const { query, isSubmitBtnActive } = this.state; + + return ( + +
+
+
+

{gettext('Users')}

+
+
+
+

{gettext('Search Users')}

+
+ + + + + + + + + + +
+
+
+

{gettext('Result')}

+ +
+
+
+
+
+ ); + } +} + +export default OrgUsersSearchUsers; diff --git a/frontend/src/pages/org-admin/org-users-users.js b/frontend/src/pages/org-admin/org-users-users.js index d25bf229dc..26a2a44619 100644 --- a/frontend/src/pages/org-admin/org-users-users.js +++ b/frontend/src/pages/org-admin/org-users-users.js @@ -9,9 +9,58 @@ import InviteUserDialog from '../../components/dialog/org-admin-invite-user-dial import toaster from '../../components/toast'; import { seafileAPI } from '../../utils/seafile-api'; import OrgUserInfo from '../../models/org-user'; -import { gettext, invitationLink, orgID } from '../../utils/constants'; +import { gettext, invitationLink, orgID, siteRoot } from '../../utils/constants'; import { Utils } from '../../utils/utils'; +class Search extends React.Component { + + constructor(props) { + super(props); + this.state = { + value: '' + }; + } + + handleInputChange = (e) => { + this.setState({ + value: e.target.value + }); + } + + handleKeyPress = (e) => { + if (e.key == 'Enter') { + e.preventDefault(); + this.handleSubmit(); + } + } + + handleSubmit = () => { + const value = this.state.value.trim(); + if (!value) { + return false; + } + this.props.submit(value); + } + + render() { + return ( +
+ + +
+ ); + } +} + class OrgUsers extends Component { constructor(props) { @@ -117,6 +166,17 @@ class OrgUsers extends Component { }); } + searchItems = (keyword) => { + navigate(`${siteRoot}org/useradmin/search-users/?query=${encodeURIComponent(keyword)}`); + } + + getSearch = () => { + return ; + } + render() { const topBtn = 'btn btn-secondary operation-item'; let topbarChildren; @@ -143,7 +203,7 @@ class OrgUsers extends Component { return ( - +