From 08efb963f92c42a87d501f60445e2a444eb002eb Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Thu, 7 May 2026 14:51:21 +0800 Subject: [PATCH] chore(studio): add custom instance type input to project creation GENCOMP-76 (#45660) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Adds a "Custom instance type" input on the new-project modal, rendered directly below the existing custom Postgres version field and gated behind the same non-prod check. - Wires the value through `custom_supabase_internal_requests.ami.instance_type`, merged with the existing AMI search-tag payload so both can be set independently. Screenshot 2026-05-07 at 12 32 41 PM ## Test plan - [x] On a non-prod build, open the new-project modal and confirm the "Custom instance type" field appears below "Custom Postgres version". - [ ] Submit with only an instance type set and verify the request body includes `custom_supabase_internal_requests.instance_type` and no `ami` block. - [x] Submit with both fields set and verify both `ami.search_tags` and `instance_type` are sent. - [x] Submit with neither set and verify `custom_supabase_internal_requests` is omitted. - [x] Verify the field is hidden in prod builds. 🤖 Generated with [Claude Code](https://claude.com/claude-code) ## Summary by CodeRabbit * **New Features** * Added instance type field to project-creation wizard. * Added an internal-only configuration panel for advanced customization. * **Refactor** * Simplified Advanced Configuration panel layout and behavior. * **Documentation** * Updated documentation links to use internal reference URLs. --------- Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: Joshen Lim --- .../ProjectCreation/AdvancedConfiguration.tsx | 198 +++++++++--------- .../CustomPostgresVersionInput.tsx | 32 --- .../InternalOnlyConfiguration.tsx | 67 ++++++ .../ProjectCreation/ProjectCreation.schema.ts | 1 + .../ProjectCreation/SecurityOptions.tsx | 11 +- apps/studio/pages/new/[slug].tsx | 32 +-- 6 files changed, 186 insertions(+), 155 deletions(-) delete mode 100644 apps/studio/components/interfaces/ProjectCreation/CustomPostgresVersionInput.tsx create mode 100644 apps/studio/components/interfaces/ProjectCreation/InternalOnlyConfiguration.tsx diff --git a/apps/studio/components/interfaces/ProjectCreation/AdvancedConfiguration.tsx b/apps/studio/components/interfaces/ProjectCreation/AdvancedConfiguration.tsx index 566c01c5c78..2bad28d99b4 100644 --- a/apps/studio/components/interfaces/ProjectCreation/AdvancedConfiguration.tsx +++ b/apps/studio/components/interfaces/ProjectCreation/AdvancedConfiguration.tsx @@ -26,121 +26,111 @@ import { DOCS_URL } from '@/lib/constants' interface AdvancedConfigurationProps { form: UseFormReturn - layout?: 'vertical' | 'horizontal' - collapsible?: boolean } -export const AdvancedConfiguration = ({ - form, - layout = 'horizontal', - collapsible = true, -}: AdvancedConfigurationProps) => { +export const AdvancedConfiguration = ({ form }: AdvancedConfigurationProps) => { const disableOrioleProjectCreation = useFlag('disableOrioleProjectCreation') - const content = ( - <> - ( - <> - - - field.onChange(value === 'true')} - defaultValue={field.value.toString()} + return ( + + + + Advanced Configuration + + + +

+ These settings cannot be changed after the project is created +

+ ( + <> + - - - - Postgres - Default - - } - description="Recommended for production workloads" - className="[&>div>div>p]:text-left [&>div>div>p]:text-xs [&>div>div>label]:flex [&>div>div>label]:items-center [&>div>div>label]:gap-x-2" - /> - - - - - - + + field.onChange(value === 'true')} + defaultValue={field.value.toString()} + > + + - Postgres with OrioleDB - Alpha + Postgres + Default } - description="Not recommended for production workloads" - className={cn( - '[&>div>div>p]:text-left [&>div>div>p]:text-xs [&>div>div>label]:flex [&>div>div>label]:items-center [&>div>div>label]:gap-x-2', - form.getValues('useOrioleDb') ? 'rounded-b-none!' : '' - )} - disabled={disableOrioleProjectCreation} + description="Recommended for production workloads" + className="[&>div>div>p]:text-left [&>div>div>p]:text-xs [&>div>div>label]:flex [&>div>div>label]:items-center [&>div>div>label]:gap-x-2" /> - - {disableOrioleProjectCreation && ( - - OrioleDB is temporarily disabled for new projects. Please try again - later. - - )} - - - -
-
- {form.getValues('useOrioleDb') && ( - - - - )} -
- - )} - /> -

