Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {PROJECT_PERFORMANCE_TYPE} from 'app/views/performance/utils';

import {createDefinedContext} from './utils';

type useCurrentPerformanceView = {
performanceType: PROJECT_PERFORMANCE_TYPE;
};

const [PerformanceDisplayProvider, _usePerformanceDisplayType] =
createDefinedContext<useCurrentPerformanceView>({
name: 'CurrentPerformanceViewContext',
});

export {PerformanceDisplayProvider};

export function usePerformanceDisplayType(): PROJECT_PERFORMANCE_TYPE {
return _usePerformanceDisplayType().performanceType;
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
import {usePageError} from 'app/utils/performance/contexts/pageError';
import {PerformanceDisplayProvider} from 'app/utils/performance/contexts/performanceDisplayContext';

import Table from '../../table';
import {PROJECT_PERFORMANCE_TYPE} from '../../utils';
import {DoubleChartRow, TripleChartRow} from '../widgets/components/widgetChartRow';
import {PerformanceWidgetSetting} from '../widgets/widgetDefinitions';

import {BasePerformanceViewProps} from './types';

export function AllTransactionsView(props: BasePerformanceViewProps) {
return (
<div>
<TripleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.USER_MISERY_AREA,
PerformanceWidgetSetting.TPM_AREA,
PerformanceWidgetSetting.FAILURE_RATE_AREA,
PerformanceWidgetSetting.APDEX_AREA,
PerformanceWidgetSetting.P50_DURATION_AREA,
PerformanceWidgetSetting.P95_DURATION_AREA,
PerformanceWidgetSetting.P99_DURATION_AREA,
]}
/>
<DoubleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.MOST_RELATED_ERRORS,
PerformanceWidgetSetting.MOST_RELATED_ISSUES,
PerformanceWidgetSetting.MOST_IMPROVED,
PerformanceWidgetSetting.MOST_REGRESSED,
]}
/>
<Table {...props} setError={usePageError().setPageError} />
</div>
<PerformanceDisplayProvider value={{performanceType: PROJECT_PERFORMANCE_TYPE.ANY}}>
<div>
<TripleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.USER_MISERY_AREA,
PerformanceWidgetSetting.TPM_AREA,
PerformanceWidgetSetting.FAILURE_RATE_AREA,
PerformanceWidgetSetting.APDEX_AREA,
PerformanceWidgetSetting.P50_DURATION_AREA,
PerformanceWidgetSetting.P95_DURATION_AREA,
PerformanceWidgetSetting.P99_DURATION_AREA,
]}
/>
<DoubleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.MOST_RELATED_ERRORS,
PerformanceWidgetSetting.MOST_RELATED_ISSUES,
PerformanceWidgetSetting.MOST_IMPROVED,
PerformanceWidgetSetting.MOST_REGRESSED,
]}
/>
<Table {...props} setError={usePageError().setPageError} />
</div>
</PerformanceDisplayProvider>
);
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
import {usePageError} from 'app/utils/performance/contexts/pageError';
import {PerformanceDisplayProvider} from 'app/utils/performance/contexts/performanceDisplayContext';

import Table from '../../table';
import {PROJECT_PERFORMANCE_TYPE} from '../../utils';
import {FRONTEND_OTHER_COLUMN_TITLES} from '../data';
import {DoubleChartRow, TripleChartRow} from '../widgets/components/widgetChartRow';
import {PerformanceWidgetSetting} from '../widgets/widgetDefinitions';

import {BasePerformanceViewProps} from './types';

export function FrontendOtherView(props: BasePerformanceViewProps) {
return (
<div>
<Table
{...props}
columnTitles={FRONTEND_OTHER_COLUMN_TITLES}
setError={usePageError().setPageError}
/>
</div>
<PerformanceDisplayProvider
value={{performanceType: PROJECT_PERFORMANCE_TYPE.FRONTEND_OTHER}}
>
<div data-test-id="frontend-pageload-view">
<TripleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.TPM_AREA,
PerformanceWidgetSetting.DURATION_HISTOGRAM,
PerformanceWidgetSetting.P50_DURATION_AREA,
PerformanceWidgetSetting.P95_DURATION_AREA,
PerformanceWidgetSetting.P99_DURATION_AREA,
]}
/>
<DoubleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.MOST_RELATED_ERRORS,
PerformanceWidgetSetting.MOST_RELATED_ISSUES,
]}
/>
<Table
{...props}
columnTitles={FRONTEND_OTHER_COLUMN_TITLES}
setError={usePageError().setPageError}
/>
</div>
</PerformanceDisplayProvider>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {usePageError} from 'app/utils/performance/contexts/pageError';
import {PerformanceDisplayProvider} from 'app/utils/performance/contexts/performanceDisplayContext';

