mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[RAM] add maintenance window banner (#163516)
## Summary Solves: https://github.com/elastic/kibana/issues/163465 Add maintenance window banner to Rules list and Alerts list in O11y and Management. <img width="1334" alt="Screenshot 2023-08-09 at 13 03 50" src="de0708b1
-db2a-4517-91aa-a3d6b3e62b44"> <img width="1350" alt="Screenshot 2023-08-09 at 13 05 10" src="9f7c488d
-e992-4807-a60e-3c077b623b4e"> --------- Co-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
9079b1c60b
commit
b3122cb656
14 changed files with 306 additions and 59 deletions
|
@ -10,14 +10,15 @@ import React from 'react';
|
|||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { render, waitFor, cleanup } from '@testing-library/react';
|
||||
import {
|
||||
MaintenanceWindowStatus,
|
||||
MAINTENANCE_WINDOW_FEATURE_ID,
|
||||
} from '@kbn/alerting-plugin/common';
|
||||
import type { MaintenanceWindow } from '@kbn/alerting-plugin/common';
|
||||
import type { AsApiContract } from '@kbn/alerting-plugin/server/routes/lib';
|
||||
import { MAINTENANCE_WINDOW_FEATURE_ID } from '@kbn/alerting-plugin/common';
|
||||
import { MaintenanceWindowCallout } from '.';
|
||||
import { fetchActiveMaintenanceWindows } from './api';
|
||||
import {
|
||||
RECURRING_RUNNING_MAINTENANCE_WINDOW,
|
||||
RUNNING_MAINTENANCE_WINDOW_1,
|
||||
RUNNING_MAINTENANCE_WINDOW_2,
|
||||
UPCOMING_MAINTENANCE_WINDOW,
|
||||
} from './mock';
|
||||
|
||||
jest.mock('./api', () => ({
|
||||
fetchActiveMaintenanceWindows: jest.fn(() => Promise.resolve([])),
|
||||
|
@ -32,49 +33,6 @@ const TestProviders: React.FC<{}> = ({ children }) => {
|
|||
);
|
||||
};
|
||||
|
||||
const RUNNING_MAINTENANCE_WINDOW_1: Partial<MaintenanceWindow> = {
|
||||
title: 'Running maintenance window 1',
|
||||
id: '63057284-ac31-42ba-fe22-adfe9732e5ae',
|
||||
status: MaintenanceWindowStatus.Running,
|
||||
events: [{ gte: '2023-04-20T16:27:30.753Z', lte: '2023-04-20T16:57:30.753Z' }],
|
||||
};
|
||||
|
||||
const RUNNING_MAINTENANCE_WINDOW_2: Partial<MaintenanceWindow> = {
|
||||
title: 'Running maintenance window 2',
|
||||
id: '45894340-df98-11ed-ac81-bfcb4982b4fd',
|
||||
status: MaintenanceWindowStatus.Running,
|
||||
events: [{ gte: '2023-04-20T16:47:42.871Z', lte: '2023-04-20T17:11:32.192Z' }],
|
||||
};
|
||||
|
||||
const RECURRING_RUNNING_MAINTENANCE_WINDOW: Partial<AsApiContract<MaintenanceWindow>> = {
|
||||
title: 'Recurring running maintenance window',
|
||||
id: 'e2228300-e9ad-11ed-ba37-db17c6e6182b',
|
||||
status: MaintenanceWindowStatus.Running,
|
||||
events: [
|
||||
{ gte: '2023-05-03T12:27:18.569Z', lte: '2023-05-03T12:57:18.569Z' },
|
||||
{ gte: '2023-05-10T12:27:18.569Z', lte: '2023-05-10T12:57:18.569Z' },
|
||||
],
|
||||
expiration_date: '2024-05-03T12:27:35.088Z',
|
||||
r_rule: {
|
||||
dtstart: '2023-05-03T12:27:18.569Z',
|
||||
tzid: 'Europe/Amsterdam',
|
||||
freq: 3,
|
||||
interval: 1,
|
||||
count: 2,
|
||||
byweekday: ['WE'],
|
||||
},
|
||||
};
|
||||
|
||||
const UPCOMING_MAINTENANCE_WINDOW: Partial<MaintenanceWindow> = {
|
||||
title: 'Upcoming maintenance window',
|
||||
id: '5eafe070-e030-11ed-ac81-bfcb4982b4fd',
|
||||
status: MaintenanceWindowStatus.Upcoming,
|
||||
events: [
|
||||
{ gte: '2023-04-21T10:36:14.028Z', lte: '2023-04-21T10:37:00.000Z' },
|
||||
{ gte: '2023-04-28T10:36:14.028Z', lte: '2023-04-28T10:37:00.000Z' },
|
||||
],
|
||||
};
|
||||
|
||||
const fetchActiveMaintenanceWindowsMock = fetchActiveMaintenanceWindows as jest.Mock;
|
||||
|
||||
const kibanaServicesMock = {
|
||||
|
|
|
@ -50,7 +50,12 @@ export function MaintenanceWindowCallout({
|
|||
|
||||
if (activeMaintenanceWindows.some(({ status }) => status === MaintenanceWindowStatus.Running)) {
|
||||
return (
|
||||
<EuiCallOut title={MAINTENANCE_WINDOW_RUNNING} color="warning" iconType="iInCircle">
|
||||
<EuiCallOut
|
||||
title={MAINTENANCE_WINDOW_RUNNING}
|
||||
color="warning"
|
||||
iconType="iInCircle"
|
||||
data-test-subj="maintenanceWindowCallout"
|
||||
>
|
||||
{MAINTENANCE_WINDOW_RUNNING_DESCRIPTION}
|
||||
</EuiCallOut>
|
||||
);
|
||||
|
|
|
@ -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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { AsApiContract } from '@kbn/alerting-plugin/server/routes/lib';
|
||||
import { MaintenanceWindow, MaintenanceWindowStatus } from './types';
|
||||
|
||||
export const RUNNING_MAINTENANCE_WINDOW_1: Partial<MaintenanceWindow> = {
|
||||
title: 'Running maintenance window 1',
|
||||
id: '63057284-ac31-42ba-fe22-adfe9732e5ae',
|
||||
status: MaintenanceWindowStatus.Running,
|
||||
events: [{ gte: '2023-04-20T16:27:30.753Z', lte: '2023-04-20T16:57:30.753Z' }],
|
||||
};
|
||||
|
||||
export const RUNNING_MAINTENANCE_WINDOW_2: Partial<MaintenanceWindow> = {
|
||||
title: 'Running maintenance window 2',
|
||||
id: '45894340-df98-11ed-ac81-bfcb4982b4fd',
|
||||
status: MaintenanceWindowStatus.Running,
|
||||
events: [{ gte: '2023-04-20T16:47:42.871Z', lte: '2023-04-20T17:11:32.192Z' }],
|
||||
};
|
||||
|
||||
export const RECURRING_RUNNING_MAINTENANCE_WINDOW: Partial<AsApiContract<MaintenanceWindow>> = {
|
||||
title: 'Recurring running maintenance window',
|
||||
id: 'e2228300-e9ad-11ed-ba37-db17c6e6182b',
|
||||
status: MaintenanceWindowStatus.Running,
|
||||
events: [
|
||||
{ gte: '2023-05-03T12:27:18.569Z', lte: '2023-05-03T12:57:18.569Z' },
|
||||
{ gte: '2023-05-10T12:27:18.569Z', lte: '2023-05-10T12:57:18.569Z' },
|
||||
],
|
||||
expiration_date: '2024-05-03T12:27:35.088Z',
|
||||
r_rule: {
|
||||
dtstart: '2023-05-03T12:27:18.569Z',
|
||||
tzid: 'Europe/Amsterdam',
|
||||
freq: 3,
|
||||
interval: 1,
|
||||
count: 2,
|
||||
byweekday: ['WE'],
|
||||
},
|
||||
};
|
||||
|
||||
export const UPCOMING_MAINTENANCE_WINDOW: Partial<MaintenanceWindow> = {
|
||||
title: 'Upcoming maintenance window',
|
||||
id: '5eafe070-e030-11ed-ac81-bfcb4982b4fd',
|
||||
status: MaintenanceWindowStatus.Upcoming,
|
||||
events: [
|
||||
{ gte: '2023-04-21T10:36:14.028Z', lte: '2023-04-21T10:37:00.000Z' },
|
||||
{ gte: '2023-04-28T10:36:14.028Z', lte: '2023-04-28T10:37:00.000Z' },
|
||||
],
|
||||
};
|
184
x-pack/plugins/observability/public/pages/alerts/alerts.test.tsx
Normal file
184
x-pack/plugins/observability/public/pages/alerts/alerts.test.tsx
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* 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 { render, waitFor } from '@testing-library/react';
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import { AppMountParameters } from '@kbn/core/public';
|
||||
import { TimeBuckets } from '@kbn/data-plugin/common';
|
||||
import { fetchActiveMaintenanceWindows } from '@kbn/alerts-ui-shared/src/maintenance_window_callout/api';
|
||||
import { RUNNING_MAINTENANCE_WINDOW_1 } from '@kbn/alerts-ui-shared/src/maintenance_window_callout/mock';
|
||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
|
||||
import { MAINTENANCE_WINDOW_FEATURE_ID } from '@kbn/alerting-plugin/common/maintenance_window';
|
||||
|
||||
import { ObservabilityPublicPluginsStart } from '../../plugin';
|
||||
import { AlertsPage } from './alerts';
|
||||
import { kibanaStartMock } from '../../utils/kibana_react.mock';
|
||||
import * as pluginContext from '../../hooks/use_plugin_context';
|
||||
import * as dataContext from '../../hooks/use_has_data';
|
||||
import { createObservabilityRuleTypeRegistryMock } from '../../rules/observability_rule_type_registry_mock';
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
import { euiDarkVars } from '@kbn/ui-theme';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
|
||||
const mockUseKibanaReturnValue = kibanaStartMock.startContract();
|
||||
mockUseKibanaReturnValue.services.application.capabilities = {
|
||||
...mockUseKibanaReturnValue.services.application.capabilities,
|
||||
[MAINTENANCE_WINDOW_FEATURE_ID]: {
|
||||
save: true,
|
||||
show: true,
|
||||
},
|
||||
};
|
||||
|
||||
jest.mock('../../utils/kibana_react', () => ({
|
||||
__esModule: true,
|
||||
useKibana: jest.fn(() => mockUseKibanaReturnValue),
|
||||
}));
|
||||
jest.mock('@kbn/kibana-react-plugin/public', () => ({
|
||||
__esModule: true,
|
||||
useKibana: jest.fn(() => mockUseKibanaReturnValue),
|
||||
}));
|
||||
jest.mock('@kbn/observability-shared-plugin/public');
|
||||
jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({
|
||||
appMountParameters: {
|
||||
setHeaderActionMenu: () => {},
|
||||
} as unknown as AppMountParameters,
|
||||
config: {
|
||||
unsafe: {
|
||||
slo: { enabled: false },
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
observability: { enabled: false },
|
||||
},
|
||||
thresholdRule: { enabled: false },
|
||||
},
|
||||
compositeSlo: {
|
||||
enabled: false,
|
||||
},
|
||||
aiAssistant: {
|
||||
enabled: false,
|
||||
feedback: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
observabilityRuleTypeRegistry: createObservabilityRuleTypeRegistryMock(),
|
||||
ObservabilityPageTemplate: KibanaPageTemplate,
|
||||
kibanaFeatures: [],
|
||||
core: {} as CoreStart,
|
||||
plugins: {} as ObservabilityPublicPluginsStart,
|
||||
hasAnyData: true,
|
||||
isAllRequestsComplete: true,
|
||||
}));
|
||||
|
||||
jest.spyOn(dataContext, 'useHasData').mockImplementation(() => ({
|
||||
hasDataMap: {},
|
||||
hasAnyData: true,
|
||||
isAllRequestsComplete: true,
|
||||
onRefreshTimeRange: jest.fn(),
|
||||
forceUpdate: 'false',
|
||||
}));
|
||||
|
||||
jest.mock('@kbn/alerts-ui-shared/src/maintenance_window_callout/api', () => ({
|
||||
fetchActiveMaintenanceWindows: jest.fn(() => Promise.resolve([])),
|
||||
}));
|
||||
const fetchActiveMaintenanceWindowsMock = fetchActiveMaintenanceWindows as jest.Mock;
|
||||
|
||||
jest.mock('../../hooks/use_time_buckets', () => ({
|
||||
useTimeBuckets: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../../hooks/use_has_data', () => ({
|
||||
useHasData: jest.fn(),
|
||||
}));
|
||||
|
||||
const { useTimeBuckets } = jest.requireMock('../../hooks/use_time_buckets');
|
||||
const { useHasData } = jest.requireMock('../../hooks/use_has_data');
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
cacheTime: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
function AllTheProviders({ children }: { children: any }) {
|
||||
return (
|
||||
<ThemeProvider
|
||||
theme={() => ({ eui: { ...euiDarkVars, euiColorLightShade: '#ece' }, darkMode: true })}
|
||||
>
|
||||
<IntlProvider locale="en">
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
</IntlProvider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
describe('AlertsPage with all capabilities', () => {
|
||||
const timeBuckets = new TimeBuckets({
|
||||
'histogram:maxBars': 12,
|
||||
'histogram:barTarget': 10,
|
||||
dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS',
|
||||
'dateFormat:scaled': [
|
||||
['', 'HH:mm:ss.SSS'],
|
||||
['PT1S', 'HH:mm:ss'],
|
||||
['PT1M', 'HH:mm'],
|
||||
['PT1H', 'YYYY-MM-DD HH:mm'],
|
||||
['P1DT', 'YYYY-MM-DD'],
|
||||
['P1YT', 'YYYY'],
|
||||
],
|
||||
});
|
||||
|
||||
async function setup() {
|
||||
return render(<AlertsPage />, { wrapper: AllTheProviders });
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
fetchActiveMaintenanceWindowsMock.mockResolvedValue([]);
|
||||
useHasData.mockReturnValue({
|
||||
hasDataMap: {
|
||||
apm: { hasData: true, status: 'success' },
|
||||
synthetics: { hasData: true, status: 'success' },
|
||||
infra_logs: { hasData: undefined, status: 'success' },
|
||||
infra_metrics: { hasData: true, status: 'success' },
|
||||
ux: { hasData: undefined, status: 'success' },
|
||||
alert: { hasData: false, status: 'success' },
|
||||
},
|
||||
hasAnyData: true,
|
||||
isAllRequestsComplete: true,
|
||||
onRefreshTimeRange: () => {},
|
||||
forceUpdate: '',
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fetchActiveMaintenanceWindowsMock.mockClear();
|
||||
useTimeBuckets.mockReturnValue(timeBuckets);
|
||||
});
|
||||
|
||||
it('should render an alerts page template', async () => {
|
||||
const wrapper = await setup();
|
||||
await waitFor(() => {
|
||||
expect(wrapper.getByText('Alerts')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders MaintenanceWindowCallout if one exists', async () => {
|
||||
fetchActiveMaintenanceWindowsMock.mockResolvedValue([RUNNING_MAINTENANCE_WINDOW_1]);
|
||||
const wrapper = await setup();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(wrapper.getByTestId('maintenanceWindowCallout')).toBeInTheDocument();
|
||||
expect(fetchActiveMaintenanceWindowsMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -13,6 +13,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { loadRuleAggregations } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { AlertConsumers } from '@kbn/rule-data-utils';
|
||||
import { useBreadcrumbs } from '@kbn/observability-shared-plugin/public';
|
||||
import { MaintenanceWindowCallout } from '@kbn/alerts-ui-shared';
|
||||
|
||||
import { useKibana } from '../../utils/kibana_react';
|
||||
import { useHasData } from '../../hooks/use_has_data';
|
||||
|
@ -41,6 +42,7 @@ const DEFAULT_INTERVAL = '60s';
|
|||
const DEFAULT_DATE_FORMAT = 'YYYY-MM-DD HH:mm';
|
||||
|
||||
function InternalAlertsPage() {
|
||||
const kibanaServices = useKibana().services;
|
||||
const {
|
||||
charts,
|
||||
data: {
|
||||
|
@ -56,7 +58,7 @@ function InternalAlertsPage() {
|
|||
getAlertsStateTable: AlertsStateTable,
|
||||
getAlertSummaryWidget: AlertSummaryWidget,
|
||||
},
|
||||
} = useKibana().services;
|
||||
} = kibanaServices;
|
||||
const { ObservabilityPageTemplate, observabilityRuleTypeRegistry } = usePluginContext();
|
||||
const alertSearchBarStateProps = useAlertSearchBarStateContainer(ALERTS_URL_STORAGE_KEY, {
|
||||
replace: false,
|
||||
|
@ -178,6 +180,9 @@ function InternalAlertsPage() {
|
|||
>
|
||||
<HeaderMenu />
|
||||
<EuiFlexGroup direction="column" gutterSize="m">
|
||||
<EuiFlexItem>
|
||||
<MaintenanceWindowCallout kibanaServices={kibanaServices} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<ObservabilityAlertSearchBar
|
||||
{...alertSearchBarStateProps}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import React from 'react';
|
||||
import { EuiButtonEmpty, EuiStat } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
import { euiStyled } from '@kbn/kibana-react-plugin/common';
|
||||
|
||||
export interface RuleStatsState {
|
||||
|
@ -20,7 +21,7 @@ export interface RuleStatsState {
|
|||
type StatType = 'disabled' | 'snoozed' | 'error';
|
||||
|
||||
const Divider = euiStyled.div`
|
||||
border-right: 1px solid ${({ theme }) => theme.eui.euiColorLightShade};
|
||||
border-right: 1px solid ${euiThemeVars.euiColorLightShade};
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
|
|
|
@ -6,10 +6,14 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { mockCasesContract } from '@kbn/cases-plugin/public/mocks';
|
||||
import { timefilterServiceMock } from '@kbn/data-plugin/public/query/timefilter/timefilter_service.mock';
|
||||
|
||||
const triggersActionsUiStartMock = {
|
||||
createStart() {
|
||||
return {
|
||||
getAlertSummaryWidget: jest.fn(() => (
|
||||
<div data-test-subj="alerts-summary-widget">mocked component</div>
|
||||
)),
|
||||
getAlertsSearchBar: jest.fn(() => (
|
||||
<div data-test-subj="alerts-search-bar">mocked component</div>
|
||||
)),
|
||||
|
@ -67,9 +71,7 @@ const data = {
|
|||
create: jest.fn(),
|
||||
},
|
||||
query: {
|
||||
timefilter: {
|
||||
timefilter: jest.fn(),
|
||||
},
|
||||
timefilter: timefilterServiceMock.createSetupContract(),
|
||||
},
|
||||
search: {
|
||||
searchSource: {
|
||||
|
|
|
@ -19,6 +19,7 @@ export const kibanaStartMock = {
|
|||
...observabilityPublicPluginsStartMock.createStart(),
|
||||
storage: coreMock.createStorage(),
|
||||
cases: { ...casesPluginMock.createStartContract() },
|
||||
charts: { theme: { useChartsTheme: () => {}, useChartsBaseTheme: () => {} } },
|
||||
},
|
||||
};
|
||||
},
|
||||
|
|
|
@ -14,6 +14,9 @@ import {
|
|||
waitForElementToBeRemoved,
|
||||
cleanup,
|
||||
} from '@testing-library/react';
|
||||
|
||||
import { fetchActiveMaintenanceWindows } from '@kbn/alerts-ui-shared/src/maintenance_window_callout/api';
|
||||
import { RUNNING_MAINTENANCE_WINDOW_1 } from '@kbn/alerts-ui-shared/src/maintenance_window_callout/mock';
|
||||
import { actionTypeRegistryMock } from '../../../action_type_registry.mock';
|
||||
import { ruleTypeRegistryMock } from '../../../rule_type_registry.mock';
|
||||
import { percentileFields, RulesList } from './rules_list';
|
||||
|
@ -38,7 +41,7 @@ import {
|
|||
getDisabledByLicenseRuleTypeFromApi,
|
||||
} from './test_helpers';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { parseDuration } from '@kbn/alerting-plugin/common';
|
||||
import { MAINTENANCE_WINDOW_FEATURE_ID, parseDuration } from '@kbn/alerting-plugin/common';
|
||||
import { getFormattedDuration } from '../../../lib/monitoring_utils';
|
||||
|
||||
jest.mock('../../../../common/lib/kibana');
|
||||
|
@ -104,6 +107,12 @@ jest.mock('react-router-dom', () => ({
|
|||
pathname: '/triggersActions/rules/',
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('@kbn/alerts-ui-shared/src/maintenance_window_callout/api', () => ({
|
||||
fetchActiveMaintenanceWindows: jest.fn(() => Promise.resolve([])),
|
||||
}));
|
||||
const fetchActiveMaintenanceWindowsMock = fetchActiveMaintenanceWindows as jest.Mock;
|
||||
|
||||
jest.mock('../../../lib/capabilities', () => ({
|
||||
hasAllPrivilege: jest.fn(() => true),
|
||||
hasSaveRulesCapability: jest.fn(() => true),
|
||||
|
@ -152,6 +161,7 @@ describe('Update Api Key', () => {
|
|||
const addDanger = jest.fn();
|
||||
|
||||
beforeAll(() => {
|
||||
fetchActiveMaintenanceWindowsMock.mockResolvedValue([]);
|
||||
loadRulesWithKueryFilter.mockResolvedValue({
|
||||
page: 1,
|
||||
perPage: 10000,
|
||||
|
@ -161,6 +171,13 @@ describe('Update Api Key', () => {
|
|||
loadActionTypes.mockResolvedValue([]);
|
||||
loadRuleTypes.mockResolvedValue([ruleTypeFromApi]);
|
||||
loadAllActions.mockResolvedValue([]);
|
||||
useKibanaMock().services.application.capabilities = {
|
||||
...useKibanaMock().services.application.capabilities,
|
||||
[MAINTENANCE_WINDOW_FEATURE_ID]: {
|
||||
save: true,
|
||||
show: true,
|
||||
},
|
||||
};
|
||||
useKibanaMock().services.notifications.toasts = {
|
||||
addSuccess,
|
||||
addError,
|
||||
|
@ -197,6 +214,7 @@ describe('Update Api Key', () => {
|
|||
|
||||
describe('rules_list component empty', () => {
|
||||
beforeEach(() => {
|
||||
fetchActiveMaintenanceWindowsMock.mockResolvedValue([]);
|
||||
loadRulesWithKueryFilter.mockResolvedValue({
|
||||
page: 1,
|
||||
perPage: 10000,
|
||||
|
@ -228,7 +246,13 @@ describe('rules_list component empty', () => {
|
|||
|
||||
ruleTypeRegistry.list.mockReturnValue([ruleType]);
|
||||
actionTypeRegistry.list.mockReturnValue([]);
|
||||
|
||||
useKibanaMock().services.application.capabilities = {
|
||||
...useKibanaMock().services.application.capabilities,
|
||||
[MAINTENANCE_WINDOW_FEATURE_ID]: {
|
||||
save: true,
|
||||
show: true,
|
||||
},
|
||||
};
|
||||
useKibanaMock().services.ruleTypeRegistry = ruleTypeRegistry;
|
||||
useKibanaMock().services.actionTypeRegistry = actionTypeRegistry;
|
||||
});
|
||||
|
@ -244,6 +268,13 @@ describe('rules_list component empty', () => {
|
|||
expect(await screen.findByTestId('createFirstRuleEmptyPrompt')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders MaintenanceWindowCallout if one exists', async () => {
|
||||
fetchActiveMaintenanceWindowsMock.mockResolvedValue([RUNNING_MAINTENANCE_WINDOW_1]);
|
||||
renderWithProviders(<RulesList />);
|
||||
expect(await screen.findByText('Maintenance window is running')).toBeInTheDocument();
|
||||
expect(fetchActiveMaintenanceWindowsMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('renders Create rule button', async () => {
|
||||
renderWithProviders(<RulesList showCreateRuleButtonInPrompt />);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import {
|
|||
RuleLastRunOutcomeValues,
|
||||
} from '@kbn/alerting-plugin/common';
|
||||
import { ruleDetailsRoute as commonRuleDetailsRoute } from '@kbn/rule-data-utils';
|
||||
import { MaintenanceWindowCallout } from '@kbn/alerts-ui-shared';
|
||||
import {
|
||||
Rule,
|
||||
RuleTableItem,
|
||||
|
@ -169,6 +170,7 @@ export const RulesList = ({
|
|||
setHeaderActions,
|
||||
}: RulesListProps) => {
|
||||
const history = useHistory();
|
||||
const kibanaServices = useKibana().services;
|
||||
const {
|
||||
actionTypeRegistry,
|
||||
application: { capabilities },
|
||||
|
@ -176,7 +178,7 @@ export const RulesList = ({
|
|||
kibanaFeatures,
|
||||
notifications: { toasts },
|
||||
ruleTypeRegistry,
|
||||
} = useKibana().services;
|
||||
} = kibanaServices;
|
||||
const canExecuteActions = hasExecuteActionsCapability(capabilities);
|
||||
const [isPerformingAction, setIsPerformingAction] = useState<boolean>(false);
|
||||
const [page, setPage] = useState<Pagination>({ index: 0, size: DEFAULT_SEARCH_PAGE_SIZE });
|
||||
|
@ -722,7 +724,7 @@ export const RulesList = ({
|
|||
{showSearchBar && !isEmpty(filters.ruleParams) ? (
|
||||
<RulesListClearRuleFilterBanner onClickClearFilter={handleClearRuleParamFilter} />
|
||||
) : null}
|
||||
|
||||
<MaintenanceWindowCallout kibanaServices={kibanaServices} />
|
||||
<RulesListPrompts
|
||||
showNoAuthPrompt={showNoAuthPrompt}
|
||||
showCreateFirstRulePrompt={showCreateFirstRulePrompt}
|
||||
|
|
|
@ -92,6 +92,8 @@ jest.mock('../../../lib/capabilities', () => ({
|
|||
jest.mock('../../../../common/get_experimental_features', () => ({
|
||||
getIsExperimentalFeatureEnabled: jest.fn(),
|
||||
}));
|
||||
jest.mock('@kbn/alerts-ui-shared', () => ({ MaintenanceWindowCallout: jest.fn(() => <></>) }));
|
||||
|
||||
const { loadRuleAggregationsWithKueryFilter } = jest.requireMock(
|
||||
'../../../lib/rule_api/aggregate_kuery_filter'
|
||||
);
|
||||
|
|
|
@ -91,6 +91,7 @@ jest.mock('../../../../common/get_experimental_features', () => ({
|
|||
jest.mock('../../../lib/rule_api/aggregate_kuery_filter', () => ({
|
||||
loadRuleAggregationsWithKueryFilter: jest.fn(),
|
||||
}));
|
||||
jest.mock('@kbn/alerts-ui-shared', () => ({ MaintenanceWindowCallout: jest.fn(() => <></>) }));
|
||||
|
||||
const { loadRuleAggregationsWithKueryFilter } = jest.requireMock(
|
||||
'../../../lib/rule_api/aggregate_kuery_filter'
|
||||
|
|
|
@ -90,6 +90,7 @@ jest.mock('../../../../common/get_experimental_features', () => ({
|
|||
jest.mock('../../../lib/rule_api/aggregate_kuery_filter', () => ({
|
||||
loadRuleAggregationsWithKueryFilter: jest.fn(),
|
||||
}));
|
||||
jest.mock('@kbn/alerts-ui-shared', () => ({ MaintenanceWindowCallout: jest.fn(() => <></>) }));
|
||||
|
||||
const { loadRuleAggregationsWithKueryFilter } = jest.requireMock(
|
||||
'../../../lib/rule_api/aggregate_kuery_filter'
|
||||
|
|
|
@ -91,6 +91,7 @@ jest.mock('../../../../common/get_experimental_features', () => ({
|
|||
jest.mock('../../../lib/rule_api/aggregate_kuery_filter', () => ({
|
||||
loadRuleAggregationsWithKueryFilter: jest.fn(),
|
||||
}));
|
||||
jest.mock('@kbn/alerts-ui-shared', () => ({ MaintenanceWindowCallout: jest.fn(() => <></>) }));
|
||||
|
||||
const { loadRuleAggregationsWithKueryFilter } = jest.requireMock(
|
||||
'../../../lib/rule_api/aggregate_kuery_filter'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue