mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 10:55:06 +03:00
fix/api-keys-array-coerce
5990
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4b8509db2b |
fix(studio): use shared EMPTY_ARR for api-keys fallback
A fresh `[]` literal on every fetch breaks referential equality for downstream consumers (the useMemo in Landing.utils.ts re-runs on every render). Use the shared EMPTY_ARR instance, matching the idiom already used by lint-query, schemas-query, fdws-query and friends. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V9mYmaGzoXkrJtTkrLKaVA |
||
|
|
61e9818599 | Merge branch 'master' into fix/api-keys-array-coerce | ||
|
|
2a3025df25 |
feat(studio): role inference core for scoped pat (#48805)
## 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? Logic-only extraction from #48742. Scoped PATs are enforced server-side as the intersection of the token's granted scopes and the owner's live role, re-checked on every request. This lands the pure inference layer that will power advisory (never blocking) UI feedback; no UI consumes it yet. - FGA_SCOPE_MINIMUM_ROLE: all 83 permission scopes transcribed from the OpenFGA model's role unions, mapped to the lowest base role that holds them. A drift-guard test pins the key set to the scope ids published in @supabase/shared-types, so upstream additions fail CI here with re-transcription instructions. - estimateRoleLevel: derives the user's base role per org (or per project for project-invited members) from the ungated /platform/profile/ permissions rows via four discriminating ABAC probes. Works for every member type with no permission-gated endpoint. - computeTokenRoleContext + applySelectionToRoleContext: role resolution (expensive, memoized) is split from selection evaluation (cheap, re-run per permission toggle). AccessToken.permissions.ts gains only what the roles module needs: the PermissionLevel type and the catalog's `level` field (decides whether an org or project role governs a resource), plus getEntryScopes, which selectionToScopes now reuses. The UI-only additions from #48742 (risk badge/dot variants, mode labels, the OverallRisk.text -> description rename) are deliberately left out so this PR touches no .tsx. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added role-aware evaluation for scoped access-token permissions. * Added support for organization- and project-level permission scoping. * Added guidance when selected permissions exceed the current role, including read-only downgrades and inaccessible resources. * Added clearer grouping of permission access issues by resource. * **Tests** * Added comprehensive coverage for role mapping, permission evaluation, scoping, and failure scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Wen Bo Xie <wenbox323@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
33008a39e5 |
chore(studio): remove scoped pat orphaned form (#48803)
## 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? First step in breaking down #48635 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Removed the scoped access-token form, including token details, expiration settings, resource access, and permission configuration. * Removed resource and permission selection controls from the access-token workflow. * **Tests** * Removed automated coverage for access-token validation, permission handling, expiration logic, and resource selection. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Wen Bo Xie <wenbox323@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
cddb430310 |
feat(studio): scoped pat root branch (#48384)
## Description This is the Scoped PAT stacked PRs root branch ## How to test ### With the `scopedPAT` enabled (default on staging) Go to https://studio-staging-git-scopedpat-merge-token-lists-supabase.vercel.app/dashboard/account/tokens. - You shouldn't see two tabs anymore - If you had classic tokens, they should have the _Legacy_ badge - You can create scoped tokens - You have a way to copy newly created tokens before closing the form side panel ### With the `scopedPAT` disabled (use the devtool to override) - You shouldn't see two tabs anymore - If you had classic tokens, they should **not** have the _Legacy_ badge - You can create classic tokens - You have a way to copy newly created tokens above the list upon form submission <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Show classic and scoped access tokens together in one list, with classic tokens labeled “Legacy” when the scoped experience is enabled. * Add scoped access token creation with a two-step configure → review → success flow (when enabled). * Add a dismissible migration notice about scoped tokens with a link to API docs. * Show “View permissions” only for scoped tokens. * **Bug Fixes** * Token deletion now supports both classic and scoped tokens with the correct confirmation and success handling. * The scoped tokens page now redirects to the unified access tokens page. * **Accessibility** * Improved accessibility by adding a label to the token “more options” action. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ali Waseem <waseema393@gmail.com> Co-authored-by: kemal.earth <606977+kemaldotearth@users.noreply.github.com> |
||
|
|
2afb87af05 |
fix(ui): add bottom padding to scroll container in RLS search (#48759)
Fixes FE-4075. ## What kind of change does this PR introduce? The footer displaying the total number of RLS policies overlaps the last search result in the RLS Policy Search dialog. As a result, the last policy entry is partially hidden and cannot be fully read when scrolling to the bottom. ## What is the current behavior? The search results container now reserves space for the footer, preventing it from overlapping the last search result. All policy entries remain fully visible when scrolling to the bottom. <img width="400" height="300" alt="image" src="https://github.com/user-attachments/assets/46529ca4-bdce-4fa2-b0ba-ea87e769cc24" /> ## What is the new behavior? <img width="400" height="300" alt="CleanShot 2026-08-05 at 18 19 27@2x" src="https://github.com/user-attachments/assets/093a3f9e-fd4c-4ff6-b483-2839f3916d13" /> ## How to test - Open a project in the Supabase Dashboard. - Navigate to Database → RLS Policies. - Open the policy search dialog. - Search for a term that returns enough results to make the list scrollable - Scroll to the bottom of the results. The [database.sql](https://gist.github.com/monicakh/49b5ff201893eb43aea329395b3f635b) to create the tables/policies to test. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved scrolling in policy search results. * Added spacing at the bottom so results remain visible above the fixed footer. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
840127cd69 |
let inline error callers own mutation failures (#48640)
## What kind of change does this PR introduce? Code clean-up following #48470, #48471, #48472, #48473, and #48474. ## What is the current behavior? Mutation hooks provide fallback error toasts, so callers that already render errors inline must suppress those toasts with empty `onError` handlers. ## What is the new behavior? The affected callers own their error presentation. Inline interstitial errors remain unchanged, API authorisation retains its state-reset handlers, and Project Claim retains its combined caller-owned toast. ## To test There is no useful before-and-after visual check for this PR: the rendered error states should be identical on `master` and this branch. The change only removes the default-toast and no-op-handler pair underneath the UI. The existing [Organisation Invite](https://github.com/supabase/supabase/pull/48470), [API authorisation, AWS Marketplace](https://github.com/supabase/supabase/pull/48471), and [Stripe Projects](https://github.com/supabase/supabase/pull/48472) failure tests cover the inline errors and confirm that no duplicate toast appears. |
||
|
|
93b5ae71bf |
chore: remove unused useProjectUsageStats hook (#48792)
## Problem `useProjectUsageStats` (`apps/studio/hooks/analytics/useProjectUsageStats.tsx`) has no importers anywhere in the codebase — dead code, and it also still queries BigQuery directly (`logs.all`, no OTEL path), which would've made it another gap in the reports→ClickHouse migration if it were ever wired up. ## Fix Deletes the file. Confirmed nothing imports it, and none of its own imports (`useFillTimeseriesSorted`, `useTimeseriesUnixToIso`, `genChartQuery`, `EventChart`) become unused as a result — all are still used elsewhere. ## How to test - `pnpm tsc --noEmit` — no errors referencing the removed file. - `pnpm vitest run hooks/analytics` — 28 tests pass, no breakage. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Removed the project usage analytics statistics feature, including its data retrieval, time-series processing, filtering, refresh controls, and loading/error states. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8618991b6f |
Initialize explorer home page (#48790)
## Context More groundwork for the Explorer - initializing the home page Note that nothing here is functional, all just visual still <img width="1387" height="960" alt="image" src="https://github.com/user-attachments/assets/d4967578-edbd-476f-8150-d9d5e9d66666" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a new Explorer landing page with an assistant chat form. * Added quick actions for creating notebooks and SQL work. * Added notebook and chat template cards for faster project exploration. * **Improvements** * Explorer content now fills the available page height. * Assistant send button styling now reflects whether submission is available. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
21919ec9b8 | feat(pipelines): Use new restart endpoint (#48737) | ||
|
|
51c5b9f013 |
chore: sync ssl enforcement and temporary access (#48743)
## 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 - fix-up ## What is the current behavior? Temporary access depends on ssl enforcement. The frontend doesn't enforce this very well or keep state between the two configs. ## What is the new behavior? This updates the two configs to be interdependent and updates to each one triggers a frontend state change on the other. ## Additional context Before: https://github.com/user-attachments/assets/8f040b62-587c-4268-9e27-27dd09b052a3 After: https://github.com/user-attachments/assets/c62e006e-6147-4c94-b6cf-375ca300b890 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added confirmation dialogs and downtime warnings before changing database SSL enforcement. - Added loading states and success or failure notifications for SSL updates. - Enabled SSL enforcement directly from temporary database access settings. - **Bug Fixes** - Prevented SSL enforcement from being disabled while temporary database access is enabled. - Improved settings refresh after SSL enforcement changes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4550ee18a4 |
Initialize tabs UI for explorer (#48789)
## Context Continued ground work for Explorer - just initializes the Tab UI for Explorer as such: - Plan is to continue using the existing tabs store + EditorTabs component - Purely visual, nothing functional <img width="1389" height="556" alt="image" src="https://github.com/user-attachments/assets/d46c5ae7-01a8-4887-9452-11b98327d6bf" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an Explorer workspace with animated navigation and tab controls. * Added a home tab and a new-tab menu for creating notebooks, with chat creation shown as unavailable. * Added support for notebook tabs in the editor and Explorer navigation. * Added flexible tab layouts with custom tab content, optional new-tab actions, and configurable collapse controls. * Improved editor navigation to recognize Explorer workspaces alongside existing table and SQL editors. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a7671019a8 |
Scaffold the explorer layout (#48740)
## Context Resolves FE-4074 Just adds scaffolding for the explorer UI - no data fetching yet. Initializes the page + side nav, based off Saxon's POC in `poc/explorer-prototype` <img width="1389" height="500" alt="image" src="https://github.com/user-attachments/assets/8f293992-97d9-403e-91d6-2e104cd20eb5" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features - Added a project Explorer page accessible from `/project/:ref/explorer`. - Added navigation for browsing notebooks and chats. - Added search fields, back navigation, animated transitions, and empty states for Explorer sections. - Added a conditional Explorer link to the SQL Editor menu when enabled. ## Documentation - Marked the Explorer route migration as complete in the migration checklist. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6b1fc3d11d |
recover failed Vercel deploy connections (#48474)
## What kind of change does this PR introduce? Bug fix. ## What is the current behavior? A failed Vercel connection after project creation is only logged, leaving the project-creation screen in its loading state. ## What is the new behavior? The flow preserves the created project and shows the connection error with retry and open-project actions in the standard project-creation footer. Project-creation failures remain ordinary inline form errors. Connection failures are owned by this flow without a duplicate toast or a no-op error handler. | Before | After | | --- | --- | |  | <img width="1024" height="563" alt="Create Vercel Project Supabase" src="https://github.com/user-attachments/assets/b7d3fdca-d7a0-4b50-9231-3cf7dc371a87" /> | ## To test ### Before on master 1. Switch to `master`. 2. With local Studio running and while signed in, open an organisation you can access. Copy its slug from `http://localhost:8082/org/<YOUR_ORG_SLUG>`. 3. Open `apps/studio/components/interfaces/ProjectCreation/ProjectCreationForm.tsx`. 4. Find `isSuccessNewProject={isSuccessNewProject}` in the `ProjectCreationFooter` props and temporarily change it to: ```tsx isSuccessNewProject={true} ``` 5. Replace `<YOUR_ORG_SLUG>` in this URL with the slug from step 2, then open it: `http://localhost:8082/integrations/vercel/<YOUR_ORG_SLUG>/deploy-button/new-project`. 6. Confirm **Create new project** remains in its loading state and there is no error, retry action, or route to the created project. This represents the current stuck state. 7. Revert the temporary edit before switching branches. ### After on this branch 1. Switch to `dnywh/vercel-deploy-recovery`. 2. With local Studio running and while signed in, open an organisation you can access. Copy its slug from `http://localhost:8082/org/<YOUR_ORG_SLUG>`. 3. Open `apps/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx`. 4. Find the conditional beginning with `newProjectRef === undefined` inside `InterstitialLayout`. 5. Replace that whole conditional with: ```tsx <VercelConnectionError projectRef="abcdefghijklmnopqrst" message="Connection request failed" onRetry={() => undefined} /> ``` 6. Replace `<YOUR_ORG_SLUG>` in this URL with the slug from step 2, then open it: `http://localhost:8082/integrations/vercel/<YOUR_ORG_SLUG>/deploy-button/new-project`. 7. Confirm the admonition says **Unable to connect to Vercel** and **Your Supabase project was still created. Error: Connection request failed**. 8. Confirm **Open project** and **Retry connection** appear as compact, right-aligned footer buttons. The retry action is intentionally inert in this visual-only mock, and no project or Vercel connection is created. 9. Revert the temporary edit. ## Additional context Follows #48473. The consistency follow-up #48640 is stacked on this PR. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added inline error messages to project creation forms for integration, API, and validation failures. - Added clear Vercel connection states, including waiting, connecting, success, and error screens. - Added retry actions and links to open successfully created projects. - **Bug Fixes** - Improved error handling so Vercel connection issues remain visible in context instead of appearing only as notifications. - **Tests** - Added coverage for partial-success messaging, project links, and retry behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
a28214c236 |
feat(studio): add ClickHouse OTEL SQL for the Auth report's v2 metrics (#48750)
## Problem Part of DEBUG-73 (migrate reports queries to the OTEL/ClickHouse endpoint). The Auth report's v2 metrics (ActiveUsers, SignInAttempts, PasswordResetRequests, TotalSignUps, sign-in/sign-up processing time, error breakdowns) currently only query the BigQuery-backed logs.all endpoint. ## Fix Adds `AUTH_REPORT_SQL_OTEL`, a ClickHouse-dialect mirror of the existing `AUTH_REPORT_SQL`, covering all 10 metrics. Threads a `useOtel` parameter through `fetchLogs` and the three report config creators (`createUsageReportConfig`, `createErrorsReportConfig`, `createLatencyReportConfig`), defaulting to `false` everywhere. This PR is inert on its own: nothing yet passes `useOtel: true`, so it changes no runtime behavior. The follow-up PR (stacked on this one) wires the `otelReports` feature flag through the Auth report page to actually select the OTEL SQL. Also includes: one dataProvider now validates its raw rows with a Zod schema instead of casting to `any`, and removal of a few functions in this file that had zero callers (`AUTH_ERROR_CODE_VALUES`, `createAuthReportConfig`, an exact duplicate of a status-code color map, an unused hook). ## How to test - Unit: `cd apps/studio && npx vitest run data/reports/v2/auth.config.otel.test.ts` - No manual testing needed for this PR alone since it changes no runtime behavior (useOtel defaults to false, unwired). The follow-up PR covers manual testing of the actual flag-gated behavior. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added OpenTelemetry-backed authentication reports. * Authentication reports now include usage, errors, latency, sign-ins, sign-ups, and edge-log metrics. * Added filtering by provider, status code, action, and time range. * Added selectable telemetry sources for retrieving report logs. * **Bug Fixes** * Improved validation of authentication error codes. * Improved handling of missing report data with consistent empty results. * Improved report formatting for more consistent attribute display. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8831e15fc3 |
Revert "refactor(studio): static tab kind registry and tab id codec (PR 1/9)" (#48762)
Reverts supabase/supabase#48718 |
||
|
|
aed332b663 |
feat: migrate Edge Functions report to ClickHouse OTEL logs (#48756)
## Problem
The Edge Functions report (`observability/edge-functions`) only queries
BigQuery. As part of the broader Reports→ClickHouse OTEL migration
(DEBUG-73), we need each report migrated one at a time behind the
`otelReports` flag.
## Fix
Adds a ClickHouse OTEL SQL variant (`METRIC_SQL_OTEL`) for the 4 Edge
Functions metrics (TotalInvocations, ExecutionStatusCodes,
InvocationsByRegion, ExecutionTime), querying the unified `logs` table
filtered to `source = 'function_edge_logs'`, with fields read from
`log_attributes` (`function_id`, `response.status_code`,
`response.headers.x_sb_edge_region`, `execution_time_ms`) — the same
mapping already used by `edge-functions-last-hour-stats-query.ts`.
`edgeFunctionReports()` now takes a `useOtel` flag that picks between
the BQ and OTEL query sets and forwards it to `fetchLogs`. The page
wires this up via `useFlag('otelReports')`, matching the pattern used
for the Auth report. No behavior change while the flag is off — report
still fetches from BigQuery.
Also removed two pieces of dead code spotted in `report.utils.ts` while
touching it: the unused `useEdgeFnIdToName` hook and a
`STATUS_CODE_COLORS` map that was an exact duplicate of
`REPORT_STATUS_CODE_COLORS` (the one actually imported elsewhere).
This PR is standalone — no dependency on the in-flight Auth report OTEL
stack.
## How to test
- `pnpm vitest run data/reports/v2/edge-functions.config.otel.test.ts` —
9 new tests covering the OTEL SQL shape (single logs table,
unix-microsecond timestamp bucketing, field mapping, filters).
- `pnpm vitest run data/reports` and `pnpm vitest run
data/edge-functions components/interfaces/Reports` — existing suites (46
+ 54 tests) still pass, confirming no regression to the BQ path.
- Manually: with `otelReports` flag enabled, visit a project's Edge
Functions observability report and confirm charts render from the
ClickHouse endpoint.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added OpenTelemetry support for Edge Functions observability metrics,
including invocations, status codes, regional activity, and execution
time.
* Reports can now dynamically use either the standard or OpenTelemetry
logs source.
* **Bug Fixes**
* Improved filtering and timestamp handling for OpenTelemetry-based Edge
Functions metrics.
* Added coverage for status, execution time, function, and region
filters.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
55095dcd00 |
chore: highlight totp app friendly name (#48755)
## 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? UI update ## What is the current behavior? We only show the alternative factor's name, if one exists. ## What is the new behavior? When presenting user with the MFA screen, make the MFA factor's friendly_name appear. ## Additional context Before: <img width="456" height="371" alt="Screenshot 2026-08-05 at 15 41 07" src="https://github.com/user-attachments/assets/7d506641-6a9e-49fe-8c40-98c1eef4b384" /> After: <img width="459" height="394" alt="Screenshot 2026-08-05 at 15 38 27" src="https://github.com/user-attachments/assets/034312ba-691e-4f56-b4e3-a82df2a17273" /> <img width="468" height="434" alt="Screenshot 2026-08-05 at 15 37 43" src="https://github.com/user-attachments/assets/4c585eae-b8e2-4f93-8210-2c8ac7c20278" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved multi-factor authentication prompts with clearer formatting and more consistent factor labels. * Ensured the primary code label appears whenever a verification factor is selected. * Added a fallback label for authentication factors without a display name. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ffd6d6636d |
refactor(studio): static tab kind registry and tab id codec (PR 1/9) (#48718)
## Summary First PR in the tab/snippet decoupling stack. Purely additive: no existing call sites change behavior except the `EntityTypeIcon` rewire, which preserves its API exactly. - **`state/tabs/kinds.ts`** — static `TAB_KINDS` descriptor table (`TabKind`, `TabSurface`, `surfaceOf`, `kindsOnSurface`, `isTabKind`). Leaf-safe: its only reference to the domain `Tab` type is a type-only import, so it stays importable at module scope (needed later for the valtio store and the persistence migration reader) without creating a runtime cycle. - **`state/tabs/kinds.icons.tsx`** — per-kind icon leaf module (`ui` + `lucide-react` + `TabKind` type only), plus the preserved `LogsSnippetIcon`. - **`state/tabs/tab-id.ts`** — `createTabId` / `parseTabId` / `toUrlSegment` / `parseUrlSegment(segment, surface)` codec. `parseUrlSegment` is surface-scoped: a bare segment only resolves to a kind when the surface has exactly one bare kind (true for `sql`). The table surface has five bare kinds (`r`/`v`/`m`/`f`/`p`) with no URL disambiguator between them, matching `/editor/[id]`, which learns kind from the fetched entity rather than the URL — so a bare table segment correctly resolves to nothing. - **`components/ui/EntityTypeIcon.tsx`** — rewired to a thin wrapper delegating to `kinds.icons.tsx`, preserving its exact prop API (`type`, `size`, `strokeWidth`, `isActive`, `sqlSource`) for all existing consumers. - **`state/tabs/tab-id.test.ts`** — codec round-trips per kind, bare-vs-prefixed URL segments, the `templates`/`examples`/`new` sentinels, and surface scoping (including the table-surface ambiguity above). Full plan: `apps/studio/TABS_DECOUPLING_PLAN.md` (not included in this PR). ## Test plan - [x] `pnpm typecheck` - [x] `pnpm lint --filter=studio` (0 errors) - [x] `pnpm --filter studio run lint:ratchet` (warning counts did not increase) - [x] `pnpm test:studio` (full suite green, including 50 new/updated tests in `state/tabs/`) - [x] `pnpm format` (no-op) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added consistent icons and metadata for SQL, notebook, chat, table, view, and related tab types. * Added support for creating, parsing, and converting tab identifiers to URL segments. * Improved handling of tab types across SQL and table surfaces. * **Bug Fixes** * Invalid, empty, or ambiguous tab identifiers and URL segments are now rejected. * **Tests** * Added coverage for tab identifiers, URL conversion, supported tab types, and edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9952d6f10f |
[FE-4067] fix(studio): re-allow all regions in local project creation (#48704)
Local dev stacks can run in any of the three supported regions (e.g. Bobbie's is in `ap-southeast-1`), but enabling High Availability on the project creation form pinned local to Frankfurt only. This unrestricts local so all three regions are selectable again. **Changed:** - `getHighAvailabilityRegionCode()` returns `undefined` for `local` (same as prod), so `filterHighAvailabilityRegions()` no longer collapses the list — staging stays pinned to `us-east-1` - The three-region warning in `RegionSelector` now adds a local-only recommendation: "Use Central EU (Frankfurt) unless you're on a personal dev stack." - Updated unit tests, including an `ap-southeast-1` fixture region to prove pass-through ## To test - On a local stack, open the new project form and enable High Availability — the region selector should offer all three regions (East US, Frankfurt, Southeast Asia) instead of locking to Frankfurt, and the warning should recommend Frankfurt unless you're on a personal dev stack - Confirm staging behavior is unchanged (HA still pins to East US) - `pnpm --filter studio exec vitest run components/interfaces/ProjectCreation` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Local development projects can now use high-availability regions beyond Central EU. * Region filtering and availability messaging now correctly reflect the active environment, including staging restrictions. * **User Experience** * Added guidance recommending Central EU for local projects, unless using a personal development stack. * Region selection now provides clearer environment-specific information when options are limited. <!-- 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> |
||
|
|
3c811b9c29 |
fix(studio): extend SupportForm project waitFor timeout (#48211)
## What kind of change does this PR introduce?
Test flake fix.
## What is the current behavior?
`SupportFormPage` → “submits support request with attachments…” can fail
under CI load:
- expected project selector text `Project 1`
- received `No specific project`
Org is applied first; the project is filled asynchronously via
`onInitialLoad` after org projects fetch. That wait still used the
default ~1s `waitFor`, while every sibling Project 1 assertion already
uses `{ timeout: 5_000 }` (see #45852).
## What is the new behavior?
- Attachments test waits up to 5s for Organization 1 + Project 1
- Same timeout for the org-switch → Project 2 waiter (same pattern)
No production code changes.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Improved support form test reliability by allowing additional time for
organization and project selectors to load during asynchronous
interactions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
9b3e0a9060 |
show Vercel connection errors inline (#48473)
## What kind of change does this PR introduce? Bug fix. ## What is the current behavior? Vercel install and project-link failures use transient toasts. ## What is the new behavior? Failures remain visible below the relevant action and clear when the user retries or changes a selection. The Vercel mutation hooks expose errors without choosing their presentation. Interstitial callers render them inline, while existing non-interstitial callers explicitly retain their toasts. | Before | After | | --- | --- | | <img width="1024" height="759" alt="Install Vercel Integration Supabase" src="https://github.com/user-attachments/assets/6348cdd2-220a-4ad8-89f9-7fc51de36a3c" /> | <img width="1024" height="759" alt="Install Vercel Integration Supabase" src="https://github.com/user-attachments/assets/ecc50c4e-daab-4f6d-bf86-7282e2aff92c" /> | ## To test 1. Switch to `dnywh/inline-vercel-errors` (this branch). 2. Open `apps/studio/pages/integrations/vercel/install.tsx`. 3. Find the `actionError` assignment immediately below `useVercelIntegrationCreateMutation` and replace the whole assignment with: ```tsx const actionError = 'Creating Vercel integration failed: Test error' ``` 4. With local Studio running and while signed in, open `http://localhost:8082/integrations/vercel/install?code=test&configurationId=test&source=marketplace` 5. Confirm the error remains visible below **Install integration**. No Vercel installation or real authorisation code is required. 6. Revert the temporary edit. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Bug Fixes * Improved error handling across Vercel project connection and installation flows. * Validation, duplicate-connection, and connection failures now appear inline in the relevant setup steps. * Errors clear automatically when the selected project or organization changes. * Notifications remain available in supported flows, including new project creation and side-panel setup. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2165746784 |
fix(studio): keep SQL editor source menu open when switching sources (#48715)
## 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 ## What is the current behavior? Selecting Database/Logs in the SQL Editor's query-source dropdown closes the menu (Radix's default select behavior), so switching to Logs gives no visible indication that a Time range control just became available until the dropdown is reopened. ## What is the new behavior? Selecting a source keeps the dropdown open, so the newly-available source-specific controls (e.g. Time range for Logs) are immediately visible. ## Additional context Fixes FE-4036 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved source switching in the SQL editor so the selection menu remains open while changing between database and logs sources. * Ensured source-specific controls update correctly after switching. * **Tests** * Added coverage for source selection, menu behavior, and source-specific control updates. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5986fecc89 |
fix(studio): use table + card component in log retention upgrade prompt (#48713)
## Summary - Refactor the SQL Editor / Logs "Log retention" upgrade-prompt dialog to use the design system's `Card` + `Table` components instead of a custom flexbox-div table, matching the pattern in `apps/design-system/registry/default/example/table-demo.tsx` - No behavior or data change Fixes FE-4034 Non-blocking review nit from #48452 (comment: https://github.com/supabase/supabase/pull/48452#issuecomment-5128918096) ## Test plan - [x] `pnpm --filter studio typecheck` passes - [x] `pnpm --filter studio run lint:ratchet` passes (no new warnings) - [x] Prettier check passes <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Style** * Updated the upgrade prompt with a more consistent card and table layout. * Preserved existing plan names and log retention details. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b9053794a0 |
fix(studio): add tooltip explaining why Prettify SQL is disabled (#48712)
## 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 ## What is the current behavior? In the SQL Editor, the Prettify SQL action (both the "More actions" dropdown menu item and the toolbar button) is disabled for logs snippets, but gives no indication why. ## What is the new behavior? The disabled Prettify menu item now uses `DropdownMenuItemTooltip` and the disabled Prettify toolbar button uses `ButtonTooltip`, both showing "Can only prettify SQL queries" while disabled. Addresses review feedback from #48452 (Linear FE-4038). ## Additional context Resolves FE-4038 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Updated SQL editor tooltips with clearer, consistent messaging. * Log-source users now see an explanation when SQL formatting is unavailable. * Regular users continue to see the SQL prettify keyboard shortcut. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
89010c1649 |
fix(studio): show selected custom time range in SQL editor time range menu (#48709)
## What Display the actual selected custom date range in the Time Range dropdown's secondary text, instead of the static "Custom range" label. The range is formatted as `DD MMM, HH:mm - DD MMM, HH:mm` to match the existing format in the Logs Explorer's date-picker trigger button, ensuring visual consistency across the Logs UI. Fixes FE-4035 ## Test plan - [x] Typecheck passes: `pnpm typecheck` - [x] Manually verify: Open SQL Editor with `sqlEditorLogsSource` flag enabled, open the Time Range dropdown menu, select a Custom range, and confirm the dropdown's secondary text now displays the selected date range instead of "Custom range" <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Custom time ranges now display formatted start and end timestamps for clearer time selection. * Preset time ranges continue to show their existing helper text. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0791b04eb8 |
feat(sql-editor): roll out manual saving by default (#48706)
## 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? Feature — progresses the SQL Editor manual saving rollout, and removes a fully rolled out feature flag. ## What is the current behavior? Manual saving (snippets save only on an explicit Save / Cmd+S rather than autosaving every edit) is opt-in. It requires both the `sqlEditorManualSave` ConfigCat flag and the user turning on the "Disable snippet auto-saving" feature preview themselves. That flag is now fully rolled out. ## What is the new behavior? - `sqlEditorManualSave` is removed, so the feature preview is listed for everyone. (Delete the flag in ConfigCat after a few months.) - New `sqlEditorManualSaveForced` flag progresses the rollout. It forces manual saving on regardless of what the user stored previously, including an explicit opt-out, via a new `isForced` field on `FeaturePreview` that `initializeFlags` resolves ahead of the localStorage lookup — so the feature preview modal reflects the forced state too, not just the save behavior. Turning the flag off reverts everyone who never opted in, so it remains a working kill switch. - Users the rollout switches over get a one-time dialog on their first SQL Editor route, explaining that snippets no longer autosave. Dismissal persists in `sql-editor-manual-save-notice-dismissed` (allowlisted, so it survives sign-out). - Users who opted into the preview themselves never see the dialog — it records their dismissal up front instead, since the notice needs to outlive the feature preview and once the preview is retired there's no stored opt-in left to recognize them by. - The preview keeps its switch so users who lose their local storage can opt in early, but once the rollout reaches them the "Disable feature" button is disabled with a tooltip explaining why. ### To test Turn on `sqlEditorManualSaveForced` on via the dev toolbar. - No `supabase-ui-sql-editor-manual-save` and no dismissal key → dialog appears on `/project/<ref>/sql`, toolbar shows the Save button. Dismiss, reload → no dialog. - `supabase-ui-sql-editor-manual-save` set to `false` (previously opted out) → still forced onto manual saving, and still gets the dialog. - `supabase-ui-sql-editor-manual-save` set to `true` → no dialog, and the dismissal key is written automatically. - Flag off, no opt-in → autosave, no dialog, and the "Disable autosave" power-off button still opens the preview modal. - Preview modal while forced → "Disable feature" is disabled with a tooltip; another preview (e.g. Column-level privileges) still disables normally. ## Additional context |
||
|
|
0e71933ce3 |
[FE-4070] fix(studio): allow adding expressions to RLS policies (#48700)
A table RLS policy created via SQL without a `USING`/`WITH CHECK` clause
stores `null` for that field, and the policy editor's payload diff
skipped `null` fields entirely — so adding an expression later through
the dashboard closed the panel as if saved but persisted nothing. This
fixes the diff so those policies are editable, and cleans up adjacent
issues in the same code path.
**Changed:**
- Extracted the update-payload diff from `PolicyEditorPanel`'s submit
handler into a pure `generateUpdatePolicyPayload()` in
`PolicyEditorPanel.utils.ts`. A stored `null` definition/check now
counts as empty, so typing an expression into a previously empty editor
produces a payload field. The diff is branched by command so INSERT
policies only ever emit `WITH CHECK`, never an invalid `USING` clause.
- The required-expression validation ("Please provide a SQL
expression…") now applies only when creating a policy. When updating, a
`null` clause is valid, so rename-only and role-only saves on such
policies work; the update path instead rejects attempts to clear an
existing `USING`/`WITH CHECK` expression with an inline error (`ALTER
POLICY` can only replace an expression, not remove it).
- Saving with no changes now closes the panel without a round trip —
previously a null-vs-undefined comparison injected a
present-but-`undefined` payload key, which sent a literal `BEGIN;
COMMIT;` to the user's database.
- Fixed the unsaved-changes check comparing the form's lowercase command
against `'INSERT'` (never matched), which made closing an untouched
INSERT policy editor prompt about unsaved changes. It now compares
`selectedPolicy.command`.
**Added:**
- `PolicyEditorPanel.utils.test.ts` — 11 unit tests covering null→value
transitions for definition and check, INSERT command mapping,
value→value updates, no-op saves, and empty-value handling.
## To test
- Run in the SQL editor: `create policy "p1" on <table> for delete to
authenticated;` (no `USING` clause), then edit `p1` in Database →
Policies, add a `USING` expression, and save. Confirm via `select
pg_get_expr(polqual, polrelid) from pg_policy where polname = 'p1'` that
the expression persisted.
- Same for INSERT: `create policy "p2" on <table> for insert to
authenticated;`, then add a `WITH CHECK` expression via the editor and
confirm `polwithcheck` is set (and `polqual` stays null).
- On `p1` (still without a `USING` expression? recreate it if you added
one), rename the policy without touching the expression editors — the
rename should save successfully.
- Edit a policy that already has a `USING` expression, change it, and
confirm the new expression persists (regression).
- Open a policy and save without changing anything — the panel should
close with no `policy-update` network request.
- On a policy with an existing `USING` (or `WITH CHECK`) expression,
clear that editor and save — an inline error should appear and no
request should fire.
- Open an INSERT policy that has a `WITH CHECK` expression, change
nothing, and close the panel — it should close without an "Unsaved
changes" prompt.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Policy updates now submit only changed fields.
* Improved handling of policy expressions, including INSERT-specific
mappings.
* Prevented removal of existing `USING` or `WITH CHECK` expressions
where unsupported.
* Empty expressions are omitted from update requests.
* Updates are canceled when no changes are detected.
* **Tests**
* Added coverage for unchanged policies, expression updates, name and
role changes, and INSERT policy behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
|
||
|
|
ceace2e90b |
fix(studio): account for SQL result column headers (#48676)
## 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 ## What is the current behavior? Fixes #48672. The SQL Editor results grid calculates each column's initial width from cell values only. When a long final column contains a short value such as `NULL`, scrolling to the end of a wide result set reveals a truncated header even though the full column name is needed to identify the result. ### Before <img width="760" height="370" alt="Before: final SQL result column header is truncated" src="https://github.com/user-attachments/assets/f73b7540-fc45-4ddf-91b6-996afe41807e" /> ## What is the new behavior? The initial width now accounts for both the column name and its cell values while preserving the existing minimum and maximum width constraints. ### After <img width="760" height="370" alt="After: full SQL result column header is visible" src="https://github.com/user-attachments/assets/b289ab86-4277-46fc-ae9a-35c3eac5442f" /> ## Additional context The width calculation was extracted into a utility and covered for: - short headers and values - headers longer than their values - values longer than their headers - empty result sets - maximum-width capping Verification: - `pnpm --filter studio exec vitest --run components/interfaces/SQLEditor/UtilityPanel/Results.utils.test.ts tests/components/SQLEditor/Results.test.tsx` - `pnpm --filter studio run typecheck` - `pnpm --filter studio run lint:ratchet` - `pnpm run test:prettier` - `SKIP_ASSET_UPLOAD=1 pnpm run build:studio` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Improvements** - SQL query results now automatically size columns based on their headers and content. - Column widths remain within practical minimum and maximum limits for improved readability and usability. - **Tests** - Added coverage for minimum and maximum widths, content-based sizing, and empty result sets. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
21511042a3 |
feat(studio): assistant logs context and reports guard (#48514)
## 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? Feature — final PR (9/9) of the SQL editor logs-source stack. **Base branch:** `charislam/sql-editor-inline-ai-clickhouse-dialect` (PR 8). Nothing here is user-visible: entry points stay behind `sqlEditorLogsSource` + `otelLegacyLogs`, and flag rollout happens after the whole stack merges. ## What is the current behavior? - The Assistant has no idea a SQL editor snippet targets the logs backend. Ask it about a logs snippet and it answers in Postgres, because the attached query is fenced as ` ```sql ` and nothing tells the model otherwise. - Because the `sql` fence is what `MessageMarkdown` treats as runnable Postgres, an attached ClickHouse query is rendered with a Run-against-Postgres affordance and branded with `untrustedSql`. - "Debug with Assistant" on a failed logs query produces a dialect-less prompt, so both the in-app assistant and the copyable version get debugged as Postgres. - A report referencing a `log_sql` snippet runs its ClickHouse SQL against the user's Postgres database and surfaces the resulting error. ## What is the new behavior? **Assistant panel.** The "Current Query" chip records which backend the attached query targets. That reaches the model two ways: each attachment is fenced with its own dialect (` ```clickhouse ` vs ` ```sql `), and a `containsLogsSnippets` flag rides on the user message as AI SDK `metadata`. The server reads the flag off the conversation and prepends the ClickHouse dialect rules plus the logs schema reference as a non-cached context message. Two design points worth calling out in review: - The flag lives on the **message**, not the request body, so Retry and the tool-approval continuation reproduce the context a message was originally asked in — neither of those passes a per-call body. - It's derived from **what's actually attached**, so detaching the chip drops the claim rather than leaving the two able to disagree. The `clickhouse` fence also keeps a logs query out of `MessageMarkdown`'s `sql` branch, so it's no longer offered as runnable Postgres or branded with `untrustedSql` — a boundary this stack's distinct brands exist to prevent crossing. **Debug flow.** `buildDebugChatArgs` attaches its query with a source for the same reason, and names the dialect in the prompt text so the copyable version stands on its own outside the app. **Reports.** A report only stores a snippet id, so whether it queries the logs backend is only knowable once the content loads. `ReportBlock` guards on the fetched type and renders a `LogsSnippetReportBlock` placeholder instead of executing. Double-guarded: no `sql` for a logs snippet (so it's out of the query key and `queryFn` short-circuits even on an explicit `refetch`) and `enabled` excludes it. **Incidental cleanups.** `buildAssistantContextMessages` extracted out of `generate-assistant-response`; a schema-access sentinel that was duplicated as a string literal across two files (and compared against) replaced with one exported constant; `SqlSnippet` deduplicated to a single declaration; `resolveSnippetSource` / `isLogsSource` shared instead of re-implemented per surface. **Tests.** 4 new/extended suites. Notable cases pinned: a message with no metadata must validate (`safeValidateUIMessages` applies `metadataSchema` to *every* message, so a required schema would 400 every existing conversation); only *user* messages count, so a model reply can't talk the server into a different dialect; a mixed-attachment message is flagged without overclaiming a single source; and `ReportBlock` registers no pg-meta mock for the logs cases, so an unhandled request failing the test *is* the assertion that logs SQL never reaches Postgres. Verified: `pnpm typecheck`, `lint:ratchet` (no regression), Prettier, and the full Studio suite (459 files / 4969 tests). ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added support for recognizing log snippets in reports, with clear guidance to open them in the SQL editor or remove them. - AI Assistant now understands log snippets and provides ClickHouse-specific context, formatting, and troubleshooting guidance. - Snippets retain their source information when shared with the AI Assistant. - **Bug Fixes** - Prevented unsupported log snippets from being executed as regular database queries. - Improved source detection when opening snippets directly from links. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8b38e0d1ed |
feat(studio): ClickHouse dialect for logs snippet AI + rewrite to ClickHouse (#48501)
## 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? Feature, plus a refactor of the shared logs-rewrite flow. PR 8 of the SQL editor query-source series. Stacked on #48457 — review that one first, and merge this after it. ## What is the current behavior? A `log_sql` snippet runs against the ClickHouse-backed analytics endpoint, but the SQL editor's AI still writes Postgres: inline edits get Postgres system prompts, and the result is run through `sql-formatter`, which mangles ClickHouse backticks and `log_attributes` map lookups. Legacy Logs Explorer saved queries open in the editor as `log_sql` snippets. Those are BigQuery dialect and error against the ClickHouse endpoint the editor runs them on, with no in-editor way out — only the Logs Explorer offered a rewrite. The completion route was also asymmetric. It assembled a schema/code/instruction message for Postgres but forwarded `prompt` verbatim for ClickHouse, so a client wanting ClickHouse had to hand-build the equivalent string. ## What is the new behavior? **Inline AI speaks ClickHouse for logs snippets.** `sqlSourceToDialect` maps a snippet's source to `postgres`/`clickhouse` and `buildCompletionRequestBody` threads it through. For ClickHouse, `useSqlEditorAi` strips code fences from the response and skips `formatSql`. Execution and dialect both follow the snippet type, so a snippet's valid dialect never flips. **Rewrite to ClickHouse in the editor.** A banner offers the rewrite for a logs snippet whose text trips `looksLikeLegacyLogsQuery`, and proposes the result through the editor's existing AI diff view rather than replacing the snippet, so it's accepted or discarded like any other AI edit. Gated on `otelLegacyLogs`: on a non-migrated org the BigQuery text is still correct, so rewriting it would break a working query. The offer is a state machine (`offered` / `rewriting` / `failed` / `noRewriteNeeded` / `dismissed`) with a declarative table of valid transitions, so the states are mutually exclusive by construction and dismissal is terminal. A failure keeps its message and offers a retry; a response identical to the input is reported rather than opening an empty diff. **One place assembles completion prompts.** The route now uses a single template for both dialects, branching only the schema section and — for `intent: 'rewrite'` — the instruction. `lib/ai/clickhouse-logs.ts` is the single home for ClickHouse-logs prompt content, replacing two independently maintained descriptions of the same table. Clients carry no prompt text. **The rewrite flow is shared with the Logs Explorer.** Both surfaces previously hand-rolled the same sequence and had drifted: only one detected a no-op rewrite, they sourced `log_attributes` keys differently, and the Explorer formatted errors with an `as Error` cast. Both now use `useLegacyLogsRewrite` and the same state-driven banner, so the Explorer picks up no-op detection and typed error extraction. **Attribute keys are fetched on submit, not while typing.** The detected source would otherwise feed a reactive query key, making every edit that changed it cost another network call. `useLogsAttributeKeys` is imperative and goes through `queryClient.fetchQuery`, so a source already cached — including by the Explorer header and query panel, which subscribe reactively — is reused. This also closes a gap where inline edits never received keys at all, unlike full rewrites. `getErrorMessage` gains an optional typed fallback and no longer stringifies a bare object into `'[object Object]'`; every existing caller already hand-rolled a fallback, except `QueueSettings`, which interpolated the raw result and now passes one. Nothing here is user-visible until the `sqlEditorLogsSource` flag is enabled. Tests: dialect selection and request-body shape, the ClickHouse prompt content (including that the schema section does not restate the dialect rules), the reducer's valid and invalid transitions, `shouldOfferLegacyLogsRewrite`, on-submit key discovery with cache reuse, and `getErrorMessage`. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an Assistant banner to help rewrite legacy BigQuery-style logs queries into ClickHouse SQL. * SQL assistance now adapts to the selected query type, including relevant log attribute context. * Rewrite suggestions can be reviewed as editor diffs before being applied. * **Bug Fixes** * Improved rewrite failure handling, retry options, dismissal behavior, and “no rewrite needed” messaging. * Error notifications now provide a clearer fallback message when details are unavailable. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b3c5c9fc04 |
feat(studio): logs snippets in SQL editor nav, search, and tabs (#48457)
## What PR 7 of the SQL-editor query-source (Database vs Logs) stack. Surfaces `log_sql` snippets as a distinct query source across the SQL editor sidebar. Stacked on **`charislam/toolbar-ui-creation-flow`** (PR 6 — toolbar UI + creation flow); review/merge that first. Nothing is user-visible until the flags roll out — every entry point requires **both** `sqlEditorLogsSource` **and** `otelLegacyLogs`. ## Changes - **Nav** — a flag-gated **Logs** section (`LogsSnippetsSection`) backed by its own single-type `log_sql` query. The active snippet is injected only into the section it belongs to, via a shared `withActiveSnippet(snippets, active, belongsPredicate)` helper (also DRYs the private/favorites/shared injections). - **Search** (`SearchList`) — a **Logs** result group with a shared, extracted `SqlSnippetTree`; the "N results found" count now sums database + logs, with loading/empty states covering both queries. - **Tabs** — an immutable `sqlSource` field on tab/recent-item metadata (set at tab creation, lazily backfilled once the snippet loads via `useEffectEvent`), and a distinct `ScrollText` icon via a shared `LogsSnippetIcon`. Tab cleanup treats `log_sql` tabs as live and only prunes them when logs data is authoritative (`canPruneLogsTabs`), so a disabled/erroring logs query never wrongly deletes logs tabs or blocks database-tab cleanup. - **Data layer** — `useSqlSnippetsQuery` gains an optional `type` param so logs reuse the same `SnippetWithContent` shape as the other sections (no casts). ## Tests - `state/tabs.test.ts` — `sqlSource` backfill + creation-time carry-through. - `components/layouts/Tabs/Tabs.utils.test.tsx` — cleanup prunes stale database/logs snippets, keeps live ones, and preserves logs tabs when logs data isn't authoritative. ## Verification - `pnpm --filter studio typecheck` ✓ - `pnpm --filter studio run lint:ratchet` ✓ - `pnpm test:studio` (affected suites) ✓ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a collapsible Logs section to the SQL editor sidebar for browsing, sorting, selecting, renaming, and deleting log queries. * Expanded SQL search with separate, paginated results for database and log queries. * Added dedicated log-query icons across navigation, tabs, previews, and recent items. * **Bug Fixes** * Improved tab and recent-item cleanup while preserving active log queries and accurate source metadata. * **Tests** * Added coverage for log tab cleanup and SQL source metadata synchronization. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a66dae48f2 |
fix(studio): restart action for table editor load errors FE-4054 (#48687)
## Problem When the table editor showed a "Failed to load tables" or "Failed to load schemas" error (for example, when the underlying database or API gateway is unhealthy), there was no working way to restart the project from that error state. Restarting only worked by navigating to Project Settings. ## Fix "Failed to load tables" goes through the existing `ErrorMatcher` classification system, which only showed troubleshooting steps (including a restart action) for connection-timeout errors. Added an `ERROR_MAPPINGS` entry for the unclassified/generic API error case, reusing the existing `RestartDatabaseTroubleshootingSection` and `RestartProjectDialog` components already used for connection timeouts. "Failed to load schemas" (in the shared `SchemaSelector`, used across the table editor and several Database pages) only offered a retry. Added a "Restart database" button next to it, wired to the same `RestartProjectDialog`. ## How to test - In the table editor, trigger a table-load failure that isn't a connection timeout (any generic API error). The error card should now show a "Try restarting your project" step with a working restart action. - Open the schema selector while schemas fail to load (e.g. mock a 503 from the schemas query). A "Restart database" button should appear next to "Reload schemas" and open the restart confirmation dialog. - `apps/studio/components/interfaces/ErrorHandling/ErrorMatcher.test.tsx` and `apps/studio/components/ui/SchemaSelector.test.tsx` cover both cases. FE-4054 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added database restart guidance when schema loading fails. * Added options to reload schemas or restart the database, including a confirmation prompt. * Added troubleshooting guidance for unclassified table-loading errors. * **Bug Fixes** * Improved error handling by displaying relevant fallback guidance for unknown errors while preserving classified troubleshooting instructions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2ba2c37163 |
fix(studio): preserve deep-linked date range in Unified Logs FE-4020 (#48685)
## Problem Clicking a bar in a usage chart (e.g. the Postgres activity chart on the project dashboard) navigates to Unified Logs with the log_type filter applied correctly, but the clicked bar's time range is silently dropped: the page falls back to the default last-hour window. If the actual matching logs are outside that window, the main list shows "No results found" even though the sidebar facet count (computed from the correct deep-linked range) shows a nonzero count. Root cause: the table's initial `columnFilters` state was seeded only from the `filter` URL param, never from `date`. A debounced effect syncs `columnFilters` back into the URL shortly after mount, and for the `date` field it treats a missing `columnFilters` entry as a cleared brush, overwriting the deep-linked `date` param with null. ## Fix Added `buildDefaultColumnFilters` in `UnifiedLogs.filters.ts`, which seeds a `date` entry into the initial `columnFilters` from `search.date` when present, alongside the existing filter-param seeding. `UnifiedLogs.tsx` now uses this helper instead of building `defaultColumnFilters` inline, so a deep-linked range survives the debounced round-trip instead of getting nulled out. ## How to test - On the project dashboard, click a bar in a usage chart (e.g. Postgres activity) for a time period further back than the last hour. - Expected result: Unified Logs opens with both the log_type filter and the clicked bar's date range applied, and the row list matches the sidebar facet count instead of showing "No results found". - `UnifiedLogs.filters.test.ts` has unit tests covering the new seeding behavior. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved log filtering from URL parameters. * Preserved valid date ranges when opening deep-linked log views. * Prevented malformed or duplicate date filters from appearing in the logs table. * **Tests** * Added coverage for valid, missing, malformed, and duplicate date filter scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9dc5c0faf3 |
feat: privatelink read replica (#48642)
Frontend changes for new privatelink functionality. The updates to the API are already live, but will be putting the UI changes behind a feature flag while we do some full end to end testing. Changes to Integration page: <img width="744" height="456" alt="image" src="https://github.com/user-attachments/assets/02026083-4b61-4f36-927b-1bac42cb73e2" /> Changes to create associations page: <img width="859" height="411" alt="image" src="https://github.com/user-attachments/assets/303b4ec5-3b5a-4eaf-8d22-45e1e63a0705" /> Fixes SEC-919 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - AWS PrivateLink connections can target the primary database or a read replica. - Connection lists and confirmation dialogs now identify the selected database clearly. - Replica details include improved status information and a “Manage replica” link. - **Bug Fixes** - Replica removal errors now provide clearer guidance and link to integration settings when PrivateLink issues occur. - **Updates** - Infrastructure diagrams focus on visualization, with replica management actions moved to dedicated management views. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
270925b680 |
feat(studio): add dashboard_auth:sign_in_with_chatgpt enabled feature (#48677)
Adds a `dashboard_auth:sign_in_with_chatgpt` enabled-features flag so deployments can disable the sign in with ChatGPT button via `disabled_features`, the same way `dashboard_auth:sign_in_with_github` works. Previously the button was only gated by the ConfigCat rollout flag / localStorage opt-in, so white-labeled deployments with custom auth providers had no way to turn it off. **Added:** - `dashboard_auth:sign_in_with_chatgpt` (default `true`) in `enabled-features.json` + schema - Tests covering the feature-disabled state **Changed:** - `useEnabledIdentityProviders` now gates ChatGPT as `featureEnabled && (localStorageOptIn || configCatFlag)` — the feature flag is the static kill switch, the existing OR'd pair remains the rollout mechanism ## To test - Sign-in and sign-up pages behave exactly as before by default (flag defaults to `true`, ConfigCat/localStorage rollout gate unchanged) - With `dashboard_auth:sign_in_with_chatgpt` in a profile's `disabled_features`, the ChatGPT button no longer renders even with `?siwc-enabled=1` or the ConfigCat flag on - GitHub button gating unaffected <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a feature flag to control ChatGPT sign-in availability. - ChatGPT sign-in is now available only when the feature is enabled and an applicable rollout or opt-in condition is met. - **Tests** - Expanded coverage for ChatGPT and GitHub sign-in provider availability under different feature-flag and rollout conditions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
a0cec24f49 |
Remove references to fly (#48648)
## Context As per PR title - should not have any visual nor functional change <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Changes** - Standardized infrastructure, region, and database configuration around AWS-based environments. - Removed Fly.io-specific region and provider options from project creation, instance sizing, and infrastructure settings. - Enabled disk validation, spend-cap eligibility, backup restoration, and extension setup consistently across supported projects. - Updated billing and region displays to use the applicable AWS configuration. - **Bug Fixes** - Corrected project-specific restrictions that could incorrectly hide configuration and billing controls. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8e3e14f198 |
Joshen/fe 4064 add a toast callout for feature preview (#48645)
## Context Adds a banner toast for the database connections feature preview <img width="315" height="322" alt="image" src="https://github.com/user-attachments/assets/8caaab88-10a0-4a06-b678-25fc9c44dd81" /> ## Other changes As the observability page currently has a number of banner toasts (metrics API, unified logs, index advisor for query performance), am opting to REMOVE the metrics API's banner toast by virtue of how long its been around for. Mainly to prevent over stacking of banner toasts as it can be annoying. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a dismissible Database Connections banner with SQL examples and a link to its feature preview. * Banner dismissal and CTA interactions are now tracked. * Dismissed banners can reappear when reintroduced. * **Bug Fixes** * Banners are hidden after the feature is enabled or dismissed. * Improved banner handling to prevent duplicate active banners. * **Changes** * Replaced the Metrics API banner with the Database Connections banner. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9006e33f11 |
Add categories for feature previews (#48641)
## Context Given that our number of feature previews have been expanding, am opting to group them into categories for easier understanding of the context of each feature preview. Ideally we're able to tag all feature previews into categories (or add more categories), but leaving the unclassified ones under "others" for now <img width="936" height="661" alt="image" src="https://github.com/user-attachments/assets/b48bd9a2-fe33-4cb0-9288-1cd9c8264da0" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Feature previews are now organized into expandable categories. * Observability and database previews are grouped for easier browsing. * Uncategorized previews remain available under an “Others” section. * Existing feature selection options and sorting behavior are preserved. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
76257f164b |
fix(studio): align storage row icon weight (#48480)
## What kind of change does this PR introduce? Bug fix stacked on #48478. ## What is the current behavior? Storage Explorer renders the custom closed-folder icon at `1.5` but leaves the Lucide open-folder icon at its default `2`. The duplicated file-picker implementation also uses a different set of stroke-width overrides. ## What is the new behavior? A shared `StorageRowIcon` renders loading, open and closed folder, image, audio, video and generic file icons at `1.5` across Storage Explorer, row editing and the bucket file picker. Test by comparing open and closed folders and file-type rows in Storage Explorer and the bucket file picker. | Before | After | | --- | --- | | <img width="524" height="336" alt="CleanShot 2026-08-03 at 18 38 06@2x" src="https://github.com/user-attachments/assets/15eb8b9f-69fc-4eee-8428-d7ec26dce8dc" /> | <img width="522" height="328" alt="CleanShot 2026-08-03 at 18 39 20@2x" src="https://github.com/user-attachments/assets/17b7dddd-8d36-421c-8356-c9c1bd7456e8" /> | | _Thicker image and file icon compared to folder icon_ | _Every icon has the same stroke thickness_ | <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Standardized file, folder, media, and loading icons across storage views. * Improved visual consistency with unified icon sizing, styling, and stroke width. * **Tests** * Added coverage for loading, folder, media, and generic file icon states. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fc69c45985 |
Bring database connections to feature preview (#48638)
## Context As per PR title - brings Database Connections into feature preview Should be working for both hosted + self-host/local Also adjusts existing feature previews to remove "New" - Platform webhooks - Temporary database access <img width="600" alt="image" src="https://github.com/user-attachments/assets/b18ae8ca-ce0b-4649-975c-e70749a87dcd" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a Database Connections preview highlighting live activity, query blocking detection, session termination, and AI-assisted summaries. * Added access to project-specific observability connections from the preview. * Added a Database Connections entry to the observability menu when enabled. * **Improvements** * Updated feature previews and labels, including changes to “new” status indicators. * Added controls to manage Database Connections preview visibility. * **Bug Fixes** * Improved blocker detection so results respect the selected role filters. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3f5ac679e0 |
fix(studio): redirect to feature preview route after enabling (#48637)
Enabling a feature preview that has a route (e.g. Column-level
privileges) closed the modal but never navigated to the feature's page
on the TanStack runtime (local + staging). The modal closed itself via a
nuqs query-param update *and* called `router.push` — the queued nuqs
flush navigates to the pathname it captured before the push, landing
after the redirect and reverting it. The Next runtime was unaffected
because the stock nuqs pages adapter patches the URL shallowly via the
history API instead of navigating.
**Changed:**
- When the enabled preview has a `getRoute`, skip the explicit
`toggleFeaturePreviewModal(false)` — `router.push(route)` navigates
without the `featurePreviewModal` param, which is what closes the modal.
One URL update instead of two racing ones; works on both runtimes.
- Previews without a route keep the explicit close (unchanged behavior).
## To test
- On a project page, open Feature Previews (avatar menu), select
**Column-level privileges**, click **Enable feature** → modal closes and
you land on `/project/{ref}/database/column-privileges` with the "We've
taken you to where you can try it out." toast (no bounce back to the
previous page)
- Repeat with **Disable Advisor rules** → lands on
`/project/{ref}/advisors/rules/security`
- Enable a preview without a route (e.g. **PG Delta Diff**) → modal
closes, stays on the current page, "It's now active across the
dashboard." toast
- Disable a preview → modal stays open, "disabled" toast, no navigation
- Verified locally on the TanStack runtime; worth a quick click-through
on the Vercel preview (Next runtime) too
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved feature activation navigation to prevent conflicting URL
updates.
* Non-route features continue to close the preview modal and display the
activation confirmation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
|
||
|
|
73c9dbfa52 |
fix(studio): standardise custom icon weight (#48478)
## What kind of change does this PR introduce? Bug fix and internal tooling update. Resolves FE-3472. ## What is the current behavior? Custom Studio icons use inconsistent source stroke widths, and some child-level styling prevents component props from overriding them. Mixed custom and Lucide icon sets can therefore appear uneven. ## What is the new behavior? Custom stroke icons use a root-level `stroke-width="1.5"`; fill-only logos use `stroke="none"`. The build validates that contract and regenerated components preserve existing exports and props. Studio applies the same `1.5` weight across Reports categories and uses one shared destination icon mapping in the replication selector, destination rows and diagram. | Before | After | | --- | --- | | <img width="418" height="516" alt="56398" src="https://github.com/user-attachments/assets/6afa7042-e6be-40e7-9911-af2f61238c9d" /> | <img width="390" height="550" alt="CleanShot 2026-07-30 at 17 12 37@2x" src="https://github.com/user-attachments/assets/870f49cf-c8fa-40db-8be8-2eb5f264ff4a" /> | | <img width="510" height="734" alt="CleanShot 2026-07-30 at 17 19 28@2x" src="https://github.com/user-attachments/assets/a5b2c088-dcd2-4907-976b-5820794d06e3" /> | <img width="554" height="742" alt="CleanShot 2026-07-30 at 17 16 06@2x" src="https://github.com/user-attachments/assets/ed3a77c4-5d94-4ca7-b9e4-1403b725a981" /> | ## Testing At 100% zoom, compare custom and Lucide icon weight in: - Reports: **Add your first chart** and **Add block** - Database > Replication: the destination selector, destination rows and replication diagram - Command menu (`⌘K`): **Search Database Tables**, **Search RLS Policies**, **Search Edge Functions** and **Search Storage** - Authentication > Users: right-click a user row and compare the context-menu icons - Database > Schema Visualizer: open a table node overflow menu - A paused project: **Export your data > Download backups** <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added consistent destination icons across replication panels, rows, and diagrams. * Updated instance health and metric icons for clearer identification. * Standardized icon stroke weight and reduced default icon stroke thickness. * **Documentation** * Clarified custom icon requirements, default properties, and validation guidance. * **Bug Fixes** * Improved consistency of icon rendering across replication destinations and reports. * **Tests** * Added coverage for icon SVG validation and replication destination icon rendering. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2c53ca4a79 |
Support listing and reading custom reports from Assistant (#48530)
## Context This is pre-requisite work for adding support to managing custom reports from the Assistant. Planning to break this into a number of PRs, briefly - Adding read support for custom reports - Adding write support for custom reports - Adding run support for custom reports - Should be able to infer data from the results then This PR starts with adding support for listing and reading custom reports from the Assistant ## Other changes involved - Updates setting up of the home page report to have better title and description - Swaps the variant of the ToggleGroup in the SQL block for custom reports as the default variant blends into the background color of the PopoverContent ## To test - [ ] Assistant should be able to list custom reports + read its contents <img width="428" height="755" alt="image" src="https://github.com/user-attachments/assets/6a15b660-c0ee-4a06-984c-87eff3943eec" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added AI-assisted tools to list reports and retrieve report details, including chart counts, layouts, configurations, and SQL-backed chart information. - Added clearer empty-state messaging when no snippets are available. - **Improvements** - New homepage reports now use the name “Homepage Report” and include a descriptive project-home summary. - Updated query controls with refreshed visual styling. - Improved content requests to support additional request context. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
022b374f2d |
show Stripe Projects errors inline (#48472)
## What kind of change does this PR introduce? Bug fix. ## What is the current behavior? Stripe Projects confirmation failures only appear in a toast. The existing **Unable to load authorization** Admonition is a separate error state shown when the account request itself cannot be loaded. ## What is the new behavior? Confirmation failures remain visible below the authorisation actions, clear on retry, and do not also trigger a toast. They use the shared `InterstitialActionError`. | Before | After | | --- | --- | | <img width="1024" height="759" alt="Authorize Stripe Projects Supabase" src="https://github.com/user-attachments/assets/83cb3144-9ddb-46b7-bfce-970497be61e2" /> | <img width="1024" height="759" alt="Authorize Stripe Projects Supabase" src="https://github.com/user-attachments/assets/bccedde9-9935-457b-a980-0c80499f2f27" /> | ## To test These instructions visually check the after state on this branch. Opening an invalid `ar_id` without the hardcodes only exercises the existing load-error Admonition, which this PR does not change. ### After on this branch 1. In `apps/studio/pages/partners/stripe/projects/login.tsx`, replace the `confirmationError` assignment with: ```tsx const confirmationError = 'Failed to authorize Stripe Projects: Test error' ``` 2. In the same file, replace the block beginning with `const linkedOrg` and ending with `interstitialDescription` with: ```tsx const linkedOrg = { name: 'Example Organization' } const emailMatches = true const displayName = primaryEmail ?? username ?? 'reviewer@example.com' const isPending = false const isConfirmed = false const isConfirming = false const isError = false const showAuthorizationState = true const interstitialDescription = 'This will create an organization on your behalf in Supabase' ``` 3. While signed in locally, open `http://localhost:8082/partners/stripe/projects/login?ar_id=test`. 4. Confirm the error appears below **Authorize Stripe Projects** and **Cancel**. No real Stripe request is required. 5. Revert both temporary edits. ### Before on master (optional) 1. Check out `master`. 2. In `apps/studio/pages/partners/stripe/projects/login.tsx`, replace the block beginning with `const linkedOrg` and ending with `interstitialDescription` with the same block from step 2 above. Do not add `confirmationError`. 3. While signed in locally, open `http://localhost:8082/partners/stripe/projects/login?ar_id=test`. 4. Click **Authorize Stripe Projects**. 5. Confirm the failed confirmation appears in a toast beginning **Failed to confirm account request**. 6. Revert the temporary edit before changing branches. ## Additional context Stacked on #48471. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Bug Fixes** * Authorization errors during Stripe Projects login are now displayed inline in both authorization flows. * Authorization remains available after a failed confirmation attempt. * Failed authorization requests no longer trigger an additional toast notification. * Previous errors are cleared when retrying authorization. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e7796315d2 |
fix sheets stealing focus (#48521)
## What kind of change does this PR introduce? Bug fix. Resolves DEPR-539. ## What is the current behavior? When a focused child unmounts, Radix can move focus to the Sheet wrapper and break the expected tab order. Several callsites suppress the wrapper's tabindex individually. ## What is the new behavior? Sheet still focuses its first interactive child when opened, but the wrapper itself is no longer focusable by default. Callers can opt in with an explicit `tabIndex` when needed. ## Additional context ### Testing Compare this Studio experience on both this branch and `master`: 1. Open any project with an Edge Function. 2. Go to **Edge Functions**, open the function, then click **Test**. 3. Under **Headers**, click **Add Headers**. Click the first header key input, then Tab slowly through the header inputs and remove buttons. On `master`, focus can jump to the whole Sheet. On this branch, focus stays on the controls in order. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved keyboard focus behavior across sheets and panels. * Sheets now focus the first available interactive element when opened, without adding unnecessary focus targets. * Preserved support for programmatic focus and prevented focus from unexpectedly moving to the sheet when focused content is removed. * Updated authentication, integrations, connection, logging, storage, and other sheet interfaces consistently. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7a77760a10 |
fix(studio): confirm before discarding dirty replication destination forms (#48522)
## What kind of change does this PR introduce? Bug fix (dirty form dismissal for Replication destination sheets), plus small docs/skill updates so agents pick up the existing modality pattern. ## What is the current behavior? Closing the Add/Edit destination sheet (Cancel, Escape, or backdrop) discards in-progress form state with no confirm. Same for the nested Create publication sheet. ## What is the new behavior? Dirty closes go through `useConfirmOnClose` + `DiscardChangesConfirmationDialog`, matching other Studio sheets. Successful submit still closes without prompting. Also: skills + `forms.mdx` now point at Modality “Dirty form dismissal”. | After | | --- | | <img width="1024" height="759" alt="Replication Database Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/6f568a2a-c76b-442a-b592-d638bb36adc4" /> | ### How to test 1. Studio → Database → Replication → **Add destination** (any pipelines type with access). 2. Change a field so the form is dirty. 3. Try Cancel, Escape, and backdrop click → discard dialog appears; **Keep editing** stays open; **Discard changes** closes. 4. Submit successfully with a valid config → sheet closes with no discard dialog. 5. Repeat for **Edit destination** from a destination row menu. 6. Optional: Add destination → create a new publication from the publication picker → dirty that nested sheet and dismiss the same way. 7. Optional: Add destination → Read Replica → change region → dismiss → discard dialog; deploy still closes without prompting. ## Additional context Sheet owns the close guard; forms report dirty via a ref because RHF lives in the child. Nested `NewPublicationPanel` wires the guard locally. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added unsaved-changes tracking to replication destination and publication forms. - Added confirmation prompts before closing forms with unsaved changes via Cancel, Escape, or backdrop dismissal. - Forms now reset appropriately after successful submission or confirmed dismissal. - **Documentation** - Updated form and UI pattern guidance to document dirty-form dismissal behavior for sheets and dialogs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
eef0f57309 |
fix(studio): clarify Storage columns keyboard focus and selection (#48222)
## What kind of change does this PR introduce? Accessibility / UX fix ([DEPR-630](https://linear.app/supabase/issue/DEPR-630)). ## What is the current behavior? In Storage **As columns** view, keyboard select is unclear: the checkbox stays hidden until hover, so Tab/Space selection is hard to see. The row actions (three dots) menu also shows a browser default blue outline on Tab. ## What is the new behavior? Same icon/checkbox swap as list/hover, but also on keyboard focus: - Checkbox replaces the icon on hover, `:focus-within`, and when selected (no layout shift) - Checkbox becomes visible when focused via keyboard (without needing hover) - Row gets an inset outline while the checkbox is focused - Folders have no checkbox (non-focusable spacer only) - Row actions trigger uses `focus-ring` instead of the browser blue outline | Before | After | | --- | --- | | <img width="1046" height="362" alt="CleanShot 2026-07-31 at 14 37 47@2x" src="https://github.com/user-attachments/assets/9b827627-17e6-49a6-87a3-1253b4cef1da" /> | <img width="1046" height="390" alt="CleanShot 2026-07-31 at 14 37 13@2x" src="https://github.com/user-attachments/assets/2fd2b426-a8e2-4fda-b1ba-4df728b7b2f1" /> | | _Checkbox focussed but not visually shown_ | _Checkbox focussed and visually shown_ | ## To test 1. Open the **Studio preview** for this PR. 2. Go to **Storage → Files** → open a bucket with several files. 3. Set view to **As columns**. 4. Tab until a **file** checkbox is focused. **Expect:** - Icon is replaced by the checkbox (same slot; neighbouring row icons should not look shifted) - Checkbox visible without hovering - Row shows an inset outline 5. Press **Space** to select. Checkbox stays in the icon slot; selection background applies. 6. Hover another file. Same icon to checkbox swap as before. 7. Tab to the three-dot actions control on a row. Expect the shared focus ring (not a blue browser outline); the menu icon should become visible. 8. Folders: no checkbox in the tab order; click icon/name still opens the folder. 9. Smoke **As list**. Same swap behaviour. ## Additional context From Kemal's DEPR-621 review. |
||
|
|
f7454cf94e |
feat(studio): oauth impersonation warning on authorize (#48162)
## What kind of change does this PR introduce? Feature + docs. Stacked on #48161 (logo contract / [DEPR-604](https://linear.app/supabase/issue/DEPR-604/define-connect-logo-asset-and-variant-contract)). ## What is the current behavior? After #48161, curated logos only resolve from allowlisted `redirect_uri` hosts. A requester can still present a trusted partner **name** (e.g. Claude) while redirecting to an unrelated remote host; the UI shows Supabase alone but does not call out the mismatch. ## What is the new behavior? - Shows a caution admonition when the requester name looks like a trusted partner (Claude, Cursor, ChatGPT/OpenAI, Perplexity) but `redirect_uri` is a **remote** host outside that partner's allowlist. - Skips localhost / loopback redirects for the caution (common for local MCP clients); those still get curated logos when the name matches a trusted partner. - Highlights the footer redirect URL in warning colour when the caution is shown. - Documents the behaviour in the Connect interstitials pattern. ### To test Real MCP clients (Claude, Cursor, etc.) only send users to **production** `/authorize`, so you cannot drive a local or preview Studio build from those tools. Use a Network override instead: 1. Start Studio and sign in (`pnpm dev:studio`, or use the [Vercel preview](https://studio-staging-git-danny-oauth-impersonation-warning-supabase.vercel.app/)). 2. Open `/dashboard/authorize?auth_id=foo` (any `auth_id` is fine; the real response may 404) ([Vercel preview](https://studio-staging-git-danny-oauth-impersonation-warning-supabase.vercel.app/dashboard/authorize?auth_id=foo)). 3. DevTools → **Network** → find `GET …/platform/oauth/authorizations/foo` (or whatever id you used). 4. Right-click → **Override content** (enable Local Overrides / pick a folder if prompted). 5. Paste one of the payloads below (status **200**), save, then reload the authorize page. 6. Keep `expires_at` in the future so the request does not look expired. #### Impersonation caution (trusted name + remote non-allowlisted redirect) Expect: - Supabase alone (no curated Claude mark) - Caution: “Redirect does not match this app name” - Footer redirect URL in warning colour ```json { "name": "Claude", "website": "https://claude.ai", "icon": null, "domain": "claude.ai", "redirect_uri": "https://evil.com/callback", "expires_at": "2099-01-01T00:00:00.000Z", "scopes": ["organizations:read", "projects:read"], "approved_at": null, "registration_type": "dynamic" } ``` | Preview | | --- | | <img width="764" height="958" alt="Authorize Claude Supabase" src="https://github.com/user-attachments/assets/e6eee016-5710-41ba-9925-87511e009e22" /> | #### Localhost MCP: no caution Expect curated Claude + Supabase pair (name match + loopback), **no** caution, normal footer colour. Local MCP clients often use loopback redirects. ```json { "name": "Claude", "website": "https://claude.ai", "icon": null, "domain": "claude.ai", "redirect_uri": "http://127.0.0.1:42813/callback", "expires_at": "2099-01-01T00:00:00.000Z", "scopes": ["organizations:read", "projects:read"], "approved_at": null, "registration_type": "dynamic" } ``` | Preview | | --- | | <img width="764" height="958" alt="Authorize Claude Supabase" src="https://github.com/user-attachments/assets/79f36865-3c8e-43e5-9490-24288efc74aa" /> | #### Legitimate curated partner: no caution Expect curated Cursor + Supabase pair, no admonition, normal footer colour. ```json { "name": "Cursor", "website": "https://cursor.com", "icon": null, "domain": "cursor.com", "redirect_uri": "https://cursor.com/callback", "expires_at": "2099-01-01T00:00:00.000Z", "scopes": ["organizations:read", "projects:read"], "approved_at": null, "registration_type": "dynamic" } ``` | Preview | | --- | | <img width="764" height="958" alt="56164" src="https://github.com/user-attachments/assets/412333a3-a74f-42eb-9f63-d56b6a26bf91" /> | #### Unrelated name + remote redirect: no caution Expect Supabase alone (no icon), no admonition. ```json { "name": "Acme Tools", "website": "https://evil.com", "icon": null, "domain": "evil.com", "redirect_uri": "https://evil.com/callback", "expires_at": "2099-01-01T00:00:00.000Z", "scopes": ["organizations:read", "projects:read"], "approved_at": null, "registration_type": "dynamic" } ``` | Preview | | --- | | <img width="764" height="958" alt="Authorize Acme Tools Supabase" src="https://github.com/user-attachments/assets/dab24817-5c26-4aa1-a447-796c4af5868b" /> | <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Added an OAuth caution when a requester name matches a known partner but uses an unapproved remote redirect host. - Improved trusted partner logo selection for localhost/loopback redirects while preserving safe fallbacks for untrusted redirects. - **Documentation** - Updated Connect interstitial guidance for redirect mismatches and localhost/loopback behavior. - **Tests** - Expanded coverage for caution visibility, messaging, localhost logo pairing, and trusted redirect scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2b26da360e |
show API and AWS authorization errors inline (#48471)
## What kind of change does this PR introduce? Bug fix and design-system update. ## What is the current behavior? API authorisation and AWS Marketplace action failures use transient toasts. The inline action-error treatment introduced for organisation invitations is implemented locally. ## What is the new behavior? Action failures remain visible below their actions and clear on retry or organisation change. This PR adds a shared `InterstitialActionError` component, updates the connect-interstitial guidance and demo to use it, and retroactively applies it to `OrganizationInvite`. Mutation errors are read directly from their mutation hooks rather than copied into component state. | Before | After | | --- | --- | | <img width="1024" height="759" alt="Authorize API Access Supabase" src="https://github.com/user-attachments/assets/9520aff3-496d-44b1-b5b5-02b331872e32" /> | <img width="1024" height="759" alt="Authorize API Access Supabase" src="https://github.com/user-attachments/assets/2d09e337-573a-45b5-80ac-7c546ed1401d" /> | | <img width="1024" height="759" alt="Link AWS Marketplace Supabase" src="https://github.com/user-attachments/assets/bb1a4581-0399-432a-8037-d84ab15ecc4b" /> | <img width="1024" height="759" alt="Link AWS Marketplace Supabase" src="https://github.com/user-attachments/assets/f9d43cd9-c661-42ed-91c0-e45ccb9c19f5" /> | _Note since taking that AWS screenshot: the error message now replaces the prior footer text. I.e. “Learn more about billing through AWS.” is now gone when an error message is present._ ## To test ### AWS Marketplace For a visual check with local Studio running: 1. In `apps/studio/components/interfaces/Organization/CloudMarketplace/AwsMarketplaceOnboarding.tsx`, immediately before `if (!buyerId)`, temporarily add: ```tsx return ( <AwsMarketplaceInterstitial> <div className="flex flex-col gap-5"> <InterstitialAccountRow displayName="reviewer@example.com" /> <OrganizationSelector organizations={[ { name: 'Example Organization', slug: 'example-organization', plan: { id: 'pro', name: 'Pro' }, } as Organization, ]} selectedSlug="example-organization" disabled onSelect={() => undefined} /> <div className="flex flex-col gap-5"> <div className="flex flex-col gap-2"> <Button variant="primary" block> Link organization </Button> <InterstitialActionError error="Failed to link organization: Test error" /> </div> <p className="text-center text-xs text-foreground-lighter text-balance"> <InlineLink href={`${DOCS_URL}/guides/platform/aws-marketplace`}> Learn more </InlineLink>{' '} about billing through AWS. </p> </div> </div> </AwsMarketplaceInterstitial> ) ``` 2. Open `http://localhost:8082/aws-marketplace-onboarding?buyer_id=test` while signed in. 3. Confirm the error appears below **Link organization** with a divider. Remove the temporary return before committing anything. ### API authorization For a visual check with local Studio running: 1. In `apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Valid.tsx`, immediately before `if (isLoading)`, temporarily add: ```tsx return ( <ApiAuthorizationMainView approvalState="indeterminate" form={form} requester={{ name: 'Test App', website: 'https://example.com', icon: null, domain: 'example.com', scopes: [], expires_at: '2099-01-01T00:00:00.000Z', approved_at: null, registration_type: 'static', }} organizations={{ _tag: 'success', organizations: [ { name: 'Example Organization', slug: 'example-organization' } as Organization, ], }} requestedOrganizationSlug={undefined} actionError="Failed to authorize request: Test error" onOrganizationChange={() => undefined} onApprove={() => undefined} onDecline={() => undefined} /> ) ``` 2. Open `http://localhost:8082/authorize?auth_id=test` while signed in. 3. Confirm the error appears below the authorisation actions with a divider. Remove the temporary return before committing anything. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added consistent inline error messaging for authorization, organization invitations, and AWS Marketplace onboarding. * Error messages now appear within the relevant interstitial and replace supporting footer content until resolved. * Retry and action buttons remain available after failed operations. * **Bug Fixes** * AWS Marketplace linking failures no longer trigger toast notifications. * Billing guidance is hidden while an onboarding error is displayed. * **Tests** * Added coverage for authorization, cancellation, and AWS Marketplace failure states. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |