From dd562c4203d0f2d46bbbbf2ec915adca1dec9112 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Wed, 8 Sep 2021 16:32:52 -0700 Subject: [PATCH] Refactor UA Overview to support step-completion (#111243) * Refactor UA Overview to store step-completion state at the root and delegate step-completion logic to each step component. * Add completion status to logs and issues steps --- .../client_integration/helpers/index.ts | 1 + .../helpers/time_manipulation.ts | 24 ++++++++ .../overview/backup_step/backup_step.test.tsx | 58 ++++++++++++++----- .../fix_issues_step/fix_issues_step.test.tsx | 31 ++++++++++ .../fix_logs_step/fix_logs_step.test.tsx | 43 ++++++++++++-- .../overview/backup_step/backup_step.tsx | 19 +++--- .../overview/backup_step/cloud_backup.tsx | 35 ++++++++--- .../fix_issues_step/es_stats/es_stats.tsx | 27 +++++++-- .../fix_issues_step/fix_issues_step.tsx | 56 ++++++++++++++---- .../kibana_stats/kibana_stats.tsx | 12 +++- .../deprecations_count_checkpoint.tsx | 31 +++++++--- .../overview/fix_logs_step/fix_logs_step.tsx | 18 ++++-- .../components/overview/overview.tsx | 37 +++++++++--- .../public/application/components/types.ts | 5 ++ 14 files changed, 323 insertions(+), 74 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/time_manipulation.ts diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/index.ts index 7b20b8f7504a2e..8b8cadac70c48e 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/index.ts @@ -6,4 +6,5 @@ */ export { setupEnvironment, WithAppDependencies, kibanaVersion } from './setup_environment'; +export { advanceTime } from './time_manipulation'; export { kibanaDeprecationsServiceHelpers } from './kibana_deprecations_service.mock'; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/time_manipulation.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/time_manipulation.ts new file mode 100644 index 00000000000000..65cec195497361 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/time_manipulation.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act } from 'react-dom/test-utils'; + +/** + * These helpers are intended to be used in conjunction with jest.useFakeTimers(). + */ + +const flushPromiseJobQueue = async () => { + // See https://stackoverflow.com/questions/52177631/jest-timer-and-promise-dont-work-well-settimeout-and-async-function + await Promise.resolve(); +}; + +export const advanceTime = async (ms: number) => { + await act(async () => { + jest.advanceTimersByTime(ms); + await flushPromiseJobQueue(); + }); +}; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/backup_step/backup_step.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/backup_step/backup_step.test.tsx index 39a94ec458be4c..3dcc55adbe61d0 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/backup_step/backup_step.test.tsx +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/backup_step/backup_step.test.tsx @@ -5,9 +5,8 @@ * 2.0. */ -import { act } from 'react-dom/test-utils'; - -import { setupEnvironment } from '../../helpers'; +import { CLOUD_BACKUP_STATUS_POLL_INTERVAL_MS } from '../../../../common/constants'; +import { setupEnvironment, advanceTime } from '../../helpers'; import { OverviewTestBed, setupOverviewPage } from '../overview.helpers'; describe('Overview - Backup Step', () => { @@ -34,6 +33,11 @@ describe('Overview - Backup Step', () => { expect(exists('snapshotRestoreLink')).toBe(true); expect(find('snapshotRestoreLink').props().href).toBe('snapshotAndRestoreUrl'); }); + + test('renders step as incomplete ', () => { + const { exists } = testBed; + expect(exists('backupStep-incomplete')).toBe(true); + }); }); describe('On Cloud', () => { @@ -104,6 +108,11 @@ describe('Overview - Backup Step', () => { expect(exists('cloudSnapshotsLink')).toBe(true); expect(find('dataBackedUpStatus').text()).toContain('Last snapshot created on'); }); + + test('renders step as complete ', () => { + const { exists } = testBed; + expect(exists('backupStep-complete')).toBe(true); + }); }); describe(`when data isn't backed up`, () => { @@ -121,24 +130,47 @@ describe('Overview - Backup Step', () => { expect(exists('dataNotBackedUpStatus')).toBe(true); expect(exists('cloudSnapshotsLink')).toBe(true); }); + + test('renders step as incomplete ', () => { + const { exists } = testBed; + expect(exists('backupStep-incomplete')).toBe(true); + }); }); + }); - // FLAKY: https://github.com/elastic/kibana/issues/111255 - test.skip('polls for new status', async () => { - // The behavior we're testing involves state changes over time, so we need finer control over - // timing. + describe('poll for new status', () => { + beforeEach(async () => { jest.useFakeTimers(); - testBed = await setupCloudOverviewPage(); - expect(server.requests.length).toBe(4); - // Resolve the polling timeout. - await act(async () => { - jest.runAllTimers(); + // First request will succeed. + httpRequestsMockHelpers.setLoadCloudBackupStatusResponse({ + isBackedUp: true, + lastBackupTime: '2021-08-25T19:59:59.863Z', }); - expect(server.requests.length).toBe(5); + testBed = await setupCloudOverviewPage(); + }); + + afterEach(() => { jest.useRealTimers(); }); + + test('renders step as incomplete when a success state is followed by an error state', async () => { + const { exists } = testBed; + expect(exists('backupStep-complete')).toBe(true); + + // Second request will error. + httpRequestsMockHelpers.setLoadCloudBackupStatusResponse(undefined, { + statusCode: 400, + message: 'error', + }); + + // Resolve the polling timeout. + await advanceTime(CLOUD_BACKUP_STATUS_POLL_INTERVAL_MS); + testBed.component.update(); + + expect(exists('backupStep-incomplete')).toBe(true); + }); }); }); }); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_issues_step/fix_issues_step.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_issues_step/fix_issues_step.test.tsx index 77d3862b9e9628..0b572ab41deaa0 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_issues_step/fix_issues_step.test.tsx +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_issues_step/fix_issues_step.test.tsx @@ -44,6 +44,37 @@ describe('Overview - Fix deprecation issues step', () => { server.restore(); }); + describe('Step status', () => { + test(`It's complete when there are no critical deprecations`, async () => { + httpRequestsMockHelpers.setLoadEsDeprecationsResponse(esDeprecationsEmpty); + + await act(async () => { + const deprecationService = deprecationsServiceMock.createStartContract(); + deprecationService.getAllDeprecations = jest.fn().mockRejectedValue([]); + + testBed = await setupOverviewPage({ + services: { + core: { + deprecations: deprecationService, + }, + }, + }); + }); + + const { exists, component } = testBed; + + component.update(); + + expect(exists(`fixIssuesStep-complete`)).toBe(true); + }); + + test(`It's incomplete when there are critical deprecations`, async () => { + const { exists } = testBed; + + expect(exists(`fixIssuesStep-incomplete`)).toBe(true); + }); + }); + describe('ES deprecations', () => { test('Shows deprecation warning and critical counts', () => { const { exists, find } = testBed; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_logs_step/fix_logs_step.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_logs_step/fix_logs_step.test.tsx index dec34ba1e37203..acc64e2872642d 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_logs_step/fix_logs_step.test.tsx +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_logs_step/fix_logs_step.test.tsx @@ -33,14 +33,49 @@ describe('Overview - Fix deprecation logs step', () => { server.restore(); }); + describe('Step status', () => { + test(`It's complete when there are no deprecation logs since last checkpoint`, async () => { + httpRequestsMockHelpers.setUpdateDeprecationLoggingResponse(getLoggingResponse(true)); + + httpRequestsMockHelpers.setLoadDeprecationLogsCountResponse({ + count: 0, + }); + + await act(async () => { + testBed = await setupOverviewPage(); + }); + + const { exists, component } = testBed; + + component.update(); + + expect(exists(`fixLogsStep-complete`)).toBe(true); + }); + + test(`It's incomplete when there are deprecation logs since last checkpoint`, async () => { + httpRequestsMockHelpers.setUpdateDeprecationLoggingResponse(getLoggingResponse(true)); + + httpRequestsMockHelpers.setLoadDeprecationLogsCountResponse({ + count: 5, + }); + + await act(async () => { + testBed = await setupOverviewPage(); + }); + + const { exists, component } = testBed; + + component.update(); + + expect(exists(`fixLogsStep-incomplete`)).toBe(true); + }); + }); + describe('Step 1 - Toggle log writing and collecting', () => { test('toggles deprecation logging', async () => { const { find, actions } = testBed; - httpRequestsMockHelpers.setUpdateDeprecationLoggingResponse({ - isDeprecationLogIndexingEnabled: false, - isDeprecationLoggingEnabled: false, - }); + httpRequestsMockHelpers.setUpdateDeprecationLoggingResponse(getLoggingResponse(false)); expect(find('deprecationLoggingToggle').props()['aria-checked']).toBe(true); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/backup_step/backup_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/backup_step/backup_step.tsx index b85f166e413f58..46b11aee15b33d 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/backup_step/backup_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/backup_step/backup_step.tsx @@ -11,33 +11,34 @@ import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; import type { CloudSetup } from '../../../../../../cloud/public'; import { OnPremBackup } from './on_prem_backup'; -import { CloudBackup, CloudBackupStatusResponse } from './cloud_backup'; +import { CloudBackup } from './cloud_backup'; +import type { OverviewStepProps } from '../../types'; const title = i18n.translate('xpack.upgradeAssistant.overview.backupStepTitle', { defaultMessage: 'Back up your data', }); -interface Props { +interface Props extends OverviewStepProps { cloud?: CloudSetup; - cloudBackupStatusResponse?: CloudBackupStatusResponse; } -export const getBackupStep = ({ cloud, cloudBackupStatusResponse }: Props): EuiStepProps => { +export const getBackupStep = ({ cloud, isComplete, setIsComplete }: Props): EuiStepProps => { + const status = isComplete ? 'complete' : 'incomplete'; + if (cloud?.isCloudEnabled) { return { + status, title, - status: cloudBackupStatusResponse!.data?.isBackedUp ? 'complete' : 'incomplete', + 'data-test-subj': `backupStep-${status}`, children: ( - + ), }; } return { title, + 'data-test-subj': 'backupStep-incomplete', status: 'incomplete', children: , }; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/backup_step/cloud_backup.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/backup_step/cloud_backup.tsx index e73cfaab8b2b64..abef34a27f30fd 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/backup_step/cloud_backup.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/backup_step/cloud_backup.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { useEffect } from 'react'; import moment from 'moment-timezone'; import { FormattedDate, FormattedTime, FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; @@ -20,22 +20,39 @@ import { EuiCallOut, } from '@elastic/eui'; -import { CloudBackupStatus } from '../../../../../common/types'; -import { UseRequestResponse } from '../../../../shared_imports'; -import { ResponseError } from '../../../lib/api'; - -export type CloudBackupStatusResponse = UseRequestResponse; +import { useAppContext } from '../../../app_context'; interface Props { - cloudBackupStatusResponse: UseRequestResponse; cloudSnapshotsUrl: string; + setIsComplete: (isComplete: boolean) => void; } export const CloudBackup: React.FunctionComponent = ({ - cloudBackupStatusResponse, cloudSnapshotsUrl, + setIsComplete, }) => { - const { isInitialRequest, isLoading, error, data, resendRequest } = cloudBackupStatusResponse; + const { + services: { api }, + } = useAppContext(); + + const { + isInitialRequest, + isLoading, + error, + data, + resendRequest, + } = api.useLoadCloudBackupStatus(); + + // Tell overview whether the step is complete or not. + useEffect(() => { + // Loading shouldn't invalidate the previous state. + if (!isLoading) { + // An error should invalidate the previous state. + setIsComplete((!error && data?.isBackedUp) ?? false); + } + // Depending upon setIsComplete would create an infinite loop. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [error, isLoading, data]); if (isInitialRequest && isLoading) { return ; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/es_stats/es_stats.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/es_stats/es_stats.tsx index a55f22c8dfda4d..7d0dcacfaa2075 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/es_stats/es_stats.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/es_stats/es_stats.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FunctionComponent } from 'react'; +import React, { FunctionComponent, useEffect, useMemo } from 'react'; import { useHistory } from 'react-router-dom'; import { EuiStat, EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiCard } from '@elastic/eui'; @@ -35,7 +35,11 @@ const i18nTexts = { ), }; -export const ESDeprecationStats: FunctionComponent = () => { +interface Props { + setIsFixed: (isFixed: boolean) => void; +} + +export const ESDeprecationStats: FunctionComponent = ({ setIsFixed }) => { const history = useHistory(); const { services: { api }, @@ -43,10 +47,21 @@ export const ESDeprecationStats: FunctionComponent = () => { const { data: esDeprecations, isLoading, error } = api.useLoadEsDeprecations(); - const warningDeprecations = - esDeprecations?.deprecations?.filter((deprecation) => deprecation.isCritical === false) || []; - const criticalDeprecations = - esDeprecations?.deprecations?.filter((deprecation) => deprecation.isCritical) || []; + const warningDeprecations = useMemo( + () => + esDeprecations?.deprecations?.filter((deprecation) => deprecation.isCritical === false) || [], + [esDeprecations] + ); + const criticalDeprecations = useMemo( + () => esDeprecations?.deprecations?.filter((deprecation) => deprecation.isCritical) || [], + [esDeprecations] + ); + + useEffect(() => { + if (!isLoading && !error) { + setIsFixed(criticalDeprecations.length === 0); + } + }, [setIsFixed, criticalDeprecations, isLoading, error]); const hasWarnings = warningDeprecations.length > 0; const hasCritical = criticalDeprecations.length > 0; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/fix_issues_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/fix_issues_step.tsx index f235075350e66e..df9bf58198d9d8 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/fix_issues_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/fix_issues_step.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { FunctionComponent, useState, useEffect } from 'react'; import { EuiText, EuiFlexItem, EuiFlexGroup, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -13,6 +13,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; import { ESDeprecationStats } from './es_stats'; import { KibanaDeprecationStats } from './kibana_stats'; +import type { OverviewStepProps } from '../../types'; import './_fix_issues_step.scss'; @@ -22,10 +23,49 @@ const i18nTexts = { }), }; -export const getFixIssuesStep = ({ nextMajor }: { nextMajor: number }): EuiStepProps => { +interface Props { + setIsComplete: OverviewStepProps['setIsComplete']; +} + +interface StepProps extends OverviewStepProps { + nextMajor: number; +} + +const FixIssuesStep: FunctionComponent = ({ setIsComplete }) => { + // We consider ES and Kibana issues to be fixed when there are 0 critical issues. + const [isEsFixed, setIsEsFixed] = useState(false); + const [isKibanaFixed, setIsKibanaFixed] = useState(false); + + useEffect(() => { + setIsComplete(isEsFixed && isKibanaFixed); + // Depending upon setIsComplete would create an infinite loop. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isEsFixed, isKibanaFixed]); + + return ( + + + + + + + + + + ); +}; + +export const getFixIssuesStep = ({ + nextMajor, + isComplete, + setIsComplete, +}: StepProps): EuiStepProps => { + const status = isComplete ? 'complete' : 'incomplete'; + return { title: i18nTexts.reviewStepTitle, - status: 'incomplete', + status, + 'data-test-subj': `fixIssuesStep-${status}`, children: ( <> @@ -40,15 +80,7 @@ export const getFixIssuesStep = ({ nextMajor }: { nextMajor: number }): EuiStepP - - - - - - - - - + ), }; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/kibana_stats/kibana_stats.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/kibana_stats/kibana_stats.tsx index 28e60e7e735fb4..2cfc555116ba6f 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/kibana_stats/kibana_stats.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/kibana_stats/kibana_stats.tsx @@ -41,7 +41,11 @@ const i18nTexts = { ), }; -export const KibanaDeprecationStats: FunctionComponent = () => { +interface Props { + setIsFixed: (isFixed: boolean) => void; +} + +export const KibanaDeprecationStats: FunctionComponent = ({ setIsFixed }) => { const history = useHistory(); const { services: { @@ -77,6 +81,12 @@ export const KibanaDeprecationStats: FunctionComponent = () => { const criticalDeprecationsCount = kibanaDeprecations?.filter((deprecation) => deprecation.level === 'critical')?.length ?? 0; + useEffect(() => { + if (!isLoading && !error) { + setIsFixed(criticalDeprecationsCount === 0); + } + }, [setIsFixed, criticalDeprecationsCount, isLoading, error]); + const hasCritical = criticalDeprecationsCount > 0; const hasWarnings = warningDeprecationsCount > 0; const hasNoDeprecations = !isLoading && !error && !hasWarnings && !hasCritical; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_logs_step/deprecations_count_checkpoint/deprecations_count_checkpoint.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_logs_step/deprecations_count_checkpoint/deprecations_count_checkpoint.tsx index 58b7b7ca11ebd6..f0a4096687f6ca 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_logs_step/deprecations_count_checkpoint/deprecations_count_checkpoint.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_logs_step/deprecations_count_checkpoint/deprecations_count_checkpoint.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FunctionComponent, useState } from 'react'; +import React, { FunctionComponent, useState, useEffect } from 'react'; import moment from 'moment-timezone'; import { FormattedDate, FormattedTime, FormattedMessage } from '@kbn/i18n/react'; @@ -64,7 +64,13 @@ const getPreviousCheckpointDate = () => { return now; }; -export const DeprecationsCountCheckpoint: FunctionComponent = () => { +interface Props { + setHasNoDeprecationLogs: (hasNoLogs: boolean) => void; +} + +export const DeprecationsCountCheckpoint: FunctionComponent = ({ + setHasNoDeprecationLogs, +}) => { const { services: { api }, } = useAppContext(); @@ -73,10 +79,11 @@ export const DeprecationsCountCheckpoint: FunctionComponent = () => { previousCheck ); - const warningsCount = data?.count || 0; - const calloutTint = warningsCount > 0 ? 'warning' : 'success'; - const calloutIcon = warningsCount > 0 ? 'alert' : 'check'; - const calloutTestId = warningsCount > 0 ? 'hasWarningsCallout' : 'noWarningsCallout'; + const logsCount = data?.count || 0; + const hasLogs = logsCount > 0; + const calloutTint = hasLogs ? 'warning' : 'success'; + const calloutIcon = hasLogs ? 'alert' : 'check'; + const calloutTestId = hasLogs ? 'hasWarningsCallout' : 'noWarningsCallout'; const onResetClick = () => { const now = moment().toISOString(); @@ -85,6 +92,16 @@ export const DeprecationsCountCheckpoint: FunctionComponent = () => { localStorage.set(LS_SETTING_ID, now); }; + useEffect(() => { + // Loading shouldn't invalidate the previous state. + if (!isLoading) { + // An error should invalidate the previous state. + setHasNoDeprecationLogs(!error && !hasLogs); + } + // Depending upon setHasNoDeprecationLogs would create an infinite loop. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [error, isLoading, hasLogs]); + if (isInitialRequest && isLoading) { return ; } @@ -109,7 +126,7 @@ export const DeprecationsCountCheckpoint: FunctionComponent = () => { return ( { +interface Props { + setIsComplete: OverviewStepProps['setIsComplete']; +} + +const FixLogsStep: FunctionComponent = ({ setIsComplete }) => { const state = useDeprecationLogging(); return ( @@ -88,17 +93,20 @@ const FixLogsStep: FunctionComponent = () => {

{i18nTexts.deprecationsCountCheckpointTitle}

- + )} ); }; -export const getFixLogsStep = (): EuiStepProps => { +export const getFixLogsStep = ({ isComplete, setIsComplete }: OverviewStepProps): EuiStepProps => { + const status = isComplete ? 'complete' : 'incomplete'; + return { + status, title: i18nTexts.identifyStepTitle, - status: 'incomplete', - children: , + 'data-test-subj': `fixLogsStep-${status}`, + children: , }; }; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx index 1c11bc165d931c..010c9b73671589 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FunctionComponent, useEffect } from 'react'; +import React, { FunctionComponent, useEffect, useState } from 'react'; import { EuiSteps, @@ -26,6 +26,8 @@ import { getFixIssuesStep } from './fix_issues_step'; import { getFixLogsStep } from './fix_logs_step'; import { getUpgradeStep } from './upgrade_step'; +type OverviewStep = 'backup' | 'fix_issues' | 'fix_logs'; + export const Overview: FunctionComponent = () => { const { kibanaVersionInfo: { nextMajor }, @@ -51,11 +53,19 @@ export const Overview: FunctionComponent = () => { breadcrumbs.setBreadcrumbs('overview'); }, [breadcrumbs]); - let cloudBackupStatusResponse; + const [completedStepsMap, setCompletedStepsMap] = useState({ + backup: false, + fix_issues: false, + fix_logs: false, + }); - if (cloud?.isCloudEnabled) { - cloudBackupStatusResponse = api.useLoadCloudBackupStatus(); - } + const isStepComplete = (step: OverviewStep) => completedStepsMap[step]; + const setCompletedStep = (step: OverviewStep, isCompleted: boolean) => { + setCompletedStepsMap({ + ...completedStepsMap, + [step]: isCompleted, + }); + }; return ( @@ -97,9 +107,20 @@ export const Overview: FunctionComponent = () => { diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/types.ts b/x-pack/plugins/upgrade_assistant/public/application/components/types.ts index 81495c45420bfc..6b52f7cece514b 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/types.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/types.ts @@ -31,3 +31,8 @@ export interface DeprecationLoggingPreviewProps { resendRequest: () => void; toggleLogging: () => void; } + +export interface OverviewStepProps { + isComplete: boolean; + setIsComplete: (isComplete: boolean) => void; +}