Skip to content

Commit

Permalink
[Infra] Refactor routes context providers and inventory alert flyout (e…
Browse files Browse the repository at this point in the history
…lastic#177189)

closes [144387](elastic#144387)

## Summary

This PR changes the context Waffle context providers usage, so that they
are only used in the Inventory UI page. Therefore, removes the
`waffleTime`, `waffleOptions` and `waffleFilters` query parameters from
other Infrastructure pages:

Hosts View route example:

**Before**
```
https://edge-oblt.kb.us-west2.gcp.elastic-cloud.com/app/metrics/hosts?
  waffleFilter=(expression:%27%27,kind:kuery)&
  waffleTime=(currentTime:1708347453400,isAutoReloading:!f)&
  waffleOptions=(accountId:%27%27,autoBounds:!t,boundsOverride:(max:1,min:0),customMetrics:!(),customOptions:!(),groupBy:!(),legend:(palette:cool,reverseColors:!f,steps:10),metric:(type:cpu),nodeType:host,region:%27%27,sort:(by:name,direction:desc),source:default,timelineOpen:!f,view:map)&
  _a=(dateRange:(from:now-15m,to:now),filters:!(),limit:500,panelFilters:!(),query:(language:kuery,query:%27%27))&
  controlPanels=(cloud.provider:(explicitInput:(fieldName:cloud.provider,id:cloud.provider,title:%27Cloud%20Provider%27),grow:!f,order:1,type:optionsListControl,width:medium),host.os.name:(explicitInput:(fieldName:host.os.name,id:host.os.name,title:%27Operating%20System%27),grow:!f,order:0,type:optionsListControl,width:medium),service.name:(explicitInput:(fieldName:service.name,id:service.name,title:%27Service%20Name%27),grow:!f,order:2,type:optionsListControl,width:medium))
```


**Now**
```
http://localhost:5601/ftw/app/metrics/hosts?
  _a=(dateRange:(from:now-15m,to:now),filters:!(),limit:100,panelFilters:!(),query:(language:kuery,query:%27%27))&
  controlPanels=(cloud.provider:(explicitInput:(fieldName:cloud.provider,id:cloud.provider,title:%27Cloud%20Provider%27),grow:!f,order:1,type:optionsListControl,width:medium),host.os.name:(explicitInput:(fieldName:host.os.name,id:host.os.name,title:%27Operating%20System%27),grow:!f,order:0,type:optionsListControl,width:medium),service.name:(explicitInput:(fieldName:service.name,id:service.name,title:%27Service%20Name%27),grow:!f,order:2,type:optionsListControl,width:medium))
```

**NOTE**: I had to refactor some alerting components because they were
depending on the `WaffleOptions` context to retrieve some properties
that are only relevant within the Inventory UI context

### How to test

- Start a local Kibana instance
- Navigate to the pages below and confirm that they work. `waffle` query
variables only exist in the Inventory UI
  - Inventory
    - Navigate to Pod details 
    - Create and load Saved Views
    - Create Inventory and Metrics alerts
  - Metrics
    - Create and load Saved Views
    - Create Inventory and Metrics alerts
  - Hosts View
    - Navigate Hosts Details

---------

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
crespocarlos and kibanamachine authored Feb 22, 2024
1 parent bc488fb commit 5a3f0a0
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ interface Props {

export const AlertFlyout = ({ options, nodeType, filter, visible, setVisible }: Props) => {
const { triggersActionsUI } = useContext(TriggerActionsContext);

const { inventoryPrefill } = useAlertPrefillContext();
const { customMetrics = [] } = inventoryPrefill ?? {};
const onCloseFlyout = useCallback(() => setVisible(false), [setVisible]);
const { inventoryPrefill } = useAlertPrefillContext();
const { customMetrics = [], accountId, region } = inventoryPrefill;

const AddAlertFlyout = useMemo(
() =>
triggersActionsUI &&
Expand All @@ -36,10 +36,12 @@ export const AlertFlyout = ({ options, nodeType, filter, visible, setVisible }:
canChangeTrigger: false,
ruleTypeId: METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID,
metadata: {
accountId,
options,
nodeType,
filter,
customMetrics,
region,
},
useRuleProducer: true,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ import { NodeTypeExpression } from './node_type';
const FILTER_TYPING_DEBOUNCE_MS = 500;

export interface AlertContextMeta {
accountId?: string;
region?: string;
options?: Partial<InfraWaffleMapOptions>;
nodeType?: InventoryItemType;
filter?: string;
Expand All @@ -86,6 +88,8 @@ type Props = Omit<
filterQueryText?: string;
sourceId: string;
alertOnNoData?: boolean;
accountId?: string;
region?: string;
},
AlertContextMeta
>,
Expand Down Expand Up @@ -309,6 +313,8 @@ export const Expressions: React.FC<Props> = (props) => {
filterQuery={ruleParams.filterQuery}
nodeType={ruleParams.nodeType}
sourceId={ruleParams.sourceId}
accountId={ruleParams.accountId}
region={ruleParams.region}
data-test-subj="preview-chart"
/>
</ExpressionRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { InventoryMetricConditions } from '../../../../common/alerting/metrics';
import { Color } from '../../../../common/color_palette';
import { MetricsExplorerAggregation, MetricsExplorerRow } from '../../../../common/http_api';
import { useSnapshot } from '../../../pages/metrics/inventory_view/hooks/use_snaphot';
import { useWaffleOptionsContext } from '../../../pages/metrics/inventory_view/hooks/use_waffle_options';
import { createInventoryMetricFormatter } from '../../../pages/metrics/inventory_view/lib/create_inventory_metric_formatter';
import { calculateDomain } from '../../../pages/metrics/metrics_explorer/components/helpers/calculate_domain';
import { getMetricId } from '../../../pages/metrics/metrics_explorer/components/helpers/get_metric_id';
Expand All @@ -37,13 +36,17 @@ interface Props {
filterQuery?: string | symbol;
nodeType: InventoryItemType;
sourceId: string;
accountId?: string;
region?: string;
}

export const ExpressionChart: React.FC<Props> = ({
expression,
filterQuery,
nodeType,
sourceId,
accountId = '',
region = '',
}) => {
const chartTheme = useTimelineChartTheme();
const timerange = useMemo(
Expand All @@ -63,7 +66,6 @@ export const ExpressionChart: React.FC<Props> = ({
type: 'custom' as SnapshotMetricType,
});

const options = useWaffleOptionsContext();
const { loading, nodes } = useSnapshot({
filterQuery,
metrics:
Expand All @@ -74,8 +76,8 @@ export const ExpressionChart: React.FC<Props> = ({
nodeType,
sourceId,
currentTime: 0,
accountId: options.accountId,
region: options.region,
accountId,
region,
timerange,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,23 @@ export const useInventoryAlertPrefill = () => {
const [filterQuery, setFilterQuery] = useState<string | undefined>();
const [metric, setMetric] = useState<SnapshotMetricInput>({ type: 'cpu' });
const [customMetrics, setCustomMetrics] = useState<SnapshotCustomMetricInput[]>([]);
// only shows for AWS when there are regions info
const [region, setRegion] = useState('');
// only shows for AWS when there are accounts info
const [accountId, setAccountId] = useState('');

return {
nodeType,
filterQuery,
metric,
customMetrics,
accountId,
region,
setAccountId,
setNodeType,
setFilterQuery,
setMetric,
setCustomMetrics,
setRegion,
};
};
10 changes: 0 additions & 10 deletions x-pack/plugins/infra/public/apps/metrics_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { InfraPublicConfig } from '../../common/plugin_config_types';
import { LinkToMetricsPage } from '../pages/link_to/link_to_metrics';
import { InfrastructurePage } from '../pages/metrics';
import { InfraClientStartDeps, InfraClientStartExports } from '../types';
import { RedirectWithQueryParams } from '../utils/redirect_with_query_params';
import { CommonInfraProviders, CoreProviders } from './common_providers';
import { prepareMountElement } from './common_styles';
import { SourceProvider } from '../containers/metrics_source';
Expand Down Expand Up @@ -104,15 +103,6 @@ const MetricsApp: React.FC<{
<Router history={history}>
<Routes>
<Route path="/link-to" component={LinkToMetricsPage} />
{uiCapabilities?.infrastructure?.show && (
<RedirectWithQueryParams from="/" exact={true} to="/inventory" />
)}
{uiCapabilities?.infrastructure?.show && (
<RedirectWithQueryParams from="/snapshot" exact={true} to="/inventory" />
)}
{uiCapabilities?.infrastructure?.show && (
<RedirectWithQueryParams from="/metrics-explorer" exact={true} to="/explorer" />
)}
{uiCapabilities?.infrastructure?.show && (
<Route path="/" component={InfrastructurePage} />
)}
Expand Down
146 changes: 73 additions & 73 deletions x-pack/plugins/infra/public/pages/metrics/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ import { SnapshotPage } from './inventory_view';
import { NodeDetail } from './metric_detail';
import { MetricsSettingsPage } from './settings';
import { SourceLoadingPage } from '../../components/source_loading_page';
import { WaffleOptionsProvider } from './inventory_view/hooks/use_waffle_options';
import { WaffleTimeProvider } from './inventory_view/hooks/use_waffle_time';
import { WaffleFiltersProvider } from './inventory_view/hooks/use_waffle_filters';
import { MetricsAlertDropdown } from '../../alerting/common/components/metrics_alert_dropdown';
import { AlertPrefillProvider } from '../../alerting/use_alert_prefill';
import { InfraMLCapabilitiesProvider } from '../../containers/ml/infra_ml_capabilities';
Expand All @@ -44,6 +41,7 @@ import { NotFoundPage } from '../404';
import { ReactQueryProvider } from '../../containers/react_query_provider';
import { usePluginConfig } from '../../containers/plugin_config_context';
import { HostsPage } from './hosts';
import { RedirectWithQueryParams } from '../../utils/redirect_with_query_params';

const ADD_DATA_LABEL = i18n.translate('xpack.infra.metricsHeaderAddDataButtonLabel', {
defaultMessage: 'Add data',
Expand Down Expand Up @@ -75,77 +73,79 @@ export const InfrastructurePage = () => {

return (
<EuiErrorBoundary>
<AlertPrefillProvider>
<WaffleOptionsProvider>
<WaffleTimeProvider>
<WaffleFiltersProvider>
<ReactQueryProvider>
<InfraMLCapabilitiesProvider>
<HelpCenterContent
feedbackLink="https://discuss.elastic.co/c/metrics"
appName={i18n.translate('xpack.infra.header.infrastructureHelpAppName', {
defaultMessage: 'Metrics',
})}
/>
{setHeaderActionMenu && theme$ && (
<HeaderMenuPortal setHeaderActionMenu={setHeaderActionMenu} theme$={theme$}>
<EuiFlexGroup responsive={false} gutterSize="s">
<EuiFlexItem>
<EuiHeaderLinks gutterSize="xs">
<EuiHeaderLink color={'text'} {...settingsLinkProps}>
{settingsTabTitle}
</EuiHeaderLink>
<Route path={'/inventory'} component={AnomalyDetectionFlyout} />
{config.featureFlags.alertsAndRulesDropdownEnabled && (
<MetricsAlertDropdown />
)}
<EuiHeaderLink
href={kibana.services?.application?.getUrlForApp(
'/integrations/browse'
)}
color="primary"
iconType="indexOpen"
>
{ADD_DATA_LABEL}
</EuiHeaderLink>
</EuiHeaderLinks>
</EuiFlexItem>
{ObservabilityAIAssistantActionMenuItem ? (
<EuiFlexItem>
<ObservabilityAIAssistantActionMenuItem />
</EuiFlexItem>
) : null}
</EuiFlexGroup>
</HeaderMenuPortal>
<ReactQueryProvider>
<AlertPrefillProvider>
<InfraMLCapabilitiesProvider>
<HelpCenterContent
feedbackLink="https://discuss.elastic.co/c/metrics"
appName={i18n.translate('xpack.infra.header.infrastructureHelpAppName', {
defaultMessage: 'Metrics',
})}
/>
{setHeaderActionMenu && theme$ && (
<HeaderMenuPortal setHeaderActionMenu={setHeaderActionMenu} theme$={theme$}>
<EuiFlexGroup responsive={false} gutterSize="s">
<EuiFlexItem>
<EuiHeaderLinks gutterSize="xs">
<EuiHeaderLink color={'text'} {...settingsLinkProps}>
{settingsTabTitle}
</EuiHeaderLink>
<Route path={'/inventory'} component={AnomalyDetectionFlyout} />
{config.featureFlags.alertsAndRulesDropdownEnabled && (
<MetricsAlertDropdown />
)}
<EuiHeaderLink
href={kibana.services?.application?.getUrlForApp('/integrations/browse')}
color="primary"
iconType="indexOpen"
>
{ADD_DATA_LABEL}
</EuiHeaderLink>
</EuiHeaderLinks>
</EuiFlexItem>
{ObservabilityAIAssistantActionMenuItem ? (
<EuiFlexItem>
<ObservabilityAIAssistantActionMenuItem />
</EuiFlexItem>
) : null}
</EuiFlexGroup>
</HeaderMenuPortal>
)}

<Routes>
<Route path="/inventory" component={SnapshotPage} />
{config.featureFlags.metricsExplorerEnabled && (
<Route
path="/explorer"
render={() => (
<MetricsExplorerOptionsContainer>
<WithMetricsExplorerOptionsUrlState />
{source?.configuration ? (
<PageContent
configuration={source.configuration}
createDerivedIndexPattern={createDerivedIndexPattern}
/>
) : (
<SourceLoadingPage />
)}
</MetricsExplorerOptionsContainer>
)}
<Routes>
<Route path={'/inventory'} component={SnapshotPage} />
{config.featureFlags.metricsExplorerEnabled && (
<Route path={'/explorer'}>
<MetricsExplorerOptionsContainer>
<WithMetricsExplorerOptionsUrlState />
{source?.configuration ? (
<PageContent
configuration={source.configuration}
createDerivedIndexPattern={createDerivedIndexPattern}
/>
) : (
<SourceLoadingPage />
)}
</MetricsExplorerOptionsContainer>
</Route>
)}
<Route path="/detail/:type/:node" component={NodeDetail} />
{isHostsViewEnabled && <Route path={'/hosts'} component={HostsPage} />}
<Route path={'/settings'} component={MetricsSettingsPage} />
<Route render={() => <NotFoundPage title="Infrastructure" />} />
</Routes>
</InfraMLCapabilitiesProvider>
</ReactQueryProvider>
</WaffleFiltersProvider>
</WaffleTimeProvider>
</WaffleOptionsProvider>
</AlertPrefillProvider>
/>
)}

<Route path="/detail/:type/:node" component={NodeDetail} />
{isHostsViewEnabled && <Route path="/hosts" component={HostsPage} />}
<Route path="/settings" component={MetricsSettingsPage} />

<RedirectWithQueryParams from="/snapshot" exact to="/inventory" />
<RedirectWithQueryParams from="/metrics-explorer" exact to="/explorer" />
<RedirectWithQueryParams from="/" exact to="/inventory" />

<Route render={() => <NotFoundPage title="Infrastructure" />} />
</Routes>
</InfraMLCapabilitiesProvider>
</AlertPrefillProvider>
</ReactQueryProvider>
</EuiErrorBoundary>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jest.mock('react-router-dom', () => ({
let PREFILL_NODETYPE: WaffleOptionsState['nodeType'] | undefined;
let PREFILL_METRIC: WaffleOptionsState['metric'] | undefined;
let PREFILL_CUSTOM_METRICS: WaffleOptionsState['customMetrics'] | undefined;
let PREFILL_ACCOUNT_ID: WaffleOptionsState['accountId'] | undefined;
let PREFILL_REGION: WaffleOptionsState['region'] | undefined;
jest.mock('../../../../alerting/use_alert_prefill', () => ({
useAlertPrefillContext: () => ({
inventoryPrefill: {
Expand All @@ -34,6 +36,12 @@ jest.mock('../../../../alerting/use_alert_prefill', () => ({
setCustomMetrics(customMetrics: WaffleOptionsState['customMetrics']) {
PREFILL_CUSTOM_METRICS = customMetrics;
},
setAccountId(accountId: WaffleOptionsState['accountId']) {
PREFILL_ACCOUNT_ID = accountId;
},
setRegion(region: WaffleOptionsState['region']) {
PREFILL_REGION = region;
},
},
}),
}));
Expand All @@ -45,6 +53,8 @@ describe('useWaffleOptions', () => {
PREFILL_NODETYPE = undefined;
PREFILL_METRIC = undefined;
PREFILL_CUSTOM_METRICS = undefined;
PREFILL_ACCOUNT_ID = undefined;
PREFILL_REGION = undefined;
});

it('should sync the options to the inventory alert preview context', () => {
Expand All @@ -61,6 +71,8 @@ describe('useWaffleOptions', () => {
field: 'hey.system.are.you.good',
},
],
accountId: '123456789012',
region: 'us-east-1',
} as WaffleOptionsState;
act(() => {
result.current.changeNodeType(newOptions.nodeType);
Expand All @@ -77,5 +89,15 @@ describe('useWaffleOptions', () => {
});
rerender();
expect(PREFILL_CUSTOM_METRICS).toEqual(newOptions.customMetrics);
act(() => {
result.current.changeAccount(newOptions.accountId);
});
rerender();
expect(PREFILL_ACCOUNT_ID).toEqual(newOptions.accountId);
act(() => {
result.current.changeRegion(newOptions.region);
});
rerender();
expect(PREFILL_REGION).toEqual(newOptions.region);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,14 @@ export const useWaffleOptions = () => {

const { inventoryPrefill } = useAlertPrefillContext();
useEffect(() => {
const { setNodeType, setMetric, setCustomMetrics } = inventoryPrefill;
const { setNodeType, setMetric, setCustomMetrics, setAccountId, setRegion } = inventoryPrefill;
setNodeType(state.nodeType);
setMetric(state.metric);
setCustomMetrics(state.customMetrics);
// only shows for AWS when there are accounts info
setAccountId(state.accountId);
// only shows for AWS when there are regions info
setRegion(state.region);
}, [state, inventoryPrefill]);

const changeTimelineOpen = useCallback(
Expand Down
Loading

0 comments on commit 5a3f0a0

Please sign in to comment.