mirror of
https://github.com/ansible/awx.git
synced 2026-03-05 10:41:05 -03:30
Merge pull request #8776 from nixocio/ui_issue_7708
Show access tab when credential does not belong to an organization Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
@@ -144,7 +144,7 @@ class AddResourceRole extends React.Component {
|
|||||||
currentStepId,
|
currentStepId,
|
||||||
maxEnabledStep,
|
maxEnabledStep,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { onClose, roles, i18n } = this.props;
|
const { onClose, roles, i18n, resource } = this.props;
|
||||||
|
|
||||||
// Object roles can be user only, so we remove them when
|
// Object roles can be user only, so we remove them when
|
||||||
// showing role choices for team access
|
// showing role choices for team access
|
||||||
@@ -235,18 +235,24 @@ class AddResourceRole extends React.Component {
|
|||||||
t`Choose the type of resource that will be receiving new roles. For example, if you'd like to add new roles to a set of users please choose Users and click Next. You'll be able to select the specific resources in the next step.`
|
t`Choose the type of resource that will be receiving new roles. For example, if you'd like to add new roles to a set of users please choose Users and click Next. You'll be able to select the specific resources in the next step.`
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SelectableCard
|
<SelectableCard
|
||||||
isSelected={selectedResource === 'users'}
|
isSelected={selectedResource === 'users'}
|
||||||
label={i18n._(t`Users`)}
|
label={i18n._(t`Users`)}
|
||||||
dataCy="add-role-users"
|
dataCy="add-role-users"
|
||||||
|
ariaLabel={i18n._(t`Users`)}
|
||||||
onClick={() => this.handleResourceSelect('users')}
|
onClick={() => this.handleResourceSelect('users')}
|
||||||
/>
|
/>
|
||||||
<SelectableCard
|
{resource?.type === 'credential' &&
|
||||||
isSelected={selectedResource === 'teams'}
|
!resource?.organization ? null : (
|
||||||
label={i18n._(t`Teams`)}
|
<SelectableCard
|
||||||
dataCy="add-role-teams"
|
isSelected={selectedResource === 'teams'}
|
||||||
onClick={() => this.handleResourceSelect('teams')}
|
label={i18n._(t`Teams`)}
|
||||||
/>
|
dataCy="add-role-teams"
|
||||||
|
ariaLabel={i18n._(t`Teams`)}
|
||||||
|
onClick={() => this.handleResourceSelect('teams')}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
enableNext: selectedResource !== null,
|
enableNext: selectedResource !== null,
|
||||||
@@ -329,10 +335,12 @@ AddResourceRole.propTypes = {
|
|||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
onSave: PropTypes.func.isRequired,
|
onSave: PropTypes.func.isRequired,
|
||||||
roles: PropTypes.shape(),
|
roles: PropTypes.shape(),
|
||||||
|
resource: PropTypes.shape(),
|
||||||
};
|
};
|
||||||
|
|
||||||
AddResourceRole.defaultProps = {
|
AddResourceRole.defaultProps = {
|
||||||
roles: {},
|
roles: {},
|
||||||
|
resource: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
export { AddResourceRole as _AddResourceRole };
|
export { AddResourceRole as _AddResourceRole };
|
||||||
|
|||||||
@@ -221,4 +221,22 @@ describe('<_AddResourceRole />', () => {
|
|||||||
expect(TeamsAPI.associateRole).toHaveBeenCalledTimes(2);
|
expect(TeamsAPI.associateRole).toHaveBeenCalledTimes(2);
|
||||||
expect(handleSave).toHaveBeenCalled();
|
expect(handleSave).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should not display team as a choice in case credential does not have organization', () => {
|
||||||
|
const spy = jest.spyOn(_AddResourceRole.prototype, 'handleResourceSelect');
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<AddResourceRole
|
||||||
|
onClose={() => {}}
|
||||||
|
onSave={() => {}}
|
||||||
|
roles={roles}
|
||||||
|
resource={{ type: 'credential', organization: null }}
|
||||||
|
/>,
|
||||||
|
{ context: { network: { handleHttpError: () => {} } } }
|
||||||
|
).find('AddResourceRole');
|
||||||
|
const selectableCardWrapper = wrapper.find('SelectableCard');
|
||||||
|
expect(selectableCardWrapper.length).toBe(1);
|
||||||
|
selectableCardWrapper.first().simulate('click');
|
||||||
|
expect(spy).toHaveBeenCalledWith('users');
|
||||||
|
expect(wrapper.state('selectedResource')).toBe('users');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
|
|||||||
fetchAccessRecords();
|
fetchAccessRecords();
|
||||||
}}
|
}}
|
||||||
roles={resource.summary_fields.object_roles}
|
roles={resource.summary_fields.object_roles}
|
||||||
|
resource={resource}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showDeleteModal && (
|
{showDeleteModal && (
|
||||||
|
|||||||
@@ -31,7 +31,14 @@ const Description = styled.p`
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function SelectableCard({ label, description, onClick, isSelected, dataCy }) {
|
function SelectableCard({
|
||||||
|
label,
|
||||||
|
description,
|
||||||
|
onClick,
|
||||||
|
isSelected,
|
||||||
|
dataCy,
|
||||||
|
ariaLabel,
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<SelectableItem
|
<SelectableItem
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
@@ -40,6 +47,7 @@ function SelectableCard({ label, description, onClick, isSelected, dataCy }) {
|
|||||||
tabIndex="0"
|
tabIndex="0"
|
||||||
data-cy={dataCy}
|
data-cy={dataCy}
|
||||||
isSelected={isSelected}
|
isSelected={isSelected}
|
||||||
|
aria-label={ariaLabel}
|
||||||
>
|
>
|
||||||
<Indicator isSelected={isSelected} />
|
<Indicator isSelected={isSelected} />
|
||||||
<Contents>
|
<Contents>
|
||||||
@@ -55,12 +63,14 @@ SelectableCard.propTypes = {
|
|||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
onClick: PropTypes.func.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
isSelected: PropTypes.bool,
|
isSelected: PropTypes.bool,
|
||||||
|
ariaLabel: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectableCard.defaultProps = {
|
SelectableCard.defaultProps = {
|
||||||
label: '',
|
label: '',
|
||||||
description: '',
|
description: '',
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
|
ariaLabel: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SelectableCard;
|
export default SelectableCard;
|
||||||
|
|||||||
@@ -56,15 +56,12 @@ function Credential({ i18n, setBreadcrumb }) {
|
|||||||
id: 99,
|
id: 99,
|
||||||
},
|
},
|
||||||
{ name: i18n._(t`Details`), link: `/credentials/${id}/details`, id: 0 },
|
{ name: i18n._(t`Details`), link: `/credentials/${id}/details`, id: 0 },
|
||||||
];
|
{
|
||||||
|
|
||||||
if (credential && credential.organization) {
|
|
||||||
tabsArray.push({
|
|
||||||
name: i18n._(t`Access`),
|
name: i18n._(t`Access`),
|
||||||
link: `/credentials/${id}/access`,
|
link: `/credentials/${id}/access`,
|
||||||
id: 1,
|
id: 1,
|
||||||
});
|
},
|
||||||
}
|
];
|
||||||
|
|
||||||
let showCardHeader = true;
|
let showCardHeader = true;
|
||||||
|
|
||||||
@@ -108,14 +105,12 @@ function Credential({ i18n, setBreadcrumb }) {
|
|||||||
<Route key="edit" path="/credentials/:id/edit">
|
<Route key="edit" path="/credentials/:id/edit">
|
||||||
<CredentialEdit credential={credential} />
|
<CredentialEdit credential={credential} />
|
||||||
</Route>,
|
</Route>,
|
||||||
credential.organization && (
|
<Route key="access" path="/credentials/:id/access">
|
||||||
<Route key="access" path="/credentials/:id/access">
|
<ResourceAccessList
|
||||||
<ResourceAccessList
|
resource={credential}
|
||||||
resource={credential}
|
apiModel={CredentialsAPI}
|
||||||
apiModel={CredentialsAPI}
|
/>
|
||||||
/>
|
</Route>,
|
||||||
</Route>
|
|
||||||
),
|
|
||||||
<Route key="not-found" path="*">
|
<Route key="not-found" path="*">
|
||||||
{!hasContentLoading && (
|
{!hasContentLoading && (
|
||||||
<ContentError isNotFound>
|
<ContentError isNotFound>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ describe('<Credential />', () => {
|
|||||||
wrapper = mountWithContexts(<Credential setBreadcrumb={() => {}} />);
|
wrapper = mountWithContexts(<Credential setBreadcrumb={() => {}} />);
|
||||||
});
|
});
|
||||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 2);
|
await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initially renders org-based credential succesfully', async () => {
|
test('initially renders org-based credential succesfully', async () => {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ function CredentialDetail({ i18n, credential }) {
|
|||||||
{}
|
{}
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}, [credentialId, credential_type]),
|
}, [credentialId, credential_type.id]),
|
||||||
{
|
{
|
||||||
fields: [],
|
fields: [],
|
||||||
managedByTower: true,
|
managedByTower: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user