From 635c8336d13f9d0d28bf687b8c69c6224efcef14 Mon Sep 17 00:00:00 2001 From: NavpreetGrewal <65915811+NavpreetGrewal@users.noreply.github.com> Date: Thu, 10 Dec 2020 09:01:13 -0800 Subject: [PATCH] Zeva 343:Display "New User" button and make user list clickable only if user is admin inside Vehicle supplier/users tab (#437) * ZEVA-343: Display "New User" button and make user list clickbale only if user is admin inside Vehicle supplier/users tab. * Add permission "VIEW_USERS" for Engineer/Analyst role. * Rename fixture to avoid conflict --- .../0016_update_roles_permissions.py | 45 +++++++++++++++++++ .../OrganizationDetailsContainer.js | 1 + .../VehicleSupplierUserListContainer.js | 4 +- .../components/OrganizationDetailsPage.js | 4 +- .../organizations/components/UsersTable.js | 22 +++++---- .../components/VehicleSupplierUserListPage.js | 12 +++-- 6 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 backend/api/fixtures/operational/0016_update_roles_permissions.py diff --git a/backend/api/fixtures/operational/0016_update_roles_permissions.py b/backend/api/fixtures/operational/0016_update_roles_permissions.py new file mode 100644 index 000000000..a91ba4c28 --- /dev/null +++ b/backend/api/fixtures/operational/0016_update_roles_permissions.py @@ -0,0 +1,45 @@ +from django.db import transaction + +from api.management.data_script import OperationalDataScript +from api.models.permission import Permission +from api.models.role import Role +from api.models.role_permission import RolePermission +from api.authorities import REQUIRED_AUTHORITIES + + +class UpdateRolesPermissions(OperationalDataScript): + """ + Adds the Roles and Permissions + """ + is_revertable = False + comment = 'Updates the permissions for the roles so that they make more ' \ + 'sense with application.' + + def check_run_preconditions(self): + return True + + def update_analyst(self): + + role = Role.objects.get( + role_code="Engineer/Analyst" + ) + + permissions_to_be_added = [ + 'VIEW_USERS', + ] + + for permission_code in permissions_to_be_added: + permission = Permission.objects.get(permission_code=permission_code) + RolePermission.objects.get_or_create( + permission=permission, + role=role + ) + + @transaction.atomic + def run(self): + self.update_analyst() + + print('Updated Permissions') + + +script_class = UpdateRolesPermissions diff --git a/frontend/src/organizations/OrganizationDetailsContainer.js b/frontend/src/organizations/OrganizationDetailsContainer.js index e8004024f..497115b1d 100644 --- a/frontend/src/organizations/OrganizationDetailsContainer.js +++ b/frontend/src/organizations/OrganizationDetailsContainer.js @@ -38,6 +38,7 @@ const OrganizationDetailsContainer = (props) => { loading={loading} members={members} setFiltered={setFiltered} + user={user} /> ); }; diff --git a/frontend/src/organizations/VehicleSupplierUserListContainer.js b/frontend/src/organizations/VehicleSupplierUserListContainer.js index ed115e7be..9019f5b77 100644 --- a/frontend/src/organizations/VehicleSupplierUserListContainer.js +++ b/frontend/src/organizations/VehicleSupplierUserListContainer.js @@ -20,7 +20,7 @@ const VehicleSupplierUserListContainer = (props) => { const [filtered, setFiltered] = useState([]); const [loading, setLoading] = useState(true); const [users, setUsers] = useState([]); - const { keycloak, location } = props; + const { keycloak, location, user} = props; const { state: locationState } = location; const refreshDetails = () => { @@ -53,6 +53,7 @@ const VehicleSupplierUserListContainer = (props) => { loading={loading} locationState={locationState} members={users} + user={user} setFiltered={setFiltered} /> @@ -61,6 +62,7 @@ const VehicleSupplierUserListContainer = (props) => { VehicleSupplierUserListContainer.propTypes = { keycloak: CustomPropTypes.keycloak.isRequired, location: PropTypes.shape().isRequired, + user: CustomPropTypes.user.isRequired }; export default withRouter(VehicleSupplierUserListContainer); diff --git a/frontend/src/organizations/components/OrganizationDetailsPage.js b/frontend/src/organizations/components/OrganizationDetailsPage.js index 9133e9cf9..4485ea5b0 100644 --- a/frontend/src/organizations/components/OrganizationDetailsPage.js +++ b/frontend/src/organizations/components/OrganizationDetailsPage.js @@ -11,7 +11,7 @@ import UsersTable from './UsersTable'; const OrganizationDetailsPage = (props) => { const { - details, filtered, loading, members, setFiltered, + details, filtered, loading, members, setFiltered, user } = props; if (loading) { @@ -85,6 +85,7 @@ const OrganizationDetailsPage = (props) => { filtered={filtered} items={members} setFiltered={setFiltered} + user={user} /> @@ -102,6 +103,7 @@ OrganizationDetailsPage.propTypes = { loading: PropTypes.bool.isRequired, members: PropTypes.arrayOf(PropTypes.shape()), setFiltered: PropTypes.func.isRequired, + user: CustomPropTypes.user.isRequired, }; export default OrganizationDetailsPage; diff --git a/frontend/src/organizations/components/UsersTable.js b/frontend/src/organizations/components/UsersTable.js index 9156a219b..f3aa25a19 100644 --- a/frontend/src/organizations/components/UsersTable.js +++ b/frontend/src/organizations/components/UsersTable.js @@ -3,7 +3,7 @@ */ import React from 'react'; import PropTypes from 'prop-types'; - +import CustomPropTypes from '../../app/utilities/props'; import ReactTable from '../../app/components/ReactTable'; import history from '../../app/History'; @@ -37,7 +37,7 @@ const UsersTable = (props) => { id: 'status', }]; - const { filtered, items, setFiltered } = props; + const { filtered, items, setFiltered, user } = props; return ( { }]} filtered={filtered} getTrProps={(state, row) => { - if (row && row.original) { - return { - onClick: () => { - const { id } = row.original; - history.push(`/users/${id}/edit`); - }, - className: 'clickable', + if (row && row.original + && typeof user.hasPermission === 'function' + && user.hasPermission('EDIT_USERS') + ) { + return { + onClick: () => { + const { id } = row.original; + history.push(`/users/${id}/edit`); + }, + className: 'clickable', }; } @@ -71,6 +74,7 @@ UsersTable.propTypes = { filtered: PropTypes.arrayOf(PropTypes.shape()).isRequired, items: PropTypes.arrayOf(PropTypes.shape()).isRequired, setFiltered: PropTypes.func.isRequired, + user: CustomPropTypes.user.isRequired, }; export default UsersTable; diff --git a/frontend/src/organizations/components/VehicleSupplierUserListPage.js b/frontend/src/organizations/components/VehicleSupplierUserListPage.js index 4a820d854..47c3bbbf1 100644 --- a/frontend/src/organizations/components/VehicleSupplierUserListPage.js +++ b/frontend/src/organizations/components/VehicleSupplierUserListPage.js @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import CustomPropTypes from '../../app/utilities/props'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { useParams } from 'react-router-dom'; - import Button from '../../app/components/Button'; import History from '../../app/History'; import ROUTES_ORGANIZATIONS from '../../app/routes/Organizations'; @@ -12,7 +12,7 @@ import UsersTable from './UsersTable'; const VehicleSupplierUserListPage = (props) => { const { id } = useParams(); const { - loading, locationState, members, filtered, setFiltered, + loading, locationState, members, filtered, user, setFiltered, } = props; if (loading) { return ; @@ -24,7 +24,8 @@ const VehicleSupplierUserListPage = (props) => {

Users

-
+ {typeof user.hasPermission === 'function'&& user.hasPermission('EDIT_USERS') && user.isGovernment && +
-
+
}
@@ -43,6 +44,7 @@ const VehicleSupplierUserListPage = (props) => { filtered={filtered} items={members} setFiltered={setFiltered} + user={user} />
@@ -76,6 +78,8 @@ VehicleSupplierUserListPage.propTypes = { locationState: PropTypes.arrayOf(PropTypes.shape()), members: PropTypes.arrayOf(PropTypes.shape({})), setFiltered: PropTypes.func.isRequired, + user: CustomPropTypes.user.isRequired + }; export default VehicleSupplierUserListPage;