diff --git a/assets/js/components/ChecksSelection/ChecksSelection.jsx b/assets/js/components/ChecksSelection/ChecksSelection.jsx
index 86011fe1e8..27ec91f429 100644
--- a/assets/js/components/ChecksSelection/ChecksSelection.jsx
+++ b/assets/js/components/ChecksSelection/ChecksSelection.jsx
@@ -65,9 +65,8 @@ function ChecksSelection({
);
useEffect(() => {
- onUpdateCatalog();
onClear();
- }, [onUpdateCatalog, onClear]);
+ }, []);
const onCheckSelectionGroupChange = (checks, groupSelected) => {
const groupChecks = checks.map((check) => check.id);
diff --git a/assets/js/components/ChecksSelection/ChecksSelection.test.jsx b/assets/js/components/ChecksSelection/ChecksSelection.test.jsx
index 6b94c78b5d..1d271330eb 100644
--- a/assets/js/components/ChecksSelection/ChecksSelection.test.jsx
+++ b/assets/js/components/ChecksSelection/ChecksSelection.test.jsx
@@ -51,7 +51,6 @@ describe('ChecksSelection component', () => {
expect(unselectedSwitches[1]).not.toBeChecked();
expect(unselectedSwitches[2]).not.toBeChecked();
- expect(onUpdateCatalog).toBeCalled();
expect(onClear).toBeCalled();
});
@@ -93,7 +92,6 @@ describe('ChecksSelection component', () => {
await user.click(offSwitches[2]);
expect(screen.getAllByRole('switch')[0]).not.toBeChecked();
- expect(onUpdateCatalog).toBeCalled();
expect(onClear).toBeCalled();
});
@@ -113,7 +111,6 @@ describe('ChecksSelection component', () => {
);
expect(screen.getByText(error)).toBeVisible();
- expect(onUpdateCatalog).toBeCalled();
expect(onClear).toBeCalled();
});
@@ -144,7 +141,6 @@ describe('ChecksSelection component', () => {
await user.click(screen.getByText('Select Checks for Execution'));
expect(onSave).toBeCalledWith([checkID1, checkID2], targetID);
- expect(onUpdateCatalog).toBeCalled();
expect(onClear).toBeCalled();
});
});
diff --git a/assets/js/components/HostDetails/HostInfoBox.jsx b/assets/js/components/HostDetails/HostInfoBox.jsx
new file mode 100644
index 0000000000..a5dd63ac8b
--- /dev/null
+++ b/assets/js/components/HostDetails/HostInfoBox.jsx
@@ -0,0 +1,28 @@
+import React from 'react';
+
+import ListView from '@components/ListView';
+import ProviderLabel from '@components/ProviderLabel';
+
+function HostInfoBox({ provider, agentVersion }) {
+ return (
+
+
,
+ },
+ { title: 'Agent version', content: agentVersion },
+ {
+ title: '',
+ content: '',
+ },
+ ]}
+ />
+
+ );
+}
+
+export default HostInfoBox;
diff --git a/assets/js/components/HostDetails/HostInfoBox.test.jsx b/assets/js/components/HostDetails/HostInfoBox.test.jsx
new file mode 100644
index 0000000000..cb34c0d79e
--- /dev/null
+++ b/assets/js/components/HostDetails/HostInfoBox.test.jsx
@@ -0,0 +1,53 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import HostInfoBox from './HostInfoBox';
+
+describe('Host Info Box', () => {
+ const scenarios = [
+ {
+ agentVersion: '1.1.0+git.dev17.1660137228.fe5ba8a',
+ provider: 'aws',
+ providerText: 'AWS',
+ },
+ {
+ agentVersion: '1.2.0+git.dev17.1660137228.fe5ba8a',
+ provider: 'aws',
+ providerText: 'AWS',
+ },
+ {
+ agentVersion: '2.0.0+git.dev17.1660137228.fe5ba8a',
+ provider: 'azure',
+ providerText: 'Azure',
+ },
+ {
+ agentVersion: '1.1.0',
+ provider: 'gcp',
+ providerText: 'GCP',
+ },
+ {
+ agentVersion: '1.2.0',
+ provider: 'kvm',
+ providerText: 'KVM',
+ },
+ {
+ agentVersion: '2.0.0',
+ provider: 'vmware',
+ providerText: 'VMware',
+ },
+ {
+ agentVersion: '2.1.0',
+ provider: 'nutanix',
+ providerText: 'Nutanix',
+ },
+ ];
+
+ it.each(scenarios)(
+ 'should display host info box for $providerText',
+ ({ agentVersion, provider, providerText }) => {
+ render();
+ expect(screen.getByText(providerText)).toBeTruthy();
+ expect(screen.getByText(agentVersion)).toBeTruthy();
+ }
+ );
+});
diff --git a/assets/js/components/HostDetails/index.js b/assets/js/components/HostDetails/index.js
index 50233e8d07..e4b86f3ad5 100644
--- a/assets/js/components/HostDetails/index.js
+++ b/assets/js/components/HostDetails/index.js
@@ -1,3 +1,5 @@
import HostDetails from './HostDetails';
+import HostInfoBox from './HostInfoBox';
+export { HostInfoBox };
export default HostDetails;
diff --git a/assets/js/components/HostSettings/HostSettings.jsx b/assets/js/components/HostSettings/HostSettings.jsx
new file mode 100644
index 0000000000..c45a926740
--- /dev/null
+++ b/assets/js/components/HostSettings/HostSettings.jsx
@@ -0,0 +1,74 @@
+import React, { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { useParams } from 'react-router-dom';
+
+import PageHeader from '@components/PageHeader';
+import BackButton from '@components/BackButton';
+import { HostInfoBox } from '@components/HostDetails';
+
+import ChecksSelection from '@components/ChecksSelection/ChecksSelection';
+
+import { updateCatalog } from '@state/actions/catalog';
+import { getCatalog } from '@state/selectors/catalog';
+import { getHost } from '@state/selectors';
+
+function HostSettings() {
+ const dispatch = useDispatch();
+
+ const { hostID } = useParams();
+ const host = useSelector(getHost(hostID));
+
+ const {
+ data: catalog,
+ error: catalogError,
+ loading: catalogLoading,
+ } = useSelector(getCatalog());
+
+ const catalogEnv = {
+ provider: host?.provider,
+ target_type: 'host',
+ };
+
+ const onCatalogRefresh = () => {
+ dispatch(updateCatalog(catalogEnv));
+ };
+
+ useEffect(() => {
+ if (host) {
+ onCatalogRefresh();
+ }
+ }, [dispatch, host]);
+
+ if (!host) {
+ return Loading...
;
+ }
+
+ return (
+
+
Back to Host Details
+
+ Check Settings for {host?.hostname}
+
+
+
{
+ // TODO: dispatch check selection for a host
+ }}
+ onUpdateCatalog={onCatalogRefresh}
+ onClear={() => {
+ // TODO:
+ }}
+ saving={false}
+ error={null}
+ success={false}
+ />
+
+ );
+}
+
+export default HostSettings;
diff --git a/assets/js/components/HostSettings/index.js b/assets/js/components/HostSettings/index.js
new file mode 100644
index 0000000000..33ccdac03e
--- /dev/null
+++ b/assets/js/components/HostSettings/index.js
@@ -0,0 +1,3 @@
+import HostSettings from './HostSettings';
+
+export default HostSettings;
diff --git a/assets/js/trento.jsx b/assets/js/trento.jsx
index e08aaec7f0..5163ad2def 100644
--- a/assets/js/trento.jsx
+++ b/assets/js/trento.jsx
@@ -30,6 +30,7 @@ import { me } from '@lib/auth';
import { networkClient } from '@lib/network';
import Guard from '@components/Guard';
import CheckResultDetailPage from '@components/ExecutionResults/CheckResultDetail';
+import HostSettings from '@components/HostSettings';
import DatabaseDetails from './components/DatabaseDetails';
import SapSystemDetails from './components/SapSystemDetails/SapSystemDetails';
import { store } from './state';
@@ -59,6 +60,10 @@ function App() {
}>
} />
} />
+ }
+ />
} />
} />
} />