diff --git a/static/app/components/onboarding/useCreateProject.ts b/static/app/components/onboarding/useCreateProject.ts index 73df713f5238bb..d9ab0f6d95932e 100644 --- a/static/app/components/onboarding/useCreateProject.ts +++ b/static/app/components/onboarding/useCreateProject.ts @@ -7,10 +7,13 @@ import useApi from 'sentry/utils/useApi'; import useOrganization from 'sentry/utils/useOrganization'; interface Variables { - platform: OnboardingSelectedSDK; default_rules?: boolean; firstTeamSlug?: string; name?: string; + /** + * If no platform is provided, the project will be created with the 'other' platform + */ + platform?: OnboardingSelectedSDK; } export function useCreateProject() { @@ -26,7 +29,7 @@ export function useCreateProject() { { method: 'POST', data: { - platform: platform.key, + platform: platform?.key, name, default_rules: default_rules ?? true, origin: 'ui', diff --git a/static/app/components/onboarding/useCreateProjectAndRules.ts b/static/app/components/onboarding/useCreateProjectAndRules.ts index 9f292a41406694..d3cbb93b607c32 100644 --- a/static/app/components/onboarding/useCreateProjectAndRules.ts +++ b/static/app/components/onboarding/useCreateProjectAndRules.ts @@ -16,8 +16,8 @@ type Variables = { createNotificationAction: ReturnType< typeof useCreateNotificationAction >['createNotificationAction']; - platform: OnboardingSelectedSDK; projectName: string; + platform?: OnboardingSelectedSDK; team?: string; }; diff --git a/static/app/types/onboarding.tsx b/static/app/types/onboarding.tsx index 9ce9e23dcf5d4a..d17b404d12c509 100644 --- a/static/app/types/onboarding.tsx +++ b/static/app/types/onboarding.tsx @@ -109,8 +109,8 @@ export interface UpdatedTask extends Partial { - category: Category; key: PlatformKey; + category?: Category; } export type OnboardingRecentCreatedProject = { diff --git a/static/app/utils/platform.tsx b/static/app/utils/platform.tsx index 00976ce106dd2e..7f84374c2280d3 100644 --- a/static/app/utils/platform.tsx +++ b/static/app/utils/platform.tsx @@ -1,4 +1,3 @@ -import type {Platform} from 'sentry/components/platformPicker'; import { backend, desktop, @@ -8,7 +7,7 @@ import { PlatformCategory, serverless, } from 'sentry/data/platformCategories'; -import type {PlatformKey} from 'sentry/types/project'; +import type {PlatformIntegration, PlatformKey} from 'sentry/types/project'; /** * @@ -72,7 +71,7 @@ export function isDisabledGamingPlatform({ platform, enabledConsolePlatforms, }: { - platform: Platform; + platform: PlatformIntegration; enabledConsolePlatforms?: string[]; }) { return platform.type === 'console' && !enabledConsolePlatforms?.includes(platform.id); diff --git a/static/app/views/projectInstall/createProject.spec.tsx b/static/app/views/projectInstall/createProject.spec.tsx index 47980cdcfb3552..ad33e1389da31d 100644 --- a/static/app/views/projectInstall/createProject.spec.tsx +++ b/static/app/views/projectInstall/createProject.spec.tsx @@ -455,5 +455,27 @@ describe('CreateProject', () => { }) ); }); + + it("should create 'other' platform if no platform is selected", async () => { + const {projectCreationMockRequest} = renderFrameworkModalMockRequests({ + organization, + teamSlug: teamWithAccess.slug, + }); + render(, {organization}); + expect(screen.getByRole('button', {name: 'Create Project'})).toBeDisabled(); + await userEvent.type(screen.getByPlaceholderText('project-name'), 'my-project'); + expect(screen.getByRole('button', {name: 'Create Project'})).toBeEnabled(); + await userEvent.click(screen.getByRole('button', {name: 'Create Project'})); + expect(projectCreationMockRequest).toHaveBeenCalledWith( + `/teams/${organization.slug}/${teamWithAccess.slug}/projects/`, + expect.objectContaining({ + data: { + default_rules: true, + name: 'my-project', + origin: 'ui', + }, + }) + ); + }); }); }); diff --git a/static/app/views/projectInstall/createProject.tsx b/static/app/views/projectInstall/createProject.tsx index febfc5d80f983d..9f23c74d3c29e0 100644 --- a/static/app/views/projectInstall/createProject.tsx +++ b/static/app/views/projectInstall/createProject.tsx @@ -23,6 +23,7 @@ import {useCreateProjectAndRules} from 'sentry/components/onboarding/useCreatePr import PlatformPicker, {type Platform} from 'sentry/components/platformPicker'; import TeamSelector from 'sentry/components/teamSelector'; import {categoryList} from 'sentry/data/platformPickerCategories'; +import {otherPlatform} from 'sentry/data/platforms'; import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import type {IssueAlertRule} from 'sentry/types/alerts'; @@ -58,7 +59,7 @@ import {makeProjectsPathname} from 'sentry/views/projects/pathname'; type FormData = { projectName: string; alertRule?: Partial; - platform?: Partial; + platform?: OnboardingSelectedSDK; team?: string; }; @@ -69,12 +70,6 @@ type CreatedProject = Pick & { team?: string; }; -function isNotPartialPlatform( - platform: Partial | undefined -): platform is OnboardingSelectedSDK { - return !!platform?.key; -} - function getMissingValues({ team, projectName, @@ -250,15 +245,10 @@ export function CreateProject() { team, alertRule, }: {selectedFramework?: OnboardingSelectedSDK} & Omit & { - platform: OnboardingSelectedSDK; + platform?: OnboardingSelectedSDK; }) => { const selectedPlatform = selectedFramework ?? platform; - if (!selectedPlatform) { - addErrorMessage(t('Please select a platform in Step 1')); - return; - } - let projectToRollback: Project | undefined; try { @@ -272,6 +262,11 @@ export function CreateProject() { }); projectToRollback = project; + const projectPlatform = selectedPlatform ?? { + ...otherPlatform, + key: otherPlatform.id, + }; + trackAnalytics('project_creation_page.created', { organization, issue_alert: alertRuleConfig.shouldCreateCustomRule @@ -280,7 +275,7 @@ export function CreateProject() { ? 'No Rule' : 'Default', project_id: project.id, - platform: selectedPlatform.key, + platform: projectPlatform.key, rule_ids: ruleIds, }); @@ -298,7 +293,7 @@ export function CreateProject() { id: project.id, name: project.name, team: project.team?.slug, - platform: selectedPlatform, + platform: projectPlatform, alertRule, notificationRule, }); @@ -372,21 +367,14 @@ export function CreateProject() { ); const handleProjectCreation = useCallback( - async (data: FormData) => { - const selectedPlatform = data.platform; - - if (!isNotPartialPlatform(selectedPlatform)) { - addErrorMessage(t('Please select a platform in Step 1')); - return; - } - + async ({platform, ...data}: FormData) => { if ( - selectedPlatform.type !== 'language' || + platform?.type !== 'language' || !Object.values(SupportedLanguages).includes( - selectedPlatform.language as SupportedLanguages + platform?.language as SupportedLanguages ) ) { - configurePlatform({...data, platform: selectedPlatform}); + configurePlatform({...data, platform}); return; } @@ -399,11 +387,11 @@ export function CreateProject() { { - configurePlatform({...data, platform: selectedPlatform, selectedFramework}); + configurePlatform({...data, platform, selectedFramework}); }} - onSkip={() => configurePlatform({...data, platform: selectedPlatform})} + onSkip={() => configurePlatform({...data, platform})} /> ), { @@ -412,7 +400,7 @@ export function CreateProject() { trackAnalytics( 'project_creation.select_framework_modal_close_button_clicked', { - platform: selectedPlatform.key, + platform: platform.key, organization, } );