mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Infra][Logs Explorer] Factor out shared custom hook into a package (#182336)
## 📓 Summary
This work is just the extraction of a utility hook implemented in the
`infra` plugin for re-usability, as there are some scenarios where it
becomes handy in the logs explorer plugin too.
For improved reusability in future, I extracted the useBoolean hook into
a react-hooks package, where additional stateful utility hooks can go in
future.
This also replaces the current usage of the hook in the `infra` plugin
and is used to refactor part of the logs_explorer top nav.
---------
Co-authored-by: Marco Antonio Ghiani <marcoantonio.ghiani@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
9a320b0507
commit
7a69fdd469
25 changed files with 264 additions and 81 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -639,6 +639,7 @@ x-pack/plugins/observability_solution/profiling @elastic/obs-ux-infra_services-t
|
|||
packages/kbn-profiling-utils @elastic/obs-ux-infra_services-team
|
||||
x-pack/packages/kbn-random-sampling @elastic/kibana-visualizations
|
||||
packages/kbn-react-field @elastic/kibana-data-discovery
|
||||
packages/kbn-react-hooks @elastic/obs-ux-logs-team
|
||||
packages/react/kibana_context/common @elastic/appex-sharedux
|
||||
packages/react/kibana_context/render @elastic/appex-sharedux
|
||||
packages/react/kibana_context/root @elastic/appex-sharedux
|
||||
|
|
|
@ -650,6 +650,7 @@
|
|||
"@kbn/profiling-utils": "link:packages/kbn-profiling-utils",
|
||||
"@kbn/random-sampling": "link:x-pack/packages/kbn-random-sampling",
|
||||
"@kbn/react-field": "link:packages/kbn-react-field",
|
||||
"@kbn/react-hooks": "link:packages/kbn-react-hooks",
|
||||
"@kbn/react-kibana-context-common": "link:packages/react/kibana_context/common",
|
||||
"@kbn/react-kibana-context-render": "link:packages/react/kibana_context/render",
|
||||
"@kbn/react-kibana-context-root": "link:packages/react/kibana_context/root",
|
||||
|
|
28
packages/kbn-react-hooks/README.md
Normal file
28
packages/kbn-react-hooks/README.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# @kbn/react-hooks
|
||||
|
||||
A utility package, `@kbn/react-hooks`, provides custom react hooks for simple abstractions.
|
||||
|
||||
## Custom Hooks
|
||||
|
||||
### [useBoolean](./src/useBoolean)
|
||||
|
||||
Simplify handling boolean value with predefined handlers.
|
||||
|
||||
```tsx
|
||||
function App() {
|
||||
const [value, { on, off, toggle }] = useBoolean();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<EuiText>
|
||||
The current value is <strong>{value.toString().toUpperCase()}</strong>
|
||||
</EuiText>
|
||||
<EuiFlexGroup>
|
||||
<EuiButton onClick={on}>On</EuiButton>
|
||||
<EuiButton onClick={off}>Off</EuiButton>
|
||||
<EuiButton onClick={toggle}>Toggle</EuiButton>
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
10
packages/kbn-react-hooks/index.ts
Normal file
10
packages/kbn-react-hooks/index.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { useBoolean } from './src/use_boolean';
|
||||
export type { UseBooleanHandlers, UseBooleanResult } from './src/use_boolean';
|
13
packages/kbn-react-hooks/jest.config.js
Normal file
13
packages/kbn-react-hooks/jest.config.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../..',
|
||||
roots: ['<rootDir>/packages/kbn-react-hooks'],
|
||||
};
|
5
packages/kbn-react-hooks/kibana.jsonc
Normal file
5
packages/kbn-react-hooks/kibana.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"type": "shared-common",
|
||||
"id": "@kbn/react-hooks",
|
||||
"owner": "@elastic/obs-ux-logs-team"
|
||||
}
|
7
packages/kbn-react-hooks/package.json
Normal file
7
packages/kbn-react-hooks/package.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "@kbn/react-hooks",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0",
|
||||
"sideEffects": false
|
||||
}
|
9
packages/kbn-react-hooks/src/use_boolean/index.ts
Normal file
9
packages/kbn-react-hooks/src/use_boolean/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './use_boolean';
|
105
packages/kbn-react-hooks/src/use_boolean/use_boolean.test.ts
Normal file
105
packages/kbn-react-hooks/src/use_boolean/use_boolean.test.ts
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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 { act, cleanup, renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
import { useBoolean } from './use_boolean';
|
||||
|
||||
describe('useBoolean hook', () => {
|
||||
afterEach(cleanup);
|
||||
|
||||
it('should return an array. The first element should be a boolean, the second element is an object which should contain three functions: "on", "off" and "toggle"', () => {
|
||||
const { result } = renderHook(() => useBoolean());
|
||||
const [value, handlers] = result.current;
|
||||
|
||||
expect(typeof value).toBe('boolean');
|
||||
expect(typeof handlers).toBe('object');
|
||||
expect(typeof handlers.on).toBe('function');
|
||||
expect(typeof handlers.off).toBe('function');
|
||||
expect(typeof handlers.toggle).toBe('function');
|
||||
});
|
||||
|
||||
it('should initialize the value with false by default', () => {
|
||||
const { result } = renderHook(() => useBoolean());
|
||||
const [value, handlers] = result.current;
|
||||
|
||||
expect(value).toBe(false);
|
||||
expect(typeof handlers).toBe('object');
|
||||
});
|
||||
|
||||
it('should toggle the value when no value is passed to the updater function', () => {
|
||||
const { result } = renderHook(() => useBoolean());
|
||||
const [, { toggle }] = result.current;
|
||||
|
||||
expect(result.current[0]).toBe(false);
|
||||
|
||||
act(() => {
|
||||
toggle();
|
||||
});
|
||||
expect(result.current[0]).toBe(true);
|
||||
|
||||
act(() => {
|
||||
toggle();
|
||||
});
|
||||
expect(result.current[0]).toBe(false);
|
||||
});
|
||||
|
||||
it('should set the value to true the value when the "on" method is invoked, once or multiple times', () => {
|
||||
const { result } = renderHook(() => useBoolean());
|
||||
const [, { on }] = result.current;
|
||||
|
||||
expect(result.current[0]).toBe(false);
|
||||
|
||||
act(() => {
|
||||
on();
|
||||
});
|
||||
expect(result.current[0]).toBe(true);
|
||||
|
||||
act(() => {
|
||||
on();
|
||||
on();
|
||||
});
|
||||
expect(result.current[0]).toBe(true);
|
||||
});
|
||||
|
||||
it('should set the value to false the value when the "off" method is invoked, once or multiple times', () => {
|
||||
const { result } = renderHook(() => useBoolean(true));
|
||||
const [, { off }] = result.current;
|
||||
|
||||
expect(result.current[0]).toBe(true);
|
||||
|
||||
act(() => {
|
||||
off();
|
||||
});
|
||||
expect(result.current[0]).toBe(false);
|
||||
|
||||
act(() => {
|
||||
off();
|
||||
off();
|
||||
});
|
||||
expect(result.current[0]).toBe(false);
|
||||
});
|
||||
|
||||
it('should return the handlers as memoized functions', () => {
|
||||
const { result } = renderHook(() => useBoolean(true));
|
||||
const [, { on, off, toggle }] = result.current;
|
||||
|
||||
expect(typeof on).toBe('function');
|
||||
expect(typeof off).toBe('function');
|
||||
expect(typeof toggle).toBe('function');
|
||||
|
||||
act(() => {
|
||||
toggle();
|
||||
});
|
||||
|
||||
const [, handlers] = result.current;
|
||||
expect(on).toBe(handlers.on);
|
||||
expect(off).toBe(handlers.off);
|
||||
expect(toggle).toBe(handlers.toggle);
|
||||
});
|
||||
});
|
35
packages/kbn-react-hooks/src/use_boolean/use_boolean.ts
Normal file
35
packages/kbn-react-hooks/src/use_boolean/use_boolean.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 { useMemo } from 'react';
|
||||
import useToggle from 'react-use/lib/useToggle';
|
||||
|
||||
export type VoidHandler = () => void;
|
||||
|
||||
export interface UseBooleanHandlers {
|
||||
on: VoidHandler;
|
||||
off: VoidHandler;
|
||||
toggle: ReturnType<typeof useToggle>[1];
|
||||
}
|
||||
|
||||
export type UseBooleanResult = [boolean, UseBooleanHandlers];
|
||||
|
||||
export const useBoolean = (initialValue: boolean = false): UseBooleanResult => {
|
||||
const [value, toggle] = useToggle(initialValue);
|
||||
|
||||
const handlers = useMemo(
|
||||
() => ({
|
||||
toggle,
|
||||
on: () => toggle(true),
|
||||
off: () => toggle(false),
|
||||
}),
|
||||
[toggle]
|
||||
);
|
||||
|
||||
return [value, handlers];
|
||||
};
|
19
packages/kbn-react-hooks/tsconfig.json
Normal file
19
packages/kbn-react-hooks/tsconfig.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types",
|
||||
"types": [
|
||||
"jest",
|
||||
"node",
|
||||
"react",
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
],
|
||||
"kbn_references": []
|
||||
}
|
|
@ -1272,6 +1272,8 @@
|
|||
"@kbn/random-sampling/*": ["x-pack/packages/kbn-random-sampling/*"],
|
||||
"@kbn/react-field": ["packages/kbn-react-field"],
|
||||
"@kbn/react-field/*": ["packages/kbn-react-field/*"],
|
||||
"@kbn/react-hooks": ["packages/kbn-react-hooks"],
|
||||
"@kbn/react-hooks/*": ["packages/kbn-react-hooks/*"],
|
||||
"@kbn/react-kibana-context-common": ["packages/react/kibana_context/common"],
|
||||
"@kbn/react-kibana-context-common/*": ["packages/react/kibana_context/common/*"],
|
||||
"@kbn/react-kibana-context-render": ["packages/react/kibana_context/render"],
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { EuiPopover, EuiIcon, type IconType, type IconColor, type IconSize } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import { useBoolean } from '../../../../hooks/use_boolean';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
|
||||
export const Popover = ({
|
||||
children,
|
||||
|
|
|
@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n';
|
|||
|
||||
import React from 'react';
|
||||
import { EuiButtonIcon, EuiContextMenuPanel, EuiContextMenuItem, EuiPopover } from '@elastic/eui';
|
||||
import { useBoolean } from '../../../../hooks/use_boolean';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
|
||||
interface Props {
|
||||
items: React.ReactNode[];
|
||||
|
|
|
@ -10,9 +10,9 @@ import { EuiFlexGroup, EuiFlexItem, type EuiAccordionProps } from '@elastic/eui'
|
|||
import type { TimeRange } from '@kbn/es-query';
|
||||
import type { InventoryItemType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { findInventoryFields } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
import { usePluginConfig } from '../../../../../containers/plugin_config_context';
|
||||
import { AlertFlyout } from '../../../../../alerting/inventory/components/alert_flyout';
|
||||
import { useBoolean } from '../../../../../hooks/use_boolean';
|
||||
import { AlertsSectionTitle } from '../section_titles';
|
||||
import { useAssetDetailsRenderPropsContext } from '../../../hooks/use_asset_details_render_props';
|
||||
import { Section } from '../../../components/section';
|
||||
|
|
|
@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { EuiButton, EuiPopover, EuiListGroup, EuiListGroupItem } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { NonEmptyString } from '@kbn/io-ts-utils';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
import {
|
||||
SavedViewState,
|
||||
SavedViewOperations,
|
||||
|
@ -17,7 +18,6 @@ import {
|
|||
BasicAttributes,
|
||||
} from '../../../common/saved_views';
|
||||
import { ManageViewsFlyout } from './manage_views_flyout';
|
||||
import { useBoolean } from '../../hooks/use_boolean';
|
||||
import { UpsertViewModal } from './upsert_modal';
|
||||
|
||||
interface Props<TSingleSavedViewState extends SavedViewItem, TViewState>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { EuiPopover, EuiIcon } from '@elastic/eui';
|
||||
import { useBoolean } from '../../../../../hooks/use_boolean';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
|
||||
export const Popover = ({ children }: { children: React.ReactNode }) => {
|
||||
const [isPopoverOpen, { off: closePopover, toggle: togglePopover }] = useBoolean(false);
|
||||
|
|
|
@ -9,8 +9,7 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiPopover, EuiButtonEmpty, useEuiTheme, euiCanAnimate } from '@elastic/eui';
|
||||
import { cx, css } from '@emotion/css';
|
||||
|
||||
import { useBoolean } from '../../../../../hooks/use_boolean';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
|
||||
const selectedHostsLabel = (selectedHostsCount: number) => {
|
||||
return i18n.translate('xpack.infra.hostsViewPage.table.selectedHostsButton', {
|
||||
|
|
|
@ -9,6 +9,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
|||
import { AlertConsumers, ALERT_RULE_PRODUCER } from '@kbn/rule-data-utils';
|
||||
import { BrushEndListener, type XYBrushEvent } from '@elastic/charts';
|
||||
import { useSummaryTimeRange } from '@kbn/observability-plugin/public';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
import { useKibanaContextForPlugin } from '../../../../../../hooks/use_kibana';
|
||||
import { HeightRetainer } from '../../../../../../components/height_retainer';
|
||||
import { useUnifiedSearchContext } from '../../../hooks/use_unified_search';
|
||||
|
@ -25,7 +26,6 @@ import { CreateAlertRuleButton } from '../../../../../../components/shared/alert
|
|||
import { LinkToAlertsPage } from '../../../../../../components/shared/alerts/links/link_to_alerts_page';
|
||||
import { INFRA_ALERT_FEATURE_ID } from '../../../../../../../common/constants';
|
||||
import { AlertFlyout } from '../../../../../../alerting/inventory/components/alert_flyout';
|
||||
import { useBoolean } from '../../../../../../hooks/use_boolean';
|
||||
import { usePluginConfig } from '../../../../../../containers/plugin_config_context';
|
||||
|
||||
export const AlertsTabContent = () => {
|
||||
|
|
|
@ -10,7 +10,7 @@ import React from 'react';
|
|||
import { first } from 'lodash';
|
||||
import { EuiPopover, EuiToolTip } from '@elastic/eui';
|
||||
import { InventoryItemType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { useBoolean } from '../../../../../hooks/use_boolean';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
import {
|
||||
InfraWaffleMapBounds,
|
||||
InfraWaffleMapNode,
|
||||
|
|
|
@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n';
|
|||
|
||||
import { css } from '@emotion/react';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
import { DispatchWithOptionalAction } from '../../../../../hooks/use_boolean';
|
||||
import { UseBooleanHandlers } from '@kbn/react-hooks';
|
||||
|
||||
type NodeProps<T = HTMLDivElement> = React.DetailedHTMLProps<React.HTMLAttributes<T>, T> & {
|
||||
'data-test-subj'?: string;
|
||||
|
@ -162,7 +162,7 @@ export const NodeSquare = ({
|
|||
showBorder,
|
||||
}: {
|
||||
squareSize: number;
|
||||
togglePopover: DispatchWithOptionalAction<boolean>;
|
||||
togglePopover: UseBooleanHandlers['toggle'];
|
||||
showToolTip: () => void;
|
||||
hideToolTip: () => void;
|
||||
color: string;
|
||||
|
@ -203,6 +203,7 @@ export const NodeSquare = ({
|
|||
) : (
|
||||
ellipsisMode && (
|
||||
<ValueInner aria-label={nodeAriaLabel}>
|
||||
{/* eslint-disable-next-line @kbn/i18n/strings_should_be_translated_with_i18n */}
|
||||
<Label color={color}>...</Label>
|
||||
</ValueInner>
|
||||
)
|
||||
|
|
|
@ -97,6 +97,7 @@
|
|||
"@kbn/dashboard-plugin",
|
||||
"@kbn/shared-svg",
|
||||
"@kbn/aiops-log-rate-analysis",
|
||||
"@kbn/react-hooks",
|
||||
"@kbn/search-types"
|
||||
],
|
||||
"exclude": [
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
EuiContextMenuItem,
|
||||
EuiHorizontalRule,
|
||||
} from '@elastic/eui';
|
||||
import React, { useMemo, useReducer } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils';
|
||||
import { useActor } from '@xstate/react';
|
||||
|
@ -24,59 +24,12 @@ import { useLinkProps } from '@kbn/observability-shared-plugin/public';
|
|||
import { sloFeatureId } from '@kbn/observability-shared-plugin/common';
|
||||
import { loadRuleTypes } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { useBoolean } from '@kbn/react-hooks';
|
||||
import { useKibanaContextForPlugin } from '../utils/use_kibana';
|
||||
import { useObservabilityLogsExplorerPageStateContext } from '../state_machines/observability_logs_explorer/src';
|
||||
|
||||
type ThresholdRuleTypeParams = Pick<AlertParams, 'searchConfiguration'>;
|
||||
|
||||
interface AlertsPopoverState {
|
||||
isPopoverOpen: boolean;
|
||||
isAddRuleFlyoutOpen: boolean;
|
||||
isCreateSLOFlyoutOpen: boolean;
|
||||
}
|
||||
|
||||
type AlertsPopoverAction =
|
||||
| {
|
||||
type: 'togglePopover';
|
||||
isOpen?: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'toggleAddRuleFlyout';
|
||||
isOpen?: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'toggleCreateSLOFlyout';
|
||||
isOpen?: boolean;
|
||||
};
|
||||
|
||||
function alertsPopoverReducer(state: AlertsPopoverState, action: AlertsPopoverAction) {
|
||||
switch (action.type) {
|
||||
case 'togglePopover':
|
||||
return {
|
||||
isPopoverOpen: action.isOpen ?? !state.isPopoverOpen,
|
||||
isAddRuleFlyoutOpen: state.isAddRuleFlyoutOpen,
|
||||
isCreateSLOFlyoutOpen: state.isCreateSLOFlyoutOpen,
|
||||
};
|
||||
|
||||
case 'toggleAddRuleFlyout':
|
||||
return {
|
||||
isPopoverOpen: false,
|
||||
isAddRuleFlyoutOpen: action.isOpen ?? !state.isAddRuleFlyoutOpen,
|
||||
isCreateSLOFlyoutOpen: false,
|
||||
};
|
||||
|
||||
case 'toggleCreateSLOFlyout':
|
||||
return {
|
||||
isPopoverOpen: false,
|
||||
isAddRuleFlyoutOpen: false,
|
||||
isCreateSLOFlyoutOpen: action.isOpen ?? !state.isAddRuleFlyoutOpen,
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
const defaultQuery: Query = {
|
||||
language: 'kuery',
|
||||
query: '',
|
||||
|
@ -97,22 +50,14 @@ export const AlertsPopover = () => {
|
|||
|
||||
const [pageState] = useActor(useObservabilityLogsExplorerPageStateContext());
|
||||
|
||||
const [state, dispatch] = useReducer(alertsPopoverReducer, {
|
||||
isPopoverOpen: false,
|
||||
isAddRuleFlyoutOpen: false,
|
||||
isCreateSLOFlyoutOpen: false,
|
||||
});
|
||||
|
||||
const togglePopover = () => dispatch({ type: 'togglePopover' });
|
||||
const closePopover = () => dispatch({ type: 'togglePopover', isOpen: false });
|
||||
const openAddRuleFlyout = () => dispatch({ type: 'toggleAddRuleFlyout', isOpen: true });
|
||||
const closeAddRuleFlyout = () => dispatch({ type: 'toggleAddRuleFlyout', isOpen: false });
|
||||
const openCreateSLOFlyout = () => dispatch({ type: 'toggleCreateSLOFlyout', isOpen: true });
|
||||
const closeCreateSLOFlyout = () => dispatch({ type: 'toggleCreateSLOFlyout', isOpen: false });
|
||||
const [isPopoverOpen, { toggle: togglePopover, off: closePopover }] = useBoolean();
|
||||
const [isAddRuleFlyoutOpen, { on: openAddRuleFlyout, off: closeAddRuleFlyout }] = useBoolean();
|
||||
const [isCreateSLOFlyoutOpen, { on: openCreateSLOFlyout, off: closeCreateSLOFlyout }] =
|
||||
useBoolean();
|
||||
|
||||
const addRuleFlyout = useMemo(() => {
|
||||
if (
|
||||
state.isAddRuleFlyoutOpen &&
|
||||
isAddRuleFlyoutOpen &&
|
||||
triggersActionsUi &&
|
||||
pageState.matches({ initialized: 'validLogsExplorerState' })
|
||||
) {
|
||||
|
@ -141,13 +86,10 @@ export const AlertsPopover = () => {
|
|||
onClose: closeAddRuleFlyout,
|
||||
});
|
||||
}
|
||||
}, [triggersActionsUi, pageState, state.isAddRuleFlyoutOpen]);
|
||||
}, [closeAddRuleFlyout, triggersActionsUi, pageState, isAddRuleFlyoutOpen]);
|
||||
|
||||
const createSLOFlyout = useMemo(() => {
|
||||
if (
|
||||
state.isCreateSLOFlyoutOpen &&
|
||||
pageState.matches({ initialized: 'validLogsExplorerState' })
|
||||
) {
|
||||
if (isCreateSLOFlyoutOpen && pageState.matches({ initialized: 'validLogsExplorerState' })) {
|
||||
const { logsExplorerState } = pageState.context;
|
||||
const dataView = hydrateDataSourceSelection(
|
||||
logsExplorerState.dataSourceSelection
|
||||
|
@ -178,7 +120,7 @@ export const AlertsPopover = () => {
|
|||
onClose: closeCreateSLOFlyout,
|
||||
});
|
||||
}
|
||||
}, [slo, pageState, state.isCreateSLOFlyoutOpen]);
|
||||
}, [isCreateSLOFlyoutOpen, pageState, slo, closeCreateSLOFlyout]);
|
||||
|
||||
// Check whether the user has the necessary permissions to create an SLO
|
||||
const canCreateSLOs = !!application.capabilities[sloFeatureId]?.write;
|
||||
|
@ -252,12 +194,12 @@ export const AlertsPopover = () => {
|
|||
/>
|
||||
</EuiButtonEmpty>
|
||||
}
|
||||
isOpen={state.isPopoverOpen}
|
||||
isOpen={isPopoverOpen}
|
||||
closePopover={closePopover}
|
||||
panelPaddingSize="none"
|
||||
anchorPosition="downLeft"
|
||||
>
|
||||
<EuiContextMenuPanel items={items} />
|
||||
<EuiContextMenuPanel onClick={closePopover} items={items} />
|
||||
</EuiPopover>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
"@kbn/es-query",
|
||||
"@kbn/analytics-client",
|
||||
"@kbn/core-analytics-browser",
|
||||
"@kbn/react-hooks",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
|
|
|
@ -5594,6 +5594,10 @@
|
|||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/react-hooks@link:packages/kbn-react-hooks":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/react-kibana-context-common@link:packages/react/kibana_context/common":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue