Skip to content

Commit

Permalink
feat(slo): Remember last sort, view and group option used (elastic#20…
Browse files Browse the repository at this point in the history
  • Loading branch information
kdelemme authored Jan 2, 2025
1 parent 4ae8b67 commit 750a0f3
Show file tree
Hide file tree
Showing 15 changed files with 74 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@ import { Filter } from '@kbn/es-query';
import React, { useEffect, useState } from 'react';
import { Subject } from 'rxjs';
import { GroupView } from '../../../../pages/slos/components/grouped_slos/group_view';
import { GroupByField } from '../../../../pages/slos/components/slo_list_group_by';
import { SLOView } from '../../../../pages/slos/components/toggle_slo_view';
import { SortField } from '../../../../pages/slos/hooks/use_url_search_state';
import type { ViewType, GroupByField, SortField } from '../../../../pages/slos/types';
import { buildCombinedKqlQuery } from './helpers/build_kql_query';

interface Props {
groupBy: GroupByField;
groups?: string[];
kqlQuery?: string;
view: SLOView;
view: ViewType;
sort?: SortField;
filters?: Filter[];
reloadSubject: Subject<boolean>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { GroupByField } from '../../../../../pages/slos/components/slo_list_group_by';
import type { GroupByField } from '../../../../../pages/slos/types';
import { buildCombinedKqlQuery } from './build_kql_query';

describe('buildCombinedKqlQuery', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { GroupByField } from '../../../../../pages/slos/components/slo_list_group_by';
import type { GroupByField } from '../../../../../pages/slos/types';

interface Props {
kqlQuery: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
DEFAULT_SLO_GROUPS_PAGE_SIZE,
SLO_SUMMARY_DESTINATION_INDEX_PATTERN,
} from '../../common/constants';
import { GroupByField } from '../pages/slos/components/slo_list_group_by';
import type { GroupByField } from '../pages/slos/types';
import { SearchState } from '../pages/slos/hooks/use_url_search_state';
import { useKibana } from './use_kibana';
import { sloKeys } from './query_key_factory';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import {
DEFAULT_SLO_PAGE_SIZE,
SLO_SUMMARY_DESTINATION_INDEX_PATTERN,
} from '../../common/constants';
import { SearchState, SortDirection, SortField } from '../pages/slos/hooks/use_url_search_state';
import { SearchState } from '../pages/slos/hooks/use_url_search_state';
import { useKibana } from './use_kibana';
import { sloKeys } from './query_key_factory';
import { useCreateDataView } from './use_create_data_view';
import { usePluginContext } from './use_plugin_context';
import type { SortDirection, SortField } from '../pages/slos/types';

export interface SLOListParams {
kqlQuery?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import { EuiPanel, EuiSelectableOption, EuiText } from '@elastic/eui';
import { EuiSelectableOptionCheckedType } from '@elastic/eui/src/components/selectable/selectable_option';
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import type { SortField, SearchState } from '../../hooks/use_url_search_state';
import type { SearchState } from '../../hooks/use_url_search_state';
import type { Option } from '../slo_context_menu';
import { ContextMenuItem, SLOContextMenu } from '../slo_context_menu';
import type { SortField } from '../../types';

export interface Props {
onStateChange: (newState: Partial<SearchState>) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,14 @@ import { paths } from '../../../../../common/locators/paths';
import { useFetchSloList } from '../../../../hooks/use_fetch_slo_list';
import { useKibana } from '../../../../hooks/use_kibana';
import { useSloFormattedSLIValue } from '../../hooks/use_slo_summary';
import type { SortDirection, SortField } from '../../hooks/use_url_search_state';
import { SlosView } from '../slos_view';
import { GroupByField } from '../slo_list_group_by';
import { SLOView } from '../toggle_slo_view';
import type { ViewType, GroupByField, SortDirection, SortField } from '../../types';
import { useGroupName } from './hooks/use_group_name';

interface Props {
group: string;
kqlQuery?: string;
view: SLOView;
view: ViewType;
sort?: SortField;
direction?: SortDirection;
groupBy: GroupByField;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,16 @@ import { EuiEmptyPrompt, EuiFlexItem, EuiLoadingSpinner, EuiTablePagination } fr
import { Filter } from '@kbn/es-query';
import React, { useEffect } from 'react';
import { useFetchSloGroups } from '../../../../hooks/use_fetch_slo_groups';
import type { SortDirection } from '../../hooks/use_url_search_state';
import { SortField, useUrlSearchState } from '../../hooks/use_url_search_state';
import { GroupByField } from '../slo_list_group_by';
import { SLOView } from '../toggle_slo_view';
import { useUrlSearchState } from '../../hooks/use_url_search_state';
import type { ViewType, GroupByField, SortDirection, SortField } from '../../types';
import { SloGroupListEmpty } from './group_list_empty';
import { SloGroupListError } from './group_list_error';
import { GroupListView } from './group_list_view';

interface Props {
groupBy: GroupByField;
kqlQuery?: string;
view: SLOView;
view: ViewType;
sort?: SortField;
direction?: SortDirection;
filters?: Filter[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
import { ALL_VALUE, GroupSummary } from '@kbn/slo-schema';
import { assertNever } from '@kbn/std';
import { SLI_OPTIONS } from '../../../../slo_edit/constants';
import { GroupByField } from '../../slo_list_group_by';
import type { GroupByField } from '../../../types';

export function useGroupName(groupBy: GroupByField, group: string, summary?: GroupSummary) {
const groupName = group.toLowerCase();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,8 @@ import { useGetSettings } from '../../slo_settings/hooks/use_get_settings';
import type { SearchState } from '../hooks/use_url_search_state';
import type { Option } from './slo_context_menu';
import { ContextMenuItem, SLOContextMenu } from './slo_context_menu';
import type { GroupByField } from '../types';

export type GroupByField =
| 'ungrouped'
| 'slo.tags'
| 'status'
| 'slo.indicator.type'
| 'slo.instanceId'
| '_index';
export interface Props {
onStateChange: (newState: Partial<SearchState>) => void;
state: SearchState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import { HealthCallout } from './health_callout/health_callout';
import { SloListEmpty } from './slo_list_empty';
import { SloListError } from './slo_list_error';
import { SloListView } from './slo_list_view/slo_list_view';
import { SLOView } from './toggle_slo_view';
import type { ViewType } from '../types';

export interface Props {
sloList: SLOWithSummaryResponse[];
loading: boolean;
error: boolean;
view: SLOView;
view: ViewType;
}

export function SlosView({ sloList, loading, error, view }: Props) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import React from 'react';
import type { SearchState } from '../hooks/use_url_search_state';
import { SLOSortBy } from './common/sort_by_select';
import { SloGroupBy } from './slo_list_group_by';
export type SLOView = 'cardView' | 'listView' | 'compactView';
import type { ViewType } from '../types';

interface Props {
onChangeView: (view: SLOView) => void;
onChangeView: (view: ViewType) => void;
onStateChange: (newState: Partial<SearchState>) => void;
view: SLOView;
view: ViewType;
state: SearchState;
sloList?: FindSLOResponse;
loading: boolean;
Expand Down Expand Up @@ -96,7 +96,7 @@ export function ToggleSLOView({
})}
options={toggleButtonsIcons}
idSelected={view}
onChange={(id) => onChangeView(id as SLOView)}
onChange={(id) => onChangeView(id as ViewType)}
isIconOnly
isDisabled={loading}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import { FindSLOResponse } from '@kbn/slo-schema';
import React from 'react';
import { useUrlSearchState } from '../../hooks/use_url_search_state';
import { SlosView } from '../slos_view';
import { SLOView } from '../toggle_slo_view';
import type { ViewType } from '../../types';

export interface Props {
sloList: FindSLOResponse | undefined;
loading: boolean;
error: boolean;
view: SLOView;
view: ViewType;
}

export function UngroupedView({ sloList, loading, error, view }: Props) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,19 @@
*/

import type { Filter } from '@kbn/es-query';
import { createKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public';
import {
createKbnUrlStateStorage,
createSessionStorageStateStorage,
} from '@kbn/kibana-utils-plugin/public';
import deepmerge from 'deepmerge';
import { pick } from 'lodash';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { DEFAULT_SLO_PAGE_SIZE } from '../../../../common/constants';
import type { GroupByField } from '../components/slo_list_group_by';
import type { SLOView } from '../components/toggle_slo_view';
import type { GroupByField, SortDirection, SortField, ViewType } from '../types';

export const SLO_LIST_SEARCH_URL_STORAGE_KEY = 'search';
export type SortField =
| 'sli_value'
| 'error_budget_consumed'
| 'error_budget_remaining'
| 'status'
| 'burn_rate_5m'
| 'burn_rate_1h'
| 'burn_rate_1d';

export type SortDirection = 'asc' | 'desc';
export const SLO_LIST_SEARCH_SESSION_STORAGE_KEY = 'slo.list_page_search_state';

export interface SearchState {
kqlQuery: string;
Expand All @@ -34,21 +28,21 @@ export interface SearchState {
by: SortField;
direction: SortDirection;
};
view: SLOView;
view: ViewType;
groupBy: GroupByField;
filters: Filter[];
lastRefresh?: number;
tagsFilter?: Filter;
statusFilter?: Filter;
}

export const DEFAULT_STATE = {
export const DEFAULT_STATE: SearchState = {
kqlQuery: '',
page: 0,
perPage: DEFAULT_SLO_PAGE_SIZE,
sort: { by: 'status' as const, direction: 'desc' as const },
view: 'cardView' as const,
groupBy: 'ungrouped' as const,
sort: { by: 'status', direction: 'desc' },
view: 'cardView',
groupBy: 'ungrouped',
filters: [],
lastRefresh: 0,
};
Expand All @@ -67,6 +61,8 @@ export function useUrlSearchState(): {
})
);

const sessionStorage = useRef(createSessionStorageStateStorage(window.localStorage));

useEffect(() => {
const sub = urlStateStorage.current
?.change$<SearchState>(SLO_LIST_SEARCH_URL_STORAGE_KEY)
Expand All @@ -77,21 +73,30 @@ export function useUrlSearchState(): {
});

setState(
urlStateStorage.current?.get<SearchState>(SLO_LIST_SEARCH_URL_STORAGE_KEY) ?? DEFAULT_STATE
urlStateStorage.current?.get<SearchState>(SLO_LIST_SEARCH_URL_STORAGE_KEY) ??
sessionStorage.current?.get<SearchState>(SLO_LIST_SEARCH_SESSION_STORAGE_KEY) ??
DEFAULT_STATE
);

return () => {
sub?.unsubscribe();
};
}, [urlStateStorage]);
}, [urlStateStorage, sessionStorage]);

const onStateChange = useCallback(
(newState: Partial<SearchState>) => {
const updatedState = { ...state, page: 0, ...newState };
setState((stateN) => updatedState);
setState(() => updatedState);

urlStateStorage.current?.set(SLO_LIST_SEARCH_URL_STORAGE_KEY, updatedState, {
replace: true,
});

// Discard search itself from session storage. Keep only view preferences
sessionStorage.current?.set(
SLO_LIST_SEARCH_SESSION_STORAGE_KEY,
pick(updatedState, 'sort', 'view', 'groupBy')
);
},
[state]
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

export type ViewType = 'cardView' | 'listView' | 'compactView';
export type GroupByField =
| 'ungrouped'
| 'slo.tags'
| 'status'
| 'slo.indicator.type'
| 'slo.instanceId'
| '_index';
export type SortDirection = 'asc' | 'desc';
export type SortField =
| 'sli_value'
| 'error_budget_consumed'
| 'error_budget_remaining'
| 'status'
| 'burn_rate_5m'
| 'burn_rate_1h'
| 'burn_rate_1d';

0 comments on commit 750a0f3

Please sign in to comment.