diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionBody.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionBody.js
new file mode 100644
index 0000000000..15cdc27f51
--- /dev/null
+++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionBody.js
@@ -0,0 +1,94 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { useIntl } from 'react-intl';
+import { Loader } from '@strapi/design-system/Loader';
+import { Grid } from '@strapi/design-system/Grid';
+import { Box } from '@strapi/design-system/Box';
+import { Flex } from '@strapi/design-system/Flex';
+import { Typography } from '@strapi/design-system/Typography';
+import { pxToRem } from '@strapi/helper-plugin';
+import getDefaultMessage from '../utils/getActionTypesDefaultMessages';
+import ActionItem from './ActionItem';
+
+const ActionBody = ({ status, data, formattedDate }) => {
+ const { formatMessage } = useIntl();
+
+ if (status === 'loading') {
+ return (
+
+
+
+ );
+ }
+
+ const { action, user, payload } = data;
+
+ return (
+ <>
+
+
+ {formatMessage({
+ id: 'Settings.permissions.auditLogs.details',
+ defaultMessage: 'Log Details',
+ })}
+
+
+
+
+
+
+
+ {/* TODO remove when adding JSON component */}
+
+ {JSON.stringify(payload, null, 2)}
+
+ >
+ );
+};
+
+ActionBody.defaultProps = {
+ data: {},
+};
+
+ActionBody.propTypes = {
+ status: PropTypes.oneOf(['idle', 'loading', 'error', 'success']).isRequired,
+ data: PropTypes.shape({
+ action: PropTypes.string,
+ date: PropTypes.string,
+ payload: PropTypes.object,
+ user: PropTypes.object,
+ }),
+ formattedDate: PropTypes.string.isRequired,
+};
+
+export default ActionBody;
diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/ModalDialog/ActionItem.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionItem.js
similarity index 100%
rename from packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/ModalDialog/ActionItem.js
rename to packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionItem.js
diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/Modal/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/Modal/index.js
new file mode 100644
index 0000000000..51cd6b2c37
--- /dev/null
+++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/Modal/index.js
@@ -0,0 +1,53 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { useQuery } from 'react-query';
+import { ModalLayout, ModalHeader, ModalBody } from '@strapi/design-system/ModalLayout';
+import { Breadcrumbs, Crumb } from '@strapi/design-system/Breadcrumbs';
+import { useNotification } from '@strapi/helper-plugin';
+import useFormatTimeStamp from '../hooks/useFormatTimeStamp';
+import { useFetchClient } from '../../../../../../hooks';
+import ActionBody from './ActionBody';
+
+const Modal = ({ handleClose, logId }) => {
+ const { get } = useFetchClient();
+ const toggleNotification = useNotification();
+
+ const fetchAuditLog = async (id) => {
+ const { data } = await get(`/admin/audit-logs/${id}`);
+
+ return data;
+ };
+
+ const { data, status } = useQuery(['audit-log', logId], () => fetchAuditLog(logId), {
+ onError() {
+ toggleNotification({
+ type: 'warning',
+ message: { id: 'notification.error', defaultMessage: 'An error occured' },
+ });
+ handleClose();
+ },
+ });
+
+ const formatTimeStamp = useFormatTimeStamp();
+ const formattedDate = data ? formatTimeStamp(data.date) : '';
+
+ return (
+
+
+
+ {formattedDate}
+
+
+
+
+
+
+ );
+};
+
+Modal.propTypes = {
+ handleClose: PropTypes.func.isRequired,
+ logId: PropTypes.number.isRequired,
+};
+
+export default Modal;
diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/ModalDialog/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/ModalDialog/index.js
deleted file mode 100644
index 90933ae19c..0000000000
--- a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/ModalDialog/index.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { useIntl } from 'react-intl';
-import { ModalLayout, ModalHeader, ModalBody } from '@strapi/design-system/ModalLayout';
-import { Breadcrumbs, Crumb } from '@strapi/design-system/Breadcrumbs';
-import { Grid } from '@strapi/design-system/Grid';
-import { Box } from '@strapi/design-system/Box';
-import { Typography } from '@strapi/design-system/Typography';
-import { pxToRem } from '@strapi/helper-plugin';
-import getDefaultMessage from '../utils/getActionTypesDefaultMessages';
-import useFormatTimeStamp from '../hooks/useFormatTimeStamp';
-import ActionItem from './ActionItem';
-
-const ModalDialog = ({ onToggle, data: { date, user, action } }) => {
- const { formatMessage } = useIntl();
- const formatTimeStamp = useFormatTimeStamp();
- const formattedDate = formatTimeStamp(date);
-
- return (
-
-
-
- {formattedDate}
-
-
-
-
-
- {formatMessage({
- id: 'Settings.permissions.auditLogs.details',
- defaultMessage: 'Log Details',
- })}
-
-
-
-
-
-
-
-
-
- );
-};
-
-ModalDialog.propTypes = {
- onToggle: PropTypes.func.isRequired,
- data: PropTypes.object.isRequired,
-};
-
-export default ModalDialog;
diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/index.js
index 4264faa79f..fc49d05dc5 100644
--- a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/index.js
+++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/index.js
@@ -10,7 +10,7 @@ import { onRowClick, stopPropagation } from '@strapi/helper-plugin';
import useFormatTimeStamp from '../hooks/useFormatTimeStamp';
import getDefaultMessage from '../utils/getActionTypesDefaultMessages';
-const TableRows = ({ headers, rows, onModalToggle }) => {
+const TableRows = ({ headers, rows, onOpenModal }) => {
const { formatMessage } = useIntl();
const formatTimeStamp = useFormatTimeStamp();
@@ -36,7 +36,7 @@ const TableRows = ({ headers, rows, onModalToggle }) => {
onModalToggle(data.id),
+ fn: () => onOpenModal(data.id),
})}
>
{headers.map(({ key, name, cellFormatter }) => {
@@ -55,7 +55,7 @@ const TableRows = ({ headers, rows, onModalToggle }) => {
onModalToggle(data.id)}
+ onClick={() => onOpenModal(data.id)}
aria-label={formatMessage(
{ id: 'app.component.table.view', defaultMessage: '{target} details' },
{ target: `${data.action} action` }
@@ -79,7 +79,7 @@ TableRows.defaultProps = {
TableRows.propTypes = {
headers: PropTypes.array.isRequired,
rows: PropTypes.array,
- onModalToggle: PropTypes.func.isRequired,
+ onOpenModal: PropTypes.func.isRequired,
};
export default TableRows;
diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/tests/index.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/tests/index.test.js
index 34035848da..530737f8cd 100644
--- a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/tests/index.test.js
+++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/tests/index.test.js
@@ -60,14 +60,14 @@ const rows = [
},
];
-const onModalToggle = jest.fn();
+const onModalOpen = jest.fn();
// eslint-disable-next-line react/prop-types
const App = (
-
+
@@ -94,13 +94,13 @@ describe('ADMIN | Pages | AUDIT LOGS | ListView | Dynamic Table | Table Rows', (
const label = screen.getByText(/update action details/i);
const viewDetailsButton = label.closest('button');
fireEvent.click(viewDetailsButton);
- expect(onModalToggle).toHaveBeenCalled();
+ expect(onModalOpen).toHaveBeenCalled();
});
it('should open a modal when clicked on a row', () => {
render(App);
const rows = document.querySelectorAll('tr');
fireEvent.click(rows[0]);
- expect(onModalToggle).toHaveBeenCalled();
+ expect(onModalOpen).toHaveBeenCalled();
});
});
diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/index.js
index 2562a9257a..d986258bb1 100644
--- a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/index.js
+++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/index.js
@@ -15,13 +15,11 @@ import adminPermissions from '../../../../../permissions';
import { useFetchClient } from '../../../../../hooks';
import TableRows from './TableRows';
import tableHeaders from './utils/tableHeaders';
-import ModalDialog from './ModalDialog';
import PaginationFooter from './PaginationFooter';
+import Modal from './Modal';
const ListView = () => {
const { formatMessage } = useIntl();
- const [isModalOpen, setIsModalOpen] = useState(false);
- const [detailsActionData, setDetailsActionData] = useState(null);
const toggleNotification = useNotification();
const {
allowedActions: { canRead },
@@ -31,14 +29,14 @@ const ListView = () => {
useFocusWhenNavigate();
- const fetchData = async ({ queryKey }) => {
+ const fetchAuditLogsPage = async ({ queryKey }) => {
const search = queryKey[1];
const { data } = await get(`/admin/audit-logs${search}`);
return data;
};
- const { data, isLoading } = useQuery(['auditLogs', search], fetchData, {
+ const { data, isLoading } = useQuery(['auditLogs', search], fetchAuditLogsPage, {
enabled: canRead,
keepPreviousData: true,
retry: false,
@@ -64,14 +62,7 @@ const ListView = () => {
},
}));
- const handleToggle = (id) => {
- setIsModalOpen((prev) => !prev);
-
- if (data.results && id) {
- const actionData = data.results.find((action) => action.id === id);
- setDetailsActionData(actionData);
- }
- };
+ const [modalLogId, setModalLogId] = useState(null);
return (
@@ -91,11 +82,15 @@ const ListView = () => {
withBulkActions
isLoading={isLoading}
>
-
+ setModalLogId(id)}
+ />
- {isModalOpen && }
+ {modalLogId && setModalLogId(null)} logId={modalLogId} />}
);
};
diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/tests/index.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/tests/index.test.js
index d0d79d2843..320dd07b5c 100644
--- a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/tests/index.test.js
+++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/tests/index.test.js
@@ -2,13 +2,13 @@ import React from 'react';
import { Router } from 'react-router-dom';
import { IntlProvider } from 'react-intl';
import { createMemoryHistory } from 'history';
-import { render, screen, waitFor } from '@testing-library/react';
+import { render, screen, waitFor, within } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from 'react-query';
import userEvent from '@testing-library/user-event';
import { ThemeProvider, lightTheme } from '@strapi/design-system';
import { TrackingProvider } from '@strapi/helper-plugin';
import ListView from '../index';
-import { TEST_DATA, getBigTestData } from './utils/data';
+import { TEST_PAGE_DATA, TEST_SINGLE_DATA, getBigTestPageData } from './utils/data';
const history = createMemoryHistory();
const user = userEvent.setup();
@@ -87,7 +87,7 @@ describe('ADMIN | Pages | AUDIT LOGS | ListView', () => {
it('should show a list of audit logs with all actions', async () => {
mockUseQuery.mockReturnValue({
data: {
- results: TEST_DATA,
+ results: TEST_PAGE_DATA,
},
isLoading: false,
});
@@ -104,20 +104,31 @@ describe('ADMIN | Pages | AUDIT LOGS | ListView', () => {
it('should open a modal when clicked on a table row and close modal when clicked', async () => {
mockUseQuery.mockReturnValue({
data: {
- results: TEST_DATA,
+ results: TEST_PAGE_DATA,
},
isLoading: false,
});
+ render(App);
- const { container } = render(App);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
- const rows = container.querySelector('tbody').querySelectorAll('tr');
- await user.click(rows[0]);
- expect(screen.getByRole('dialog')).toBeInTheDocument();
+ mockUseQuery.mockReturnValue({
+ data: TEST_SINGLE_DATA,
+ status: 'success',
+ });
- const label = screen.getByText(/close the modal/i);
- const closeButton = label.closest('button');
+ const auditLogRow = screen.getByText('Create role').closest('tr');
+ await user.click(auditLogRow);
+
+ const modal = screen.getByRole('dialog');
+ expect(modal).toBeInTheDocument();
+
+ const modalContainer = within(modal);
+ expect(modalContainer.getByText('Create role')).toBeInTheDocument();
+ expect(modalContainer.getByText('test user')).toBeInTheDocument();
+ expect(modalContainer.getAllByText('December 22, 2022, 16:11:03')).toHaveLength(3);
+
+ const closeButton = modalContainer.getByText(/close the modal/i).closest('button');
await user.click(closeButton);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
});
@@ -125,7 +136,7 @@ describe('ADMIN | Pages | AUDIT LOGS | ListView', () => {
it('should show pagination and be on page 1 on first render', async () => {
mockUseQuery.mockReturnValue({
data: {
- results: getBigTestData(15),
+ results: getBigTestPageData(15),
pagination: {
page: 1,
pageSize: 10,
@@ -147,7 +158,7 @@ describe('ADMIN | Pages | AUDIT LOGS | ListView', () => {
it('paginates the results', async () => {
mockUseQuery.mockReturnValue({
data: {
- results: getBigTestData(35),
+ results: getBigTestPageData(35),
pagination: {
page: 1,
pageSize: 10,
@@ -191,7 +202,7 @@ describe('ADMIN | Pages | AUDIT LOGS | ListView', () => {
mockUseQuery.mockReturnValue({
data: {
- results: getBigTestData(20),
+ results: getBigTestPageData(20),
pagination: {
page: 1,
pageSize: 20,
diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/tests/utils/data.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/tests/utils/data.js
index 12fcc9559e..96964ef4d1 100644
--- a/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/tests/utils/data.js
+++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/AuditLogs/ListView/tests/utils/data.js
@@ -1,4 +1,4 @@
-export const TEST_DATA = [
+const TEST_PAGE_DATA = [
{
id: 1,
action: 'role.create',
@@ -37,15 +37,31 @@ export const TEST_DATA = [
},
];
-export const getBigTestData = (quantity) => {
+const TEST_SINGLE_DATA = {
+ id: 1,
+ action: 'role.create',
+ date: '2022-12-22T16:11:03.126Z',
+ payload: {
+ meta: 'data',
+ },
+ user: {
+ id: 1,
+ fullname: 'test user',
+ email: 'test@test.com',
+ },
+};
+
+const getBigTestPageData = (quantity) => {
const data = [];
for (let i = 0; i < quantity; i++) {
data.push({
- ...TEST_DATA[i % TEST_DATA.length],
+ ...TEST_PAGE_DATA[i % TEST_PAGE_DATA.length],
id: i + 1,
});
}
return data;
};
+
+export { TEST_PAGE_DATA, TEST_SINGLE_DATA, getBigTestPageData };
|