diff --git a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx index f1c309e959..898eef3609 100644 --- a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx +++ b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx @@ -9,6 +9,7 @@ import { CardBody as PFCardBody, Expandable as PFExpandable, } from '@patternfly/react-core'; +import getErrorMessage from './getErrorMessage'; const Card = styled(PFCard)` background-color: var(--pf-global--BackgroundColor--200); @@ -52,14 +53,7 @@ class ErrorDetail extends Component { renderNetworkError() { const { error } = this.props; const { response } = error; - - let message = ''; - if (response?.data) { - message = - typeof response.data === 'string' - ? response.data - : response.data?.detail; - } + const message = getErrorMessage(response); return ( @@ -67,7 +61,17 @@ class ErrorDetail extends Component { {response?.config?.method.toUpperCase()} {response?.config?.url}{' '} {response?.status} - {message} + + {Array.isArray(message) ? ( + + ) : ( + message + )} + ); } diff --git a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx index b6499766dc..409fefc3f8 100644 --- a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx +++ b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx @@ -21,4 +21,26 @@ describe('ErrorDetail', () => { ); expect(wrapper).toHaveLength(1); }); + test('testing errors', () => { + const wrapper = mountWithContexts( + + ); + wrapper.find('Expandable').prop('onToggle')(); + wrapper.update(); + // console.log(wrapper.find('ErrorDetail').prop('error')); + }); }); diff --git a/awx/ui_next/src/components/ErrorDetail/getErrorMessage.js b/awx/ui_next/src/components/ErrorDetail/getErrorMessage.js new file mode 100644 index 0000000000..82783f8f63 --- /dev/null +++ b/awx/ui_next/src/components/ErrorDetail/getErrorMessage.js @@ -0,0 +1,15 @@ +export default function getErrorMessage(response) { + if (typeof response.data === 'string') { + return response.data; + } + if (!response.data) { + return null; + } + if (response.data.detail) { + return response.data.detail; + } + return Object.values(response.data).reduce( + (acc, currentValue) => acc.concat(currentValue), + [] + ); +} diff --git a/awx/ui_next/src/components/ErrorDetail/getErrorMessage.test.js b/awx/ui_next/src/components/ErrorDetail/getErrorMessage.test.js new file mode 100644 index 0000000000..c67728f00b --- /dev/null +++ b/awx/ui_next/src/components/ErrorDetail/getErrorMessage.test.js @@ -0,0 +1,60 @@ +import getErrorMessage from './getErrorMessage'; + +describe('getErrorMessage', () => { + test('should return data string', () => { + const response = { + data: 'error response', + }; + expect(getErrorMessage(response)).toEqual('error response'); + }); + test('should return detail string', () => { + const response = { + data: { + detail: 'detail string', + }, + }; + expect(getErrorMessage(response)).toEqual('detail string'); + }); + test('should return an array of strings', () => { + const response = { + data: { + project: ['project error response'], + }, + }; + expect(getErrorMessage(response)).toEqual(['project error response']); + }); + test('should consolidate error messages from multiple keys into an array', () => { + const response = { + data: { + project: ['project error response'], + inventory: ['inventory error response'], + organization: ['org error response'], + }, + }; + expect(getErrorMessage(response)).toEqual([ + 'project error response', + 'inventory error response', + 'org error response', + ]); + }); + test('should handle no response.data', () => { + const response = {}; + expect(getErrorMessage(response)).toEqual(null); + }); + test('should consolidate multiple error messages from multiple keys into an array', () => { + const response = { + data: { + project: ['project error response'], + inventory: [ + 'inventory error response', + 'another inventory error response', + ], + }, + }; + expect(getErrorMessage(response)).toEqual([ + 'project error response', + 'inventory error response', + 'another inventory error response', + ]); + }); +}); diff --git a/awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap b/awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap index e66d8780df..795f398ba2 100644 --- a/awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap +++ b/awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap @@ -322,6 +322,7 @@ exports[` should render initially 1`] = ` className="pf-c-backdrop" > should render initially 1`] = ` } } paused={false} + tag="div" >
handleSelect(question)} onMoveUp={moveUp} onMoveDown={moveDown} - canAddAndEditSurvey={canAddAndEditSurvey} + canEdit={canEdit} /> ))} {isPreviewModalOpen && ( @@ -171,7 +171,7 @@ function SurveyList({ surveyEnabled={surveyEnabled} onToggleSurvey={toggleSurvey} isDeleteDisabled={selected?.length === 0} - canAddAndEditSurvey={canAddAndEditSurvey} + canEdit={canEdit} onToggleDeleteModal={() => setIsDeleteModalOpen(true)} /> {content} diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx index 8190a01162..0564010692 100644 --- a/awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx +++ b/awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx @@ -54,11 +54,7 @@ describe('', () => { let wrapper; await act(async () => { wrapper = mountWithContexts( - + ); }); wrapper.update(); diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyListItem.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyListItem.jsx index bddffc0186..44260988b7 100644 --- a/awx/ui_next/src/screens/Template/Survey/SurveyListItem.jsx +++ b/awx/ui_next/src/screens/Template/Survey/SurveyListItem.jsx @@ -4,7 +4,8 @@ import { withI18n } from '@lingui/react'; import { Link } from 'react-router-dom'; import { Button as _Button, - Chip as _Chip, + Chip, + ChipGroup, DataListAction as _DataListAction, DataListCheck, DataListItemCells, @@ -29,11 +30,8 @@ const Button = styled(_Button)` padding-left: 0; `; const Required = styled.span` - color: red; - margin-left: 5px; -`; -const Chip = styled(_Chip)` - margin-right: 5px; + color: var(--pf-global--danger-color--100); + margin-left: var(--pf-global--spacer--xs); `; const Label = styled.b` @@ -41,7 +39,7 @@ const Label = styled.b` `; function SurveyListItem({ - canAddAndEditSurvey, + canEdit, question, i18n, isLast, @@ -67,7 +65,7 @@ function SurveyListItem({