- These settings cannot be changed after the project is created -

- + + + + + + + + Postgres with OrioleDB + Alpha + + } + description="Not recommended for production workloads" + className={cn( + '[&>div>div>p]:text-left [&>div>div>p]:text-xs [&>div>div>label]:flex [&>div>div>label]:items-center [&>div>div>label]:gap-x-2', + form.getValues('useOrioleDb') ? 'rounded-b-none!' : '' + )} + disabled={disableOrioleProjectCreation} + /> + + {disableOrioleProjectCreation && ( + + OrioleDB is temporarily disabled for new projects. Please try again + later. + + )} + + + + + + {form.getValues('useOrioleDb') && ( + + + + )} + + + )} + /> + + + ) - - const collapsibleContent = ( - - - Advanced Configuration - - - - {content} - - - ) - - return {collapsible ? collapsibleContent : content} } diff --git a/apps/studio/components/interfaces/ProjectCreation/CustomPostgresVersionInput.tsx b/apps/studio/components/interfaces/ProjectCreation/CustomPostgresVersionInput.tsx deleted file mode 100644 index ac29150bb05..00000000000 --- a/apps/studio/components/interfaces/ProjectCreation/CustomPostgresVersionInput.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { UseFormReturn } from 'react-hook-form' -import { FormControl, FormField, Input_Shadcn_ } from 'ui' -import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' - -import { CreateProjectForm } from './ProjectCreation.schema' -import Panel from '@/components/ui/Panel' - -interface CustomPostgresVersionInputProps { - form: UseFormReturn -} - -export const CustomPostgresVersionInput = ({ form }: CustomPostgresVersionInputProps) => { - return ( - - ( - - - - - - )} - /> - - ) -} diff --git a/apps/studio/components/interfaces/ProjectCreation/InternalOnlyConfiguration.tsx b/apps/studio/components/interfaces/ProjectCreation/InternalOnlyConfiguration.tsx new file mode 100644 index 00000000000..a8a9027d259 --- /dev/null +++ b/apps/studio/components/interfaces/ProjectCreation/InternalOnlyConfiguration.tsx @@ -0,0 +1,67 @@ +import { CollapsibleContent, CollapsibleTrigger } from '@ui/components/shadcn/ui/collapsible' +import { ChevronRight } from 'lucide-react' +import { UseFormReturn } from 'react-hook-form' +import { Collapsible, FormControl, FormField, Input_Shadcn_ } from 'ui' +import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' + +import { CreateProjectForm } from './ProjectCreation.schema' +import Panel from '@/components/ui/Panel' + +interface InternalOnlyConfigurationProps { + form: UseFormReturn +} + +export const InternalOnlyConfiguration = ({ form }: InternalOnlyConfigurationProps) => { + return ( + + + + Internal-only Configuration + + + +

+ These settings are only applicable for local/staging projects +

+
+ ( + + + + + + )} + /> + + ( + + + + + + )} + /> +
+
+
+
+ ) +} diff --git a/apps/studio/components/interfaces/ProjectCreation/ProjectCreation.schema.ts b/apps/studio/components/interfaces/ProjectCreation/ProjectCreation.schema.ts index f80485ed6c0..fe59e5b5d79 100644 --- a/apps/studio/components/interfaces/ProjectCreation/ProjectCreation.schema.ts +++ b/apps/studio/components/interfaces/ProjectCreation/ProjectCreation.schema.ts @@ -17,6 +17,7 @@ export const FormSchema = z postgresVersion: z.string({ required_error: 'Please enter a Postgres version.', }), + instanceType: z.string().optional(), dbRegion: z.string({ required_error: 'Please select a region.', }), diff --git a/apps/studio/components/interfaces/ProjectCreation/SecurityOptions.tsx b/apps/studio/components/interfaces/ProjectCreation/SecurityOptions.tsx index ebb0465d0c8..340cb9ce64b 100644 --- a/apps/studio/components/interfaces/ProjectCreation/SecurityOptions.tsx +++ b/apps/studio/components/interfaces/ProjectCreation/SecurityOptions.tsx @@ -1,4 +1,3 @@ -import Link from 'next/link' import { UseFormReturn } from 'react-hook-form' import { Checkbox, @@ -17,8 +16,10 @@ import { Admonition } from 'ui-patterns' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { CreateProjectForm } from './ProjectCreation.schema' +import { InlineLink } from '@/components/ui/InlineLink' import Panel from '@/components/ui/Panel' import { useTrackDefaultPrivilegesExposure } from '@/hooks/misc/useDataApiRevokeOnCreateDefault' +import { DOCS_URL } from '@/lib/constants' interface SecurityOptionsProps { form: UseFormReturn @@ -51,13 +52,9 @@ export const SecurityOptions = ({ form, layout = 'horizontal' }: SecurityOptions Autogenerate a RESTful API for your public schema. Recommended if using a client library like{' '} - + supabase-js - + . diff --git a/apps/studio/pages/new/[slug].tsx b/apps/studio/pages/new/[slug].tsx index af1eeef4a65..b3606be43bb 100644 --- a/apps/studio/pages/new/[slug].tsx +++ b/apps/studio/pages/new/[slug].tsx @@ -18,11 +18,11 @@ import { AUTO_ENABLE_RLS_EVENT_TRIGGER_SQL } from '@/components/interfaces/Datab import { AdvancedConfiguration } from '@/components/interfaces/ProjectCreation/AdvancedConfiguration' import { CloudProviderSelector } from '@/components/interfaces/ProjectCreation/CloudProviderSelector' import { ComputeSizeSelector } from '@/components/interfaces/ProjectCreation/ComputeSizeSelector' -import { CustomPostgresVersionInput } from '@/components/interfaces/ProjectCreation/CustomPostgresVersionInput' import { DatabasePasswordInput } from '@/components/interfaces/ProjectCreation/DatabasePasswordInput' import { DisabledWarningDueToIncident } from '@/components/interfaces/ProjectCreation/DisabledWarningDueToIncident' import { FreeProjectLimitWarning } from '@/components/interfaces/ProjectCreation/FreeProjectLimitWarning' import { HighAvailabilityInput } from '@/components/interfaces/ProjectCreation/HighAvailabilityInput' +import { InternalOnlyConfiguration } from '@/components/interfaces/ProjectCreation/InternalOnlyConfiguration' import { OrganizationSelector } from '@/components/interfaces/ProjectCreation/OrganizationSelector' import { extractPostgresVersionDetails, @@ -131,6 +131,7 @@ const Wizard: NextPageWithLayout = () => { projectName: projectName || '', highAvailability: false, postgresVersion: '', + instanceType: '', cloudProvider: PROVIDERS[defaultProvider].id, dbPass: '', dbPassStrength: 0, @@ -311,6 +312,7 @@ const Wizard: NextPageWithLayout = () => { dbPass, dbRegion, postgresVersion, + instanceType, instanceSize, dataApi, dataApiDefaultPrivileges, @@ -355,15 +357,20 @@ const Wizard: NextPageWithLayout = () => { .join('\n') || undefined, } - if (postgresVersion) { - if (!postgresVersion.match(/1[2-9]\..*/)) { - toast.error( - `Invalid Postgres version, should start with a number between 12-19, a dot and additional characters, i.e. 15.2 or 15.2.0-3` - ) - } + if (postgresVersion && !postgresVersion.match(/1[2-9]\..*/)) { + toast.error( + `Invalid Postgres version, should start with a number between 12-19, a dot and additional characters, i.e. 15.2 or 15.2.0-3` + ) + } + if (postgresVersion || instanceType) { data['customSupabaseRequest'] = { - ami: { search_tags: { 'tag:postgresVersion': postgresVersion } }, + ami: { + ...(postgresVersion && { + search_tags: { 'tag:postgresVersion': postgresVersion }, + }), + ...(instanceType && { instance_type: instanceType }), + }, } } @@ -463,7 +470,7 @@ const Wizard: NextPageWithLayout = () => { {projectCreationDisabled ? ( ) : ( -
+
{canCreateProject && ( @@ -502,16 +509,17 @@ const Wizard: NextPageWithLayout = () => { )} - {showNonProdFields && } - + {showAdvancedConfig && !!availableOrioleVersion && ( )} + {showNonProdFields && } + {shouldShowFreeProjectInfo ? (