[ML] Explain Log Rate Spikes: Fix analysis table row pinning. (#141455)

- Fixes styling of hovered and pinned rows to use EUI provided variables.
- The above was also done for the Log Pattern Analysis page to fix an issue with dark theme.
- Fixes unpinning a row for field/value pairs.
- Fixes pinning/unpinning for groups.
This commit is contained in:
Walter Rafelsberger 2022-09-26 10:30:03 +02:00 committed by GitHub
parent f576b1f467
commit 8937be2db4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 250 additions and 106 deletions

View file

@ -120,7 +120,7 @@ export const DocumentCountChart: FC<DocumentCountChartProps> = ({
const overallSeriesNameWithSplit = i18n.translate(
'xpack.aiops.dataGrid.field.documentCountChartSplit.seriesLabel',
{
defaultMessage: 'other document count',
defaultMessage: 'Other document count',
}
);

View file

@ -5,13 +5,12 @@
* 2.0.
*/
import React, { useEffect, useState, FC, useMemo } from 'react';
import React, { useEffect, useState, FC } from 'react';
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import type { WindowParameters } from '@kbn/aiops-utils';
import type { ChangePoint } from '@kbn/ml-agg-utils';
import { DocumentCountChart, DocumentCountChartPoint } from '../document_count_chart';
import { TotalCountHeader } from '../total_count_header';
@ -27,9 +26,9 @@ const clearSelectionLabel = i18n.translate(
export interface DocumentCountContentProps {
brushSelectionUpdateHandler: (d: WindowParameters) => void;
clearSelectionHandler: () => void;
changePoint?: ChangePoint;
documentCountStats?: DocumentCountStats;
documentCountStatsSplit?: DocumentCountStats;
documentCountStatsSplitLabel?: string;
totalCount: number;
windowParameters?: WindowParameters;
}
@ -37,9 +36,9 @@ export interface DocumentCountContentProps {
export const DocumentCountContent: FC<DocumentCountContentProps> = ({
brushSelectionUpdateHandler,
clearSelectionHandler,
changePoint,
documentCountStats,
documentCountStatsSplit,
documentCountStatsSplitLabel = '',
totalCount,
windowParameters,
}) => {
@ -52,10 +51,6 @@ export const DocumentCountContent: FC<DocumentCountContentProps> = ({
const bucketTimestamps = Object.keys(documentCountStats?.buckets ?? {}).map((time) => +time);
const timeRangeEarliest = Math.min(...bucketTimestamps);
const timeRangeLatest = Math.max(...bucketTimestamps);
const chartPointsSplitLabel = useMemo(
() => `${changePoint?.fieldName}:${changePoint?.fieldValue}`,
[changePoint]
);
if (
documentCountStats === undefined ||
@ -121,7 +116,7 @@ export const DocumentCountContent: FC<DocumentCountContentProps> = ({
timeRangeEarliest={timeRangeEarliest}
timeRangeLatest={timeRangeLatest}
interval={documentCountStats.interval}
chartPointsSplitLabel={chartPointsSplitLabel}
chartPointsSplitLabel={documentCountStatsSplitLabel}
isBrushCleared={isBrushCleared}
/>
)}

View file

@ -23,7 +23,6 @@ import { useFetchStream } from '@kbn/aiops-utils';
import type { WindowParameters } from '@kbn/aiops-utils';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import type { ChangePoint } from '@kbn/ml-agg-utils';
import type { Query } from '@kbn/es-query';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
@ -32,7 +31,7 @@ import type { ApiExplainLogRateSpikes } from '../../../common/api';
import { SpikeAnalysisGroupsTable } from '../spike_analysis_table';
import { SpikeAnalysisTable } from '../spike_analysis_table';
import { GroupTableItem } from '../spike_analysis_table/spike_analysis_table_groups';
import { useSpikeAnalysisTableRowContext } from '../spike_analysis_table/spike_analysis_table_row_provider';
const groupResultsMessage = i18n.translate(
'xpack.aiops.spikeAnalysisTable.groupedSwitchLabel.groupResults',
@ -54,10 +53,6 @@ interface ExplainLogRateSpikesAnalysisProps {
/** Window parameters for the analysis */
windowParameters: WindowParameters;
searchQuery: Query['query'];
onPinnedChangePoint?: (changePoint: ChangePoint | null) => void;
onSelectedChangePoint?: (changePoint: ChangePoint | null) => void;
selectedChangePoint?: ChangePoint;
onSelectedGroup?: (group: GroupTableItem | null) => void;
}
export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps> = ({
@ -66,14 +61,12 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
latest,
windowParameters,
searchQuery,
onPinnedChangePoint,
onSelectedChangePoint,
selectedChangePoint,
onSelectedGroup,
}) => {
const { http } = useAiopsAppContext();
const basePath = http.basePath.get() ?? '';
const { clearAllRowState } = useSpikeAnalysisTableRowContext();
const [currentAnalysisWindowParameters, setCurrentAnalysisWindowParameters] = useState<
WindowParameters | undefined
>();
@ -81,6 +74,9 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
const onSwitchToggle = (e: { target: { checked: React.SetStateAction<boolean> } }) => {
setGroupResults(e.target.checked);
// When toggling the group switch, clear all row selections
clearAllRowState();
};
const {
@ -109,15 +105,9 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
// Start handler clears possibly hovered or pinned
// change points on analysis refresh.
function startHandler() {
// Reset grouping to false when restarting the analysis.
// Reset grouping to false and clear all row selections when restarting the analysis.
setGroupResults(false);
if (onPinnedChangePoint) {
onPinnedChangePoint(null);
}
if (onSelectedChangePoint) {
onSelectedChangePoint(null);
}
clearAllRowState();
setCurrentAnalysisWindowParameters(windowParameters);
start();
@ -249,10 +239,6 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
changePoints={data.changePoints}
groupTableItems={groupTableItems}
loading={isRunning}
onPinnedChangePoint={onPinnedChangePoint}
onSelectedChangePoint={onSelectedChangePoint}
selectedChangePoint={selectedChangePoint}
onSelectedGroup={onSelectedGroup}
dataViewId={dataView.id}
/>
) : null}
@ -260,9 +246,6 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
<SpikeAnalysisTable
changePoints={data.changePoints}
loading={isRunning}
onPinnedChangePoint={onPinnedChangePoint}
onSelectedChangePoint={onSelectedChangePoint}
selectedChangePoint={selectedChangePoint}
dataViewId={dataView.id}
/>
) : null}

View file

@ -36,6 +36,8 @@ import {
import type { AiopsAppDependencies } from '../../hooks/use_aiops_app_context';
import { AiopsAppContext } from '../../hooks/use_aiops_app_context';
import { SpikeAnalysisTableRowStateProvider } from '../spike_analysis_table/spike_analysis_table_row_provider';
import { ExplainLogRateSpikesPage } from './explain_log_rate_spikes_page';
export interface ExplainLogRateSpikesAppStateProps {
@ -164,7 +166,9 @@ export const ExplainLogRateSpikesAppState: FC<ExplainLogRateSpikesAppStateProps>
return (
<AiopsAppContext.Provider value={appDependencies}>
<UrlStateContextProvider value={{ searchString: urlSearchString, setUrlState }}>
<ExplainLogRateSpikesPage dataView={dataView} savedSearch={savedSearch} />
<SpikeAnalysisTableRowStateProvider>
<ExplainLogRateSpikesPage dataView={dataView} savedSearch={savedSearch} />
</SpikeAnalysisTableRowStateProvider>
</UrlStateContextProvider>
</AiopsAppContext.Provider>
);

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import React, { useCallback, useEffect, useMemo, useState, FC } from 'react';
import React, { useCallback, useEffect, useState, FC } from 'react';
import {
EuiEmptyPrompt,
EuiFlexGroup,
@ -19,6 +19,7 @@ import {
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import type { DataView } from '@kbn/data-views-plugin/public';
import type { WindowParameters } from '@kbn/aiops-utils';
import type { ChangePoint } from '@kbn/ml-agg-utils';
@ -38,10 +39,21 @@ import { SearchPanel } from '../search_panel';
import { restorableDefaults } from './explain_log_rate_spikes_app_state';
import { ExplainLogRateSpikesAnalysis } from './explain_log_rate_spikes_analysis';
import type { GroupTableItem } from '../spike_analysis_table/spike_analysis_table_groups';
import { useSpikeAnalysisTableRowContext } from '../spike_analysis_table/spike_analysis_table_row_provider';
// TODO port to `@emotion/react` once `useEuiBreakpoint` is available https://github.com/elastic/eui/pull/6057
import './explain_log_rate_spikes_page.scss';
function getDocumentCountStatsSplitLabel(changePoint?: ChangePoint, group?: GroupTableItem) {
if (changePoint) {
return `${changePoint?.fieldName}:${changePoint?.fieldValue}`;
} else if (group) {
return i18n.translate('xpack.aiops.spikeAnalysisPage.documentCountStatsSplitGroupLabel', {
defaultMessage: 'Selected group',
});
}
}
/**
* ExplainLogRateSpikes props require a data view.
*/
@ -58,6 +70,15 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
}) => {
const { data: dataService } = useAiopsAppContext();
const {
currentSelectedChangePoint,
currentSelectedGroup,
setPinnedChangePoint,
setPinnedGroup,
setSelectedChangePoint,
setSelectedGroup,
} = useSpikeAnalysisTableRowContext();
const [aiopsListState, setAiopsListState] = usePageUrlState(AppStateKey, restorableDefaults);
const [globalState, setGlobalState] = useUrlState('_g');
@ -93,19 +114,6 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
[currentSavedSearch, aiopsListState, setAiopsListState]
);
const [pinnedChangePoint, setPinnedChangePoint] = useState<ChangePoint | null>(null);
const [selectedChangePoint, setSelectedChangePoint] = useState<ChangePoint | null>(null);
const [selectedGroup, setSelectedGroup] = useState<GroupTableItem | null>(null);
// If a row is pinned, still overrule with a potentially hovered row.
const currentSelectedChangePoint = useMemo(() => {
if (selectedChangePoint) {
return selectedChangePoint;
} else if (pinnedChangePoint) {
return pinnedChangePoint;
}
}, [pinnedChangePoint, selectedChangePoint]);
const {
documentStats,
timefilter,
@ -119,8 +127,7 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
aiopsListState,
setGlobalState,
currentSelectedChangePoint,
undefined,
selectedGroup
currentSelectedGroup
);
const { totalCount, documentCountStats, documentCountStatsCompare } = documentStats;
@ -170,6 +177,7 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
function clearSelection() {
setWindowParameters(undefined);
setPinnedChangePoint(null);
setPinnedGroup(null);
setSelectedChangePoint(null);
setSelectedGroup(null);
}
@ -230,12 +238,15 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
clearSelectionHandler={clearSelection}
documentCountStats={documentCountStats}
documentCountStatsSplit={
currentSelectedChangePoint || selectedGroup
currentSelectedChangePoint || currentSelectedGroup
? documentCountStatsCompare
: undefined
}
documentCountStatsSplitLabel={getDocumentCountStatsSplitLabel(
currentSelectedChangePoint,
currentSelectedGroup
)}
totalCount={totalCount}
changePoint={currentSelectedChangePoint}
windowParameters={windowParameters}
/>
</EuiPanel>
@ -250,10 +261,6 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
latest={latest}
windowParameters={windowParameters}
searchQuery={searchQuery}
onPinnedChangePoint={setPinnedChangePoint}
onSelectedChangePoint={setSelectedChangePoint}
selectedChangePoint={currentSelectedChangePoint}
onSelectedGroup={setSelectedGroup}
/>
)}
{windowParameters === undefined && (

View file

@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import type { TimefilterContract } from '@kbn/data-plugin/public';
import {
useEuiBackgroundColor,
EuiButton,
EuiSpacer,
EuiFlexGroup,
@ -62,6 +63,7 @@ export const CategoryTable: FC<Props> = ({
setSelectedCategory,
}) => {
const euiTheme = useEuiTheme();
const primaryBackgroundColor = useEuiBackgroundColor('primary');
const { openInDiscoverWithFilter } = useDiscoverLinks();
const [selectedCategories, setSelectedCategories] = useState<Category[]>([]);
const { onTableChange, pagination, sorting } = useTableState<Category>(categories ?? [], 'key');
@ -193,22 +195,18 @@ export const CategoryTable: FC<Props> = ({
pinnedCategory.key === category.key
) {
return {
backgroundColor: 'rgb(227,240,249,0.37)',
backgroundColor: primaryBackgroundColor,
};
}
if (
selectedCategory &&
selectedCategory.key === category.key &&
selectedCategory.key === category.key
) {
if (selectedCategory && selectedCategory.key === category.key) {
return {
backgroundColor: euiTheme.euiColorLightestShade,
};
}
return {
backgroundColor: 'white',
backgroundColor: euiTheme.euiColorEmptyShade,
};
};

View file

@ -116,6 +116,7 @@ export const LogCategorizationPage: FC<LogCategorizationPageProps> = ({
aiopsListState,
setGlobalState,
undefined,
undefined,
BAR_TARGET
);

View file

@ -9,6 +9,7 @@ import React, { FC, useCallback, useMemo, useState } from 'react';
import { sortBy } from 'lodash';
import {
useEuiBackgroundColor,
EuiBadge,
EuiBasicTable,
EuiBasicTableColumn,
@ -29,6 +30,7 @@ import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
import { MiniHistogram } from '../mini_histogram';
import { getFailedTransactionsCorrelationImpactLabel } from './get_failed_transactions_correlation_impact_label';
import { useSpikeAnalysisTableRowContext } from './spike_analysis_table_row_provider';
const NARROW_COLUMN_WIDTH = '120px';
const ACTIONS_COLUMN_WIDTH = '60px';
@ -48,20 +50,18 @@ interface SpikeAnalysisTableProps {
changePoints: ChangePoint[];
dataViewId?: string;
loading: boolean;
onPinnedChangePoint?: (changePoint: ChangePoint | null) => void;
onSelectedChangePoint?: (changePoint: ChangePoint | null) => void;
selectedChangePoint?: ChangePoint;
}
export const SpikeAnalysisTable: FC<SpikeAnalysisTableProps> = ({
changePoints,
dataViewId,
loading,
onPinnedChangePoint,
onSelectedChangePoint,
selectedChangePoint,
}) => {
const euiTheme = useEuiTheme();
const primaryBackgroundColor = useEuiBackgroundColor('primary');
const { pinnedChangePoint, selectedChangePoint, setPinnedChangePoint, setSelectedChangePoint } =
useSpikeAnalysisTableRowContext();
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
@ -318,6 +318,32 @@ export const SpikeAnalysisTable: FC<SpikeAnalysisTableProps> = ({
};
}, [pageIndex, pageSize, sortField, sortDirection, changePoints]);
const getRowStyle = (changePoint: ChangePoint) => {
if (
pinnedChangePoint &&
pinnedChangePoint.fieldName === changePoint.fieldName &&
pinnedChangePoint.fieldValue === changePoint.fieldValue
) {
return {
backgroundColor: primaryBackgroundColor,
};
}
if (
selectedChangePoint &&
selectedChangePoint.fieldName === changePoint.fieldName &&
selectedChangePoint.fieldValue === changePoint.fieldValue
) {
return {
backgroundColor: euiTheme.euiColorLightestShade,
};
}
return {
backgroundColor: euiTheme.euiColorEmptyShade,
};
};
// Don't pass on the `loading` state to the table itself because
// it disables hovering events. Because the mini histograms take a while
// to load, hovering would not update the main chart. Instead,
@ -339,28 +365,22 @@ export const SpikeAnalysisTable: FC<SpikeAnalysisTableProps> = ({
return {
'data-test-subj': `aiopsSpikeAnalysisTableRow row-${changePoint.fieldName}-${changePoint.fieldValue}`,
onClick: () => {
if (onPinnedChangePoint) {
onPinnedChangePoint(changePoint);
if (
changePoint.fieldName === pinnedChangePoint?.fieldName &&
changePoint.fieldValue === pinnedChangePoint?.fieldValue
) {
setPinnedChangePoint(null);
} else {
setPinnedChangePoint(changePoint);
}
},
onMouseEnter: () => {
if (onSelectedChangePoint) {
onSelectedChangePoint(changePoint);
}
setSelectedChangePoint(changePoint);
},
onMouseLeave: () => {
if (onSelectedChangePoint) {
onSelectedChangePoint(null);
}
setSelectedChangePoint(null);
},
style:
selectedChangePoint &&
selectedChangePoint.fieldValue === changePoint.fieldValue &&
selectedChangePoint.fieldName === changePoint.fieldName
? {
backgroundColor: euiTheme.euiColorLightestShade,
}
: null,
style: getRowStyle(changePoint),
};
}}
/>

View file

@ -9,6 +9,7 @@ import React, { FC, useCallback, useMemo, useState } from 'react';
import { sortBy } from 'lodash';
import {
useEuiBackgroundColor,
EuiBadge,
EuiBasicTable,
EuiBasicTableColumn,
@ -34,6 +35,7 @@ import { MiniHistogram } from '../mini_histogram';
import { getFailedTransactionsCorrelationImpactLabel } from './get_failed_transactions_correlation_impact_label';
import { SpikeAnalysisTable } from './spike_analysis_table';
import { useSpikeAnalysisTableRowContext } from './spike_analysis_table_row_provider';
const NARROW_COLUMN_WIDTH = '120px';
const EXPAND_COLUMN_WIDTH = '40px';
@ -64,10 +66,6 @@ interface SpikeAnalysisTableProps {
groupTableItems: GroupTableItem[];
dataViewId?: string;
loading: boolean;
onPinnedChangePoint?: (changePoint: ChangePoint | null) => void;
onSelectedChangePoint?: (changePoint: ChangePoint | null) => void;
selectedChangePoint?: ChangePoint;
onSelectedGroup?: (group: GroupTableItem | null) => void;
}
export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
@ -75,10 +73,6 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
groupTableItems,
dataViewId,
loading,
onPinnedChangePoint,
onSelectedChangePoint,
selectedChangePoint,
onSelectedGroup,
}) => {
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
@ -89,6 +83,10 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
);
const euiTheme = useEuiTheme();
const primaryBackgroundColor = useEuiBackgroundColor('primary');
const { pinnedGroup, selectedGroup, setPinnedGroup, setSelectedGroup } =
useSpikeAnalysisTableRowContext();
const toggleDetails = (item: GroupTableItem) => {
const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap };
@ -121,9 +119,6 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
<SpikeAnalysisTable
changePoints={expandedTableItems as ChangePoint[]}
loading={loading}
onPinnedChangePoint={onPinnedChangePoint}
onSelectedChangePoint={onSelectedChangePoint}
selectedChangePoint={selectedChangePoint}
dataViewId={dataViewId}
/>
);
@ -458,6 +453,24 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
};
}, [pageIndex, pageSize, sortField, sortDirection, groupTableItems]);
const getRowStyle = (group: GroupTableItem) => {
if (pinnedGroup && pinnedGroup.id === group.id) {
return {
backgroundColor: primaryBackgroundColor,
};
}
if (selectedGroup && selectedGroup.id === group.id) {
return {
backgroundColor: euiTheme.euiColorLightestShade,
};
}
return {
backgroundColor: euiTheme.euiColorEmptyShade,
};
};
return (
<EuiBasicTable
data-test-subj="aiopsSpikeAnalysisGroupsTable"
@ -473,16 +486,20 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
rowProps={(group) => {
return {
'data-test-subj': `aiopsSpikeAnalysisGroupsTableRow row-${group.id}`,
onMouseEnter: () => {
if (onSelectedGroup) {
onSelectedGroup(group);
onClick: () => {
if (group.id === pinnedGroup?.id) {
setPinnedGroup(null);
} else {
setPinnedGroup(group);
}
},
onMouseEnter: () => {
setSelectedGroup(group);
},
onMouseLeave: () => {
if (onSelectedGroup) {
onSelectedGroup(null);
}
setSelectedGroup(null);
},
style: getRowStyle(group),
};
}}
/>

View file

@ -0,0 +1,118 @@
/*
* 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, {
createContext,
useContext,
useMemo,
useState,
type FC,
type Dispatch,
type SetStateAction,
} from 'react';
import type { ChangePoint } from '@kbn/ml-agg-utils';
import type { GroupTableItem } from './spike_analysis_table_groups';
type ChangePointOrNull = ChangePoint | null;
type GroupOrNull = GroupTableItem | null;
interface SpikeAnalysisTableRow {
pinnedChangePoint: ChangePointOrNull;
setPinnedChangePoint: Dispatch<SetStateAction<ChangePointOrNull>>;
pinnedGroup: GroupOrNull;
setPinnedGroup: Dispatch<SetStateAction<GroupOrNull>>;
selectedChangePoint: ChangePointOrNull;
setSelectedChangePoint: Dispatch<SetStateAction<ChangePointOrNull>>;
selectedGroup: GroupOrNull;
setSelectedGroup: Dispatch<SetStateAction<GroupOrNull>>;
currentSelectedChangePoint?: ChangePoint;
currentSelectedGroup?: GroupTableItem;
clearAllRowState: () => void;
}
export const spikeAnalysisTableRowContext = createContext<SpikeAnalysisTableRow | undefined>(
undefined
);
export const SpikeAnalysisTableRowStateProvider: FC = ({ children }) => {
// State that will be shared with all components
const [pinnedChangePoint, setPinnedChangePoint] = useState<ChangePointOrNull>(null);
const [pinnedGroup, setPinnedGroup] = useState<GroupOrNull>(null);
const [selectedChangePoint, setSelectedChangePoint] = useState<ChangePointOrNull>(null);
const [selectedGroup, setSelectedGroup] = useState<GroupOrNull>(null);
// If a row is pinned, still overrule with a potentially hovered row.
const currentSelectedChangePoint = useMemo(() => {
if (selectedChangePoint) {
return selectedChangePoint;
} else if (pinnedChangePoint) {
return pinnedChangePoint;
}
}, [pinnedChangePoint, selectedChangePoint]);
// If a group is pinned, still overrule with a potentially hovered group.
const currentSelectedGroup = useMemo(() => {
if (selectedGroup) {
return selectedGroup;
} else if (pinnedGroup) {
return pinnedGroup;
}
}, [selectedGroup, pinnedGroup]);
const contextValue: SpikeAnalysisTableRow = useMemo(
() => ({
pinnedChangePoint,
setPinnedChangePoint,
pinnedGroup,
setPinnedGroup,
selectedChangePoint,
setSelectedChangePoint,
selectedGroup,
setSelectedGroup,
currentSelectedChangePoint,
currentSelectedGroup,
clearAllRowState: () => {
setPinnedChangePoint(null);
setPinnedGroup(null);
setSelectedChangePoint(null);
setSelectedGroup(null);
},
}),
[
pinnedChangePoint,
setPinnedChangePoint,
pinnedGroup,
setPinnedGroup,
selectedChangePoint,
setSelectedChangePoint,
selectedGroup,
setSelectedGroup,
currentSelectedChangePoint,
currentSelectedGroup,
]
);
return (
// Provider managing the state
<spikeAnalysisTableRowContext.Provider value={contextValue}>
{children}
</spikeAnalysisTableRowContext.Provider>
);
};
export const useSpikeAnalysisTableRowContext = () => {
const spikeAnalysisTableRow = useContext(spikeAnalysisTableRowContext);
// If `undefined`, throw an error.
if (spikeAnalysisTableRow === undefined) {
throw new Error('useSpikeAnalysisTableRowContext was used outside of its Provider');
}
return spikeAnalysisTableRow;
};

View file

@ -40,8 +40,8 @@ export const useData = (
aiopsListState: AiOpsIndexBasedAppState,
onUpdate: (params: Dictionary<unknown>) => void,
selectedChangePoint?: ChangePoint,
barTarget: number = DEFAULT_BAR_TARGET,
selectedGroup?: GroupTableItem | null
selectedGroup?: GroupTableItem | null,
barTarget: number = DEFAULT_BAR_TARGET
) => {
const {
uiSettings,
@ -49,6 +49,7 @@ export const useData = (
query: { filterManager },
},
} = useAiopsAppContext();
const [lastRefresh, setLastRefresh] = useState(0);
const [fieldStatsRequest, setFieldStatsRequest] = useState<
DocumentStatsSearchStrategyParams | undefined