Skip to content

Commit 9dc81c5

Browse files
DominikB2014andrewshie-sentry
authored andcommitted
feat(insights): add smaller issues widget (#97608)
Adds a smaller issues widget to the modern frontend overview page, this is so the issues widget feels more balanced and doesn't consume 2/3 of the row. Note: More styling adjustments (the slightly taller widget size) and "open in issues" context menu to be addressed in a follow up PR <img width="1211" height="730" alt="image" src="https://github.com/user-attachments/assets/82f29d08-fa5a-485b-bb67-b4962c5ca141" />
1 parent ede8bad commit 9dc81c5

File tree

5 files changed

+89
-16
lines changed

5 files changed

+89
-16
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type {
2+
TabularColumn,
3+
TabularMeta,
4+
} from 'sentry/views/dashboards/widgets/common/types';
5+
import {TableWidgetVisualization} from 'sentry/views/dashboards/widgets/tableWidget/tableWidgetVisualization';
6+
import {useErrors} from 'sentry/views/insights/common/queries/useDiscover';
7+
import {ErrorField} from 'sentry/views/insights/types';
8+
9+
const columns: TabularColumn[] = [
10+
{key: 'issue', sortable: false},
11+
{key: 'title', sortable: false},
12+
{key: 'count()', sortable: false},
13+
];
14+
15+
export function OverviewIssuesWidget() {
16+
const {data, meta, isLoading} = useErrors(
17+
{
18+
fields: [ErrorField.ISSUE, ErrorField.TITLE, 'count()'],
19+
sorts: [{field: 'count()', kind: 'desc'}],
20+
limit: 6,
21+
},
22+
'api.insights.overview-issues-widget'
23+
);
24+
25+
if (isLoading) {
26+
return <TableWidgetVisualization.LoadingPlaceholder columns={columns} />;
27+
}
28+
29+
const tableData = {
30+
data,
31+
meta: {fields: {...meta?.fields}, units: {...meta?.units}} as TabularMeta, // TODO: ideally this is properly typed, but EventsMeta doesn't match TabularMeta even tho they seem like they should
32+
};
33+
34+
return <TableWidgetVisualization tableData={tableData} columns={columns} />;
35+
}

static/app/views/insights/common/queries/useDiscover.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import {
99
useWrappedDiscoverQuery,
1010
useWrappedDiscoverQueryWithoutPageFilters,
1111
} from 'sentry/views/insights/common/queries/useSpansQuery';
12-
import type {SpanProperty, SpanResponse} from 'sentry/views/insights/types';
12+
import type {
13+
ErrorProperty,
14+
ErrorResponse,
15+
SpanProperty,
16+
SpanResponse,
17+
} from 'sentry/views/insights/types';
1318

1419
interface UseDiscoverQueryOptions {
1520
additonalQueryKey?: string[];
@@ -49,6 +54,13 @@ export const useSpans = <Fields extends SpanProperty[]>(
4954
return useDiscover<Fields, SpanResponse>(options, DiscoverDatasets.SPANS, referrer);
5055
};
5156

57+
export const useErrors = <Fields extends ErrorProperty[]>(
58+
options: UseDiscoverOptions<Fields> = {},
59+
referrer: string
60+
) => {
61+
return useDiscover<Fields, ErrorResponse>(options, DiscoverDatasets.ERRORS, referrer);
62+
};
63+
5264
const useDiscover = <T extends Array<Extract<keyof ResponseType, string>>, ResponseType>(
5365
options: UseDiscoverOptions<T> = {},
5466
dataset: DiscoverDatasets,

static/app/views/insights/pages/backend/backendOverviewPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ const StyledTransactionNameSearchBar = styled(TransactionNameSearchBar)`
269269

270270
export default BackendOverviewPageWithProviders;
271271

272-
export const StackedWidgetWrapper = styled('div')`
272+
const StackedWidgetWrapper = styled('div')`
273273
display: flex;
274274
flex-direction: column;
275275
gap: ${space(2)};

static/app/views/insights/pages/frontend/newFrontendOverviewPage.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import useOrganization from 'sentry/utils/useOrganization';
2222
import usePageFilters from 'sentry/utils/usePageFilters';
2323
import useProjects from 'sentry/utils/useProjects';
2424
import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout';
25+
import {OverviewIssuesWidget} from 'sentry/views/insights/common/components/overviewIssuesWidget';
2526
import {InsightsProjectSelector} from 'sentry/views/insights/common/components/projectSelector';
2627
import {ToolRibbon} from 'sentry/views/insights/common/components/ribbon';
2728
import {STARRED_SEGMENT_TABLE_QUERY_KEY} from 'sentry/views/insights/common/components/tableCells/starredSegmentCell';
@@ -32,10 +33,7 @@ import OverviewTransactionThroughputChartWidget from 'sentry/views/insights/comm
3233
import {useSpans} from 'sentry/views/insights/common/queries/useDiscover';
3334
import {useOnboardingProject} from 'sentry/views/insights/common/queries/useOnboardingProject';
3435
import {QueryParameterNames} from 'sentry/views/insights/common/views/queryParameters';
35-
import {
36-
StackedWidgetWrapper,
37-
TripleRowWidgetWrapper,
38-
} from 'sentry/views/insights/pages/backend/backendOverviewPage';
36+
import {TripleRowWidgetWrapper} from 'sentry/views/insights/pages/backend/backendOverviewPage';
3937
import {
4038
FrontendOverviewTable,
4139
isAValidSort,
@@ -53,7 +51,6 @@ import {
5351
import {useFrontendQuery} from 'sentry/views/insights/pages/frontend/useFrontendQuery';
5452
import {InsightsSpanTagProvider} from 'sentry/views/insights/pages/insightsSpanTagProvider';
5553
import {WebVitalsWidget} from 'sentry/views/insights/pages/platform/nextjs/webVitalsWidget';
56-
import {IssuesWidget} from 'sentry/views/insights/pages/platform/shared/issuesWidget';
5754
import {TransactionNameSearchBar} from 'sentry/views/insights/pages/transactionNameSearchBar';
5855
import {useOverviewPageTrackPageload} from 'sentry/views/insights/pages/useOverviewPageTrackAnalytics';
5956
import {categorizeProjects} from 'sentry/views/insights/pages/utils';
@@ -209,15 +206,19 @@ export function NewFrontendOverviewPage() {
209206
<LegacyOnboarding project={onboardingProject} organization={organization} />
210207
) : (
211208
<Fragment>
212-
<ModuleLayout.Third>
213-
<StackedWidgetWrapper>
214-
<OverviewTransactionThroughputChartWidget />
215-
<OverviewTransactionDurationChartWidget />
216-
</StackedWidgetWrapper>
217-
</ModuleLayout.Third>
218-
<ModuleLayout.TwoThirds>
219-
<IssuesWidget />
220-
</ModuleLayout.TwoThirds>
209+
<ModuleLayout.Full>
210+
<TripleRowWidgetWrapper>
211+
<ModuleLayout.Third>
212+
<OverviewTransactionThroughputChartWidget />
213+
</ModuleLayout.Third>
214+
<ModuleLayout.Third>
215+
<OverviewTransactionDurationChartWidget />
216+
</ModuleLayout.Third>
217+
<ModuleLayout.Third>
218+
<OverviewIssuesWidget />
219+
</ModuleLayout.Third>
220+
</TripleRowWidgetWrapper>
221+
</ModuleLayout.Full>
221222
<ModuleLayout.Full>
222223
<TripleRowWidgetWrapper>
223224
<ModuleLayout.Third>

static/app/views/insights/types.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,31 @@ export type SpanQueryFilters = Partial<Record<SpanStringFields, string>> & {
508508
[SpanFields.PROJECT_ID]?: string;
509509
};
510510

511+
export enum ErrorField {
512+
ISSUE = 'issue',
513+
TITLE = 'title',
514+
}
515+
516+
enum ErrorFunction {
517+
COUNT = 'count',
518+
}
519+
520+
type ErrorStringFields = ErrorField.TITLE;
521+
type ErrorNumberFields = ErrorField.ISSUE;
522+
523+
type NoArgErrorFunction = ErrorFunction.COUNT;
524+
525+
type ErrorResponseRaw = {
526+
[Property in ErrorStringFields as `${Property}`]: string;
527+
} & {
528+
[Property in ErrorNumberFields as `${Property}`]: number;
529+
} & {
530+
[Property in NoArgErrorFunction as `${Property}()`]: number;
531+
};
532+
533+
export type ErrorResponse = Flatten<ErrorResponseRaw>;
534+
export type ErrorProperty = keyof ErrorResponse;
535+
511536
// Maps the subregion code to the subregion name according to UN m49 standard
512537
// We also define this in relay in `country_subregion.rs`
513538
export const subregionCodeToName = {

0 commit comments

Comments
 (0)