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.map(m => (
+ - {m}
+ ))}
+
+ ) : (
+ 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({