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

[Index Management] Add indices list columns to the extensions service #174785

Merged
merged 12 commits into from
Jan 22, 2024
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
18 changes: 18 additions & 0 deletions x-pack/plugins/index_management/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ This service is exposed from the Index Management setup contract and can be used
- `addBanner(banner: any)`: adds a banner on top of the indices list, for example when some indices run into an ILM issue
- `addFilter(filter: any)`: adds a filter to the indices list, for example to filter indices managed by ILM
- `addToggle(toggle: any)`: adds a toggle to the indices list, for example to display hidden indices
- `addColumn(column: IndicesListColumn)`: adds a column to the indices list, for example to display an ILM phase
- `setEmptyListContent(content: EmptyListContent)`: replaces the default empty prompt displayed when there are no indices in the indices list. The empty list content has the following interface:

```ts
export interface EmptyListContent {
renderContent: (args: {
createIndexButton: ReturnType<FunctionComponent>;
}) => ReturnType<FunctionComponent>;
}
```

#### Extensions to the indices list and the index details page
- `addAction(action: any)`: adds an option to the "manage index" menu, for example to add an ILM policy to the index
Expand Down Expand Up @@ -44,6 +54,14 @@ interface IndexContent {
```
- `setIndexMappingsContent(content: IndexContent)`: adds content to the mappings tab of the index details page. The content is displayed in the right bottom corner, below the mappings docs link.

## Index data enrichers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL, this is great. We should be using this for serverless search.

The extensions service that allows to render additional UI elements in the indices list and on the index details page often
relies on additional index data that is not available by default. To make these additional data available in the response of
the `GET /indices` request, an index data enricher can be registered. A data enricher is essentially an extra request that is
done for the array of indices and the information is added to the response. Currently, 3 data enrichers are registered
by the ILM, Rollup and CCR plugins. Before adding a data enricher, the cost of the additional request should be taken
in consideration (see [this file](https://github.com/elastic/kibana/blob/main/x-pack/plugins/index_management/server/services/index_data_enricher.ts) for more details).

## Indices tab

### Quick steps for testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ jest.mock('@elastic/eui/lib/components/search_bar/search_box', () => {
import React from 'react';
import { act } from 'react-dom/test-utils';

import { API_BASE_PATH, INTERNAL_API_BASE_PATH } from '../../../common';
import { API_BASE_PATH, Index, INTERNAL_API_BASE_PATH } from '../../../common';
import { setupEnvironment } from '../helpers';
import { IndicesTestBed, setup } from './indices_tab.helpers';
import { createDataStreamPayload, createNonDataStreamIndex } from './data_streams_tab.helpers';
import {
createDataStreamBackingIndex,
createDataStreamPayload,
createNonDataStreamIndex,
} from './data_streams_tab.helpers';

import { createMemoryHistory } from 'history';
import {
Expand Down Expand Up @@ -81,30 +85,8 @@ describe('<IndexManagementHome />', () => {
describe('data stream column', () => {
beforeEach(async () => {
httpRequestsMockHelpers.setLoadIndicesResponse([
{
health: '',
status: '',
primary: '',
replica: '',
documents: '',
documents_deleted: '',
size: '',
primary_size: '',
name: 'data-stream-index',
data_stream: 'dataStream1',
},
{
health: '',
status: '',
primary: '',
replica: '',
documents: '',
documents_deleted: '',
size: '',
primary_size: '',
name: 'no-data-stream-index',
data_stream: null,
},
createDataStreamBackingIndex('data-stream-index', 'dataStream1'),
createNonDataStreamIndex('no-data-stream-index'),
]);

// The detail panel should still appear even if there are no data streams.
Expand Down Expand Up @@ -195,26 +177,6 @@ describe('<IndexManagementHome />', () => {
expect(testBed.exists('createIndexMessage')).toBe(true);
});

it('displays an empty list content if set via extensions service', async () => {
httpRequestsMockHelpers.setLoadIndicesResponse([]);
await act(async () => {
testBed = await setup(httpSetup, {
services: {
extensionsService: {
_emptyListContent: {
renderContent: () => {
return <div>Empty list content</div>;
},
},
},
},
});
});
testBed.component.update();

expect(testBed.component.text()).toContain('Empty list content');
});

it('renders "no indices found" prompt for search', async () => {
const { find, component, exists } = testBed;
await act(async () => {
Expand Down Expand Up @@ -530,4 +492,70 @@ describe('<IndexManagementHome />', () => {
expect(httpSetup.get).toHaveBeenNthCalledWith(2, '/api/index_management/indices');
});
});

describe('extensions service', () => {
it('displays an empty list content if set via extensions service', async () => {
httpRequestsMockHelpers.setLoadIndicesResponse([]);
await act(async () => {
testBed = await setup(httpSetup, {
services: {
extensionsService: {
_emptyListContent: {
renderContent: () => {
return <div>Empty list content</div>;
},
},
},
},
});
});
testBed.component.update();

expect(testBed.component.text()).toContain('Empty list content');
});

it('renders additional columns registered via extensions service', async () => {
httpRequestsMockHelpers.setLoadIndicesResponse([
{
...createNonDataStreamIndex('test-index'),
ilm: {
phase: 'hot phase',
managed: true,
},
},
]);
await act(async () => {
testBed = await setup(httpSetup, {
services: {
extensionsService: {
_columns: [
{
fieldName: 'ilm.phase',
label: 'ILM column 1',
order: 55,
},
{
fieldName: 'ilm.managed',
label: 'ILM column 2',
order: 56,
render: (index: Index) => {
if (index.ilm?.managed) {
return <div>ILM managed</div>;
}
},
},
],
},
},
});
});
testBed.component.update();

const text = testBed.component.text();
expect(text).toContain('ILM column 1');
expect(text).toContain('hot phase');
expect(text).toContain('ILM column 2');
expect(text).toContain('ILM managed');
});
});
});
Loading