diff --git a/assets/js/components/ClusterDetails/AscsErsClusterDetails.jsx b/assets/js/components/ClusterDetails/AscsErsClusterDetails.jsx index 7ee426b07a..b1bf87c231 100644 --- a/assets/js/components/ClusterDetails/AscsErsClusterDetails.jsx +++ b/assets/js/components/ClusterDetails/AscsErsClusterDetails.jsx @@ -1,6 +1,10 @@ import React, { useState, useEffect } from 'react'; import { get } from 'lodash'; +import { EOS_SETTINGS, EOS_CLEAR_ALL, EOS_PLAY_CIRCLE } from 'eos-icons-react'; +import { RUNNING_STATES } from '@state/lastExecutions'; + +import Button from '@components/Button'; import PageHeader from '@components/PageHeader'; import BackButton from '@components/BackButton'; import Table from '@components/Table'; @@ -10,6 +14,7 @@ import DottedPagination from '@components/DottedPagination'; import ClusterNodeLink from '@components/ClusterDetails/ClusterNodeLink'; import SapSystemLink from '@components/SapSystemLink'; import { renderEnsaVersion } from '@components/SapSystemDetails'; +import Tooltip from '@components/Tooltip'; import CheckResultsOverview from '@components/CheckResultsOverview'; @@ -65,13 +70,19 @@ const nodeDetailsConfig = { }; function AscsErsClusterDetails({ + clusterID, clusterName, + selectedChecks, + hasSelectedChecks, cibLastWritten, provider, hosts, sapSystems, details, catalog, + lastExecution, + onStartExecution, + navigate, }) { const [enrichedSapSystems, setEnrichedSapSystems] = useState([]); const [currentSapSystem, setCurrentSapSystem] = useState(null); @@ -91,6 +102,15 @@ function AscsErsClusterDetails({ const catalogLoading = get(catalog, 'loading'); const catalogError = get(catalog, 'error'); + const executionData = get(lastExecution, 'data'); + const executionLoading = get(lastExecution, 'loading', true); + const executionError = get(lastExecution, 'error'); + + const startExecutionDisabled = + executionLoading || + !hasSelectedChecks || + RUNNING_STATES.includes(executionData?.status); + return (
Back to Clusters @@ -101,6 +121,51 @@ function AscsErsClusterDetails({ {clusterName}
+
+
+ + + + + + + +
+
@@ -174,10 +239,15 @@ function AscsErsClusterDetails({
{}} + loading={catalogLoading || executionLoading} + error={catalogError || executionError} + onCheckClick={(health) => + navigate( + `/clusters/${clusterID}/executions/last?health=${health}` + ) + } />
diff --git a/assets/js/components/ClusterDetails/AscsErsClusterDetails.test.jsx b/assets/js/components/ClusterDetails/AscsErsClusterDetails.test.jsx index d64a881cdb..7481dee862 100644 --- a/assets/js/components/ClusterDetails/AscsErsClusterDetails.test.jsx +++ b/assets/js/components/ClusterDetails/AscsErsClusterDetails.test.jsx @@ -1,5 +1,6 @@ import React from 'react'; +import { faker } from '@faker-js/faker'; import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom'; @@ -7,10 +8,13 @@ import '@testing-library/jest-dom'; import { renderWithRouter } from '@lib/test-utils'; import { + hostFactory, buildHostsFromAscsErsClusterDetails, buildSapSystemsFromAscsErsClusterDetails, ascsErsClusterDetailsFactory, clusterFactory, + checksExecutionCompletedFactory, + checksExecutionRunningFactory, } from '@lib/test-utils/factories'; import { providerData } from '@components/ProviderLabel/ProviderLabel'; @@ -275,4 +279,129 @@ describe('ClusterDetails AscsErsClusterDetails component', () => { }); }); }); + + it('should suggest to the user to select some checks if the selection is empty', async () => { + const user = userEvent.setup(); + + const { + clusterID, + clusterName, + cib_last_written: cibLastWritten, + type: clusterType, + sid, + provider, + details, + } = clusterFactory.build({ type: 'ascs_ers' }); + + const hosts = hostFactory.buildList(2, { cluster_id: clusterID }); + + renderWithRouter( + + ); + + const startExecutionButton = screen.getByText('Start Execution'); + await user.hover(startExecutionButton); + expect(screen.queryByText('Select some Checks first!')).toBeVisible(); + }); + + const executionId = faker.string.uuid(); + + const executionScenarios = [ + { + name: 'Execution is being loaded from wanda', + selectedChecks: ['some'], + hasSelectedChecks: true, + lastExecution: { data: null, loading: true, error: null }, + }, + { + name: 'No checks were selected', + selectedChecks: [], + hasSelectedChecks: false, + lastExecution: { + data: checksExecutionCompletedFactory.build({ + execution_id: executionId, + }), + loading: false, + error: null, + }, + }, + { + name: 'Execution is still running', + selectedChecks: ['A123'], + hasSelectedChecks: true, + lastExecution: { + data: checksExecutionRunningFactory.build({ + execution_id: executionId, + }), + loading: false, + error: null, + }, + }, + { + name: 'Execution has been requested', + selectedChecks: ['A123'], + hasSelectedChecks: true, + lastExecution: { + data: { + execution_id: executionId, + status: 'requested', + }, + loading: false, + error: null, + }, + }, + ]; + + it.each(executionScenarios)( + 'should disable starting a new execution when $name', + ({ selectedChecks, hasSelectedChecks, lastExecution }) => { + const hanaCluster = clusterFactory.build({ + type: 'ascs_ers', + }); + + const { + clusterID, + clusterName, + cib_last_written: cibLastWritten, + type: clusterType, + sid, + provider, + details, + } = hanaCluster; + + const hosts = hostFactory.buildList(2, { cluster_id: clusterID }); + + renderWithRouter( + + ); + + expect(screen.getByText('Start Execution')).toBeDisabled(); + } + ); }); diff --git a/assets/js/components/ClusterDetails/ClusterDetailsPage.jsx b/assets/js/components/ClusterDetails/ClusterDetailsPage.jsx index f043c04a6a..de05aad30b 100644 --- a/assets/js/components/ClusterDetails/ClusterDetailsPage.jsx +++ b/assets/js/components/ClusterDetails/ClusterDetailsPage.jsx @@ -91,13 +91,23 @@ export function ClusterDetailsPage() { case 'ascs_ers': return ( + dispatch( + executionRequested(clusterID, hostList, checks, navigateFunction) + ) + } + navigate={navigate} /> ); default: