Skip to content

Commit b613ff4

Browse files
authored
feat(aci): Add issue preview to uptime monitor form (#112224)
1 parent 4ca6b21 commit b613ff4

File tree

5 files changed

+85
-5
lines changed

5 files changed

+85
-5
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {formatUptimeUrl} from 'sentry/views/detectors/components/forms/uptime/formatUptimeUrl';
2+
3+
describe('formatUptimeUrl', () => {
4+
it('returns the host when the URL has no path', () => {
5+
expect(formatUptimeUrl('https://example.com')).toBe('example.com');
6+
});
7+
8+
it('includes the path and strips a trailing slash', () => {
9+
expect(formatUptimeUrl('https://example.com/health/check/')).toBe(
10+
'example.com/health/check'
11+
);
12+
});
13+
14+
it('returns null for invalid URLs', () => {
15+
expect(formatUptimeUrl('not-a-url')).toBeNull();
16+
});
17+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Takes a full URL used by the uptime detector and formats it nicely for display purposes
3+
*
4+
* https://example.com/health/check/ -> example.com/health/check
5+
*/
6+
export function formatUptimeUrl(url: string): string | null {
7+
const parsedUrl = URL.parse(url);
8+
if (!parsedUrl?.hostname) {
9+
return null;
10+
}
11+
12+
const path = parsedUrl.pathname === '/' ? '' : parsedUrl.pathname;
13+
14+
return `${parsedUrl.hostname}${path}`.replace(/\/$/, '');
15+
}

static/app/views/detectors/components/forms/uptime/index.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ import {
2727
uptimeFormDataToEndpointPayload,
2828
uptimeSavedDetectorToFormData,
2929
} from 'sentry/views/detectors/components/forms/uptime/fields';
30+
import {formatUptimeUrl} from 'sentry/views/detectors/components/forms/uptime/formatUptimeUrl';
3031
import {PreviewSection} from 'sentry/views/detectors/components/forms/uptime/previewSection';
3132
import {UptimeRegionWarning} from 'sentry/views/detectors/components/forms/uptime/regionWarning';
3233
import {UptimeDetectorResolveSection} from 'sentry/views/detectors/components/forms/uptime/resolve';
34+
import {UptimeIssuePreview} from 'sentry/views/detectors/components/forms/uptime/uptimeIssuePreview';
3335
import {UptimeDetectorVerificationSection} from 'sentry/views/detectors/components/forms/uptime/verification';
3436

3537
const ENVIRONMENT_CONFIG: EnvironmentConfig = {
@@ -49,14 +51,11 @@ function UptimeDetectorForm() {
4951
return null;
5052
}
5153

52-
const parsedUrl = URL.parse(url);
53-
if (!parsedUrl) {
54+
const urlName = formatUptimeUrl(url);
55+
if (!urlName) {
5456
return null;
5557
}
5658

57-
const path = parsedUrl.pathname === '/' ? '' : parsedUrl.pathname;
58-
const urlName = `${parsedUrl.hostname}${path}`.replace(/\/$/, '');
59-
6059
return t('Uptime check for %s', urlName);
6160
});
6261

@@ -70,6 +69,7 @@ function UptimeDetectorForm() {
7069
<UptimeDetectorResolveSection step={nextStep()} />
7170
<AssignSection step={nextStep()} />
7271
<DescribeSection step={nextStep()} />
72+
<UptimeIssuePreview step={nextStep()} />
7373
<AutomateSection step={nextStep()} />
7474
</Stack>
7575
);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {t} from 'sentry/locale';
2+
import {DetectorIssuePreview} from 'sentry/views/detectors/components/forms/common/detectorIssuePreview';
3+
import {IssuePreviewSection} from 'sentry/views/detectors/components/forms/common/issuePreviewSection';
4+
import {ownerToActor} from 'sentry/views/detectors/components/forms/common/ownerToActor';
5+
import {useDetectorFormContext} from 'sentry/views/detectors/components/forms/context';
6+
import {useUptimeDetectorFormField} from 'sentry/views/detectors/components/forms/uptime/fields';
7+
import {formatUptimeUrl} from 'sentry/views/detectors/components/forms/uptime/formatUptimeUrl';
8+
9+
const FALLBACK_ISSUE_TITLE = t('Downtime detected for …');
10+
const SUBTITLE = t('Your monitored domain is down');
11+
12+
function useUptimeIssueTitle() {
13+
const url = useUptimeDetectorFormField('url');
14+
15+
if (!url) {
16+
return FALLBACK_ISSUE_TITLE;
17+
}
18+
19+
const displayUrl = formatUptimeUrl(url);
20+
if (!displayUrl) {
21+
return FALLBACK_ISSUE_TITLE;
22+
}
23+
24+
return t('Downtime detected for %s', displayUrl);
25+
}
26+
27+
export function UptimeIssuePreview({step}: {step?: number}) {
28+
const owner = useUptimeDetectorFormField('owner');
29+
const issueTitle = useUptimeIssueTitle();
30+
const assignee = ownerToActor(owner);
31+
const {project} = useDetectorFormContext();
32+
33+
return (
34+
<IssuePreviewSection step={step}>
35+
<DetectorIssuePreview
36+
issueTitle={issueTitle}
37+
subtitle={SUBTITLE}
38+
assignee={assignee}
39+
project={project}
40+
/>
41+
</IssuePreviewSection>
42+
);
43+
}

static/app/views/detectors/new-setting.spec.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,11 @@ describe('DetectorEdit', () => {
957957
await userEvent.click(bodyInput);
958958
await userEvent.paste('{"test": "data"}');
959959

960+
// Issue preview reflects the URL
961+
expect(
962+
screen.getByText('Downtime detected for uptime.example.com')
963+
).toBeInTheDocument();
964+
960965
await selectEvent.openMenu(screen.getByLabelText('Select Environment'));
961966
expect(
962967
screen.queryByRole('menuitemradio', {name: 'All Environments'})

0 commit comments

Comments
 (0)