Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Upgrade Assistant] Address design feedback for ES deprecations page #109726

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@ describe('Deprecations table', () => {
);
});

it('shows critical and warning deprecations count', () => {
const { find } = testBed;
const criticalDeprecations = esDeprecationsMockResponse.deprecations.filter(
(deprecation) => deprecation.isCritical
);
const warningDeprecations = esDeprecationsMockResponse.deprecations.filter(
(deprecation) => deprecation.isCritical === false
);

expect(find('criticalDeprecationsCount').text()).toContain(criticalDeprecations.length);

expect(find('warningDeprecationsCount').text()).toContain(warningDeprecations.length);
});

describe('search bar', () => {
it('filters results by "critical" status', async () => {
const { find, actions } = testBed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('Machine learning deprecation flyout', () => {

describe('upgrade snapshots', () => {
it('successfully upgrades snapshots', async () => {
const { find, actions, exists } = testBed;
const { find, actions } = testBed;

httpRequestsMockHelpers.setUpgradeMlSnapshotResponse({
nodeId: 'my_node',
Expand Down Expand Up @@ -86,9 +86,10 @@ describe('Machine learning deprecation flyout', () => {
// Reopen the flyout
await actions.table.clickDeprecationRowAt('mlSnapshot', 0);

// Flyout actions should not be visible if deprecation was resolved
expect(exists('mlSnapshotDetails.upgradeSnapshotButton')).toBe(false);
expect(exists('mlSnapshotDetails.deleteSnapshotButton')).toBe(false);
// Flyout actions should be disabled if deprecation was resolved
expect(find('mlSnapshotDetails.upgradeSnapshotButton').props().disabled).toBe(true);
expect(find('mlSnapshotDetails.upgradeSnapshotButton').text()).toContain('Upgrade complete');
expect(find('mlSnapshotDetails.deleteSnapshotButton').props().disabled).toBe(true);
});

it('handles upgrade failure', async () => {
Expand Down Expand Up @@ -156,6 +157,11 @@ describe('Machine learning deprecation flyout', () => {

// Reopen the flyout
await actions.table.clickDeprecationRowAt('mlSnapshot', 0);

// Flyout actions should be disabled if deprecation was resolved
expect(find('mlSnapshotDetails.deleteSnapshotButton').props().disabled).toBe(true);
expect(find('mlSnapshotDetails.deleteSnapshotButton').text()).toContain('Deletion complete');
expect(find('mlSnapshotDetails.upgradeSnapshotButton').props().disabled).toBe(true);
});

it('handles delete failure', async () => {
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/upgrade_assistant/public/application/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { I18nStart, ScopedHistory } from 'src/core/public';
import { ApplicationStart } from 'kibana/public';
import { GlobalFlyout } from '../shared_imports';

import { KibanaContextProvider } from '../shared_imports';
import { KibanaContextProvider, APP_WRAPPER_CLASS } from '../shared_imports';
import { AppServicesContext } from '../types';
import { AppContextProvider, ContextValue, useAppContext } from './app_context';
import { ComingSoonPrompt } from './components/coming_soon_prompt';
Expand Down Expand Up @@ -62,7 +62,7 @@ export const RootComponent = ({
...contextValue
}: AppDependencies) => {
return (
<RedirectAppLinks application={application}>
<RedirectAppLinks application={application} className={APP_WRAPPER_CLASS}>
<i18n.Context>
<KibanaContextProvider services={services}>
<AppContextProvider value={contextValue}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {

import { EnrichedDeprecationInfo } from '../../../../../../common/types';
import { MlSnapshotContext } from './context';
import { SnapshotState } from './use_snapshot_state';

export interface FixSnapshotsFlyoutProps extends MlSnapshotContext {
deprecation: EnrichedDeprecationInfo;
Expand All @@ -38,12 +39,24 @@ const i18nTexts = {
defaultMessage: 'Upgrade',
}
),
upgradingButtonLabel: i18n.translate(
'xpack.upgradeAssistant.esDeprecations.mlSnapshots.flyout.upgradingButtonLabel',
{
defaultMessage: 'Upgrading…',
}
),
retryUpgradeButtonLabel: i18n.translate(
'xpack.upgradeAssistant.esDeprecations.mlSnapshots.flyout.retryUpgradeButtonLabel',
{
defaultMessage: 'Retry upgrade',
}
),
upgradeResolvedButtonLabel: i18n.translate(
'xpack.upgradeAssistant.esDeprecations.mlSnapshots.flyout.deleteResolvupgradeResolvedButtonLabeledButtonLabel',
{
defaultMessage: 'Upgrade complete',
}
),
closeButtonLabel: i18n.translate(
'xpack.upgradeAssistant.esDeprecations.mlSnapshots.flyout.closeButtonLabel',
{
Expand All @@ -56,6 +69,18 @@ const i18nTexts = {
defaultMessage: 'Delete',
}
),
deletingButtonLabel: i18n.translate(
'xpack.upgradeAssistant.esDeprecations.mlSnapshots.flyout.deletingButtonLabel',
{
defaultMessage: 'Deleting…',
}
),
deleteResolvedButtonLabel: i18n.translate(
'xpack.upgradeAssistant.esDeprecations.mlSnapshots.flyout.deleteResolvedButtonLabel',
{
defaultMessage: 'Deletion complete',
}
),
retryDeleteButtonLabel: i18n.translate(
'xpack.upgradeAssistant.esDeprecations.mlSnapshots.flyout.retryDeleteButtonLabel',
{
Expand Down Expand Up @@ -85,16 +110,51 @@ const i18nTexts = {
),
};

const getDeleteButtonLabel = (snapshotState: SnapshotState) => {
if (snapshotState.action === 'delete') {
if (snapshotState.error) {
return i18nTexts.retryDeleteButtonLabel;
}

switch (snapshotState.status) {
case 'in_progress':
return i18nTexts.deletingButtonLabel;
case 'complete':
return i18nTexts.deleteResolvedButtonLabel;
case 'idle':
default:
return i18nTexts.deleteButtonLabel;
}
}
return i18nTexts.deleteButtonLabel;
};

const getUpgradeButtonLabel = (snapshotState: SnapshotState) => {
if (snapshotState.action === 'upgrade') {
if (snapshotState.error) {
return i18nTexts.retryUpgradeButtonLabel;
}

switch (snapshotState.status) {
case 'in_progress':
return i18nTexts.upgradingButtonLabel;
case 'complete':
return i18nTexts.upgradeResolvedButtonLabel;
case 'idle':
default:
return i18nTexts.upgradeButtonLabel;
}
}
return i18nTexts.upgradeButtonLabel;
};

export const FixSnapshotsFlyout = ({
deprecation,
closeFlyout,
snapshotState,
upgradeSnapshot,
deleteSnapshot,
}: FixSnapshotsFlyoutProps) => {
// Flag used to hide certain parts of the UI if the deprecation has been resolved or is in progress
const isResolvable = ['idle', 'error'].includes(snapshotState.status);

const onUpgradeSnapshot = () => {
upgradeSnapshot();
closeFlyout();
Expand Down Expand Up @@ -147,36 +207,40 @@ export const FixSnapshotsFlyout = ({
</EuiButtonEmpty>
</EuiFlexItem>

{isResolvable && (
<EuiFlexItem grow={false}>
<EuiFlexGroup>
<EuiFlexItem>
<EuiButtonEmpty
data-test-subj="deleteSnapshotButton"
color="danger"
onClick={onDeleteSnapshot}
isLoading={false}
>
{snapshotState.action === 'delete' && snapshotState.error
? i18nTexts.retryDeleteButtonLabel
: i18nTexts.deleteButtonLabel}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
<EuiButton
fill
onClick={onUpgradeSnapshot}
isLoading={false}
data-test-subj="upgradeSnapshotButton"
>
{snapshotState.action === 'upgrade' && snapshotState.error
? i18nTexts.retryUpgradeButtonLabel
: i18nTexts.upgradeButtonLabel}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
)}
<EuiFlexItem grow={false}>
<EuiFlexGroup>
<EuiFlexItem>
<EuiButtonEmpty
data-test-subj="deleteSnapshotButton"
color="danger"
onClick={onDeleteSnapshot}
isLoading={
snapshotState.action === 'delete' && snapshotState.status === 'in_progress'
}
disabled={
snapshotState.status === 'in_progress' || snapshotState.status === 'complete'
}
>
{getDeleteButtonLabel(snapshotState)}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
<EuiButton
fill
onClick={onUpgradeSnapshot}
isLoading={
snapshotState.action === 'upgrade' && snapshotState.status === 'in_progress'
}
disabled={
snapshotState.status === 'in_progress' || snapshotState.status === 'complete'
}
data-test-subj="upgradeSnapshotButton"
>
{getUpgradeButtonLabel(snapshotState)}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutFooter>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const useSnapshotState = ({
return;
}

setSnapshotState(data);
setSnapshotState({ ...data, action: 'upgrade' });

// Only keep polling if it exists and is in progress.
if (data?.status === 'in_progress') {
Expand Down Expand Up @@ -97,7 +97,7 @@ export const useSnapshotState = ({
return;
}

setSnapshotState(data);
setSnapshotState({ ...data, action: 'upgrade' });
updateSnapshotStatus();
}, [api, jobId, snapshotId, updateSnapshotStatus]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,44 @@
* 2.0.
*/

import React, { useEffect } from 'react';
import React, { useEffect, useMemo } from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';

import { EuiPageHeader, EuiSpacer, EuiPageContent } from '@elastic/eui';
import {
EuiPageHeader,
EuiSpacer,
EuiPageContent,
EuiFlexGroup,
EuiFlexItem,
EuiHealth,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';

import { EnrichedDeprecationInfo } from '../../../../common/types';
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';

const getDeprecationCountByLevel = (deprecations: EnrichedDeprecationInfo[]) => {
const criticalDeprecations: EnrichedDeprecationInfo[] = [];
const warningDeprecations: EnrichedDeprecationInfo[] = [];

deprecations.forEach((deprecation) => {
if (deprecation.isCritical) {
criticalDeprecations.push(deprecation);
return;
}
warningDeprecations.push(deprecation);
});

return {
criticalDeprecations: criticalDeprecations.length,
warningDeprecations: warningDeprecations.length,
};
};

const i18nTexts = {
pageTitle: i18n.translate('xpack.upgradeAssistant.esDeprecations.pageTitle', {
defaultMessage: 'Elasticsearch deprecation warnings',
Expand All @@ -28,6 +54,20 @@ 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) => {
Expand All @@ -41,6 +81,13 @@ export const EsDeprecations = withRouter(({ history }: RouteComponentProps) => {
isInitialRequest,
} = api.useLoadEsDeprecations();

const deprecationsCountByLevel: {
warningDeprecations: number;
criticalDeprecations: number;
} = useMemo(() => getDeprecationCountByLevel(esDeprecations?.deprecations || []), [
esDeprecations?.deprecations,
]);

useEffect(() => {
breadcrumbs.setBreadcrumbs('esDeprecations');
}, [breadcrumbs]);
Expand Down Expand Up @@ -82,7 +129,20 @@ export const EsDeprecations = withRouter(({ history }: RouteComponentProps) => {

return (
<div data-test-subj="esDeprecationsContent">
<EuiPageHeader pageTitle={i18nTexts.pageTitle} description={i18nTexts.pageDescription} />
<EuiPageHeader pageTitle={i18nTexts.pageTitle} description={i18nTexts.pageDescription}>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiHealth color="danger" data-test-subj="criticalDeprecationsCount">
{i18nTexts.getCriticalStatusLabel(deprecationsCountByLevel.criticalDeprecations)}
</EuiHealth>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiHealth color="subdued" data-test-subj="warningDeprecationsCount">
{i18nTexts.getWarningStatusLabel(deprecationsCountByLevel.warningDeprecations)}
</EuiHealth>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPageHeader>

<EuiSpacer size="l" />

Expand Down
Loading