mirror of
https://github.com/supabase/supabase.git
synced 2026-05-07 17:30:25 -04:00
create-pull-request/patch
232 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3f97eeea5a |
feat(studio): extend safe SQL model to policy editor and related interfaces (#45560)
## 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? Refactor / security improvement ## What is the current behavior? SQL fragments across Studio are built from plain `string` values with no type-level distinction between developer-authored SQL, DB-sourced identifiers, and user-typed or externally-influenced content. ## What is the new behavior? Extends the safe SQL model to additional Studio interfaces, using `SafeSqlFragment`, `safeSql`, `ident()`, `literal()`, `untrustedSql()`, and `acceptUntrustedSql()` from `@supabase/pg-meta/src/pg-format`: - **Policy editor**: template constants typed as `SafeSqlFragment` via `safeSql` tagged literals; Monaco editor `onInputChange` emits `untrustedSql()`; `acceptUntrustedSql()` called only at the Save gesture; roles selector emits a composed `SafeSqlFragment` via `ident()` + `joinSqlFragments()` - **Auth hooks**: grant/revoke SQL statements use `ident()` for schema and function names - **Docs description editor**: `COMMENT ON` queries use `ident()` and `literal()` for table/column/function names and values - **Cron jobs**: `cron.schedule()` call and HTTP request builder use `literal()` for all user-provided values - **GraphQL linter CTA**: `REVOKE` statement uses `ident()` for schema, table, and role - **Storage public bucket warning**: `DROP POLICY` uses `ident()` for policy name - **View security autofix modal**: `ALTER VIEW` uses `ident()` for schema and view name - **API settings**: `CREATE SCHEMA` mutation uses `safeSql` tagged literal - **Database event trigger delete**: `DROP EVENT TRIGGER` uses `ident()` for trigger name - **Database queues query**: queue list query uses `safeSql` tagged literal - **Role impersonation**: function invocation SQL uses `ident()` and `literal()` ## Manual testing checklist - Authentication > Policies - Authentication > Hooks - Integrations > Queues - Database > Event Triggers - Integrations > Cron Jobs - Table Editor > View entity security autofix - API Settings > expose schema - Linter > GraphQL exposure CTA - Docs > table/column description editor - Role impersonation (user impersonation panel) ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Replaced ad-hoc SQL string building with a safer, fragment-based SQL construction across auth, policies, integrations, storage, and DB operations to improve SQL safety while preserving behavior. * **Bug Fixes / UX** * Policy editor and code editor now propagate role and input changes more reliably, improving editor responsiveness and policy handling without UI changes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2e904abebf |
feat(studio): add D + letter shortcuts for Database sub-pages (#45546)
## Summary Adds a contextual `D + <letter>` chord pattern for jumping between Database sub-pages, mounted only while `DatabaseLayout` is active. Establishes the pattern we can repeat for other sections (Auth, Storage, Functions, etc.). Linear: [FE-3140](https://linear.app/supabase/issue/FE-3140/define-subnavigation-pattern-for-database-management-page) ## Pattern - Chords are 2-key sequences (`D`, `<letter>`) — no global leader, no `G` prefix. - Registration is contextual: `<DatabaseNavShortcuts />` lives inside `DatabaseLayout`, so the leading `D` is only "owned" while the user is under `/project/<ref>/database/*`. Doesn't burn a global key. - Hover tooltips on each sub-menu item show the chord, anchored to the label text (Linear-style). Powered by `<ShortcutTooltip>` already used in the main nav. - Items hidden by feature flags (Roles, Column Privileges, Replication) auto-disable the chord — no muscle-memory navigating to a 404. ## Shortcuts added | Sub-page | Chord | Notes | |---|---|---| | Tables | `D T` | | | Functions | `D F` | | | Triggers | `D R` | t**R**iggers — `T` taken by Tables | | Indexes | `D I` | | | Extensions | `D X` | e**X**tensions | | Schema Visualizer | `D V` | | | Enumerated Types | `D E` | | | Publications | `D U` | p**U**blications — avoids collision with Schema Visualizer's `D P` (Download as PNG) | | Column Privileges | `D C` | flag-gated | | Settings | `D ,` | mirrors global `G ,` for project settings — avoids collision with Schema Visualizer's `D S` (Download as SVG) | | Replication | `D L` | rep**L**ication — flag-gated | | Roles | `D O` | r**O**les — flag-gated | | Backups | `D B` | platform-only | | Migrations | `D M` | | External-link sub-menu items (Policies, Wrappers, Webhooks, Security Advisor, Performance Advisor, Query Performance) are intentionally not chorded — they route out of `/database/*` and don't belong to the section's namespace. ## Collision audit Other shortcuts active on database pages (table-list, schema-visualizer) were checked against the new chords: - **Schema Visualizer** (`/database/schemas`): `D P` (Download PNG), `D S` (Download SVG), `O A`, `O S`. Publications and Settings were remapped to `D U` and `D ,` to avoid the `D P` / `D S` clashes. - **List pages** (`/database/tables`, etc.): `Shift+F`, `Shift+N`, `O S`, `F C` — no overlap with `D + <letter>`. ## Files - `state/shortcuts/registry/database-nav.ts` — new registry module with the 14 chord definitions. - `state/shortcuts/registry.ts` — spreads the new IDs/definitions into the canonical registry. - `components/interfaces/DatabaseNavShortcuts.tsx` — null-rendering hook component that wires `useShortcut` for each chord, keyed off `useGenerateDatabaseMenu` so URLs and feature gating stay in sync with the sidebar. - `components/layouts/DatabaseLayout/DatabaseLayout.tsx` — mounts the component. - `components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx` — tags each menu item with its `shortcutId`. - `components/ui/ProductMenu/ProductMenu.types.ts` — adds optional `shortcutId?: ShortcutId` field. - `components/ui/ProductMenu/ProductMenuItem.tsx` — renders the hover tooltip when an item has a `shortcutId`, anchored to the label span. ## Test plan - [ ] On `/project/<ref>/database/tables`, press `D F` — navigates to `/database/functions`. - [ ] On `/project/<ref>/database/schemas`, press `D P` — downloads the PNG (Schema Visualizer wins, no nav conflict). - [ ] On `/project/<ref>/database/schemas`, press `D U` — navigates to `/database/publications`. - [ ] On `/project/<ref>/database/tables`, press `D ,` — navigates to `/database/settings`. - [ ] Hover any sub-menu item with a chord — pill appears next to the label after ~1s. - [ ] On a project with the Replication flag off — `D L` does nothing. - [ ] Navigate to `/auth` — pressing `D F` does nothing (chord unmounts with the layout). - [ ] Type `D` then `F` slowly inside an input — does not navigate (input-focus guard). |
||
|
|
0433eeb5f5 |
feat(studio): mark sql provenance for safety (#45336)
Mark provenance of SQL via the branded types SafeSqlFragment and UntrustedSqlFragment. Only SafeSqlFragment should be executed; UntrustedSqlFragments require some kind of implicit user approval (show on screen + user has to click something) before they are promoted to SafeSqlFragment. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Editor and RLS tester show loading states for inferred/generated SQL and include a dedicated user SQL editor for safer edits. * **Refactor** * Platform-wide SQL handling tightened: snippets and AI-generated SQL are treated as untrusted/display-only until promoted, improving safety and consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
618c902e1a |
feat(studio): add keyboard shortcuts to Database listing pages (#45467)
## Summary Adds the `O→S` / `Shift+F` / `Shift+N` / `F→C` shortcut set across every Database listing page, on top of the schema-visualizer pattern from #45386. Fixes [FE-3131](https://linear.app/supabase/issue/FE-3131). A shared `list-page.*` registry replaces what would have been a per-page registry file for each route, and `useShortcut`/`Shortcut` gain a `label` override so a single ID renders contextually in Cmd+K and hover tooltips. ## Pages and shortcuts | Page | `O→S` | `Shift+F` | `Shift+N` | `F→C` | | --- | --- | --- | --- | --- | | Tables | Open schema selector | Search tables | Create new table | Clears search + entity-type filter | | Functions | Open schema selector | Search functions | Create new function | Clears search + Return Type + Security | | Triggers — data | Open schema selector | Search triggers | Create new trigger | Clears search + Table filter | | Triggers — event | — | Search event triggers | Create new event trigger | Clears search + Owner filter | | Enumerated Types | Open schema selector | Search enumerated types | Create new enumerated type | Clears search | | Indexes | Open schema selector | Search indexes | Create new index | Clears search | | Roles | — | Search roles | Add new role | Clears search + filter type → 'all' | | Publications | — | Search publications | — | Clears search | | Extensions | — | Search extensions | — | Clears search | `Shift+N` only fires when the page-specific gate allows it (permission + unlocked schema + any other prerequisite like `hasTables` for triggers). ## Test plan - [ ] On each of the 9 pages, all four shortcuts behave as listed in the table above - [ ] Hover the wrapped controls — tooltip shows the page-specific label and the right keybind badge - [ ] Open the schema selector via `O→S` — the hover tooltip is suppressed while the popover is open - [ ] `Shift+N` is a no-op on locked schemas / when permission is missing / when a prereq fails (e.g. no tables on Triggers data) - [ ] `Shift+F` focuses the search input; while focused, Escape clears (with text) → Escape blurs (when empty) - [ ] `Cmd+K` shows the page-specific shortcut name while on each page; the entry goes away on navigation - [ ] `Mod+/` reference sheet shows one "List pages" group with 4 generic entries - [ ] No regression to existing schema-visualizer / table-editor / SQL-editor shortcut behavior <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a dedicated list-page shortcut group in the shortcuts reference. * **Improvements** * Keyboard shortcuts across database list pages: focus & select search, reset filters, and create-new-item shortcuts. * Escape now clears/searches or blurs inputs to avoid accidental popover closes. * Create/new buttons respond to shortcuts when allowed; disabled actions keep permission tooltips for clarity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e6f779ea30 |
feat(studio): add keyboard shortcuts to the schema visualizer (#45386)
## Summary Adds the first batch of keyboard shortcuts for the Database → Schema Visualizer page, following the registry pattern established for the SQL editor and table editor. Fixes [FE-3115](https://linear.app/supabase/issue/FE-3115). ## Shortcuts | Shortcut | Action | | --- | --- | | `Mod+Shift+C` | Copy schema as SQL | | `Mod+Shift+M` | Copy schema as Markdown | | `D` then `P` | Download schema as PNG | | `D` then `S` | Download schema as SVG | | `O` then `A` | Open the auto-layout confirmation dialog | | `O` then `S` | Open the schema selector | All six entries appear in the Cmd+K command menu under "Shortcuts" and in the global shortcuts sheet (`Mod+/`) under a new "Schema Visualizer" group while the page is mounted. None are surfaced in Account → Preferences yet (`showInSettings: false`), matching how the SQL/table editor batches shipped. The schema selector and auto-layout button are wrapped in the unified `Shortcut` component so the keybind is shown on hover (Linear-style). The dropdown items for copy/download don't get hover hints since tooltips on dropdown items don't make sense — they're discoverable via Cmd+K instead. ## Toasts Each user-visible action now confirms via a sonner toast: - `Successfully copied as SQL` — fires on Copy as SQL (button or `Mod+Shift+C`). - `Successfully copied as Markdown` — fires on Copy as Markdown (dropdown or `Mod+Shift+M`). - `Successfully downloaded as PNG` / `Successfully downloaded as SVG` — already present in `useExportSchemaToImage`; fires on click or `D → P` / `D → S`. - `Failed to download current view: …` — error toast on download failure (also pre-existing). ## Notes - `Mod+Shift+C` and `Mod+Shift+M` collide with the SQL editor's `results.copy-csv` / `results.copy-markdown` shortcuts. They coexist cleanly because `useShortcut` only fires while the hook is mounted, and the two pages live on different routes. Both labels appear in the global shortcuts sheet honestly scoped per surface. - `SchemaSelector` was promoted to a `forwardRef` component that spreads extra props onto its outer `<div>`. This was needed for `<TooltipTrigger asChild>` to attach event handlers and the ref properly — previously they were silently dropped and the hover tooltip didn't render. - `SchemaSelector` and the auto-layout `AlertDialog` accept controlled `open` props now so the shortcuts can drive them and the tooltip can be suppressed while the popover/dialog is open (`Shortcut` gained a `tooltipOpen` passthrough for this). - Auto-layout still pops the existing confirmation dialog rather than running directly — destructive enough to keep the guardrail. ## Test plan - [x] On the Schema Visualizer page, each of the six shortcuts fires the corresponding action. - [x] Hover the schema selector and the Auto layout button — tooltip shows the action label and keybind badge. - [x] Open the schema selector popover (click or `O → S`) — hover tooltip is suppressed while open. - [x] Open the auto-layout confirm dialog (click or `O → A`) — hover tooltip is suppressed while open. - [x] Cmd+K shows all six entries under "Shortcuts" while on the page; navigating away unregisters them. - [x] `Mod+/` shortcuts sheet has a "Schema Visualizer" group listing all six. - [x] Copy as SQL / Markdown each fire a confirmation toast; PNG / SVG downloads each fire a confirmation toast. - [x] On the SQL editor results page, `Mod+Shift+M` / `Mod+Shift+C` still copy results (no regression from the duplicate keybinds). - [x] The download dropdown items still work via click; PNG/SVG downloads succeed. - [x] All other consumers of `SchemaSelector` (~15 callsites) render unchanged after the `forwardRef` promotion. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Keyboard shortcuts for schema visualizer: copy as SQL/Markdown, download PNG/SVG, auto-layout, and focus selector * Success toasts when copying content to clipboard * **Improvements** * Schema selector and auto-layout dialog can be opened/closed via keyboard and programmatically * Shortcut tooltips can be suppressed when related overlays/dialogs are open * Schema Visualizer added to the shortcuts reference sheet * **Tests** * E2E tests dismiss transient toasts to avoid UI interference <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
61c6c51b81 |
feat(studio): improve keyboard shortcuts reference (#45352)
## What kind of change does this PR introduce? Feature improvement to the Studio keyboard shortcuts reference and command palette behaviour. ## What is the current behavior? The keyboard shortcuts sheet does not support filtering, some shortcut labels are harder to scan at a glance, and the command palette shows "Show all keyboard shortcuts" before the more contextual shortcuts in the `Shortcuts` section. ## What is the new behavior? Adds live filtering to the keyboard shortcuts sheet, keeps the sheet width stable on small breakpoints, renders arrow-based shortcuts more compactly, and moves "Show all keyboard shortcuts" to the end of the `Shortcuts` section so contextual actions appear first. https://github.com/user-attachments/assets/315a1a36-0cfb-4a0d-b6de-ef3c86aa9a05 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added search for keyboard shortcuts with live filtering, group-aware results, clear-search action, and empty-state handling * Added arrow key symbols for clearer shortcut visuals * **Improvements** * Updated shortcut visuals and typography for a tighter, pill-style presentation * Improved command menu ordering so shortcut-related entries appear in a logical sequence * **Tests** * Added tests covering shortcut search behavior, display formatting, and platform-specific key rendering <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
87e8c59405 |
Add view data as user in auth users + refactor UI for role impersonation (#45358)
## Context As part of RLS testing, adding @awaseem's idea for having "View data as user" CTAs in the Auth Users's table <img width="348" height="190" alt="image" src="https://github.com/user-attachments/assets/855c8f54-0aba-478c-982b-1d9d29e419bd" /> ## Other changes Similar from @awaseem's suggestions, am also refactoring the Role Impersonation UI a little, mainly from a copy writing POV to improve the clarity of the UI. - More action-oriented and contextual header for the role impersonation popover - e.g Table Editor -> "View data as a role", or SQL Editor -> "Run SQL query as a role" - Updated labels to be bit more intuitive from a builder's POV - The actual database role is still mentioned in the option's description (so we aren't obfuscating the actual postgres logic) - Add label descriptors to elaborate what each role implies - e.g Anon -> "Not logged in" - Add docs button which points to [here](https://supabase.com/docs/guides/database/postgres/row-level-security#authenticated-and-unauthenticated-roles) that explains which roles Supabase uses - (Nit) Refactor to use Card component ### Before <img width="647" height="277" alt="image" src="https://github.com/user-attachments/assets/9ebae084-38b7-4e21-886b-f609bd71976e" /> ### After <img width="604" height="309" alt="image" src="https://github.com/user-attachments/assets/4d797309-1b6b-4fd0-aab3-63d5e144c53c" /> <img width="630" height="297" alt="image" src="https://github.com/user-attachments/assets/ca748635-c5da-4426-a9c3-8cb5aeef47a6" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added "View data as user" and "Run SQL as user" actions to user rows to impersonate a user and jump to table or SQL views. * Impersonation now surfaces an identity card in new tabs showing the impersonated identity and a Stop button. * **UI/UX Improvements** * Impersonation panels accept customizable headers, show clearer role labels (Postgres), richer role descriptions, condensed RLS copy, in-panel docs link, simplified "Stop" labels, and adjusted typography/padding for consistent styling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fa8f49b261 |
feat(studio): add keyboard shortcuts to the SQL editor (#45335)
## Summary Adds the first batch of keyboard shortcuts for the SQL editor, following the registry pattern established for the table editor. ## Shortcuts | Shortcut | Action | Notes | | --- | --- | --- | | `Esc` | Blur the SQL editor | Registered as a Monaco command with a context-key precondition so inline widgets keep owning `Esc` (suggest, find, parameter hints, snippet/rename mode, accessibility help, inline suggestions, and selection cancellation). | | `Shift+E` | Focus the SQL editor | Pairs with `Esc` for mouse-free round-trip. | | `Alt+Shift+F` | Prettify SQL | Now wired through the registry; the tooltip and dropdown badge in `UtilityActions` read the keybind from the same source of truth. Works from inside the editor (Monaco action) and from anywhere on the page (`useShortcut`). | | `Mod+Shift+Enter` | Run EXPLAIN ANALYZE | Routes results into the Explain tab. Surfaces in the Monaco context menu next to "Run Query". | | `Shift+N` | Open a new SQL snippet | Navigates to `/sql/new?skip=true` to avoid the redirect-to-last-visited effect that fires on plain `/sql/new`. | All entries appear in the command menu (`Mod+P`) under "Shortcuts" while their host components are mounted. None are surfaced in Account → Preferences → Keyboard shortcuts yet (`showInSettings: false`), matching how the table editor shortcuts shipped. ## Notes - The blur shortcut intentionally lives on the Monaco instance rather than the document-level hotkey listener — the document listener can't preempt Monaco's own `Esc` handling. Other shortcuts that need to fire while the editor has focus (run, save, format, explain) are registered as Monaco actions; everything else uses `useShortcut`. - Format and explain are double-registered (Monaco action + `useShortcut`) so they fire whether the editor is focused or not. The Monaco actions don't read the user's enable/disable preference yet — same asymmetry as the existing run/save actions. - `Shift+N` is scoped to the SQL editor route. To make it work globally we'd register it at a higher layout level. ## Test plan - [x] Inside editor: `Esc` blurs; suggest/find/parameter hints still close on `Esc`; multi-cursor selection collapses on first `Esc`, blurs on second. - [x] Outside editor: `Shift+E` returns focus to the editor. - [x] `Alt+Shift+F` formats from inside and outside the editor; tooltip + dropdown badge show the correct keybind. - [x] `Mod+Shift+Enter` runs EXPLAIN ANALYZE and switches to the Explain tab. - [x] `Shift+N` opens a fresh snippet without bouncing back to the previous one. - [x] All five shortcuts appear in `Mod+P` with the right badges. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Keyboard shortcuts for SQL editor: format SQL, run EXPLAIN ANALYZE, focus/blur editor, and open a new SQL snippet. * Added "Prettify SQL" and "Run EXPLAIN ANALYZE" actions to the editor context menu with shortcuts. * Centralized registration of SQL editor shortcuts so they appear across the app. * **UX Improvements** * Escape key blurs editor focus when appropriate to allow easy exit without disrupting editor widgets. * **Style** * Adjusted success toast capitalization for copied Markdown. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com> |
||
|
|
e7c33bf580 |
feat(studio): add insert, filter, sort, refresh shortcuts to the table editor (#45191)
## 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 — a second batch of table editor shortcuts, stacked on top of #45178. ## What is the current behavior? Inserts / filters / sort / refresh are all mouse-only. No keyboard access, and no affordance for discovering what keybinds might exist. ## What is the new behavior? ### New shortcuts | Keybind | Action | Surface | |---|---|---| | `I` then `R` | Insert row | hotkey + Cmd+K + inline keybind in Insert dropdown | | `I` then `C` | Insert column | hotkey + Cmd+K + inline keybind in Insert dropdown | | `I` then `U` | Import data from CSV | hotkey + Cmd+K + inline keybind in Insert dropdown | | `Shift+F` | Focus filters | hotkey + Cmd+K — focuses the new filter bar's freeform input | | `F` then `C` | Clear filters | hotkey + Cmd+K — gated on `filters.length > 0` | | `S` then `C` | Clear sort | hotkey + Cmd+K — gated on `sorts.length > 0` | | `Shift+R` | Refresh table | hotkey + Cmd+K + hover tooltip on the Refresh button | All are `ignoreInputs: true` so they don't fire while typing. The insert / clear-filters / clear-sort shortcuts use two-step chords so they don't clobber single-letter keys users might reach for elsewhere; Focus filters and Refresh keep their Shift-prefixed single-step bindings. ### Infrastructure - **New `<ShortcutBadge>`** (`components/ui/ShortcutBadge.tsx`) — inline keybind display. Reads the sequence straight from the registry, so the ID is the single source of truth. Renders multi-step chords with a "then" separator between steps. Defaults to `variant="inline"` (the flat `text-foreground/40` style used across the app in `RunButton`, `ActionBar`, `OperationQueueSidePanel`, etc.) with `variant="pill"` available if someone needs the boxed style. - **Insert dropdown restyled** — each `DropdownMenuItem` in `HeaderNew`'s Insert menu now shows its keybind inline on the right (centered vertically, with `pr-4` + `shrink-0` so long table names in the description never crowd the badge). - **`RefreshButton`** swapped from `ButtonTooltip` to `<Shortcut>` so the keybind tooltip renders automatically from the registry. - **`FilterPopoverPrimitive` untouched** — the old filter bar is being deleted, so Shift+F is scoped to the new filter bar only. The handler focuses `[data-testid="filter-bar-freeform-input"]` (the existing freeform input in the ui-patterns `FilterBar` → `FilterGroup`). ## Additional context Stacked on #45178 (FE-3057 — initial table editor shortcuts). Rebase after that one merges. ### Test plan - [x] Open a table → Insert dropdown shows keybind to the right of each item, no wrap encroachment even with long table names - [x] `I` then `R` opens the Row editor; `I` then `C` opens the Column editor; `I` then `U` opens the CSV import flow - [x] `Shift+F` focuses the new filter bar's freeform input - [x] Add a filter → `F` then `C` clears it; shortcut disabled in Cmd+K when no filters are applied - [x] Sort a column → `S` then `C` clears sort; shortcut disabled when no sorts - [x] `Shift+R` refreshes the table (spinner shows on the Refresh button); hover the button → keybind tooltip - [x] All seven new entries show up in Cmd+K when their gates are satisfied <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added keyboard shortcuts for table actions: insert row, insert column, import CSV, refresh, focus filters, clear filters, and clear sorts. * Shortcuts are available in the command menu and show visual keyboard hints. * **UI** * Menu entries now display shortcut badges. * Refined dropdown spacing/layout and updated the refresh control to surface its shortcut. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
42b431a270 |
feat(studio): add keyboard shortcuts to the table editor (#45178)
## 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 — a set of new keyboard shortcuts for the table editor, along with infrastructure to register, gate, and surface them. ## What is the current behavior? Clicking into the grid "traps" the keyboard: Escape doesn't pop out, there are no shortcuts for row selection / deletion / navigation, and the search-tables input grabs focus on page load. ## What is the new behavior? ### New shortcuts (all scoped to the table editor) | Keybind | Action | Surface | |---|---|---| | `Esc` | Exit grid selection — clears the highlighted cell and drops focus back to the page | hotkey | | `↑` / `↓` | Start grid navigation from the first cell when no cell is selected | hotkey | | `Shift+Space` | Toggle selection on the current row | hotkey + checkbox tooltip | | `Mod+A` | Toggle selection on all displayed rows (matches Excel) | hotkey + header-checkbox tooltip + Cmd+K | | `Mod+Shift+A` | Toggle selection on all rows in the table | hotkey + "Select all rows in table" button tooltip + Cmd+K | | `Mod+Backspace` | Delete selected rows | hotkey + delete-button tooltip + Cmd+K | ### Infrastructure - **Split registry** — table-editor shortcuts moved to `state/shortcuts/registry/table-editor.ts`, spread into `SHORTCUT_IDS`. Makes it easy to scope a runtime check to a specific surface. - **`eventMatchesAnyShortcut`** (`state/shortcuts/matchEvent.ts`) — queries the hotkey library's live `SequenceManager` so gated shortcuts (`enabled: false`) are correctly excluded. Covered by `matchEvent.test.ts`. - **`handleCellKeyDown`** now calls `event.preventGridDefault()` whenever the keystroke matches an active table-editor shortcut, so rdg's "start editing on key press" default doesn't compete with shortcut actions (e.g. typing `Shift+X` no longer opens edit mode with `X` as input). - **`<Shortcut>` / `<ShortcutTooltip>`** used on the header checkbox, the per-row checkbox, the "Select all rows in table" button, and the delete button — keybinds show up on hover (Linear-style) so users can discover them without reading docs. - **CSS** — `.rdg:not(:focus-within) .rdg-cell[aria-selected='true']` drops the selected-cell outline whenever focus leaves the grid, reinforcing the "you're out" feedback after `Esc`. - **`useShortcut`** wraps the Cmd+K-registered action to close the command menu after firing (previously menu stayed open after selecting an action). - **Search-tables input** no longer auto-focuses on load, so arrow shortcuts work immediately without clicking out first. ## Additional context Linear: FE-3057 ### Test plan - [x] Open any table → `↓` selects the first cell; subsequent arrows navigate rows - [x] `Esc` drops focus out of the grid and re-enables `↓` to re-enter - [x] Click a cell → `Shift+Space` toggles that row's selection (checkbox) - [x] `Mod+A` toggles all displayed rows - [x] With pagination + some rows selected → `Mod+Shift+A` toggles "Select all rows in table" - [x] With rows selected → `Mod+Backspace` deletes them (existing confirmation flow) - [x] Hover the header checkbox / per-row checkbox / delete button → keybind tooltip after ~500ms - [x] Cmd+K with selection → the relevant action shows up; selecting it closes the palette and runs <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added table editor keyboard shortcuts for navigation, row selection, and cell actions, with command-menu integration and visible shortcut tooltips. * **Improvements** * Better keyboard handling in grid cells allowing external shortcuts to override default behavior. * Select-all/deselect-all toggle and improved select-row UX; selected-cell styling no longer shows when grid loses focus. * Command menu now reliably closes before executing shortcut actions. * Removed autofocus on the table editor search input for consistent focus behavior. * **Tests** * Added unit tests covering shortcut matching and command-menu shortcut behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
5f867e5f6c |
Feature Preview: RLS Tester (#45121)
## Context Resolves FE-3077 Related discussion: https://github.com/orgs/supabase/discussions/45233 Verifying the correctness of your RLS policies set up has always been a gap, as highlighted by a number of GitHub discussions like [here](https://github.com/orgs/supabase/discussions/12269) and [here](https://github.com/orgs/supabase/discussions/14401). As such, we're piloting a dedicated UI for RLS testing (using role impersonation as the base), in which you'll be able to - Run a SQL query as a user (not logged in / logged in - this is the role impersonation part) - See which RLS policies are being evaluated as part of the query - And hopefully be able to debug which policies are not set up correctly Changes are currently set as a feature preview - and we'll iterate as we get feedback from everyone 🙂 🙏 <img width="613" height="957" alt="image" src="https://github.com/user-attachments/assets/83c37f8a-28fc-43b3-b0ff-e28571d8710c" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * RLS Tester: run queries as anon or authenticated users, view inferred SQL, per-table policy summaries, and data previews of accessible rows. * UI preview: new RLS Tester preview card and modal with opt-in toggle; RLS Tester sheet with role/user selector and query editor. * SQLEditor: “Explain” tab is always visible. * **Chores** * Added supporting API endpoints, background checks for table RLS status, and a local-storage flag to persist the preview opt-in. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7f5865872a |
Enforce noUnusedLocals and noUnusedParameters in tsconfig.json + fix all related issues (#45264)
## Context Enforce `noUnusedLocals` and `noUnusedParameters` in tsconfig.json + fix all related issues |
||
|
|
d6e400620d |
chore(studio): remove old table editor filter bar (#45220)
## Summary - Removes the legacy Table Editor filter bar and its `supabase-ui-table-filter-bar` feature-preview flag (opt-out rate ~0.13%, no plans to keep supporting it). - Merges `HeaderNew` into `Header`, consolidates `useTableFilterNew` into `useTableFilter`, and adds `useOptionalTableEditorTableStateSnapshot` so `useTableFilter` can safely fall back to URL params when called outside the table-editor provider (e.g. from the sidebar). - Drops the associated preview modal entry, screenshot, and local storage key. Based on the closed PR https://github.com/supabase/supabase/pull/44867. Closes [FE-3071](https://linear.app/supabase/issue/FE-3071/remove-old-table-editor-filter-bar). ## Test plan - [x] `pnpm --filter=studio typecheck` passes - [x] `pnpm --filter=studio lint` passes - [x] Open the Table Editor, confirm the new filter bar renders and filters apply/clear correctly - [x] Apply filters, reload the page — filters persist via URL params - [x] Delete a column that has an active filter — filter is removed cleanly - [x] Right-click a cell — "Filter by value" still appears for simple values - [x] Select rows — row-selection header (copy / export / delete) still works - [x] Foreign Row Selector still renders (`FilterPopoverPrimitive` retained for this usage) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Table filter bar is now permanently available (no longer gated behind preview feature). * **Improvements** * Reorganized table header layout with improved filter UI placement and styling. * Streamlined and unified filter behavior across the grid for more consistent operation. * Simplified insert row/column functionality with clearer permission handling. * **Refactor** * Consolidated filter system by removing redundant implementations and feature flags. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ec7233b33c |
feat(studio): add keyboard shortcuts reference (#45197)
## What kind of change does this PR introduce? Feature. ## What is the current behaviour? Keyboard shortcuts can be discovered piecemeal through command palette entries, tooltips, and preferences, but there is no universal shortcut reference surface. ## What is the new behaviour? Adds a global `Mod+/` shortcut and command palette action to open a keyboard shortcuts reference sheet. The sheet renders registered shortcuts grouped from general dashboard actions through navigation and more specific surfaces. | Preview | | --- | | <img width="820" height="928" alt="CleanShot 2026-04-24 at 11 27 51@2x" src="https://github.com/user-attachments/assets/8ceb4a35-7adc-474b-8702-5c08a4219d25" /> | <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a comprehensive keyboard shortcuts reference sheet that displays all available shortcuts organized into logical categories. * New keyboard shortcut Mod+/ (Cmd+/ on Mac) opens the reference sheet instantly from anywhere within the application. * Shortcuts are displayed with their formatted keyboard combinations, with multi-step sequences clearly separated for easy reference and discovery. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fa4053cd59 |
fix(studio): preserve ignoreInputs across re-renders in useShortcut (#45174)
## Summary Fixes [FE-3060](https://linear.app/supabase/issue/FE-3060/modshiftc-modshiftm-shortcuts-suppressed-when-a-table-editor-cell-is). `Mod+Shift+C` (Copy as CSV) and `Mod+Shift+M` (Copy as Markdown) — and any other Meta/Ctrl/Escape shortcut registered via `useShortcut` without an explicit `ignoreInputs` — stopped firing when focus landed on a `react-data-grid` cell in the table editor (or any other input/contenteditable). ## Fix In `apps/studio/state/shortcuts/useShortcut.tsx`, only include `ignoreInputs` in the options object when it's actually set, so TanStack's register-time default sticks across re-renders. Updated the `ignoreInputs resolution` test to assert that the key is omitted (rather than passed as `undefined`) when neither caller nor registry set it. ## Test plan - [x] SQL editor results: `Cmd+Shift+C`, `Cmd+Shift+M`, `Cmd+Shift+J`, `Cmd+Shift+D` still fire - [x] `Mod+ArrowUp` / `Mod+ArrowDown` / `Mod+ArrowLeft` / `Mod+ArrowRight` inside a focused cell editor still blocked (registry sets `ignoreInputs: true`) - [x] Unit tests: `pnpm vitest run state/shortcuts/useShortcut.test.tsx` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed keyboard shortcut handling to properly respect the hotkey library's default configuration values when custom options are not explicitly specified. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d67050c44e |
test(studio): add unit tests for shortcut primitives (#45162)
## Summary Closes [FE-3056](https://linear.app/supabase/issue/FE-3056/add-unit-tests-for-new-shortcut-primitives). Backfills unit coverage for the shortcut primitives added in the recent keyboard-shortcut overhaul — these shipped with no tests. - **`state/shortcuts/formatShortcut.test.ts`** (16 tests) — `hotkeyToKeys`: `Mod → Meta` mapping (case-sensitive, substring-safe), single/multi-modifier combos, named keys, punctuation, edge cases. - **`state/shortcuts/useShortcut.test.tsx`** (26 tests) — mocks `useHotkeySequence`, `useRegisterCommands`, and `useIsShortcutEnabled` to unit-test: sequence/callback wiring (single-step + multi-step G-chords), full option-resolution priority (caller → registry → fallback) for `enabled` / `timeout` / `ignoreInputs`, global-preference AND gating, command-menu registration across all four enable permutations, stable action identity, stale-closure protection via `useLatest`, and badge rendering with/without the "then" separator. - **`components/ui/Shortcut.test.tsx`** (12 tests) — mocks `useShortcut` and `ShortcutTooltip` to verify prop forwarding (including rerender behavior), tooltip positioning props, unset-prop hygiene, and the `asChild` pass-through contract (clicks on the child do not fire `onTrigger`). 54 tests total, all passing. ## Test plan - [x] `pnpm --filter studio test state/shortcuts/formatShortcut.test.ts state/shortcuts/useShortcut.test.tsx components/ui/Shortcut.test.tsx` - [x] `tsc --noEmit` clean across the three test files <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added comprehensive test coverage for the Shortcut component, verifying rendering, hook integration, and tooltip behavior. * Added test suite for hotkey key formatting, covering plain keys, named keys, modifiers, and edge cases. * Added test suite for the useShortcut hook, validating hotkey sequences, enablement logic, command menu integration, and callback handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
28a2c25e0e |
feat(studio): add navigation shortcuts with hover tooltips (#45127)
## Summary - Adds `<Shortcut>` component: binds a registered shortcut + renders a Linear-style hover tooltip (label + keybind pills) in one declaration - Adds `<ShortcutTooltip>` as the lower-level primitive for cases where binding lives elsewhere - Registers 13 G-chord navigation shortcuts (`G H` / `G T` / `G S` / `G D` / `G A` / `G B` / `G F` / `G R` / `G V` / `G O` / `G L` / `G I` / `G ,`) - Wires shortcuts into `SideBarNavLink` — binding + dynamic-delay tooltip (0ms collapsed, 1000ms expanded) replaces the old label-only collapsed tooltip Closes [FE-3048](https://linear.app/supabase/issue/FE-3048/create-navigation-shortcuts). ## Test plan - [x] Hover each main sidebar nav item with sidebar expanded — tooltip appears after delay with label + shortcut pills - [x] Collapse sidebar — tooltip appears instantly on hover - [x] Press `G` then a registered letter anywhere outside text inputs — navigates to that screen - [x] Press `G` inside a text input — no navigation fires - [x] Disabled nav items (project inactive) — no shortcut fires, no tooltip anomaly - [x] Feature-gated routes (auth/storage/realtime off) — shortcut is gone with the route <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Global keyboard shortcuts added for navigating major app sections (home, editors, database, auth, storage, functions, realtime, advisors, observability, logs, integrations, settings). * Navigation items display their keybinds in hover tooltips and can be triggered via those shortcuts. * Tooltip timing adapts to sidebar state (immediate when collapsed, delayed when expanded). * Shortcut-aware tooltip display now shows multi-step key sequences clearly. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3838e32d33 |
chore(studio): migrate useKeyboardShortcuts to useShortcut (#45100)
## Summary - Follow-up to #45099 — migrates the final legacy hotkey hook (`useKeyboardShortcuts` in `apps/studio/components/grid/components/common/Hooks.tsx`) to `useShortcut`, backed by `SHORTCUT_DEFINITIONS`. - Adds 4 registry entries (`TABLE_EDITOR_JUMP_FIRST_ROW` / `_LAST_ROW` / `_FIRST_COL` / `_LAST_COL`), all `showInSettings: false` so they stay non-configurable (same as today). - Adds `ignoreInputs` to `ShortcutOptions` and threads it through `useShortcut` → `useHotkeySequence`. Replaces the legacy `whitelistNodes: ['INPUT', 'TEXTAREA', 'SELECT']` with the built-in TanStack option, which also covers `contenteditable`. - Drops the `navigator.appVersion` macOS/Windows detection in `Shortcuts.tsx` (`Mod` resolves this automatically) and the manual `event.stopPropagation()` calls (TanStack's default is `stopPropagation: true`). - Deletes `Hooks.tsx` — no remaining consumers. Closes FE-3049. ## Why `ignoreInputs: true` on these entries `Mod+Arrow*` is a Ctrl/Meta combo. TanStack's default for Ctrl/Meta combos is `ignoreInputs: false`, which would fire the shortcut even when focus is in a text input — not what we want. Setting `ignoreInputs: true` in the registry preserves the legacy whitelist behavior. ## Test plan All shortcuts should still fire with **Cmd** (macOS) / **Ctrl** (Win/Linux). Test surface: **Table Editor** → open any table with rows and multiple columns. **Grid navigation (with a cell selected — click a cell first)** - [x] `Cmd+ArrowUp` jumps selection to row 0 in the same column - [x] `Cmd+ArrowDown` jumps selection to the last row in the same column - [x] `Cmd+ArrowLeft` jumps selection to the first non-frozen column in the same row - [x] `Cmd+ArrowRight` jumps selection to the last column in the same row (not the trailing "add column" cell) **Whitelist regression (most important — the `ignoreInputs` check)** - [x] Open the **Filter** popover on a table → put focus in the filter value `<input>` → type with arrow keys / use `Cmd+ArrowLeft/Right` for word-jump → cursor moves in the input, grid selection does **not** jump - [x] Same for a `<textarea>` (e.g. row editor → a text column with a textarea) — `Cmd+ArrowUp/Down` should not hijack focus away from the textarea - [x] Same for a `<select>` (e.g. row editor → enum / boolean column) — arrow keys behave normally - [x] Editing a cell value in-place (double-click a cell to enter edit mode) — arrow keys navigate the text, don't jump the grid **Platform check** - [x] On macOS, the shortcuts fire with `Cmd` (not `Ctrl`) - [x] On Windows/Linux, they fire with `Ctrl` (not `Cmd`) — `Mod` resolution - [x] None of the new entries appear in Account → Preferences → Keyboard shortcuts (all `showInSettings: false`) **Regression checks** - [x] `pnpm --filter=studio typecheck` passes (verified locally) - [x] Existing shortcuts from #45099 (`Cmd+K`, `Cmd+I`, `Cmd+S` in op queue, results copy, etc.) still work unchanged <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added four keyboard shortcuts for table navigation: jump to first/last row and first/last column using Mod+Arrow keys. * Added a shortcut option to prevent triggers when focus is in input fields. * **Bug Fixes** * Improved keyboard shortcut handling for more consistent behavior across platforms. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
40791f9846 |
chore(studio): migrate useHotKey to useShortcut (#45099)
## Summary - Migrates all 11 `useHotKey` call sites across 9 files to `useShortcut`, backed by `SHORTCUT_DEFINITIONS` in `state/shortcuts/registry.ts`. - Adds 10 new registry entries (all `showInSettings: false` to keep behavior identical to today — these were not previously user-configurable). - Deletes `apps/studio/hooks/ui/useHotKey.ts`. - Simplifies `ActionBar.handleSave` — the legacy hook passed a `KeyboardEvent` the callback used for `preventDefault`/`stopPropagation` and a textarea-plain-Enter guard; all of that is redundant under `useShortcut` (TanStack handles default/propagation; `Mod+Enter` never fires on plain Enter). - Removes a stale commented-out `useHotKey` reference in `DataTableFilterCommand.tsx`. Part of FE-3025 (legacy hotkey hook cleanup). `useKeyboardShortcuts` in `grid/components/common/Hooks.tsx` will be migrated in a follow-up. ## Test plan All shortcuts should still fire with **Cmd** (macOS) / **Ctrl** (Win/Linux). **Table Editor — operation queue** (requires pending unsaved edits on a row) - [x] `Cmd+S` saves pending edits - [x] `Cmd+.` toggles the operation queue side panel - [x] `Cmd+Z` undoes the latest edit and re-fetches the affected table rows - [x] With no pending edits, none of the above fire (gated by `isEnabled`) **Table Editor — side panel editor forms** (row, table, column, policy, etc.) - [x] `Cmd+Enter` submits the form when the panel is visible - [x] Does not submit if the form is disabled/loading or the panel is hidden **Unified Logs — data table** - [x] `Cmd+B` toggles the filter controls sidebar (desktop) - [x] `Cmd+B` opens the filter drawer (mobile, `<sm` breakpoint) - [x] `Cmd+Esc` resets active column filters (reset button visible) - [x] `Cmd+U` resets column order + visibility - [x] `Cmd+J` toggles live mode **Unified Logs — reset focus** - [x] `Cmd+.` blurs the currently focused element / resets focus to body **AI Assistant panel** - [x] While editing a message, `Cmd+Esc` cancels the edit **Regression checks** - [x] `pnpm --filter=studio typecheck` passes (verified locally) - [x] None of the new shortcut entries appear in Account → Preferences → Keyboard shortcuts (all `showInSettings: false`) - [x] Existing shortcuts (`Cmd+K`, `Cmd+I`, `Cmd+E`, results copy/download) still work unchanged <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Refactor * Implemented a centralized keyboard shortcut registry system for managing shortcuts consistently across the application * Updated multiple UI components throughout the interface to use the new shortcut management system * All existing keyboard shortcuts continue to function without any changes in behavior or user experience ## Chores * Removed legacy keyboard shortcut hook implementation <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b721a2d780 |
feat(studio): advisor signal items for banned IPs (#44372)
## What kind of change does this PR introduce? Feature. Resolves DEPR-430. ## What is the current behaviour? The homepage Advisor summary, shared Advisor panel, and top-nav Advisor indicator only surface lints and notifications. Banned IPs are not represented as dismissible Advisor items, so network bans are easy to miss unless a user visits Database Settings directly. The `public bucket allows listing` warning is no longer part of this PR. That warning will move to a follow-up Splinter `WARN` lint so it can flow through the standard lint surfaces instead of a bespoke Studio signal path. ## What is the new behaviour? - adds a new Advisor `signal` source for banned IPs on the platform homepage, in the shared Advisor panel, and in the top-nav Advisor indicator - keeps dismissals client-side only for now, scoped by project and exact IP fingerprint - keeps banned IP signals at `warning` severity because they still indicate suspicious traffic and remain actionable if a user wants to review or remove a ban - leaves `/project/[ref]/advisors/security` as follow-up work because that surface is still lint-native, and banned IPs are management-plane signals rather than Splinter lints | After | | --- | | <img width="1728" height="997" alt="Mallet Toolshed Supabase-65A60B4A-107E-4D79-B9A8-23F754BEAB08" src="https://github.com/user-attachments/assets/c08ecbbb-c302-43bd-81bb-6ba7eb18b7b3" /> | ## Reviewer testing notes 1. Use a throwaway project. 2. Get the database connection string for that project. 3. Attempt to connect with the wrong password 3-4 times until you hit an `ECONNREFUSED`-style error, which should mean your IP has been banned. 4. Refresh Studio and confirm the project overview shows the new `Banned IP address` signal. 5. Open the Advisor Center and confirm: - the top-nav Advisor dot turns warning yellow - the signal detail shows `Entity`, `Issue`, and `Resolve` - `Edit network bans`, `Dismiss`, and `Learn more` are present 6. Open Database Settings > Network bans and confirm your banned IP appears there and can be unbanned. 7. Note that `/project/[ref]/advisors/security` will not show this item. That page is still lint-only, and this banned IP work is a short-term client-side signal rather than a true lint. Longer term, we likely want a more durable event model here so banned IPs can power notifications, webhooks, emails, and other project-level alerts. --------- Co-authored-by: kemal <hello@kemal.earth> Co-authored-by: Charis Lam <26616127+charislam@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
a7341c70ea |
feat(shortcuts): add showInSettings flag to ShortcutDefinition (#44997)
Closes [FE-3021](https://linear.app/supabase/issue/FE-3021/hide-shortcut-in-settings-option-for-new-api). ## Summary - Adds an optional `showInSettings` field to `ShortcutDefinition` (defaults to `true`). - `HotkeySettings` filters out entries where `showInSettings === false` before rendering the Account → Preferences → Keyboard shortcuts list. - No registry entries are flipped in this PR — opt-in per shortcut as needed. ## Test plan - [x] Confirm all existing shortcuts still appear under Account → Preferences → Keyboard shortcuts. - [x] Temporarily set `showInSettings: false` on one entry and verify it disappears from the list. - [x] `pnpm --filter studio exec tsc --noEmit` passes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Keyboard shortcuts can now be selectively hidden from the Account preferences settings based on configuration. * **Refactor** * Updated keyboard shortcut filtering logic to respect visibility settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e8df67d5d5 |
chore: migrate shortcuts to new hooks API (#44955)
## 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? Cleanup shortcuts with new hooks <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Centralized keyboard shortcut system for consistent shortcut behavior across the app and moved preference toggles to a unified registry. * **New Features** * Added explicit shortcuts for Command Menu, AI Assistant, Inline Editor, and result copy/download actions. * Hotkey preferences UI now renders dynamically from the centralized shortcut list. * **Tests** * Test helpers updated to include the command menu provider for accurate shortcut behavior in tests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3ed436de74 |
feat: new shortcuts hook with registrations (#44954)
## 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? - Brand new hook APIs for registering shortcuts using tanstack hotkeys - Support for command menu injection when shortcut is added <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Centralized keyboard shortcuts system with per‑shortcut registration and per‑user enable/disable preferences stored locally * Added a "Copy results as Markdown" shortcut (Mod+Shift+M) * Shortcuts can be surfaced in the Command Menu with a visual shortcut badge for discoverability * **Documentation** * Legacy keyboard shortcut hooks marked as deprecated and documentation updated to point to the new shortcut API <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
1c228ad18c |
Chore dnd kit supabase grid columns sort (#44654)
## Problem We currently have 3 different libraries for drag & drop, two of which are not actively maintained anymore. ## Solution Migrate all usage of the two unmaintained libraries to DndKit. This PR focuses on using DndKit instead of `react-dnd` for column reordering in the table editor ## Screencast https://github.com/user-attachments/assets/54fb36f4-5671-42e2-9698-2ae928a69f55 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Column drag-and-drop rebuilt with a live drag preview and improved pointer/keyboard handling * **Improvements** * More reliable column reordering with refined move/freeze/unfreeze behavior and stable index recomputation * Standardized column type/format display and simplified grid rendering * **Accessibility** * Added accessible labeling for column actions controls * **Tests** * End-to-end locator updated to target the column actions button deterministically <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
205cbe7d26 | chore(studio}: enforce import order, remove bare import specifiers (#44585) | ||
|
|
333175b17b |
refactor: switch to @ imports and enforce sorting for studio/state (#44523)
* **Refactor** * Updated internal module import paths to use standardized alias conventions across the codebase. * Reorganized import statement ordering for improved code consistency. |
||
|
|
cccae29569 |
refactor(studio): extract storage preferences into useStoragePreference hook (#44519)
## 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? Refactor ## What is the current behavior? Storage explorer preferences (`view`, `sortBy`, `sortByOrder`, `sortBucket`) are managed inline within the Valtio proxy state in `storage-explorer.tsx`, which reads/writes localStorage directly. ## What is the new behavior? Preferences are extracted into a dedicated `useStoragePreference` hook backed by `useLocalStorage`. A companion `getStoragePreference` function allows the Valtio state to read sort options imperatively for API calls without holding preference data itself. Consumers import the hook directly instead of reading preferences from the snapshot. ## Additional context No behavioral or visual changes — localStorage key and data shape are unchanged. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Storage view and sorting preferences now persist per project and drive the explorer UI. * Changing view or sort preferences refreshes folder contents and clears the open file preview. * **Chores** * Centralized preference handling for consistent behavior across the storage explorer. * **Tests** * Updated tests to exercise the new preference-backed behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
edacf2413d |
chore(studio): ship connect section, remove getting started and experiment plumbing (#44329)
## Summary The `connectSection` A/B experiment concluded as a true null (no effect on activation or any downstream metric after 13 days at 50/50, ~153K mature orgs). Saxon decided to ship the Connect section as the permanent experience. This PR removes the Getting Started control variant, the old Connect modal, all experiment flag gating, and related telemetry types. ## Changes - Delete `GettingStarted/` directory (5 files: section component, types, utils, progress hook) - Delete old `Connect.tsx` dialog modal (replaced by ConnectSheet) - Remove `connectSection` PostHog flag reads from `Home.tsx` and `LayoutHeader.tsx` - Remove `getSectionVisibility()` experiment logic and `ConnectSectionVariant` type - Remove `getting-started` from `DEFAULT_SECTION_ORDER` - Always render `<ConnectSheet />` in header (no more conditional with old `<Connect />` modal) - Remove `variant` prop from `ConnectSection` component - Remove 4 getting-started telemetry event interfaces from `telemetry-constants.ts` - Update `mergeSectionOrder` tests to reflect new section order ## Testing Tested on Vercel preview: - [x] Project homepage shows Connect section for new projects (< 10 days old) - [x] Connect section hidden for mature projects (> 10 days old) - [x] Header Connect button opens ConnectSheet (not old modal) - [x] Connect tiles open ConnectSheet with correct tab - [x] Section drag-and-drop still works without getting-started in the order - [x] Existing users with `getting-started` in localStorage order don't break (mergeSectionOrder strips it) ## Linear - fixes GROWTH-730 --------- Co-authored-by: Alaister Young <alaister@users.noreply.github.com> |
||
|
|
753638caf4 |
fix: storage explorer column infinite loading loads the wrong column (#44275)
## Problem When scrolling down in a column that has more than 200 items to trigger its lazy loading, while other columns are displayed and the targeted column isn't the last one, it doesn't load its items. Fixes #43799 ## Solution - Don't rely on the storage state for opened folders for the lazy loading - Add the item path information to the column and use it to define the API request path ## How to test - create a bucket - create a folder and upload more than 200 items in it - in this folder, create a sub folder and upload more than 200 items in it (make sure its name position it _before_ the files) - refresh the page - without scrolling the first column, select the subfolder - now scroll down on the first column past the last of its items and verify it loads more items - do the same on the sub folder column To easily create many files to upload, use the following commands: For root folder: ```sh for i in {0..300} do echo hello >"root_$(printf "%03d" "$i").txt" done ``` For sub folder: ```sh for i in {0..300} do echo hello >"sub_$(printf "%03d" "$i").txt" done ``` |
||
|
|
0c5f64fcba |
feat(assistant): upgrade default models to gpt-5.4-nano and gpt-5.3-codex (#44107)
Replaces `gpt-5-mini` and `gpt-5` with `gpt-5.4-nano` and `gpt-5.3-codex` respectively. Clients with stale model IDs in IndexedDB will gracefully reset to the new defaults. While we can technically keep the existing models around, we've [opted](https://supabase.slack.com/archives/C051L8U2EJF/p1774283070517609?thread_ts=1773771991.871669&cid=C051L8U2EJF) to replace them w/ the newer models for simplicity. Basic completion endpoints use `'none'` reasoning level for optimal speed. Rationale for these models is they provide they best balance of intelligence/speed and cost. GPT-5.4-nano is less expensive (0.8x price), faster, and smarter than GPT-5-mini. GPT-5.4-mini would be even smarter but is 3x the price. GPT-5.3-Codex is ~1.4x the price of GPT-5, while GPT-5.4 would be 2x price, but 5.3-Codex is still a big intelligence boost from GPT-5. See [eval comparison](https://www.braintrust.dev/app/supabase.io/p/Assistant/experiments/mattrossman%2Fai-509-v2-upgrade-assistant-models-beyond-gpt-5-family-1774468619?c=master-1774458837&diff=between_experiments), scores are relatively stable and conciseness naturally improves on gpt-5.4-nano. Other change: - Fixed an eval test case to clarify that https://supabase.help is also a correct URL for submitting support ticket, which was unfairly scored as incorrect [here](https://www.braintrust.dev/app/supabase.io/p/Assistant/trace?object_type=experiment&object_id=5244cccd-23b2-4f79-9dd2-287f1b40ebad&r=bac9b903-8bde-4c21-99dd-e0ed141c4f9e&s=f248fbf5-75bf-4aab-be0a-87a4298e6d11) I sanity checked the Assistant, natural language filters, and SQL Editor completions on staging preview. References: - https://openai.com/index/introducing-gpt-5-4-mini-and-nano/ - https://openai.com/index/introducing-gpt-5-3-codex/ - https://developers.openai.com/api/docs/pricing Closes AI-509 |
||
|
|
adf8b0c67c |
feat(assistant): per-endpoint reasoningEffort + model config cleanup (#43981)
We're exploring support for newer models like [gpt-5.4-nano](https://openai.com/index/introducing-gpt-5-4-mini-and-nano/) in Assistant. This model doesn't support the `'minimal'` reasoning effort level we use for gpt-5-mini which leads to vague errors. <img width="595" height="263" alt="CleanShot 2026-03-18 at 17 13 05@2x" src="https://github.com/user-attachments/assets/cf7c2370-322d-4a8a-be55-23e680db0aa0" /> Also, we've [previously discussed](https://supabase.slack.com/archives/C0161K73J1J/p1771544464850199?thread_ts=1771493920.775699&cid=C0161K73J1J) that reasoning adds unnecessary latency to otherwise simple AI completion endpoints like `title-v2`. We want more control of reasoning level independent of model/endpoint. This PR aims to solve both problems by: - making reasoning effort configurable on a per-request basis - adding compile-time guardrails to prevent selecting an incompatible reasoning level for models - adding a `DEFAULT_COMPLETION_MODEL` with minimal reasoning that we can update with newer models that support disabling reasoning (independent of Assistant chat model reasoning) Other improvements to our model config logic: - Fixes bug in `onboarding/design.ts` and `assistant.eval.ts` where `providerOptions` was being dropped - `getModel()` now returns a bundled `modelParams` object (spread into AI SDK calls) so `providerOptions` can't be accidentally omitted (this [has happened before](https://supabase.slack.com/archives/C0161K73J1J/p1771518443534309?thread_ts=1771493920.775699&cid=C0161K73J1J)) - Introduces an `ASSISTANT_MODELS` registry as a single source of truth for assistant model config, eliminating hardcoded model IDs across the codebase - Aligns free/pro model conditional logic with `assistant.advance_model` entitlement naming conventions instead of the `isLimited` pattern - Adds `console.error` logging of Assistant stream errors so we can interpret reasoning effort compatibility errors in the future (instead of just opaque "Sorry, I'm having trouble responding right now" card) - Removes unnecessary type casts and generally making the model config logic stricter - Removes pre-existing dead code: `anthropic` provider variant in `GetModelParams` / `PROVIDERS` registry that was never implemented in `getModel()` Now if you try to select an unsupported reasoning level you get a type error: <img width="1306" height="320" alt="CleanShot 2026-03-20 at 14 37 24@2x" src="https://github.com/user-attachments/assets/a6ac234b-5ea5-4d81-8e01-ac4be34a0800" /> And if for some reason an invalid reasoning level slips through, you now get a server-side error surfacing the issue: <img width="1268" height="204" alt="CleanShot 2026-03-20 at 14 58 14@2x" src="https://github.com/user-attachments/assets/aadc1b7a-9495-475f-9741-39979bd27cd7" /> I've tested gpt-5 and gpt-5-mini are still working on the staging preview and verified the models were selected properly in Braintrust logs. Both models are available on my Pro test account, and my Free test account shows the Pro upgrade CTA. Closes AI-446 Closes AI-551 |
||
|
|
a261bafbe2 |
fix(studio): keep editor browser titles in sync after renames (#44154)
## What kind of change does this PR introduce? Bug fix that resolves DEPR-414. ## What is the current behavior? Browser titles in the table/SQL editors can keep showing an old entity name after a rename. ## What is the new behavior? - `EditorBaseLayout` now prefers the live tab label when composing the browser title entity, so existing stale tab metadata no longer wins. - Updating a tab label now also syncs the persisted `metadata.name`, so renamed entities recover cleanly on reload instead of carrying stale names in local storage. - Adds a regression test covering the stale-metadata case in the editor layout. Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
87cd172567 |
fix: keep recent items labels in sync after renames (#44155)
## What kind of change does this PR introduce? Bug fix. ## What is the current behavior? The `Recent items` list shown in the table editor empty-state can keep showing an old label after a table or SQL snippet is renamed. That UI is mounted from: - `/project/[ref]/editor` - `/project/[ref]/editor/new` ## What is the new behavior? - Re-adding an existing recent item now refreshes its label and metadata instead of only bumping the timestamp. - Updating an open tab label now also updates the matching recent item, so rename flows stay aligned with the recent-items list. - The fix is applied in the shared tabs store, so table and SQL editor tab state stay consistent even though the visible `Recent items` UI currently appears in the table editor empty-state. - Adds a small store-level regression test for both cases. | Before | After | | --- | --- | | <img width="1024" height="563" alt="test Table Editor Mallet Toolshed Supabase-DA49998A-FE09-4197-8EE7-5D5366FABDC7" src="https://github.com/user-attachments/assets/d0475437-4486-4581-82f8-a84b97b08250" /> | <img width="1024" height="563" alt="test Table Editor Mallet Toolshed Supabase-8F2B6CC9-0721-4348-A094-EE94D6919B08" src="https://github.com/user-attachments/assets/f055be35-4373-4b1b-a2e1-ffe59f12c177" /> | |
||
|
|
32da7388be |
Add support for cmd z undo in table editor for queue operations (#43957)
## Context Add support for undo-ing an operation via keyboard shortcut in Table Editor for the queue operations feature preview |
||
|
|
e217f747bd |
feat(studio) instrument sentry on table creation flow (#43673)
(working with @charislam @awaseem on this one) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES Per [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md): - ✅ `pnpm --filter studio build` - ✅ `pnpm test:prettier` - ✅ `pnpm format` ## What kind of change does this PR introduce? Instruments `studio` app's table creation flow with Sentry. ## What is the current behavior? The table creation flow isn't instrumented in detail, which means we have less visibility into understanding performance problems or errors within this specific flow. ## What is the new behavior? The table creation flow is instrumented in detail. This instrumentation allows for Sentry dashboards like this one (created based on locally generated Supabase data), to help monitor anything going wrong with this critical flow: <img width="1915" height="1131" alt="image" src="https://github.com/user-attachments/assets/e2c5380e-7b00-41c1-9109-3ee4e47ff63b" /> --------- Co-authored-by: Ali Waseem <waseema393@gmail.com> |
||
|
|
156f904018 |
feat: floating mobile toolbar (#43444)
- move navigation components to `apps/studio/components/layouts/Navigation` - add [FloatingMobileToolbar](https://github.com/supabase/supabase/pull/43444/changes#diff-3dffe47fd51ca851d612d8728e03b2dc344ec213d4f3a46a824d3fa32a7cc851) as quick access to tools such as search, assistant, inline editor, etc - behind feature flag and feature preview (true by default as it's a bit annoying to have to enable it all the time as previews are stored in local-storage) - fix sidebar panels closing on viewport resizing (regression from previous pr) https://github.com/user-attachments/assets/d6881e3b-5128-4306-bb82-3ca39c755dba <img width="986" height="697" alt="Screenshot 2026-03-12 at 12 40 11" src="https://github.com/user-attachments/assets/da8511e2-7d01-4237-b814-596031c747c5" /> |
||
|
|
578a73f966 |
feat(studio): connectSection experiment — replace Getting Started with Connect section (#43629)
## Summary Re-ports PR #43119 against the current `ProjectHome` codebase (the original PR targeted `HomeNew/` which was removed during the `homeNew` graduation in #43437). Also unifies the `connectSheet` and `connectSection` feature flags into a single `connectSection` flag — the `connectSheet` flag is removed entirely, so both the ConnectSheet (header) and ConnectSection (homepage row) are controlled by one experiment. - Adds `connectSection` PostHog experiment flag that controls two things: 1. Swaps the Getting Started section for a Connect section on the project homepage for new projects (< 10 days old) 2. Swaps the legacy Connect dialog for the new ConnectSheet panel in the header - **Control** (`getting-started`): existing Getting Started section + legacy Connect dialog in header - **Treatment** (`connect`): new 4-tile Connect section + ConnectSheet in header - `undefined` (loading): neither section renders, avoiding flash - Tiles filtered by the same `useIsFeatureEnabled` flags as ConnectSheet (`show_app_frameworks`, `show_mobile_frameworks`, `show_orms`) - Connect tile clicks tracked via `home_connect_action_clicked`; section render tracked via `home_connect_section_exposed`; sheet opens tracked via `connect_sheet_opened` with source attribution (`header_button` or `connect_section`) ## Changes - `packages/common/telemetry-constants.ts` — new `home_connect_section_exposed`, `home_connect_action_clicked`, and `connect_sheet_opened` event types - `ConnectSheet/ConnectSheet.tsx` — read `connectTab` query param and sync to active mode on open; `handleModeChange` keeps param in sync on tab switch; fire `connect_sheet_opened` event with source attribution on open - `ConnectButton/ConnectButton.tsx` — set `connectSource=header_button` query param on click - `ProjectHome/ConnectSection.tsx` — new component (4-tile connect card); set `connectSource=connect_section` on tile click - `ProjectHome/Home.tsx` — experiment flag wiring - `LayoutHeader/LayoutHeader.tsx` — read `connectSection` flag instead of `connectSheet` to toggle ConnectSheet vs legacy Connect dialog ## Test plan To test on the Vercel preview, set `connectSection=connect` to 100% in PostHog (or override via cookie `ph_override_connectSection=connect`). No separate `connectSheet` flag is needed — `connectSection` controls both features. - [x] Treatment (`connect` variant) — "Get connected" section renders on new project, Getting Started hidden - [x] Control (`getting-started`) — Getting Started renders, Connect section hidden - [x] Mature project (> 10 days) — neither section regardless of flag - [x] Clicking each tile opens ConnectSheet on the correct tab (Framework / Direct / ORM / MCP) - [x] Switching tabs inside sheet updates `connectTab` URL param - [x] Closing sheet clears `connectTab` param - [x] Direct URL deep-link (`?showConnect=true&connectTab=orm`) opens sheet on correct tab - [x] Dark mode — background gradient renders correctly - [x] Light mode — background switches to light gradient - [x] Responsive layout — 4 cols (xl), 2×2 (md), stacked (mobile) - [x] Telemetry — `home_connect_section_exposed` fires once on load; `home_connect_action_clicked` fires with correct `mode` - [x] Treatment — header Connect button opens ConnectSheet (not legacy Connect dialog) - [x] Control — header Connect button opens legacy Connect dialog (not ConnectSheet) - [x] Telemetry — clicking a ConnectSection tile fires `connect_sheet_opened` with `source: 'connect_section'` - [x] Telemetry — clicking header Connect button fires `connect_sheet_opened` with `source: 'header_button'` --------- Co-authored-by: Ali Waseem <waseema393@gmail.com> |
||
|
|
8732fc3bd9 |
fix: add multi-object download signing for storage (#43576)
Bug fix ## What is the current behavior? Read-only users cannot download files because the download feature requires minting a temporary API key, which is properly blocked for read-only users. ## What is the new behavior? Instead of using temporary API keys, we now create signed URLs for the files to be downloaded. We batch-create signed URLs for an entire folder's worth of files, requiring only a single management API call, then use those signed URLs to download the files. This allows read-only users to download files without needing elevated permissions. ## Additional context Resolves FE-2737 |
||
|
|
9b0dc8d9b9 |
Chore/fix storage explorer when switching buckets (#43541)
## Context Taking a slightly different approach to [this PR](https://github.com/supabase/supabase/pull/43370) Original problem was that if you opened some folders while in a bucket and then switched to a different bucket, the folder UI will persists (folders from Bucket A will render when landing on Bucket B) ## Changes involved - Shift `StorageExplorerStateContextProvider` into `[bucketId].tsx]` instead of `ProjectContext` - The valtio store here only applies for the storage explorer so having it so high in the project's context was unnecessary - This also just implies that the valtio store will automatically reset whenever the bucket changes - Simplify storage explorer valtio store by initializing the store with the bucket - We'll initialize the selected bucket with the store now (Same as previous PR) - Removes unnecessary `setSelectedBucket` method which required a separate `useEffect` in `StorageExplorer.tsx` ## To test - [ ] Verify that the original is resolved - [ ] General smoke test of the storage explorer - i've also re-added the e2e test that Gildas wrote up in his PR |
||
|
|
4a173eea60 |
Revert "fix: storage view is not reset when switching buckets" (#43539)
Reverts supabase/supabase#43370 |
||
|
|
9ce3bdf552 |
fix: storage view is not reset when switching buckets (#43370)
## Problem When navigating between buckets after having selected a folder, the storage view shows the previous folder content. ## Solution Set the selected bucket before navigating to it, preventing a race condition with Valtio updates and the effect that loads the bucket content. ## How to test 1. Create 2 buckets 2. In one of them, create a folder and upload some files 3. Go back to the bucket list 4. Open the other bucket Results: - It should not show the previous bucket content anymore - It should not show an empty 2nd column either --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
ddd94a9c24 |
Joshen/fe 2660 clean up stale feature flags enabled for 2 months part 2 (#43331)
## Context Follow up from https://github.com/supabase/supabase/pull/43329, but mutually exclusive Just cleaning up feature flags that have been toggled on for all users and unchanged for the past 2 months - edgefunctionreport - storagereport - realtimeReport - postgrestreport - authreportv2 - newEdgeFunctionOverviewCharts - apiReportCountries (Already not used) - SentryLogDrain - reportGranularityV2 - storageAnalyticsVector - ShowIndexAdvisorOnTableEditor |
||
|
|
90d3b56db0 |
Joshen/fe 2621 show custom domain on dashboard and connect modal (#43233)
## Context Main fix is to adjust the new home page + connect dialog (and connect sheet) to render the project's custom domain if available <img width="471" height="255" alt="image" src="https://github.com/user-attachments/assets/3a208b2e-bdeb-43f5-a2e7-3495881dbaaa" /> <img width="1065" height="233" alt="image" src="https://github.com/user-attachments/assets/2a7b8f81-8c0b-4803-bf0a-fc16a2f1e0e1" /> ## Changes involved - Created a `useProjectApiUrl` hook that will return the API URL depending if custom domains is available, otherwise default to default project API URL - Refactored all the other places that were manually deriving the project's endpoint - Storage Explorer -> copy URL - Edge Functions - Integrations -> Data API + API Docs - Auth Providers -> Callback URL - Also updated the copy CTA for the addons page - Instead of just "Change xxx", make it a bit more actionable - For add ons with binary states (Custom domains, IPv4) - If not enabled yet, "Enable xxx", otherwise "Toggle xxx" - For PITR - If not enabled yet, "Enable PITR", otherwise "Change recovery duration" - Also added "Edit custom domain" CTA if enabled <img width="1144" height="518" alt="image" src="https://github.com/user-attachments/assets/4f152ea5-0cc7-412c-95e8-ad5bb37c19c3" /> ## To test - [ ] Verify that for a project with custom domain set up, all the affected UI mentioned in the above section look correct |
||
|
|
b8b14f06e0 |
refactor: move storage utils out of valtio + write tests (#43225)
Refactor ## What is the current behavior? Many utility functions are in the Valtio object which is overly large and complex. ## What is the new behavior? Some utility functions are moved out and tested. No behaviour has been changed, they've just been moved with any necessary changes to arguments. |
||
|
|
e8c309c312 |
fix: resolve undefined project ref in TabsStateContextProvider (#43222)
This pull request refactors how the `TabsStateContextProvider` receives
the project reference and updates related imports for consistency and
maintainability. The main change is to pass `projectRef` explicitly as a
prop instead of fetching it internally, which improves context control
and makes the component easier to test and reuse. Additionally, the PR
updates import paths to use absolute aliases and removes an unused
function.
This fixes an issue which you can replicate by:
1. Go to SQL editor
2. Open any snippet
3. Delete the local storage `supabase_studio_tabs_{project ref}`
4. Refresh the page while still the snippet is open
This will make the snippet to enter in a ghost state where the tab name
is not visible but you see the content.
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
|
||
|
|
ff4f58d725 |
chore(studio): Implement auto retry logic for renaming folders in Storage Explorer (#43086)
## Context Renaming folders on the Storage Explorer has a tendency to be flaky as we're using the `POST /objects/move` storage API to move files to the renamed folder which handles one file per request. For a big folder (e.g 100+ files), users will easily hit rate limits and run into 429s with the API, in which the current behaviour just shows toast errors as the error handler, leaving an odd state upon running through every file in the folder where some files are in the old folder, and others in the new one ## Changes involved Main solution is to implement an automatic retry logic for `renameFolder`, but changes involved are: - Remove batching logic for renaming folders (Which fires `n` requests per batch) - The batch logic was negligible anyways since our batch size was only 2 😅 - Instead we now handle moving of files sequentially - If a file runs into an error during the `POST` request, retry the request after `n` seconds - If the error was a 429, retry after 60 seconds, otherwise just 5 seconds - Will attempt the request for a total of 3 times - Toast progress description will also be updated to show the message (timer will also count down to keep the UI interactive and not look stuck) <img width="362" height="98" alt="image" src="https://github.com/user-attachments/assets/52ba685a-2f35-42f1-8fcf-98351184fd56" /> - After the whole process is completed, if any file ran into an error, toast description will add a CTA to retry the rename ## Demo https://github.com/user-attachments/assets/d65b3c22-f9f8-4984-9521-6fc83a69f82e ## To test Have a folder in your project's storage bucket with 100+ files (can stress test with nested folders) - [ ] Verify that you can rename the folder, and the dashboard automatically handles errors |
||
|
|
637b6fb792 |
chore: update react-resizable-panels to v4 to support pixel width (#42990)
This pull request standardizes the usage of props and value types for the `ResizablePanelGroup` and `ResizablePanel` components across multiple files in the codebase. Specifically, it replaces the deprecated `direction` prop with `orientation`, and updates numeric prop values (such as `defaultSize`, `minSize`, and `maxSize`) to be passed as strings. This ensures consistency with the updated component API and improves type safety. **Component API Updates:** * Replaced the `direction` prop with `orientation` for all usages of `ResizablePanelGroup` * Updated all `ResizablePanel` props (`defaultSize`, `minSize`, `maxSize`) to be passed as strings instead of numbers, ensuring compatibility with the latest API requirements. * Removed deprecated or unnecessary props such as `order` from `ResizablePanel` components, and ensured all size-related props are consistently formatted as strings. |
||
|
|
233c2d4a4c |
feat(inline sql editor): snippet management in editor panel (#43011)
- EditorPanel can now load, save, and rename SQL snippets inline - New SaveSnippetDialog component for saving snippets with AI-generated titles - EditorPanel state tracks active snippet ID and pending reset - EditQueryButton opens the inline editor panel instead of navigating to SQL editor page - AIEditor exposes onMount callback for editor instance access - SnippetDropdown label updated to "Create snippet" ## TO TEST ### Normal CRUD - open inline SQL Editor - try creating a new snippet - try editing an existing snippet ### Homepage V2 Report - Try adding a new block → create snippet - create the snippet in inline sql editor - select the snippet in the report block section |
||
|
|
a7e0a428fe |
fix: improve error handling for upload cases in storage explorer (#43054)
This pull request refactors and improves error handling in the
`createStorageExplorerState` function within
`apps/studio/state/storage-explorer.tsx`. The changes make the switch
statement more robust and readable by introducing block scoping for each
case and handling additional error scenarios with more specific
messages.
* Refactored the switch statement to use block scoping (`{}`) for each
case, improving readability and preventing variable leakage between
cases.
* Enhanced the handling of HTTP 400 errors by checking the response body
for specific error messages, and displaying more precise error toasts
for "Invalid key" and "Invalid Compact JWS" cases.
* Added a default case to the switch statement to catch and display any
other error messages not explicitly handled, ensuring users receive
feedback for unexpected errors.
|
||
|
|
20d1ac0f83 |
feat(assistant): send user feedback to Braintrust traces (#43021)
- Expose Braintrust span ID to client via `x-braintrust-span-id` response header, captured in chat transport - On feedback submission, call `logFeedback()` with `scores["User Rating"]` (1/0), `comment`, and on the root span assign `metadata.feedbackCategory` - Silently skipped when tracing is disabled (HIPAA, missing env vars) - Log `requestedModel` in trace metadata so we can see what model the user selected vs what was actually used after throttling Example traces: - [Thumbs up](https://www.braintrust.dev/app/supabase.io/p/Assistant/trace?object_type=project_logs&object_id=5a8d02e5-b3b6-40cc-ba76-ecee286478f4&r=0bb71680-784c-45c1-a234-cba0242562d6&s=0bb71680-784c-45c1-a234-cba0242562d6) - [Thumbs down + negative feedback](https://www.braintrust.dev/app/supabase.io/p/Assistant/trace?object_type=project_logs&object_id=5a8d02e5-b3b6-40cc-ba76-ecee286478f4&r=d5a78084-6c9a-4230-8615-1e864bb9bac7&s=d5a78084-6c9a-4230-8615-1e864bb9bac7) <img width="645" height="173" alt="CleanShot 2026-02-19 at 13 30 25@2x" src="https://github.com/user-attachments/assets/6c463e83-27c6-4afb-a8d0-a329ed61270a" /> Closes AI-442 |