Skip to content

Commit

Permalink
Reorder SLO List page
Browse files Browse the repository at this point in the history
  • Loading branch information
CoenWarmer committed Mar 9, 2023
1 parent 8a11060 commit 7619245
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 2 deletions.
259 changes: 259 additions & 0 deletions x-pack/plugins/observability/public/pages/overview/overview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
/*
* 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 { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiSpacer } from '@elastic/eui';
import { BoolQuery } from '@kbn/es-query';
import { i18n } from '@kbn/i18n';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { AlertConsumers } from '@kbn/rule-data-utils';
import React, { useEffect, useMemo, useCallback, useState } from 'react';

import { observabilityFeatureId } from '../../../common';
import type { ObservabilityAppServices } from '../../application/types';
import { LoadingObservability } from '../../components/loading_observability';
import { HeaderActions } from './components/header_actions';
import { DataAssistantFlyout } from './components/data_assistant_flyout';
import { EmptySections } from './components/empty_sections';
import { HeaderMenu } from './components/header_menu';
import { Resources } from './components/resources';
import { NewsFeed } from './components/news_feed';
import { ObservabilityStatusProgress } from '../../components/app/observability_status/observability_status_progress';
import { observabilityAlertFeatureIds, paths } from '../../config';
import { useBreadcrumbs } from '../../hooks/use_breadcrumbs';
import { useDatePickerContext } from '../../hooks/use_date_picker_context';
import { useFetcher } from '../../hooks/use_fetcher';
import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions';
import { useGuidedSetupProgress } from '../../hooks/use_guided_setup_progress';
import { useHasData } from '../../hooks/use_has_data';
import { usePluginContext } from '../../hooks/use_plugin_context';
import { useTimeBuckets } from '../../hooks/use_time_buckets';
import { getNewsFeed } from '../../services/get_news_feed';
import { buildEsQuery } from '../../utils/build_es_query';
import { getAlertSummaryTimeRange } from '../../utils/alert_summary_widget';

import { DEFAULT_DATE_FORMAT, DEFAULT_INTERVAL } from '../constants';
import { calculateBucketSize } from './helpers/calculate_bucket_size';
import { useOverviewMetrics } from './helpers/use_overview_metrics';
import { SectionContainer } from '../../components/app/section';
import { DataSections } from './components/data_sections';

const ALERTS_PER_PAGE = 10;
const ALERTS_TABLE_ID = 'xpack.observability.overview.alert.table';

export function OverviewPage() {
const {
cases: {
ui: { getCasesContext },
},
charts,
http,
triggersActionsUi: {
alertsTableConfigurationRegistry,
getAlertsStateTable: AlertsStateTable,
getAlertSummaryWidget: AlertSummaryWidget,
},
kibanaVersion,
} = useKibana<ObservabilityAppServices>().services;

const { ObservabilityPageTemplate } = usePluginContext();

useBreadcrumbs([
{
text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', {
defaultMessage: 'Overview',
}),
},
]);

const { data: newsFeed } = useFetcher(
() => getNewsFeed({ http, kibanaVersion }),
[http, kibanaVersion]
);
const { hasAnyData, isAllRequestsComplete } = useHasData();

const { trackMetric } = useOverviewMetrics({ hasAnyData });

const CasesContext = getCasesContext();
const userCasesPermissions = useGetUserCasesPermissions();

const [isDataAssistantFlyoutVisible, setIsDataAssistantFlyoutVisible] = useState(false);

const { isGuidedSetupProgressDismissed } = useGuidedSetupProgress();
const [isGuidedSetupTourVisible, setGuidedSetupTourVisible] = useState(false);

const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useDatePickerContext();

const [esQuery, setEsQuery] = useState<{ bool: BoolQuery }>(
buildEsQuery({
from: relativeStart,
to: relativeEnd,
})
);

const timeBuckets = useTimeBuckets();
const bucketSize = useMemo(
() =>
calculateBucketSize({
start: absoluteStart,
end: absoluteEnd,
timeBuckets,
}),
[absoluteStart, absoluteEnd, timeBuckets]
);
const alertSummaryTimeRange = useMemo(
() =>
getAlertSummaryTimeRange(
{
from: relativeStart,
to: relativeEnd,
},
bucketSize?.intervalString || DEFAULT_INTERVAL,
bucketSize?.dateFormat || DEFAULT_DATE_FORMAT
),
[bucketSize, relativeEnd, relativeStart]
);

const chartThemes = {
theme: charts.theme.useChartsTheme(),
baseTheme: charts.theme.useChartsBaseTheme(),
};

useEffect(() => {
setEsQuery(
buildEsQuery({
from: relativeStart,
to: relativeEnd,
})
);
}, [relativeEnd, relativeStart]);

const handleTimeRangeRefresh = useCallback(() => {
setEsQuery(
buildEsQuery({
from: relativeStart,
to: relativeEnd,
})
);
}, [relativeEnd, relativeStart]);

const handleCloseGuidedSetupTour = () => {
setGuidedSetupTourVisible(false);
};

const handleGuidedSetupClick = useCallback(() => {
if (isGuidedSetupProgressDismissed) {
trackMetric({ metric: 'guided_setup_view_details_after_dismiss' });
}

handleCloseGuidedSetupTour();

setIsDataAssistantFlyoutVisible(true);
}, [trackMetric, isGuidedSetupProgressDismissed]);

if (hasAnyData === undefined) {
return <LoadingObservability />;
}

return (
<ObservabilityPageTemplate
isPageDataLoaded={isAllRequestsComplete}
pageHeader={{
pageTitle: i18n.translate('xpack.observability.overview.pageTitle', {
defaultMessage: 'Overview',
}),
rightSideItems: [
<HeaderActions
showTour={isGuidedSetupTourVisible}
onGuidedSetupClick={handleGuidedSetupClick}
onTourDismiss={handleCloseGuidedSetupTour}
onTimeRangeRefresh={handleTimeRangeRefresh}
/>,
],
rightSideGroupProps: {
responsive: true,
},
}}
>
<HeaderMenu />

<ObservabilityStatusProgress
onDismissClick={() => setGuidedSetupTourVisible(true)}
onViewDetailsClick={() => setIsDataAssistantFlyoutVisible(true)}
/>

<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<SectionContainer
title={i18n.translate('xpack.observability.overview.alerts.title', {
defaultMessage: 'Alerts',
})}
appLink={{
href: paths.observability.alerts,
label: i18n.translate('xpack.observability.overview.alerts.appLink', {
defaultMessage: 'Show alerts',
}),
}}
initialIsOpen={hasAnyData}
hasError={false}
>
<CasesContext
owner={[observabilityFeatureId]}
permissions={userCasesPermissions}
features={{ alerts: { sync: false } }}
>
<AlertSummaryWidget
featureIds={observabilityAlertFeatureIds}
filter={esQuery}
fullSize
timeRange={alertSummaryTimeRange}
chartThemes={chartThemes}
/>
<AlertsStateTable
alertsTableConfigurationRegistry={alertsTableConfigurationRegistry}
configurationId={AlertConsumers.OBSERVABILITY}
flyoutSize="s"
featureIds={observabilityAlertFeatureIds}
hideLazyLoader
id={ALERTS_TABLE_ID}
pageSize={ALERTS_PER_PAGE}
query={esQuery}
showExpandToDetails={false}
showAlertStatusWithFlapping
/>
</CasesContext>
</SectionContainer>
</EuiFlexItem>
<EuiFlexItem>
{/* Data sections */}
<DataSections bucketSize={bucketSize} />
<EmptySections />
</EuiFlexItem>
<EuiSpacer size="s" />
</EuiFlexGroup>

