* fix(grid): keep the busy overlay elapsed time across result view switches (issue #12821)
The elapsed pill of the grid busy overlay re-based itself on the mount time
whenever the surface became busy, so switching the result view mid-query
(which unmounts and remounts the grid) restarted the counter at zero.
Read the execution start from the tab when the busy surface is driven by a
query execution, and keep the per-mount baseline for busy surfaces that no
execution drives.
* fix(grid): rebase elapsed timer on a new execution
* test(grid): cover elapsed timer rebasing
---------
Co-authored-by: dev <dev@local>
Co-authored-by: zipg <4047349+zipg@users.noreply.github.com>
* feat(sidebar): support opening all connections in a group (#12814)
* fix(sidebar): export findConnectionNode from connectionStore and call directly (#12814)
When the snippet sync passphrase is saved in the system keychain, the
passphrase field is empty and only shows a '••••••••' placeholder. The
eye toggle was still rendered, so clicking it switched an empty input
to text and the placeholder dots stayed: the button looked broken.
Hide the toggle while the field only holds the saved-passphrase
placeholder and show it again once a new passphrase is typed. This is
the same rule the WebDAV secrets passphrase field already uses
(`!webdavHasSavedSecretsPassphrase || !!webdavSecretsPassphrase`). The
saved passphrase is not read back from the keychain into the UI.
Fixes#12839
* fix(import): keep data sheets selectable when an Excel sheet is empty
* fix(import): scan past the preview window before judging an Excel sheet empty
Anchor the preview window at the first content row instead of stopping at
data_start_row + preview_limit, so a sheet whose only data sits beyond the
preview limit is no longer reported as an empty preview. The grid-size guard
now counts only the anchored window so a far first data row cannot falsely
trip MAX_FAST_PREVIEW_CELLS.
* fix(clippy): drop test-only transfer column name wrapper
resolve_transfer_target_column_names lost its last non-test caller in
7fdf16283, so the lib build fails the CI clippy job with dead_code. Fold
its four test call sites into resolve_transfer_target_column_names_or
with the source names as fallback.
* fix(grid): degrade keyless-table row locator when the engine rejects tableoid
PostgreSQL-compatible engines without system-column support (Hologres'
query translation layer rejects tableoid, #12647) failed every keyless
table open with a db error because the ctid row locator introduced by
0264cfb projects tableoid/ctid/xmin unconditionally for postgres-type
connections. Hologres reports a plain PG-11-style server_version, so the
gate cannot be driven off the version string.
On the first failed keyless-table load, retry once without the locator;
a successful retry remembers the connection so later opens skip the
locator entirely (keyless tables stay read-only there), and a failed
retry restores the flag so the real server error stays visible. Loads
without the locator keep the original execution path.
Pin the emitted statement in the dialect suite and cover the fallback
behavior (retry once, remember per connection, restore on double
failure) with compositional vitest cases.
* test(grid): drop unused QueryResult import to stay under the lint warning budget
Add previous/next statement and statement-start navigation to the SQL editor.
The commands reuse the executable statement ranges behind "execute current
statement" and "select current statement", so navigation boundaries always
match what execution would run.
Defaults: Ctrl+Shift+ArrowUp (previous), Ctrl+Shift+ArrowDown (next),
Alt+Home (statement start). All three are configurable under Settings >
Shortcuts and translated in every shipped locale.
Covered by unit tests for the range math and a mounted QueryEditor integration
test that drives the keybindings.
Refs #12678
Pasting a copied row into a new row coerced every empty field to SQL NULL,
because coerceDataGridCellValue treats an empty input over a NULL cell as
"clear this cell". That rule is right for the editor, but a paste carries
literal text: '' has to stay ''.
- paste paths now pass preserveEmptyString, and the coercion honours it only
for columns the grid classifies as text (resolveDataGridTypeVisualKind ===
"string"). Numeric, boolean, temporal, uuid, JSON, binary, array and
unclassified columns keep their NULL, since none of them has an '' value to
preserve and the save layer would format '' as a literal that the server
rejects or stores as a different value.
- the clipboard parser turns the configured copy/extract "NULL text" back
into NULL, so a NULL cell survives a copy/paste round trip through text
while an empty string stays empty. With the default (empty) NULL text every
empty field stays an empty string.
Co-authored-by: yiqiui <yiqiui@users.noreply.github.com>
* feat(sidebar): support F5 shortcut to refresh sidebar connection and databases (#12246)
* fix(sidebar): declare refreshNode on SidebarTreeRuntimeHost and preserve tooltip text (#12246)
In grouped horizontal layouts, the active tab was only signaled by a
neutral rail segment, which is not enough to spot it among several
colorful groups (issue #12485). Paint a primary-colored top-edge accent
on the active grouped tab — the same vocabulary as the vertical tab's
inset --ring edge — so the chosen tab stays findable at a glance. The
var fallback keeps legacy WebViews painted.
Fixes#12485
Co-authored-by: zipg <4047349+zipg@users.noreply.github.com>
An Oracle TNS connection stores its alias in `database` and the
`jdbc:oracle:thin:@<alias>?TNS_ADMIN=<dir>` string that resolves it in
`connection_string`. `scrubConnectionForPlaintextExport()` blanked
`connection_string` unconditionally, so a plaintext export/import silently
dropped the directory that resolves the alias — the re-imported connection
could not connect and had to be reconfigured from scratch (issue #12672).
The string is now rebuilt from the alias and TNS_ADMIN only, so every other
query parameter is dropped instead of forwarded. Validating the stored string
is not enough: the JDBC layer decodes each parameter name with URLDecoder and
trims it before comparing, so `?%70assword=`, `?+password=` and
`?password%20=` all read as `password` there. Rebuilding makes that
impossible by construction, and every non-TNS connection string (JDBC URLs,
DSNs, service-name strings) is still dropped along with the stored password.
Co-authored-by: dev <dev@local>
* feat(query): show source connection colors in results
* fix(query): omit absent result source connection metadata
* ci: retrigger checks after runner timeout
* fix(ci): increase heap budget for frontend type checking
* fix(ci): retry transient Windows installer bundling failures
* test(query): await lazy component imports before teardown
* test: adapt result color and CI coverage to latest main
Workbench panels used a translucent 1px border on a small radius, which nearly
vanished against the same-coloured shell in dark themes and read as stray pixels
on the anti-aliased arc (most visible on Linux). Introduce .dbx-panel with the
radius one step above rounded-md (so the Corner style setting still applies) and
an opaque border in dark themes, and let the sidebar's inner overflow container
inherit the radius so its header no longer paints over the rounded corner.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
The go-to-column lookup list was built from the database column order, so
after dragging column headers into a custom order the list disagreed with
the grid (and with the column filter panel, which already follows the
local order). Build it from orderedDisplayableColumnIndexes instead; the
item index carried by each entry is still the real column index, so the
jump target is unchanged.
Related #11845