Adds filtering for system level roles

This commit is contained in:
Alex Corey
2021-02-17 14:43:22 -05:00
parent 2a9a471181
commit 1f59d6182b
4 changed files with 75 additions and 21 deletions

View File

@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { TeamsAPI, UsersAPI } from '../../api';
import { RolesAPI, TeamsAPI, UsersAPI } from '../../api';
import AddResourceRole from '../AddRole/AddResourceRole';
import AlertModal from '../AlertModal';
import DataListToolbar from '../DataListToolbar';
@@ -26,7 +26,13 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
const location = useLocation();
const {
result: { accessRecords, itemCount, relatedSearchableKeys, searchableKeys },
result: {
accessRecords,
itemCount,
relatedSearchableKeys,
searchableKeys,
organizationRoles,
},
error: contentError,
isLoading,
request: fetchAccessRecords,
@@ -37,6 +43,41 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
apiModel.readAccessList(resource.id, params),
apiModel.readAccessOptions(resource.id),
]);
// Eventually this could be expanded to other access lists.
// We will need to combine the role ids of all the different level
// of resource level roles.
let orgRoles;
if (location.pathname.includes('/organizations')) {
const {
data: { results: roles },
} = await RolesAPI.read({ content_type__isnull: true });
const sysAdmin = roles.filter(
role => role.name === 'System Administrator'
);
const sysAud = roles.filter(role => {
let auditor;
if (role.name === 'System Auditor') {
auditor = role.id;
}
return auditor;
});
orgRoles = Object.values(resource.summary_fields.object_roles).map(
opt => {
let item;
if (opt.name === 'Admin') {
item = [`${opt.id}, ${sysAdmin[0].id}`, opt.name];
} else if (sysAud[0].id && opt.name === 'Auditor') {
item = [`${sysAud[0].id}, ${opt.id}`, opt.name];
} else {
item = [`${opt.id}`, opt.name];
}
return item;
}
);
}
return {
accessRecords: response.data.results,
itemCount: response.data.count,
@@ -46,8 +87,9 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
searchableKeys: Object.keys(
actionsResponse.data.actions?.GET || {}
).filter(key => actionsResponse.data.actions?.GET[key].filterable),
organizationRoles: orgRoles,
};
}, [apiModel, location, resource.id]),
}, [apiModel, location, resource]),
{
accessRecords: [],
itemCount: 0,
@@ -94,17 +136,14 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
},
];
if (location.pathname.includes('/organizations')) {
const roles = Object.values(
resource.summary_fields.object_roles
).map(opt => [opt.id.toString(), opt.name]);
if (organizationRoles?.length > 0) {
toolbarSearchColumns.push({
name: i18n._(t`Roles`),
key: `or__roles__in`,
options: roles,
options: organizationRoles,
});
}
return (
<>
<PaginatedDataList

View File

@@ -6,7 +6,7 @@ import {
waitForElement,
} from '../../../testUtils/enzymeHelpers';
import { OrganizationsAPI, TeamsAPI, UsersAPI } from '../../api';
import { OrganizationsAPI, TeamsAPI, UsersAPI, RolesAPI } from '../../api';
import ResourceAccessList from './ResourceAccessList';
@@ -105,6 +105,14 @@ describe('<ResourceAccessList />', () => {
});
TeamsAPI.disassociateRole.mockResolvedValue({});
UsersAPI.disassociateRole.mockResolvedValue({});
RolesAPI.read.mockResolvedValue({
data: {
results: [
{ id: 1, name: 'System Administrator' },
{ id: 14, name: 'System Auditor' },
],
},
});
const history = createMemoryHistory({
initialEntries: ['/organizations/1/access'],
});
@@ -203,7 +211,7 @@ describe('<ResourceAccessList />', () => {
key: 'or__roles__in',
name: 'Roles',
options: [
['2', 'Admin'],
['2, 1', 'Admin'],
['3', 'Execute'],
['4', 'Project Admin'],
],

View File

@@ -56,6 +56,8 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
onRoleDelete(role, accessRecord);
}}
isReadOnly={!role.user_capabilities.unattach}
ouiaId={`${role.name}-${role.id}`}
closeBtnAriaLabel={i18n._(t`Remove ${role.name} chip`)}
>
{role.name}
</Chip>

View File

@@ -98,11 +98,12 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
>
<Chip
className=""
closeBtnAriaLabel="close"
closeBtnAriaLabel="Remove Member chip"
component="div"
isOverflowChip={false}
isReadOnly={false}
onClick={[Function]}
ouiaId="Member-3"
tooltipPosition="top"
>
Member
@@ -164,11 +165,12 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
>
<Chip
className=""
closeBtnAriaLabel="close"
closeBtnAriaLabel="Remove Member chip"
component="div"
isOverflowChip={false}
isReadOnly={false}
onClick={[Function]}
ouiaId="Member-3"
tooltipPosition="top"
>
Member
@@ -253,11 +255,12 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
>
<Chip
className=""
closeBtnAriaLabel="close"
closeBtnAriaLabel="Remove Member chip"
component="div"
isOverflowChip={false}
isReadOnly={false}
onClick={[Function]}
ouiaId="Member-3"
tooltipPosition="top"
>
Member
@@ -688,11 +691,12 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
>
<Chip
className=""
closeBtnAriaLabel="close"
closeBtnAriaLabel="Remove Member chip"
component="div"
isOverflowChip={false}
isReadOnly={false}
onClick={[Function]}
ouiaId="Member-3"
tooltipPosition="top"
>
Member
@@ -865,12 +869,13 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
>
<Chip
className=""
closeBtnAriaLabel="close"
closeBtnAriaLabel="Remove Member chip"
component="div"
isOverflowChip={false}
isReadOnly={false}
key=".$3"
onClick={[Function]}
ouiaId="Member-3"
tooltipPosition="top"
>
<GenerateId
@@ -878,7 +883,7 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
>
<div
className="pf-c-chip"
data-ouia-component-id="OUIA-Generated-Chip-1"
data-ouia-component-id="Member-3"
data-ouia-component-type="PF4/Chip"
data-ouia-safe={true}
>
@@ -889,19 +894,19 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
Member
</span>
<Button
aria-label="close"
aria-label="Remove Member chip"
aria-labelledby="remove_pf-random-id-1 pf-random-id-1"
id="remove_pf-random-id-1"
onClick={[Function]}
ouiaId="close"
ouiaId="Member-3"
variant="plain"
>
<button
aria-disabled={false}
aria-label="close"
aria-label="Remove Member chip"
aria-labelledby="remove_pf-random-id-1 pf-random-id-1"
className="pf-c-button pf-m-plain"
data-ouia-component-id="close"
data-ouia-component-id="Member-3"
data-ouia-component-type="PF4/Button"
data-ouia-safe={true}
disabled={false}