1
1
import { useCallback , useEffect , useMemo , useState } from 'react' ;
2
2
import styled from '@emotion/styled' ;
3
3
import * as Sentry from '@sentry/react' ;
4
+ import debounce from 'lodash/debounce' ;
4
5
import omit from 'lodash/omit' ;
5
6
import startCase from 'lodash/startCase' ;
6
7
import { PlatformIcon } from 'platformicons' ;
@@ -18,8 +19,7 @@ import ExternalLink from 'sentry/components/links/externalLink';
18
19
import List from 'sentry/components/list' ;
19
20
import ListItem from 'sentry/components/list/listItem' ;
20
21
import { SupportedLanguages } from 'sentry/components/onboarding/frameworkSuggestionModal' ;
21
- import { useCreateProject } from 'sentry/components/onboarding/useCreateProject' ;
22
- import { useCreateProjectRules } from 'sentry/components/onboarding/useCreateProjectRules' ;
22
+ import { useCreateProjectAndRules } from 'sentry/components/onboarding/useCreateProjectAndRules' ;
23
23
import type { Platform } from 'sentry/components/platformPicker' ;
24
24
import PlatformPicker from 'sentry/components/platformPicker' ;
25
25
import TeamSelector from 'sentry/components/teamSelector' ;
@@ -140,8 +140,7 @@ export function CreateProject() {
140
140
const location = useLocation ( ) ;
141
141
const { createNotificationAction, notificationProps} = useCreateNotificationAction ( ) ;
142
142
const canUserCreateProject = useCanCreateProject ( ) ;
143
- const createProject = useCreateProject ( ) ;
144
- const createProjectRules = useCreateProjectRules ( ) ;
143
+ const createProjectAndRules = useCreateProjectAndRules ( ) ;
145
144
const { teams} = useTeams ( ) ;
146
145
const accessTeams = teams . filter ( ( team : Team ) => team . access . includes ( 'team:admin' ) ) ;
147
146
const referrer = decodeScalar ( location . query . referrer ) ;
@@ -151,44 +150,6 @@ export function CreateProject() {
151
150
null
152
151
) ;
153
152
154
- const createRules = useCallback (
155
- async ( {
156
- project,
157
- alertRuleConfig,
158
- } : { project : Project } & Pick < FormData , 'alertRuleConfig' > ) => {
159
- const ruleIds = [ ] ;
160
-
161
- if ( alertRuleConfig ?. shouldCreateCustomRule ) {
162
- const ruleData = await createProjectRules . mutateAsync ( {
163
- projectSlug : project . slug ,
164
- name : project . name ,
165
- conditions : alertRuleConfig ?. conditions ,
166
- actions : alertRuleConfig ?. actions ,
167
- actionMatch : alertRuleConfig ?. actionMatch ,
168
- frequency : alertRuleConfig ?. frequency ,
169
- } ) ;
170
-
171
- ruleIds . push ( ruleData . id ) ;
172
- }
173
-
174
- const notificationRule = await createNotificationAction ( {
175
- shouldCreateRule : alertRuleConfig ?. shouldCreateRule ,
176
- name : project . name ,
177
- projectSlug : project . slug ,
178
- conditions : alertRuleConfig ?. conditions ,
179
- actionMatch : alertRuleConfig ?. actionMatch ,
180
- frequency : alertRuleConfig ?. frequency ,
181
- } ) ;
182
-
183
- if ( notificationRule ) {
184
- ruleIds . push ( notificationRule . id ) ;
185
- }
186
-
187
- return ruleIds ;
188
- } ,
189
- [ createNotificationAction , createProjectRules ]
190
- ) ;
191
-
192
153
const autoFill = useMemo ( ( ) => {
193
154
return referrer === 'getting-started' && projectId === createdProject ?. id ;
194
155
} , [ referrer , projectId , createdProject ?. id ] ) ;
@@ -235,9 +196,6 @@ export function CreateProject() {
235
196
missingValues . isMissingMessagingIntegrationChannel ,
236
197
] . filter ( value => value ) . length ;
237
198
238
- const canSubmitForm =
239
- ! createProject . isPending && canUserCreateProject && formErrorCount === 0 ;
240
-
241
199
const submitTooltipText = getSubmitTooltipText ( {
242
200
...missingValues ,
243
201
formErrorCount,
@@ -284,17 +242,15 @@ export function CreateProject() {
284
242
let projectToRollback : Project | undefined ;
285
243
286
244
try {
287
- const project = await createProject . mutateAsync ( {
288
- name : projectName ,
245
+ const { project, ruleIds } = await createProjectAndRules . mutateAsync ( {
246
+ projectName,
289
247
platform : selectedPlatform ,
290
- default_rules : alertRuleConfig ?. defaultRules ?? true ,
291
- firstTeamSlug : team ,
248
+ team,
249
+ alertRuleConfig,
250
+ createNotificationAction,
292
251
} ) ;
293
-
294
252
projectToRollback = project ;
295
253
296
- const ruleIds = await createRules ( { project, alertRuleConfig} ) ;
297
-
298
254
trackAnalytics ( 'project_creation_page.created' , {
299
255
organization,
300
256
issue_alert : alertRuleConfig ?. defaultRules
@@ -373,11 +329,20 @@ export function CreateProject() {
373
329
}
374
330
}
375
331
} ,
376
- [ createRules , organization , createProject , setCreatedProject , navigate , api ]
332
+ [
333
+ organization ,
334
+ setCreatedProject ,
335
+ navigate ,
336
+ api ,
337
+ createProjectAndRules ,
338
+ createNotificationAction ,
339
+ ]
377
340
) ;
378
341
379
342
const handleProjectCreation = useCallback (
380
343
async ( data : FormData ) => {
344
+ setErrors ( undefined ) ;
345
+
381
346
const selectedPlatform = data . platform ;
382
347
383
348
if ( ! isNotPartialPlatform ( selectedPlatform ) ) {
@@ -428,6 +393,11 @@ export function CreateProject() {
428
393
[ configurePlatform , organization ]
429
394
) ;
430
395
396
+ const debounceHandleProjectCreation = useMemo (
397
+ ( ) => debounce ( handleProjectCreation , 2000 , { leading : true , trailing : false } ) ,
398
+ [ handleProjectCreation ]
399
+ ) ;
400
+
431
401
const handlePlatformChange = useCallback (
432
402
( value : Platform | null ) => {
433
403
if ( ! value ) {
@@ -549,8 +519,9 @@ export function CreateProject() {
549
519
< Button
550
520
data-test-id = "create-project"
551
521
priority = "primary"
552
- disabled = { ! canSubmitForm }
553
- onClick = { ( ) => handleProjectCreation ( formData ) }
522
+ disabled = { ! ( canUserCreateProject && formErrorCount === 0 ) }
523
+ busy = { createProjectAndRules . isPending }
524
+ onClick = { ( ) => debounceHandleProjectCreation ( formData ) }
554
525
>
555
526
{ t ( 'Create Project' ) }
556
527
</ Button >
0 commit comments