Commit Graph
5505 Commits
Author SHA1 Message Date
Alaister YoungandAlaister Young de4bec77d6 [MUL-1338] fix(studio): lock compute size to large for HA projects (#49249)
When the High availability (Multigres) toggle is enabled in the New
Project form, the Compute size dropdown now offers only **Large** and
the form value is forced to `large`. Previously HA projects showed the
same micro/small/medium options as regular projects.

**Added:**
- `HIGH_AVAILABILITY_INSTANCE_SIZE` constant (`'large'`) alongside the
other `HIGH_AVAILABILITY_*` constants

**Changed:**
- `ComputeSizeSelector` watches `highAvailability` and renders only
Large when it's on (hiding the "Larger instance sizes available after
creation" row); the `cloudProvider` read is now a reactive `useWatch`
instead of a render-time `getValues()`, so the list re-filters when HA
forces the provider to `AWS_K8S`
- `HighAvailabilityInput` forces `instanceSize` to `large` when HA
toggles on and restores the previously selected size when it toggles
off, alongside the existing `dbRegion`/`cloudProvider` handling
- The compute size and region selects ignore Radix's spurious
`onValueChange('')` — Radix emits it when a select's value and option
list change in the same tick, which wiped the forced value (details in
the inline comments)
- HA projects skip the "Confirm compute costs" modal on submit — HA is
free during Alpha, so the forced large size shouldn't trigger the
$110/mo confirmation

## To test

- On a paid org, open the New Project form: with HA off, the Compute
size dropdown shows micro/small/medium plus the disabled "Larger
instance sizes available after creation" row
- Toggle High availability on: the dropdown shows only Large, the
trigger reads "large / 8 GB RAM / 2-core CPU" (not the placeholder), the
region locks as before, and the footer shows $110/m
- Check the network tab: the `available-regions` request goes out with
`desired_instance_size=large` and returns 200 (no request with an empty
`desired_instance_size`)
- Select medium first, toggle HA on then off: medium is restored (same
for other sizes); rapid toggling shouldn't leave the field blank
- With HA on, submitting goes straight through without the "Confirm
compute costs" modal; a non-HA medium project still shows it

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* High-availability projects now automatically use the required
dedicated instance size.
* Disabling high availability restores the previously selected instance
size.
* Compute size options are filtered based on cloud provider and
high-availability settings.

* **Bug Fixes**
* Prevented accidental clearing of compute size or region selections
during option updates.
* Compute-cost confirmation is no longer required for high-availability
projects.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-08-19 13:03:39 +00:00
Gildas Garcia 54f56a1baa Scoped PAT: use CSS for the long text reveal animation (#49245)
Simplify the code for the long text reveal animation on hover using only
CSS. This also improves performances on some devices

## How to test

- Open
https://studio-staging-git-gildas-scoped-pat-css-only-a-1d2de2-supabase.vercel.app/dashboard/account/tokens
- Create a token with project settings read/write permissions
- In the review step, ensure you can hover long URL to trigger a
scrolling animation showing its end
- In the review step, ensure short URL don't have this animation on
hover
- Create the token
- Open its permissions and check the hover effects again

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Style**
- Improved endpoint path reveal animations with smoother transitions and
masking.
  - Added responsive behavior based on available container space.
  - Increased transition duration for easier reading.
  - Added support for reduced-motion preferences.
- **Bug Fixes**
- Improved endpoint path visibility and hover behavior while preserving
the existing copy interaction.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-19 12:12:55 +02:00
Joshen Lim 6fd48944a8 Support multi series bar charts in explorer and chart-bar (#49241)
## Context

- Updates the BarChart in our design system to support multi series in a
similar fashion to how the LineChart already supports multi series
- Update chart renderer in explorer notebooks to support multiple Y axes
using the `MultiSelector` component
- Up to 3 y columns can be selected for now (Arbitrary limit from a
color's selection POV but also just felt like anything more and the
chart doesn't feel useful)
- Only linear scale will be supported if multiple y columns are selected
(Will switch back to linear if originally on log scale)

<img width="943" height="493" alt="image"
src="https://github.com/user-attachments/assets/2eba46f0-7e41-4544-a3ff-2bf08773d11b"
/>
<img width="946" height="497" alt="image"
src="https://github.com/user-attachments/assets/4ffe7a73-6f97-4f0d-a33a-31e4035800ab"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Charts now support selecting and displaying up to three Y-axis data
series.
  * Bar and line charts render multiple series with distinct colors.
* Cumulative calculations work independently across multiple selected
series.
* Chart controls provide clearer responsive layouts and limit selections
appropriately.

* **Bug Fixes**
* Logarithmic scaling automatically switches to linear when multiple
series or unsupported values are selected.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-19 16:58:35 +08:00
Joshen Lim 2034a1b929 Use DiffEditor for QueryCell for logs migration (#49238)
## Context

Previously we added the clickhouse logs migration banner for the Query
Cell in Notebooks
But rewriting was doing a direct swap of the content

Changes here opt to use the DiffEditor instead to maintain the same UX
for query editing that's not done by the user directly

<img width="972" height="423" alt="image"
src="https://github.com/user-attachments/assets/6863531a-3b53-4756-b134-12ae16191b80"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added a review workflow for legacy SQL rewrites.
  * View proposed rewrites in a full-editor comparison overlay.
* Accept rewrites to update and save the SQL, or discard them without
applying changes.
* **Bug Fixes**
* Prevented query execution, source changes, and visibility toggling
while a rewrite is under review.
* Prevented outdated rewrite proposals from overwriting newer SQL edits.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-19 16:20:03 +08:00
Joshen Lim 5d851f12ec Properly hook up browser tab label for explorer (#49240)
## Context

Very tiny one - just hooks up the browser tab label for explorer
properly

Browser tab should be the focused explorer tab, otherwise defaults to
'Explorer'
<img width="175" height="48" alt="image"
src="https://github.com/user-attachments/assets/fa6eef96-3222-4bf6-b929-993441970728"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
  - Browser titles now accurately reflect the active Explorer tab.
- Untitled tabs display “Untitled,” while views without an active
Explorer tab display “Explorer.”

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-19 15:49:15 +08:00
claude[bot]andClaude 4e280d4498 fix(studio): disambiguate query cancel telemetry and gate live-mode hotkey (#49137)
<!-- ccr-slack-attribution -->
_Requested by **Pam Chia** · [Slack
thread](https://supabase.slack.com/archives/C076KTY11DF/p1786930264662829?thread_ts=1786930264.662829&cid=C076KTY11DF)_

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Bug fix. Two telemetry correctness fixes in the Database Connections
feature preview. No visual changes, no new events.

Linear:
[GROWTH-1107](https://linear.app/supabase/issue/GROWTH-1107/fix-database-connections-feature-preview-banner-dead-end-plus)

## What is the current behavior?

### 1. `query_cancel_button_clicked` cannot tell its two surfaces apart

"Cancel query" is reachable from two places on
`/observability/connections`. One is the three-dot dropdown menu on an
activity row. The other is inside the "Confirm to terminate this
session?" dialog, which offers "Cancel query" alongside "Terminate" when
the session is running a query.

**Before:** both buttons fire `query_cancel_button_clicked` with an
identical payload (`activityState`, `isBlocking`). In analysis the two
are one undifferentiated number, so there is no way to see whether
people cancel straight from the row or only after opening the terminate
dialog and reading the "Cancelling it may solve the problem without
closing the connection" warning. That warning is the main nudge away
from terminating, and today we cannot measure whether it lands.

### 2. The live-mode hotkey fires telemetry for users who do not have
the feature

**Before:** the Mod+J live-mode shortcut is registered whenever the page
mounts, regardless of whether the Database Connections feature preview
is enabled. The live badge, the toggle button and the activity query are
all gated on the feature, so a user without it can press Mod+J, emit
`database_connections_live_mode_clicked`, and see nothing change. Those
events inflate the metric with interactions that had no effect.

## What is the new behavior?

### 1. `query_cancel_button_clicked` carries an `origin`

**After:** the event reports which surface it came from, so the two
flows can be split in analysis. Nothing changes for the user.

`QueryCancelButtonClickedEvent` in
`packages/common/telemetry-constants.ts` gains a required `origin:
'dropdown_menu' | 'terminate_dialog'` property, following the shape
already used by `index_advisor_enable_button_clicked` (`origin: 'banner'
| 'dialog'`). Values are snake_case to match the dominant convention
among the existing `origin` unions in that file. In `ActivityRow.tsx`
the shared `onCancelQuery` handler now takes the origin as an argument
and each of the two call sites passes its own value. Because `track()`
is strictly typed per action, the required property is enforced at
compile time rather than by convention.

### 2. The live-mode hotkey is gated on the feature

**After:** Mod+J only does something, and only reports something, for
users who actually have Database Connections enabled. Everyone else is
unaffected, as before.

`useShortcut` already accepts an `enabled` option that disables the
hotkey and hides the command-menu entry. The registration in
`pages/project/[ref]/observability/connections.tsx` now passes `enabled:
isDatabaseConnectionsEnabled`, reusing the value already read from
`useIsDatabaseConnectionsEnabled()` and already used to gate the
activity query and the visible controls on the same page.

## Additional context

**Scope was reduced from the original plan.** GROWTH-1107 originally
covered four items. #49132 rewrote the Database Connections gating model
and superseded three of them, so only the two above remain:

- The feature preview banner is no longer flag-gated, so there is
nothing to gate on `topForPostgres`.
- `isEnabled` on `database_connections_banner_cta_button_clicked` is now
a real variable rather than a constant, since it is true on the new
"Explore Database Connections" variant. It stays as is.
- The wrong-feature fallback in the feature preview modal no longer
triggers for this preview.

Nothing in that area is touched here. GROWTH-1107 has been updated to
reflect the reduced scope.

**Validation** (run locally):

- `tsc --noEmit` in `packages/common` and in `apps/studio`. Studio
reports the same two pre-existing errors before and after this change
and none in the changed files.
- `eslint` on both changed studio files: clean. `lint:ratchet`: passes.
- `vitest --run
components/interfaces/Observability/DatabaseConnections`: 36 passed.
- Prettier check on all three files: clean.


## To test

Verified in a real browser on the studio-staging Vercel preview,
checking telemetry at the wire level (network inspection of `POST
/platform/telemetry/event`). Checks derived from the diff, covering both
fixes and their negative cases.

- [x] Mod+J with the Database Connections feature preview off: no
`database_connections_live_mode_clicked` request fired and no UI change;
the page stays on the enable-preview gate screen
- [x] Mod+J with the preview on: the live badge visibly toggles and
exactly one event fires per press (`newState: "disabled"` on the first
press since live mode starts on by default, then `"enabled"` on the
second)
- [x] "Cancel query" from the activity row dropdown on an active
`pg_sleep(120)` session: `query_cancel_button_clicked` with
`custom_properties:
{"activityState":"active","isBlocking":false,"origin":"dropdown_menu"}`
- [x] "Cancel query" inside the "Confirm to terminate this session?"
dialog: `query_cancel_button_clicked` with `custom_properties:
{"activityState":"active","isBlocking":false,"origin":"terminate_dialog"}`

Opening the terminate dialog in the last check also fired
`session_terminate_button_clicked`, correctly distinct from the cancel
event. No new console errors versus the page-load baseline across all
four checks.

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-19 15:39:07 +08:00
Danny White b3edaa02f0 feat(studio): remove unified logs banner and deprioritise tos banner (#49239)
## What kind of change does this PR introduce?

Studio UI cleanup for sidebar BannerStack items and Unified Logs preview
defaults.

## What is the current behavior?

The sidebar BannerStack shows both a Unified Logs promo banner and a
Terms of Service update notice. Unified Logs has been default opt-in for
a while, and the ToS banner currently shares priority with other
higher-value notices. The default opt-in behaviour is still gated behind
the `unifiedLogsDefaultOptIn` feature flag.

Closes
[DEPR-646](https://linear.app/supabase/issue/DEPR-646/remove-unified-logs-banner-and-deprioritise-tos-banner).

| Before |
| --- |
| <img width="1024" height="759" alt="5717"
src="https://github.com/user-attachments/assets/1a19e6f6-0c7f-49e8-8e7e-9f83196b2353"
/> |

## What is the new behavior?

- Removes the Unified Logs BannerStack item and its component
- Keeps the ToS update banner but lowers its priority so other banners
surface first
- Sets Unified Logs `isDefaultOptIn` to `true` and removes
`unifiedLogsDefaultOptIn` flag usage

## To test

- Open any project in Studio (e.g. `/project/<ref>`)
- Confirm the sidebar BannerStack no longer shows the "Unified Logs is
here" banner
- If you have not dismissed the ToS notice and it is still before the
expiry date, confirm it still appears but sits behind higher-priority
banners (e.g. free micro upgrade on eligible projects)
- Open `/project/<ref>/logs` and confirm Unified Logs loads by default
for users who have not previously toggled the preview off

## After merge

- [ ] Retire the `unifiedLogsDefaultOptIn` PostHog flag

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Unified Logs preview is now enabled by default when available, while
preserving individual user choices.

- **Bug Fixes**
- Terms of Service update notifications now appear with higher priority.

- **Changes**
- Removed the Unified Logs promotional banner, including related
navigation, dismissal, and tracking behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-19 17:37:14 +10:00
Eduardo Gurgel 7bac134fa5 fix(studio): use realtime entitlements for max settings (#49228)
* Realtime settings now respect plan-based limits while enforcing safe
maximum caps.
  * Validation messages dynamically reflect the applicable limit.
* Settings validate correctly whether realtime access is active or
suspended.
* Saving remains disabled until all applicable realtime limits are
loaded.
  * A loading indicator appears while settings and limits are retrieved.
* Improved form reset behavior, accessibility labels, and settings
guidance.
2026-08-19 19:30:22 +12:00
Joshen LimandAli Waseem ce2ed77c02 Add clickhouse migration banner to QueryEditor (#49184)
## Context

Adds the clickhouse migration banner into the QueryEditor for explorer
if the source selected is logs - will apply for both the notebook query
cells and query tab

JFYI i've omitted out the diffing view for now, like what've currently
got for the SQL Editor

Got a separate ticket to look into that, but was thinking of waiting for
[this PR](https://github.com/supabase/supabase/pull/49112) from Charis
to go in first

<img width="1391" height="369" alt="image"
src="https://github.com/user-attachments/assets/5880df99-44b5-4a9f-8ff7-c9d7af3bcb93"
/>
<img width="1054" height="474" alt="image"
src="https://github.com/user-attachments/assets/ef5d225b-3b53-4d6d-ab6c-19804e3358e6"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added guidance in SQL editors to identify and rewrite legacy logs
queries.
* Integrated rewrite suggestions into the query editor’s existing SQL
diff workflow.
* Increased the height of embedded query editors for improved usability.
* Kept rewrite guidance available when no rewrite is needed or an
attempt is unsuccessful.

* **Bug Fixes**
  * Improved spacing for empty query-result messages.

* **Tests**
* Added coverage for rewrite visibility, acceptance, dismissal, and
no-change outcomes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-08-19 00:16:00 +08:00
Charis 79fbe467ba feat(studio): wire notebook create/update proposals into assistant panel (#49159)
## Summary

PR 4 of the notebook-approval-preview stack.

- Adds `NotebookProposalRenderer`, wiring
`create_notebook`/`update_notebook` into `MessagePartSwitcher` and
rendering `NotebookPreview` across all 6 tool states (drafting,
approval-requested, approval-responded, output-available, output-denied,
output-error).
- `update_notebook` fetches the live notebook via `useNotebookQuery`,
checks `expected_updated_at` against the fetched `updated_at`, and gates
the confirm action behind a refresh when stale.
- A tool-input parse failure renders a raw-input admonition instead of
returning `null`, so `ConfirmFooter` — and the ability to Skip/deny —
stays available rather than leaving the chat stuck.

Towards FE-4143

## Test plan

- [x] `tsc --noEmit` clean
- [x] `eslint` clean on touched files
- [x] `prettier --check` clean
- [x] New `NotebookProposalRenderer.test.tsx` (create/update previews +
approve, version-mismatch warning, parse-failure fallback with working
Skip, output-available/output-denied summaries)
- [x] Existing notebook test suites (`notebook-tools.test.ts`,
`notebook-operations`, `NotebookPreview`) still pass

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added AI-assisted notebook creation and updating with previews,
approval controls, and operation summaries.
* Added clear handling for loading, errors, denied actions, stale
notebook versions, and invalid proposals.
  * Added links to open notebooks after successful creation or updates.
  * Preserved notebook SQL content when displaying proposed changes.

* **Bug Fixes**
* Improved notebook proposal handling for conflicts and incomplete tool
responses.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 11:56:50 -04:00
Charis 071a07118a feat(studio): add NotebookPreview diff component (#49112)
## Summary

Stacked on #49109 (PR 1 — `deriveNotebookDiff`). This is PR 3 of the
notebook approval-preview stack: a pure presentational component that
renders the cell-level diff for a proposed notebook create/update, for
use in the assistant approval UI (wired in a later PR).

- `NotebookPreview` — header summary (`"6 cells"` for create, `"+2 −1 ~1
↕1"` for update) + entry list + "Show N more cells" for long notebooks.
- `NotebookPreviewCell` — dispatches per entry tag:
`unchanged`/`removed`/`moved` collapse to a muted badge row; `added`
renders source via `CodeBlock` (with a max-height/expand toggle);
`replaced` renders a `DiffEditor` diff, plus a before → after metadata
line when only `database_identifier`/`time_range` changed (SQL/text
identical).
- `NotebookPreview.utils` — pure helpers (labels, source/metadata
extraction, language mapping, summary formatting), unit tested.
- **Safety property**: cell content only ever renders through
`CodeBlock`/`DiffEditor` (literal source), never through a markdown
renderer — agent-authored text can't trigger image loads or link
navigation before the user approves. Covered by an adversarial test
(`![x](evil)`, `[y](evil)`, `<img onerror>` → zero
`img`/`[href]`/`[src]` DOM nodes).
- Adds `'markdown'` as a supported `CodeBlock` language (small, additive
change to `packages/ui-patterns`).

Towards FE-4143

## Test plan

- [x] `pnpm --filter studio test` — NotebookPreview suite (21 tests)
passes
- [x] `pnpm --filter studio exec eslint
components/interfaces/Explorer/NotebookPreview` — clean
- [x] `pnpm --filter studio exec tsc --noEmit` — no new errors
- [x] `pnpm exec prettier --check` — clean

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added notebook previews showing create and update summaries.
* Displayed added, removed, moved, unchanged, and replaced cells with
metadata and source diffs.
* Added expandable previews with truncation and a “Show more cells”
option.
  * Added Markdown syntax highlighting to code blocks.

* **Bug Fixes**
* Safely render adversarial agent-authored Markdown as literal content.

* **Tests**
* Added comprehensive coverage for notebook previews, summaries,
metadata, formatting, and truncation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 11:44:23 -04:00
Monica KhouryandAli Waseem fff5928056 fix: scroll to required fields on support form submit (#49147)
Fixes FE-4130. 

## What is the current behavior?

When submitting the support form with required fields missing, the form
does not scroll to or focus the required empty field. Users have to
manually find which field they missed.

## What is the new behavior?

On submit, the form automatically scrolls to and focuses the first
required field that's missing a value - including "What issue are you
having?" and "Which library are you having issues with?".

## Additional context

The scroll wasn't working due to a Chrome bug where scrollIntoView is
blocked when overflow-x: hidden and overflow-y: auto are on the same
element (the sidebar scroll container). The fix manually walks the DOM
to find the scrollable parent and calls scrollTo() directly. Dropdown
fields (Radix Selects) were also unfindable via the usual name
attribute, so data-support-field attributes are used as a stable DOM
hook for those.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Bug Fixes

* Improved support form validation by automatically scrolling to the
first invalid or missing required field.
* Added smooth scrolling and focus behavior to help users quickly
correct form errors.
* Ensured the client library field is brought into view when required
information is missing.
* Improved field targeting for category and client library validation
messages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-08-18 15:27:01 +03:00
kemal.earth ce27b4ee5b chore(studio): scoped pat mcp tool ui improvement (#49188)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Follow on from view permissions sheet and review step tidy up to show a
clear list of available mcp tools.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added an “Available MCP tools” section to scoped token reviews and
token details.
* Displays enabled tools as badges, with a clear empty state when none
are available.
* **Improvements**
  * Simplified capability cards to focus on enabled API endpoints.
* Removed per-permission MCP tool details and ungranted capability
listings.
* Updated endpoint count formatting for clearer singular and plural
labels.
* **Tests**
* Updated capability and token detail tests to reflect the new MCP tool
summary presentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 12:29:12 +01:00
dbb153042e feat(studio): cleaned up view permissions sheet (#49144)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Breaking down #49007 into smaller PR's. Part 1 merged in.

More to follow...


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Redesigned token capability details with expandable cards and dense
views for larger permission sets.
  * Added filtering by all, read, and read-write capabilities.
* Improved endpoint and MCP tool attribution, display, and endpoint
copying.
  * Added risk banners with permission and access warnings.
* Enhanced resource badges, responsive layouts, relative timestamps, and
dismissible creation guidance.

* **Bug Fixes**
  * Corrected MCP tool attribution across alternative permission scopes.
  * Improved handling and display of inaccessible resources.

* **Tests**
* Expanded coverage for capability views, filtering, risk messaging, and
permission evaluation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-08-18 10:58:56 +01:00
Saxon Fletcher c80f8ad78d chore(studio): upgrade AI SDK to v7 (#49167)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Chore / dependency upgrade.

## What is the current behavior?

Studio is on AI SDK 6 (`ai` ^6.0.174, `@ai-sdk/react` ^3). Tool
approvals still use the v6 `needsApproval` flag on individual tools.

## What is the new behavior?

Upgrades Studio to AI SDK 7 (`ai` 7.0.59) and the matching `@ai-sdk/*`
packages. Aligns call sites with v7 names (`instructions`,
`isStepCount`, `onEnd`, `ToolExecutionOptions`).

This is the bottom of stack #49171. Later layers add a shared Confirm
card and AssistantQueryCell.

## Additional context

- Stack: #49167 → #49168 → #49169 → #49170
- `needsApproval` on tools is left as-is in this PR so the upgrade can
land independently. A follow-up can move those gates to `streamText({
toolApproval })` and `experimental_toolApprovalSecret`.
- Independent of the notebook preview stack
([#49112](https://github.com/supabase/supabase/pull/49112),
[#49159](https://github.com/supabase/supabase/pull/49159)), which should
merge first before we wrap notebook proposals in Confirm.

## Test plan

- [ ] `pnpm --filter studio test` for `lib/ai/tools/*` and assistant
generate path
- [ ] Assistant chat still streams and tool-approval SQL / Edge Function
still pause for confirm
- [ ] Evals still run with mock tools (`needsApproval: false` overrides)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Improvements**
* Updated AI-powered chat, onboarding, SQL, code completion, and recipe
generation workflows for more reliable responses.
* Streaming responses now better preserve reasoning and source
information where available.
* Improved tool privacy notices while preserving dynamically generated
tool descriptions.
* Refined AI response handling, including step limits and structured
policy results.
* **Bug Fixes**
* Improved compatibility across AI-powered tool interactions and
execution scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 17:04:36 +08:00
Danny White cb8a609607 feat(studio): focus column name input after adding a column (#49183) 2026-08-18 18:06:54 +10:00
Alaister YoungandAlaister Young 6073c7a7e7 [FE-4193] fix(studio): show proper names for custom identity providers (#49182)
Unregistered `custom:*` identity providers (e.g. white-label
deployments' own OAuth providers) rendered their raw id — the account
preferences "Sign-in methods" list showed something like `Custom:Acme`
instead of `Acme`. `getProviderDisplay()` now derives a proper
title-cased name from any `custom:*` id, so this works generically for
every custom provider.

**Changed:**
- `getProviderDisplay()` derives a title-cased display name for
unregistered `custom:*` providers (`custom:acme` → "Acme",
`custom:my_provider` → "My Provider"), case-insensitively. Registered
ones (e.g. `custom:openai` → ChatGPT) are unaffected.
- `SignInWithCustom` reuses `getProviderDisplay()` instead of its own
`formatProviderName`, which only stripped a lowercase `custom:` prefix —
the display name also now flows into its error toast.
- Added unit tests for the new fallback branch.

## To test

- On a deployment with a custom provider (or by temporarily hardcoding
an identity with `provider: 'custom:acme'` in `AccountIdentities`),
check `/account/me` → Sign-in methods shows "Acme", not "Custom:Acme"
- Unlink dialog/toast for that identity should also say "Acme"
- Sign-in page with a custom provider configured should show "Continue
with Acme"
- `pnpm vitest run lib/external-identity-providers.test.ts` in
`apps/studio` passes

Addresses [FE-4193](https://linear.app/supabase/issue/FE-4193)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added support for unregistered custom identity providers.
* Custom provider names are now displayed in a clearer, title-cased
format with underscores converted to spaces.
* Matching providers use the SAML icon while preserving their configured
display names.

* **Bug Fixes**
* Improved sign-in error messages and button labels for custom
providers.
  * Provider identifiers are now handled case-insensitively.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-08-18 15:33:04 +08:00
Joshen Lim 7adc83ee39 Implement run notebook functionality (#49178)
## Context

Implements the "Run notebook" functionality which will run all database
or logs cells within the notebook.

<img width="206" height="110" alt="image"
src="https://github.com/user-attachments/assets/703f4f78-1e3c-43b8-8c7e-771720ac3464"
/>

Am opting to do some via `useImperativeHandle` in `QueryEditor` to
expose the `run` method, then having `ExplorerNotebookTab` calling `run`
on each database / logs cells for the run notebook action.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a “Run notebook” action to execute all database and log query
cells together.
- The action displays a loading state and is disabled while running or
when no executable cells are available.
- Query results continue to update after execution, including when
individual queries encounter errors.

- **Tests**
- Added coverage for running executable cells and handling notebooks
without runnable queries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 14:55:14 +08:00
Danny White 5f9ce727c0 fix(ui): systematise control surface fills and hover borders (#48887)
## What kind of change does this PR introduce?

Bug fix / design-system token hygiene for form and selector chrome.

## What is the current behavior?

After opaque default-button fills, text fields, selects, and selector
tiles drifted apart: inputs and selects mixed ad-hoc washes, hover
borders bounced between `border-stronger` / `border-foreground-muted`,
invalid fields had no hover step, and composites like InputGroup leaked
inner hover borders.

Follow-up to #48837 (opaque button fills) where Select rest still felt
darker than Input on forms such as scoped access tokens.

## What is the new behavior?

Named control roles and one interactive border:

| Role | Fill | Rest border | Hover / focus / open |
| --- | --- | --- | --- |
| Field (sunk) | `bg-field` | `border-control` | `border-control-hover`
|
| Raised control | `bg-control-raised` | `border-strong` |
`border-control-hover` |
| Overlaying action | card → popover | `border-strong` |
`border-control-hover` |
| Invalid field | `bg-destructive-200` | `border-destructive-400` |
`border-destructive` |

- `--field` / `--control-raised` / `--border-control-hover` live in
`semantic.css` (source of truth for roles; README points there)
- Input / Textarea / InputGroup / legacy TextArea use the field ladder
(incl. invalid hover)
- Select and empty MultiSelect use raised; filled MultiSelect sinks to
field
- Default + dashed Button, CommandMenu trigger, and radio
card/stacked/large use `border-control-hover`
- Studio selector tiles aligned: Connect mode, role impersonation,
DuckLake modes, compute “Contact us”

| Before and After |
| --- |
| <img width="1576" height="759" alt="Access Tokens Account Supabase"
src="https://github.com/user-attachments/assets/4bbe8b2b-a31a-4d63-80ba-04a1a8a5609d"
/> |
| <img width="1576" height="759" alt="Access Tokens Account Supabase"
src="https://github.com/user-attachments/assets/92271223-4103-4cc6-a7c0-9e4ff71cce30"
/> |

## Additional context

`--control-raised` aliases `--card` today (role name so fill can diverge
later). Rest `border-control` / `border-strong` both still map to
`--input` via compat; the shared interactive step is
`--border-control-hover`.

## To test

1. **[Account → Access
Tokens](https://studio-staging-git-dnywh-fixcontrol-surface-tokens-supabase.vercel.app/dashboard/account/tokens)**
Open Generate / New scoped token. Side-by-side Input, Select,
RadioGroupStacked, MultiSelect. Confirm sunk vs raised fills, shared
hover border, MultiSelect flips to sunk once a value is selected. Leave
a required field empty to check invalid rest → hover → focus.

2. **[Org →
Projects](https://studio-staging-git-dnywh-fixcontrol-surface-tokens-supabase.vercel.app/dashboard/org/_)**
Hover the dashed Status filter. Hover default / filled filter buttons
when active. Confirm hover/open borders match.

3. **[Project →
Connect](https://studio-staging-git-dnywh-fixcontrol-surface-tokens-supabase.vercel.app/dashboard/project/_)**
Open Connect from the header. Mode grid tiles: hover + selected borders
match radio cards (no old muted-foreground ring).

4. **[Project →
Compute](https://studio-staging-git-dnywh-fixcontrol-surface-tokens-supabase.vercel.app/dashboard/project/_/settings/infrastructure)**
(optional)
   Compute size radios + “Contact us” tile hover.
2026-08-18 16:54:25 +10:00
Joshen Lim b6e43311d3 Reorganize explorer folder structure (#49172)
## Context

Just reorganizing the files under the Explorer folder as details are a
bit more clearer

Mainly shifting related and exclusive files into their own folder and
tests into `__tests__` folder + renaming some files

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added query result display settings for switching between table and
chart views.
- Added chart configuration options for chart type, axes, scaling,
cumulative mode, and labels.
- Automatically prevents invalid logarithmic scaling when chart data is
incompatible.

- **Refactor**
- Standardized Explorer tab and query source naming across the interface
without changing existing behavior.
- Updated Explorer navigation, routing, and page wiring to use the
standardized components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 14:40:53 +08:00
Danny White 4760c1af77 feat(studio): polish PrivateLink connection UI (#49164)
## What kind of change does this PR introduce?

Polish for the AWS PrivateLink integrations UI.

## What is the current behavior?

The add/view sheet labels the optional nickname field as "Description",
delete confirmation always shows the AWS account ID, list admonitions
use generic copy, and delete uses a fire-and-forget mutation.

## What is the new behavior?

- Rename the optional nickname field to **Name**, with helper copy
explaining it appears on the connections list
- Tighten list admonition copy to reference connections below and
pluralise share wording
- Rename `showAcceptLink` to `shouldShowAcceptLink`
- Delete confirmation uses the connection name (or account ID when
unnamed) and clearer read replica fallback copy
- Delete uses `mutateAsync` so the dialog can await the mutation

| Before | After | 
| --- | --- |
| <img width="828" height="515" alt="Integrations Settings Chisel
Toolshed Supabase"
src="https://github.com/user-attachments/assets/9e255d4b-a048-459c-87ff-ee1b65f42f9a"
/> | <img width="828" height="515" alt="Integrations Settings Chisel
Toolshed Supabase"
src="https://github.com/user-attachments/assets/500e3922-912f-4e3b-a875-295ac7bd689e"
/> |

## To test

1. Open **Project settings → Integrations → AWS PrivateLink** on a
project with PrivateLink access
2. Click **Add connection** and confirm the optional field is labelled
**Name** with helper copy underneath
3. Add a connection with a name (e.g. `Production VPC`) and confirm the
list row shows that title
4. If you have a waiting or expired connection, confirm the list
admonition copy references shares below
5. Open a named connection, click **Delete**, and confirm the dialog
uses the connection name rather than always showing the raw account ID
6. Cancel delete and confirm the sheet stays open

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Updated AWS PrivateLink connection messages with clearer singular and
plural wording.
* Improved guidance for expired and pending connections, including
acceptance-instruction links.
* Renamed the account field to “Name,” marked it optional, and clarified
its purpose and default behavior.
* Enhanced deletion confirmations with clearer connection names and AWS
account identifiers.
  * Improved deletion handling to provide more reliable feedback.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 14:25:42 +10:00
Joshen Lim bfab3090f5 QueryTab: Scope role impersonation to each tab instead of global (#49139)
## Context

Previous PR [here](https://github.com/supabase/supabase/pull/49101)
introduced role impersonation to the Explorer -> Query Tab, but the
setting was global (e.g selected role would be the same despite
switching query tabs)

Changes here shifts the scope of the role impersonation into the query
draft so that the value is tied to each individual query tab instead

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Query drafts now remember selected impersonated roles when switching
between drafts or returning later.
  * Added support for clearing saved impersonated roles.
  * Impersonation state remains isolated across query tabs.

* **Bug Fixes**
* Prevented impersonation settings from carrying over between unrelated
drafts.
  * Invalid saved role data is safely ignored during restoration.
  * Logs drafts no longer persist or update impersonated roles.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 11:27:09 +08:00
Joshen Lim cfde341c31 QueryTab: Scope row limit to each tab instead of global (#49138)
## Context

Previous PR [here](https://github.com/supabase/supabase/pull/49098)
introduced row limits to the Explorer -> Query Tab, but the setting was
global (e.g selected row limit value would be the same despite switching
query tabs)

Changes here shifts the scope of row limit into the query draft so that
the value is tied to each individual query tab instead

Also added a logic as CodeRabbit suggested
[here](https://github.com/supabase/supabase/pull/49138#discussion_r3795525802)
- to default invalid row limit values to 100 if the persisted data is
mutated incorrectly

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

* **New Features**
* Query tabs now retain row-limit settings independently for each
database draft.
* Row-limit preferences are restored when reopening Studio, with older
drafts defaulting to 100 rows.

* **Bug Fixes**
* Changing the row limit now persists immediately and no longer affects
other query drafts.
  * Invalid saved row limits are safely normalized to a supported value.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 10:44:32 +08:00
Danny White fba3733148 test(studio): allow scoped token creation in CI (#49163)
## What kind of change does this PR introduce?

Test reliability fix.

## What is the current behavior?

The two longest scoped access token creation tests can exceed Vitest's
default five-second timeout when they run under the full Studio CI
shard, despite passing locally.

## What is the new behavior?

The project-scoped and organisation-scoped token creation tests each use
a targeted ten-second timeout. The global timeout and production code
remain unchanged.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Tests**
* Increased test timeouts for project- and organization-scoped token
creation scenarios to improve test reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 11:40:40 +10:00
David Whittington ff6c8d4b30 fix(log-drains): add UK1 and US2-FED Datadog regions (#49156)
## Summary
- Add `UK1` and `US2-FED` to the Datadog region dropdown in the log
drains studio UI
- Add the same two regions to the Datadog region list in the log-drains
docs page

The Logflare backend added support for these two Datadog regions in
[Logflare/logflare#3790](https://github.com/Logflare/logflare/pull/3790)
(shipped in v1.50.1), but the studio dropdown and docs were never
updated, so customers on UK1 or US2-FED couldn't actually select their
region when setting up a Datadog log drain.

## Test plan
- [ ] Open Project Settings → Log Drains → add a Datadog destination and
confirm UK1 and US2-FED appear in the Region dropdown
- [ ] Confirm a log drain configured with `UK1`/`US2-FED` saves and
sends events successfully

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added support for configuring Datadog log drains in the UK1 and
US2-FED regions.

* **Documentation**
* Updated the monitoring and debugging guide with the UK1 Datadog
region.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 15:22:13 -05:00
Joshen Lim 60be899fdb Selecting a PID from the overview card should clear filters if not visible in the UI (#49135)
## Context

For Database Connections - the PIDs on the overview cards are selectable
such that clicking on them should scroll the browser down to where the
row is.

However, if the selected PID isn't rendered due to the applied filters,
clicking on it will seemingly do nothing. Changes here hence opt to
remove all filters then scroll to the selected PID into view, so that
users can always quickly find which PID the overview card is
referencing.

Also chucked in some refactors to centralize the management of filters,
and functionality of selecting a PID into their own hooks

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added shared filtering for database activity by state, role,
application, search text, and view.
* Activity filters are now preserved in the URL for easier navigation
and sharing.
* Selecting activity metrics or process IDs now automatically reveals
the relevant activity row.
* Blocker view highlights root activities that are blocking other
queries.

* **Bug Fixes**
* Improved selection behavior when the chosen activity is hidden by
active filters.

* **Tests**
* Added coverage for individual, combined, case-insensitive, and
blocker-specific filtering scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 17:45:02 +08:00
Alaister YoungandAlaister Young 397965cfae [FE-4186] fix(studio): endless region selector loading for AWS_NIMBUS orgs (#49131)
On the new-project form, the Region select's trigger label and inline
spinner were driven by `isLoadingAvailableRegions` — the `isPending`
state of `useOrganizationAvailableRegionsQuery`. For `AWS_NIMBUS` orgs
that query is permanently disabled (`smartRegionEnabled` is false), and
a disabled query stays `isPending` forever, so the trigger showed
"Loading available regions..." with a spinner indefinitely even though
the default region was actually selected underneath and the form still
worked.

**Changed:**
- The trigger label and spinner now use the provider-aware `isLoading`
(`smartRegionEnabled ? isLoadingAvailableRegions :
isLoadingDefaultRegion`), which the component already used for the
select's `disabled` state and placeholder. For non-Nimbus providers the
two values are identical, so the normal path is unaffected.

## To test

- Emulate a Nimbus deployment locally by setting
`"infra:cloud_providers": ["AWS_NIMBUS"]` in
`apps/studio/hooks/custom-content/custom-content.json`, then open the
new-project form: the Region field should show the default region (name
+ flag) within a moment — not an endless "Loading available regions..."
spinner — and the dropdown should open with the specific-regions list
- Restore the normal provider list and reload: the field should briefly
load, then show smart regions ("General regions") plus specific regions
with Recommended badges, as before
- Toggle High Availability on/off in either config: the selector should
transition between region lists without getting stuck loading

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
  * Improved loading indicators in the region selector.
* The selector now consistently shows the correct loading state while
regions are being loaded.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-08-17 17:20:05 +08:00
b044408e79 [FE-4185] feat(studio): custom content key for auth page logo link (#49130)
Adds a `dashboard_auth:logo_link_url` custom content key so
white-labeled deployments can point the logged-out logo link at their
own marketing site instead of the hardcoded `https://supabase.com`.

**Added:**
- `dashboard_auth:logo_link_url` custom content key (schema, types,
default `null`, sample value)

**Changed:**
- `SignInLayout` and `ForgotPasswordLayout` now resolve the
marketing-site logo href from custom content, falling back to
`https://supabase.com` — these two shared layouts cover all auth pages
(sign-in, sign-in-sso, sign-in-mfa, sign-in-partner, forgot/reset
password) in both the Next and TanStack runtimes

## To test

- On a normal deployment (key `null`): visit `/sign-in` and
`/forgot-password` logged out — the logo should still link to
`https://supabase.com`
- Set `"dashboard_auth:logo_link_url": "https://example.com"` in
`apps/studio/hooks/custom-content/custom-content.json` locally — the
logo on those pages should link to `https://example.com`
- Signed-in contexts (`logoLinkToMarketingSite` unset) still link to
`/organizations`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added support for configuring the URL linked from authentication-page
logos.
* Authentication logos now use the configured destination when
available.
* Added a default destination to ensure logo links remain functional
when no custom URL is set.
* **Documentation**
* Added sample configuration for the customizable authentication logo
link.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-08-17 09:15:53 +00:00
Joshen Lim dfb0603a36 Joshenlim/fe 4063 set up incremental default opt in for database connections (#49132)
## Context

As per PR title - sets up incremental default opt in for the Database
Connections feature preview

Database Connections preview banner should still only show up if it's
never been dismissed before, but the CTA's changed to "Explore" rather
than "Enable" if the user's default opted in

Related discussion here:
https://github.com/orgs/supabase/discussions/48639

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Database Connections preview is now enabled by default.
  * Added clearer handling for preview state and initialization.
* Banner actions open Database Connections when enabled, or the feature
preview when disabled.
* **Bug Fixes**
* Improved banner and menu visibility while preview settings initialize.
* Preserved banner dismissal behavior after a previous preference
change.
* Improved navigation consistency across Database Connections entry
points.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 16:11:07 +08:00
Danny White 14fe0c0cc8 fix(studio): slightly round split-button corners on focus (#49129)
## What kind of change does this PR introduce?

UI polish for split buttons (primary action + dropdown chevron).
Follow-up to #49055.

## What is the current behavior?

The focus ring sits above the neighbouring half, but the inner edge
stays square, so the ring has two sharp corners at the join.

## What is the new behavior?

On keyboard focus, the squared-off edge uses a slight radius so the ring
matches the outer corners more closely. Resting state is unchanged.
Split-button callsites now share the same join classes as the
design-system example.

| Before | After |
| --- | --- |
| <img width="1030" height="296" alt="43471"
src="https://github.com/user-attachments/assets/9df3bd72-c7ac-4419-ae18-a7e649dc2d66"
/> | <img width="1056" height="276" alt="CleanShot 2026-08-17 at 10 45
09@2x"
src="https://github.com/user-attachments/assets/52e8a4dc-9c52-45ce-b4d0-f0e7b1b75935"
/> |

## To test

Tab to each half (labelled button, then chevron). Inner corners of the
focus ring should be slightly rounded, not square.

1. [Split with
dropdown](https://design-system-git-fix-split-button-focus-radius-supabase.vercel.app/design-system/docs/components/button#split-with-dropdown)
(no login)
2. [Access
Tokens](https://studio-staging-git-fix-split-button-focus-radius-supabase.vercel.app/dashboard/account/tokens)
→ Generate new token
3. Any project on [studio
staging](https://studio-staging-git-fix-split-button-focus-radius-supabase.vercel.app/dashboard/_/settings/general)
→ Settings → General → Restart project

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Accessibility**
  - Added accessible labels to dropdown and export controls.
- Improved keyboard-focus visibility, layering, and rounded edge
treatment across joined buttons and menus.
  - Removed misleading or redundant screen-reader text and titles.

- **Bug Fixes**
- Prevented split-button controls from shrinking or displaying awkward
borders and corners.
- Refined hover and focus behavior for action buttons throughout
settings, database, storage, account, and documentation interfaces.

- **Documentation**
- Clarified guidance for using overflow menus and responsive
split-button actions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 17:28:22 +10:00
Danny White 65a5e593ca feat(studio): tighten Integrations layout (#49088)
## What kind of change does this PR introduce?

UI

## What is the current behavior?

GitHub’s empty state and Integrations icon spacing do not match the
PrivateLink list. Add connection has no plus. PrivateLink rows use a
kebab instead of click-to-view.

## What is the new behavior?

GitHub empty state matches the connections list. **Connect GitHub** is
tiny and asks you to connect before choosing a repo. Section icons
align. **Add connection** has a plus. PrivateLink rows are clickable;
delete stays in the sheet.

| Before | After |
| --- | --- |
| <img width="1456" height="1508" alt="CleanShot 2026-08-14 at 12 48
48@2x"
src="https://github.com/user-attachments/assets/27485e35-c24f-478e-8328-aad03ebb1dfb"
/> | <img width="1468" height="1494" alt="CleanShot 2026-08-14 at 14 22
19@2x"
src="https://github.com/user-attachments/assets/056e3b48-4542-4be5-9b21-4b5abd726e8e"
/> |

## Additional context

Stacked on #49087. No Vercel card work in this PR. See #49030 for the
end state, as it may already include fixes you might propose.

## To test

- **Project Settings → Integrations.** Check GitHub, Vercel, and
PrivateLink icon alignment.
- GitHub not connected: description should say **Connect GitHub to link
a repository to this project.** Button should be tiny.
- If GitHub has no repo (org page), the empty state should ask you to
add a connection.
- PrivateLink **Add connection** should show a plus. Click a connection
row to view it. No kebab.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* AWS PrivateLink connections now display clearer titles, status,
replica details, and database visibility.
* GitHub organization integrations now provide improved empty states and
clearer connection actions.
  * Added plus icons to connection buttons.

* **Improvements**
* Updated GitHub guidance based on authorization and repository
selection status.
  * Standardized connection labels and refined integration page layouts.
* Improved AWS integration icon presentation and responsive upgrade
prompts.

* **Bug Fixes**
  * Simplified default connection button wording across integrations.
* Improved AWS account title fallback behavior when a nickname is
unavailable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 17:11:52 +10:00
Danny White fe347d8876 feat(studio): show PrivateLink accept guidance on the list (#49087)
## What kind of change does this PR introduce?

Feature

## What is the current behavior?

Accept-in-AWS guidance lives only in the view sheet, as a per-status
essay with a nested button/link. Delete is easy to miss and does not
name the database.

## What is the new behavior?

The list warns when any connection is Waiting or Expired. View
connection uses that same admonition. Delete uses a confirm dialog that
names the database, including from **View connection**.

| Before | After |
| --- | --- |
| <img width="1444" height="480" alt="CleanShot 2026-08-14 at 12 46
23@2x"
src="https://github.com/user-attachments/assets/015b261b-0bee-48f4-8f2d-d0d23293e120"
/> | <img width="1456" height="676" alt="CleanShot 2026-08-14 at 12 47
17@2x"
src="https://github.com/user-attachments/assets/0a12371b-553a-4e52-b042-7498af722f4a"
/> |
| <img width="844" height="560" alt="CleanShot 2026-08-14 at 12 46
49@2x"
src="https://github.com/user-attachments/assets/f664b165-d351-4572-8536-27f4a9749975"
/> | <img width="842" height="452" alt="CleanShot 2026-08-14 at 12 47
09@2x"
src="https://github.com/user-attachments/assets/a387c294-5814-451b-9359-e70c73de2cb2"
/> |

## Additional context

Stacked on #49086. See #49030 for the end state, as it may already
include fixes you might propose.

## To test

- **Project Settings → Integrations → AWS PrivateLink → Add
connection.** Leave it unaccepted in AWS. The list should show the
12-hour accept warning.
- **View connection** on that row. Same warning, **View instructions**,
not a status essay.
- **⋯ → Delete** on a row, and **Delete** inside **View connection.**
The dialog should name the database.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added clearer AWS PrivateLink connection alerts for pending and
expired connections, including guidance and acceptance links when
applicable.
* Existing PrivateLink connections can now be deleted directly from the
connection form.
* Added confirmation dialogs with loading and completion states for
deletion.
* Added more specific descriptions for primary databases and read
replicas.

* **Bug Fixes**
* Improved connection status messaging and handling for AWS PrivateLink
integrations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 16:41:27 +10:00
Joshen Lim 097a105663 joshenlim/fe 4176 add role impersonation to explorerquerysourcemenu (#49101)
## Context

Stacked off from https://github.com/supabase/supabase/pull/49098 - adds
role impersonation for both Notebook Query cell + Explorer Query tab

Note that this refactors the role impersonation state a little to
decouple some stuffs to make this work, since the role impersonation
state is global and we need a local state to support this UX

Similarly to row limit, for query tab its intentional that for now that
the role impersonation isn't scoped to the query draft atm as I wanna
avoid making changes to explorer-query given there was a couple of PRs
in flux that adjusts that file - will handle that separately

<img width="1117" height="577" alt="image"
src="https://github.com/user-attachments/assets/9bfd6287-efff-418b-a1c0-934ee2c840cb"
/>

<img width="1917" height="436" alt="image"
src="https://github.com/user-attachments/assets/bfd1be82-8f77-4764-bd3a-4b9c63169b82"
/>


## To test
- [ ] Verify that role impersonation works in notebook query cell
- [ ] Verify that role impersonation works in notebook query tab

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added role impersonation support to SQL Explorer queries.
* Users can select an impersonated role directly from database query
menus.
  * Query execution now applies the selected role when configured.
* Added local role selection state for individual query tabs and cells.
* Improved reuse and consistency of role impersonation controls across
the interface.
* Role selections and impersonation details remain synchronized across
supported query components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 14:22:50 +08:00
Danny White 4433d9ddaf feat(studio): mark PrivateLink waiting as a warning (#49086)
## What kind of change does this PR introduce?

UI

## What is the current behavior?

Waiting (still labelled Ready in #49085) is green. Creating is orange.
Deleting is red.

## What is the new behavior?

Waiting is orange. Creating is grey. Deleting is orange. Connected stays
the only green state.

| Before | After |
| --- | --- |
| <img width="1448" height="492" alt="CleanShot 2026-08-14 at 12 43
59@2x"
src="https://github.com/user-attachments/assets/c0d95b51-7841-4714-a01b-47e5587c3efb"
/> | <img width="1434" height="470" alt="CleanShot 2026-08-14 at 12 44
59@2x"
src="https://github.com/user-attachments/assets/3ba10dc5-5fdd-464a-a748-5085d2d65df3"
/> |
| <img width="842" height="440" alt="CleanShot 2026-08-14 at 12 44
21@2x"
src="https://github.com/user-attachments/assets/757db647-4b7c-4f77-8dcf-1eb289c40cc1"
/> | <img width="842" height="432" alt="CleanShot 2026-08-14 at 12 44
49@2x"
src="https://github.com/user-attachments/assets/1311a6d2-4712-4cb9-a6f2-f39387f0a953"
/> |

## Additional context

Stacked on #49085. See #49030 for the end state, as it may already
include fixes you might propose.

## To test

- **Project Settings → Integrations → AWS PrivateLink.** A connection
that AWS has not accepted yet should show an orange **Waiting** badge,
not green Ready.
- Creating should be grey. Deleting orange. Expired and Failed stay red.
- **Docs preview → Platform → PrivateLink.** Should say Waiting, not
Ready.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Updated AWS PrivateLink connection statuses to accurately show
“Waiting” while the AWS Resource Share is pending acceptance.
* Refined status badge styling for creating, waiting, and deleting
connections.
  * Clarified that Resource Shares must be accepted within 12 hours.

* **Documentation**
* Updated PrivateLink setup instructions to reflect the revised
connection status flow.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 16:19:10 +10:00
Joshen Lim d61477085e Joshenlim/fe 4175 add row limit in explorerquerysourcemenu (#49098)
## Context

Related to Explorer/Notebook - builds on the ExplorerQuerySourceMenu by
adding an option for row limit in both Notebook Query cell + Query Tab

## Side note RE persistence of the selected row limit value
Note that for QueryTab - its intentional that for now that the row limit
isn't scoped to the query draft atm as I wanna avoid making changes to
`explorer-query` atm as there's a couple of PRs in flux that touches
that file. So will handle that separately

^ This means that switching between query tabs will not change nor
persist the row limit

<img width="931" height="335" alt="image"
src="https://github.com/user-attachments/assets/d1d52ee7-7c1d-42aa-a6ae-1d7d99ab95c9"
/>

<img width="1381" height="486" alt="image"
src="https://github.com/user-attachments/assets/689368c9-c0fc-4000-a09e-f59bfa7afa97"
/>

## To test
- [ ] Verify that row limit behaviour works in notebooks
- [ ] Verify that row limit behaviour works in explorer query tab
2026-08-17 13:36:31 +08:00
Danny White 0c1da8fd09 feat(studio): tighten PrivateLink sheet fields (#49085)
## What kind of change does this PR introduce?

Feature

## What is the current behavior?

Add connection field order and nickname handling are harder to scan.
Empty description can still show up as a blank name.

## What is the new behavior?

Add connection is AWS account ID, then database, then optional
description. An empty description is omitted from the list title.

| Before | After |
| --- | --- |
| <img width="846" height="874" alt="CleanShot 2026-08-14 at 12 42
33@2x"
src="https://github.com/user-attachments/assets/abfc4f37-a401-4bba-9408-c2530b0ac09b"
/> | <img width="844" height="794" alt="CleanShot 2026-08-14 at 12 43
01@2x"
src="https://github.com/user-attachments/assets/0cadeaea-583d-4c2b-9336-3d0fe6a1415b"
/> |

## Additional context

Stacked on #49084. See #49030 for the end state, as it may already
include fixes you might propose.

## To test

- **Project Settings → Integrations → AWS PrivateLink → Add
connection.** Confirm field order: account ID, database, description.
- Save once with a description and once without. Without one, the row
title should fall back to the account ID.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added AWS account ID and database target fields to the PrivateLink
setup form.
- Added validation and improved preservation of entered values while
editing.
  - Made the connection description optional.
- Updated connection status labels and badges for clearer status
visibility.

- **Documentation**
- Updated PrivateLink setup instructions to reflect the revised field
order and optional description.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 11:46:41 +10:00
Danny White 44292c0996 feat(studio): extract PrivateLink status copy (#49084)
## What kind of change does this PR introduce?

Refactor

## What is the current behavior?

Status labels and sheet copy are inline switches in the list and form.

## What is the new behavior?

One status lookup drives the badge and the view-sheet copy. No intended
visual change. Ready is still green.

| Before and After |
| --- |
| <img width="1460" height="486" alt="CleanShot 2026-08-14 at 12 37
13@2x"
src="https://github.com/user-attachments/assets/0c6c0b03-25f7-4e64-a0cd-72e7ef966454"
/> |
| _No visual changes_ |

## Additional context

Stacked on #48967. See https://github.com/supabase/supabase/pull/49030
for the end state, as it may already include fixes you might propose.

## To test

- **Project Settings → Integrations → AWS PrivateLink.** Look at a
connection row badge, then **View** it. Labels should match today’s
statuses. Ready should still be green.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added clear status messaging for AWS PrivateLink connections,
including accepted, ready, creating, deleting, expired, and failed
states.
* Added fallback messaging for unavailable or unrecognized connection
statuses.

* **Bug Fixes**
* Improved consistency of PrivateLink status badges, labels,
descriptions, and visual styles.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 11:32:18 +10:00
Danny White c15a8b6739 chore(studio): lighten FormLayout descriptions and tighten GitHub copy (#49091)
## What kind of change does this PR introduce?

UI nits

## What is the current behavior?

`FormLayout` descriptions that are not in a react-hook-form field use
`text-foreground-light`, which fights the component’s
`text-foreground-lighter` variant. New-project GitHub helper copy is one
long colon sentence.

## What is the new behavior?

Those `FormLayout` descriptions use the shared description variant
(`foreground-lighter`). New-project GitHub copy is two short sentences.

| Figure |
| --- |
| <img width="820" height="798" alt="CleanShot 2026-08-14 at 14 33
32@2x"
src="https://github.com/user-attachments/assets/7703a01d-efcb-41c2-8f6a-e96fc8a7187d"
/> |
| _Example call site of **before** the `FormLayout` fix._ |
| <img width="1384" height="582" alt="CleanShot 2026-08-14 at 14 53
39@2x"
src="https://github.com/user-attachments/assets/1bce1ee7-befd-4f53-881c-bbc7a87dd467"
/> |
| _**After** New-project copy shortening._ |

## To test

- **Organization → New project.** GitHub (optional): “Ideal for
agent-first workflows. Update your schema in code and push it to GitHub.
Supabase deploys the changes.”
- **Project Settings → Database → SSL configuration.** “Reject non-SSL
connections to your database” should look more muted
(`foreground-lighter`), not the brighter `foreground-light`.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Simplified the GitHub repository field description while preserving
deployment guidance and the “Learn more” link.

* **Style**
* Lightened the color of descriptive text in form layouts for improved
visual hierarchy.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 11:29:59 +10:00
Stephen Morgan 3d966e3709 feat(studio): show PrivateLink resource IDs and use connection copy (#48967)
## What kind of change does this PR introduce?

Feature and docs

## What is the current behavior?

PrivateLink is labelled as an AWS account, and there is no way to tell
which resource configuration belongs to the primary vs a read replica.

Put simply: you’re not adding an AWS account. You’re adding a
connection. One AWS account can have multiple PrivateLink connections,
just to different databases, with more fields also coming soon.

Part of PRODSEC-238 and fixes SEC-939.

## What is the new behavior?

Each connection shows resource configuration IDs so primary and replica
are distinguishable. Customer-facing copy says **connection**. API paths
and AWS console labels still say association.

| Before | After |
| --- | --- |
| <img width="1452" height="496" alt="CleanShot 2026-08-14 at 12 33
49@2x"
src="https://github.com/user-attachments/assets/3b295136-0325-4587-9291-b5f01fc07806"
/> | <img width="1440" height="434" alt="CleanShot 2026-08-14 at 12 34
30@2x"
src="https://github.com/user-attachments/assets/dd6ba064-18e4-4969-9c76-e3b79ac9d288"
/> |
| <img width="846" height="912" alt="CleanShot 2026-08-14 at 12 33
28@2x"
src="https://github.com/user-attachments/assets/c4c6caca-a2f6-4516-99c7-ad7cf865f8ac"
/> | <img width="844" height="880" alt="CleanShot 2026-08-14 at 12 34
39@2x"
src="https://github.com/user-attachments/assets/f3874c6b-abdc-4ef8-84fa-141cd9150871"
/> |
| <img width="1448" height="560" alt="CleanShot 2026-08-14 at 12 33
10@2x"
src="https://github.com/user-attachments/assets/8ae734cb-ec1f-4e4e-acf7-f4de459296d1"
/> | <img width="1460" height="496" alt="CleanShot 2026-08-14 at 12 32
15@2x"
src="https://github.com/user-attachments/assets/883050d5-a6f1-44bd-8ebd-1513a2c41e9f"
/> |

## Additional context

First PR in a stacked PrivateLink series (#49084 onwards). See
https://github.com/supabase/supabase/pull/49030 for the end state, as it
may already include fixes you might propose.

## To test

- **Project Settings → Integrations → AWS PrivateLink.** Open **Add
connection**, or **View** an existing one. Confirm the UI says
connection, and that resource config IDs are copyable.
- **Docs preview → Platform → PrivateLink.** Procedure steps should say
Add connection / View connection.

---------

Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
2026-08-17 11:06:26 +10:00
Danny White 89cd156e39 fix(studio): clarify MFA backup authenticator copy (#49083)
## What kind of change does this PR introduce?

Bug fix (copy and layout)

## What is the current behavior?

After setting up a single MFA factor, Account > Security warns you to
add a "backup sign-in method". That reads like another account identity
(email / Google / SSO), not a second authenticator app. The add action
also sits at the bottom of the MFA card, so the callout has no nearby
control.

Fixes
[FE-4171](https://linear.app/supabase/issue/FE-4171/clarify-backup-sign-in-method-after-mfa-setup)

## What is the new behavior?

The MFA block is a `PageSection` with **Add app** in the aside. When one
factor is configured, a danger callout above the card tells you to add a
backup authenticator app, with **Add another app** opening the same
modal.

| Before | After |
| --- | --- |
| <img width="1482" height="896" alt="CleanShot 2026-08-14 at 10 27
33@2x"
src="https://github.com/user-attachments/assets/7a8f3737-8e11-49c4-8f8e-3fda527a8c40"
/> | <img width="1468" height="802" alt="CleanShot 2026-08-14 at 10 57
06@2x"
src="https://github.com/user-attachments/assets/b2f6060e-b6c1-49e4-ae5c-99553ea3e60a"
/> |

## To test

1. Open **Account > Security** (`/account/security`).
2. **0 apps:** empty card, **Add app** in the section aside. Click it.
The add-factor modal should open.
3. **1 app:** danger callout under the section title. Copy should
mention a backup authenticator app, not a sign-in method. **Add another
app** and **Add app** should both open the same modal.
4. **2 apps:** callout and add buttons gone. Remove still works.

Add or remove an authenticator app on that page to hit each state. If
you already have one factor, step 3 is the important check.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Improved the multi-factor authentication interface with clearer
sections, cards, and guidance.
  * Added an empty state when no authenticator apps are configured.
* Added a warning when only one authenticator remains to help prevent
account lockout.
  * Limited authenticator app setup to two configured factors.

* **Bug Fixes**
* Improved loading and error-state presentation for authentication
factor management.
* Simplified the security page to provide a more consistent MFA
experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 10:47:50 +10:00
Charis 628473b3eb refactor(studio): extract notebook query-cell logic and give log cells display settings (#49075)
Final PR of the stack. #49069, #49070, #49072 and #49074 have merged, so
this now targets `master` directly.

**Rebased onto latest `master`**, which includes the centralized
result-rendering work (#49096). See "Conflict resolution" below.

## What's left after master's own fixes

`QueryCell` was written for database cells and adapted to log cells
afterwards. Master has since fixed most of it directly:
`handleUpdateCell` no longer bails on a non-database cell, the cell's
own binding is read via `getQuerySourceBinding`, and
`database_identifier` / `time_range` propagate across a source change.

What remains:

- **`display` was only passed for database cells**, so the `view` field
on `log_cell` stayed unreachable and a logs query could never be
charted. That is the one behavioral fix left in this PR.
- The per-backend branching is inline and untested.

## What changed

Per-backend logic moves into `QueryCell.utils.ts`, where it is
unit-tested: `changeCellSource`, `setCellSql`, `cloneQueryCell`,
`getCellDisplay`, `toQueryModel`. Each narrows on the cell tag exactly
once, so the SQL brand and the backend's parameters stay correlated
rather than being re-derived at each call site. `cloneQueryCell` also
rebuilds the chart's series array, which valtio hands over as `readonly
string[]`.

`NotebookEditor` renders through `isQueryCell` (#49069) rather than a
tag switch, so a new backend gets picked up by classifying it in
`CELL_KINDS` instead of by remembering to add a `case`.

## Conflict resolution

Two rounds of master's work landed in this file set.

**`QueryCell/index.tsx` (master's own rework).** `changeCellSource`
**subsumes the four source-change branches** master had inline, each
covered by a test:

| Master's branch | Test |
|---|---|
| database → database (replica change) | `keeps the query when only the
database changes` |
| logs → logs (time-range change) | `keeps the query when only the log
time range changes` |
| database → logs | `carries the query text over when moving from the
database to logs` |
| logs → database | `carries the query text over and restores a default
row limit …` |

Two improvements fall out of consolidating them:

- A **logs → database** move now keeps the selected replica; pinned by
`applies the selected database when moving from logs to the database`.
- The row-limit default is **named** rather than a hard-coded `100`.
`Explorer/utils.ts` now shares `DEFAULT_CELL_ROW_LIMIT` with
`createQueryCellSkeleton`, so cell creation and backend conversion can't
drift.

Untouched from master: `snap.updateCell`, `AddCellDropdown`,
`MoveCellDropdownContent`, the `SortableSection` grip props, and
`NotebookEditor`'s add-cell buttons, skeletons, `reorderCells` and
`insertCellAfter`.

**Centralized result rendering (#49096).** That PR moved
`QueryCell/QueryResultChart.tsx` up to `Explorer/`, split
`QueryResultTable` into `QueryResultError`, and added
`QueryResultRenderer`. Since this PR removes `QueryChartConfig`, the
type swap had to follow the move and also reach `QueryResultRenderer`,
which is new and referenced the removed type. `QueryResultRenderer`,
`QueryResultError` and `DataGridResults` are otherwise untouched — the
empty/error-state centralization is fully preserved, and `QueryEditor`
still renders through it.

## Behavior worth a second opinion

`changeCellSource` **carries the query text across a backend change**
and rebrands it. This is probably not what a user wants — Postgres SQL
and logs SQL are separate dialects over separate schemas, so a
carried-over query will usually fail to run, and the rebrand asserts a
dialect the text was never written in.

Keeping it for now because it destroys nothing and needs no confirmation
prompt. The tradeoff is written up at the function. Worth revisiting
once we know whether people switch source to port an existing query or
to start a fresh one — if it's the latter, clearing the body behind a
confirmation is the better answer.

Results *are* dropped on a backend change, since another engine returns
unrelated columns.

## Incidental

`Explorer/types.ts` drops `QueryChartConfig`, which duplicated the wire
schema's `ChartConfig` field for field. `chart` stays persisted
alongside `view`, so switching to the table and back returns the user's
chart settings rather than rebuilding them.

## Verification

Typecheck, Prettier, and the lint ratchet clean. 1013 tests pass across
`state/`, the Explorer surfaces, notebooks, query sources, `data/sql`,
the SQL editor, and `components/ui`; 13 of them are new coverage for the
extracted helpers.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Improved notebook cell rendering with more consistent handling of
query and markdown cells.
- Query cells now preserve SQL, source settings, display preferences,
chart configuration, and query results when edited or switched between
sources.
  - Added a default limit of 100 rows for applicable database queries.

- **Bug Fixes**
- Prevented stale query results from carrying over when changing query
sources.
- Improved chart configuration consistency across query results and
display settings.

- **Tests**
- Added comprehensive coverage for query-cell updates, source
transitions, SQL changes, display state, and chart data.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 09:42:18 -04:00
Joshen Lim bddb806b57 Joshenlim/fe 4174 project creation ignores selected us east 1 region (#49092)
## Context

Addresses a bug on local only whereby when toggling HA in the project
creation form, the database region was getting fixed to eu-central-1
irregardless of the region that was chosen on the UI. Was a result of
old code that wasn't cleaned up when we introduced region selection for
HA locally.

Added regression test to cover this case as well 🙏 

## To test
Can only be tested locally
- [ ] On the project creation form, toggle HA and create a project in
us-east-1 - the project should be created in the selected region, and
not eu-central-1

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Fixed project creation so high-availability settings no longer replace
a manually selected database region.
- Smart-region providers continue using the selected smart or specific
region.

- **Tests**
- Added regression coverage to verify that manually selected regions are
submitted correctly in local high-availability environments.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 20:38:00 +07:00
Joshen Lim ebb8e2336e Centralize empty state + error handling for query results (#49096)
## Context

Related to Explorer/Notebook - currently with the chart view, if the
query has any errors, there's no error UI being shown
Mainly because the error UI handlers are all within the table view

Changes here hence opt to extract the empty state + error UI into a
centralized renderer

<img width="936" height="366" alt="image"
src="https://github.com/user-attachments/assets/437891dc-241e-4c43-97a6-6eef52472ee7"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added unified query result display for prompts, errors, empty results,
tables, and charts.
  * Query results now switch consistently between table and chart views.

* **Bug Fixes**
  * Improved empty-result layout centering across views.
  * Expanded error display to use the available width.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 19:57:36 +07:00
fadymak 17dde3d324 feat(account): let OAuth-only users add a password to their account (#49057)
Allows a user to add a password which automatically creates and email
identity to enable email + password authentication for OAuth-only
accounts.

Gated behind a feature flag: `enableAccountPassword`

When a user does not have an email identity, allow them to set a
password:

<img width="762" height="284" alt="Screenshot 2026-08-13 at 14 52 53"
src="https://github.com/user-attachments/assets/70b4883a-ed38-488a-a1b7-908caa112a0b"
/>

Password modal:

<img width="519" height="423" alt="Screenshot 2026-08-13 at 14 56 57"
src="https://github.com/user-attachments/assets/56ac370d-9e6c-4b05-986f-3aa9a51826c2"
/>

Email identity has been created, allow unlinking and/or updating email
address or password:

<img width="764" height="285" alt="Screenshot 2026-08-13 at 14 55 04"
src="https://github.com/user-attachments/assets/5d9d7692-f4e3-4638-958d-15fefad01333"
/>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * OAuth-only accounts can set a password from Sign-in methods.
* Added password visibility controls, validation guidance, and success
or error feedback.
  * Sign-in methods display the account email when available.

* **Updates**
* Renamed “Account identities” to “Sign-in methods” throughout account
preferences.
* Standardized password requirements across password setup and reset
forms.
* Setting a password refreshes the current session and signs out other
sessions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 14:56:23 +02:00
Charis b5bfc70c06 fix(studio): correlate a query's SQL brand with the backend it runs against (#49074)
Fourth of the stack; PRs 1–3 (#49069, #49070, #49072) have merged, so
this now targets `master` directly.

**Rebased onto latest `master`.** See "Conflict resolution" at the
bottom for what was reconciled.

## The bug

`QueryEditor` took `sql: string`, so a query's dialect brand died at the
prop boundary and the component re-branded whatever it was handed based
on a separately-passed `source`. Nothing tied the two together, which
meant nothing stopped Postgres SQL from reaching the analytics endpoint.

Explorer query drafts made it concrete. `explorer-query.ts` branded
**every** draft with `untrustedSql` regardless of source:

```ts
uncheckedSql: untrustedSql(sql)   // even for a logs draft
```

and the editor then re-branded that same text with `untrustedLogSql` at
run time for a logs draft — laundering a Postgres-branded value straight
through the boundary that `safe-analytics-sql.ts` exists to defend. The
brands are deliberately disjoint precisely so this can't happen; passing
plain strings around defeated it.

## The fix

Both carriers are now tagged by backend, so one `_tag` check narrows the
SQL brand and that backend's parameters together.

- **`ExplorerQueryDraft`** becomes `DatabaseQueryDraft |
LogsQueryDraft`, and `toDraft` is the single place a persisted string
re-enters the type system — branded for the backend its binding names.
The draft is rebuilt rather than mutated in place, since a backend
change changes which brand its SQL carries.
- **`QueryEditor`** takes one discriminated `query` prop instead of
`sql` + `source` + `rowLimit`. The tag picks both the brander at the
editor boundary and the execution endpoint, so the mismatch is no longer
expressible.
- The two `acceptUntrusted*` promotions stay **inlined** in the run
handler rather than factored into a shared helper, so each stays visible
next to the user gesture that authorizes it, per the safe-SQL model.
- **`rowLimit` moves onto the database member.** Logs execution has no
use for it — `applyAutoLimit` is Postgres-specific — so it no longer
sits on a shared type where it reads as meaningful for both.

## Local storage

Existing query drafts shape-mismatch and fall back to a database binding
via the existing `safeParse` guard — harmless, and notebooks are still
behind the `explorer` flag so there is no saved server content in play.

## Conflict resolution

`master` moved inside every file this PR touches. The type change is
applied on top of that work; nothing was reverted.

| Preserved from `master` | Where |
|---|---|
| zod parsing of persisted drafts (`persistedDraftsSchema`,
`persistedDraftSchema`) | `explorer-query.ts` |
| `MAX_PERSISTED_EXPLORER_QUERY_DRAFTS` cap, retaining
most-recently-updated | `explorer-query.ts` |
| debounced SQL persistence + `flushPendingPersistence`, immediate
write-through for rename/source | `explorer-query.ts` |
| `removeDraft` clearing pending timers | `explorer-query.ts` |
| `getQuerySourceBinding(cell)` and the four source-change branches,
incl. `database_identifier` / `time_range` propagation |
`QueryCell/index.tsx` |
| `restoredQueryKey` per `ref:id` and the `role="status"` loader |
`QueryTab.tsx` |
| `applyAutoLimit` relocated to `@/data/sql/utils` | `QueryEditor.tsx` |

Two adaptations were needed:

- `updateDraft` rebuilds the draft through `toDraft` instead of mutating
it in place — required, because the object's shape depends on its tag.
The debounced `persist` closure still re-reads `state.drafts[id]` at
fire time, so behavior is unchanged.
- Master's new test `falls back to the database source when persisted
source data is invalid` asserted `draft.source`, which the tagged union
replaces. Rewritten to assert the same intent against `_tag`.

**Dropped from this PR's original description:** it previously claimed
to fix a log cell always running against a synthesized default time
range. Master fixed that itself by adopting `getQuerySourceBinding`
(from #49072), so the claim no longer applies.

## Verification

Typecheck, Prettier, and the lint ratchet clean. 736 tests pass across
`state/`, the Explorer surfaces, notebooks, query sources, `data/sql`,
and the SQL editor — including master's new `QueryTab.test.tsx`,
`ExplorerQuerySourceMenu.test.tsx`,
`ExplorerQueryTabCoordinator.test.tsx`, and the five draft-store tests
added since this branch was cut.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
  - Improved Explorer query handling across database and logs backends.
- Preserved query text when switching backends while clearing
incompatible results.
  - Retained results when changing parameters within the same backend.
- Improved restoration of saved drafts, including fallback handling for
legacy or invalid sources.
- Added validation before executing edited SQL to help prevent invalid
requests.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 08:49:54 -04:00
Charis 0ed49231b7 refactor(studio): unify CellSource and the SQL editor's QuerySource into QuerySourceBinding (#49072)
Third of a stack. **Stacked on #49070** (which is stacked on #49069) —
review those first. Base retargets automatically as each merges.

Mechanical throughout; no behavior change.

## The problem

Three types described where a query runs, and no two agreed:

| | shape |
|---|---|
| `CellSource` (registry) | `{ id, type, parameters: { … } }` — `id` and
`type` always held the same literal |
| `QuerySource` (SQL editor) | `{ type: 'database' } \| { type: 'logs',
dateRange }` |
| notebook cells | flat per-backend fields, neither of the above |

Anything crossing between them needed a translation that dropped fields
on the way — which is how a notebook cell's replica selection had
nowhere to go.

## What changed

One `QuerySourceBinding`: a backend `_tag` with that backend's
parameters spread flat beside it, borrowed from the wire schema (#49069)
so the binding and the persisted cell agree by construction.

- **`QuerySource` is deleted.** `useRunSource` returns the shared
binding, so `runSource.type`/`dateRange` become `_tag`/`time_range`
across the SQL editor — that is most of the file count here.
- **`getQuerySourceBinding`** projects a notebook cell onto a binding;
**`toQuerySourceBinding`** does the same for any backend-tagged carrier.
Both overloaded so an already-narrowed caller gets the matching binding
back rather than the union, which keeps the result spreadable without
re-narrowing.
- **`ExplorerQuerySourceMenu`** drops its inline copy of the
custom-range and upgrade-prompt logic in favor of `useLogsCustomRange`,
which the SQL editor menu already used.

The registry keeps only what is genuinely runtime: endpoints, labels,
icons, availability, defaults. What a query *is* stays in the wire
schema.

## Verification

Typecheck, Prettier, and the lint ratchet clean. 405 tests pass across
the notebook schema, query sources, the logs components, the SQL editor,
and the Explorer surfaces.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Updated query source handling across Explorer and SQL Editor for a
more consistent selection experience.
* Database and log sources now preserve identifiers and time ranges more
reliably when switching or editing queries.
* Source menus, labels, icons, validation, and query execution now
reflect the selected source more accurately.

* **Bug Fixes**
* Invalid or outdated saved source settings now safely fall back to a
database source.
* Improved log-source detection and time-range handling throughout query
editing and execution.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-08-14 15:09:29 +07:00
Charis c0e109f662 refactor(studio): borrow the wire schema's time range in the query-source registry (#49070)
Second of a stack. **Stacked on #49069** — review that one first; this
PR's diff only makes sense on top of it. Base will retarget to `master`
automatically when #49069 merges.

Net `-72` lines. No behavior change beyond the one noted at the bottom.

## The problem

The query-source registry carried its own `LogTimeRange` type and
`logTimeRangeSchema`, which had drifted from the notebook wire schema's
copy in four ways:

| | wire schema | registry |
|---|---|---|
| discriminant | `_tag: 'relative_time_range'` | `type: 'relative'` |
| absolute bounds | `start` / `end` | `from` / `to` |
| relative units | minute…year | minute, hour, day |
| validation | none | positive int, end-after-start |

Two definitions of one concept, neither convertible to the other without
a lossy mapping — and the notebook query cell was papering over it by
discarding a log cell's persisted range and substituting a default.

## What changed

#49069 moved the validations onto the wire schema's `timeRangeSchema`
and exported it. This PR deletes the registry's copy and points every
consumer at `TimeRange`. The registry keeps what is genuinely runtime:
endpoints, labels, availability, defaults.

The field renames ripple mechanically through the logs date-picker
helpers, the time-range submenu, `useLogsCustomRange`, the SQL editor's
session state, and their tests. Coverage for the absolute-range and unit
rules moved to `notebook-schema.test.ts` in #49069, alongside the schema
that now owns them.

`ExplorerQuerySourceMenu` also drops its hand-rolled custom-range
construction in favor of `customDateRangeToLogTimeRange`, which already
existed and does the same clamping.

## One behavior change

`logTimeRangeToDatePickerValue` now renders a range whose unit has no
picker preset (week, month, year — allowed by the wire schema, not
offered in the UI) as a resolved absolute range, instead of trying and
failing to build a helper for it. Previously unreachable, since the
registry's narrower unit set made those ranges unrepresentable.

## Verification

Typecheck, Prettier, and the lint ratchet clean. 401 tests pass across
the notebook schema, query sources, the logs source components, the SQL
editor, and the Explorer surfaces.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
  * Improved log time-range handling across Explorer and SQL Editor.
* Custom date ranges now display and resolve correctly, including
clamping invalid ranges.
* Unsupported relative time units are converted to compatible absolute
date-picker values.

* **Refactor**
* Standardized log queries on a shared time-range format for more
consistent validation and behavior.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-08-14 13:45:41 +07:00
Saxon Fletcher 39c3960215 fix(studio): harden Explorer query persistence (#49039)
<img width="1690" height="1034" alt="image"
src="https://github.com/user-attachments/assets/2dc5b10b-8e64-413b-861e-8b0b62e2d880"
/>

## Summary

- debounce draft persistence and flush pending edits when the page exits
- validate untrusted local storage with Zod, recover from malformed
entries, and retain the 50 most recently updated drafts
- harden route restoration, recent-item routing, close confirmation, and
local cleanup
- disable execution while project or replica data is resolving and fail
closed for missing replicas
- use an HTTP-safe UUID generator for self-hosted Studio
- adopt the upstream Explorer toolbar title API
- expand component and state coverage for persistence and execution
behavior

## To test

1. Open Explorer, select **Run SQL**, then enter SQL and rename the
query.
2. Reload the page and confirm the draft is restored; close its tab and
confirm it is discarded after the prompt.

## Why

This layer makes local-only Explorer drafts resilient to rapid edits,
reloads, stale browser data, and tab lifecycle edge cases.

## Impact

Queries remain local-only, and closing their tabs discards them after
confirmation. Save-as-notebook functionality remains intentionally out
of scope.

## Validation

- fresh non-incremental Studio TypeScript check
- 68 Vitest tests pass across Explorer, query sources, tabs layout, and
query/tab state
- Studio ESLint ratchet and Prettier check both clean


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Explorer query drafts now save automatically and restore reliably
across navigation, tab closures, page exits, and visibility changes.
- Recent query items now open directly to their associated Explorer
query.
- Logs time-range selections are handled consistently, including custom
ranges and preset matching.

- **Bug Fixes**
  - Prevented stale query loading states when switching between queries.
  - Improved handling of invalid or outdated saved drafts.
  - Limited saved drafts to the 50 most recently updated queries.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 13:16:54 +07:00
Danny White 2c8cc7ec8a feat(studio): relocate read replica modules under Infrastructure (#49043)
## What kind of change does this PR introduce?

Feature. Stack 1 of 5 for
[PIPE-1007](https://linear.app/supabase/issue/PIPE-1007/move-read-replicas-out-of-replication-into-infrastructure).

## What is the current behavior?

Read replica UI lives under Database / Replication.

## What is the new behavior?

Moves replica form, row, and modals into Settings/Infrastructure and
extracts `REPLICA_STATUS` plus path helpers. URLs and user-facing
behaviour are unchanged.

## Additional context

Keep `infrastructure:read_replicas` off in prod until the full stack
lands.

Stack: this PR →
[#49044](https://github.com/supabase/supabase/pull/49044) →
[#49045](https://github.com/supabase/supabase/pull/49045) →
[#49046](https://github.com/supabase/supabase/pull/49046) →
[#48921](https://github.com/supabase/supabase/pull/48921)

## To test

Open [Database /
Replication](https://studio-staging-git-danny-pipe-1007-01-relocate-701014-supabase.vercel.app/dashboard/project/_/database/replication?destinationType=Read+Replica).
Confirm add replica still works as today. No new Infrastructure section
yet.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added navigation for viewing a specific read replica and starting the
add-replica setup flow.
- Improved read-replica setup validation, including unsupported regions
and invalid PostgreSQL versions.

- **Bug Fixes**
  - Corrected default region and success messaging behavior.
- Prevented incomplete pricing labels and clarified eligibility
warnings.
  - Improved display handling for localized pricing values.

- **Tests**
- Added coverage for read-replica navigation paths and fallback
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 15:21:24 +10:00
Joshen Lim 67d4fed40d Joshenlim/fe 4157 explorer migrate results component into explorer (#49066)
## Context

Related to Notebooks/Explorers - this one's just shifting files from the
SQLEditor into more generic folders from a file organization POV, such
that files under the Explorer folder have no dependency on files within
the SQLEditor folder

Mainly
- UtilityTabResults.utils: `getSqlErrorLines`
  - Moved into `data/sql/utils.ts`
- SQLEditor.utils: `applyAutoLimit`, `getSqlErrorLines`,
`trimTrailingSemicolons`
  - Moved into `data/sql/utils.ts`
- SQLEditor/UtilityPanel: `ResultCell`, `Results`, `CellDetailPanel`
  - Moved into `components/ui/DataGridResults`
  - Also shifted corresponding tests over here
- Also addressed some `any` type casts 

## To test
- Just need to ensure that the SQL Editor still works as expected

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Standardized query results across the Studio with a shared data grid.
* Improved result-table formatting, column sizing, clipboard handling,
and large-value display.
  * Added safer automatic row limits for eligible SQL queries.
  * Centralized SQL error display and formatting utilities.

* **Refactor**
  * Improved type safety for query rows and cell values.

* **Tests**
* Added comprehensive coverage for result-grid and SQL utility behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 11:29:39 +07:00