import Table from '../../table';
import {PROJECT_PERFORMANCE_TYPE} from '../../utils';
import {FRONTEND_PAGELOAD_COLUMN_TITLES} from '../data';
import {DoubleChartRow, TripleChartRow} from '../widgets/components/widgetChartRow';
import {PerformanceWidgetSetting} from '../widgets/widgetDefinitions';
Expand All @@ -9,30 +11,34 @@ import {BasePerformanceViewProps} from './types';

export function FrontendPageloadView(props: BasePerformanceViewProps) {
return (
<div data-test-id="frontend-pageload-view">
<DoubleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.TPM_AREA,
PerformanceWidgetSetting.MOST_RELATED_ERRORS,
PerformanceWidgetSetting.WORST_LCP_VITALS,
]}
/>
<TripleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.P75_LCP_AREA,
PerformanceWidgetSetting.LCP_HISTOGRAM,
PerformanceWidgetSetting.FCP_HISTOGRAM,
PerformanceWidgetSetting.USER_MISERY_AREA,
PerformanceWidgetSetting.TPM_AREA,
]}
/>
<Table
{...props}
columnTitles={FRONTEND_PAGELOAD_COLUMN_TITLES}
setError={usePageError().setPageError}
/>
</div>
<PerformanceDisplayProvider
value={{performanceType: PROJECT_PERFORMANCE_TYPE.FRONTEND}}
>
<div data-test-id="frontend-pageload-view">
<TripleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.P75_LCP_AREA,
PerformanceWidgetSetting.LCP_HISTOGRAM,
PerformanceWidgetSetting.FCP_HISTOGRAM,
PerformanceWidgetSetting.USER_MISERY_AREA,
PerformanceWidgetSetting.TPM_AREA,
]}
/>
<DoubleChartRow
{...props}
allowedCharts={[
PerformanceWidgetSetting.MOST_RELATED_ERRORS,
PerformanceWidgetSetting.MOST_RELATED_ISSUES,
PerformanceWidgetSetting.WORST_LCP_VITALS,
]}
/>
<Table
{...props}
columnTitles={FRONTEND_PAGELOAD_COLUMN_TITLES}
setError={usePageError().setPageError}
/>
</div>
</PerformanceDisplayProvider>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import styled from '@emotion/styled';
import MenuItem from 'app/components/menuItem';
import {Organization} from 'app/types';
import localStorage from 'app/utils/localStorage';
import {usePerformanceDisplayType} from 'app/utils/performance/contexts/performanceDisplayContext';
import {useOrganization} from 'app/utils/useOrganization';
import withOrganization from 'app/utils/withOrganization';
import ContextMenu from 'app/views/dashboardsV2/contextMenu';
import {PROJECT_PERFORMANCE_TYPE} from 'app/views/performance/utils';

import {GenericPerformanceWidgetDataType} from '../types';
import {PerformanceWidgetSetting, WIDGET_DEFINITIONS} from '../widgetDefinitions';
Expand All @@ -29,20 +31,38 @@ type Props = {
} & ChartRowProps;

// Use local storage for chart settings for now.
const getContainerLocalStorageKey = (index: number, height: number) =>
`landing-chart-container#${height}#${index}`;
const getContainerLocalStorageObjectKey = 'landing-chart-container';
const getContainerKey = (
index: number,
performanceType: PROJECT_PERFORMANCE_TYPE,
height: number
) => `landing-chart-container#${performanceType}#${height}#${index}`;

function getWidgetStorageObject() {
const localObject = JSON.parse(
localStorage.getItem(getContainerLocalStorageObjectKey) || '{}'
);
return localObject;
}

function setWidgetStorageObject(localObject: Record<string, string>) {
localStorage.setItem(getContainerLocalStorageObjectKey, JSON.stringify(localObject));
}

