From d4274ea27e45caeb27eff40b9817cd9c5fc7acf0 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Mon, 25 May 2026 11:23:35 +0200 Subject: [PATCH] Fix wrapper forms design (#46283) ## Screenshots Before: image image After: image image ## Summary by CodeRabbit * **Style** * Clearer section separation using visual separators for wrapper creation/edit flows. * Adjusted column selector sizing for improved responsiveness. * Secure fields show a loading state while retrieving secrets. * **Refactor** * Unified form section layout across wrapper management for more consistent, scannable configuration panels. * Simplified data-target and schema areas for easier navigation and editing. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46283?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) --- .../Wrappers/CreateIcebergWrapperSheet.tsx | 314 ++++++++---------- .../Wrappers/CreateWrapperSheet.tsx | 276 +++++++-------- .../Wrappers/EditWrapperSheet.tsx | 152 ++++----- .../Wrappers/WrapperTableEditor.tsx | 2 +- 4 files changed, 338 insertions(+), 406 deletions(-) diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/CreateIcebergWrapperSheet.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/CreateIcebergWrapperSheet.tsx index 437857d3681..2e10cf991c2 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/CreateIcebergWrapperSheet.tsx +++ b/apps/studio/components/interfaces/Integrations/Wrappers/CreateIcebergWrapperSheet.tsx @@ -4,8 +4,6 @@ import { SubmitHandler, useForm, useWatch } from 'react-hook-form' import { toast } from 'sonner' import { Button, - Card, - CardContent, Form, FormControl, FormField, @@ -18,18 +16,15 @@ import { SheetTitle, } from 'ui' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' -import { - PageSection, - PageSectionContent, - PageSectionDescription, - PageSectionMeta, - PageSectionSummary, - PageSectionTitle, -} from 'ui-patterns/PageSection' import * as z from 'zod' import { CreateWrapperSheetProps } from './CreateWrapperSheet' import InputField from './InputField' +import { + FormSection, + FormSectionContent, + FormSectionLabel, +} from '@/components/ui/Forms/FormSection' import { useSchemaCreateMutation } from '@/data/database/schema-create-mutation' import { useSchemasQuery } from '@/data/database/schemas-query' import { useFDWCreateMutation } from '@/data/fdw/fdw-create-mutation' @@ -258,173 +253,144 @@ export const CreateIcebergWrapperSheet = ({ Create a {wrapperMeta.label} wrapper - - - - Wrapper Configuration - - - - - - ( - 0 ? ( - <> - Your wrapper's server name will be{' '} - {wrapperName}_server - - ) : ( - '' - ) - } - > - - - - - )} - /> - - - - - - - - Data target - - - - - - ( - -
- - -
-
-

- AWS S3 storage that's optimized for analytics workloads. -

-
-
-
- -
-
-

- Managed Apache Iceberg built directly into your R2 bucket. -

-
-
-
- -
-
-

- Can be used with any S3-compatible storage. -

-
-
-
-
-
-
- )} - /> -
-
-
-
- - - - - {wrapperMeta.label} Configuration - - - - - {targetOptions.map((option) => - option.hidden ? ( - - ) : ( - - - - ) + Wrapper Configuration}> + + ( + 0 ? ( + <> + Your wrapper's server name will be{' '} + {wrapperName}_server + + ) : ( + '' + ) + } + > + + + + )} - - - - - - - Foreign Schema - + /> + + + Data target}> + + ( + +
+ + +
+
+

+ AWS S3 storage that's optimized for analytics workloads. +

+
+
+
+ +
+
+

+ Managed Apache Iceberg built directly into your R2 bucket. +

+
+
+
+ +
+
+

+ Can be used with any S3-compatible storage. +

+
+
+
+
+
+
+ )} + /> +
+
+ + {wrapperMeta.label} Configuration} + > + + {targetOptions.map((option) => + option.hidden ? ( + + ) : ( + + ) + )} + + + +

Foreign Schema

+

You can query your data from the foreign tables in the specified schema after the wrapper is created. - - - - - - - {wrapperMeta.sourceSchemaOption && ( - - )} - - - - - - - +