<EuiHorizontalRule />

<EuiFlexGroup>
<EuiFlexItem>
{/* Resources / What's New sections */}
<EuiFlexGroup>
<EuiFlexItem grow={4}>
{!!newsFeed?.items?.length && <NewsFeed items={newsFeed.items.slice(0, 3)} />}
</EuiFlexItem>
<EuiFlexItem grow={2}>
<Resources />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>

{isDataAssistantFlyoutVisible ? (
<DataAssistantFlyout onClose={() => setIsDataAssistantFlyoutVisible(false)} />
) : null}
</ObservabilityPageTemplate>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { useDeleteSlo } from '../../hooks/slo/use_delete_slo';
import { useFetchSloList } from '../../hooks/slo/use_fetch_slo_list';
import { useFetchHistoricalSummary } from '../../hooks/slo/use_fetch_historical_summary';
import { useLicense } from '../../hooks/use_license';
import { SlosPage } from '.';
import { SlosPage } from './slos';
import { emptySloList, sloList } from '../../data/slo/slo';
import type { ConfigSchema } from '../../plugin';
import type { Subset } from '../../typings';
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/observability/public/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { RuleDetailsPage } from '../pages/rule_details';
import { AlertingPages } from '../config';
import { AlertDetails } from '../pages/alert_details';
import { DatePickerContextProvider } from '../context/date_picker_context';
import { SlosPage } from '../pages/slos';
import { SlosPage } from '../pages/slos/slos';
import { SloDetailsPage } from '../pages/slo_details';
import { SloEditPage } from '../pages/slo_edit';

Expand Down

0 comments on commit 7619245

Please sign in to comment.