mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
codex/fix-tanstack-e2e
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
de2a7d8d9e |
Add view options to Query (#49447)
Currently Query tabs in explorer do not support view options e.g. table vs chart. This adds display state to query tabs to match the behaviour of Notebooks ## To test - create a query in explorer - Run a query - Set the display options via toolbar <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Query results can now be displayed as either a table or chart. * Chart settings are saved with each query draft and restored when reopened. * Display preferences are maintained independently across query drafts. * Editing a preview query now converts it into a permanent tab. * **Bug Fixes** * Invalid or legacy display settings safely fall back to the table view without removing saved drafts. * Charts and empty states now use the available editor space more effectively. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
bfab3090f5 |
QueryTab: Scope role impersonation to each tab instead of global (#49139)
## Context Previous PR [here](https://github.com/supabase/supabase/pull/49101) introduced role impersonation to the Explorer -> Query Tab, but the setting was global (e.g selected role would be the same despite switching query tabs) Changes here shifts the scope of the role impersonation into the query draft so that the value is tied to each individual query tab instead <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Query drafts now remember selected impersonated roles when switching between drafts or returning later. * Added support for clearing saved impersonated roles. * Impersonation state remains isolated across query tabs. * **Bug Fixes** * Prevented impersonation settings from carrying over between unrelated drafts. * Invalid saved role data is safely ignored during restoration. * Logs drafts no longer persist or update impersonated roles. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
cfde341c31 |
QueryTab: Scope row limit to each tab instead of global (#49138)
## Context Previous PR [here](https://github.com/supabase/supabase/pull/49098) introduced row limits to the Explorer -> Query Tab, but the setting was global (e.g selected row limit value would be the same despite switching query tabs) Changes here shifts the scope of row limit into the query draft so that the value is tied to each individual query tab instead Also added a logic as CodeRabbit suggested [here](https://github.com/supabase/supabase/pull/49138#discussion_r3795525802) - to default invalid row limit values to 100 if the persisted data is mutated incorrectly <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Query tabs now retain row-limit settings independently for each database draft. * Row-limit preferences are restored when reopening Studio, with older drafts defaulting to 100 rows. * **Bug Fixes** * Changing the row limit now persists immediately and no longer affects other query drafts. * Invalid saved row limits are safely normalized to a supported value. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b5bfc70c06 |
fix(studio): correlate a query's SQL brand with the backend it runs against (#49074)
Fourth of the stack; PRs 1–3 (#49069, #49070, #49072) have merged, so this now targets `master` directly. **Rebased onto latest `master`.** See "Conflict resolution" at the bottom for what was reconciled. ## The bug `QueryEditor` took `sql: string`, so a query's dialect brand died at the prop boundary and the component re-branded whatever it was handed based on a separately-passed `source`. Nothing tied the two together, which meant nothing stopped Postgres SQL from reaching the analytics endpoint. Explorer query drafts made it concrete. `explorer-query.ts` branded **every** draft with `untrustedSql` regardless of source: ```ts uncheckedSql: untrustedSql(sql) // even for a logs draft ``` and the editor then re-branded that same text with `untrustedLogSql` at run time for a logs draft — laundering a Postgres-branded value straight through the boundary that `safe-analytics-sql.ts` exists to defend. The brands are deliberately disjoint precisely so this can't happen; passing plain strings around defeated it. ## The fix Both carriers are now tagged by backend, so one `_tag` check narrows the SQL brand and that backend's parameters together. - **`ExplorerQueryDraft`** becomes `DatabaseQueryDraft | LogsQueryDraft`, and `toDraft` is the single place a persisted string re-enters the type system — branded for the backend its binding names. The draft is rebuilt rather than mutated in place, since a backend change changes which brand its SQL carries. - **`QueryEditor`** takes one discriminated `query` prop instead of `sql` + `source` + `rowLimit`. The tag picks both the brander at the editor boundary and the execution endpoint, so the mismatch is no longer expressible. - The two `acceptUntrusted*` promotions stay **inlined** in the run handler rather than factored into a shared helper, so each stays visible next to the user gesture that authorizes it, per the safe-SQL model. - **`rowLimit` moves onto the database member.** Logs execution has no use for it — `applyAutoLimit` is Postgres-specific — so it no longer sits on a shared type where it reads as meaningful for both. ## Local storage Existing query drafts shape-mismatch and fall back to a database binding via the existing `safeParse` guard — harmless, and notebooks are still behind the `explorer` flag so there is no saved server content in play. ## Conflict resolution `master` moved inside every file this PR touches. The type change is applied on top of that work; nothing was reverted. | Preserved from `master` | Where | |---|---| | zod parsing of persisted drafts (`persistedDraftsSchema`, `persistedDraftSchema`) | `explorer-query.ts` | | `MAX_PERSISTED_EXPLORER_QUERY_DRAFTS` cap, retaining most-recently-updated | `explorer-query.ts` | | debounced SQL persistence + `flushPendingPersistence`, immediate write-through for rename/source | `explorer-query.ts` | | `removeDraft` clearing pending timers | `explorer-query.ts` | | `getQuerySourceBinding(cell)` and the four source-change branches, incl. `database_identifier` / `time_range` propagation | `QueryCell/index.tsx` | | `restoredQueryKey` per `ref:id` and the `role="status"` loader | `QueryTab.tsx` | | `applyAutoLimit` relocated to `@/data/sql/utils` | `QueryEditor.tsx` | Two adaptations were needed: - `updateDraft` rebuilds the draft through `toDraft` instead of mutating it in place — required, because the object's shape depends on its tag. The debounced `persist` closure still re-reads `state.drafts[id]` at fire time, so behavior is unchanged. - Master's new test `falls back to the database source when persisted source data is invalid` asserted `draft.source`, which the tagged union replaces. Rewritten to assert the same intent against `_tag`. **Dropped from this PR's original description:** it previously claimed to fix a log cell always running against a synthesized default time range. Master fixed that itself by adopting `getQuerySourceBinding` (from #49072), so the claim no longer applies. ## Verification Typecheck, Prettier, and the lint ratchet clean. 736 tests pass across `state/`, the Explorer surfaces, notebooks, query sources, `data/sql`, and the SQL editor — including master's new `QueryTab.test.tsx`, `ExplorerQuerySourceMenu.test.tsx`, `ExplorerQueryTabCoordinator.test.tsx`, and the five draft-store tests added since this branch was cut. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved Explorer query handling across database and logs backends. - Preserved query text when switching backends while clearing incompatible results. - Retained results when changing parameters within the same backend. - Improved restoration of saved drafts, including fallback handling for legacy or invalid sources. - Added validation before executing edited SQL to help prevent invalid requests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0ed49231b7 |
refactor(studio): unify CellSource and the SQL editor's QuerySource into QuerySourceBinding (#49072)
Third of a stack. **Stacked on #49070** (which is stacked on #49069) — review those first. Base retargets automatically as each merges. Mechanical throughout; no behavior change. ## The problem Three types described where a query runs, and no two agreed: | | shape | |---|---| | `CellSource` (registry) | `{ id, type, parameters: { … } }` — `id` and `type` always held the same literal | | `QuerySource` (SQL editor) | `{ type: 'database' } \| { type: 'logs', dateRange }` | | notebook cells | flat per-backend fields, neither of the above | Anything crossing between them needed a translation that dropped fields on the way — which is how a notebook cell's replica selection had nowhere to go. ## What changed One `QuerySourceBinding`: a backend `_tag` with that backend's parameters spread flat beside it, borrowed from the wire schema (#49069) so the binding and the persisted cell agree by construction. - **`QuerySource` is deleted.** `useRunSource` returns the shared binding, so `runSource.type`/`dateRange` become `_tag`/`time_range` across the SQL editor — that is most of the file count here. - **`getQuerySourceBinding`** projects a notebook cell onto a binding; **`toQuerySourceBinding`** does the same for any backend-tagged carrier. Both overloaded so an already-narrowed caller gets the matching binding back rather than the union, which keeps the result spreadable without re-narrowing. - **`ExplorerQuerySourceMenu`** drops its inline copy of the custom-range and upgrade-prompt logic in favor of `useLogsCustomRange`, which the SQL editor menu already used. The registry keeps only what is genuinely runtime: endpoints, labels, icons, availability, defaults. What a query *is* stays in the wire schema. ## Verification Typecheck, Prettier, and the lint ratchet clean. 405 tests pass across the notebook schema, query sources, the logs components, the SQL editor, and the Explorer surfaces. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Updated query source handling across Explorer and SQL Editor for a more consistent selection experience. * Database and log sources now preserve identifiers and time ranges more reliably when switching or editing queries. * Source menus, labels, icons, validation, and query execution now reflect the selected source more accurately. * **Bug Fixes** * Invalid or outdated saved source settings now safely fall back to a database source. * Improved log-source detection and time-range handling throughout query editing and execution. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
c0e109f662 |
refactor(studio): borrow the wire schema's time range in the query-source registry (#49070)
Second of a stack. **Stacked on #49069** — review that one first; this PR's diff only makes sense on top of it. Base will retarget to `master` automatically when #49069 merges. Net `-72` lines. No behavior change beyond the one noted at the bottom. ## The problem The query-source registry carried its own `LogTimeRange` type and `logTimeRangeSchema`, which had drifted from the notebook wire schema's copy in four ways: | | wire schema | registry | |---|---|---| | discriminant | `_tag: 'relative_time_range'` | `type: 'relative'` | | absolute bounds | `start` / `end` | `from` / `to` | | relative units | minute…year | minute, hour, day | | validation | none | positive int, end-after-start | Two definitions of one concept, neither convertible to the other without a lossy mapping — and the notebook query cell was papering over it by discarding a log cell's persisted range and substituting a default. ## What changed #49069 moved the validations onto the wire schema's `timeRangeSchema` and exported it. This PR deletes the registry's copy and points every consumer at `TimeRange`. The registry keeps what is genuinely runtime: endpoints, labels, availability, defaults. The field renames ripple mechanically through the logs date-picker helpers, the time-range submenu, `useLogsCustomRange`, the SQL editor's session state, and their tests. Coverage for the absolute-range and unit rules moved to `notebook-schema.test.ts` in #49069, alongside the schema that now owns them. `ExplorerQuerySourceMenu` also drops its hand-rolled custom-range construction in favor of `customDateRangeToLogTimeRange`, which already existed and does the same clamping. ## One behavior change `logTimeRangeToDatePickerValue` now renders a range whose unit has no picker preset (week, month, year — allowed by the wire schema, not offered in the UI) as a resolved absolute range, instead of trying and failing to build a helper for it. Previously unreachable, since the registry's narrower unit set made those ranges unrepresentable. ## Verification Typecheck, Prettier, and the lint ratchet clean. 401 tests pass across the notebook schema, query sources, the logs source components, the SQL editor, and the Explorer surfaces. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved log time-range handling across Explorer and SQL Editor. * Custom date ranges now display and resolve correctly, including clamping invalid ranges. * Unsupported relative time units are converted to compatible absolute date-picker values. * **Refactor** * Standardized log queries on a shared time-range format for more consistent validation and behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
39c3960215 |
fix(studio): harden Explorer query persistence (#49039)
<img width="1690" height="1034" alt="image" src="https://github.com/user-attachments/assets/2dc5b10b-8e64-413b-861e-8b0b62e2d880" /> ## Summary - debounce draft persistence and flush pending edits when the page exits - validate untrusted local storage with Zod, recover from malformed entries, and retain the 50 most recently updated drafts - harden route restoration, recent-item routing, close confirmation, and local cleanup - disable execution while project or replica data is resolving and fail closed for missing replicas - use an HTTP-safe UUID generator for self-hosted Studio - adopt the upstream Explorer toolbar title API - expand component and state coverage for persistence and execution behavior ## To test 1. Open Explorer, select **Run SQL**, then enter SQL and rename the query. 2. Reload the page and confirm the draft is restored; close its tab and confirm it is discarded after the prompt. ## Why This layer makes local-only Explorer drafts resilient to rapid edits, reloads, stale browser data, and tab lifecycle edge cases. ## Impact Queries remain local-only, and closing their tabs discards them after confirmation. Save-as-notebook functionality remains intentionally out of scope. ## Validation - fresh non-incremental Studio TypeScript check - 68 Vitest tests pass across Explorer, query sources, tabs layout, and query/tab state - Studio ESLint ratchet and Prettier check both clean <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Explorer query drafts now save automatically and restore reliably across navigation, tab closures, page exits, and visibility changes. - Recent query items now open directly to their associated Explorer query. - Logs time-range selections are handled consistently, including custom ranges and preset matching. - **Bug Fixes** - Prevented stale query loading states when switching between queries. - Improved handling of invalid or outdated saved drafts. - Limited saved drafts to the 50 most recently updated queries. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fc3f6aaea8 |
Add source selector for explorer query tab (#49063)
## Context This is just pulling out the relevant changes from https://github.com/supabase/supabase/pull/49028 as I might have messed up the stack while making changes down the PRs 🙏 Builds on the Query Tab in the Explorer UI, adds the source selector component to run either a database query or a logs query - will subsequently be looking into have the source selector component in the QueryCell as well (within notebooks) <img width="1095" height="594" alt="image" src="https://github.com/user-attachments/assets/ab6e8d91-aed3-4845-9777-acbd7a3a7cb1" /> <img width="1086" height="667" alt="image" src="https://github.com/user-attachments/assets/75d99063-755d-4ba6-a128-7ddcbbc9f161" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added query-source selection for Explorer and notebook queries. - Supports log queries, database selection, and read-replica connections. - Added validation for custom log time ranges and retention limits, with upgrade guidance when applicable. - Query source choices are saved and restored across sessions. - Changing sources clears previous results to prevent stale data. - **Bug Fixes** - Improved handling of unavailable log querying and missing database connections. - Legacy saved queries now fall back safely to the default database source. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
75d16f360f |
feat(studio): add Explorer query tabs (#49038)
<img width="1693" height="1037" alt="image" src="https://github.com/user-attachments/assets/51fdf618-f06e-45ca-bf30-e1307dfbb372" /> ## Stack Depends on #49041. Followed by #49028. ## Summary - add a dedicated ad-hoc query tab type and route under Explorer - connect query tabs to the shared `QueryEditor` through a `QueryTab` lifecycle adapter - add local query draft/result state and restore query tabs from their routes - confirm before closing populated local-only drafts and clean up their state on close ## To test 1. Open Explorer, select **Run SQL**, enter `select 1`, and run the query. 2. Rename the query, reload the page, then close the tab and confirm the discard prompt appears. ## Why Explorer needs a lightweight place to run SQL without creating a snippet. This layer adds the query-tab lifecycle on top of the shared editor foundation. ## Impact Queries in this layer run against the selected project's primary database. Drafts are local to the browser and are discarded when their tabs are closed. ## Validation - fresh non-incremental Studio TypeScript check - 22 focused tests across query draft state, tab state, and notebook tab registration <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for creating, opening, editing, and running SQL queries in Explorer. * Added project-scoped persistence for query drafts and results. * Added dedicated query routes, query icons, and query tabs. * Added unsaved-changes warnings when closing query tabs. * Added a pinned Explorer Home tab and “New query” option. * Improved notebook tab registration and editor tab organization. * **Bug Fixes** * Improved tab navigation, closing behavior, and layout. * **Tests** * Added coverage for query persistence, cleanup, restoration, and tab navigation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |