Skip to content

Commit

Permalink
feat(slo): store view and compact mode in URL state (#172878)
Browse files Browse the repository at this point in the history
(cherry picked from commit 4eea0d6)
  • Loading branch information
kdelemme committed Dec 8, 2023
1 parent b79c4b3 commit b508553
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 32 deletions.
8 changes: 4 additions & 4 deletions x-pack/plugins/observability/public/locators/slo_list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ describe('SloListLocator', () => {
it("returns the correct url with the default search state when no 'kqlQuery' provided", async () => {
const location = await locator.getLocation({});
expect(location.app).toEqual('observability');
expect(location.path).toEqual(
"/slos?search=(kqlQuery:'',page:0,sort:(by:status,direction:desc),viewMode:compact)"
expect(location.path).toMatchInlineSnapshot(
`"/slos?search=(compact:!t,kqlQuery:'',page:0,sort:(by:status,direction:desc),view:cardView)"`
);
});

Expand All @@ -23,8 +23,8 @@ describe('SloListLocator', () => {
kqlQuery: 'slo.name: "Service Availability" and slo.indicator.type : "sli.kql.custom"',
});
expect(location.app).toEqual('observability');
expect(location.path).toEqual(
"/slos?search=(kqlQuery:'slo.name:%20%22Service%20Availability%22%20and%20slo.indicator.type%20:%20%22sli.kql.custom%22',page:0,sort:(by:status,direction:desc),viewMode:compact)"
expect(location.path).toMatchInlineSnapshot(
`"/slos?search=(compact:!t,kqlQuery:'slo.name:%20%22Service%20Availability%22%20and%20slo.indicator.type%20:%20%22sli.kql.custom%22',page:0,sort:(by:status,direction:desc),view:cardView)"`
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@
import { EuiFlexGroup, EuiFlexItem, EuiPagination } from '@elastic/eui';
import { useIsMutating } from '@tanstack/react-query';
import React, { useState } from 'react';
import useLocalStorage from 'react-use/lib/useLocalStorage';
import { SlosView } from './slos_view';
import { SLO_LIST_IS_COMPACT } from './slo_view_settings';
import { SLOViewType, ToggleSLOView } from './toggle_slo_view';
import { useFetchSloList } from '../../../hooks/slo/use_fetch_slo_list';
import { useUrlSearchState } from '../hooks/use_url_search_state';
import { SloListSearchBar, SortField } from './slo_list_search_bar';
import { SlosView } from './slos_view';
import { SloListSearchBar, SortDirection, SortField } from './slo_list_search_bar';
import { SLOView, ToggleSLOView } from './toggle_slo_view';

export interface Props {
autoRefresh: boolean;
Expand All @@ -25,8 +23,9 @@ export function SloList({ autoRefresh }: Props) {
const [page, setPage] = useState(state.page);
const [query, setQuery] = useState(state.kqlQuery);
const [sort, setSort] = useState<SortField>(state.sort.by);
const [direction] = useState<'asc' | 'desc'>(state.sort.direction);
const [sloView, setSLOView] = useState<SLOViewType>('cardView');
const [direction] = useState<SortDirection>(state.sort.direction);
const [view, setView] = useState<SLOView>(state.view);
const [isCompact, setCompact] = useState<boolean>(state.compact);

const {
isLoading,
Expand All @@ -47,8 +46,6 @@ export function SloList({ autoRefresh }: Props) {
const isCloningSlo = Boolean(useIsMutating(['cloningSlo']));
const isUpdatingSlo = Boolean(useIsMutating(['updatingSlo']));
const isDeletingSlo = Boolean(useIsMutating(['deleteSlo']));
const [isCompact, setIsCompact] = useLocalStorage<'true' | 'false'>(SLO_LIST_IS_COMPACT, 'true');
const isCompactView = isCompact === 'true';

const handlePageClick = (pageNumber: number) => {
setPage(pageNumber);
Expand All @@ -67,6 +64,17 @@ export function SloList({ autoRefresh }: Props) {
storeState({ page: 0, sort: { by: newSort, direction: state.sort.direction } });
};

const handleChangeView = (newView: SLOView) => {
setView(newView);
storeState({ view: newView });
};

const handleToggleCompactView = () => {
const newCompact = !isCompact;
setCompact(newCompact);
storeState({ compact: newCompact });
};

return (
<EuiFlexGroup direction="column" gutterSize="m" data-test-subj="sloList">
<EuiFlexItem grow>
Expand All @@ -79,20 +87,18 @@ export function SloList({ autoRefresh }: Props) {
</EuiFlexItem>
<EuiFlexItem grow={false}>
<ToggleSLOView
sloView={sloView}
setSLOView={setSLOView}
toggleCompactView={() =>
isCompact === 'true' ? setIsCompact('false') : setIsCompact('true')
}
isCompact={isCompactView}
sloView={view}
onChangeView={handleChangeView}
onToggleCompactView={handleToggleCompactView}
isCompact={isCompact}
/>
</EuiFlexItem>
<SlosView
sloList={results}
loading={isLoading || isRefetching}
error={isError}
isCompact={isCompactView}
sloView={sloView}
isCompact={isCompact}
sloView={view}
/>

{total > 0 ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface Props {
}

export type SortField = 'sli_value' | 'error_budget_consumed' | 'error_budget_remaining' | 'status';
export type SortDirection = 'asc' | 'desc';

export type Item<T> = EuiSelectableOption & {
label: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import { i18n } from '@kbn/i18n';
import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { SLOViewSettings } from './slo_view_settings';

export type SLOViewType = 'cardView' | 'listView';
export type SLOView = 'cardView' | 'listView';

interface Props {
toggleCompactView: () => void;
onToggleCompactView: () => void;
onChangeView: (view: SLOView) => void;
isCompact: boolean;
setSLOView: (view: SLOViewType) => void;
sloView: SLOViewType;
sloView: SLOView;
}

const toggleButtonsIcons = [
{
id: `cardView`,
Expand All @@ -33,7 +34,12 @@ const toggleButtonsIcons = [
},
];

export function ToggleSLOView({ sloView, setSLOView, toggleCompactView, isCompact = true }: Props) {
export function ToggleSLOView({
sloView,
onChangeView,
onToggleCompactView,
isCompact = true,
}: Props) {
return (
<EuiFlexGroup alignItems="center">
<EuiFlexItem>
Expand All @@ -43,12 +49,12 @@ export function ToggleSLOView({ sloView, setSLOView, toggleCompactView, isCompac
})}
options={toggleButtonsIcons}
idSelected={sloView}
onChange={(id) => setSLOView(id as SLOViewType)}
onChange={(id) => onChangeView(id as SLOView)}
isIconOnly
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<SLOViewSettings toggleCompactView={toggleCompactView} isCompact={isCompact} />
<SLOViewSettings toggleCompactView={onToggleCompactView} isCompact={isCompact} />
</EuiFlexItem>
</EuiFlexGroup>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import { createKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public';
import deepmerge from 'deepmerge';
import { useHistory } from 'react-router-dom';
import type { SortField, ViewMode } from '../components/slo_list_search_bar';
import type { SortField, SortDirection } from '../components/slo_list_search_bar';
import type { SLOView } from '../components/toggle_slo_view';

export const SLO_LIST_SEARCH_URL_STORAGE_KEY = 'search';

Expand All @@ -17,16 +18,18 @@ export interface SearchState {
page: number;
sort: {
by: SortField;
direction: 'asc' | 'desc';
direction: SortDirection;
};
viewMode: ViewMode;
view: SLOView;
compact: boolean;
}

export const DEFAULT_STATE = {
kqlQuery: '',
page: 0,
sort: { by: 'status' as const, direction: 'desc' as const },
viewMode: 'compact' as const,
view: 'cardView' as const,
compact: true,
};

export function useUrlSearchState(): {
Expand Down

0 comments on commit b508553

Please sign in to comment.