import React, {Fragment} from 'react';
import styled from '@emotion/styled';
import Alert from 'sentry/components/alert';
import {Breadcrumbs} from 'sentry/components/breadcrumbs';
import ButtonBar from 'sentry/components/buttonBar';
import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton';
import * as Layout from 'sentry/components/layouts/thirds';
import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter';
import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionTooltip';
import SearchBar from 'sentry/components/searchBar';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {browserHistory} from 'sentry/utils/browserHistory';
import {decodeScalar, decodeSorts} from 'sentry/utils/queryString';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
import useOrganization from 'sentry/utils/useOrganization';
import {useOnboardingProject} from 'sentry/views/performance/browser/webVitals/utils/useOnboardingProject';
import {DurationChart} from 'sentry/views/performance/database/durationChart';
import {NoDataMessage} from 'sentry/views/performance/database/noDataMessage';
import {isAValidSort, QueriesTable} from 'sentry/views/performance/database/queriesTable';
import {
MODULE_DESCRIPTION,
MODULE_DOC_LINK,
MODULE_TITLE,
} from 'sentry/views/performance/database/settings';
import {ThroughputChart} from 'sentry/views/performance/database/throughputChart';
import {useSelectedDurationAggregate} from 'sentry/views/performance/database/useSelectedDurationAggregate';
import * as ModuleLayout from 'sentry/views/performance/moduleLayout';
import {ModulePageProviders} from 'sentry/views/performance/modulePageProviders';
import Onboarding from 'sentry/views/performance/onboarding';
import {useModuleBreadcrumbs} from 'sentry/views/performance/utils/useModuleBreadcrumbs';
import {useSynchronizeCharts} from 'sentry/views/starfish/components/chart';
import {useSpanMetrics} from 'sentry/views/starfish/queries/useDiscover';
import {useSpanMetricsSeries} from 'sentry/views/starfish/queries/useDiscoverSeries';
import {ModuleName, SpanMetricsField} from 'sentry/views/starfish/types';
import {QueryParameterNames} from 'sentry/views/starfish/views/queryParameters';
import {ActionSelector} from 'sentry/views/starfish/views/spans/selectors/actionSelector';
import {DomainSelector} from 'sentry/views/starfish/views/spans/selectors/domainSelector';
export function DatabaseLandingPage() {
const organization = useOrganization();
const moduleName = ModuleName.DB;
const location = useLocation();
const onboardingProject = useOnboardingProject();
const [selectedAggregate] = useSelectedDurationAggregate();
const spanDescription = decodeScalar(location.query?.['span.description'], '');
const spanAction = decodeScalar(location.query?.['span.action']);
const spanDomain = decodeScalar(location.query?.['span.domain']);
const sortField = decodeScalar(location.query?.[QueryParameterNames.SPANS_SORT]);
let sort = decodeSorts(sortField).filter(isAValidSort)[0];
if (!sort) {
sort = DEFAULT_SORT;
}
const handleSearch = (newQuery: string) => {
browserHistory.push({
...location,
query: {
...location.query,
'span.description': newQuery === '' ? undefined : newQuery,
[QueryParameterNames.SPANS_CURSOR]: undefined,
},
});
};
const chartFilters = {
'span.module': ModuleName.DB,
has: 'span.description',
};
const tableFilters = {
'span.module': ModuleName.DB,
'span.action': spanAction,
'span.domain': spanDomain,
'span.description': spanDescription ? `*${spanDescription}*` : undefined,
has: 'span.description',
};
const cursor = decodeScalar(location.query?.[QueryParameterNames.SPANS_CURSOR]);
const queryListResponse = useSpanMetrics(
{
search: MutableSearch.fromQueryObject(tableFilters),
fields: [
'project.id',
'span.group',
'span.description',
'spm()',
'avg(span.self_time)',
'sum(span.self_time)',
'time_spent_percentage()',
],
sorts: [sort],
limit: LIMIT,
cursor,
},
'api.starfish.use-span-list'
);
const {
isLoading: isThroughputDataLoading,
data: throughputData,
error: throughputError,
} = useSpanMetricsSeries(
{
search: MutableSearch.fromQueryObject(chartFilters),
yAxis: ['spm()'],
},
'api.starfish.span-landing-page-metrics-chart'
);
const {
isLoading: isDurationDataLoading,
data: durationData,
error: durationError,
} = useSpanMetricsSeries(
{
search: MutableSearch.fromQueryObject(chartFilters),
yAxis: [`${selectedAggregate}(${SpanMetricsField.SPAN_SELF_TIME})`],
},
'api.starfish.span-landing-page-metrics-chart'
);
const isCriticalDataLoading =
isThroughputDataLoading || isDurationDataLoading || queryListResponse.isLoading;
const isAnyCriticalDataAvailable =
(queryListResponse.data ?? []).length > 0 ||
durationData[`${selectedAggregate}(span.self_time)`].data?.some(
({value}) => value > 0
) ||
throughputData['spm()'].data?.some(({value}) => value > 0);
useSynchronizeCharts([!isThroughputDataLoading && !isDurationDataLoading]);
const crumbs = useModuleBreadcrumbs('db');
return (
{MODULE_TITLE}
{!onboardingProject && !isCriticalDataLoading && (
)}
{onboardingProject && (
)}
{!onboardingProject && (
)}
);
}
const DEFAULT_SORT = {
field: 'time_spent_percentage()' as const,
kind: 'desc' as const,
};
function AlertBanner(props) {
return ;
}
const FilterOptionsContainer = styled('div')`
display: flex;
flex-wrap: wrap;
gap: ${space(2)};
@media (min-width: ${p => p.theme.breakpoints.small}) {
flex-wrap: nowrap;
}
`;
const SelectorContainer = styled('div')`
flex-basis: 100%;
@media (min-width: ${p => p.theme.breakpoints.small}) {
flex-basis: auto;
}
`;
const LIMIT: number = 25;
function PageWithProviders() {
return (
);
}
export default PageWithProviders;