Skip to content

Commit 329e27b

Browse files
feat(uptime): Set default name from url (#95164)
Split out and added a test from #93042
1 parent 15a103b commit 329e27b

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,4 +342,21 @@ describe('Uptime Alert Form', function () {
342342
})
343343
);
344344
});
345+
346+
it('sets a default name from the url', async function () {
347+
render(<UptimeAlertForm organization={organization} project={project} />, {
348+
organization,
349+
});
350+
await userEvent.clear(input('URL'));
351+
await userEvent.type(input('URL'), 'http://my-cool-site.com/');
352+
353+
const simpleName = input('Uptime rule name');
354+
expect(simpleName).toHaveValue('Uptime check for my-cool-site.com');
355+
356+
await userEvent.clear(input('URL'));
357+
await userEvent.type(input('URL'), 'http://example.com/with-path');
358+
359+
const pathName = input('Uptime rule name');
360+
expect(pathName).toHaveValue('Uptime check for example.com/with-path');
361+
});
345362
});

static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import {useEffect, useState} from 'react';
1+
import {useEffect, useRef, useState} from 'react';
22
import styled from '@emotion/styled';
3+
import type {IReactionDisposer} from 'mobx';
34
import {autorun} from 'mobx';
45
import {Observer} from 'mobx-react';
56

@@ -124,6 +125,38 @@ export function UptimeAlertForm({project, handleDelete, rule}: Props) {
124125
[formModel, navigate, organization, projects, rule]
125126
);
126127

128+
// When mutating the name field manually, we'll disable automatic name
129+
// generation from the URL
130+
const [hasCustomName, setHasCustomName] = useState(false);
131+
const disposeNameSetter = useRef<IReactionDisposer>(null);
132+
const hasRule = !!rule;
133+
134+
// Suggest rule name from URL
135+
useEffect(() => {
136+
if (hasRule || hasCustomName) {
137+
return () => {};
138+
}
139+
disposeNameSetter.current = autorun(() => {
140+
const url = formModel.getValue('url');
141+
142+
if (typeof url !== 'string') {
143+
return;
144+
}
145+
146+
try {
147+
const parsedUrl = new URL(url);
148+
const path = parsedUrl.pathname === '/' ? '' : parsedUrl.pathname;
149+
const urlName = `${parsedUrl.hostname}${path}`.replace(/\/$/, '');
150+
151+
formModel.setValue('name', t('Uptime check for %s', urlName));
152+
} catch {
153+
// Nothing to do if we failed to parse the URL
154+
}
155+
});
156+
157+
return disposeNameSetter.current;
158+
}, [formModel, hasRule, hasCustomName]);
159+
127160
return (
128161
<Form
129162
model={formModel}
@@ -325,6 +358,14 @@ export function UptimeAlertForm({project, handleDelete, rule}: Props) {
325358
name="name"
326359
label={t('Uptime rule name')}
327360
placeholder={t('Uptime rule name')}
361+
onChange={() => {
362+
// Immediately dispose of the autorun name setter, since it won't
363+
// receive the hasCustomName state before the autorun is ran
364+
// again after this change (overriding whatever change the user
365+
// just made)
366+
disposeNameSetter.current?.();
367+
setHasCustomName(true);
368+
}}
328369
inline={false}
329370
flexibleControlStateSize
330371
stacked

0 commit comments

Comments
 (0)