mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Fix bug in Index Management ILM details (#213101)
## Summary We had a bug in Index Management. When the user clicks Index Management > Index details > Index lifecycle, the page was unable to load. After refreshing, the info was displayed correctly.  This error was caused because the hook invariant violation rule was not being fulfilled: https://react.dev/errors/310?invariant=310. The lifecycle tab is rendered through the extension service that comes from the ILM plugin. In [this PR](https://github.com/elastic/kibana/pull/204449/files#diff-021836407481af0b98d7d91abab452bed569e3197072713bdf57a065f43ef734R43) we modified the ILM component introducing the `euiTheme` hook, which was causing the the hook invariant violation error. With this PR the hook is now rendered in the Index Management plugin and passed to ILM to avoid the error. ### Demo <details> <summary>Video</summary> https://github.com/user-attachments/assets/2c212d30-b7a9-42de-9869-cc10093f0f33 </details> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
5d565abd02
commit
521f34511e
5 changed files with 47 additions and 26 deletions
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { FunctionComponent, ReactNode } from 'react';
|
||||
import type { ApplicationStart } from '@kbn/core-application-browser';
|
||||
import { EuiBreadcrumb } from '@elastic/eui';
|
||||
import { EuiBreadcrumb, EuiThemeComputed } from '@elastic/eui';
|
||||
import { Index } from './types';
|
||||
|
||||
export enum Section {
|
||||
|
@ -36,6 +36,7 @@ export interface IndexDetailsTab {
|
|||
renderTabContent: (args: {
|
||||
index: Index;
|
||||
getUrlForApp: ApplicationStart['getUrlForApp'];
|
||||
euiTheme: EuiThemeComputed;
|
||||
}) => ReturnType<FunctionComponent>;
|
||||
// a number to specify the order of the tabs
|
||||
order: number;
|
||||
|
|
|
@ -179,7 +179,7 @@ exports[`extend index management ilm summary extension should render a phase def
|
|||
>
|
||||
<span
|
||||
class="euiBadge emotion-euiBadge"
|
||||
style="--euiBadgeBackgroundColor: #F6726A; --euiBadgeTextColor: #07101F;"
|
||||
style="--euiBadgeBackgroundColor: #B9A888; --euiBadgeTextColor: #07101F;"
|
||||
title="Hot"
|
||||
>
|
||||
<span
|
||||
|
@ -349,7 +349,7 @@ exports[`extend index management ilm summary extension should render a step info
|
|||
>
|
||||
<span
|
||||
class="euiBadge emotion-euiBadge"
|
||||
style="--euiBadgeBackgroundColor: #F6726A; --euiBadgeTextColor: #07101F;"
|
||||
style="--euiBadgeBackgroundColor: #B9A888; --euiBadgeTextColor: #07101F;"
|
||||
title="Hot"
|
||||
>
|
||||
<span
|
||||
|
@ -515,7 +515,7 @@ exports[`extend index management ilm summary extension should render an error pa
|
|||
>
|
||||
<span
|
||||
class="euiBadge emotion-euiBadge"
|
||||
style="--euiBadgeBackgroundColor: #F6726A; --euiBadgeTextColor: #07101F;"
|
||||
style="--euiBadgeBackgroundColor: #B9A888; --euiBadgeTextColor: #07101F;"
|
||||
title="Hot"
|
||||
>
|
||||
<span
|
||||
|
|
|
@ -23,6 +23,7 @@ import { init as initUiMetric } from '../public/application/services/ui_metric';
|
|||
import { indexLifecycleTab } from '../public/extend_index_management/components/index_lifecycle_summary';
|
||||
import { Index } from '@kbn/index-management-plugin/common';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
|
||||
const { httpSetup } = init();
|
||||
|
||||
|
@ -34,6 +35,26 @@ jest.mock('@kbn/index-management-plugin/public', async () => {
|
|||
return indexManagementMock.createSetup();
|
||||
});
|
||||
|
||||
// Mock useEuiTheme to return the desired theme
|
||||
jest.mock('@elastic/eui', () => ({
|
||||
...jest.requireActual('@elastic/eui'),
|
||||
useEuiTheme: () => ({
|
||||
euiTheme: {
|
||||
themeName: 'EUI_THEME_BOREALIS',
|
||||
colors: {
|
||||
vis: {
|
||||
euiColorVis1: '#6092C0',
|
||||
euiColorVis2: '#D36086',
|
||||
euiColorVis4: '#CA8EAE',
|
||||
euiColorVis5: '#D6BF57',
|
||||
euiColorVis6: '#B9A888',
|
||||
euiColorVis9: '#E7664C',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
const indexWithoutLifecyclePolicy: Index = {
|
||||
health: 'yellow',
|
||||
status: 'open',
|
||||
|
@ -329,6 +350,11 @@ describe('extend index management', () => {
|
|||
const policyErrorPanel = 'policyErrorPanel';
|
||||
const phaseDefinitionPanel = 'phaseDefinitionPanel';
|
||||
|
||||
const IlmContentComponent = ({ index }: { index: Index }) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
return <IlmComponent index={index} getUrlForApp={getUrlForApp} euiTheme={euiTheme} />;
|
||||
};
|
||||
|
||||
test('should not render the tab when index has no index lifecycle policy', () => {
|
||||
const shouldRenderTab =
|
||||
indexLifecycleTab.shouldRenderTab &&
|
||||
|
@ -345,10 +371,7 @@ describe('extend index management', () => {
|
|||
index: indexWithLifecyclePolicy,
|
||||
});
|
||||
expect(shouldRenderTab).toBeTruthy();
|
||||
const ilmContent = (
|
||||
<IlmComponent index={indexWithLifecyclePolicy} getUrlForApp={getUrlForApp} />
|
||||
);
|
||||
const rendered = mountWithIntl(ilmContent);
|
||||
const rendered = mountWithIntl(<IlmContentComponent index={indexWithLifecyclePolicy} />);
|
||||
expect(rendered.render()).toMatchSnapshot();
|
||||
expect(findTestSubject(rendered, policyPropertiesPanel).exists()).toBeTruthy();
|
||||
expect(findTestSubject(rendered, phaseDefinitionPanel).exists()).toBeFalsy();
|
||||
|
@ -357,10 +380,7 @@ describe('extend index management', () => {
|
|||
});
|
||||
|
||||
test('should render an error panel when index has lifecycle error', () => {
|
||||
const ilmContent = (
|
||||
<IlmComponent index={indexWithLifecycleError} getUrlForApp={getUrlForApp} />
|
||||
);
|
||||
const rendered = mountWithIntl(ilmContent);
|
||||
const rendered = mountWithIntl(<IlmContentComponent index={indexWithLifecycleError} />);
|
||||
expect(rendered.render()).toMatchSnapshot();
|
||||
expect(findTestSubject(rendered, policyPropertiesPanel).exists()).toBeTruthy();
|
||||
expect(findTestSubject(rendered, phaseDefinitionPanel).exists()).toBeFalsy();
|
||||
|
@ -369,10 +389,9 @@ describe('extend index management', () => {
|
|||
});
|
||||
|
||||
test('should render a phase definition panel when lifecycle has phase definition', () => {
|
||||
const ilmContent = (
|
||||
<IlmComponent index={indexWithLifecyclePhaseDefinition} getUrlForApp={getUrlForApp} />
|
||||
const rendered = mountWithIntl(
|
||||
<IlmContentComponent index={indexWithLifecyclePhaseDefinition} />
|
||||
);
|
||||
const rendered = mountWithIntl(ilmContent);
|
||||
expect(rendered.render()).toMatchSnapshot();
|
||||
expect(findTestSubject(rendered, policyPropertiesPanel).exists()).toBeTruthy();
|
||||
expect(findTestSubject(rendered, phaseDefinitionPanel).exists()).toBeTruthy();
|
||||
|
@ -381,10 +400,7 @@ describe('extend index management', () => {
|
|||
});
|
||||
|
||||
test('should render a step info panel when lifecycle is waiting for a step completion', () => {
|
||||
const ilmContent = (
|
||||
<IlmComponent index={indexWithLifecycleWaitingStep} getUrlForApp={getUrlForApp} />
|
||||
);
|
||||
const rendered = mountWithIntl(ilmContent);
|
||||
const rendered = mountWithIntl(<IlmContentComponent index={indexWithLifecycleWaitingStep} />);
|
||||
expect(rendered.render()).toMatchSnapshot();
|
||||
expect(findTestSubject(rendered, policyPropertiesPanel).exists()).toBeTruthy();
|
||||
expect(findTestSubject(rendered, phaseDefinitionPanel).exists()).toBeFalsy();
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
EuiBadgeProps,
|
||||
EuiBadge,
|
||||
EuiCode,
|
||||
useEuiTheme,
|
||||
EuiThemeComputed,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { ApplicationStart } from '@kbn/core/public';
|
||||
|
@ -33,15 +33,17 @@ import { getPolicyEditPath } from '../../application/services/navigation';
|
|||
interface Props {
|
||||
index: Index;
|
||||
getUrlForApp: ApplicationStart['getUrlForApp'];
|
||||
euiTheme: EuiThemeComputed;
|
||||
}
|
||||
|
||||
export const IndexLifecycleSummary: FunctionComponent<Props> = ({ index, getUrlForApp }) => {
|
||||
export const IndexLifecycleSummary: FunctionComponent<Props> = ({
|
||||
index,
|
||||
getUrlForApp,
|
||||
euiTheme,
|
||||
}) => {
|
||||
const { ilm: ilmData } = index;
|
||||
// only ILM managed indices render the ILM tab
|
||||
const ilm = ilmData as IlmExplainLifecycleLifecycleExplainManaged;
|
||||
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
const isBorealis = euiTheme.themeName === 'EUI_THEME_BOREALIS';
|
||||
|
||||
// Changing the mappings for the phases in Borealis as a mid-term solution. See https://github.com/elastic/kibana/issues/203664#issuecomment-2536593361.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import React, { FunctionComponent, useEffect } from 'react';
|
||||
import { EuiBreadcrumb } from '@elastic/eui';
|
||||
import { EuiBreadcrumb, useEuiTheme } from '@elastic/eui';
|
||||
import { breadcrumbService, IndexManagementBreadcrumb } from '../../../../services/breadcrumbs';
|
||||
import { Index } from '../../../../../../common';
|
||||
import { IndexDetailsTab, IndexDetailsTabId } from '../../../../../../common/constants';
|
||||
|
@ -24,13 +24,15 @@ export const DetailsPageTab: FunctionComponent<Props> = ({ tabs, tab, index }) =
|
|||
core: { getUrlForApp },
|
||||
} = useAppContext();
|
||||
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
useEffect(() => {
|
||||
const breadcrumb: EuiBreadcrumb = selectedTab?.breadcrumb ?? { text: selectedTab?.name };
|
||||
breadcrumbService.setBreadcrumbs(IndexManagementBreadcrumb.indexDetails, breadcrumb);
|
||||
}, [selectedTab]);
|
||||
|
||||
return selectedTab ? (
|
||||
selectedTab.renderTabContent({ index, getUrlForApp })
|
||||
selectedTab.renderTabContent({ index, getUrlForApp, euiTheme })
|
||||
) : (
|
||||
<DetailsPageOverview indexDetails={index} />
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue