mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
200 lines
6.2 KiB
TypeScript
200 lines
6.2 KiB
TypeScript
import {useEffect, useRef, useState} from 'react';
|
|
import type {InjectedRouter} from 'react-router';
|
|
import {browserHistory} from 'react-router';
|
|
import * as Sentry from '@sentry/react';
|
|
import type {Location} from 'history';
|
|
import isEqual from 'lodash/isEqual';
|
|
|
|
import {loadOrganizationTags} from 'sentry/actionCreators/tags';
|
|
import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
|
|
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
|
|
import {ALL_ACCESS_PROJECTS} from 'sentry/constants/pageFilters';
|
|
import {t} from 'sentry/locale';
|
|
import type {PageFilters, Project} from 'sentry/types';
|
|
import {trackAnalytics} from 'sentry/utils/analytics';
|
|
import type {MEPState} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
|
|
import {
|
|
canUseMetricsData,
|
|
METRIC_SEARCH_SETTING_PARAM,
|
|
} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
|
|
import {PerformanceEventViewProvider} from 'sentry/utils/performance/contexts/performanceEventViewContext';
|
|
import useRouteAnalyticsEventNames from 'sentry/utils/routeAnalytics/useRouteAnalyticsEventNames';
|
|
import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams';
|
|
import useApi from 'sentry/utils/useApi';
|
|
import useOrganization from 'sentry/utils/useOrganization';
|
|
import usePrevious from 'sentry/utils/usePrevious';
|
|
import useProjects from 'sentry/utils/useProjects';
|
|
import withPageFilters from 'sentry/utils/withPageFilters';
|
|
|
|
import {getLandingDisplayFromParam} from './landing/utils';
|
|
import {generatePerformanceEventView, getDefaultStatsPeriod} from './data';
|
|
import {PerformanceLanding} from './landing';
|
|
import {
|
|
addRoutePerformanceContext,
|
|
getSelectedProjectPlatforms,
|
|
handleTrendsClick,
|
|
} from './utils';
|
|
|
|
type Props = {
|
|
location: Location;
|
|
router: InjectedRouter;
|
|
selection: PageFilters;
|
|
demoMode?: boolean;
|
|
};
|
|
|
|
type State = {
|
|
error?: string;
|
|
};
|
|
|
|
function PerformanceContent({selection, location, demoMode, router}: Props) {
|
|
const api = useApi();
|
|
const organization = useOrganization();
|
|
const {projects} = useProjects();
|
|
const mounted = useRef(false);
|
|
const previousDateTime = usePrevious(selection.datetime);
|
|
const [state, setState] = useState<State>({error: undefined});
|
|
const withStaticFilters = canUseMetricsData(organization);
|
|
const eventView = generatePerformanceEventView(
|
|
location,
|
|
projects,
|
|
{
|
|
withStaticFilters,
|
|
},
|
|
organization
|
|
);
|
|
|
|
function getOnboardingProject(): Project | undefined {
|
|
// XXX used by getsentry to bypass onboarding for the upsell demo state.
|
|
if (demoMode) {
|
|
return undefined;
|
|
}
|
|
|
|
if (projects.length === 0) {
|
|
return undefined;
|
|
}
|
|
|
|
// Current selection is 'my projects' or 'all projects'
|
|
if (eventView.project.length === 0 || eventView.project[0] === ALL_ACCESS_PROJECTS) {
|
|
const filtered = projects.filter(p => p.firstTransactionEvent === false);
|
|
if (filtered.length === projects.length) {
|
|
return filtered[0];
|
|
}
|
|
}
|
|
|
|
// Any other subset of projects.
|
|
const filtered = projects.filter(
|
|
p =>
|
|
eventView.project.includes(parseInt(p.id, 10)) &&
|
|
p.firstTransactionEvent === false
|
|
);
|
|
if (filtered.length === eventView.project.length) {
|
|
return filtered[0];
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
const onboardingProject = getOnboardingProject();
|
|
|
|
useRouteAnalyticsEventNames(
|
|
'performance_views.overview.view',
|
|
'Performance Views: Transaction overview view'
|
|
);
|
|
|
|
useRouteAnalyticsParams({
|
|
project_platforms: getSelectedProjectPlatforms(location, projects),
|
|
show_onboarding: onboardingProject !== undefined,
|
|
tab: getLandingDisplayFromParam(location)?.field,
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (!mounted.current) {
|
|
loadOrganizationTags(api, organization.slug, selection);
|
|
addRoutePerformanceContext(selection);
|
|
mounted.current = true;
|
|
return;
|
|
}
|
|
if (!isEqual(previousDateTime, selection.datetime)) {
|
|
loadOrganizationTags(api, organization.slug, selection);
|
|
addRoutePerformanceContext(selection);
|
|
}
|
|
}, [
|
|
selection.datetime,
|
|
previousDateTime,
|
|
selection,
|
|
api,
|
|
organization,
|
|
onboardingProject,
|
|
location,
|
|
projects,
|
|
]);
|
|
|
|
function setError(newError?: string) {
|
|
if (
|
|
typeof newError === 'object' ||
|
|
(Array.isArray(newError) && typeof newError[0] === 'object')
|
|
) {
|
|
Sentry.withScope(scope => {
|
|
scope.setExtra('error', newError);
|
|
Sentry.captureException(new Error('setError failed with error type.'));
|
|
});
|
|
return;
|
|
}
|
|
setState({...state, error: newError});
|
|
}
|
|
|
|
function handleSearch(searchQuery: string, currentMEPState?: MEPState) {
|
|
trackAnalytics('performance_views.overview.search', {organization});
|
|
|
|
browserHistory.push({
|
|
pathname: location.pathname,
|
|
query: {
|
|
...location.query,
|
|
cursor: undefined,
|
|
query: String(searchQuery).trim() || undefined,
|
|
[METRIC_SEARCH_SETTING_PARAM]: currentMEPState,
|
|
isDefaultQuery: false,
|
|
},
|
|
});
|
|
}
|
|
|
|
return (
|
|
<SentryDocumentTitle title={t('Performance')} orgSlug={organization.slug}>
|
|
<PerformanceEventViewProvider value={{eventView}}>
|
|
<PageFiltersContainer
|
|
defaultSelection={{
|
|
datetime: {
|
|
start: null,
|
|
end: null,
|
|
utc: false,
|
|
period: getDefaultStatsPeriod(organization),
|
|
},
|
|
}}
|
|
>
|
|
<PerformanceLanding
|
|
router={router}
|
|
eventView={eventView}
|
|
setError={setError}
|
|
handleSearch={handleSearch}
|
|
handleTrendsClick={() =>
|
|
handleTrendsClick({
|
|
location,
|
|
organization,
|
|
projectPlatforms: getSelectedProjectPlatforms(location, projects),
|
|
})
|
|
}
|
|
onboardingProject={onboardingProject}
|
|
organization={organization}
|
|
location={location}
|
|
projects={projects}
|
|
selection={selection}
|
|
withStaticFilters={withStaticFilters}
|
|
/>
|
|
</PageFiltersContainer>
|
|
</PerformanceEventViewProvider>
|
|
</SentryDocumentTitle>
|
|
);
|
|
}
|
|
|
|
export default withPageFilters(PerformanceContent);
|