-
-
Couldn't load subscription status.
- Fork 4.5k
feat(project-creation): Replace input text with select to list integration channels #101403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4397a7a
16769df
280d89c
6739e23
6f28480
adec286
fb40b9a
ba2245d
cfc551c
981ee3c
9609715
1488f2a
9405bbe
f016f7f
f1fadad
c41c910
59e57b0
796e708
705773e
8785006
52c4a08
e8db15e
6654245
698d801
7e40f21
8a88a65
0dd0396
c6696cb
b2ec59b
91e3e72
dfc98cd
a158e10
e87dca6
2dcf341
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,7 @@ import {useTeams} from 'sentry/utils/useTeams'; | |
| import { | ||
| MultipleCheckboxOptions, | ||
| useCreateNotificationAction, | ||
| type IntegrationChannel, | ||
| } from 'sentry/views/projectInstall/issueAlertNotificationOptions'; | ||
| import type { | ||
| AlertRuleOptions, | ||
|
|
@@ -53,6 +54,7 @@ import type { | |
| import IssueAlertOptions, { | ||
| getRequestDataFragment, | ||
| } from 'sentry/views/projectInstall/issueAlertOptions'; | ||
| import {useValidateChannel} from 'sentry/views/projectInstall/useValidateChannel'; | ||
| import {makeProjectsPathname} from 'sentry/views/projects/pathname'; | ||
|
|
||
| type FormData = { | ||
|
|
@@ -82,7 +84,7 @@ function getMissingValues({ | |
| isOrgMemberWithNoAccess: boolean; | ||
| notificationProps: { | ||
| actions?: string[]; | ||
| channel?: string; | ||
| channel?: IntegrationChannel; | ||
| }; | ||
| projectName: string; | ||
| team: string | undefined; | ||
|
|
@@ -130,6 +132,7 @@ function getSubmitTooltipText({ | |
| if (isMissingPlatform) { | ||
| return t('Please select a platform'); | ||
| } | ||
|
|
||
| return t('Please select a team'); | ||
| } | ||
|
|
||
|
|
@@ -141,6 +144,7 @@ export function CreateProject() { | |
| const location = useLocation(); | ||
| const canUserCreateProject = useCanCreateProject(); | ||
| const createProjectAndRules = useCreateProjectAndRules(); | ||
|
|
||
| const {teams} = useTeams(); | ||
| const accessTeams = teams.filter((team: Team) => team.access.includes('team:admin')); | ||
| const referrer = decodeScalar(location.query.referrer); | ||
|
|
@@ -163,6 +167,12 @@ export function CreateProject() { | |
| createNotificationActionParam | ||
| ); | ||
|
|
||
| const validateChannel = useValidateChannel({ | ||
| channel: notificationProps.channel, | ||
| integrationId: notificationProps.integration?.id, | ||
| enabled: false, | ||
| }); | ||
|
|
||
| const defaultTeam = accessTeams?.[0]?.slug; | ||
|
|
||
| const initialData: FormData = useMemo(() => { | ||
|
|
@@ -204,18 +214,26 @@ export function CreateProject() { | |
| platform: formData.platform, | ||
| }); | ||
|
|
||
| const isNotifyingViaIntegration = | ||
| alertRuleConfig.shouldCreateRule && | ||
| notificationProps.actions?.includes(MultipleCheckboxOptions.INTEGRATION); | ||
|
|
||
| const formErrorCount = [ | ||
| missingValues.isMissingPlatform, | ||
| missingValues.isMissingTeam, | ||
| missingValues.isMissingProjectName, | ||
| missingValues.isMissingAlertThreshold, | ||
| missingValues.isMissingMessagingIntegrationChannel, | ||
| isNotifyingViaIntegration && validateChannel.error, | ||
| ].filter(value => value).length; | ||
|
|
||
| const submitTooltipText = getSubmitTooltipText({ | ||
| ...missingValues, | ||
| formErrorCount, | ||
| }); | ||
| const submitTooltipText = | ||
| isNotifyingViaIntegration && validateChannel.error | ||
| ? validateChannel.error | ||
| : getSubmitTooltipText({ | ||
| ...missingValues, | ||
| formErrorCount, | ||
| }); | ||
|
|
||
| const updateFormData = useCallback( | ||
| <K extends keyof FormData>(field: K, value: FormData[K]) => { | ||
|
|
@@ -557,16 +575,25 @@ export function CreateProject() { | |
| <Tooltip | ||
| title={ | ||
| canUserCreateProject | ||
| ? submitTooltipText | ||
| ? isNotifyingViaIntegration && validateChannel.isFetching | ||
| ? t('Validating integration channel\u2026') | ||
| : submitTooltipText | ||
| : t('You do not have permission to create projects') | ||
| } | ||
| disabled={formErrorCount === 0 && canUserCreateProject} | ||
| disabled={ | ||
| formErrorCount === 0 && | ||
| canUserCreateProject && | ||
| !(isNotifyingViaIntegration && validateChannel.isFetching) | ||
| } | ||
| > | ||
| <Button | ||
| data-test-id="create-project" | ||
| priority="primary" | ||
| disabled={!(canUserCreateProject && formErrorCount === 0)} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the button is 'busy' by clicking on it doesn't submit the form - I tested. |
||
| busy={createProjectAndRules.isPending} | ||
| busy={ | ||
| createProjectAndRules.isPending || | ||
| (isNotifyingViaIntegration && validateChannel.isFetching) | ||
| } | ||
| onClick={() => debounceHandleProjectCreation(formData)} | ||
| > | ||
| {t('Create Project')} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Channel Validation Hook Initialization Issue
The
useValidateChannelhook increateProject.tsxis initialized withenabled: false, preventing channel validation from running. The form's validation logic and submit button state, which rely onvalidateChannel.errorandisFetching, therefore don't reflect actual channel validation. This can allow invalid integration channels to be submitted or misrepresent validation status in the UI.