[ML] Fix swim lane time selection with a single time point and the Watcher URL (#89125)
* [ML] fix swim lane selected times with only start boundaries * [ML] unit test * [ML] update url variables * [ML] selectedLanes to an array type * [ML] handle legacy query params
This commit is contained in:
parent
110e880fbf
commit
b35a4e645d
|
@ -93,7 +93,18 @@ export interface ExplorerAppState {
|
|||
mlExplorerSwimlane: {
|
||||
selectedType?: 'overall' | 'viewBy';
|
||||
selectedLanes?: string[];
|
||||
selectedTimes?: [number, number];
|
||||
/**
|
||||
* @deprecated legacy query param variable, use `selectedLanes`
|
||||
*/
|
||||
selectedLane?: string[] | string;
|
||||
/**
|
||||
* It's possible to have only "from" time boundaries, e.g. in the Watcher URL
|
||||
*/
|
||||
selectedTimes?: [number, number] | number;
|
||||
/**
|
||||
* @deprecated legacy query param variable, use `selectedTimes`
|
||||
*/
|
||||
selectedTime?: [number, number] | number;
|
||||
showTopFieldValues?: boolean;
|
||||
viewByFieldName?: string;
|
||||
viewByPerPage?: number;
|
||||
|
|
|
@ -130,4 +130,38 @@ describe('useSelectedCells', () => {
|
|||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('should extend single time point selection with a bucket interval value', () => {
|
||||
(useTimefilter() as jest.Mocked<TimefilterContract>).getBounds.mockReturnValue({
|
||||
min: moment(1498824778 * 1000),
|
||||
max: moment(1502366798 * 1000),
|
||||
});
|
||||
|
||||
const urlState = {
|
||||
mlExplorerSwimlane: {
|
||||
selectedType: 'overall',
|
||||
selectedLanes: ['Overall'],
|
||||
selectedTimes: 1498780800,
|
||||
showTopFieldValues: true,
|
||||
viewByFieldName: 'apache2.access.remote_ip',
|
||||
viewByFromPage: 1,
|
||||
viewByPerPage: 10,
|
||||
},
|
||||
mlExplorerFilter: {},
|
||||
} as ExplorerAppState;
|
||||
|
||||
const setUrlState = jest.fn();
|
||||
|
||||
const bucketInterval = 86400;
|
||||
|
||||
const { result } = renderHook(() => useSelectedCells(urlState, setUrlState, bucketInterval));
|
||||
|
||||
expect(result.current[0]).toEqual({
|
||||
lanes: ['Overall'],
|
||||
showTopFieldValues: true,
|
||||
times: [1498780800, 1498867200],
|
||||
type: 'overall',
|
||||
viewByFieldName: 'apache2.access.remote_ip',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,18 +19,33 @@ export const useSelectedCells = (
|
|||
const timeBounds = timeFilter.getBounds();
|
||||
|
||||
// keep swimlane selection, restore selectedCells from AppState
|
||||
const selectedCells = useMemo(() => {
|
||||
return appState?.mlExplorerSwimlane?.selectedType !== undefined
|
||||
? {
|
||||
type: appState.mlExplorerSwimlane.selectedType,
|
||||
lanes: appState.mlExplorerSwimlane.selectedLanes!,
|
||||
times: appState.mlExplorerSwimlane.selectedTimes!,
|
||||
showTopFieldValues: appState.mlExplorerSwimlane.showTopFieldValues,
|
||||
viewByFieldName: appState.mlExplorerSwimlane.viewByFieldName,
|
||||
}
|
||||
: undefined;
|
||||
const selectedCells: AppStateSelectedCells | undefined = useMemo(() => {
|
||||
if (!appState?.mlExplorerSwimlane?.selectedType) {
|
||||
return;
|
||||
}
|
||||
|
||||
let times =
|
||||
appState.mlExplorerSwimlane.selectedTimes ?? appState.mlExplorerSwimlane.selectedTime!;
|
||||
if (typeof times === 'number' && bucketIntervalInSeconds) {
|
||||
times = [times, times + bucketIntervalInSeconds];
|
||||
}
|
||||
|
||||
let lanes =
|
||||
appState.mlExplorerSwimlane.selectedLanes ?? appState.mlExplorerSwimlane.selectedLane!;
|
||||
|
||||
if (typeof lanes === 'string') {
|
||||
lanes = [lanes];
|
||||
}
|
||||
|
||||
return {
|
||||
type: appState.mlExplorerSwimlane.selectedType,
|
||||
lanes,
|
||||
times,
|
||||
showTopFieldValues: appState.mlExplorerSwimlane.showTopFieldValues,
|
||||
viewByFieldName: appState.mlExplorerSwimlane.viewByFieldName,
|
||||
} as AppStateSelectedCells;
|
||||
// TODO fix appState to use memoization
|
||||
}, [JSON.stringify(appState?.mlExplorerSwimlane)]);
|
||||
}, [JSON.stringify(appState?.mlExplorerSwimlane), bucketIntervalInSeconds]);
|
||||
|
||||
const setSelectedCells = useCallback(
|
||||
(swimlaneSelectedCells?: AppStateSelectedCells) => {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<br />
|
||||
<br />
|
||||
|
||||
<a href="<%= serverAddress %>#/explorer/?_g=(ml:(jobIds:!('{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0._source.job_id}}')),time:(from:'{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.start.0}}',mode:absolute,to:'{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.end.0}}'))&_a=(explorer:(mlExplorerSwimlane:(selectedLane:Overall,selectedTime:{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.timestamp_epoch.0}},selectedType:overall)),query:(query_string:(analyze_wildcard:!t,query:'*')))">
|
||||
<a href="<%= serverAddress %>#/explorer/?_g=(ml:(jobIds:!('{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0._source.job_id}}')),time:(from:'{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.start.0}}',mode:absolute,to:'{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.end.0}}'))&_a=(explorer:(mlExplorerSwimlane:(selectedLanes:!(Overall),selectedTimes:{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.timestamp_epoch.0}},selectedType:overall)),query:(query_string:(analyze_wildcard:!t,query:'*')))">
|
||||
<%= openInAnomalyExplorerLinkText %>
|
||||
</a>
|
||||
<br />
|
||||
|
|
Loading…
Reference in a new issue