Skip to content

Commit

Permalink
[ResponceOps][MaintenanceWindow] MX Pagination (#202539)
Browse files Browse the repository at this point in the history
Fixes: #198252

In this PR I introduced pagination in MW frontend part and also pass
filters(status and search) to the backend. Pagination arguments were
passed to backend in another PR:
https://github.com/elastic/kibana/pull/197172/files#diff-f375a192a08a6db3fbb6b6e927cecaab89ff401efc4034f00761e8fc4478734c

How to test:
Go to Maintenance Window, create more than 10 MW with different
statuses. Try pagination, search on text and filter by status.

Check the PR satisfies following conditions:

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
guskovaue and kibanamachine authored Dec 21, 2024
1 parent f8b7eda commit 43abe23
Show file tree
Hide file tree
Showing 31 changed files with 1,149 additions and 184 deletions.
5 changes: 4 additions & 1 deletion packages/kbn-check-mappings-update-cli/current_fields.json
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,10 @@
],
"maintenance-window": [
"enabled",
"events"
"events",
"expirationDate",
"title",
"updatedAt"
],
"map": [
"bounds",
Expand Down
14 changes: 14 additions & 0 deletions packages/kbn-check-mappings-update-cli/current_mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2521,6 +2521,20 @@
"events": {
"format": "epoch_millis||strict_date_optional_time",
"type": "date_range"
},
"expirationDate": {
"type": "date"
},
"title": {
"fields": {
"keyword": {
"type": "keyword"
}
},
"type": "text"
},
"updatedAt": {
"type": "date"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
"lens": "5cfa2c52b979b4f8df56dd13c477e152183468b9",
"lens-ui-telemetry": "8c47a9e393861f76e268345ecbadfc8a5fb1e0bd",
"links": "1dd432cc94619a513b75cec43660a50be7aadc90",
"maintenance-window": "bf36863f5577c2d22625258bdad906eeb4cccccc",
"maintenance-window": "b84d9e0b3f89be0ae4b6fe1af6e38b4cd2554931",
"map": "76c71023bd198fb6b1163b31bafd926fe2ceb9da",
"metrics-data-source": "81b69dc9830699d9ead5ac8dcb9264612e2a3c89",
"metrics-explorer-view": "98cf395d0e87b89ab63f173eae16735584a8ff42",
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/alerting/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export {
MAINTENANCE_WINDOW_PATHS,
MAINTENANCE_WINDOW_DEEP_LINK_IDS,
MAINTENANCE_WINDOW_DATE_FORMAT,
MAINTENANCE_WINDOW_DEFAULT_PER_PAGE,
MAINTENANCE_WINDOW_DEFAULT_TABLE_ACTIVE_PAGE,
} from './maintenance_window';

export {
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/alerting/common/maintenance_window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,6 @@ export type MaintenanceWindowDeepLinkIds =
(typeof MAINTENANCE_WINDOW_DEEP_LINK_IDS)[keyof typeof MAINTENANCE_WINDOW_DEEP_LINK_IDS];

export const MAINTENANCE_WINDOW_DATE_FORMAT = 'MM/DD/YY hh:mm A';

export const MAINTENANCE_WINDOW_DEFAULT_PER_PAGE = 10 as const;
export const MAINTENANCE_WINDOW_DEFAULT_TABLE_ACTIVE_PAGE = 1 as const;
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import { maintenanceWindowResponseSchemaV1 } from '../../../response';

const MAX_DOCS = 10000;

const statusSchema = schema.oneOf([
schema.literal('running'),
schema.literal('finished'),
schema.literal('upcoming'),
schema.literal('archived'),
]);

export const findMaintenanceWindowsRequestQuerySchema = schema.object(
{
// we do not need to use schema.maybe here, because if we do not pass property page, defaultValue will be used
Expand All @@ -30,6 +37,15 @@ export const findMaintenanceWindowsRequestQuerySchema = schema.object(
description: 'The number of maintenance windows to return per page.',
},
}),
search: schema.maybe(
schema.string({
meta: {
description:
'An Elasticsearch simple_query_string query that filters the objects in the response.',
},
})
),
status: schema.maybe(schema.oneOf([statusSchema, schema.arrayOf(statusSchema)])),
},
{
validate: (params) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { AppMockRenderer, createAppMockRenderer } from '../lib/test_utils';
import { useFindMaintenanceWindows } from './use_find_maintenance_windows';

const mockAddDanger = jest.fn();
const mockedHttp = jest.fn();

jest.mock('../utils/kibana_react', () => {
const originalModule = jest.requireActual('../utils/kibana_react');
Expand All @@ -21,6 +22,7 @@ jest.mock('../utils/kibana_react', () => {
return {
services: {
...services,
http: mockedHttp,
notifications: { toasts: { addDanger: mockAddDanger } },
},
};
Expand All @@ -33,6 +35,8 @@ jest.mock('../services/maintenance_windows_api/find', () => ({

const { findMaintenanceWindows } = jest.requireMock('../services/maintenance_windows_api/find');

const defaultHookProps = { page: 1, perPage: 10, search: '', selectedStatus: [] };

let appMockRenderer: AppMockRenderer;

describe('useFindMaintenanceWindows', () => {
Expand All @@ -42,10 +46,20 @@ describe('useFindMaintenanceWindows', () => {
appMockRenderer = createAppMockRenderer();
});

it('should call findMaintenanceWindows with correct arguments on successful scenario', async () => {
renderHook(() => useFindMaintenanceWindows({ ...defaultHookProps }), {
wrapper: appMockRenderer.AppWrapper,
});

await waitFor(() =>
expect(findMaintenanceWindows).toHaveBeenCalledWith({ http: mockedHttp, ...defaultHookProps })
);
});

it('should call onError if api fails', async () => {
findMaintenanceWindows.mockRejectedValue('This is an error.');

renderHook(() => useFindMaintenanceWindows(), {
renderHook(() => useFindMaintenanceWindows({ ...defaultHookProps }), {
wrapper: appMockRenderer.AppWrapper,
});

Expand All @@ -55,7 +69,7 @@ describe('useFindMaintenanceWindows', () => {
});

it('should not try to find maintenance windows if not enabled', async () => {
renderHook(() => useFindMaintenanceWindows({ enabled: false }), {
renderHook(() => useFindMaintenanceWindows({ enabled: false, ...defaultHookProps }), {
wrapper: appMockRenderer.AppWrapper,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,32 @@ import { i18n } from '@kbn/i18n';
import { useQuery } from '@tanstack/react-query';
import { useKibana } from '../utils/kibana_react';
import { findMaintenanceWindows } from '../services/maintenance_windows_api/find';
import { type MaintenanceWindowStatus } from '../../common';

interface UseFindMaintenanceWindowsProps {
enabled?: boolean;
page: number;
perPage: number;
search: string;
selectedStatus: MaintenanceWindowStatus[];
}

export const useFindMaintenanceWindows = (props?: UseFindMaintenanceWindowsProps) => {
const { enabled = true } = props || {};
export const useFindMaintenanceWindows = (params: UseFindMaintenanceWindowsProps) => {
const { enabled = true, page, perPage, search, selectedStatus } = params;

const {
http,
notifications: { toasts },
} = useKibana().services;

const queryFn = () => {
return findMaintenanceWindows({ http });
return findMaintenanceWindows({
http,
page,
perPage,
search,
selectedStatus,
});
};

const onErrorFn = (error: Error) => {
Expand All @@ -36,24 +47,22 @@ export const useFindMaintenanceWindows = (props?: UseFindMaintenanceWindowsProps
}
};

const {
isLoading,
isFetching,
isInitialLoading,
data = [],
refetch,
} = useQuery({
queryKey: ['findMaintenanceWindows'],
const queryKey = ['findMaintenanceWindows', page, perPage, search, selectedStatus];

const { isLoading, isFetching, isInitialLoading, data, refetch } = useQuery({
queryKey,
queryFn,
onError: onErrorFn,
refetchOnWindowFocus: false,
retry: false,
cacheTime: 0,
enabled,
placeholderData: { maintenanceWindows: [], total: 0 },
keepPreviousData: true,
});

return {
maintenanceWindows: data,
data,
isLoading: enabled && (isLoading || isFetching),
isInitialLoading,
refetch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ describe('MaintenanceWindowsList', () => {
isLoading={false}
items={items}
readOnly={false}
page={1}
perPage={10}
total={22}
onPageChange={() => {}}
onStatusChange={() => {}}
selectedStatus={[]}
onSearchChange={() => {}}
/>
);

Expand Down Expand Up @@ -128,6 +135,13 @@ describe('MaintenanceWindowsList', () => {
isLoading={false}
items={items}
readOnly={true}
page={1}
perPage={10}
total={22}
onPageChange={() => {}}
onStatusChange={() => {}}
selectedStatus={[]}
onSearchChange={() => {}}
/>
);

Expand All @@ -145,6 +159,13 @@ describe('MaintenanceWindowsList', () => {
isLoading={false}
items={items}
readOnly={false}
page={1}
perPage={10}
total={22}
onPageChange={() => {}}
onStatusChange={() => {}}
selectedStatus={[]}
onSearchChange={() => {}}
/>
);
fireEvent.click(result.getByTestId('refresh-button'));
Expand Down
Loading

0 comments on commit 43abe23

Please sign in to comment.