From 5cc4cd55dfd67908f2e5dd2d56971f53e308a942 Mon Sep 17 00:00:00 2001 From: Guilhem Lemouel Date: Fri, 7 Aug 2026 18:47:31 +0200 Subject: [PATCH] fix(frontend): tidy the resource drawer around the Supabase entry point Connect Supabase was a hand-styled anchor carrying Supabase's brand hex values rather than a Button, and it sat in a row whose other controls had settled on unifiedSize md. Making it a Button meant SupabaseIcon had to satisfy IconType, so it now takes `size` (deriving height/width from it) alongside the string props its other callers pass. The manual resource form spaced every field 32px apart and WhitelistIp added another 16px of its own, which read as a gap rather than a rhythm. One gap of 16px, with the form itself given a little more separation from the description above it. Co-Authored-By: Claude Opus 5 (1M context) --- .../src/lib/components/ApiConnectForm.svelte | 104 ++++++++++++++++-- .../src/lib/components/AppConnectInner.svelte | 30 ++--- .../src/lib/components/WhitelistIp.svelte | 1 - .../lib/components/copilot/ResourceGen.svelte | 1 + .../lib/components/icons/SupabaseIcon.svelte | 73 +++++++++--- 5 files changed, 169 insertions(+), 40 deletions(-) diff --git a/frontend/src/lib/components/ApiConnectForm.svelte b/frontend/src/lib/components/ApiConnectForm.svelte index e3927ddc64..89343beb29 100644 --- a/frontend/src/lib/components/ApiConnectForm.svelte +++ b/frontend/src/lib/components/ApiConnectForm.svelte @@ -11,12 +11,18 @@ import Button from './common/button/Button.svelte' import { Loader2 } from 'lucide-svelte' import { untrack } from 'svelte' - import { base } from '$lib/base' import GitHubAppIntegration from './GitHubAppIntegration.svelte' import BedrockCredentialsCheck from './BedrockCredentialsCheck.svelte' import { isCloudHosted } from '$lib/cloud' import ResourceGen from './copilot/ResourceGen.svelte' import SyncResourceTypes from './SyncResourceTypes.svelte' + import Modal2 from './common/modal/Modal2.svelte' + import SupabaseProjectStep, { + type SupabasePick + } from './workspaceSettings/SupabaseProjectStep.svelte' + import { supabaseResourceValue } from './workspaceSettings/supabaseProvisioning' + import { useSupabaseOauth } from './workspaceSettings/supabaseOauth.svelte' + import { sendUserToast } from '$lib/toast' interface Props { resourceType: string @@ -127,6 +133,51 @@ let rawCodeEditor: { setCode: (code: string) => void } | undefined = $state(undefined) let textFileContent: string | undefined = $state(undefined) + let supabaseOpen = $state(false) + let supaStep: ReturnType | undefined = $state(undefined) + let supaResult: SupabasePick | undefined = $state(undefined) + + // Authorizing is not something to present a dialog about first: the button goes straight + // to the popup, and the dialog opens on the way back, already holding the projects. + const supaOauth = useSupabaseOauth() + let awaitingSupabaseAuth = $state(false) + + function connectSupabase() { + if (supaOauth.authed) { + supabaseOpen = true + return + } + awaitingSupabaseAuth = true + supaOauth.connect() + } + + $effect(() => { + if (awaitingSupabaseAuth && supaOauth.authed) { + awaitingSupabaseAuth = false + supabaseOpen = true + } + }) + + // The resource is being edited here rather than created for us, so the project's password + // goes straight into the form as a value. The user can link it to a secret variable with + // the same affordance every other password field has. + function applySupabasePick(pick: SupabasePick) { + args = { + ...(args ?? {}), + ...supabaseResourceValue(pick.project, ''), + password: pick.password + } + rawCode = JSON.stringify(args, null, 2) + rawCodeEditor?.setCode(rawCode) + supabaseOpen = false + supaResult = undefined + sendUserToast(`Filled in the connection for ${pick.project.name}`) + } + + $effect(() => { + if (supaResult) applySupabasePick(supaResult) + }) + function parseTextFileContent() { args = { content: textFileContent @@ -172,7 +223,7 @@ }} > {#snippet trigger()} - {/snippet} @@ -206,14 +257,15 @@ {/if} {#if resourceType == 'postgresql' && supabaseWizard} - - -
Connect Supabase
-
+ Connect Supabase + {/if} {/if} + + +
+
+ +
+ {#if supaStep} + {@const action = supaStep.getAction()} +
+ +
+ {/if} +
+
diff --git a/frontend/src/lib/components/AppConnectInner.svelte b/frontend/src/lib/components/AppConnectInner.svelte index de5bf45cd8..dad835c7e7 100644 --- a/frontend/src/lib/components/AppConnectInner.svelte +++ b/frontend/src/lib/components/AppConnectInner.svelte @@ -990,7 +990,7 @@ /> {:else if step == 2 && manual} -
+
{:else if step == 2 && !manual} {#if manual == false && resourceType != ''} diff --git a/frontend/src/lib/components/WhitelistIp.svelte b/frontend/src/lib/components/WhitelistIp.svelte index 8d8bac1a5d..a33c96604c 100644 --- a/frontend/src/lib/components/WhitelistIp.svelte +++ b/frontend/src/lib/components/WhitelistIp.svelte @@ -18,7 +18,6 @@ {#if ips} -
If necessary, the workers IPs to whitelist are: {ips.join(', ')} diff --git a/frontend/src/lib/components/copilot/ResourceGen.svelte b/frontend/src/lib/components/copilot/ResourceGen.svelte index 42e42fb9fa..34534285b4 100644 --- a/frontend/src/lib/components/copilot/ResourceGen.svelte +++ b/frontend/src/lib/components/copilot/ResourceGen.svelte @@ -124,6 +124,7 @@