Skip to content

Commit

Permalink
Add date picker to Assed Details
Browse files Browse the repository at this point in the history
  • Loading branch information
crespocarlos committed Aug 22, 2023
1 parent 9591264 commit ea4bf91
Show file tree
Hide file tree
Showing 19 changed files with 459 additions and 296 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const ContextProviders = ({
}) => {
const { asset, dateRange, overrides, onTabsStateChange, assetType = 'host', renderMode } = props;
return (
<DateRangeProvider dateRange={dateRange}>
<DateRangeProvider initialDateRange={dateRange}>
<MetadataStateProvider asset={asset} assetType={assetType}>
<AssetDetailsStateProvider
state={{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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 { EuiSuperDatePicker, type OnTimeChangeProps } from '@elastic/eui';
import React, { useCallback } from 'react';
import { useDateRangeProviderContext } from '../hooks/use_date_range';

export const DatePicker = () => {
const { dateRange, setDateRange } = useDateRangeProviderContext();
const onTimeChange = useCallback(
({ start, end, isInvalid }: OnTimeChangeProps) => {
if (!isInvalid) {
setDateRange({ from: start, to: end });
}
},
[setDateRange]
);

return (
<EuiSuperDatePicker
start={dateRange.from}
end={dateRange.to}
onTimeChange={onTimeChange}
updateButtonProps={{ iconOnly: true }}
width="full"
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import createContainer from 'constate';
import type { AssetDetailsProps } from '../types';
import { useDateRangeProviderContext } from './use_date_range';
import { useMetadataStateProviderContext } from './use_metadata_state';

export interface UseAssetDetailsStateProps {
Expand All @@ -19,7 +18,6 @@ export interface UseAssetDetailsStateProps {

export function useAssetDetailsState({ state }: UseAssetDetailsStateProps) {
const { metadata } = useMetadataStateProviderContext();
const { dateRange, dateRangeTs } = useDateRangeProviderContext();
const { asset, assetType, onTabsStateChange, overrides, renderMode } = state;

// When the asset asset.name is known we can load the page faster
Expand All @@ -32,8 +30,6 @@ export function useAssetDetailsState({ state }: UseAssetDetailsStateProps) {
name: asset.name || metadata?.name || 'asset-name',
},
assetType,
dateRange,
dateRangeTs,
onTabsStateChange,
overrides,
renderMode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,38 @@
* 2.0.
*/

import type { TimeRange } from '@kbn/es-query';
import createContainer from 'constate';
import { useMemo } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { parseDateRange } from '../../../utils/datemath';
import type { AssetDetailsProps } from '../types';

import { toTimestampRange } from '../utils';

const DEFAULT_DATE_RANGE = {
const DEFAULT_DATE_RANGE: TimeRange = {
from: 'now-15m',
to: 'now',
};

export type UseAssetDetailsStateProps = Pick<AssetDetailsProps, 'dateRange'>;
export interface UseAssetDetailsStateProps {
initialDateRange: TimeRange;
}

export function useDateRangeProvider({ initialDateRange }: UseAssetDetailsStateProps) {
const [dateRange, setDateRange] = useState(initialDateRange);

export function useDateRangeProvider({ dateRange: rawDateRange }: UseAssetDetailsStateProps) {
const dateRange = useMemo(() => {
const parsedDateRange = useMemo(() => {
const { from = DEFAULT_DATE_RANGE.from, to = DEFAULT_DATE_RANGE.to } =
parseDateRange(rawDateRange);
parseDateRange(dateRange);

return { from, to };
}, [rawDateRange]);
}, [dateRange]);

const dateRangeTs = toTimestampRange(dateRange);
const getDateRangeInTimestamp = useCallback(
() => toTimestampRange(parsedDateRange),
[parsedDateRange]
);

return {
dateRange,
dateRangeTs,
};
return { dateRange, setDateRange, getDateRangeInTimestamp };
}

export const [DateRangeProvider, useDateRangeProviderContext] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useDateRangeProviderContext } from './use_date_range';
export type UseMetadataProviderProps = Pick<AssetDetailsProps, 'asset' | 'assetType'>;

export function useMetadataProvider({ asset, assetType }: UseMetadataProviderProps) {
const { dateRangeTs } = useDateRangeProviderContext();
const { getDateRangeInTimestamp } = useDateRangeProviderContext();
const inventoryModel = findInventoryModel(assetType);
const { sourceId } = useSourceContext();

Expand All @@ -24,7 +24,7 @@ export function useMetadataProvider({ asset, assetType }: UseMetadataProviderPro
assetType,
inventoryModel.requiredMetrics,
sourceId,
dateRangeTs
getDateRangeInTimestamp()
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
import { APM_HOST_FILTER_FIELD } from '../constants';
import { LinkToAlertsRule, LinkToApmServices, LinkToNodeDetails, LinkToUptime } from '../links';
import { FlyoutTabIds, type LinkOptions, type Tab, type TabIds } from '../types';
import { toTimestampRange } from '../utils';
import { useAssetDetailsStateContext } from './use_asset_details_state';
import { useDateRangeProviderContext } from './use_date_range';
import { useTabSwitcherContext } from './use_tab_switcher';
Expand All @@ -31,7 +30,7 @@ export const usePageHeader = (tabs: Tab[], links?: LinkOptions[]) => {
};

const useRightSideItems = (links?: LinkOptions[]) => {
const { dateRange } = useDateRangeProviderContext();
const { getDateRangeInTimestamp } = useDateRangeProviderContext();
const { asset, assetType, overrides } = useAssetDetailsStateContext();
const { metadata } = useMetadataStateProviderContext();

Expand All @@ -41,7 +40,7 @@ const useRightSideItems = (links?: LinkOptions[]) => {
<LinkToNodeDetails
asset={asset}
assetType={assetType}
currentTimestamp={toTimestampRange(dateRange).to}
currentTimestamp={getDateRangeInTimestamp().to}
/>
),
alertRule: <LinkToAlertsRule onClick={overrides?.alertRule?.onCreateRuleClick} />,
Expand All @@ -58,7 +57,13 @@ const useRightSideItems = (links?: LinkOptions[]) => {
/>
),
}),
[asset, assetType, dateRange, metadata?.info?.host?.ip, overrides?.alertRule?.onCreateRuleClick]
[
asset,
assetType,
getDateRangeInTimestamp,
metadata?.info?.host?.ip,
overrides?.alertRule?.onCreateRuleClick,
]
);

const rightSideItems = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,30 @@
* 2.0.
*/

import React from 'react';
import type { TimeRange } from '@kbn/es-query';
import React, { useCallback } from 'react';
import { AnomaliesTable } from '../../../../pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/anomalies_table';
import { useAssetDetailsStateContext } from '../../hooks/use_asset_details_state';
import { useDateRangeProviderContext } from '../../hooks/use_date_range';

export const Anomalies = () => {
const { dateRange, setDateRange } = useDateRangeProviderContext();
const { asset, overrides } = useAssetDetailsStateContext();
const { onClose = () => {} } = overrides?.anomalies ?? {};

return <AnomaliesTable closeFlyout={onClose} hostName={asset.name} />;
const handleDateRangeChange = useCallback(
(newDateRange: TimeRange) => {
setDateRange(newDateRange);
},
[setDateRange]
);

return (
<AnomaliesTable
closeFlyout={onClose}
hostName={asset.name}
dateRange={dateRange}
onDateRangeChange={handleDateRangeChange}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@ import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elas
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
import { LogStream } from '@kbn/logs-shared-plugin/public';
import { DEFAULT_LOG_VIEW, LogViewReference } from '@kbn/logs-shared-plugin/common';

import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import { findInventoryFields } from '../../../../../common/inventory_models';
import { InfraLoadingPanel } from '../../../loading';
import { useAssetDetailsStateContext } from '../../hooks/use_asset_details_state';
import { useDataViewsProviderContext } from '../../hooks/use_data_views';
import { useDateRangeProviderContext } from '../../hooks/use_date_range';
import { DatePicker } from '../../date_picker/date_picker';

const TEXT_QUERY_THROTTLE_INTERVAL_MS = 500;

export const Logs = () => {
const { asset, assetType, overrides, onTabsStateChange, dateRangeTs } =
useAssetDetailsStateContext();
const { getDateRangeInTimestamp } = useDateRangeProviderContext();
const { asset, assetType, overrides, onTabsStateChange } = useAssetDetailsStateContext();
const { logs } = useDataViewsProviderContext();

const { query: overrideQuery } = overrides?.logs ?? {};
Expand All @@ -35,7 +36,7 @@ export const Logs = () => {
const [textQuery, setTextQuery] = useState(overrideQuery ?? '');
const [textQueryDebounced, setTextQueryDebounced] = useState(overrideQuery ?? '');

const currentTimestamp = dateRangeTs.to;
const currentTimestamp = getDateRangeInTimestamp().to;
const startTimestamp = currentTimestamp - 60 * 60 * 1000; // 60 minutes

useDebounce(
Expand Down Expand Up @@ -89,6 +90,9 @@ export const Logs = () => {

return (
<EuiFlexGroup direction="column" data-test-subj="infraAssetDetailsLogsTabContent">
<EuiFlexItem grow={false}>
<DatePicker />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="m" alignItems="center" responsive={false}>
<EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ import React, { useCallback, useMemo } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiCallOut, EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiFlexGroup } from '@elastic/eui';
import { EuiFlexItem } from '@elastic/eui';
import { Table } from './table';
import { getAllFields } from './utils';
import { useMetadataStateProviderContext } from '../../hooks/use_metadata_state';
import { useAssetDetailsStateContext } from '../../hooks/use_asset_details_state';
import { DatePicker } from '../../date_picker/date_picker';

export interface MetadataSearchUrlState {
metadataSearchUrlState: string;
Expand Down Expand Up @@ -70,13 +73,20 @@ export const Metadata = () => {
}

return (
<Table
search={query}
onSearchChange={onSearchChange}
showActionsColumn={showActionsColumn}
rows={fields}
loading={metadataLoading}
/>
<EuiFlexGroup direction="column">
<EuiFlexItem grow={false}>
<DatePicker />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<Table
search={query}
onSearchChange={onSearchChange}
showActionsColumn={showActionsColumn}
rows={fields}
loading={metadataLoading}
/>
</EuiFlexItem>
</EuiFlexGroup>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { EuiFlexGrid, EuiFlexItem, EuiTitle, EuiSpacer, EuiFlexGroup } from '@el
import type { DataView } from '@kbn/data-views-plugin/public';
import type { TimeRange } from '@kbn/es-query';
import { FormattedMessage } from '@kbn/i18n-react';
import { LensEmbeddableInput } from '@kbn/lens-plugin/public';
import {
assetDetailsDashboards,
XY_MISSING_VALUE_DOTTED_LINE_CONFIG,
Expand All @@ -18,6 +19,7 @@ import { buildCombinedHostsFilter } from '../../../../../utils/filters/build';
import { LensChart, HostMetricsExplanationContent } from '../../../../lens';
import { METRIC_CHART_HEIGHT } from '../../../constants';
import { Popover } from '../../common/popover';
import { useDateRangeProviderContext } from '../../../hooks/use_date_range';

type DataViewOrigin = 'logs' | 'metrics';

Expand All @@ -30,6 +32,7 @@ interface Props {

export const MetricsGrid = React.memo(
({ nodeName, metricsDataView, logsDataView, timeRange }: Props) => {
const { setDateRange } = useDateRangeProviderContext();
const getDataView = useCallback(
(dataViewOrigin: DataViewOrigin) => {
return dataViewOrigin === 'metrics' ? metricsDataView : logsDataView;
Expand All @@ -50,6 +53,21 @@ export const MetricsGrid = React.memo(
[getDataView, nodeName]
);

const handleBrushEnd = useCallback(
({
range,
preventDefault,
}: Parameters<NonNullable<LensEmbeddableInput['onBrushEnd']>>[0]) => {
setDateRange({
from: new Date(range[0]).toISOString(),
to: new Date(range[1]).toISOString(),
});

preventDefault();
},
[setDateRange]
);

return (
<EuiFlexGroup gutterSize="m" direction="column">
<EuiFlexItem grow={false}>
Expand Down Expand Up @@ -77,7 +95,7 @@ export const MetricsGrid = React.memo(
title={title}
overrides={overrides}
visualizationType="lnsXY"
disableTriggers
onBrushEnd={handleBrushEnd}
/>
</EuiFlexItem>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ import { MetricsGrid } from './metrics/metrics_grid';
import { useAssetDetailsStateContext } from '../../hooks/use_asset_details_state';
import { useMetadataStateProviderContext } from '../../hooks/use_metadata_state';
import { useDataViewsProviderContext } from '../../hooks/use_data_views';
import { useDateRangeProviderContext } from '../../hooks/use_date_range';
import { DatePicker } from '../../date_picker/date_picker';

export const Overview = () => {
const { asset, assetType, dateRange, renderMode } = useAssetDetailsStateContext();
const { dateRange } = useDateRangeProviderContext();
const { asset, assetType, renderMode } = useAssetDetailsStateContext();
const {
metadata,
loading: metadataLoading,
Expand All @@ -29,6 +32,9 @@ export const Overview = () => {

return (
<EuiFlexGroup direction="column" gutterSize="m">
<EuiFlexItem grow={false}>
<DatePicker />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<KPIGrid nodeName={asset.name} timeRange={dateRange} dataView={metrics.dataView} />
</EuiFlexItem>
Expand Down
Loading

0 comments on commit ea4bf91

Please sign in to comment.