diff --git a/assets/js/components/ExecutionResults/ExecutionResults.jsx b/assets/js/components/ExecutionResults/ExecutionResults.jsx
index 31628f14df..868e94faa7 100644
--- a/assets/js/components/ExecutionResults/ExecutionResults.jsx
+++ b/assets/js/components/ExecutionResults/ExecutionResults.jsx
@@ -4,22 +4,57 @@ import Table from '@components/Table';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import LoadingBox from '@components/LoadingBox';
+import Modal from '@components/Modal';
-import { getCheckResults, getCheckDescription } from './checksUtils';
+import {
+ getCheckResults,
+ getCheckDescription,
+ getCheckRemediation,
+} from './checksUtils';
import ResultsContainer from './ResultsContainer';
import { ExecutionIcon } from './ExecutionIcon';
import CheckResultOutline from './CheckResultOutline';
import ExecutionHeader from './ExecutionHeader';
+const addHostnameToTargets = (targets, hostnames) =>
+ targets?.map((target) => {
+ const { agent_id } = target;
+
+ const { hostname } = hostnames.find(({ id }) => agent_id === id);
+ return {
+ ...target,
+ hostname,
+ };
+ });
+
+function MarkdownContent({ children }) {
+ return (
+
+ {children}
+
+ );
+}
+
const resultsTableConfig = {
usePadding: false,
columns: [
{
title: 'Id',
key: 'checkID',
- render: (checkID) => (
-
{checkID}
+ render: (checkID, item) => (
+
+ {
+ e.stopPropagation();
+ item.onClickRemediation();
+ }}
+ >
+ {checkID}
+
+
),
},
{
@@ -50,25 +85,6 @@ const resultsTableConfig = {
),
};
-const addHostnameToTargets = (targets, hostnames) =>
- targets?.map((target) => {
- const { agent_id } = target;
-
- const { hostname } = hostnames.find(({ id }) => agent_id === id);
- return {
- ...target,
- hostname,
- };
- });
-
-function MarkdownContent({ children }) {
- return (
-
- {children}
-
- );
-}
-
function ExecutionResults({
clusterID,
clusterName,
@@ -89,6 +105,8 @@ function ExecutionResults({
onStartExecution = () => {},
}) {
const [predicates, setPredicates] = useState([]);
+ const [selectedCheck, setSelectedCheck] = useState(null);
+ const [modalOpen, setModalOpen] = useState(false);
const hosts = hostnames.map((item) => item.id);
@@ -135,6 +153,10 @@ function ExecutionResults({
description: getCheckDescription(catalog, checkID),
expectationResults,
agentsCheckResults: addHostnameToTargets(agentsCheckResults, hostnames),
+ onClickRemediation: () => {
+ setModalOpen(true);
+ setSelectedCheck(checkID);
+ },
})
);
@@ -159,9 +181,23 @@ function ExecutionResults({
hosts={hosts}
onContentRefresh={onContentRefresh}
onStartExecution={onStartExecution}
+ selectedCheck={selectedCheck}
>
+
+ {getCheckDescription(catalog, selectedCheck)}
+
+ }
+ onClose={() => setModalOpen(false)}
+ >
+
+ {getCheckRemediation(catalog, selectedCheck)}
+
+
>
);
}
diff --git a/assets/js/components/ExecutionResults/ExecutionResults.test.jsx b/assets/js/components/ExecutionResults/ExecutionResults.test.jsx
index 512e34f683..899778b245 100644
--- a/assets/js/components/ExecutionResults/ExecutionResults.test.jsx
+++ b/assets/js/components/ExecutionResults/ExecutionResults.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { screen } from '@testing-library/react';
-
+import { screen, fireEvent } from '@testing-library/react';
import { faker } from '@faker-js/faker';
import { renderWithRouter } from '@lib/test-utils';
@@ -411,4 +410,75 @@ describe('ExecutionResults', () => {
)
).toBeTruthy();
});
+
+ it('should open remediation modal when clicking on checkID', async () => {
+ const {
+ clusterID,
+ hostnames,
+ loading,
+ catalog,
+ executionError,
+ executionStarted,
+ executionResult,
+ checks,
+ } = prepareStateData('completed');
+
+ renderWithRouter(
+
+ );
+
+ const { id: checkID, remediation } = catalog[0];
+ const clickableID = screen.getByText(checkID);
+ expect(clickableID.textContent).toBe(checks[0]);
+ let remediationModalElement = screen.queryByText(remediation);
+ expect(remediationModalElement).not.toBeInTheDocument();
+ fireEvent.click(clickableID);
+ remediationModalElement = screen.getByText(remediation);
+ expect(remediationModalElement).toBeInTheDocument();
+ });
+
+ it('should not open remediation modal when clicking on description', async () => {
+ const {
+ clusterID,
+ hostnames,
+ loading,
+ catalog,
+ executionError,
+ executionStarted,
+ executionResult,
+ checks,
+ } = prepareStateData('completed');
+
+ renderWithRouter(
+
+ );
+
+ const { remediation, description } = catalog[0];
+ const checkDescriptionText = screen.getByText(description);
+ expect(description).toBe(checkDescriptionText.textContent);
+ let remediationModalElement = screen.queryByText(remediation);
+ fireEvent.click(checkDescriptionText);
+ remediationModalElement = screen.queryByText(remediation);
+ expect(remediationModalElement).not.toBeInTheDocument();
+ });
});