diff --git a/frontend/src/components/single-selector.js b/frontend/src/components/single-selector.js index 2eab4daa13..927d6aaafa 100644 --- a/frontend/src/components/single-selector.js +++ b/frontend/src/components/single-selector.js @@ -74,7 +74,7 @@ class Selector extends Component { {customSelectorToggle ? customSelectorToggle : ( {currentSelectedOption.text} - {isDropdownToggleShown && } + {isDropdownToggleShown && } )} diff --git a/frontend/src/pages/sys-admin/users/users-content.js b/frontend/src/pages/sys-admin/users/users-content.js index 9c3eb604e5..b360836492 100644 --- a/frontend/src/pages/sys-admin/users/users-content.js +++ b/frontend/src/pages/sys-admin/users/users-content.js @@ -15,7 +15,6 @@ import OpMenu from '../../../components/dialog/op-menu'; import SysAdminUserSetQuotaDialog from '../../../components/dialog/sysadmin-dialog/set-quota'; import CommonOperationConfirmationDialog from '../../../components/dialog/common-operation-confirmation-dialog'; import UserLink from '../user-link'; -import UsersFilterBar from './users-filter-bar'; const { availableRoles, availableAdminRoles, institutions } = window.sysadmin.pageOptions; dayjs.extend(relativeTime); @@ -42,11 +41,11 @@ class Content extends Component { }; getPreviousPage = () => { - this.props.getListByPage(this.props.currentPage - 1, this.props.is_active, this.props.role); + this.props.getListByPage(this.props.currentPage - 1); }; getNextPage = () => { - this.props.getListByPage(this.props.currentPage + 1, this.props.is_active, this.props.role); + this.props.getListByPage(this.props.currentPage + 1); }; sortByQuotaUsage = (e) => { @@ -164,14 +163,6 @@ class Content extends Component { return (
- {this.props.currentItem === 'database' && - - } {items.length ? table : }
); @@ -201,12 +192,7 @@ Content.propTypes = { onUserSelected: PropTypes.func, curPerPage: PropTypes.number, hasNextPage: PropTypes.bool, - sortOrder: PropTypes.string, - is_active: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - role: PropTypes.string, - currentItem: PropTypes.string, - onStatusChange: PropTypes.func, - onRoleChange: PropTypes.func + sortOrder: PropTypes.string }; class Item extends Component { diff --git a/frontend/src/pages/sys-admin/users/users-filter-bar.css b/frontend/src/pages/sys-admin/users/users-filter-bar.css index c11bd48102..78a2746cb1 100644 --- a/frontend/src/pages/sys-admin/users/users-filter-bar.css +++ b/frontend/src/pages/sys-admin/users/users-filter-bar.css @@ -1,29 +1,4 @@ -.users-filter-bar .users-filter-bar-dropdown-toggle { - height: 30px; - line-height: 30px; - padding-left: 8px; +.users-filter-bar .filter-item, +.users-filter-bar .cur-option { font-size: 14px; - border-radius: 5px; -} - -.users-filter-bar .users-filter-bar-dropdown-toggle .sf3-font-down { - color: #999; - margin-left: auto; - display: inline-flex; - justify-content: center; - align-items: center; - font-size: 12px; - width: 24px; - height: 24px; -} - -.users-filter-bar .users-filter-bar-dropdown-toggle:hover { - background-color: #f5f5f5; - cursor: pointer; -} - -.users-filter-bar .dropdown-menu .dropdown-item { - padding: 0.25rem 0.5rem; - display: flex; - justify-content: space-between; } diff --git a/frontend/src/pages/sys-admin/users/users-filter-bar.js b/frontend/src/pages/sys-admin/users/users-filter-bar.js index 5787864f7c..d1689b8970 100644 --- a/frontend/src/pages/sys-admin/users/users-filter-bar.js +++ b/frontend/src/pages/sys-admin/users/users-filter-bar.js @@ -1,117 +1,83 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { Dropdown, DropdownToggle, DropdownItem, DropdownMenu } from 'reactstrap'; import { gettext } from '../../../utils/constants'; +import Selector from '../../../components/single-selector'; import './users-filter-bar.css'; const { availableRoles } = window.sysadmin.pageOptions; class UsersFilterBar extends Component { - constructor(props) { - super(props); - this.state = { - isStatusOpen: false, - isRoleOpen: false, - }; - } - - translateStatus = (status) => { - switch (status) { - case '0': - return gettext('Inactive'); - case '1': - return gettext('Active'); - default: - return gettext('All'); - } - }; - translateRole = (role) => { switch (role) { + case '': + return gettext('All'); case 'default': return gettext('Default'); case 'guest': return gettext('Guest'); default: - return gettext('All'); + return role; } }; - toggleStatusDropdown = () => { - this.setState({ isStatusOpen: !this.state.isStatusOpen }); + selectStatusOption = (option) => { + this.props.onStatusChange(option.value); }; - toggleRoleDropdown = () => { - this.setState({ isRoleOpen: !this.state.isRoleOpen }); - }; - - renderCheck = () => { - return ; + selectRoleOption = (option) => { + this.props.onRoleChange(option.value); }; render() { - const { onStatusChange, onRoleChange } = this.props; + const { isActive, role } = this.props; + + this.statusOptions = [ + { value: '', text: gettext('All') }, + { value: '1', text: gettext('Active') }, + { value: '0', text: gettext('Inactive') } + ].map(item => { + item.isSelected = isActive == item.value; + return item; + }); + const currentSelectedStatusOption = this.statusOptions.filter(item => item.isSelected)[0]; + + this.roleOptions = [''].concat(availableRoles).map(item => { + return { + value: item, + text: this.translateRole(item), + isSelected: item == role + }; + }); + const currentSelectedRoleOption = this.roleOptions.filter(item => item.isSelected)[0] || { // `|| {...}`: to be compatible with old data(roles not in the present `availableRoles` + value: role, + text: this.translateRole(role), + isSelected: true + }; + return ( -
- - - {gettext('Status')}{': '}{this.translateStatus(this.props.isActive)} - - - - { onStatusChange(''); }}> - {gettext('All')}{this.props.isActive === '' && this.renderCheck()} - - { onStatusChange('1'); }}> - {gettext('Active')}{this.props.isActive === '1' && this.renderCheck()} - - { onStatusChange('0'); }}> - {gettext('Inactive')}{this.props.isActive === '0' && this.renderCheck()} - - - - - - {gettext('Role')}{': '}{this.translateRole(this.props.role)} - - - - { onRoleChange(''); }}> - {gettext('All')} - {this.props.role === '' && this.renderCheck()} - - {availableRoles.map((item, index) => { - return ( - { onRoleChange(item); }}> - {this.translateRole(item)} - {this.props.role === item && this.renderCheck()} - - ); - })} - - +
+ {`${gettext('Status')}:`} + + + {`${gettext('Role')}:`} +
); } } UsersFilterBar.propTypes = { - loading: PropTypes.bool, - curPerPage: PropTypes.number, - sortBy: PropTypes.string, - currentPage: PropTypes.number, - sortOrder: PropTypes.string, onStatusChange: PropTypes.func, onRoleChange: PropTypes.func, role: PropTypes.string, diff --git a/frontend/src/pages/sys-admin/users/users.js b/frontend/src/pages/sys-admin/users/users.js index 0560ef5ac9..b63bef46e1 100644 --- a/frontend/src/pages/sys-admin/users/users.js +++ b/frontend/src/pages/sys-admin/users/users.js @@ -16,6 +16,7 @@ import SysAdminAdminUser from '../../../models/sysadmin-admin-user'; import MainPanelTopbar from '../main-panel-topbar'; import Search from '../search'; import UsersNav from './users-nav'; +import UsersFilterBar from './users-filter-bar'; import Content from './users-content'; const { availableRoles } = window.sysadmin.pageOptions; @@ -44,8 +45,8 @@ class Users extends Component { isBatchSetQuotaDialogOpen: false, isBatchDeleteUserDialogOpen: false, isBatchAddAdminDialogOpen: false, - is_active: null, - role: null, + is_active: '', + role: '' }; } @@ -59,15 +60,17 @@ class Users extends Component { sortBy = '', sortOrder = 'asc', is_active, - role, + role } = this.state; this.setState({ perPage: parseInt(urlParams.get('per_page') || perPage), currentPage: parseInt(urlParams.get('page') || currentPage), sortBy: urlParams.get('order_by') || sortBy, sortOrder: urlParams.get('direction') || sortOrder, + is_active: urlParams.get('is_active') || is_active, + role: urlParams.get('role') || role }, () => { - this.getUsersListByPage(this.state.currentPage, is_active, role); + this.getUsersListByPage(this.state.currentPage); }); } } @@ -164,8 +167,8 @@ class Users extends Component { }); }; - getUsersListByPage = (page, is_active, role) => { - const { perPage, sortBy, sortOrder } = this.state; + getUsersListByPage = (page) => { + const { perPage, sortBy, sortOrder, is_active, role } = this.state; const { isLDAPImported } = this.props; systemAdminAPI.sysAdminListUsers(page, perPage, isLDAPImported, sortBy, sortOrder, is_active, role).then(res => { let users = res.data.data.map(user => {return new SysAdminUser(user);}); @@ -183,11 +186,12 @@ class Users extends Component { }); }; - updateURL = (page, perPage) => { + updateURLSearchParams = (obj) => { let url = new URL(location.href); let searchParams = new URLSearchParams(url.search); - searchParams.set('page', page); - searchParams.set('per_page', perPage); + for (const key in obj) { + searchParams.set(key, obj[key]); + } url.search = searchParams.toString(); navigate(url.toString()); }; @@ -198,21 +202,28 @@ class Users extends Component { is_active: is_active, currentPage: 1 }, () => { - const { currentPage, perPage, is_active, role } = this.state; - this.updateURL(currentPage, perPage); - this.getUsersListByPage(currentPage, is_active, role); + const { currentPage, perPage } = this.state; + this.updateURLSearchParams({ + 'page': currentPage, + 'per_page': perPage, + 'is_active': is_active + }); + this.getUsersListByPage(currentPage); }); }; - // role: 'default', 'guest', '' onRoleChange = (role) => { this.setState({ role: role, currentPage: 1 }, () => { - const { currentPage, perPage, is_active, role } = this.state; - this.updateURL(currentPage, perPage); - this.getUsersListByPage(currentPage, is_active, role); + const { currentPage, perPage } = this.state; + this.updateURLSearchParams({ + 'page': currentPage, + 'per_page': perPage, + 'role': role + }); + this.getUsersListByPage(currentPage); }); }; @@ -222,15 +233,14 @@ class Users extends Component { sortOrder: this.state.sortOrder == 'asc' ? 'desc' : 'asc', currentPage: 1 }, () => { - let url = new URL(location.href); - let searchParams = new URLSearchParams(url.search); - const { currentPage, sortBy, sortOrder, is_active, role } = this.state; - searchParams.set('page', currentPage); - searchParams.set('order_by', sortBy); - searchParams.set('direction', sortOrder); - url.search = searchParams.toString(); - navigate(url.toString()); - this.getUsersListByPage(currentPage, is_active, role); + const { currentPage, perPage, sortBy, sortOrder } = this.state; + this.updateURLSearchParams({ + 'page': currentPage, + 'per_page': perPage, + 'order_by': sortBy, + 'direction': sortOrder + }); + this.getUsersListByPage(currentPage); }); }; @@ -346,7 +356,7 @@ class Users extends Component { this.setState({ perPage: perPage }, () => { - this.getUsersListByPage(1, this.state.is_active, this.state.role); + this.getUsersListByPage(1); }); }; @@ -471,6 +481,8 @@ class Users extends Component { render() { const { isAdmin, isLDAPImported } = this.props; const { + is_active, + role, hasUserSelected, isImportUserDialogOpen, isAddUserDialogOpen, @@ -478,6 +490,7 @@ class Users extends Component { isBatchSetQuotaDialogOpen, isBatchAddAdminDialogOpen } = this.state; + const curTab = this.getCurrentNavItem(); return ( @@ -491,8 +504,16 @@ class Users extends Component {
- +
+ {curTab == 'database' && + + }