|
1 |
| -import {useEffect, useState} from 'react'; |
| 1 | +import {useEffect, useRef, useState} from 'react'; |
2 | 2 | import styled from '@emotion/styled';
|
| 3 | +import type {IReactionDisposer} from 'mobx'; |
3 | 4 | import {autorun} from 'mobx';
|
4 | 5 | import {Observer} from 'mobx-react';
|
5 | 6 |
|
@@ -124,6 +125,38 @@ export function UptimeAlertForm({project, handleDelete, rule}: Props) {
|
124 | 125 | [formModel, navigate, organization, projects, rule]
|
125 | 126 | );
|
126 | 127 |
|
| 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 | + |
127 | 160 | return (
|
128 | 161 | <Form
|
129 | 162 | model={formModel}
|
@@ -325,6 +358,14 @@ export function UptimeAlertForm({project, handleDelete, rule}: Props) {
|
325 | 358 | name="name"
|
326 | 359 | label={t('Uptime rule name')}
|
327 | 360 | 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 | + }} |
328 | 369 | inline={false}
|
329 | 370 | flexibleControlStateSize
|
330 | 371 | stacked
|
|
0 commit comments