Skip to content

Commit 9d099ed

Browse files
committed
✨ Implement settings page change for modifying highlights
1 parent 32518b3 commit 9d099ed

File tree

4 files changed

+108
-29
lines changed

4 files changed

+108
-29
lines changed

static/app/components/events/contexts/index.tsx

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,38 @@ type Props = {
1616
group?: Group;
1717
};
1818

19+
type ContextValueType = any;
20+
21+
export function getOrderedContextItems(event): [string, ContextValueType][] {
22+
const {user, contexts} = event;
23+
24+
const {feedback, response, ...otherContexts} = contexts ?? {};
25+
const orderedContext: [string, ContextValueType][] = [
26+
['response', response],
27+
['feedback', feedback],
28+
['user', user],
29+
...Object.entries(otherContexts),
30+
];
31+
// For these context keys, use 'key' as 'type' rather than 'value.type'
32+
const overrideTypes = new Set(['response', 'feedback', 'user']);
33+
const items = orderedContext
34+
.filter(([_k, v]) => {
35+
const contextKeys = Object.keys(v ?? {});
36+
const isInvalid =
37+
// Empty context
38+
contextKeys.length === 0 ||
39+
// Empty aside from 'type' key
40+
(contextKeys.length === 1 && contextKeys[0] === 'type');
41+
return !isInvalid;
42+
})
43+
.map<[string, ContextValueType]>(([alias, ctx]) => [
44+
alias,
45+
{...ctx, type: overrideTypes.has(ctx.type) ? ctx : ctx?.type ?? alias},
46+
]);
47+
48+
return items;
49+
}
50+
1951
export function EventContexts({event, group}: Props) {
2052
const hasNewTagsUI = useHasNewTagsUI();
2153
const {projects} = useProjects();
@@ -39,35 +71,17 @@ export function EventContexts({event, group}: Props) {
3971
}, [usingOtel, sdk]);
4072

4173
if (hasNewTagsUI) {
42-
const orderedContext: [string, any][] = [
43-
['response', response],
44-
['feedback', feedback],
45-
['user', user],
46-
...Object.entries(otherContexts),
47-
];
48-
// For these context keys, use 'key' as 'type' rather than 'value.type'
49-
const overrideTypes = new Set(['response', 'feedback', 'user']);
50-
const cards = orderedContext
51-
.filter(([_k, v]) => {
52-
const contextKeys = Object.keys(v ?? {});
53-
const isInvalid =
54-
// Empty context
55-
contextKeys.length === 0 ||
56-
// Empty aside from 'type' key
57-
(contextKeys.length === 1 && contextKeys[0] === 'type');
58-
return !isInvalid;
59-
})
60-
.map(([k, v]) => (
61-
<ContextCard
62-
key={k}
63-
type={overrideTypes.has(k) ? k : v?.type ?? ''}
64-
alias={k}
65-
value={v}
66-
event={event}
67-
group={group}
68-
project={project}
69-
/>
70-
));
74+
const cards = getOrderedContextItems(event).map(([alias, contextValue]) => (
75+
<ContextCard
76+
key={alias}
77+
type={contextValue.type}
78+
alias={alias}
79+
value={contextValue}
80+
event={event}
81+
group={group}
82+
project={project}
83+
/>
84+
));
7185

7286
return <ContextDataSection cards={cards} />;
7387
}

static/app/data/forms/projectGeneralSettings.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import {createFilter} from 'react-select';
22
import styled from '@emotion/styled';
33
import {PlatformIcon} from 'platformicons';
44

5+
import {CONTEXT_DOCS_LINK} from 'sentry/components/events/contextSummary/utils';
6+
import {TAGS_DOCS_LINK} from 'sentry/components/events/eventTags/util';
57
import type {Field} from 'sentry/components/forms/types';
8+
import ExternalLink from 'sentry/components/links/externalLink';
69
import platforms from 'sentry/data/platforms';
710
import {t, tct, tn} from 'sentry/locale';
811
import {space} from 'sentry/styles/space';
@@ -89,6 +92,40 @@ export const fields: Record<string, Field> = {
8992
},
9093
}),
9194
},
95+
highlightTags: {
96+
name: 'highlightTags',
97+
type: 'string',
98+
multiline: true,
99+
autosize: true,
100+
rows: 1,
101+
placeholder: t('handled, environment, release, my-tag'),
102+
label: t('Highlighted Tags'),
103+
help: tct(
104+
'[link:Tags] to promote to the top of each issue page for quick debugging. Separate entries with a newline.',
105+
{
106+
link: <ExternalLink openInNewTab href={TAGS_DOCS_LINK} />,
107+
}
108+
),
109+
getValue: val => extractMultilineFields(val),
110+
setValue: val => convertMultilineFieldValue(val),
111+
},
112+
highlightContext: {
113+
name: 'highlightContext',
114+
type: 'string',
115+
multiline: true,
116+
autosize: true,
117+
rows: 1,
118+
placeholder: t('browser, runtime, user, my-context'),
119+
label: t('Highlighted Context'),
120+
help: tct(
121+
'[link:Structured context] to promote to the top of each issue page for quick debugging. Separate entries with a newline.',
122+
{
123+
link: <ExternalLink openInNewTab href={CONTEXT_DOCS_LINK} />,
124+
}
125+
),
126+
getValue: val => extractMultilineFields(val),
127+
setValue: val => convertMultilineFieldValue(val),
128+
},
92129

93130
subjectPrefix: {
94131
name: 'subjectPrefix',

static/app/types/project.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ export type Project = {
5959
builtinSymbolSources?: string[];
6060
defaultEnvironment?: string;
6161
hasUserReports?: boolean;
62+
highlightContext?: string[];
63+
highlightTags?: string[];
6264
latestDeploys?: Record<string, Pick<Deploy, 'dateFinished' | 'version'>> | null;
6365
latestRelease?: {version: string} | null;
6466
options?: Record<string, boolean | string>;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type {Project} from 'sentry/types';
2+
import {
3+
type ApiQueryKey,
4+
useApiQuery,
5+
type UseApiQueryOptions,
6+
} from 'sentry/utils/queryClient';
7+
8+
interface DetailedProjectParameters {
9+
orgSlug: string;
10+
projectSlug: string;
11+
}
12+
13+
export const makeDetailedProjectQueryKey = ({
14+
orgSlug,
15+
projectSlug,
16+
}: DetailedProjectParameters): ApiQueryKey => [`/projects/${orgSlug}/${projectSlug}/`];
17+
18+
export function useDetailedProject(
19+
params: DetailedProjectParameters,
20+
options: Partial<UseApiQueryOptions<Project>> = {}
21+
) {
22+
return useApiQuery<Project>(makeDetailedProjectQueryKey(params), {
23+
staleTime: Infinity,
24+
...options,
25+
});
26+
}

0 commit comments

Comments
 (0)