const getChartSetting = (
index: number,
height: number,
performanceType: PROJECT_PERFORMANCE_TYPE,
defaultType: PerformanceWidgetSetting,
forceDefaultChartSetting?: boolean // Used for testing.
): PerformanceWidgetSetting => {
if (forceDefaultChartSetting) {
return defaultType;
}
const key = getContainerLocalStorageKey(index, height);
const value = localStorage.getItem(key);
const key = getContainerKey(index, performanceType, height);
const localObject = getWidgetStorageObject();
const value = localObject?.[key];

if (
value &&
Object.values(PerformanceWidgetSetting).includes(value as PerformanceWidgetSetting)
Expand All @@ -55,25 +75,36 @@ const getChartSetting = (
const _setChartSetting = (
index: number,
height: number,
performanceType: PROJECT_PERFORMANCE_TYPE,
setting: PerformanceWidgetSetting
) => {
const key = getContainerLocalStorageKey(index, height);
localStorage.setItem(key, setting);
const key = getContainerKey(index, performanceType, height);
const localObject = getWidgetStorageObject();
localObject[key] = setting;

setWidgetStorageObject(localObject);
};

const _WidgetContainer = (props: Props) => {
const {organization, index, chartHeight, ...rest} = props;
const _chartSetting = getChartSetting(
const {organization, index, chartHeight, allowedCharts, ...rest} = props;
const performanceType = usePerformanceDisplayType();
let _chartSetting = getChartSetting(
index,
chartHeight,
performanceType,
rest.defaultChartSetting,
rest.forceDefaultChartSetting
);

if (!allowedCharts.includes(_chartSetting)) {
_chartSetting = rest.defaultChartSetting;
}

const [chartSetting, setChartSettingState] = useState(_chartSetting);

const setChartSetting = (setting: PerformanceWidgetSetting) => {
if (!props.forceDefaultChartSetting) {
_setChartSetting(index, chartHeight, setting);
_setChartSetting(index, chartHeight, performanceType, setting);
}
setChartSettingState(setting);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface BaseChartSetting {
}

export enum PerformanceWidgetSetting {
DURATION_HISTOGRAM = 'duration_histogram',
LCP_HISTOGRAM = 'lcp_histogram',
FCP_HISTOGRAM = 'fcp_histogram',
FID_HISTOGRAM = 'fid_histogram',
Expand All @@ -43,6 +44,13 @@ export const WIDGET_DEFINITIONS: ({
}: {
organization: Organization;
}) => ({
[PerformanceWidgetSetting.DURATION_HISTOGRAM]: {
title: t('Duration Distribution'),
titleTooltip: getTermHelp(organization, PERFORMANCE_TERM.DURATION_DISTRIBUTION),
fields: ['transaction.duration'],
dataType: GenericPerformanceWidgetDataType.histogram,
chartColor: WIDGET_PALETTE[5],
},
[PerformanceWidgetSetting.LCP_HISTOGRAM]: {
title: t('LCP Distribution'),
titleTooltip: getTermHelp(organization, PERFORMANCE_TERM.DURATION_DISTRIBUTION),
Expand Down
10 changes: 5 additions & 5 deletions tests/js/spec/views/performance/landing/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ describe('Performance > Landing > Index', function () {
const titles = wrapper.find('div[data-test-id="performance-widget-title"]');
expect(titles).toHaveLength(5);

expect(titles.at(0).text()).toEqual('Transactions Per Minute');
expect(titles.at(1).text()).toEqual('Most Related Errors');
expect(titles.at(2).text()).toEqual('p75 LCP');
expect(titles.at(3).text()).toEqual('LCP Distribution');
expect(titles.at(4).text()).toEqual('FCP Distribution');
expect(titles.at(0).text()).toEqual('p75 LCP');
expect(titles.at(1).text()).toEqual('LCP Distribution');
expect(titles.at(2).text()).toEqual('FCP Distribution');
expect(titles.at(3).text()).toEqual('Most Related Errors');
expect(titles.at(4).text()).toEqual('Most Related Issues');
});

it('renders frontend other view', async function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import {mountWithTheme} from 'sentry-test/enzyme';
import {initializeData} from 'sentry-test/performance/initializePerformanceData';

import {PerformanceDisplayProvider} from 'app/utils/performance/contexts/performanceDisplayContext';
import {OrganizationContext} from 'app/views/organizationContext';
import WidgetContainer from 'app/views/performance/landing/widgets/components/widgetContainer';
import {PerformanceWidgetSetting} from 'app/views/performance/landing/widgets/widgetDefinitions';
import {PROJECT_PERFORMANCE_TYPE} from 'app/views/performance/utils';

const WrappedComponent = ({data, ...rest}) => {
return (
<OrganizationContext.Provider value={data.organization}>
<WidgetContainer
{...data}
{...rest}
allowedCharts={[
PerformanceWidgetSetting.TPM_AREA,
PerformanceWidgetSetting.FAILURE_RATE_AREA,
PerformanceWidgetSetting.USER_MISERY_AREA,
]}
forceDefaultChartSetting
/>
</OrganizationContext.Provider>
<PerformanceDisplayProvider value={{performanceType: PROJECT_PERFORMANCE_TYPE.ANY}}>
<OrganizationContext.Provider value={data.organization}>
<WidgetContainer
{...data}
{...rest}
allowedCharts={[
PerformanceWidgetSetting.TPM_AREA,
PerformanceWidgetSetting.FAILURE_RATE_AREA,
PerformanceWidgetSetting.USER_MISERY_AREA,
]}
forceDefaultChartSetting
/>
</OrganizationContext.Provider>
</PerformanceDisplayProvider>
);
};

Expand Down