+ + } + > + + {wrapperMeta.sourceSchemaOption && ( + + )} + + +
diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx index 39779c53d9d..26362ec67d6 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx +++ b/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx @@ -6,35 +6,30 @@ import { SubmitHandler, useFieldArray, useForm, useWatch } from 'react-hook-form import { toast } from 'sonner' import { Button, - Card, - CardContent, Form, FormControl, FormField, Input, RadioGroupStacked, RadioGroupStackedItem, + Separator, SheetFooter, SheetHeader, - SheetSection, SheetTitle, WarningIcon, } from 'ui' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' -import { - PageSection, - PageSectionContent, - PageSectionDescription, - PageSectionMeta, - PageSectionSummary, - PageSectionTitle, -} from 'ui-patterns/PageSection' import * as z from 'zod' import InputField from './InputField' import { WrapperMeta } from './Wrappers.types' import { FormattedWrapperTable, getWrapperCreationFormSchema, NewTable } from './Wrappers.utils' import WrapperTableEditor from './WrapperTableEditor' +import { + FormSection, + FormSectionContent, + FormSectionLabel, +} from '@/components/ui/Forms/FormSection' import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query' import { useSchemaCreateMutation } from '@/data/database/schema-create-mutation' import { invalidateSchemasQuery, useSchemasQuery } from '@/data/database/schemas-query' @@ -221,70 +216,51 @@ export const CreateWrapperSheet = ({ Create a {wrapperMeta.label} wrapper - - - - - Wrapper Configuration - - - - - - + Wrapper Configuration}> + + ( + ( - 0 ? ( - <> - Your wrapper's server name will be{' '} - {wrapper_name}_server - - ) : ( - '' - ) - } - > - - - - - )} - /> - - - - - - - - {wrapperMeta.label} Configuration - - - - - {wrapperMeta.server.options - .filter((option) => !option.hidden) - .map((option) => ( - - - - ))} - - - - - - - Data target - - - + description={ + wrapper_name.length > 0 ? ( + <> + Your wrapper's server name will be{' '} + {wrapper_name}_server + + ) : ( + '' + ) + } + > + + + + + )} + /> + + + + {wrapperMeta.label} Configuration} + > + + {wrapperMeta.server.options + .filter((option) => !option.hidden) + .map((option) => ( + + ))} + + + + Data target}> + )} /> - - + + + {mode === 'tables' && ( - - - - Foreign Tables - + +

Foreign Tables

+

You can query your data from these foreign tables after the wrapper is created - - - - - {tablesField.map((t, tableIndex) => { - // FIXME: make inference work - const table = t as unknown as FormattedWrapperTable - return ( -

-
-

- {table.schema_name}.{table.table_name} -

-

- Columns:{' '} - {(table.columns ?? []).map((column: any) => column.name).join(', ')} -

-
-
-
-
- ) - })} - -
- -
- {tablesField.length === 0 && errors.tables && ( -

- {errors.tables.message?.toString()}

- )} - -
+ + } + > + +
+ {tablesField.map((t, tableIndex) => { + // FIXME: make inference work + const table = t as unknown as FormattedWrapperTable + return ( +
+
+

+ {table.schema_name}.{table.table_name} +

+

+ Columns:{' '} + {(table.columns ?? []).map((column: any) => column.name).join(', ')} +

+
+
+
+
+ ) + })} + +
+ +
+ {tablesField.length === 0 && errors.tables && ( +

+ {errors.tables.message?.toString()} +

+ )} +
+
+ )} + {mode === 'schema' && ( - - - - Foreign Schema - + +

Foreign Schema

+

You can query your data from the foreign tables in the specified schema after the wrapper is created. - - - - +

+ + } + > + {wrapperMeta.sourceSchemaOption && !wrapperMeta.sourceSchemaOption?.readOnly && ( // Hide the field if the source schema is read-only @@ -462,10 +444,10 @@ export const CreateWrapperSheet = ({ control={form.control} /> - -
+ + )} -
+