- {user.name}
+ {user.name}
|
|
- {user.quota ? user.self_usage + ' / ' + user.quota : user.self_usage} |
- {user.ctime} / {user.last_login ? user.last_login : '--'} |
+ {`${user.self_usage} / ${user.quota || '--'}`} |
+
+ {user.ctime} /
+
+ {user.last_login ? user.last_login : '--'}
+ |
{isOperationMenuShow && (
diff --git a/frontend/src/pages/org-admin/org-users-admins.js b/frontend/src/pages/org-admin/org-users-admins.js
new file mode 100644
index 0000000000..47417e85d7
--- /dev/null
+++ b/frontend/src/pages/org-admin/org-users-admins.js
@@ -0,0 +1,114 @@
+import React, { Component, Fragment } from 'react';
+import Nav from './org-users-nav';
+import OrgAdminList from './org-admin-list';
+import MainPanelTopbar from './main-panel-topbar';
+import AddOrgAdminDialog from '../../components/dialog/org-add-admin-dialog';
+import ModalPortal from '../../components/modal-portal';
+import toaster from '../../components/toast';
+import { seafileAPI } from '../../utils/seafile-api';
+import OrgUserInfo from '../../models/org-user';
+import { gettext, orgID } from '../../utils/constants';
+import { Utils } from '../../utils/utils';
+
+class OrgUsers extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ orgAdminUsers: [],
+ isShowAddOrgAdminDialog: false
+ };
+ }
+
+ toggleAddOrgAdmin = () => {
+ this.setState({isShowAddOrgAdminDialog: !this.state.isShowAddOrgAdminDialog});
+ }
+
+ initOrgAdmin = () => {
+ seafileAPI.orgAdminListOrgUsers(orgID, true).then(res => {
+ let userList = res.data.user_list.map(item => {
+ return new OrgUserInfo(item);
+ });
+ this.setState({orgAdminUsers: userList});
+ }).catch(error => {
+ let errMessage = Utils.getErrorMsg(error);
+ toaster.danger(errMessage);
+ });
+ }
+
+ toggleOrgAdminDelete = (email) => {
+ seafileAPI.orgAdminDeleteOrgUser(orgID, email).then(res => {
+ this.setState({
+ orgAdminUsers: this.state.orgAdminUsers.filter(item => item.email != email)
+ });
+ let msg = gettext('Successfully deleted %s');
+ msg = msg.replace('%s', email);
+ toaster.success(msg);
+ }).catch(error => {
+ let errMessage = Utils.getErrorMsg(error);
+ toaster.danger(errMessage);
+ });
+ }
+
+ toggleRevokeAdmin = (email) => {
+ seafileAPI.orgAdminSetOrgAdmin(orgID, email, false).then(res => {
+ this.setState({
+ orgAdminUsers: this.state.orgAdminUsers.filter(item => item.email != email)
+ });
+ let msg = gettext('Successfully revoke the admin permission of %s');
+ msg = msg.replace('%s', res.data.name);
+ toaster.success(msg);
+ }).catch(error => {
+ let errMessage = Utils.getErrorMsg(error);
+ toaster.danger(errMessage);
+ });
+ }
+
+ onAddedOrgAdmin = (userInfo) => {
+ this.state.orgAdminUsers.unshift(userInfo);
+ this.setState({
+ orgAdminUsers: this.state.orgAdminUsers
+ });
+ let msg = gettext('Successfully set %s as admin.');
+ msg = msg.replace('%s', userInfo.email);
+ toaster.success(msg);
+ this.toggleAddOrgAdmin();
+ }
+
+ render() {
+ const topBtn = 'btn btn-secondary operation-item';
+ let topbarChildren;
+ topbarChildren = (
+
+
+ {this.state.isShowAddOrgAdminDialog &&
+
+
+
+ }
+
+ );
+
+ return (
+
+
+
+
+ );
+ }
+}
+
+export default OrgUsers;
diff --git a/frontend/src/pages/org-admin/org-users-list.js b/frontend/src/pages/org-admin/org-users-list.js
index 4e575f5af9..b63717442a 100644
--- a/frontend/src/pages/org-admin/org-users-list.js
+++ b/frontend/src/pages/org-admin/org-users-list.js
@@ -4,7 +4,6 @@ import { gettext } from '../../utils/constants';
import UserItem from './org-user-item';
const propTypes = {
- currentTab: PropTypes.string.isRequired,
initOrgUsersData: PropTypes.func.isRequired,
toggleDelete: PropTypes.func.isRequired,
orgUsers: PropTypes.array.isRequired,
@@ -17,14 +16,10 @@ class OrgUsersList extends React.Component {
constructor(props) {
super(props);
this.state = {
- isItemFreezed: false,
+ isItemFreezed: false
};
}
- componentDidMount() {
- this.props.initOrgUsersData(this.props.page);
- }
-
onFreezedItem = () => {
this.setState({isItemFreezed: true});
}
@@ -46,7 +41,20 @@ class OrgUsersList extends React.Component {
this.props.initOrgUsersData(page);
}
+ sortByQuotaUsage = (e) => {
+ e.preventDefault();
+ this.props.sortByQuotaUsage();
+ }
+
render() {
+ const { sortBy, sortOrder } = this.props;
+ let sortIcon;
+ if (sortBy == '') {
+ // initial sort icon
+ sortIcon = ;
+ } else {
+ sortIcon = ;
+ }
let { orgUsers, page, pageNext } = this.props;
return (
@@ -55,9 +63,11 @@ class OrgUsersList extends React.Component {
{gettext('Name')} |
{gettext('Status')} |
- {gettext('Space Used')} |
- {gettext('Create At / Last Login')} |
- {gettext('Operations')} |
+
+ {gettext('Space Used')} {sortIcon} / {gettext('Quota')}
+ |
+ {gettext('Created At')} / {gettext('Last Login')} |
+ {/*Operations*/} |
@@ -66,7 +76,7 @@ class OrgUsersList extends React.Component {
+
+ {this.navItems.map((item, index) => {
+ return (
+ -
+ {item.text}
+
+ );
+ })}
+
+
+ );
+ }
+}
+
+Nav.propTypes = propTypes;
+
+export default Nav;
diff --git a/frontend/src/pages/org-admin/org-users-users.js b/frontend/src/pages/org-admin/org-users-users.js
new file mode 100644
index 0000000000..4ea4d543a0
--- /dev/null
+++ b/frontend/src/pages/org-admin/org-users-users.js
@@ -0,0 +1,167 @@
+import React, { Component, Fragment } from 'react';
+import { navigate } from '@reach/router';
+import Nav from './org-users-nav';
+import OrgUsersList from './org-users-list';
+import MainPanelTopbar from './main-panel-topbar';
+import ModalPortal from '../../components/modal-portal';
+import AddOrgUserDialog from '../../components/dialog/org-add-user-dialog';
+import InviteUserDialog from '../../components/dialog/org-admin-invite-user-dialog';
+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 { Utils } from '../../utils/utils';
+
+class OrgUsers extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ orgUsers: [],
+ page: 1,
+ pageNext: false,
+ sortBy: '',
+ sortOrder: 'asc',
+ isShowAddOrgUserDialog: false,
+ isInviteUserDialogOpen: false
+ };
+ }
+
+ componentDidMount() {
+ let urlParams = (new URL(window.location)).searchParams;
+ const { page, sortBy, sortOrder } = this.state;
+ this.setState({
+ /*
+ perPage: parseInt(urlParams.get('per_page') || perPage),
+ currentPage: parseInt(urlParams.get('page') || currentPage),
+ */
+ page: parseInt(urlParams.get('page') || page),
+ sortBy: urlParams.get('order_by') || sortBy,
+ sortOrder: urlParams.get('direction') || sortOrder
+ }, () => {
+ this.initOrgUsersData(this.state.page);
+ });
+ }
+
+ sortByQuotaUsage = () => {
+ this.setState({
+ sortBy: 'quota_usage',
+ sortOrder: this.state.sortOrder == 'asc' ? 'desc' : 'asc',
+ page: 1
+ }, () => {
+ let url = new URL(location.href);
+ let searchParams = new URLSearchParams(url.search);
+ const { page, sortBy, sortOrder } = this.state;
+ searchParams.set('page', page);
+ searchParams.set('order_by', sortBy);
+ searchParams.set('direction', sortOrder);
+ url.search = searchParams.toString();
+ navigate(url.toString());
+ this.initOrgUsersData(page);
+ });
+ }
+
+ toggleAddOrgUser = () => {
+ this.setState({isShowAddOrgUserDialog: !this.state.isShowAddOrgUserDialog});
+ }
+
+ toggleInviteUserDialog = () => {
+ this.setState({isInviteUserDialogOpen: !this.state.isInviteUserDialogOpen});
+ }
+
+ initOrgUsersData = (page) => {
+ const { sortBy, sortOrder } = this.state;
+ seafileAPI.orgAdminListOrgUsers(orgID, '', page, sortBy, sortOrder).then(res => {
+ let userList = res.data.user_list.map(item => {
+ return new OrgUserInfo(item);
+ });
+ this.setState({
+ orgUsers: userList,
+ pageNext: res.data.page_next,
+ page: res.data.page,
+ });
+ }).catch(error => {
+ let errMessage = Utils.getErrorMsg(error);
+ toaster.danger(errMessage);
+ });
+ }
+
+ addOrgUser = (email, name, password) => {
+ seafileAPI.orgAdminAddOrgUser(orgID, email, name, password).then(res => {
+ let userInfo = new OrgUserInfo(res.data);
+ this.state.orgUsers.unshift(userInfo);
+ this.setState({
+ orgUsers: this.state.orgUsers
+ });
+ this.toggleAddOrgUser();
+ let msg = gettext('successfully added user %s.');
+ msg = msg.replace('%s', email);
+ toaster.success(msg);
+ }).catch(error => {
+ let errMessage = Utils.getErrorMsg(error);
+ toaster.danger(errMessage);
+ this.toggleAddOrgUser();
+ });
+ }
+
+ toggleOrgUsersDelete = (email) => {
+ seafileAPI.orgAdminDeleteOrgUser(orgID, email).then(res => {
+ let users = this.state.orgUsers.filter(item => item.email != email);
+ this.setState({orgUsers: users});
+ let msg = gettext('Successfully deleted %s');
+ msg = msg.replace('%s', email);
+ toaster.success(msg);
+ }).catch(error => {
+ let errMessage = Utils.getErrorMsg(error);
+ toaster.danger(errMessage);
+ });
+ }
+
+ render() {
+ const topBtn = 'btn btn-secondary operation-item';
+ let topbarChildren;
+ topbarChildren = (
+
+
+ {invitationLink &&
+
+ }
+ {this.state.isShowAddOrgUserDialog &&
+
+
+
+ }
+ {this.state.isInviteUserDialogOpen &&
+
+
+
+ }
+
+ );
+
+ return (
+
+
+
+
+ );
+ }
+}
+
+export default OrgUsers;
diff --git a/frontend/src/pages/org-admin/org-users.js b/frontend/src/pages/org-admin/org-users.js
deleted file mode 100644
index 728a019ac3..0000000000
--- a/frontend/src/pages/org-admin/org-users.js
+++ /dev/null
@@ -1,232 +0,0 @@
-import React, { Component, Fragment } from 'react';
-import PropTypes from 'prop-types';
-import OrgUsersList from './org-users-list';
-import OrgAdminList from './org-admin-list';
-import MainPanelTopbar from './main-panel-topbar';
-import AddOrgAdminDialog from '../../components/dialog/org-add-admin-dialog';
-import ModalPortal from '../../components/modal-portal';
-import AddOrgUserDialog from '../../components/dialog/org-add-user-dialog';
-import InviteUserDialog from '../../components/dialog/org-admin-invite-user-dialog';
-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 { Utils } from '../../utils/utils';
-
-class OrgUsers extends Component {
-
- constructor(props) {
- super(props);
- this.state = {
- orgAdminUsers: [],
- isShowAddOrgAdminDialog: false,
- orgUsers: [],
- page: 1,
- pageNext: false,
- isShowAddOrgUserDialog: false,
- isInviteUserDialogOpen: false,
- };
- }
-
- tabItemClick = (param) => {
- this.props.tabItemClick(param);
- }
-
- toggleAddOrgAdmin = () => {
- this.setState({isShowAddOrgAdminDialog: !this.state.isShowAddOrgAdminDialog});
- }
-
- toggleAddOrgUser = () => {
- this.setState({isShowAddOrgUserDialog: !this.state.isShowAddOrgUserDialog});
- }
-
- toggleInviteUserDialog = () => {
- this.setState({isInviteUserDialogOpen: !this.state.isInviteUserDialogOpen});
- }
-
- initOrgUsersData = (page) => {
- seafileAPI.orgAdminListOrgUsers(orgID, '', page).then(res => {
- let userList = res.data.user_list.map(item => {
- return new OrgUserInfo(item);
- });
- this.setState({
- orgUsers: userList,
- pageNext: res.data.page_next,
- page: res.data.page,
- });
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- }
-
- addOrgUser = (email, name, password) => {
- seafileAPI.orgAdminAddOrgUser(orgID, email, name, password).then(res => {
- let userInfo = new OrgUserInfo(res.data);
- this.state.orgUsers.unshift(userInfo);
- this.setState({
- orgUsers: this.state.orgUsers
- });
- this.toggleAddOrgUser();
- let msg = gettext('successfully added user %s.');
- msg = msg.replace('%s', email);
- toaster.success(msg);
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- this.toggleAddOrgUser();
- });
- }
-
- toggleOrgUsersDelete = (email) => {
- seafileAPI.orgAdminDeleteOrgUser(orgID, email).then(res => {
- let users = this.state.orgUsers.filter(item => item.email != email);
- this.setState({orgUsers: users});
- let msg = gettext('Successfully deleted %s');
- msg = msg.replace('%s', email);
- toaster.success(msg);
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- }
-
- initOrgAdmin = () => {
- seafileAPI.orgAdminListOrgUsers(orgID, true).then(res => {
- let userList = res.data.user_list.map(item => {
- return new OrgUserInfo(item);
- });
- this.setState({orgAdminUsers: userList});
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- }
-
- toggleOrgAdminDelete = (email) => {
- seafileAPI.orgAdminDeleteOrgUser(orgID, email).then(res => {
- this.setState({
- orgAdminUsers: this.state.orgAdminUsers.filter(item => item.email != email)
- });
- let msg = gettext('Successfully deleted %s');
- msg = msg.replace('%s', email);
- toaster.success(msg);
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- }
-
- toggleRevokeAdmin = (email) => {
- seafileAPI.orgAdminSetOrgAdmin(orgID, email, false).then(res => {
- this.setState({
- orgAdminUsers: this.state.orgAdminUsers.filter(item => item.email != email)
- });
- let msg = gettext('Successfully revoke the admin permission of %s');
- msg = msg.replace('%s', res.data.name);
- toaster.success(msg);
- }).catch(error => {
- let errMessage = Utils.getErrorMsg(error);
- toaster.danger(errMessage);
- });
- }
-
- onAddedOrgAdmin = (userInfo) => {
- this.state.orgAdminUsers.unshift(userInfo);
- this.setState({
- orgAdminUsers: this.state.orgAdminUsers
- });
- let msg = gettext('Successfully set %s as admin.');
- msg = msg.replace('%s', userInfo.email);
- toaster.success(msg);
- this.toggleAddOrgAdmin();
- }
-
- render() {
- const topBtn = 'btn btn-secondary operation-item';
- let topbarChildren;
- if (this.props.currentTab === 'admins') {
- topbarChildren = (
-
-
- {this.state.isShowAddOrgAdminDialog &&
-
-
-
- }
-
- );
- } else if (this.props.currentTab === 'users') {
- topbarChildren = (
-
-
- {invitationLink &&
-
- }
- {this.state.isShowAddOrgUserDialog &&
-
-
-
- }
- {this.state.isInviteUserDialogOpen &&
-
-
-
- }
-
- );
- }
-
- return (
-
-
-
-
-
-
- - this.tabItemClick('users')}>
- {gettext('All')}
-
- - this.tabItemClick('admins')}>
- {gettext('Admin')}
-
-
-
- {this.props.currentTab === 'users' &&
-
- }
- {this.props.currentTab === 'admins' &&
-
- }
-
-
-
- );
- }
-}
-
-const propTypes = {
- currentTab: PropTypes.string.isRequired,
- tabItemClick: PropTypes.func.isRequired,
-};
-
-OrgUsers.propTypes = propTypes;
-
-export default OrgUsers;
|