From 5e175475dcfc108f8bb7c4c82b9120201035460c Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 18 Aug 2021 13:59:20 -0400 Subject: [PATCH 01/18] wip - new kibana deprecations list design --- .../kibana_deprecations.tsx | 60 +++---- .../kibana_deprecations_table.tsx | 156 ++++++++++++++++++ .../public/application/lib/breadcrumbs.ts | 2 +- 3 files changed, 187 insertions(+), 31 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx index 56d6e23d9d4f3..9912fc16fb9b2 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx @@ -8,27 +8,39 @@ import React, { useEffect, useState, useCallback } from 'react'; import { withRouter, RouteComponentProps } from 'react-router-dom'; -import { EuiButtonEmpty, EuiPageContent, EuiPageHeader, EuiSpacer } from '@elastic/eui'; +import { EuiPageContent, EuiPageHeader, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; import type { DomainDeprecationDetails } from 'kibana/public'; import { SectionLoading } from '../../../shared_imports'; import { useAppContext } from '../../app_context'; import { NoDeprecationsPrompt } from '../shared'; -import { KibanaDeprecationList } from './deprecation_list'; +import { LEVEL_MAP } from '../constants'; import { StepsModal, StepsModalContent } from './steps_modal'; import { KibanaDeprecationErrors } from './kibana_deprecation_errors'; import { ResolveDeprecationModal } from './resolve_deprecation_modal'; -import { LEVEL_MAP } from '../constants'; +import { KibanaDeprecationsTable } from './kibana_deprecations_table'; const i18nTexts = { pageTitle: i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.pageTitle', { - defaultMessage: 'Kibana', - }), - pageDescription: i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.pageDescription', { - defaultMessage: - 'Review the issues listed here and make the necessary changes before upgrading. Critical issues must be resolved before you upgrade.', + defaultMessage: 'Kibana deprecation warnings', }), + pageDescription: ( + + {i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.quickResolveText', { + defaultMessage: 'Quick Resolve', + })} + + ), + }} + /> + ), docLinkText: i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.docLinkText', { defaultMessage: 'Documentation', }), @@ -64,7 +76,7 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent >(undefined); const [isResolvingDeprecation, setIsResolvingDeprecation] = useState(false); - const { deprecations, breadcrumbs, docLinks, api, notifications } = useAppContext(); + const { deprecations, breadcrumbs, api, notifications } = useAppContext(); const getAllDeprecations = useCallback(async () => { setIsLoading(true); @@ -145,36 +157,22 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent {i18nTexts.isLoading} ); - } else if (kibanaDeprecations?.length) { + } + + if (kibanaDeprecations?.length) { return (
- {i18nTexts.docLinkText} - , - ]} /> - + - {stepsModalContent && ( + {/* {stepsModalContent && ( toggleStepsModal()} modalContent={stepsModalContent} /> )} @@ -185,10 +183,12 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent isResolvingDeprecation={isResolvingDeprecation} deprecation={resolveModalContent} /> - )} + )} */}
); - } else if (error) { + } + + if (error) { return ; } diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx new file mode 100644 index 0000000000000..b3b31c238c6d6 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -0,0 +1,156 @@ +/* + * 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 React from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiInMemoryTable, + EuiBasicTableColumn, + EuiButton, + EuiLink, + EuiBadge, +} from '@elastic/eui'; + +import type { DomainDeprecationDetails } from 'kibana/public'; + +const i18nTexts = { + refreshButtonLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.refreshButtonLabel', + { + defaultMessage: 'Refresh', + } + ), + statusColumnTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.statusColumnTitle', + { + defaultMessage: 'Status', + } + ), + issueColumnTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.issueColumnTitle', + { + defaultMessage: 'Issue', + } + ), + getDeprecationIssue: (domainId: string) => { + return i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.table.issueCellDescription', { + defaultMessage: '{domainId} is using a deprecated feature', + values: { + domainId, + }, + }); + }, + criticalBadgeLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.criticalBadgeLabel', + { + defaultMessage: 'critical', + } + ), + searchPlaceholderLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.searchPlaceholderLabel', + { + defaultMessage: 'Filter', + } + ), +}; + +interface Props { + deprecations?: DomainDeprecationDetails[]; + reload: () => void; +} + +export const KibanaDeprecationsTable: React.FunctionComponent = ({ + deprecations, + reload, +}) => { + const columns: Array> = [ + { + field: 'level', + name: i18nTexts.statusColumnTitle, + width: '5%', + truncateText: true, + sortable: true, + render: (level: DomainDeprecationDetails['level']) => { + if (level === 'critical') { + return {i18nTexts.criticalBadgeLabel}; + } + + return <>{''}; + }, + }, + { + field: 'domainId', + width: '95%', + name: i18nTexts.issueColumnTitle, + truncateText: true, + sortable: true, + render: (domainId: DomainDeprecationDetails['domainId']) => { + // TODO update to handle opening flyout + return {i18nTexts.getDeprecationIssue(domainId)}; + }, + }, + ]; + + const pagination = { + initialPageSize: 50, + pageSizeOptions: [50, 100, 200], + }; + + const sorting = { + sort: { + field: 'level', + direction: 'asc', + }, + } as const; + + const searchConfig = { + // TODO fix + // query: {}, + filters: [ + { + type: 'is', + field: 'level', + name: i18n.translate('xpack.idxMgmt.componentTemplatesList.table.isManagedFilterLabel', { + defaultMessage: 'Critical', + }), + }, + ], + box: { + incremental: true, + placeholder: i18nTexts.searchPlaceholderLabel, + }, + toolsRight: [ + + {i18nTexts.refreshButtonLabel} + , + ], + }; + + return ( + ({ + 'data-test-subj': 'row', + })} + cellProps={() => ({ + 'data-test-subj': 'cell', + })} + data-test-subj="kibanaDeprecationsTable" + tableLayout="auto" + /> + ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/lib/breadcrumbs.ts b/x-pack/plugins/upgrade_assistant/public/application/lib/breadcrumbs.ts index f36dc2096ddc7..1beb759442f9f 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/lib/breadcrumbs.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/lib/breadcrumbs.ts @@ -21,7 +21,7 @@ const i18nTexts = { kibanaDeprecations: i18n.translate( 'xpack.upgradeAssistant.breadcrumb.kibanaDeprecationsLabel', { - defaultMessage: 'Kibana deprecations', + defaultMessage: 'Kibana deprecation warnings', } ), }, From a51056ded7538b5fae71be0ade59b78b8e0c5d89 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 18 Aug 2021 15:35:22 -0400 Subject: [PATCH 02/18] implement flyout --- .../public/application/app.tsx | 3 +- .../deprecation_details_flyout.tsx | 163 ++++++++++++++++++ .../kibana_deprecations.tsx | 113 ++++++------ .../kibana_deprecations_table.tsx | 7 +- 4 files changed, 230 insertions(+), 56 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx diff --git a/x-pack/plugins/upgrade_assistant/public/application/app.tsx b/x-pack/plugins/upgrade_assistant/public/application/app.tsx index 864be6e5d996d..365913debeafd 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/app.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/app.tsx @@ -9,8 +9,8 @@ import React from 'react'; import { Router, Switch, Route, Redirect } from 'react-router-dom'; import { I18nStart, ScopedHistory } from 'src/core/public'; import { ApplicationStart } from 'kibana/public'; +import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public'; import { GlobalFlyout } from '../shared_imports'; - import { KibanaContextProvider } from '../shared_imports'; import { AppServicesContext } from '../types'; import { AppContextProvider, ContextValue, useAppContext } from './app_context'; @@ -18,7 +18,6 @@ import { ComingSoonPrompt } from './components/coming_soon_prompt'; import { EsDeprecations } from './components/es_deprecations'; import { KibanaDeprecationsContent } from './components/kibana_deprecations'; import { Overview } from './components/overview'; -import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public'; const { GlobalFlyoutProvider } = GlobalFlyout; export interface AppDependencies extends ContextValue { diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx new file mode 100644 index 0000000000000..47f821cbfdf6b --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx @@ -0,0 +1,163 @@ +/* + * 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 React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { + EuiButtonEmpty, + EuiButton, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiFlexGroup, + EuiFlexItem, + EuiTitle, + EuiText, + EuiCallOut, + EuiLink, + EuiSpacer, +} from '@elastic/eui'; + +import type { DomainDeprecationDetails } from 'kibana/public'; + +export interface DeprecationDetailsFlyoutProps { + deprecation: DomainDeprecationDetails; + closeFlyout: () => void; +} + +const i18nTexts = { + learnMoreLinkLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.learnMoreLinkLabel', + { + defaultMessage: 'Learn more about this deprecation', + } + ), + closeButtonLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.closeButtonLabel', + { + defaultMessage: 'Close', + } + ), + quickResolveButtonLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.quickResolveButtonLabel', + { + defaultMessage: 'Quick resolve', + } + ), + quickResolveCalloutTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.quickResolveCalloutTitle', + { + defaultMessage: 'Quick resolve action available', + } + ), + quickResolveCalloutDescription: ( + + {i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.flyout.quickResolveText', { + defaultMessage: 'Quick resolve', + })} + + ), + }} + /> + ), + manualFixTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.manualFixTitle', + { + defaultMessage: 'Fix manually', + } + ), +}; + +export const DeprecationDetailsFlyout = ({ + deprecation, + closeFlyout, +}: DeprecationDetailsFlyoutProps) => { + const { documentationUrl, message, correctiveActions } = deprecation; + + return ( + <> + + +

Deprecation title goes here...

+
+
+ + +

{message}

+ + {documentationUrl && ( +

+ + {i18nTexts.learnMoreLinkLabel} + +

+ )} +
+ + + + {correctiveActions.api && ( + <> + +

{i18nTexts.quickResolveCalloutDescription}

+
+ + + + )} + + +

{i18nTexts.manualFixTitle}

+
+ + + + +
    + {correctiveActions.manualSteps.map((step, stepIndex) => ( + // TODO temp inline style +
  1. + {step} +
  2. + ))} +
+
+
+ + + + + {i18nTexts.closeButtonLabel} + + + + {/* Only show the Quick resolve button if deprecation supports it */} + {correctiveActions.api && ( + + {/* TODO implement onClick */} + {}}> + {i18nTexts.quickResolveButtonLabel} + + + )} + + + + ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx index 9912fc16fb9b2..e22a8d72ddba6 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx @@ -13,14 +13,17 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import type { DomainDeprecationDetails } from 'kibana/public'; -import { SectionLoading } from '../../../shared_imports'; +import { SectionLoading, GlobalFlyout } from '../../../shared_imports'; import { useAppContext } from '../../app_context'; import { NoDeprecationsPrompt } from '../shared'; -import { LEVEL_MAP } from '../constants'; -import { StepsModal, StepsModalContent } from './steps_modal'; import { KibanaDeprecationErrors } from './kibana_deprecation_errors'; -import { ResolveDeprecationModal } from './resolve_deprecation_modal'; import { KibanaDeprecationsTable } from './kibana_deprecations_table'; +import { + DeprecationDetailsFlyout, + DeprecationDetailsFlyoutProps, +} from './deprecation_details_flyout'; + +const { useGlobalFlyout } = GlobalFlyout; const i18nTexts = { pageTitle: i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.pageTitle', { @@ -58,33 +61,25 @@ const i18nTexts = { }), }; -const sortByLevelDesc = (a: DomainDeprecationDetails, b: DomainDeprecationDetails) => { - return -1 * (LEVEL_MAP[a.level] - LEVEL_MAP[b.level]); -}; - export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponentProps) => { const [kibanaDeprecations, setKibanaDeprecations] = useState< DomainDeprecationDetails[] | undefined >(undefined); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(undefined); - const [stepsModalContent, setStepsModalContent] = useState( + const [flyoutContent, setFlyoutContent] = useState( undefined ); - const [resolveModalContent, setResolveModalContent] = useState< - undefined | DomainDeprecationDetails - >(undefined); - const [isResolvingDeprecation, setIsResolvingDeprecation] = useState(false); + // const [isResolvingDeprecation, setIsResolvingDeprecation] = useState(false); - const { deprecations, breadcrumbs, api, notifications } = useAppContext(); + const { deprecations, breadcrumbs, api } = useAppContext(); const getAllDeprecations = useCallback(async () => { setIsLoading(true); try { const response = await deprecations.getAllDeprecations(); - const sortedDeprecations = response.sort(sortByLevelDesc); - setKibanaDeprecations(sortedDeprecations); + setKibanaDeprecations(response); } catch (e) { setError(e); } @@ -92,35 +87,60 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent setIsLoading(false); }, [deprecations]); - const toggleStepsModal = (newStepsModalContent?: StepsModalContent) => { - setStepsModalContent(newStepsModalContent); + const toggleFlyout = (newFlyoutContent?: DomainDeprecationDetails) => { + setFlyoutContent(newFlyoutContent); }; - const toggleResolveModal = (newResolveModalContent?: DomainDeprecationDetails) => { - setResolveModalContent(newResolveModalContent); - }; + const { + addContent: addContentToGlobalFlyout, + removeContent: removeContentFromGlobalFlyout, + } = useGlobalFlyout(); - const resolveDeprecation = async (deprecationDetails: DomainDeprecationDetails) => { - setIsResolvingDeprecation(true); + const closeFlyout = useCallback(() => { + toggleFlyout(); + removeContentFromGlobalFlyout('deprecationDetails'); + }, [removeContentFromGlobalFlyout]); - const response = await deprecations.resolveDeprecation(deprecationDetails); + useEffect(() => { + if (flyoutContent) { + addContentToGlobalFlyout({ + id: 'deprecationDetails', + Component: DeprecationDetailsFlyout, + props: { + deprecation: flyoutContent, + closeFlyout, + }, + flyoutProps: { + onClose: closeFlyout, + 'data-test-subj': 'kibanaDeprecationDetails', + 'aria-labelledby': 'kibanaDeprecationDetailsFlyoutTitle', + }, + }); + } + }, [addContentToGlobalFlyout, closeFlyout, flyoutContent]); - setIsResolvingDeprecation(false); - toggleResolveModal(); + // TODO finish implementing + // const resolveDeprecation = async (deprecationDetails: DomainDeprecationDetails) => { + // setIsResolvingDeprecation(true); - // Handle error case - if (response.status === 'fail') { - notifications.toasts.addError(new Error(response.reason), { - title: i18nTexts.errorMessage, - }); + // const response = await deprecations.resolveDeprecation(deprecationDetails); - return; - } + // setIsResolvingDeprecation(false); + // // toggleResolveModal(); - notifications.toasts.addSuccess(i18nTexts.successMessage); - // Refetch deprecations - getAllDeprecations(); - }; + // // Handle error case + // if (response.status === 'fail') { + // notifications.toasts.addError(new Error(response.reason), { + // title: i18nTexts.errorMessage, + // }); + + // return; + // } + + // notifications.toasts.addSuccess(i18nTexts.successMessage); + // // Refetch deprecations + // getAllDeprecations(); + // }; useEffect(() => { async function sendTelemetryData() { @@ -170,20 +190,11 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent - - - {/* {stepsModalContent && ( - toggleStepsModal()} modalContent={stepsModalContent} /> - )} - - {resolveModalContent && ( - toggleResolveModal()} - resolveDeprecation={resolveDeprecation} - isResolvingDeprecation={isResolvingDeprecation} - deprecation={resolveModalContent} - /> - )} */} + ); } diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index b3b31c238c6d6..b37c4b0725a52 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -60,11 +60,13 @@ const i18nTexts = { interface Props { deprecations?: DomainDeprecationDetails[]; reload: () => void; + toggleFlyout: (newFlyoutContent?: DomainDeprecationDetails) => void; } export const KibanaDeprecationsTable: React.FunctionComponent = ({ deprecations, reload, + toggleFlyout }) => { const columns: Array> = [ { @@ -87,9 +89,8 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ name: i18nTexts.issueColumnTitle, truncateText: true, sortable: true, - render: (domainId: DomainDeprecationDetails['domainId']) => { - // TODO update to handle opening flyout - return {i18nTexts.getDeprecationIssue(domainId)}; + render: (domainId: DomainDeprecationDetails['domainId'], deprecation: DomainDeprecationDetails) => { + return toggleFlyout(deprecation)}>{i18nTexts.getDeprecationIssue(domainId)}; }, }, ]; From 33147ad21b0348d4dc3af060d1e6d34e6f1853c7 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 25 Aug 2021 12:52:48 -0400 Subject: [PATCH 03/18] added resolution and type columns --- .../kibana_deprecations_table.tsx | 149 +++++++++++++++++- 1 file changed, 145 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index b37c4b0725a52..5a8484e2a8c8a 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -12,6 +12,11 @@ import { EuiButton, EuiLink, EuiBadge, + EuiToolTip, + EuiText, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, } from '@elastic/eui'; import type { DomainDeprecationDetails } from 'kibana/public'; @@ -35,6 +40,66 @@ const i18nTexts = { defaultMessage: 'Issue', } ), + typeColumnTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.typeColumnTitle', + { + defaultMessage: 'Type', + } + ), + resolutionColumnTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.resolutionColumnTitle', + { + defaultMessage: 'Resolution', + } + ), + manualCellLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.manualCellLabel', + { + defaultMessage: 'Manual', + } + ), + manualCellTooltipLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.manualCellTooltipLabel', + { + defaultMessage: 'Resolve this deprecation manually.', + } + ), + automatedCellLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.automatedCellLabel', + { + defaultMessage: 'Automated', + } + ), + configDeprecationTypeCellLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.configDeprecationTypeCellLabel', + { + defaultMessage: 'Config', + } + ), + featureDeprecationTypeCellLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.featureDeprecationTypeCellLabel', + { + defaultMessage: 'Feature', + } + ), + unknownDeprecationTypeCellLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.unknownDeprecationTypeCellLabel', + { + defaultMessage: 'Unknown', + } + ), + automatedCellTooltipLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.automatedCellTooltipLabel', + { + defaultMessage: 'This is an automated resolution.', + } + ), + typeFilterLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.typeFilterLabel', + { + defaultMessage: 'Type', + } + ), getDeprecationIssue: (domainId: string) => { return i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.table.issueCellDescription', { defaultMessage: '{domainId} is using a deprecated feature', @@ -66,7 +131,7 @@ interface Props { export const KibanaDeprecationsTable: React.FunctionComponent = ({ deprecations, reload, - toggleFlyout + toggleFlyout, }) => { const columns: Array> = [ { @@ -85,12 +150,67 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ }, { field: 'domainId', - width: '95%', + width: '40%', name: i18nTexts.issueColumnTitle, truncateText: true, sortable: true, - render: (domainId: DomainDeprecationDetails['domainId'], deprecation: DomainDeprecationDetails) => { - return toggleFlyout(deprecation)}>{i18nTexts.getDeprecationIssue(domainId)}; + render: ( + domainId: DomainDeprecationDetails['domainId'], + deprecation: DomainDeprecationDetails + ) => { + return ( + toggleFlyout(deprecation)}> + {i18nTexts.getDeprecationIssue(domainId)} + + ); + }, + }, + { + field: 'deprecationType', + name: i18nTexts.typeColumnTitle, + width: '20%', + truncateText: true, + sortable: true, + render: (deprecationType: DomainDeprecationDetails['deprecationType']) => { + switch (deprecationType) { + case 'config': + return i18nTexts.configDeprecationTypeCellLabel; + case 'feature': + return i18nTexts.featureDeprecationTypeCellLabel; + default: + return i18nTexts.unknownDeprecationTypeCellLabel; + } + }, + }, + { + field: 'correctiveActions', + name: i18nTexts.resolutionColumnTitle, + width: '30%', + truncateText: true, + sortable: true, + render: (correctiveActions: DomainDeprecationDetails['correctiveActions']) => { + if (correctiveActions.api) { + return ( + + + + + + + {i18nTexts.automatedCellLabel} + + + + ); + } + + return ( + + + {i18nTexts.manualCellLabel} + + + ); }, }, ]; @@ -118,6 +238,27 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ defaultMessage: 'Critical', }), }, + { + type: 'field_value_selection', + field: 'deprecationType', + name: i18nTexts.typeFilterLabel, + multiSelect: false, + options: [ + { + value: 'config', + name: i18nTexts.configDeprecationTypeCellLabel, + }, + { + value: 'feature', + name: i18nTexts.featureDeprecationTypeCellLabel, + }, + // TODO not working yet + { + value: 'unknown', + name: i18nTexts.unknownDeprecationTypeCellLabel, + }, + ], + }, ], box: { incremental: true, From 8c3d65d6e3b6fa6d6be1e94eeb5b4a88ba44cf99 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Mon, 30 Aug 2021 12:50:49 -0400 Subject: [PATCH 04/18] implement quick resolve functionality + remove unused code --- .../public/application/app.tsx | 7 +- .../application/components/constants.tsx | 22 --- .../deprecation_list_bar => }/index.ts | 5 +- .../_deprecation_details_flyout.scss | 4 + .../deprecation_details_flyout.tsx | 148 +++++++++++++---- .../kibana_deprecations/deprecation_item.tsx | 145 ----------------- .../kibana_deprecations/deprecation_list.tsx | 150 ------------------ .../components/kibana_deprecations/index.ts | 2 +- .../kibana_deprecations.tsx | 101 +++++++----- .../kibana_deprecations_table.tsx | 90 +++-------- .../resolution_table_cell.tsx | 146 +++++++++++++++++ .../resolve_deprecation_modal.tsx | 64 -------- .../kibana_deprecations/steps_modal.tsx | 115 -------------- .../deprecation_list_bar/count_summary.tsx | 41 ----- .../deprecation_list_bar.tsx | 69 -------- .../shared/deprecation_pagination.tsx | 24 --- .../application/components/shared/health.tsx | 88 ---------- .../application/components/shared/index.ts | 4 - .../group_by_filter.test.tsx.snap | 24 --- .../__snapshots__/level_filter.test.tsx.snap | 19 --- .../search_bar/group_by_filter.test.tsx | 31 ---- .../shared/search_bar/group_by_filter.tsx | 54 ------- .../components/shared/search_bar/index.ts | 8 - .../shared/search_bar/level_filter.test.tsx | 34 ---- .../shared/search_bar/level_filter.tsx | 51 ------ .../shared/search_bar/search_bar.tsx | 141 ---------------- .../public/application/components/types.ts | 14 -- 27 files changed, 358 insertions(+), 1243 deletions(-) rename x-pack/plugins/upgrade_assistant/public/application/components/{shared/deprecation_list_bar => }/index.ts (54%) create mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/_deprecation_details_flyout.scss delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_item.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_list.tsx create mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolution_table_cell.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolve_deprecation_modal.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/steps_modal.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/count_summary.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/deprecation_list_bar.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_pagination.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/health.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/__snapshots__/group_by_filter.test.tsx.snap delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/__snapshots__/level_filter.test.tsx.snap delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/group_by_filter.test.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/group_by_filter.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/index.ts delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/level_filter.test.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/level_filter.tsx delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/search_bar.tsx diff --git a/x-pack/plugins/upgrade_assistant/public/application/app.tsx b/x-pack/plugins/upgrade_assistant/public/application/app.tsx index 28231d40ab889..a6954bffeb949 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/app.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/app.tsx @@ -13,10 +13,7 @@ import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public import { KibanaContextProvider, APP_WRAPPER_CLASS, GlobalFlyout } from '../shared_imports'; import { AppServicesContext } from '../types'; import { AppContextProvider, ContextValue, useAppContext } from './app_context'; -import { ComingSoonPrompt } from './components/coming_soon_prompt'; -import { EsDeprecations } from './components/es_deprecations'; -import { KibanaDeprecationsContent } from './components/kibana_deprecations'; -import { Overview } from './components/overview'; +import { EsDeprecations, ComingSoonPrompt, KibanaDeprecations, Overview } from './components'; const { GlobalFlyoutProvider } = GlobalFlyout; export interface AppDependencies extends ContextValue { @@ -38,7 +35,7 @@ const App: React.FunctionComponent = () => { - + ); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx index c7f974fab6a89..67cbe8bd91bfb 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx @@ -5,30 +5,8 @@ * 2.0. */ -import { IconColor } from '@elastic/eui'; -import { invert } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { DeprecationInfo } from '../../../common/types'; - -export const LEVEL_MAP: { [level: string]: number } = { - warning: 0, - critical: 1, -}; - -interface ReverseLevelMap { - [idx: number]: DeprecationInfo['level']; -} - -export const REVERSE_LEVEL_MAP: ReverseLevelMap = invert(LEVEL_MAP) as ReverseLevelMap; - -export const COLOR_MAP: { [level: string]: IconColor } = { - warning: 'default', - critical: 'danger', -}; - -export const DEPRECATIONS_PER_PAGE = 25; - export const DEPRECATION_TYPE_MAP = { cluster_settings: i18n.translate( 'xpack.upgradeAssistant.esDeprecations.clusterDeprecationTypeLabel', diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/index.ts similarity index 54% rename from x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/index.ts rename to x-pack/plugins/upgrade_assistant/public/application/components/index.ts index cbc04fd86bfbd..8924fa2d355a1 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/index.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/index.ts @@ -5,4 +5,7 @@ * 2.0. */ -export { DeprecationListBar } from './deprecation_list_bar'; +export { KibanaDeprecations } from './kibana_deprecations'; +export { EsDeprecations } from './es_deprecations'; +export { ComingSoonPrompt } from './coming_soon_prompt'; +export { Overview } from './overview'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/_deprecation_details_flyout.scss b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/_deprecation_details_flyout.scss new file mode 100644 index 0000000000000..c877ea4b48821 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/_deprecation_details_flyout.scss @@ -0,0 +1,4 @@ +// Used to add spacing between the list of manual deprecation steps +.upgResolveStep { + margin-bottom: $euiSizeL; +} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx index 47f821cbfdf6b..3fd9631dd72c3 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx @@ -24,14 +24,26 @@ import { EuiSpacer, } from '@elastic/eui'; -import type { DomainDeprecationDetails } from 'kibana/public'; +import type { DeprecationResolutionState, KibanaDeprecationDetails } from './kibana_deprecations'; + +import './_deprecation_details_flyout.scss'; export interface DeprecationDetailsFlyoutProps { - deprecation: DomainDeprecationDetails; + deprecation: KibanaDeprecationDetails; closeFlyout: () => void; + resolveDeprecation: (deprecationDetails: KibanaDeprecationDetails) => Promise; + deprecationResolutionState?: DeprecationResolutionState; } const i18nTexts = { + getDeprecationTitle: (domainId: string) => { + return i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.flyout.flyoutTitle', { + defaultMessage: "'{domainId}' is using a deprecated feature", + values: { + domainId, + }, + }); + }, learnMoreLinkLabel: i18n.translate( 'xpack.upgradeAssistant.kibanaDeprecations.flyout.learnMoreLinkLabel', { @@ -50,12 +62,36 @@ const i18nTexts = { defaultMessage: 'Quick resolve', } ), + retryQuickResolveButtonLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.retryQuickResolveButtonLabel', + { + defaultMessage: 'Try again', + } + ), + resolvedButtonLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.resolvedButtonLabel', + { + defaultMessage: 'Resolved', + } + ), + quickResolveInProgressButtonLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.quickResolveInProgressButtonLabel', + { + defaultMessage: 'Resolution in progress…', + } + ), quickResolveCalloutTitle: i18n.translate( 'xpack.upgradeAssistant.kibanaDeprecations.flyout.quickResolveCalloutTitle', { defaultMessage: 'Quick resolve action available', } ), + quickResolveErrorTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.flyout.quickResolveErrorTitle', + { + defaultMessage: 'Error resolving deprecation', + } + ), quickResolveCalloutDescription: ( { + if (deprecationResolutionState?.resolveDeprecationStatus === 'in_progress') { + return i18nTexts.quickResolveInProgressButtonLabel; + } + + if (deprecationResolutionState?.resolveDeprecationStatus === 'ok') { + return i18nTexts.resolvedButtonLabel; + } + + if (deprecationResolutionState?.resolveDeprecationError) { + return i18nTexts.retryQuickResolveButtonLabel; + } + + return i18nTexts.quickResolveButtonLabel; +}; + export const DeprecationDetailsFlyout = ({ deprecation, closeFlyout, + resolveDeprecation, + deprecationResolutionState, }: DeprecationDetailsFlyoutProps) => { - const { documentationUrl, message, correctiveActions } = deprecation; + const { documentationUrl, message, correctiveActions, domainId } = deprecation; return ( <> -

Deprecation title goes here...

+ {/* This will be replaced with a custom title once https://github.com/elastic/kibana/pull/109840 is merged */} +

{i18nTexts.getDeprecationTitle(domainId)}

+ {deprecationResolutionState?.resolveDeprecationStatus === 'fail' && ( + <> + + {deprecationResolutionState.resolveDeprecationError} + + + + )} +

{message}

@@ -107,38 +176,43 @@ export const DeprecationDetailsFlyout = ({ - {correctiveActions.api && ( + {/* Hide resolution steps if already resolved */} + {deprecationResolutionState?.resolveDeprecationStatus !== 'ok' && ( <> - -

{i18nTexts.quickResolveCalloutDescription}

-
+ {correctiveActions.api && ( + <> + +

{i18nTexts.quickResolveCalloutDescription}

+
- - - )} + + + )} - -

{i18nTexts.manualFixTitle}

-
+ +

{i18nTexts.manualFixTitle}

+
- + - -
    - {correctiveActions.manualSteps.map((step, stepIndex) => ( - // TODO temp inline style -
  1. - {step} -
  2. - ))} -
-
+ +
    + {correctiveActions.manualSteps.map((step, stepIndex) => ( +
  1. + {step} +
  2. + ))} +
+
+ + )}
+ @@ -147,12 +221,18 @@ export const DeprecationDetailsFlyout = ({ - {/* Only show the Quick resolve button if deprecation supports it */} + {/* Only show the "Quick resolve" button if deprecation supports it */} {correctiveActions.api && ( - {/* TODO implement onClick */} - {}}> - {i18nTexts.quickResolveButtonLabel} + resolveDeprecation(deprecation)} + isLoading={Boolean( + deprecationResolutionState?.resolveDeprecationStatus === 'in_progress' + )} + disabled={Boolean(deprecationResolutionState?.resolveDeprecationStatus === 'ok')} + > + {getQuickResolveButtonLabel(deprecationResolutionState)} )} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_item.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_item.tsx deleted file mode 100644 index 5bcc49590c55e..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_item.tsx +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 React, { FunctionComponent } from 'react'; -import { - EuiAccordion, - EuiButton, - EuiFlexGroup, - EuiFlexItem, - EuiButtonEmpty, - EuiText, - EuiCallOut, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import type { DomainDeprecationDetails } from 'kibana/public'; -import { DeprecationHealth } from '../shared'; -import { LEVEL_MAP } from '../constants'; -import { StepsModalContent } from './steps_modal'; - -const i18nTexts = { - getDeprecationTitle: (domainId: string) => { - return i18n.translate('xpack.upgradeAssistant.deprecationGroupItemTitle', { - defaultMessage: "'{domainId}' is using a deprecated feature", - values: { - domainId, - }, - }); - }, - docLinkText: i18n.translate('xpack.upgradeAssistant.deprecationGroupItem.docLinkText', { - defaultMessage: 'View documentation', - }), - manualFixButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.deprecationGroupItem.fixButtonLabel', - { - defaultMessage: 'Show steps to fix', - } - ), - resolveButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.deprecationGroupItem.resolveButtonLabel', - { - defaultMessage: 'Quick resolve', - } - ), -}; - -export interface Props { - deprecation: DomainDeprecationDetails; - index: number; - forceExpand: boolean; - showStepsModal: (modalContent: StepsModalContent) => void; - showResolveModal: (deprecation: DomainDeprecationDetails) => void; -} - -export const KibanaDeprecationAccordion: FunctionComponent = ({ - deprecation, - forceExpand, - index, - showStepsModal, - showResolveModal, -}) => { - const { domainId, level, message, documentationUrl, correctiveActions } = deprecation; - - return ( - } - > - - - - {level === 'fetch_error' ? ( - - ) : ( - <> -

{message}

- - {(documentationUrl || correctiveActions?.manualSteps) && ( - - {correctiveActions?.api && ( - - showResolveModal(deprecation)} - > - {i18nTexts.resolveButtonLabel} - - - )} - - {correctiveActions?.manualSteps && ( - - - showStepsModal({ - domainId, - steps: correctiveActions.manualSteps!, - documentationUrl, - }) - } - > - {i18nTexts.manualFixButtonLabel} - - - )} - - {documentationUrl && ( - - - {i18nTexts.docLinkText} - - - )} - - )} - - )} -
-
-
-
- ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_list.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_list.tsx deleted file mode 100644 index fb61efc373acf..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_list.tsx +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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 React, { FunctionComponent, useState, useEffect } from 'react'; -import { groupBy } from 'lodash'; -import { EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; - -import type { DomainDeprecationDetails } from 'kibana/public'; - -import { LevelFilterOption } from '../types'; -import { SearchBar, DeprecationListBar, DeprecationPagination } from '../shared'; -import { DEPRECATIONS_PER_PAGE } from '../constants'; -import { KibanaDeprecationAccordion } from './deprecation_item'; -import { StepsModalContent } from './steps_modal'; -import { KibanaDeprecationErrors } from './kibana_deprecation_errors'; - -interface Props { - deprecations: DomainDeprecationDetails[]; - showStepsModal: (newStepsModalContent: StepsModalContent) => void; - showResolveModal: (deprecation: DomainDeprecationDetails) => void; - reloadDeprecations: () => Promise; - isLoading: boolean; -} - -const getFilteredDeprecations = ( - deprecations: DomainDeprecationDetails[], - level: LevelFilterOption, - search: string -) => { - return deprecations - .filter((deprecation) => { - return level === 'all' || deprecation.level === level; - }) - .filter((filteredDep) => { - if (search.length > 0) { - try { - // 'i' is used for case-insensitive matching - const searchReg = new RegExp(search, 'i'); - return searchReg.test(filteredDep.message); - } catch (e) { - // ignore any regexp errors - return true; - } - } - return true; - }); -}; - -export const KibanaDeprecationList: FunctionComponent = ({ - deprecations, - showStepsModal, - showResolveModal, - reloadDeprecations, - isLoading, -}) => { - const [currentFilter, setCurrentFilter] = useState('all'); - const [search, setSearch] = useState(''); - const [expandState, setExpandState] = useState({ - forceExpand: false, - expandNumber: 0, - }); - const [currentPage, setCurrentPage] = useState(0); - - const setExpandAll = (expandAll: boolean) => { - setExpandState({ forceExpand: expandAll, expandNumber: expandState.expandNumber + 1 }); - }; - - const levelGroups = groupBy(deprecations, 'level'); - const levelToDeprecationCountMap = Object.keys(levelGroups).reduce((counts, level) => { - counts[level] = levelGroups[level].length; - return counts; - }, {} as { [level: string]: number }); - - const filteredDeprecations = getFilteredDeprecations(deprecations, currentFilter, search); - - const deprecationsWithErrors = deprecations.filter((dep) => dep.level === 'fetch_error'); - - useEffect(() => { - const pageCount = Math.ceil(filteredDeprecations.length / DEPRECATIONS_PER_PAGE); - if (currentPage >= pageCount) { - setCurrentPage(0); - } - }, [filteredDeprecations, currentPage]); - - return ( - <> - - - {deprecationsWithErrors.length > 0 && ( - <> - - - - )} - - - - - - <> - {filteredDeprecations - .slice(currentPage * DEPRECATIONS_PER_PAGE, (currentPage + 1) * DEPRECATIONS_PER_PAGE) - .map((deprecation, index) => [ -
- - -
, - ])} - - {/* Only show pagination if we have more than DEPRECATIONS_PER_PAGE */} - {filteredDeprecations.length > DEPRECATIONS_PER_PAGE && ( - <> - - - - - )} - - - ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/index.ts index 84d2b88757188..6a1375f57cd43 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/index.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { KibanaDeprecationsContent } from './kibana_deprecations'; +export { KibanaDeprecations } from './kibana_deprecations'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx index e22a8d72ddba6..be85c84d4b589 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx @@ -6,8 +6,8 @@ */ import React, { useEffect, useState, useCallback } from 'react'; +import uuid from 'uuid'; import { withRouter, RouteComponentProps } from 'react-router-dom'; - import { EuiPageContent, EuiPageHeader, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -61,25 +61,48 @@ const i18nTexts = { }), }; -export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponentProps) => { +export interface DeprecationResolutionState { + id: string; + resolveDeprecationStatus: 'ok' | 'fail' | 'in_progress'; + resolveDeprecationError?: string; +} + +export interface KibanaDeprecationDetails extends DomainDeprecationDetails { + id: string; +} + +export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) => { const [kibanaDeprecations, setKibanaDeprecations] = useState< - DomainDeprecationDetails[] | undefined + KibanaDeprecationDetails[] | undefined >(undefined); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(undefined); - const [flyoutContent, setFlyoutContent] = useState( + const [flyoutContent, setFlyoutContent] = useState( undefined ); - // const [isResolvingDeprecation, setIsResolvingDeprecation] = useState(false); + const [deprecationResolutionState, setDeprecationResolutionState] = useState< + DeprecationResolutionState | undefined + >(undefined); const { deprecations, breadcrumbs, api } = useAppContext(); + const { + addContent: addContentToGlobalFlyout, + removeContent: removeContentFromGlobalFlyout, + } = useGlobalFlyout(); + const getAllDeprecations = useCallback(async () => { setIsLoading(true); try { - const response = await deprecations.getAllDeprecations(); - setKibanaDeprecations(response); + const newKibanaDeprecations = await deprecations.getAllDeprecations(); + const newKibanaDeprecationsWithIds = newKibanaDeprecations.map((deprecation) => { + return { + ...deprecation, + id: uuid.v4(), + }; + }); + setKibanaDeprecations(newKibanaDeprecationsWithIds); } catch (e) { setError(e); } @@ -87,20 +110,35 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent setIsLoading(false); }, [deprecations]); - const toggleFlyout = (newFlyoutContent?: DomainDeprecationDetails) => { + const toggleFlyout = (newFlyoutContent?: KibanaDeprecationDetails) => { setFlyoutContent(newFlyoutContent); }; - const { - addContent: addContentToGlobalFlyout, - removeContent: removeContentFromGlobalFlyout, - } = useGlobalFlyout(); - const closeFlyout = useCallback(() => { toggleFlyout(); removeContentFromGlobalFlyout('deprecationDetails'); }, [removeContentFromGlobalFlyout]); + const resolveDeprecation = useCallback( + async (deprecationDetails: KibanaDeprecationDetails) => { + setDeprecationResolutionState({ + id: deprecationDetails.id, + resolveDeprecationStatus: 'in_progress', + }); + + const response = await deprecations.resolveDeprecation(deprecationDetails); + + setDeprecationResolutionState({ + id: deprecationDetails.id, + resolveDeprecationStatus: response.status, + resolveDeprecationError: response.status === 'fail' ? response.reason : undefined, + }); + + closeFlyout(); + }, + [closeFlyout, deprecations] + ); + useEffect(() => { if (flyoutContent) { addContentToGlobalFlyout({ @@ -109,6 +147,11 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent props: { deprecation: flyoutContent, closeFlyout, + resolveDeprecation, + deprecationResolutionState: + deprecationResolutionState && flyoutContent.id === deprecationResolutionState.id + ? deprecationResolutionState + : undefined, }, flyoutProps: { onClose: closeFlyout, @@ -117,30 +160,13 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent }, }); } - }, [addContentToGlobalFlyout, closeFlyout, flyoutContent]); - - // TODO finish implementing - // const resolveDeprecation = async (deprecationDetails: DomainDeprecationDetails) => { - // setIsResolvingDeprecation(true); - - // const response = await deprecations.resolveDeprecation(deprecationDetails); - - // setIsResolvingDeprecation(false); - // // toggleResolveModal(); - - // // Handle error case - // if (response.status === 'fail') { - // notifications.toasts.addError(new Error(response.reason), { - // title: i18nTexts.errorMessage, - // }); - - // return; - // } - - // notifications.toasts.addSuccess(i18nTexts.successMessage); - // // Refetch deprecations - // getAllDeprecations(); - // }; + }, [ + addContentToGlobalFlyout, + closeFlyout, + deprecationResolutionState, + flyoutContent, + resolveDeprecation, + ]); useEffect(() => { async function sendTelemetryData() { @@ -194,6 +220,7 @@ export const KibanaDeprecationsContent = withRouter(({ history }: RouteComponent deprecations={kibanaDeprecations} reload={getAllDeprecations} toggleFlyout={toggleFlyout} + deprecationResolutionState={deprecationResolutionState} /> ); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index 5a8484e2a8c8a..713b87fbc68dc 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -12,14 +12,11 @@ import { EuiButton, EuiLink, EuiBadge, - EuiToolTip, - EuiText, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, + Search, } from '@elastic/eui'; -import type { DomainDeprecationDetails } from 'kibana/public'; +import type { DeprecationResolutionState, KibanaDeprecationDetails } from './kibana_deprecations'; +import { ResolutionTableCell } from './resolution_table_cell'; const i18nTexts = { refreshButtonLabel: i18n.translate( @@ -52,24 +49,6 @@ const i18nTexts = { defaultMessage: 'Resolution', } ), - manualCellLabel: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.table.manualCellLabel', - { - defaultMessage: 'Manual', - } - ), - manualCellTooltipLabel: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.table.manualCellTooltipLabel', - { - defaultMessage: 'Resolve this deprecation manually.', - } - ), - automatedCellLabel: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.table.automatedCellLabel', - { - defaultMessage: 'Automated', - } - ), configDeprecationTypeCellLabel: i18n.translate( 'xpack.upgradeAssistant.kibanaDeprecations.table.configDeprecationTypeCellLabel', { @@ -88,12 +67,6 @@ const i18nTexts = { defaultMessage: 'Unknown', } ), - automatedCellTooltipLabel: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.table.automatedCellTooltipLabel', - { - defaultMessage: 'This is an automated resolution.', - } - ), typeFilterLabel: i18n.translate( 'xpack.upgradeAssistant.kibanaDeprecations.table.typeFilterLabel', { @@ -123,24 +96,26 @@ const i18nTexts = { }; interface Props { - deprecations?: DomainDeprecationDetails[]; + deprecations?: KibanaDeprecationDetails[]; reload: () => void; - toggleFlyout: (newFlyoutContent?: DomainDeprecationDetails) => void; + toggleFlyout: (newFlyoutContent?: KibanaDeprecationDetails) => void; + deprecationResolutionState?: DeprecationResolutionState; } export const KibanaDeprecationsTable: React.FunctionComponent = ({ deprecations, reload, toggleFlyout, + deprecationResolutionState, }) => { - const columns: Array> = [ + const columns: Array> = [ { field: 'level', name: i18nTexts.statusColumnTitle, width: '5%', truncateText: true, sortable: true, - render: (level: DomainDeprecationDetails['level']) => { + render: (level: KibanaDeprecationDetails['level']) => { if (level === 'critical') { return {i18nTexts.criticalBadgeLabel}; } @@ -155,11 +130,12 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ truncateText: true, sortable: true, render: ( - domainId: DomainDeprecationDetails['domainId'], - deprecation: DomainDeprecationDetails + domainId: KibanaDeprecationDetails['domainId'], + deprecation: KibanaDeprecationDetails ) => { return ( toggleFlyout(deprecation)}> + {/* This will be replaced with a custom title once https://github.com/elastic/kibana/pull/109840 is merged */} {i18nTexts.getDeprecationIssue(domainId)} ); @@ -171,7 +147,7 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ width: '20%', truncateText: true, sortable: true, - render: (deprecationType: DomainDeprecationDetails['deprecationType']) => { + render: (deprecationType: KibanaDeprecationDetails['deprecationType']) => { switch (deprecationType) { case 'config': return i18nTexts.configDeprecationTypeCellLabel; @@ -188,28 +164,16 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ width: '30%', truncateText: true, sortable: true, - render: (correctiveActions: DomainDeprecationDetails['correctiveActions']) => { - if (correctiveActions.api) { - return ( - - - - - - - {i18nTexts.automatedCellLabel} - - - - ); - } - + render: ( + correctiveActions: KibanaDeprecationDetails['correctiveActions'], + deprecation: KibanaDeprecationDetails + ) => { return ( - - - {i18nTexts.manualCellLabel} - - + ); }, }, @@ -227,9 +191,7 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ }, } as const; - const searchConfig = { - // TODO fix - // query: {}, + const searchConfig: Search = { filters: [ { type: 'is', @@ -252,11 +214,6 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ value: 'feature', name: i18nTexts.featureDeprecationTypeCellLabel, }, - // TODO not working yet - { - value: 'unknown', - name: i18nTexts.unknownDeprecationTypeCellLabel, - }, ], }, ], @@ -267,7 +224,6 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ toolsRight: [ = ({ + deprecationId, + isAutomated, + deprecationResolutionState, +}) => { + if (isAutomated) { + if (deprecationResolutionState?.id === deprecationId) { + const { resolveDeprecationStatus } = deprecationResolutionState; + if (resolveDeprecationStatus === 'in_progress') { + return ( + + + + + + {i18nTexts.automationInProgressCellLabel} + + + ); + } + + if (resolveDeprecationStatus === 'ok') { + return ( + + + + + + {i18nTexts.automationCompleteCellLabel} + + + ); + } + + if (resolveDeprecationStatus === 'fail') { + return ( + + + + + + {i18nTexts.automationFailedCellLabel} + + + ); + } + } + + return ( + + + + + + + {i18nTexts.automatedCellLabel} + + + + ); + } + + return ( + + + {i18nTexts.manualCellLabel} + + + ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolve_deprecation_modal.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolve_deprecation_modal.tsx deleted file mode 100644 index f94512fac5630..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolve_deprecation_modal.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 React, { FunctionComponent } from 'react'; -import { i18n } from '@kbn/i18n'; - -import { EuiConfirmModal } from '@elastic/eui'; -import type { DomainDeprecationDetails } from 'kibana/public'; - -interface Props { - closeModal: () => void; - deprecation: DomainDeprecationDetails; - isResolvingDeprecation: boolean; - resolveDeprecation: (deprecationDetails: DomainDeprecationDetails) => Promise; -} - -const i18nTexts = { - getModalTitle: (domainId: string) => - i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.modalTitle', - { - defaultMessage: "Resolve deprecation in '{domainId}'?", - values: { - domainId, - }, - } - ), - cancelButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.cancelButtonLabel', - { - defaultMessage: 'Cancel', - } - ), - resolveButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.resolveButtonLabel', - { - defaultMessage: 'Resolve', - } - ), -}; - -export const ResolveDeprecationModal: FunctionComponent = ({ - closeModal, - deprecation, - isResolvingDeprecation, - resolveDeprecation, -}) => { - return ( - resolveDeprecation(deprecation)} - cancelButtonText={i18nTexts.cancelButtonLabel} - confirmButtonText={i18nTexts.resolveButtonLabel} - defaultFocusedButton="confirm" - isLoading={isResolvingDeprecation} - /> - ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/steps_modal.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/steps_modal.tsx deleted file mode 100644 index 98027d4f46aac..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/steps_modal.tsx +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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 React, { FunctionComponent } from 'react'; -import { i18n } from '@kbn/i18n'; - -import { - EuiText, - EuiSteps, - EuiButton, - EuiModal, - EuiModalBody, - EuiModalFooter, - EuiModalHeader, - EuiModalHeaderTitle, - EuiTitle, - EuiButtonEmpty, - EuiFlexGroup, - EuiFlexItem, -} from '@elastic/eui'; - -export interface StepsModalContent { - domainId: string; - steps: string[]; - documentationUrl?: string; -} - -interface Props { - closeModal: () => void; - modalContent: StepsModalContent; -} - -const i18nTexts = { - getModalTitle: (domainId: string) => - i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.stepsModal.modalTitle', { - defaultMessage: "Resolve deprecation in '{domainId}'", - values: { - domainId, - }, - }), - getStepTitle: (step: number) => - i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.stepsModal.stepTitle', { - defaultMessage: 'Step {step}', - values: { - step, - }, - }), - docLinkLabel: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.stepsModal.docLinkLabel', - { - defaultMessage: 'View documentation', - } - ), - closeButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecations.stepsModal.closeButtonLabel', - { - defaultMessage: 'Close', - } - ), -}; - -export const StepsModal: FunctionComponent = ({ closeModal, modalContent }) => { - const { domainId, steps, documentationUrl } = modalContent; - - return ( - - - - -

{i18nTexts.getModalTitle(domainId)}

-
-
-
- - - { - return { - title: i18nTexts.getStepTitle(index + 1), - children: ( - -

{step}

-
- ), - }; - })} - /> -
- - - - {documentationUrl && ( - - - {i18nTexts.docLinkLabel} - - - )} - - - - {i18nTexts.closeButtonLabel} - - - - -
- ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/count_summary.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/count_summary.tsx deleted file mode 100644 index 709ef7224870e..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/count_summary.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 React, { FunctionComponent } from 'react'; - -import { EuiText } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; - -export const DeprecationCountSummary: FunctionComponent<{ - allDeprecationsCount: number; - filteredDeprecationsCount: number; -}> = ({ filteredDeprecationsCount, allDeprecationsCount }) => ( - - {allDeprecationsCount > 0 ? ( - - ) : ( - - )} - {filteredDeprecationsCount !== allDeprecationsCount && ( - <> - {'. '} - - - )} - -); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/deprecation_list_bar.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/deprecation_list_bar.tsx deleted file mode 100644 index 6cb5ae3675c44..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_list_bar/deprecation_list_bar.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 React, { FunctionComponent } from 'react'; -import { i18n } from '@kbn/i18n'; - -import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { DeprecationCountSummary } from './count_summary'; - -const i18nTexts = { - expandAllButton: i18n.translate( - 'xpack.upgradeAssistant.deprecationListBar.expandAllButtonLabel', - { - defaultMessage: 'Expand all', - } - ), - collapseAllButton: i18n.translate( - 'xpack.upgradeAssistant.deprecationListBar.collapseAllButtonLabel', - { - defaultMessage: 'Collapse all', - } - ), -}; - -export const DeprecationListBar: FunctionComponent<{ - allDeprecationsCount: number; - filteredDeprecationsCount: number; - setExpandAll: (shouldExpandAll: boolean) => void; -}> = ({ allDeprecationsCount, filteredDeprecationsCount, setExpandAll }) => { - return ( - - - - - - - - - setExpandAll(true)} - data-test-subj="expandAll" - > - {i18nTexts.expandAllButton} - - - - setExpandAll(false)} - data-test-subj="collapseAll" - > - {i18nTexts.collapseAllButton} - - - - - - ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_pagination.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_pagination.tsx deleted file mode 100644 index ae2c0ba1c4877..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_pagination.tsx +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 React, { FunctionComponent } from 'react'; - -import { EuiFlexGroup, EuiFlexItem, EuiPagination } from '@elastic/eui'; - -export const DeprecationPagination: FunctionComponent<{ - pageCount: number; - activePage: number; - setPage: (page: number) => void; -}> = ({ pageCount, activePage, setPage }) => { - return ( - - - - - - ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/health.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/health.tsx deleted file mode 100644 index 9bf35668ac88a..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/health.tsx +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 { countBy } from 'lodash'; -import React, { FunctionComponent } from 'react'; - -import { EuiBadge, EuiToolTip } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import { DeprecationInfo } from '../../../../common/types'; -import { COLOR_MAP, REVERSE_LEVEL_MAP } from '../constants'; - -const LocalizedLevels: { [level: string]: string } = { - warning: i18n.translate('xpack.upgradeAssistant.checkupTab.deprecations.warningLabel', { - defaultMessage: 'Warning', - }), - critical: i18n.translate('xpack.upgradeAssistant.checkupTab.deprecations.criticalLabel', { - defaultMessage: 'Critical', - }), -}; - -export const LocalizedActions: { [level: string]: string } = { - warning: i18n.translate('xpack.upgradeAssistant.checkupTab.deprecations.warningActionTooltip', { - defaultMessage: 'Resolving this issue before upgrading is advised, but not required.', - }), - critical: i18n.translate('xpack.upgradeAssistant.checkupTab.deprecations.criticalActionTooltip', { - defaultMessage: 'Resolve this issue before upgrading.', - }), -}; - -interface DeprecationHealthProps { - deprecationLevels: number[]; - single?: boolean; -} - -const SingleHealth: FunctionComponent<{ level: DeprecationInfo['level']; label: string }> = ({ - level, - label, -}) => ( - - - {label} - -   - -); - -/** - * Displays a summary health for a list of deprecations that shows the number and level of severity - * deprecations in the list. - */ -export const DeprecationHealth: FunctionComponent = ({ - deprecationLevels, - single = false, -}) => { - if (deprecationLevels.length === 0) { - return ; - } - - if (single) { - const highest = Math.max(...deprecationLevels); - const highestLevel = REVERSE_LEVEL_MAP[highest]; - - return ; - } - - const countByLevel = countBy(deprecationLevels); - - return ( - - {Object.keys(countByLevel) - .map((k) => parseInt(k, 10)) - .sort() - .map((level) => [level, REVERSE_LEVEL_MAP[level]]) - .map(([numLevel, stringLevel]) => ( - - ))} - - ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts index c79d8247a93f1..31d03625de5a7 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts @@ -6,7 +6,3 @@ */ export { NoDeprecationsPrompt } from './no_deprecations'; -export { DeprecationHealth } from './health'; -export { SearchBar } from './search_bar'; -export { DeprecationPagination } from './deprecation_pagination'; -export { DeprecationListBar } from './deprecation_list_bar'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/__snapshots__/group_by_filter.test.tsx.snap b/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/__snapshots__/group_by_filter.test.tsx.snap deleted file mode 100644 index 5a8619e1e687b..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/__snapshots__/group_by_filter.test.tsx.snap +++ /dev/null @@ -1,24 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`GroupByFilter renders 1`] = ` - - - - By issue - - - By index - - - -`; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/__snapshots__/level_filter.test.tsx.snap b/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/__snapshots__/level_filter.test.tsx.snap deleted file mode 100644 index 551e212f23dd7..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/__snapshots__/level_filter.test.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DeprecationLevelFilter renders 1`] = ` - - - - Critical - - - -`; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/group_by_filter.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/group_by_filter.test.tsx deleted file mode 100644 index fa863e4935c09..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/group_by_filter.test.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 { mount, shallow } from 'enzyme'; -import React from 'react'; - -import { GroupByOption } from '../../types'; -import { GroupByFilter } from './group_by_filter'; - -const defaultProps = { - availableGroupByOptions: [GroupByOption.message, GroupByOption.index], - currentGroupBy: GroupByOption.message, - onGroupByChange: jest.fn(), -}; - -describe('GroupByFilter', () => { - test('renders', () => { - expect(shallow()).toMatchSnapshot(); - }); - - test('clicking button calls onGroupByChange', () => { - const wrapper = mount(); - wrapper.find('button.euiFilterButton-hasActiveFilters').simulate('click'); - expect(defaultProps.onGroupByChange).toHaveBeenCalledTimes(1); - expect(defaultProps.onGroupByChange.mock.calls[0][0]).toEqual(GroupByOption.message); - }); -}); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/group_by_filter.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/group_by_filter.tsx deleted file mode 100644 index c37ae47793b95..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/group_by_filter.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 React from 'react'; - -import { EuiFilterButton, EuiFilterGroup, EuiFlexItem } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import { GroupByOption } from '../../types'; - -const LocalizedOptions: { [option: string]: string } = { - message: i18n.translate('xpack.upgradeAssistant.checkupTab.controls.groupByBar.byIssueLabel', { - defaultMessage: 'By issue', - }), - index: i18n.translate('xpack.upgradeAssistant.checkupTab.controls.groupByBar.byIndexLabel', { - defaultMessage: 'By index', - }), -}; - -interface GroupByFilterProps { - availableGroupByOptions: GroupByOption[]; - currentGroupBy: GroupByOption; - onGroupByChange: (groupBy: GroupByOption) => void; -} - -export const GroupByFilter: React.FunctionComponent = ({ - availableGroupByOptions, - currentGroupBy, - onGroupByChange, -}) => { - if (availableGroupByOptions.length <= 1) { - return null; - } - - return ( - - - {availableGroupByOptions.map((option) => ( - - {LocalizedOptions[option]} - - ))} - - - ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/index.ts deleted file mode 100644 index 31ad78cf572fe..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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. - */ - -export { SearchBar } from './search_bar'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/level_filter.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/level_filter.test.tsx deleted file mode 100644 index c778e56e8df11..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/level_filter.test.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 { mount, shallow } from 'enzyme'; -import React from 'react'; -import { LevelFilterOption } from '../../types'; - -import { DeprecationLevelFilter } from './level_filter'; - -const defaultProps = { - levelsCount: { - warning: 4, - critical: 1, - }, - currentFilter: 'all' as LevelFilterOption, - onFilterChange: jest.fn(), -}; - -describe('DeprecationLevelFilter', () => { - test('renders', () => { - expect(shallow()).toMatchSnapshot(); - }); - - test('clicking button calls onFilterChange', () => { - const wrapper = mount(); - wrapper.find('button[data-test-subj="criticalLevelFilter"]').simulate('click'); - expect(defaultProps.onFilterChange).toHaveBeenCalledTimes(1); - expect(defaultProps.onFilterChange.mock.calls[0][0]).toEqual('critical'); - }); -}); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/level_filter.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/level_filter.tsx deleted file mode 100644 index 59bfaa595b0a6..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/level_filter.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 React from 'react'; - -import { EuiFilterButton, EuiFilterGroup, EuiFlexItem } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import { LevelFilterOption } from '../../types'; - -const LocalizedOptions: { [option: string]: string } = { - critical: i18n.translate( - 'xpack.upgradeAssistant.checkupTab.controls.filterBar.criticalButtonLabel', - { defaultMessage: 'Critical' } - ), -}; -interface DeprecationLevelProps { - levelsCount: { - [key: string]: number; - }; - currentFilter: LevelFilterOption; - onFilterChange(level: LevelFilterOption): void; -} - -export const DeprecationLevelFilter: React.FunctionComponent = ({ - levelsCount, - currentFilter, - onFilterChange, -}) => { - return ( - - - { - onFilterChange(currentFilter !== 'critical' ? 'critical' : 'all'); - }} - hasActiveFilters={currentFilter === 'critical'} - numFilters={levelsCount.critical || undefined} - data-test-subj="criticalLevelFilter" - > - {LocalizedOptions.critical} - - - - ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/search_bar.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/search_bar.tsx deleted file mode 100644 index 7c805398a6b47..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/search_bar/search_bar.tsx +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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 React, { FunctionComponent, useState } from 'react'; -import { i18n } from '@kbn/i18n'; -import { - EuiButton, - EuiFieldSearch, - EuiFlexGroup, - EuiFlexItem, - EuiCallOut, - EuiSpacer, -} from '@elastic/eui'; - -import type { DomainDeprecationDetails } from 'kibana/public'; -import { DeprecationInfo } from '../../../../../common/types'; -import { validateRegExpString } from '../../../lib/utils'; -import { GroupByOption, LevelFilterOption } from '../../types'; -import { DeprecationLevelFilter } from './level_filter'; -import { GroupByFilter } from './group_by_filter'; - -interface SearchBarProps { - allDeprecations?: DeprecationInfo[] | DomainDeprecationDetails; - isLoading: boolean; - loadData: () => void; - currentFilter: LevelFilterOption; - onFilterChange: (filter: LevelFilterOption) => void; - onSearchChange: (filter: string) => void; - totalDeprecationsCount: number; - levelToDeprecationCountMap: { - [key: string]: number; - }; - groupByFilterProps?: { - availableGroupByOptions: GroupByOption[]; - currentGroupBy: GroupByOption; - onGroupByChange: (groupBy: GroupByOption) => void; - }; -} - -const i18nTexts = { - searchAriaLabel: i18n.translate( - 'xpack.upgradeAssistant.deprecationListSearchBar.placeholderAriaLabel', - { defaultMessage: 'Filter' } - ), - searchPlaceholderLabel: i18n.translate( - 'xpack.upgradeAssistant.deprecationListSearchBar.placeholderLabel', - { - defaultMessage: 'Filter', - } - ), - reloadButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.deprecationListSearchBar.reloadButtonLabel', - { - defaultMessage: 'Reload', - } - ), - getInvalidSearchMessage: (searchTermError: string) => - i18n.translate('xpack.upgradeAssistant.deprecationListSearchBar.filterErrorMessageLabel', { - defaultMessage: 'Filter invalid: {searchTermError}', - values: { searchTermError }, - }), -}; - -export const SearchBar: FunctionComponent = ({ - totalDeprecationsCount, - levelToDeprecationCountMap, - isLoading, - loadData, - currentFilter, - onFilterChange, - onSearchChange, - groupByFilterProps, -}) => { - const [searchTermError, setSearchTermError] = useState(null); - const filterInvalid = Boolean(searchTermError); - return ( - <> - - - - - { - const string = e.target.value; - const errorMessage = validateRegExpString(string); - if (errorMessage) { - // Emit an empty search term to listeners if search term is invalid. - onSearchChange(''); - setSearchTermError(errorMessage); - } else { - onSearchChange(e.target.value); - if (searchTermError) { - setSearchTermError(null); - } - } - }} - /> - - - {/* These two components provide their own EuiFlexItem wrappers */} - - {groupByFilterProps && } - - - - - {i18nTexts.reloadButtonLabel} - - - - - {filterInvalid && ( - <> - - - - - )} - - - - ); -}; 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 b46bb583244f0..a5f5b515278f4 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/types.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/types.ts @@ -7,20 +7,6 @@ import { ResponseError } from '../lib/api'; -export enum LoadingState { - Loading, - Success, - Error, -} - -export type LevelFilterOption = 'all' | 'critical'; - -export enum GroupByOption { - message = 'message', - index = 'index', - node = 'node', -} - export type DeprecationTableColumns = | 'type' | 'index' From 4a9fc5bf01f7f91ce47ff89b1b4726ea65e37847 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Mon, 30 Aug 2021 13:31:48 -0400 Subject: [PATCH 05/18] handle fetch error for kibana deprecation --- .../kibana_deprecations.tsx | 64 +++++++++++++++---- .../kibana_deprecations_table.tsx | 2 +- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx index be85c84d4b589..f68e037896912 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx @@ -8,7 +8,7 @@ import React, { useEffect, useState, useCallback } from 'react'; import uuid from 'uuid'; import { withRouter, RouteComponentProps } from 'react-router-dom'; -import { EuiPageContent, EuiPageHeader, EuiSpacer } from '@elastic/eui'; +import { EuiPageContent, EuiPageHeader, EuiSpacer, EuiCallOut } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -53,12 +53,21 @@ const i18nTexts = { isLoading: i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.loadingText', { defaultMessage: 'Loading deprecations…', }), - successMessage: i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.successMessage', { - defaultMessage: 'Deprecation resolved', - }), - errorMessage: i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.errorMessage', { - defaultMessage: 'Error resolving deprecation', - }), + kibanaDeprecationErrorTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.kibanaDeprecationErrorTitle', + { + defaultMessage: 'Deprecation warnings may be incomplete', + } + ), + getKibanaDeprecationErrorDescription: (pluginIds: string[]) => + i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.kibanaDeprecationErrorDescription', { + defaultMessage: + 'Failed to get deprecation warnings for {pluginCount, plural, one {this plugin} other {these plugins}}: {pluginIds}. Check the Kibana server logs for more details.', + values: { + pluginCount: pluginIds.length, + pluginIds: pluginIds.join(', '), + }, + }), }; export interface DeprecationResolutionState { @@ -75,6 +84,7 @@ export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) const [kibanaDeprecations, setKibanaDeprecations] = useState< KibanaDeprecationDetails[] | undefined >(undefined); + const [kibanaDeprecationErrors, setKibanaDeprecationErrors] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(undefined); const [flyoutContent, setFlyoutContent] = useState( @@ -95,14 +105,27 @@ export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) setIsLoading(true); try { - const newKibanaDeprecations = await deprecations.getAllDeprecations(); - const newKibanaDeprecationsWithIds = newKibanaDeprecations.map((deprecation) => { - return { + const allDeprecations = await deprecations.getAllDeprecations(); + + const filteredDeprecations: KibanaDeprecationDetails[] = []; + const deprecationErrors: string[] = []; + + allDeprecations.forEach((deprecation) => { + // Keep track of any deprecations that failed to fetch to show warning in UI + if (deprecation.level === 'fetch_error') { + deprecationErrors.push(deprecation.domainId); + return; + } + + // Only show deprecations in the table that fetched successfully + filteredDeprecations.push({ ...deprecation, - id: uuid.v4(), - }; + id: uuid.v4(), // Associate an unique ID with each deprecation to track resolution state + }); }); - setKibanaDeprecations(newKibanaDeprecationsWithIds); + + setKibanaDeprecations(filteredDeprecations); + setKibanaDeprecationErrors(deprecationErrors); } catch (e) { setError(e); } @@ -216,6 +239,21 @@ export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) + {kibanaDeprecationErrors.length > 0 && ( + <> + +

{i18nTexts.getKibanaDeprecationErrorDescription(kibanaDeprecationErrors)}

+
+ + + + )} + Date: Mon, 30 Aug 2021 13:50:07 -0400 Subject: [PATCH 06/18] add deprecation count to page header --- .../application/components/constants.tsx | 5 ++ .../es_deprecations/es_deprecations.tsx | 41 +++----------- .../es_deprecations/es_deprecations_table.tsx | 6 +-- .../kibana_deprecations.tsx | 34 ++++++++++-- .../kibana_deprecations_table.tsx | 8 +-- .../components/shared/deprecation_count.tsx | 53 +++++++++++++++++++ .../application/components/shared/index.ts | 1 + 7 files changed, 101 insertions(+), 47 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_count.tsx diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx index 67cbe8bd91bfb..34850e6c97543 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx @@ -27,3 +27,8 @@ export const DEPRECATION_TYPE_MAP = { defaultMessage: 'Machine Learning', }), }; + +export const PAGINATION_CONFIG = { + initialPageSize: 50, + pageSizeOptions: [50, 100, 200], +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations.tsx index b714ae2ca2fd1..0d0205594753f 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations.tsx @@ -8,14 +8,7 @@ import React, { useEffect, useMemo } from 'react'; import { withRouter, RouteComponentProps } from 'react-router-dom'; -import { - EuiPageHeader, - EuiSpacer, - EuiPageContent, - EuiFlexGroup, - EuiFlexItem, - EuiHealth, -} from '@elastic/eui'; +import { EuiPageHeader, EuiSpacer, EuiPageContent } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { EnrichedDeprecationInfo } from '../../../../common/types'; @@ -23,7 +16,7 @@ import { SectionLoading } from '../../../shared_imports'; import { useAppContext } from '../../app_context'; import { EsDeprecationsTable } from './es_deprecations_table'; import { EsDeprecationErrors } from './es_deprecation_errors'; -import { NoDeprecationsPrompt } from '../shared'; +import { NoDeprecationsPrompt, DeprecationCount } from '../shared'; const getDeprecationCountByLevel = (deprecations: EnrichedDeprecationInfo[]) => { const criticalDeprecations: EnrichedDeprecationInfo[] = []; @@ -54,20 +47,6 @@ const i18nTexts = { isLoading: i18n.translate('xpack.upgradeAssistant.esDeprecations.loadingText', { defaultMessage: 'Loading deprecations…', }), - getCriticalStatusLabel: (count: number) => - i18n.translate('xpack.upgradeAssistant.esDeprecations.criticalStatusLabel', { - defaultMessage: 'Critical: {count}', - values: { - count, - }, - }), - getWarningStatusLabel: (count: number) => - i18n.translate('xpack.upgradeAssistant.esDeprecations.warningStatusLabel', { - defaultMessage: 'Warning: {count}', - values: { - count, - }, - }), }; export const EsDeprecations = withRouter(({ history }: RouteComponentProps) => { @@ -130,18 +109,10 @@ export const EsDeprecations = withRouter(({ history }: RouteComponentProps) => { return (
- - - - {i18nTexts.getCriticalStatusLabel(deprecationsCountByLevel.criticalDeprecations)} - - - - - {i18nTexts.getWarningStatusLabel(deprecationsCountByLevel.warningDeprecations)} - - - + diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations_table.tsx index ac92f288230f6..7a9b4b7c7144f 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/es_deprecations_table.tsx @@ -33,7 +33,7 @@ import { ReindexTableRow, } from './deprecation_types'; import { DeprecationTableColumns } from '../types'; -import { DEPRECATION_TYPE_MAP } from '../constants'; +import { DEPRECATION_TYPE_MAP, PAGINATION_CONFIG } from '../constants'; const i18nTexts = { refreshButtonLabel: i18n.translate( @@ -99,7 +99,7 @@ const cellToLabelMap = { }; const cellTypes = Object.keys(cellToLabelMap) as DeprecationTableColumns[]; -const pageSizeOptions = [50, 100, 200]; +const pageSizeOptions = PAGINATION_CONFIG.pageSizeOptions; const renderTableRowCells = (deprecation: EnrichedDeprecationInfo) => { switch (deprecation.correctiveAction?.type) { @@ -151,7 +151,7 @@ export const EsDeprecationsTable: React.FunctionComponent = ({ sortField: 'isCritical', }); - const [itemsPerPage, setItemsPerPage] = useState(pageSizeOptions[0]); + const [itemsPerPage, setItemsPerPage] = useState(PAGINATION_CONFIG.initialPageSize); const [currentPageIndex, setCurrentPageIndex] = useState(0); const [searchQuery, setSearchQuery] = useState(EuiSearchBar.Query.MATCH_ALL); const [searchError, setSearchError] = useState<{ message: string } | undefined>(undefined); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx index f68e037896912..46423f2f7fbd4 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useEffect, useState, useCallback } from 'react'; +import React, { useEffect, useState, useCallback, useMemo } from 'react'; import uuid from 'uuid'; import { withRouter, RouteComponentProps } from 'react-router-dom'; import { EuiPageContent, EuiPageHeader, EuiSpacer, EuiCallOut } from '@elastic/eui'; @@ -15,7 +15,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import type { DomainDeprecationDetails } from 'kibana/public'; import { SectionLoading, GlobalFlyout } from '../../../shared_imports'; import { useAppContext } from '../../app_context'; -import { NoDeprecationsPrompt } from '../shared'; +import { NoDeprecationsPrompt, DeprecationCount } from '../shared'; import { KibanaDeprecationErrors } from './kibana_deprecation_errors'; import { KibanaDeprecationsTable } from './kibana_deprecations_table'; import { @@ -80,6 +80,24 @@ export interface KibanaDeprecationDetails extends DomainDeprecationDetails { id: string; } +const getDeprecationCountByLevel = (deprecations: KibanaDeprecationDetails[]) => { + const criticalDeprecations: KibanaDeprecationDetails[] = []; + const warningDeprecations: KibanaDeprecationDetails[] = []; + + deprecations.forEach((deprecation) => { + if (deprecation.level === 'critical') { + criticalDeprecations.push(deprecation); + return; + } + warningDeprecations.push(deprecation); + }); + + return { + criticalDeprecations: criticalDeprecations.length, + warningDeprecations: warningDeprecations.length, + }; +}; + export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) => { const [kibanaDeprecations, setKibanaDeprecations] = useState< KibanaDeprecationDetails[] | undefined @@ -133,6 +151,11 @@ export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) setIsLoading(false); }, [deprecations]); + const deprecationsCountByLevel: { + warningDeprecations: number; + criticalDeprecations: number; + } = useMemo(() => getDeprecationCountByLevel(kibanaDeprecations || []), [kibanaDeprecations]); + const toggleFlyout = (newFlyoutContent?: KibanaDeprecationDetails) => { setFlyoutContent(newFlyoutContent); }; @@ -235,7 +258,12 @@ export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) bottomBorder pageTitle={i18nTexts.pageTitle} description={i18nTexts.pageDescription} - /> + > + + diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index 7512ce363a385..1f10802fcb69c 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -15,6 +15,7 @@ import { Search, } from '@elastic/eui'; +import { PAGINATION_CONFIG } from '../constants'; import type { DeprecationResolutionState, KibanaDeprecationDetails } from './kibana_deprecations'; import { ResolutionTableCell } from './resolution_table_cell'; @@ -179,11 +180,6 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ }, ]; - const pagination = { - initialPageSize: 50, - pageSizeOptions: [50, 100, 200], - }; - const sorting = { sort: { field: 'level', @@ -240,7 +236,7 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ columns={columns} search={searchConfig} sorting={sorting} - pagination={pagination} + pagination={PAGINATION_CONFIG} rowProps={() => ({ 'data-test-subj': 'row', })} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_count.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_count.tsx new file mode 100644 index 0000000000000..3312508a87073 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_count.tsx @@ -0,0 +1,53 @@ +/* + * 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 React, { FunctionComponent } from 'react'; + +import { EuiFlexGroup, EuiFlexItem, EuiHealth } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +const i18nTexts = { + getCriticalStatusLabel: (count: number) => + i18n.translate('xpack.upgradeAssistant.deprecationCount.criticalStatusLabel', { + defaultMessage: 'Critical: {count}', + values: { + count, + }, + }), + getWarningStatusLabel: (count: number) => + i18n.translate('xpack.upgradeAssistant.deprecationCount.warningStatusLabel', { + defaultMessage: 'Warning: {count}', + values: { + count, + }, + }), +}; + +interface Props { + totalCriticalDeprecations: number; + totalWarningDeprecations: number; +} + +export const DeprecationCount: FunctionComponent = ({ + totalCriticalDeprecations, + totalWarningDeprecations, +}) => { + return ( + + + + {i18nTexts.getCriticalStatusLabel(totalCriticalDeprecations)} + + + + + {i18nTexts.getWarningStatusLabel(totalWarningDeprecations)} + + + + ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts index 31d03625de5a7..89bce0813b92f 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts @@ -6,3 +6,4 @@ */ export { NoDeprecationsPrompt } from './no_deprecations'; +export { DeprecationCount } from './deprecation_count'; From e6c3dd5bda85b0100b2636ea3cc8e8a775307a0a Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Mon, 30 Aug 2021 13:54:45 -0400 Subject: [PATCH 07/18] fix CI --- .../translations/translations/ja-JP.json | 30 ------------------- .../translations/translations/zh-CN.json | 30 ------------------- .../kibana_deprecations_table.tsx | 10 +++++-- .../public/application/components/types.ts | 6 ++++ 4 files changed, 13 insertions(+), 63 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 59748225b01a3..84e060a48c5a8 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -24819,16 +24819,6 @@ "xpack.upgradeAssistant.breadcrumb.esDeprecationsLabel": "Elasticsearchの廃止予定", "xpack.upgradeAssistant.breadcrumb.kibanaDeprecationsLabel": "Kibanaの廃止予定", "xpack.upgradeAssistant.breadcrumb.overviewLabel": "アップグレードアシスタント", - "xpack.upgradeAssistant.checkupTab.changeFiltersShowMoreLabel": "より多く表示させるにはフィルターを変更します。", - "xpack.upgradeAssistant.checkupTab.controls.filterBar.criticalButtonLabel": "重大", - "xpack.upgradeAssistant.checkupTab.controls.groupByBar.byIndexLabel": "インデックス別", - "xpack.upgradeAssistant.checkupTab.controls.groupByBar.byIssueLabel": "問題別", - "xpack.upgradeAssistant.checkupTab.deprecations.criticalActionTooltip": "アップグレード前にこの問題を解決してください。", - "xpack.upgradeAssistant.checkupTab.deprecations.criticalLabel": "重大", - "xpack.upgradeAssistant.checkupTab.deprecations.warningActionTooltip": "アップグレード前にこの問題を解決することをお勧めしますが、必須ではありません。", - "xpack.upgradeAssistant.checkupTab.deprecations.warningLabel": "警告", - "xpack.upgradeAssistant.checkupTab.noDeprecationsLabel": "説明がありません", - "xpack.upgradeAssistant.checkupTab.numDeprecationsShownLabel": "{total} 件中 {numShown} 件を表示中", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.checklistStep.cancelButtonLabel": "キャンセル", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.checklistStep.closeButtonLabel": "閉じる", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.checklistStep.continueButtonLabel": "再インデックスを続ける", @@ -24865,16 +24855,6 @@ "xpack.upgradeAssistant.checkupTab.reindexing.flyout.warningsStep.destructiveCallout.calloutDetail": "続行する前に、インデックスをバックアップしてください。再インデックスを続行するには、各変更を承諾してください。", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.warningsStep.destructiveCallout.calloutTitle": "このインデックスには元に戻すことのできない破壊的な変更が含まれています", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.warningsStep.documentationLinkLabel": "ドキュメント", - "xpack.upgradeAssistant.deprecationGroupItem.docLinkText": "ドキュメンテーションを表示", - "xpack.upgradeAssistant.deprecationGroupItem.fixButtonLabel": "修正する手順を表示", - "xpack.upgradeAssistant.deprecationGroupItem.resolveButtonLabel": "クイック解決", - "xpack.upgradeAssistant.deprecationGroupItemTitle": "'{domainId}'は廃止予定の機能を使用しています", - "xpack.upgradeAssistant.deprecationListBar.collapseAllButtonLabel": "すべて縮小", - "xpack.upgradeAssistant.deprecationListBar.expandAllButtonLabel": "すべて拡張", - "xpack.upgradeAssistant.deprecationListSearchBar.filterErrorMessageLabel": "フィルター無効:{searchTermError}", - "xpack.upgradeAssistant.deprecationListSearchBar.placeholderAriaLabel": "フィルター", - "xpack.upgradeAssistant.deprecationListSearchBar.placeholderLabel": "フィルター", - "xpack.upgradeAssistant.deprecationListSearchBar.reloadButtonLabel": "再読み込み", "xpack.upgradeAssistant.emptyPrompt.learnMoreDescription": "{nextMajor}への移行に関する詳細をご覧ください。", "xpack.upgradeAssistant.emptyPrompt.title": "{uaVersion} アップグレードアシスタント", "xpack.upgradeAssistant.emptyPrompt.upgradeAssistantDescription": "アップグレードアシスタントはクラスターの廃止予定の設定を特定し、アップグレード前に問題を解決できるようにします。Elastic {nextMajor}にアップグレードするときにここに戻って確認してください。", @@ -24895,18 +24875,8 @@ "xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorTitle": "一部のKibana廃止予定が正常に取得されませんでした", "xpack.upgradeAssistant.kibanaDeprecations.deprecationLabel": "Kibana", "xpack.upgradeAssistant.kibanaDeprecations.docLinkText": "ドキュメント", - "xpack.upgradeAssistant.kibanaDeprecations.errorMessage": "廃止予定の解決エラー", "xpack.upgradeAssistant.kibanaDeprecations.loadingText": "廃止予定を読み込んでいます...", - "xpack.upgradeAssistant.kibanaDeprecations.pageDescription": "アップグレード前に、ここで一覧の問題を確認し、必要な変更を行ってください。アップグレード前に、重大な問題を解決する必要があります。", "xpack.upgradeAssistant.kibanaDeprecations.pageTitle": "Kibana", - "xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.cancelButtonLabel": "キャンセル", - "xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.modalTitle": "'{domainId}'で廃止予定を解決しますか?", - "xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.resolveButtonLabel": "解決", - "xpack.upgradeAssistant.kibanaDeprecations.stepsModal.closeButtonLabel": "閉じる", - "xpack.upgradeAssistant.kibanaDeprecations.stepsModal.docLinkLabel": "ドキュメンテーションを表示", - "xpack.upgradeAssistant.kibanaDeprecations.stepsModal.modalTitle": "'{domainId}'で廃止予定を解決", - "xpack.upgradeAssistant.kibanaDeprecations.stepsModal.stepTitle": "ステップ{step}", - "xpack.upgradeAssistant.kibanaDeprecations.successMessage": "廃止予定が解決されました", "xpack.upgradeAssistant.kibanaDeprecationStats.criticalDeprecationsLabel": "Kibanaには{criticalDeprecations}個の重大な廃止予定があります", "xpack.upgradeAssistant.kibanaDeprecationStats.criticalDeprecationsTitle": "重大", "xpack.upgradeAssistant.kibanaDeprecationStats.loadingErrorMessage": "Kibana廃止予定の取得中にエラーが発生しました。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 43cb9c95327a8..0e5a45df18be4 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -25230,16 +25230,6 @@ "xpack.upgradeAssistant.breadcrumb.esDeprecationsLabel": "Elasticsearch 弃用", "xpack.upgradeAssistant.breadcrumb.kibanaDeprecationsLabel": "Kibana 弃用", "xpack.upgradeAssistant.breadcrumb.overviewLabel": "升级助手", - "xpack.upgradeAssistant.checkupTab.changeFiltersShowMoreLabel": "更改筛选以显示更多内容。", - "xpack.upgradeAssistant.checkupTab.controls.filterBar.criticalButtonLabel": "紧急", - "xpack.upgradeAssistant.checkupTab.controls.groupByBar.byIndexLabel": "按索引", - "xpack.upgradeAssistant.checkupTab.controls.groupByBar.byIssueLabel": "按问题", - "xpack.upgradeAssistant.checkupTab.deprecations.criticalActionTooltip": "请解决此问题后再升级。", - "xpack.upgradeAssistant.checkupTab.deprecations.criticalLabel": "紧急", - "xpack.upgradeAssistant.checkupTab.deprecations.warningActionTooltip": "建议在升级之前先解决此问题,但这不是必需的。", - "xpack.upgradeAssistant.checkupTab.deprecations.warningLabel": "警告", - "xpack.upgradeAssistant.checkupTab.noDeprecationsLabel": "无弃用内容", - "xpack.upgradeAssistant.checkupTab.numDeprecationsShownLabel": "显示 {numShown} 个,共 {total} 个", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.checklistStep.cancelButtonLabel": "取消", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.checklistStep.closeButtonLabel": "关闭", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.checklistStep.continueButtonLabel": "继续重新索引", @@ -25276,16 +25266,6 @@ "xpack.upgradeAssistant.checkupTab.reindexing.flyout.warningsStep.destructiveCallout.calloutDetail": "继续前备份索引。要继续重新索引,请接受每个更改。", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.warningsStep.destructiveCallout.calloutTitle": "此索引需要无法恢复的破坏性更改", "xpack.upgradeAssistant.checkupTab.reindexing.flyout.warningsStep.documentationLinkLabel": "文档", - "xpack.upgradeAssistant.deprecationGroupItem.docLinkText": "查看文档", - "xpack.upgradeAssistant.deprecationGroupItem.fixButtonLabel": "显示修复步骤", - "xpack.upgradeAssistant.deprecationGroupItem.resolveButtonLabel": "快速解决", - "xpack.upgradeAssistant.deprecationGroupItemTitle": "“{domainId}”正在使用弃用的功能", - "xpack.upgradeAssistant.deprecationListBar.collapseAllButtonLabel": "折叠全部", - "xpack.upgradeAssistant.deprecationListBar.expandAllButtonLabel": "展开全部", - "xpack.upgradeAssistant.deprecationListSearchBar.filterErrorMessageLabel": "筛选无效:{searchTermError}", - "xpack.upgradeAssistant.deprecationListSearchBar.placeholderAriaLabel": "筛选", - "xpack.upgradeAssistant.deprecationListSearchBar.placeholderLabel": "筛选", - "xpack.upgradeAssistant.deprecationListSearchBar.reloadButtonLabel": "重新加载", "xpack.upgradeAssistant.emptyPrompt.learnMoreDescription": "详细了解如何迁移到 {nextMajor}。", "xpack.upgradeAssistant.emptyPrompt.title": "{uaVersion} 升级助手", "xpack.upgradeAssistant.emptyPrompt.upgradeAssistantDescription": "升级助手识别集群中弃用的设置,帮助您在升级前解决问题。需要升级到 Elastic {nextMajor} 时,回到这里查看。", @@ -25306,18 +25286,8 @@ "xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorTitle": "未成功检索全部的 Kibana 弃用", "xpack.upgradeAssistant.kibanaDeprecations.deprecationLabel": "Kibana", "xpack.upgradeAssistant.kibanaDeprecations.docLinkText": "文档", - "xpack.upgradeAssistant.kibanaDeprecations.errorMessage": "解决弃用时出错", "xpack.upgradeAssistant.kibanaDeprecations.loadingText": "正在加载弃用……", - "xpack.upgradeAssistant.kibanaDeprecations.pageDescription": "在升级之前查看此处所列的问题并进行必要的更改。在升级之前必须解决紧急问题。", "xpack.upgradeAssistant.kibanaDeprecations.pageTitle": "Kibana", - "xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.cancelButtonLabel": "取消", - "xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.modalTitle": "在“{domainId}”中解决弃用?", - "xpack.upgradeAssistant.kibanaDeprecations.resolveConfirmationModal.resolveButtonLabel": "解决", - "xpack.upgradeAssistant.kibanaDeprecations.stepsModal.closeButtonLabel": "关闭", - "xpack.upgradeAssistant.kibanaDeprecations.stepsModal.docLinkLabel": "查看文档", - "xpack.upgradeAssistant.kibanaDeprecations.stepsModal.modalTitle": "在“{domainId}”中解决弃用", - "xpack.upgradeAssistant.kibanaDeprecations.stepsModal.stepTitle": "步骤 {step}", - "xpack.upgradeAssistant.kibanaDeprecations.successMessage": "弃用已解决", "xpack.upgradeAssistant.kibanaDeprecationStats.criticalDeprecationsLabel": "Kibana 具有 {criticalDeprecations} 个关键弃用", "xpack.upgradeAssistant.kibanaDeprecationStats.criticalDeprecationsTitle": "紧急", "xpack.upgradeAssistant.kibanaDeprecationStats.loadingErrorMessage": "检索 Kibana 弃用时发生错误。", diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index 1f10802fcb69c..92880074c818a 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -74,6 +74,12 @@ const i18nTexts = { defaultMessage: 'Type', } ), + criticalFilterLabel: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecations.table.criticalFilterLabel', + { + defaultMessage: 'Critical', + } + ), getDeprecationIssue: (domainId: string) => { return i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.table.issueCellDescription', { defaultMessage: '{domainId} is using a deprecated feature', @@ -192,9 +198,7 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ { type: 'is', field: 'level', - name: i18n.translate('xpack.idxMgmt.componentTemplatesList.table.isManagedFilterLabel', { - defaultMessage: 'Critical', - }), + name: i18nTexts.criticalFilterLabel, }, { type: 'field_value_selection', 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 a5f5b515278f4..81495c45420bf 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/types.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/types.ts @@ -7,6 +7,12 @@ import { ResponseError } from '../lib/api'; +export enum LoadingState { + Loading, + Success, + Error, +} + export type DeprecationTableColumns = | 'type' | 'index' From aba66db6de391b7846f93343de1f8b55e3e125a3 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Mon, 30 Aug 2021 15:10:29 -0400 Subject: [PATCH 08/18] update existing CITs --- .../es_deprecations/deprecations_list.test.ts | 2 +- .../deprecations_list.test.ts | 112 +++++++++ .../error_handling.test.ts | 41 ++++ .../kibana_deprecations.helpers.ts | 22 +- .../kibana_deprecations.test.ts | 231 ------------------ .../kibana_deprecations.tsx | 2 +- .../kibana_deprecations_table.tsx | 4 +- .../no_deprecations/no_deprecations.tsx | 9 +- 8 files changed, 174 insertions(+), 249 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts create mode 100644 x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/error_handling.test.ts delete mode 100644 x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.test.ts diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/deprecations_list.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/deprecations_list.test.ts index ffee297f6f574..316e1a65f0890 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/deprecations_list.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/deprecations_list.test.ts @@ -18,7 +18,7 @@ import { createEsDeprecationsMockResponse, } from './mocked_responses'; -describe('Deprecations table', () => { +describe('ES deprecations table', () => { let testBed: ElasticsearchTestBed; const { server, httpRequestsMockHelpers } = setupEnvironment(); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts new file mode 100644 index 0000000000000..94fb4d7b5bdcb --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts @@ -0,0 +1,112 @@ +/* + * 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'; +import { deprecationsServiceMock } from 'src/core/public/mocks'; + +import type { DomainDeprecationDetails } from 'kibana/public'; +import { setupEnvironment } from '../helpers'; +import { KibanaTestBed, setupKibanaPage } from './kibana_deprecations.helpers'; + +const kibanaDeprecationsMockResponse: DomainDeprecationDetails[] = [ + { + correctiveActions: { + manualSteps: ['Step 1', 'Step 2', 'Step 3'], + api: { + method: 'POST', + path: '/test', + }, + }, + domainId: 'test_domain', + level: 'critical', + message: 'Test deprecation message 1', + }, + { + correctiveActions: { + manualSteps: ['Step 1', 'Step 2', 'Step 3'], + }, + domainId: 'test_domain', + level: 'warning', + message: 'Test deprecation message 2', + }, +]; + +describe('Kibana deprecations table', () => { + let testBed: KibanaTestBed; + const { server } = setupEnvironment(); + const deprecationService = deprecationsServiceMock.createStartContract(); + + afterAll(() => { + server.restore(); + }); + + beforeEach(async () => { + await act(async () => { + deprecationService.getAllDeprecations = jest + .fn() + .mockReturnValue(kibanaDeprecationsMockResponse); + + testBed = await setupKibanaPage({ + deprecations: deprecationService, + }); + }); + + testBed.component.update(); + }); + + test('renders deprecations', () => { + const { exists, table } = testBed; + + expect(exists('kibanaDeprecations')).toBe(true); + + const { tableCellsValues } = table.getMetaData('kibanaDeprecationsTable'); + + expect(tableCellsValues.length).toEqual(kibanaDeprecationsMockResponse.length); + }); + + it('refreshes deprecation data', async () => { + const { actions } = testBed; + + await actions.table.clickRefreshButton(); + + expect(deprecationService.getAllDeprecations).toHaveBeenCalledTimes(2); + }); + + it('shows critical and warning deprecations count', () => { + const { find } = testBed; + const criticalDeprecations = kibanaDeprecationsMockResponse.filter( + (deprecation) => deprecation.level === 'critical' + ); + const warningDeprecations = kibanaDeprecationsMockResponse.filter( + (deprecation) => deprecation.level === 'warning' + ); + + expect(find('criticalDeprecationsCount').text()).toContain(criticalDeprecations.length); + + expect(find('warningDeprecationsCount').text()).toContain(warningDeprecations.length); + }); + + describe('No deprecations', () => { + beforeEach(async () => { + await act(async () => { + testBed = await setupKibanaPage({ isReadOnlyMode: false }); + }); + + const { component } = testBed; + + component.update(); + }); + + test('renders prompt', () => { + const { exists, find } = testBed; + expect(exists('noDeprecationsPrompt')).toBe(true); + expect(find('noDeprecationsPrompt').text()).toContain( + 'Your Kibana configuration is up to date' + ); + }); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/error_handling.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/error_handling.test.ts new file mode 100644 index 0000000000000..739ff2c650706 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/error_handling.test.ts @@ -0,0 +1,41 @@ +/* + * 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'; +import { deprecationsServiceMock } from 'src/core/public/mocks'; + +import { setupEnvironment } from '../helpers'; +import { KibanaTestBed, setupKibanaPage } from './kibana_deprecations.helpers'; + +describe('Error handling', () => { + let testBed: KibanaTestBed; + const { server } = setupEnvironment(); + const deprecationService = deprecationsServiceMock.createStartContract(); + + afterAll(() => { + server.restore(); + }); + + test('handles request error', async () => { + await act(async () => { + deprecationService.getAllDeprecations = jest + .fn() + .mockRejectedValue(new Error('Internal Server Error')); + + testBed = await setupKibanaPage({ + deprecations: deprecationService, + }); + }); + + const { component, exists, find } = testBed; + + component.update(); + + expect(exists('kibanaRequestError')).toBe(true); + expect(find('kibanaRequestError').text()).toContain('Could not retrieve Kibana deprecations'); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts index 860c9249b266a..c8ab193ae4394 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts @@ -4,9 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { act } from 'react-dom/test-utils'; import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test/jest'; -import { KibanaDeprecationsContent } from '../../../public/application/components/kibana_deprecations'; +import { KibanaDeprecations } from '../../../public/application/components'; import { WithAppDependencies } from '../helpers'; const testBedConfig: TestBedConfig = { @@ -22,17 +22,23 @@ export type KibanaTestBed = TestBed & { }; const createActions = (testBed: TestBed) => { + const { component, find } = testBed; + /** * User Actions */ - - const clickExpandAll = () => { - const { find } = testBed; - find('expandAll').simulate('click'); + const table = { + clickRefreshButton: async () => { + await act(async () => { + find('refreshButton').simulate('click'); + }); + + component.update(); + }, }; return { - clickExpandAll, + table, }; }; @@ -40,7 +46,7 @@ export const setupKibanaPage = async ( overrides?: Record ): Promise => { const initTestBed = registerTestBed( - WithAppDependencies(KibanaDeprecationsContent, overrides), + WithAppDependencies(KibanaDeprecations, overrides), testBedConfig ); const testBed = await initTestBed(); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.test.ts deleted file mode 100644 index bc6bd47cf37d9..0000000000000 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.test.ts +++ /dev/null @@ -1,231 +0,0 @@ -/* - * 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 type { DomainDeprecationDetails } from 'kibana/public'; -import { act } from 'react-dom/test-utils'; -import { deprecationsServiceMock } from 'src/core/public/mocks'; - -import { setupEnvironment } from '../helpers'; -import { KibanaTestBed, setupKibanaPage } from './kibana_deprecations.helpers'; - -describe('Kibana deprecations', () => { - let testBed: KibanaTestBed; - const { server } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); - - describe('With deprecations', () => { - const kibanaDeprecationsMockResponse: DomainDeprecationDetails[] = [ - { - correctiveActions: { - manualSteps: ['Step 1', 'Step 2', 'Step 3'], - api: { - method: 'POST', - path: '/test', - }, - }, - domainId: 'test_domain', - level: 'critical', - message: 'Test deprecation message', - }, - ]; - - beforeEach(async () => { - await act(async () => { - const deprecationService = deprecationsServiceMock.createStartContract(); - deprecationService.getAllDeprecations = jest - .fn() - .mockReturnValue(kibanaDeprecationsMockResponse); - - testBed = await setupKibanaPage({ - deprecations: deprecationService, - }); - }); - - testBed.component.update(); - }); - - test('renders deprecations', () => { - const { exists, find } = testBed; - expect(exists('kibanaDeprecationsContent')).toBe(true); - expect(find('kibanaDeprecationItem').length).toEqual(1); - }); - - describe('manual steps modal', () => { - test('renders modal with a list of steps to fix a deprecation', async () => { - const { component, actions, exists, find } = testBed; - const deprecation = kibanaDeprecationsMockResponse[0]; - - expect(exists('kibanaDeprecationsContent')).toBe(true); - - // Open all deprecations - actions.clickExpandAll(); - - const accordionTestSubj = `${deprecation.domainId}Deprecation`; - - await act(async () => { - find(`${accordionTestSubj}.stepsButton`).simulate('click'); - }); - - component.update(); - - // We need to read the document "body" as the modal is added there and not inside - // the component DOM tree. - let modal = document.body.querySelector('[data-test-subj="stepsModal"]'); - - expect(modal).not.toBeNull(); - expect(modal!.textContent).toContain(`Resolve deprecation in '${deprecation.domainId}'`); - - const steps: NodeListOf | null = modal!.querySelectorAll( - '[data-test-subj="fixDeprecationSteps"] .euiStep' - ); - - expect(steps).not.toBe(null); - expect(steps.length).toEqual(deprecation!.correctiveActions!.manualSteps!.length); - - await act(async () => { - const closeButton: HTMLButtonElement | null = modal!.querySelector( - '[data-test-subj="closeButton"]' - ); - - closeButton!.click(); - }); - - component.update(); - - // Confirm modal closed and no longer appears in the DOM - modal = document.body.querySelector('[data-test-subj="stepsModal"]'); - expect(modal).toBe(null); - }); - }); - - describe('resolve modal', () => { - test('renders confirmation modal to resolve a deprecation', async () => { - const { component, actions, exists, find } = testBed; - const deprecation = kibanaDeprecationsMockResponse[0]; - - expect(exists('kibanaDeprecationsContent')).toBe(true); - - // Open all deprecations - actions.clickExpandAll(); - - const accordionTestSubj = `${deprecation.domainId}Deprecation`; - - await act(async () => { - find(`${accordionTestSubj}.resolveButton`).simulate('click'); - }); - - component.update(); - - // We need to read the document "body" as the modal is added there and not inside - // the component DOM tree. - let modal = document.body.querySelector('[data-test-subj="resolveModal"]'); - - expect(modal).not.toBe(null); - expect(modal!.textContent).toContain(`Resolve deprecation in '${deprecation.domainId}'`); - - const confirmButton: HTMLButtonElement | null = modal!.querySelector( - '[data-test-subj="confirmModalConfirmButton"]' - ); - - await act(async () => { - confirmButton!.click(); - }); - - component.update(); - - // Confirm modal should close and no longer appears in the DOM - modal = document.body.querySelector('[data-test-subj="resolveModal"]'); - expect(modal).toBe(null); - }); - }); - }); - - describe('No deprecations', () => { - beforeEach(async () => { - await act(async () => { - testBed = await setupKibanaPage({ isReadOnlyMode: false }); - }); - - const { component } = testBed; - - component.update(); - }); - - test('renders prompt', () => { - const { exists, find } = testBed; - expect(exists('noDeprecationsPrompt')).toBe(true); - expect(find('noDeprecationsPrompt').text()).toContain( - 'Your Kibana configuration is up to date' - ); - }); - }); - - describe('Error handling', () => { - test('handles request error', async () => { - await act(async () => { - const deprecationService = deprecationsServiceMock.createStartContract(); - deprecationService.getAllDeprecations = jest - .fn() - .mockRejectedValue(new Error('Internal Server Error')); - - testBed = await setupKibanaPage({ - deprecations: deprecationService, - }); - }); - - const { component, exists, find } = testBed; - - component.update(); - - expect(exists('kibanaRequestError')).toBe(true); - expect(find('kibanaRequestError').text()).toContain('Could not retrieve Kibana deprecations'); - }); - - test('handles deprecation service error', async () => { - const domainId = 'test'; - const kibanaDeprecationsMockResponse: DomainDeprecationDetails[] = [ - { - domainId, - message: `Failed to get deprecations info for plugin "${domainId}".`, - level: 'fetch_error', - correctiveActions: { - manualSteps: ['Check Kibana server logs for error message.'], - }, - }, - ]; - - await act(async () => { - const deprecationService = deprecationsServiceMock.createStartContract(); - deprecationService.getAllDeprecations = jest - .fn() - .mockReturnValue(kibanaDeprecationsMockResponse); - - testBed = await setupKibanaPage({ - deprecations: deprecationService, - }); - }); - - const { component, exists, find, actions } = testBed; - component.update(); - - // Verify top-level callout renders - expect(exists('kibanaPluginError')).toBe(true); - expect(find('kibanaPluginError').text()).toContain( - 'Not all Kibana deprecations were retrieved successfully' - ); - - // Open all deprecations - actions.clickExpandAll(); - - // Verify callout also displays for deprecation with error - expect(exists(`${domainId}Error`)).toBe(true); - }); - }); -}); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx index 46423f2f7fbd4..50c2d00a59033 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx @@ -253,7 +253,7 @@ export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) if (kibanaDeprecations?.length) { return ( -
+
= ({ {i18nTexts.refreshButtonLabel} , diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/no_deprecations/no_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/no_deprecations/no_deprecations.tsx index 2f034d461a24f..bed92d3b92ccf 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/no_deprecations/no_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/no_deprecations/no_deprecations.tsx @@ -11,12 +11,9 @@ import { EuiFlexGroup, EuiFlexItem, EuiText, EuiIcon, EuiSpacer } from '@elastic import { i18n } from '@kbn/i18n'; const i18nTexts = { - noDeprecationsText: i18n.translate( - 'xpack.upgradeAssistant.esDeprecationStats.noDeprecationsText', - { - defaultMessage: 'No warnings. Good to go!', - } - ), + noDeprecationsText: i18n.translate('xpack.upgradeAssistant.noDeprecationsText', { + defaultMessage: 'No warnings. Good to go!', + }), }; export const NoDeprecations: FunctionComponent = () => { From 3ebc4ea89fffabbbbfd091db20eb8bcef1070bbb Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Tue, 31 Aug 2021 11:47:09 -0400 Subject: [PATCH 09/18] add more CITs --- .../deprecation_details_flyout.test.ts | 118 ++++++++++++++++++ .../deprecations_list.test.ts | 84 ++++++++----- .../error_handling.test.ts | 30 +++++ .../kibana_deprecations.helpers.ts | 63 +++++++++- .../kibana_deprecations/mocked_responses.ts | 32 +++++ .../deprecation_details_flyout.tsx | 7 +- .../kibana_deprecation_errors.tsx | 73 ----------- .../kibana_deprecations.tsx | 27 +++- .../kibana_deprecations_table.tsx | 10 +- 9 files changed, 327 insertions(+), 117 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts create mode 100644 x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/mocked_responses.ts delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecation_errors.tsx diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts new file mode 100644 index 0000000000000..0f86455485067 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts @@ -0,0 +1,118 @@ +/* + * 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'; +import { deprecationsServiceMock } from 'src/core/public/mocks'; + +import { setupEnvironment } from '../helpers'; +import { KibanaTestBed, setupKibanaPage } from './kibana_deprecations.helpers'; +import { kibanaDeprecationsMockResponse } from './mocked_responses'; + +describe('Kibana deprecation details flyout', () => { + let testBed: KibanaTestBed; + const { server } = setupEnvironment(); + const deprecationService = deprecationsServiceMock.createStartContract(); + + afterAll(() => { + server.restore(); + }); + + beforeEach(async () => { + await act(async () => { + deprecationService.getAllDeprecations = jest + .fn() + .mockReturnValue(kibanaDeprecationsMockResponse); + + testBed = await setupKibanaPage({ + deprecations: deprecationService, + }); + }); + + testBed.component.update(); + }); + + describe('Deprecation with manual steps', () => { + test('renders flyout with manual steps only', async () => { + const { find, exists, actions } = testBed; + const manualDeprecation = kibanaDeprecationsMockResponse[1]; + + await actions.table.clickDeprecationAt(1); + + expect(exists('kibanaDeprecationDetails')).toBe(true); + expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe( + `'${manualDeprecation.domainId}' is using a deprecated feature` + ); + expect(find('manualStepsList').find('li').length).toEqual( + manualDeprecation.correctiveActions.manualSteps.length + ); + expect(exists('resolveButton')).toBe(false); + expect(exists('quickResolveCallout')).toBe(false); + }); + }); + + describe('Deprecation with automatic resolution', () => { + test('resolves deprecation successfully', async () => { + const { find, exists, actions } = testBed; + const quickResolveDeprecation = kibanaDeprecationsMockResponse[0]; + + deprecationService.resolveDeprecation = jest.fn().mockReturnValue({ status: 'ok' }); + + await actions.table.clickDeprecationAt(0); + + expect(exists('kibanaDeprecationDetails')).toBe(true); + expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe( + `'${quickResolveDeprecation.domainId}' is using a deprecated feature` + ); + expect(exists('resolveSteps')).toBe(true); + expect(exists('quickResolveCallout')).toBe(true); + expect(exists('resolveButton')).toBe(true); + + await actions.flyout.clickResolveButton(); + + expect(exists('kibanaDeprecationDetails')).toBe(false); + + // Reopen the flyout + await actions.table.clickDeprecationAt(0); + + expect(exists('resolveSteps')).toBe(false); + expect(find('resolveButton').props().disabled).toBe(true); + expect(find('resolveButton').text()).toContain('Resolved'); + }); + + test('handles resolve failure', async () => { + const { find, exists, actions } = testBed; + const quickResolveDeprecation = kibanaDeprecationsMockResponse[0]; + + deprecationService.resolveDeprecation = jest + .fn() + .mockReturnValue({ status: 'fail', reason: 'resolve failed' }); + + await actions.table.clickDeprecationAt(0); + + expect(exists('kibanaDeprecationDetails')).toBe(true); + expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe( + `'${quickResolveDeprecation.domainId}' is using a deprecated feature` + ); + expect(exists('resolveSteps')).toBe(true); + expect(exists('quickResolveCallout')).toBe(true); + expect(exists('resolveButton')).toBe(true); + + await actions.flyout.clickResolveButton(); + + // Verify flyout closed + expect(exists('kibanaDeprecationDetails')).toBe(false); + + // Reopen the flyout + await actions.table.clickDeprecationAt(0); + + expect(exists('deleteSettingsError')).toBe(true); + expect(exists('resolveSteps')).toBe(true); + expect(find('resolveButton').props().disabled).toBe(false); + expect(find('resolveButton').text()).toContain('Try again'); + }); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts index 94fb4d7b5bdcb..65c250dce99a5 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts @@ -8,32 +8,19 @@ import { act } from 'react-dom/test-utils'; import { deprecationsServiceMock } from 'src/core/public/mocks'; -import type { DomainDeprecationDetails } from 'kibana/public'; import { setupEnvironment } from '../helpers'; import { KibanaTestBed, setupKibanaPage } from './kibana_deprecations.helpers'; - -const kibanaDeprecationsMockResponse: DomainDeprecationDetails[] = [ - { - correctiveActions: { - manualSteps: ['Step 1', 'Step 2', 'Step 3'], - api: { - method: 'POST', - path: '/test', - }, - }, - domainId: 'test_domain', - level: 'critical', - message: 'Test deprecation message 1', - }, - { - correctiveActions: { - manualSteps: ['Step 1', 'Step 2', 'Step 3'], - }, - domainId: 'test_domain', - level: 'warning', - message: 'Test deprecation message 2', - }, -]; +import { kibanaDeprecationsMockResponse } from './mocked_responses'; + +const criticalDeprecations = kibanaDeprecationsMockResponse.filter( + (deprecation) => deprecation.level === 'critical' +); +const warningDeprecations = kibanaDeprecationsMockResponse.filter( + (deprecation) => deprecation.level === 'warning' +); +const configDeprecations = kibanaDeprecationsMockResponse.filter( + (deprecation) => deprecation.deprecationType === 'config' +); describe('Kibana deprecations table', () => { let testBed: KibanaTestBed; @@ -78,18 +65,53 @@ describe('Kibana deprecations table', () => { it('shows critical and warning deprecations count', () => { const { find } = testBed; - const criticalDeprecations = kibanaDeprecationsMockResponse.filter( - (deprecation) => deprecation.level === 'critical' - ); - const warningDeprecations = kibanaDeprecationsMockResponse.filter( - (deprecation) => deprecation.level === 'warning' - ); expect(find('criticalDeprecationsCount').text()).toContain(criticalDeprecations.length); - expect(find('warningDeprecationsCount').text()).toContain(warningDeprecations.length); }); + describe('Search bar', () => { + it('filters by "critical" status', async () => { + const { actions, table } = testBed; + + await actions.searchBar.clickCriticalFilterButton(); + + const { rows: criticalRows } = table.getMetaData('kibanaDeprecationsTable'); + + expect(criticalRows.length).toEqual(criticalDeprecations.length); + + await actions.searchBar.clickCriticalFilterButton(); + + const { rows: allRows } = table.getMetaData('kibanaDeprecationsTable'); + + expect(allRows.length).toEqual(kibanaDeprecationsMockResponse.length); + }); + + it('filters by type', async () => { + const { component, table, actions } = testBed; + + await actions.searchBar.clickTypeFilterDropdownAt(0); + + // We need to read the document "body" as the filter dropdown options are added there and not inside + // the component DOM tree. + const configTypeFilterButton: HTMLButtonElement | null = document.body.querySelector( + '.euiFilterSelect__items .euiFilterSelectItem' + ); + + expect(configTypeFilterButton).not.toBeNull(); + + await act(async () => { + configTypeFilterButton!.click(); + }); + + component.update(); + + const { rows: configRows } = table.getMetaData('kibanaDeprecationsTable'); + + expect(configRows.length).toEqual(configDeprecations.length); + }); + }); + describe('No deprecations', () => { beforeEach(async () => { await act(async () => { diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/error_handling.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/error_handling.test.ts index 739ff2c650706..83532ca39521a 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/error_handling.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/error_handling.test.ts @@ -10,6 +10,7 @@ import { deprecationsServiceMock } from 'src/core/public/mocks'; import { setupEnvironment } from '../helpers'; import { KibanaTestBed, setupKibanaPage } from './kibana_deprecations.helpers'; +import { kibanaDeprecationsMockResponse } from './mocked_responses'; describe('Error handling', () => { let testBed: KibanaTestBed; @@ -20,6 +21,35 @@ describe('Error handling', () => { server.restore(); }); + test('handles plugin error', async () => { + await act(async () => { + deprecationService.getAllDeprecations = jest.fn().mockReturnValue([ + ...kibanaDeprecationsMockResponse, + { + domainId: 'failed_plugin_id', + message: `Failed to get deprecations info for plugin "failed_plugin_id".`, + level: 'fetch_error', + correctiveActions: { + manualSteps: ['Check Kibana server logs for error message.'], + }, + }, + ]); + + testBed = await setupKibanaPage({ + deprecations: deprecationService, + }); + }); + + const { component, exists, find } = testBed; + + component.update(); + + expect(exists('kibanaDeprecationErrors')).toBe(true); + expect(find('kibanaDeprecationErrors').text()).toContain( + 'Deprecation warnings may be incomplete' + ); + }); + test('handles request error', async () => { await act(async () => { deprecationService.getAllDeprecations = jest diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts index c8ab193ae4394..fdcc3594dad36 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts @@ -5,7 +5,7 @@ * 2.0. */ import { act } from 'react-dom/test-utils'; -import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test/jest'; +import { registerTestBed, TestBed, TestBedConfig, findTestSubject } from '@kbn/test/jest'; import { KibanaDeprecations } from '../../../public/application/components'; import { WithAppDependencies } from '../helpers'; @@ -22,12 +22,12 @@ export type KibanaTestBed = TestBed & { }; const createActions = (testBed: TestBed) => { - const { component, find } = testBed; + const { component, find, table } = testBed; /** * User Actions */ - const table = { + const tableActions = { clickRefreshButton: async () => { await act(async () => { find('refreshButton').simulate('click'); @@ -35,10 +35,65 @@ const createActions = (testBed: TestBed) => { component.update(); }, + + clickDeprecationAt: async (index: number) => { + const { rows } = table.getMetaData('kibanaDeprecationsTable'); + + const deprecationDetailsLink = findTestSubject( + rows[index].reactWrapper, + 'deprecationDetailsLink' + ); + + await act(async () => { + deprecationDetailsLink.simulate('click'); + }); + component.update(); + }, + }; + + const searchBarActions = { + clickTypeFilterDropdownAt: async (index: number) => { + await act(async () => { + // EUI doesn't support data-test-subj's on the filter buttons, so we must access via CSS selector + find('kibanaDeprecations') + .find('.euiSearchBar__filtersHolder') + .find('.euiPopover') + .find('.euiFilterButton') + .at(index) + .simulate('click'); + }); + + component.update(); + }, + + clickCriticalFilterButton: async () => { + await act(async () => { + // EUI doesn't support data-test-subj's on the filter buttons, so we must access via CSS selector + find('kibanaDeprecations') + .find('.euiSearchBar__filtersHolder') + .find('.euiFilterButton') + .at(0) + .simulate('click'); + }); + + component.update(); + }, + }; + + const flyoutActions = { + clickResolveButton: async () => { + await act(async () => { + find('resolveButton').simulate('click'); + }); + + component.update(); + }, }; return { - table, + table: tableActions, + flyout: flyoutActions, + searchBar: searchBarActions, }; }; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/mocked_responses.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/mocked_responses.ts new file mode 100644 index 0000000000000..7db1861981b86 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/mocked_responses.ts @@ -0,0 +1,32 @@ +/* + * 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 type { DomainDeprecationDetails } from 'kibana/public'; + +export const kibanaDeprecationsMockResponse: DomainDeprecationDetails[] = [ + { + correctiveActions: { + manualSteps: ['Step 1', 'Step 2', 'Step 3'], + api: { + method: 'POST', + path: '/test', + }, + }, + domainId: 'test_domain_1', + level: 'critical', + message: 'Test deprecation message 1', + deprecationType: 'config', + }, + { + correctiveActions: { + manualSteps: ['Step 1', 'Step 2', 'Step 3'], + }, + domainId: 'test_domain_2', + level: 'warning', + message: 'Test deprecation message 2', + deprecationType: 'feature', + }, +]; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx index 3fd9631dd72c3..42711fb4f9e9d 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx @@ -178,7 +178,7 @@ export const DeprecationDetailsFlyout = ({ {/* Hide resolution steps if already resolved */} {deprecationResolutionState?.resolveDeprecationStatus !== 'ok' && ( - <> +
{correctiveActions.api && ( <> -
    +
      {correctiveActions.manualSteps.map((step, stepIndex) => (
    1. {step} @@ -209,7 +209,7 @@ export const DeprecationDetailsFlyout = ({ ))}
    - +
)} @@ -226,6 +226,7 @@ export const DeprecationDetailsFlyout = ({ resolveDeprecation(deprecation)} isLoading={Boolean( deprecationResolutionState?.resolveDeprecationStatus === 'in_progress' diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecation_errors.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecation_errors.tsx deleted file mode 100644 index 79ada21941b56..0000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecation_errors.tsx +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 React from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiPageContent, EuiEmptyPrompt } from '@elastic/eui'; - -interface Props { - errorType: 'pluginError' | 'requestError'; -} - -const i18nTexts = { - pluginError: { - title: i18n.translate('xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorTitle', { - defaultMessage: 'Not all Kibana deprecations were retrieved successfully', - }), - description: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorDescription', - { - defaultMessage: 'Check the Kibana server logs for errors.', - } - ), - }, - loadingError: { - title: i18n.translate('xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorTitle', { - defaultMessage: 'Could not retrieve Kibana deprecations', - }), - description: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorDescription', - { - defaultMessage: 'Check the Kibana server logs for errors.', - } - ), - }, -}; - -export const KibanaDeprecationErrors: React.FunctionComponent = ({ errorType }) => { - if (errorType === 'pluginError') { - return ( - - {i18nTexts.pluginError.title}} - body={

{i18nTexts.pluginError.description}

} - /> -
- ); - } - - return ( - - {i18nTexts.loadingError.title}} - body={

{i18nTexts.loadingError.description}

} - /> -
- ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx index 50c2d00a59033..4cfd13a7dffde 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx @@ -8,7 +8,7 @@ import React, { useEffect, useState, useCallback, useMemo } from 'react'; import uuid from 'uuid'; import { withRouter, RouteComponentProps } from 'react-router-dom'; -import { EuiPageContent, EuiPageHeader, EuiSpacer, EuiCallOut } from '@elastic/eui'; +import { EuiPageContent, EuiPageHeader, EuiSpacer, EuiCallOut, EuiEmptyPrompt } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -16,7 +16,6 @@ import type { DomainDeprecationDetails } from 'kibana/public'; import { SectionLoading, GlobalFlyout } from '../../../shared_imports'; import { useAppContext } from '../../app_context'; import { NoDeprecationsPrompt, DeprecationCount } from '../shared'; -import { KibanaDeprecationErrors } from './kibana_deprecation_errors'; import { KibanaDeprecationsTable } from './kibana_deprecations_table'; import { DeprecationDetailsFlyout, @@ -68,6 +67,15 @@ const i18nTexts = { pluginIds: pluginIds.join(', '), }, }), + requestErrorTitle: i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.requestErrorTitle', { + defaultMessage: 'Could not retrieve Kibana deprecations', + }), + requestErrorDescription: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecationErrors.requestErrorDescription', + { + defaultMessage: 'Check the Kibana server logs for errors.', + } + ), }; export interface DeprecationResolutionState { @@ -293,7 +301,20 @@ export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) } if (error) { - return ; + return ( + + {i18nTexts.requestErrorTitle}} + body={

{i18nTexts.requestErrorDescription}

} + /> +
+ ); } return null; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index 35091a894eb2a..a94687e26a3f6 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -141,7 +141,10 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ deprecation: KibanaDeprecationDetails ) => { return ( - toggleFlyout(deprecation)}> + toggleFlyout(deprecation)} + data-test-subj="deprecationDetailsLink" + > {/* This will be replaced with a custom title once https://github.com/elastic/kibana/pull/109840 is merged */} {i18nTexts.getDeprecationIssue(domainId)} @@ -196,9 +199,10 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ const searchConfig: Search = { filters: [ { - type: 'is', - field: 'level', + type: 'field_value_toggle', name: i18nTexts.criticalFilterLabel, + field: 'level', + value: 'critical', }, { type: 'field_value_selection', From 75c699d936cc468ae80d1cc25ff8df833be1583d Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Tue, 31 Aug 2021 12:01:40 -0400 Subject: [PATCH 10/18] update translations --- x-pack/plugins/translations/translations/ja-JP.json | 4 ---- x-pack/plugins/translations/translations/zh-CN.json | 4 ---- 2 files changed, 8 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 84e060a48c5a8..b66df144b631a 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -24869,10 +24869,6 @@ "xpack.upgradeAssistant.esDeprecationStats.criticalDeprecationsTitle": "重大", "xpack.upgradeAssistant.esDeprecationStats.loadingText": "Elasticsearchの廃止統計情報を読み込んでいます...", "xpack.upgradeAssistant.esDeprecationStats.statsTitle": "Elasticsearch", - "xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorDescription": "エラーについては、Kibanaサーバーログを確認してください。", - "xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorTitle": "Kibana廃止予定を取得できませんでした", - "xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorDescription": "エラーについては、Kibanaサーバーログを確認してください。", - "xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorTitle": "一部のKibana廃止予定が正常に取得されませんでした", "xpack.upgradeAssistant.kibanaDeprecations.deprecationLabel": "Kibana", "xpack.upgradeAssistant.kibanaDeprecations.docLinkText": "ドキュメント", "xpack.upgradeAssistant.kibanaDeprecations.loadingText": "廃止予定を読み込んでいます...", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 0e5a45df18be4..edc943a2c0ab7 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -25280,10 +25280,6 @@ "xpack.upgradeAssistant.esDeprecationStats.criticalDeprecationsTitle": "紧急", "xpack.upgradeAssistant.esDeprecationStats.loadingText": "正在加载 Elasticsearch 弃用统计……", "xpack.upgradeAssistant.esDeprecationStats.statsTitle": "Elasticsearch", - "xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorDescription": "请在 Kibana 服务器日志中查看错误。", - "xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorTitle": "无法检索 Kibana 弃用", - "xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorDescription": "请在 Kibana 服务器日志中查看错误。", - "xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorTitle": "未成功检索全部的 Kibana 弃用", "xpack.upgradeAssistant.kibanaDeprecations.deprecationLabel": "Kibana", "xpack.upgradeAssistant.kibanaDeprecations.docLinkText": "文档", "xpack.upgradeAssistant.kibanaDeprecations.loadingText": "正在加载弃用……", From dd6f246fca44bed1750381be3031ce88d17ea51f Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Tue, 31 Aug 2021 13:07:57 -0400 Subject: [PATCH 11/18] update tests --- .../deprecation_details_flyout.test.ts | 34 +++++++++++++------ .../deprecation_details_flyout.tsx | 2 +- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts index 3c1f96193a044..425ae5cea4d9d 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts @@ -53,8 +53,10 @@ describe('Kibana deprecation details flyout', () => { expect(find('manualStepsList').find('li').length).toEqual( manualDeprecation.correctiveActions.manualSteps.length ); - expect(exists('resolveButton')).toBe(false); + + // Quick resolve callout and button should not display expect(exists('quickResolveCallout')).toBe(false); + expect(exists('resolveButton')).toBe(false); }); }); @@ -63,26 +65,30 @@ describe('Kibana deprecation details flyout', () => { const { find, exists, actions } = testBed; const quickResolveDeprecation = kibanaDeprecationsMockResponse[0]; - deprecationService.resolveDeprecation = jest.fn().mockReturnValue({ status: 'ok' }); - await actions.table.clickDeprecationAt(0); expect(exists('kibanaDeprecationDetails')).toBe(true); expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe( `'${quickResolveDeprecation.domainId}' is using a deprecated feature` ); - expect(exists('resolveSteps')).toBe(true); + expect(find('manualStepsList').find('li').length).toEqual( + quickResolveDeprecation.correctiveActions.manualSteps.length + ); + + // Quick resolve callout and button should display expect(exists('quickResolveCallout')).toBe(true); expect(exists('resolveButton')).toBe(true); await actions.flyout.clickResolveButton(); + // Flyout should close after button click expect(exists('kibanaDeprecationDetails')).toBe(false); // Reopen the flyout await actions.table.clickDeprecationAt(0); - expect(exists('resolveSteps')).toBe(false); + // Resolve information should not display and Quick resolve button should be disabled + expect(exists('resolveSection')).toBe(false); expect(find('resolveButton').props().disabled).toBe(true); expect(find('resolveButton').text()).toContain('Resolved'); }); @@ -91,9 +97,12 @@ describe('Kibana deprecation details flyout', () => { const { find, exists, actions } = testBed; const quickResolveDeprecation = kibanaDeprecationsMockResponse[0]; - deprecationService.resolveDeprecation = jest - .fn() - .mockReturnValue({ status: 'fail', reason: 'resolve failed' }); + deprecationService.resolveDeprecation.mockReturnValue( + Promise.resolve({ + status: 'fail', + reason: 'resolve failed', + }) + ); await actions.table.clickDeprecationAt(0); @@ -101,20 +110,23 @@ describe('Kibana deprecation details flyout', () => { expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe( `'${quickResolveDeprecation.domainId}' is using a deprecated feature` ); - expect(exists('resolveSteps')).toBe(true); + + // Quick resolve callout and button should display expect(exists('quickResolveCallout')).toBe(true); expect(exists('resolveButton')).toBe(true); await actions.flyout.clickResolveButton(); - // Verify flyout closed + // Flyout should close after button click expect(exists('kibanaDeprecationDetails')).toBe(false); // Reopen the flyout await actions.table.clickDeprecationAt(0); + // Verify error displays expect(exists('quickResolveError')).toBe(true); - expect(exists('resolveSteps')).toBe(true); + // Resolve information should display and Quick resolve button should be enabled + expect(exists('resolveSection')).toBe(true); expect(find('resolveButton').props().disabled).toBe(false); expect(find('resolveButton').text()).toContain('Try again'); }); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx index 44ae2ddeaeb6f..514e7a6360de6 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx @@ -178,7 +178,7 @@ export const DeprecationDetailsFlyout = ({ {/* Hide resolution steps if already resolved */} {deprecationResolutionState?.resolveDeprecationStatus !== 'ok' && ( -
+
{correctiveActions.api && ( <> Date: Tue, 31 Aug 2021 13:16:21 -0400 Subject: [PATCH 12/18] revert testing change to reporting --- x-pack/plugins/reporting/server/routes/deprecations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/reporting/server/routes/deprecations.ts b/x-pack/plugins/reporting/server/routes/deprecations.ts index fa171e3adecfe..874885e2258ae 100644 --- a/x-pack/plugins/reporting/server/routes/deprecations.ts +++ b/x-pack/plugins/reporting/server/routes/deprecations.ts @@ -94,7 +94,7 @@ export const registerDeprecationsRoutes = (reporting: ReportingCore, logger: Log ); router.put( - { path: `${API_MIGRATE_ILM_POLICY_URL}/foo`, validate: false }, + { path: API_MIGRATE_ILM_POLICY_URL, validate: false }, authzWrapper(async ({ core: { elasticsearch } }, req, res) => { const store = await reporting.getStore(); const { From 4a7d189248f02d5a275a7feb79e0e74e1797ec09 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Tue, 31 Aug 2021 15:27:34 -0400 Subject: [PATCH 13/18] add a11y test for kibana deprecations flyout --- .../deprecation_details_flyout.tsx | 6 ++- .../kibana_deprecations_table.tsx | 4 +- .../accessibility/apps/upgrade_assistant.ts | 42 +++++++++++++------ .../upgrade_assistant/upgrade_assistant.ts | 2 +- x-pack/test/functional/config.js | 1 + .../page_objects/upgrade_assistant_page.ts | 14 +++++++ 6 files changed, 51 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx index 514e7a6360de6..a5ebf43e21a04 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx @@ -144,7 +144,9 @@ export const DeprecationDetailsFlyout = ({ {/* This will be replaced with a custom title once https://github.com/elastic/kibana/pull/109840 is merged */} -

{i18nTexts.getDeprecationTitle(domainId)}

+

+ {i18nTexts.getDeprecationTitle(domainId)} +

@@ -203,7 +205,7 @@ export const DeprecationDetailsFlyout = ({
    {correctiveActions.manualSteps.map((step, stepIndex) => ( -
  1. +
  2. {step}
  3. ))} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index a94687e26a3f6..cd4295d8b6d60 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -248,8 +248,8 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ rowProps={() => ({ 'data-test-subj': 'row', })} - cellProps={() => ({ - 'data-test-subj': 'cell', + cellProps={(deprecation, field) => ({ + 'data-test-subj': `${field.name.toLowerCase()}Cell`, })} data-test-subj="kibanaDeprecationsTable" tableLayout="auto" diff --git a/x-pack/test/accessibility/apps/upgrade_assistant.ts b/x-pack/test/accessibility/apps/upgrade_assistant.ts index aee227b01ed83..050c87fcd0d2b 100644 --- a/x-pack/test/accessibility/apps/upgrade_assistant.ts +++ b/x-pack/test/accessibility/apps/upgrade_assistant.ts @@ -76,22 +76,38 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await a11y.testAppSnapshot(); }); - it('Kibana deprecations page', async () => { - await PageObjects.common.navigateToUrl( - 'management', - 'stack/upgrade_assistant/kibana_deprecations', - { - ensureCurrentUrl: false, - shouldLoginIfPrompted: false, - shouldUseHashForSubUrl: false, - } - ); + describe('Kibana deprecations page', () => { + beforeEach(async () => { + await PageObjects.common.navigateToUrl( + 'management', + 'stack/upgrade_assistant/kibana_deprecations', + { + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + shouldUseHashForSubUrl: false, + } + ); - await retry.waitFor('Kibana deprecations to be visible', async () => { - return testSubjects.exists('kibanaDeprecationsContent'); + await retry.waitFor('Kibana deprecations to be visible', async () => { + return testSubjects.exists('kibanaDeprecations'); + }); }); - await a11y.testAppSnapshot(); + it('Deprecations table', async () => { + await a11y.testAppSnapshot(); + }); + + it('Deprecation details flyout', async () => { + await PageObjects.upgradeAssistant.clickKibanaDeprecation( + 'xpack.securitySolution is using a deprecated feature' // This deprecation was added to the test runner config so should be guaranteed + ); + + await retry.waitFor('Kibana deprecation details flyout to be visible', async () => { + return testSubjects.exists('kibanaDeprecationDetails'); + }); + + await a11y.testAppSnapshot(); + }); }); }); } diff --git a/x-pack/test/functional/apps/upgrade_assistant/upgrade_assistant.ts b/x-pack/test/functional/apps/upgrade_assistant/upgrade_assistant.ts index 4e552b6f889f6..93af80d5e9501 100644 --- a/x-pack/test/functional/apps/upgrade_assistant/upgrade_assistant.ts +++ b/x-pack/test/functional/apps/upgrade_assistant/upgrade_assistant.ts @@ -105,7 +105,7 @@ export default function upgradeAssistantFunctionalTests({ await PageObjects.upgradeAssistant.clickKibanaDeprecationsPanel(); await retry.waitFor('Kibana deprecations table to be visible', async () => { - return testSubjects.exists('kibanaDeprecationsContent'); + return testSubjects.exists('kibanaDeprecations'); }); }); }); diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index 1c0e4f9c2d50d..93f9db3d3be07 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -98,6 +98,7 @@ export default async function ({ readConfigFile }) { '--timelion.ui.enabled=true', '--savedObjects.maxImportPayloadBytes=10485760', // for OSS test management/_import_objects '--xpack.observability.unsafe.cases.enabled=true', + '--xpack.siem.enabled=true', // Used to trigger Kibana deprecation warning in UA (renamed config) ], }, uiSettings: { diff --git a/x-pack/test/functional/page_objects/upgrade_assistant_page.ts b/x-pack/test/functional/page_objects/upgrade_assistant_page.ts index 32332620ffc59..35328737f6cf2 100644 --- a/x-pack/test/functional/page_objects/upgrade_assistant_page.ts +++ b/x-pack/test/functional/page_objects/upgrade_assistant_page.ts @@ -40,4 +40,18 @@ export class UpgradeAssistantPageObject extends FtrService { await this.testSubjects.click('kibanaStatsPanel'); }); } + + async clickKibanaDeprecation(selectedIssue: string) { + const table = await this.testSubjects.find('kibanaDeprecationsTable'); + const rows = await table.findAllByTestSubject('row'); + + const selectedRow = rows.find(async (row) => { + const issue = await (await row.findByTestSubject('issueCell')).getVisibleText(); + return issue === selectedIssue; + }); + + const issueLink = await selectedRow.findByTestSubject('deprecationDetailsLink'); + + await issueLink.click(); + } } From 4634f908d0e826f7e988b1b0cffbf42dc466eb2b Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Tue, 31 Aug 2021 20:05:03 -0400 Subject: [PATCH 14/18] fix TS --- .../kibana_deprecations/kibana_deprecations_table.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index cd4295d8b6d60..7262f9fa98aab 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -249,7 +249,7 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ 'data-test-subj': 'row', })} cellProps={(deprecation, field) => ({ - 'data-test-subj': `${field.name.toLowerCase()}Cell`, + 'data-test-subj': `${((field?.name as string) || 'table').toLowerCase()}Cell`, })} data-test-subj="kibanaDeprecationsTable" tableLayout="auto" From bb7ac78e5aac06ff58f644f8d37cff63dc334f18 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 1 Sep 2021 08:45:50 -0400 Subject: [PATCH 15/18] fix tests --- .../functional/page_objects/upgrade_assistant_page.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/test/functional/page_objects/upgrade_assistant_page.ts b/x-pack/test/functional/page_objects/upgrade_assistant_page.ts index 35328737f6cf2..406800d775417 100644 --- a/x-pack/test/functional/page_objects/upgrade_assistant_page.ts +++ b/x-pack/test/functional/page_objects/upgrade_assistant_page.ts @@ -50,8 +50,11 @@ export class UpgradeAssistantPageObject extends FtrService { return issue === selectedIssue; }); - const issueLink = await selectedRow.findByTestSubject('deprecationDetailsLink'); - - await issueLink.click(); + if (selectedRow) { + const issueLink = await selectedRow.findByTestSubject('deprecationDetailsLink'); + await issueLink.click(); + } else { + this.log.debug('Unable to find selected deprecation row'); + } } } From 4c5dd0e8d4a7a592d7f7735f1019dc0bff9c61bc Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 1 Sep 2021 13:18:02 -0400 Subject: [PATCH 16/18] fix merge conflict --- x-pack/test/functional/config.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index ca11043ad119b..e29b9a2629cd5 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -98,11 +98,8 @@ export default async function ({ readConfigFile }) { '--timelion.ui.enabled=true', '--savedObjects.maxImportPayloadBytes=10485760', // for OSS test management/_import_objects '--xpack.observability.unsafe.cases.enabled=true', -<<<<<<< HEAD '--xpack.siem.enabled=true', // Used to trigger Kibana deprecation warning in UA (renamed config) -======= '--xpack.observability.unsafe.alertingExperience.enabled=true', // NOTE: Can be removed once enabled by default ->>>>>>> 94770b0092ef4027870587aea8566b5318cbb280 ], }, uiSettings: { From 677363646bb9dc2403af31a07129168d7feb40ef Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 1 Sep 2021 14:56:14 -0400 Subject: [PATCH 17/18] use deprecation title from deprecation service --- .../deprecation_details_flyout.test.ts | 8 +++----- .../deprecation_details_flyout.tsx | 15 ++------------- .../kibana_deprecations_table.tsx | 18 +++--------------- .../accessibility/apps/upgrade_assistant.ts | 2 +- 4 files changed, 9 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts index 425ae5cea4d9d..c65f15fda2e3c 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecation_details_flyout.test.ts @@ -47,9 +47,7 @@ describe('Kibana deprecation details flyout', () => { await actions.table.clickDeprecationAt(1); expect(exists('kibanaDeprecationDetails')).toBe(true); - expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe( - `'${manualDeprecation.domainId}' is using a deprecated feature` - ); + expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe(manualDeprecation.title); expect(find('manualStepsList').find('li').length).toEqual( manualDeprecation.correctiveActions.manualSteps.length ); @@ -69,7 +67,7 @@ describe('Kibana deprecation details flyout', () => { expect(exists('kibanaDeprecationDetails')).toBe(true); expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe( - `'${quickResolveDeprecation.domainId}' is using a deprecated feature` + quickResolveDeprecation.title ); expect(find('manualStepsList').find('li').length).toEqual( quickResolveDeprecation.correctiveActions.manualSteps.length @@ -108,7 +106,7 @@ describe('Kibana deprecation details flyout', () => { expect(exists('kibanaDeprecationDetails')).toBe(true); expect(find('kibanaDeprecationDetails.flyoutTitle').text()).toBe( - `'${quickResolveDeprecation.domainId}' is using a deprecated feature` + quickResolveDeprecation.title ); // Quick resolve callout and button should display diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx index a5ebf43e21a04..d9d7b50c87f0c 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx @@ -36,14 +36,6 @@ export interface DeprecationDetailsFlyoutProps { } const i18nTexts = { - getDeprecationTitle: (domainId: string) => { - return i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.flyout.flyoutTitle', { - defaultMessage: "'{domainId}' is using a deprecated feature", - values: { - domainId, - }, - }); - }, learnMoreLinkLabel: i18n.translate( 'xpack.upgradeAssistant.kibanaDeprecations.flyout.learnMoreLinkLabel', { @@ -137,16 +129,13 @@ export const DeprecationDetailsFlyout = ({ resolveDeprecation, deprecationResolutionState, }: DeprecationDetailsFlyoutProps) => { - const { documentationUrl, message, correctiveActions, domainId } = deprecation; + const { documentationUrl, message, correctiveActions, title } = deprecation; return ( <> - {/* This will be replaced with a custom title once https://github.com/elastic/kibana/pull/109840 is merged */} -

    - {i18nTexts.getDeprecationTitle(domainId)} -

    +

    {title}

    diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index 7262f9fa98aab..ce0fac22a977c 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -80,14 +80,6 @@ const i18nTexts = { defaultMessage: 'Critical', } ), - getDeprecationIssue: (domainId: string) => { - return i18n.translate('xpack.upgradeAssistant.kibanaDeprecations.table.issueCellDescription', { - defaultMessage: '{domainId} is using a deprecated feature', - values: { - domainId, - }, - }); - }, criticalBadgeLabel: i18n.translate( 'xpack.upgradeAssistant.kibanaDeprecations.table.criticalBadgeLabel', { @@ -131,22 +123,18 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ }, }, { - field: 'domainId', + field: 'title', width: '40%', name: i18nTexts.issueColumnTitle, truncateText: true, sortable: true, - render: ( - domainId: KibanaDeprecationDetails['domainId'], - deprecation: KibanaDeprecationDetails - ) => { + render: (title: KibanaDeprecationDetails['title'], deprecation: KibanaDeprecationDetails) => { return ( toggleFlyout(deprecation)} data-test-subj="deprecationDetailsLink" > - {/* This will be replaced with a custom title once https://github.com/elastic/kibana/pull/109840 is merged */} - {i18nTexts.getDeprecationIssue(domainId)} + {title} ); }, diff --git a/x-pack/test/accessibility/apps/upgrade_assistant.ts b/x-pack/test/accessibility/apps/upgrade_assistant.ts index 050c87fcd0d2b..b7c8939e350ac 100644 --- a/x-pack/test/accessibility/apps/upgrade_assistant.ts +++ b/x-pack/test/accessibility/apps/upgrade_assistant.ts @@ -99,7 +99,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('Deprecation details flyout', async () => { await PageObjects.upgradeAssistant.clickKibanaDeprecation( - 'xpack.securitySolution is using a deprecated feature' // This deprecation was added to the test runner config so should be guaranteed + 'xpack.securitySolution has a deprecated setting' // This deprecation was added to the test runner config so should be guaranteed ); await retry.waitFor('Kibana deprecation details flyout to be visible', async () => { From 2eeffaf97b63b6ca674768e65951ecab782af90c Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Thu, 2 Sep 2021 11:38:12 -0400 Subject: [PATCH 18/18] address review feedback --- .../deprecations_list.test.ts | 27 ++----- .../kibana_deprecations.helpers.ts | 18 ++++- .../kibana_deprecations.tsx | 2 + .../kibana_deprecations_table.tsx | 13 ++-- .../resolution_table_cell.tsx | 71 +++++++++---------- 5 files changed, 69 insertions(+), 62 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts index 3c323e7bcd48f..c3e3581409947 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_list.test.ts @@ -62,6 +62,8 @@ describe('Kibana deprecations table', () => { it('refreshes deprecation data', async () => { const { actions } = testBed; + expect(deprecationService.getAllDeprecations).toHaveBeenCalledTimes(1); + await actions.table.clickRefreshButton(); expect(deprecationService.getAllDeprecations).toHaveBeenCalledTimes(2); @@ -78,37 +80,22 @@ describe('Kibana deprecations table', () => { it('filters by "critical" status', async () => { const { actions, table } = testBed; + // Show only critical deprecations await actions.searchBar.clickCriticalFilterButton(); - const { rows: criticalRows } = table.getMetaData('kibanaDeprecationsTable'); - expect(criticalRows.length).toEqual(criticalDeprecations.length); + // Show all deprecations await actions.searchBar.clickCriticalFilterButton(); - const { rows: allRows } = table.getMetaData('kibanaDeprecationsTable'); - expect(allRows.length).toEqual(kibanaDeprecationsMockResponse.length); }); it('filters by type', async () => { - const { component, table, actions } = testBed; - - await actions.searchBar.clickTypeFilterDropdownAt(0); + const { table, actions } = testBed; - // We need to read the document "body" as the filter dropdown options are added there and not inside - // the component DOM tree. - const configTypeFilterButton: HTMLButtonElement | null = document.body.querySelector( - '.euiFilterSelect__items .euiFilterSelectItem' - ); - - expect(configTypeFilterButton).not.toBeNull(); - - await act(async () => { - configTypeFilterButton!.click(); - }); - - component.update(); + await actions.searchBar.openTypeFilterDropdown(); + await actions.searchBar.filterByConfigType(); const { rows: configRows } = table.getMetaData('kibanaDeprecationsTable'); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts index fdcc3594dad36..345a06d3d80a0 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/kibana_deprecations.helpers.ts @@ -52,14 +52,14 @@ const createActions = (testBed: TestBed) => { }; const searchBarActions = { - clickTypeFilterDropdownAt: async (index: number) => { + openTypeFilterDropdown: async () => { await act(async () => { // EUI doesn't support data-test-subj's on the filter buttons, so we must access via CSS selector find('kibanaDeprecations') .find('.euiSearchBar__filtersHolder') .find('.euiPopover') .find('.euiFilterButton') - .at(index) + .at(0) .simulate('click'); }); @@ -78,6 +78,20 @@ const createActions = (testBed: TestBed) => { component.update(); }, + + filterByConfigType: async () => { + // We need to read the document "body" as the filter dropdown options are added there and not inside + // the component DOM tree. The "Config" option is expected to be the first item. + const configTypeFilterButton: HTMLButtonElement | null = document.body.querySelector( + '.euiFilterSelect__items .euiFilterSelectItem' + ); + + await act(async () => { + configTypeFilterButton!.click(); + }); + + component.update(); + }, }; const flyoutActions = { diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx index f1bb179e28e24..a6d7e4fdb674a 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx @@ -86,6 +86,7 @@ export interface DeprecationResolutionState { export interface KibanaDeprecationDetails extends DomainDeprecationDetails { id: string; + filterType: DomainDeprecationDetails['deprecationType'] | 'uncategorized'; } const getDeprecationCountByLevel = (deprecations: KibanaDeprecationDetails[]) => { @@ -153,6 +154,7 @@ export const KibanaDeprecations = withRouter(({ history }: RouteComponentProps) filteredDeprecations.push({ ...deprecation, id: uuid.v4(), // Associate an unique ID with each deprecation to track resolution state + filterType: deprecation.deprecationType ?? 'uncategorized', // deprecationType is currently optional, in order to correctly handle sort/filter, we default any undefined types to "uncategorized" }); }); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx index ce0fac22a977c..9117bcdbcaee5 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations_table.tsx @@ -140,17 +140,18 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ }, }, { - field: 'deprecationType', + field: 'filterType', name: i18nTexts.typeColumnTitle, width: '20%', truncateText: true, sortable: true, - render: (deprecationType: KibanaDeprecationDetails['deprecationType']) => { - switch (deprecationType) { + render: (filterType: KibanaDeprecationDetails['filterType']) => { + switch (filterType) { case 'config': return i18nTexts.configDeprecationTypeCellLabel; case 'feature': return i18nTexts.featureDeprecationTypeCellLabel; + case 'uncategorized': default: return i18nTexts.unknownDeprecationTypeCellLabel; } @@ -194,7 +195,7 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ }, { type: 'field_value_selection', - field: 'deprecationType', + field: 'filterType', name: i18nTexts.typeFilterLabel, multiSelect: false, options: [ @@ -206,6 +207,10 @@ export const KibanaDeprecationsTable: React.FunctionComponent = ({ value: 'feature', name: i18nTexts.featureDeprecationTypeCellLabel, }, + { + value: 'uncategorized', + name: i18nTexts.unknownDeprecationTypeCellLabel, + }, ], }, ], diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolution_table_cell.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolution_table_cell.tsx index 241d3037c7980..aef52fe07a183 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolution_table_cell.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/resolution_table_cell.tsx @@ -78,43 +78,42 @@ export const ResolutionTableCell: React.FunctionComponent = ({ if (isAutomated) { if (deprecationResolutionState?.id === deprecationId) { const { resolveDeprecationStatus } = deprecationResolutionState; - if (resolveDeprecationStatus === 'in_progress') { - return ( - - - - - - {i18nTexts.automationInProgressCellLabel} - - - ); - } - - if (resolveDeprecationStatus === 'ok') { - return ( - - - - - - {i18nTexts.automationCompleteCellLabel} - - - ); - } - if (resolveDeprecationStatus === 'fail') { - return ( - - - - - - {i18nTexts.automationFailedCellLabel} - - - ); + switch (resolveDeprecationStatus) { + case 'in_progress': + return ( + + + + + + {i18nTexts.automationInProgressCellLabel} + + + ); + case 'fail': + return ( + + + + + + {i18nTexts.automationFailedCellLabel} + + + ); + case 'ok': + default: + return ( + + + + + + {i18nTexts.automationCompleteCellLabel} + + + ); } }