Skip to content

Commit

Permalink
feat(slo): handles tab from url in slo details page (#161222)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdelemme authored Jul 12, 2023
1 parent 06f7cbf commit ea0aed2
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ export const useFetchHistoricalSummary = ({
isRefetching: false,
isSuccess: false,
isError: false,
sloHistoricalSummaryResponse: data,
data,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useKibana } from '../../utils/kibana_react';
import { sloKeys } from './query_key_factory';

export interface UseFetchHistoricalSummaryResponse {
sloHistoricalSummaryResponse: FetchHistoricalSummaryResponse | undefined;
data: FetchHistoricalSummaryResponse | undefined;
isInitialLoading: boolean;
isRefetching: boolean;
isLoading: boolean;
Expand Down Expand Up @@ -55,7 +55,7 @@ export function useFetchHistoricalSummary({
});

return {
sloHistoricalSummaryResponse: data,
data,
isLoading,
isRefetching,
isInitialLoading,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import {
EuiTabbedContentTab,
} from '@elastic/eui';
import { SLOWithSummaryResponse } from '@kbn/slo-schema';
import React, { Fragment } from 'react';
import React, { Fragment, useState } from 'react';
import { i18n } from '@kbn/i18n';

import { useLocation } from 'react-router-dom';
import { useFetchActiveAlerts } from '../../../hooks/slo/use_fetch_active_alerts';
import { formatHistoricalData } from '../../../utils/slo/chart_data_formatter';
import { useFetchHistoricalSummary } from '../../../hooks/slo/use_fetch_historical_summary';
Expand All @@ -30,25 +31,28 @@ export interface Props {
slo: SLOWithSummaryResponse;
isAutoRefreshing: boolean;
}
const OVERVIEW_TAB = 'overview';
const ALERTS_TAB = 'alerts';

const TAB_ID_URL_PARAM = 'tabId';
const OVERVIEW_TAB_ID = 'overview';
const ALERTS_TAB_ID = 'alerts';

type TabId = typeof OVERVIEW_TAB_ID | typeof ALERTS_TAB_ID;

export function SloDetails({ slo, isAutoRefreshing }: Props) {
const { data: activeAlerts } = useFetchActiveAlerts({
sloIds: [slo.id],
});
const { isLoading: historicalSummaryLoading, sloHistoricalSummaryResponse = {} } =
const { search } = useLocation();
const { data: activeAlerts } = useFetchActiveAlerts({ sloIds: [slo.id] });
const { isLoading: historicalSummaryLoading, data: historicalSummaryBySlo = {} } =
useFetchHistoricalSummary({ sloIds: [slo.id], shouldRefetch: isAutoRefreshing });

const errorBudgetBurnDownData = formatHistoricalData(
sloHistoricalSummaryResponse[slo.id],
historicalSummaryBySlo[slo.id],
'error_budget_remaining'
);
const historicalSliData = formatHistoricalData(sloHistoricalSummaryResponse[slo.id], 'sli_value');
const historicalSliData = formatHistoricalData(historicalSummaryBySlo[slo.id], 'sli_value');

const tabs: EuiTabbedContentTab[] = [
{
id: OVERVIEW_TAB,
id: OVERVIEW_TAB_ID,
name: i18n.translate('xpack.observability.slo.sloDetails.tab.overviewLabel', {
defaultMessage: 'Overview',
}),
Expand Down Expand Up @@ -84,7 +88,7 @@ export function SloDetails({ slo, isAutoRefreshing }: Props) {
),
},
{
id: ALERTS_TAB,
id: ALERTS_TAB_ID,
name: i18n.translate('xpack.observability.slo.sloDetails.tab.alertsLabel', {
defaultMessage: 'Alerts',
}),
Expand All @@ -98,11 +102,24 @@ export function SloDetails({ slo, isAutoRefreshing }: Props) {
},
];

const [selectedTabId, setSelectedTabId] = useState(() => {
const searchParams = new URLSearchParams(search);
const urlTabId = searchParams.get(TAB_ID_URL_PARAM);
return urlTabId && [OVERVIEW_TAB_ID, ALERTS_TAB_ID].includes(urlTabId)
? (urlTabId as TabId)
: OVERVIEW_TAB_ID;
});

const handleSelectedTab = (newTabId: TabId) => {
setSelectedTabId(newTabId);
};

return (
<EuiTabbedContent
data-test-subj="sloDetailsTabbedContent"
tabs={tabs}
initialSelectedTab={tabs[0]}
selectedTab={tabs.find((tab) => tab.id === selectedTabId) ?? tabs[0]}
onTabClick={(tab) => handleSelectedTab(tab.id as TabId)}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React from 'react';
import { fireEvent, screen, waitFor } from '@testing-library/react';

import { useKibana } from '../../utils/kibana_react';
import { useParams } from 'react-router-dom';
import { useParams, useLocation } from 'react-router-dom';
import { useLicense } from '../../hooks/use_license';
import { useCapabilities } from '../../hooks/slo/use_capabilities';
import { useFetchSloDetails } from '../../hooks/slo/use_fetch_slo_details';
Expand All @@ -31,6 +31,7 @@ import { buildApmAvailabilityIndicator } from '../../data/slo/indicator';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: jest.fn(),
useLocation: jest.fn(),
}));

jest.mock('@kbn/observability-shared-plugin/public');
Expand All @@ -45,6 +46,7 @@ jest.mock('../../hooks/slo/use_delete_slo');

const useKibanaMock = useKibana as jest.Mock;
const useParamsMock = useParams as jest.Mock;
const useLocationMock = useLocation as jest.Mock;
const useLicenseMock = useLicense as jest.Mock;
const useCapabilitiesMock = useCapabilities as jest.Mock;
const useFetchActiveAlertsMock = useFetchActiveAlerts as jest.Mock;
Expand Down Expand Up @@ -105,11 +107,12 @@ describe('SLO Details Page', () => {
useCapabilitiesMock.mockReturnValue({ hasWriteCapabilities: true, hasReadCapabilities: true });
useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});
useFetchActiveAlertsMock.mockReturnValue({ isLoading: false, data: {} });
useCloneSloMock.mockReturnValue({ mutate: mockClone });
useDeleteSloMock.mockReturnValue({ mutate: mockDelete });
useLocationMock.mockReturnValue({ search: '' });
});

describe('when the incorrect license is found', () => {
Expand Down Expand Up @@ -155,7 +158,7 @@ describe('SLO Details Page', () => {
useLicenseMock.mockReturnValue({ hasAtLeast: () => true });
useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: true,
sloHistoricalSummaryResponse: {},
data: {},
});

render(<SloDetailsPage />);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,8 @@ export function SloDetailsPage() {
const hasRightLicense = hasAtLeast('platinum');

const { sloId } = useParams<SloDetailsPathParams>();

const [isAutoRefreshing, setIsAutoRefreshing] = useState(true);

const { isLoading, slo } = useFetchSloDetails({ sloId, shouldRefetch: isAutoRefreshing });

const isCloningOrDeleting = Boolean(useIsMutating());

useBreadcrumbs(getBreadcrumbs(basePath, slo));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function SloListItems({ sloList, loading, error }: Props) {

const { data: activeAlertsBySlo } = useFetchActiveAlerts({ sloIds });
const { data: rulesBySlo } = useFetchRulesForSlo({ sloIds });
const { isLoading: historicalSummaryLoading, sloHistoricalSummaryResponse } =
const { isLoading: historicalSummaryLoading, data: historicalSummaryBySlo } =
useFetchHistoricalSummary({ sloIds });

const { mutate: deleteSlo } = useDeleteSlo();
Expand All @@ -50,7 +50,7 @@ export function SloListItems({ sloList, loading, error }: Props) {
<SloListItem
activeAlerts={activeAlertsBySlo[slo.id]}
rules={rulesBySlo?.[slo.id]}
historicalSummary={sloHistoricalSummaryResponse?.[slo.id]}
historicalSummary={historicalSummaryBySlo?.[slo.id]}
historicalSummaryLoading={historicalSummaryLoading}
slo={slo}
onConfirmDelete={handleDelete}
Expand Down
20 changes: 10 additions & 10 deletions x-pack/plugins/observability/public/pages/slos/slos.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ describe('SLOs Page', () => {
useLicenseMock.mockReturnValue({ hasAtLeast: () => false });
useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: {},
data: {},
});
});
it('navigates to the SLOs Welcome Page', async () => {
Expand All @@ -135,7 +135,7 @@ describe('SLOs Page', () => {
useFetchSloListMock.mockReturnValue({ isLoading: false, sloList: emptySloList });
useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: {},
data: {},
});

await act(async () => {
Expand All @@ -152,7 +152,7 @@ describe('SLOs Page', () => {

useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});

await act(async () => {
Expand All @@ -167,7 +167,7 @@ describe('SLOs Page', () => {

useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});

await act(async () => {
Expand All @@ -183,7 +183,7 @@ describe('SLOs Page', () => {

useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});

await act(async () => {
Expand All @@ -201,7 +201,7 @@ describe('SLOs Page', () => {

useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});

await act(async () => {
Expand All @@ -228,7 +228,7 @@ describe('SLOs Page', () => {

useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});

await act(async () => {
Expand All @@ -253,7 +253,7 @@ describe('SLOs Page', () => {

useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});

await act(async () => {
Expand All @@ -278,7 +278,7 @@ describe('SLOs Page', () => {

useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});

await act(async () => {
Expand Down Expand Up @@ -308,7 +308,7 @@ describe('SLOs Page', () => {

useFetchHistoricalSummaryMock.mockReturnValue({
isLoading: false,
sloHistoricalSummaryResponse: historicalSummaryData,
data: historicalSummaryData,
});

await act(async () => {
Expand Down

0 comments on commit ea0aed2

Please sign in to comment.