Skip to content

refactor: clean up results panel toolbar layout#70

Merged
NicolaasGrobler merged 4 commits into
mainfrom
refactor_data_table_layout
May 17, 2026
Merged

refactor: clean up results panel toolbar layout#70
NicolaasGrobler merged 4 commits into
mainfrom
refactor_data_table_layout

Conversation

@kix007

@kix007 kix007 commented May 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Consolidates "Jump to column" (text input + dropdown) into a single searchable dropdown with keyboard nav and Esc-to-close
  • Groups export formats behind a single Download dropdown instead of 5 separate icon buttons
  • Row action buttons (Add, Duplicate, Remove, Save, Discard) are now icon-only — much more compact
  • Discard now shows a confirmation dialog before wiping local changes, and filters _isNew rows client-side instead of re-running the last SELECT query
  • Version bumped to 1.0.15 with changelog entry

Changed files

  • src/components/results/ResultsPanel.tsx
  • src/components/layout/MainContent.tsx
  • CHANGELOG.md

Summary by CodeRabbit

v1.0.15 Release Notes

  • New Features

    • Searchable "Jump to Column" dropdown with keyboard navigation and Esc-to-close functionality
    • Export actions consolidated into a single Download dropdown menu
  • Improvements

    • Toolbar redesigned with icon-only row action buttons
    • Discard changes action now includes confirmation dialog
    • Visual separators added between toolbar action groups

Review Change Stack

@vercel

vercel Bot commented May 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
queryden Ready Ready Preview, Comment May 17, 2026 2:59pm

@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@NicolaasGrobler has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 31 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f6bb4533-a603-4663-b3ef-55e8680e80ec

📥 Commits

Reviewing files that changed from the base of the PR and between 1d8f724 and 3d5c648.

📒 Files selected for processing (2)
  • src/components/layout/MainContent.tsx
  • src/components/results/ResultsPanel.tsx
📝 Walkthrough

Walkthrough

This PR releases v1.0.15, primarily refactoring the results panel toolbar with a unified jump-to-column searchable dropdown, grouped export dropdown, icon-only row action buttons, discard confirmation dialog, and updated discard behavior to filter local state instead of re-executing queries.

Changes

Version Release v1.0.15

Layer / File(s) Summary
Version bump and changelog entry
CHANGELOG.md, package.json, src-tauri/Cargo.toml, src-tauri/tauri.conf.json
Version incremented from 1.0.14 to 1.0.15 across all manifests; changelog entry added describing the results panel toolbar refactor.

Results Panel Toolbar Refactor

Layer / File(s) Summary
Dropdown state and outside-click handler
src/components/results/ResultsPanel.tsx
Added state for column and export dropdown visibility; introduced refs and useEffect for outside-click behavior to close dropdowns and clear search.
Jump-to-column searchable dropdown
src/components/results/ResultsPanel.tsx
Replaced old jump-to-column input and list with a single filterable dropdown that filters columns by name and scrolls/focuses the grid on selection.
Action buttons, export dropdown, and discard confirmation
src/components/results/ResultsPanel.tsx, src/components/layout/MainContent.tsx
Converted duplicate and remove row buttons to icon-only; added conditional Discard Changes button with confirmation dialog; replaced static export buttons with dropdown menu; updated discard handler to filter local state (_isNew rows, _isModified flags) instead of re-executing queries.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Dropdown as Jump Dropdown
  participant Grid as DataGrid
  User->>Dropdown: Click or type to search
  Dropdown->>Dropdown: Filter columns by search
  User->>Dropdown: Select column
  Dropdown->>Grid: Update gridSelection
  Grid->>Grid: Scroll and focus column
Loading
sequenceDiagram
  participant User
  participant DiscardBtn as Discard Button
  participant ConfirmDialog
  participant MainContent
  participant Grid as Grid State
  User->>DiscardBtn: Click Discard
  DiscardBtn->>ConfirmDialog: Show confirmation
  User->>ConfirmDialog: Confirm
  ConfirmDialog->>MainContent: onDiscard()
  MainContent->>Grid: Filter _isNew rows<br/>Clear _isNew/_isModified flags
  Grid->>Grid: Update local state
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A toolbar blooms with cleaner design,
Dropdowns dance in single-line,
Exports grouped, buttons sleek and trim,
Discard with care, no more to whim!
v1.0.15 shines so bright!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor: clean up results panel toolbar layout' directly and clearly describes the main change in the PR: a refactor of the results panel toolbar with consolidation of controls and layout improvements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor_data_table_layout

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/components/results/ResultsPanel.tsx (1)

467-545: ⚡ Quick win

Add explicit accessible names to icon-only action buttons.

Buttons at Line 467+ are icon-only and currently depend on title. Please add aria-label so screen readers reliably announce actions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/results/ResultsPanel.tsx` around lines 467 - 545, Several
action buttons are icon-only and rely on title text, making them inaccessible to
some screen readers; add explicit aria-label attributes to each icon-only button
(the Add/Duplicate/Delete/Save/Discard/Export buttons that render Plus, Copy,
Trash2, CheckCircle, XCircle, and Download) so they announce their purpose
reliably (e.g., aria-label="Add new row", "Duplicate row", "Delete row", "Save
changes", "Discard changes", "Export data"), keeping the existing title props
and ensuring the conditional Discard button still receives the aria-label when
rendered; update the JSX for the buttons inside ResultsPanel (the handlers
onAddRow, onDeleteRow, onSave/onRefresh, onDiscard and the export toggle) to
include these aria-labels.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Around line 7-11: Add a footer reference link for the new [1.0.15] release and
update the existing [Unreleased] compare base so the compare link is not
pointing at v1.0.11; specifically, in CHANGELOG.md add a matching `[1.0.15]:
<repo_url>/releases/tag/v1.0.15` reference (or the repo-relative compare URL
format your project uses) and change the `[Unreleased]:
.../compare/v1.0.11...HEAD` entry to compare from v1.0.15 (e.g.
`.../compare/v1.0.15...HEAD`) so both the [1.0.15] and [Unreleased] headings
have correct footer links.

In `@src/components/layout/MainContent.tsx`:
- Line 2481: The current setResults call only strips _isModified flags but
leaves edited values intact; update the discard logic in the setResults handler
so that for each row marked _isModified you restore the original values (e.g.,
use a stored snapshot field like _original or look up the row in the unmodified
baseline) and then remove the metadata flags. Specifically, change the mapping
inside setResults(prev => ...) to: if r._isNew drop it, if r._isModified replace
the row with r._original (or the matching baseline row) and remove
_isModified/_isNew/_original fields, otherwise keep the row as-is; reference the
setResults call and the row properties _isNew, _isModified and _original when
implementing this.

In `@src/components/results/ResultsPanel.tsx`:
- Line 528: The confirmation dialog text is inaccurate: update the
confirmDialog.confirm call in ResultsPanel (the invocation where const confirmed
= await confirmDialog.confirm(...)) so the message reflects client-side-only
discard behavior (e.g., "Discard all local changes? This will not affect server
data.") and keep title "Discard Changes" and type "warning"; ensure the new copy
is concise and unambiguous about no server/database reload occurring.
- Around line 437-459: The column jump uses the full columns array but the
rendered grid may use displayColumns, causing wrong targets; change the click
handler to compute and use the active column list (e.g., const activeCols =
displayColumns || columns), filter/search against activeCols with
columnDropdownSearch, derive the column index with activeCols.indexOf(c), and
use that index when building setGridSelection's current.cell/current.range and
when calling gridRef.current?.scrollToColumn(idx); also use activeCols for the
"no matching columns" check so behavior matches the displayed grid.

---

Nitpick comments:
In `@src/components/results/ResultsPanel.tsx`:
- Around line 467-545: Several action buttons are icon-only and rely on title
text, making them inaccessible to some screen readers; add explicit aria-label
attributes to each icon-only button (the
Add/Duplicate/Delete/Save/Discard/Export buttons that render Plus, Copy, Trash2,
CheckCircle, XCircle, and Download) so they announce their purpose reliably
(e.g., aria-label="Add new row", "Duplicate row", "Delete row", "Save changes",
"Discard changes", "Export data"), keeping the existing title props and ensuring
the conditional Discard button still receives the aria-label when rendered;
update the JSX for the buttons inside ResultsPanel (the handlers onAddRow,
onDeleteRow, onSave/onRefresh, onDiscard and the export toggle) to include these
aria-labels.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b9e6ba3-6f68-4368-b17c-82f0013ea16e

📥 Commits

Reviewing files that changed from the base of the PR and between 32f8714 and 1d8f724.

⛔ Files ignored due to path filters (1)
  • src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • CHANGELOG.md
  • package.json
  • src-tauri/Cargo.toml
  • src-tauri/tauri.conf.json
  • src/components/layout/MainContent.tsx
  • src/components/results/ResultsPanel.tsx

Comment thread CHANGELOG.md Outdated
Comment thread src/components/layout/MainContent.tsx Outdated
Comment thread src/components/results/ResultsPanel.tsx Outdated
Comment thread src/components/results/ResultsPanel.tsx Outdated
@NicolaasGrobler

Copy link
Copy Markdown
Collaborator

Reviewed end-to-end. The UI refactor is solid — the searchable Jump-to-column dropdown, the Export-as menu, the icon-only toolbar, and the Discard confirmation are all real improvements. Bundling the fixes I'm pushing in a moment so v1.0.16 can go out tonight.

🔴 Blocker — Discard does not actually discard modifications

src/components/layout/MainContent.tsx:2478

onDiscard={() => {
  setResults(prev => prev.filter(r => !r._isNew).map(({ _isNew, _isModified, ...rest }) => rest));
}}

This filters out unsaved new rows ✅, but for modified existing rows it only strips the _isNew/_isModified flags — it doesn't revert the edited cell values. The original executeQuery(lastSelectQueryRef.current) re-fetched the row from the server, which is the only way to recover the pre-edit value because nothing in the codebase preserves originals (cell edit at ResultsPanel.tsx:243-247 just overwrites with _isModified: true — no _original field).

Net effect on the modified-row case: edited value stays in the UI, the row is no longer flagged dirty, Save becomes a no-op (MainContent.tsx:1636 filters on _isModified). Phantom-modified state until the user manually refreshes. Bug, not perf optimization.

Fix I'll push — hybrid: re-run the SELECT only if there are modifications; otherwise filter client-side (preserves your perf win for the new-rows-only case, which is the most common):

onDiscard={() => {
  const hasModifications = results.some(r => r._isModified && !r._isNew);
  if (hasModifications && lastSelectQueryRef.current) {
    executeQuery(lastSelectQueryRef.current);
  } else {
    setResults(prev => prev.filter(r => !r._isNew).map(({ _isNew, _isModified, ...rest }) => rest));
  }
}}

🟡 SAVE button lost the dirty-count badge

ResultsPanel.tsx:520-522 (before):

<span className="text-[8px] font-bold">
  SAVE{results.filter(r => r._isNew || r._isModified).length > 0 ? ` (${results.filter(r => r._isNew || r._isModified).length})` : ""}
</span>

The (3) count was the only at-a-glance signal of how many rows are pending. Going icon-only without preserving the count is a UX regression for the editing workflow. Pushing a small numeric badge in the top-right of the Save button so the count survives.

🟡 Keyboard navigation regression in Jump-to-column

The old <select> had browser-default keyboard nav (Arrow up/down to navigate, Enter to select). The new dropdown only handles Escape — the filtered list is mouse-only. For a "Jump to column" feature this matters, especially on wide tables. Adding Arrow up/down + Enter handling (~15 lines, plus an aria-selected highlight).

🟡 Escape doesn't close the Export dropdown

Inconsistent with the Column dropdown which does. One-line fix; adding to the mousedown outside-click handler.

🔵 Stale version bump

PR bumps 1.0.14 → 1.0.15, but main already shipped v1.0.15 (PR #74). Retargeting to 1.0.16 and folding your CHANGELOG entry into the v1.0.16 section alongside the v1.0.16 splash + connection-spinner work (#75, #76, #77).

✅ What's good (no changes from me)

  • Outside-click handler uses mousedown and ref-based containment — proper React pattern.
  • autoFocus on the search input + Escape handling is correct.
  • Click-outside doesn't fight the toggle button (toggle is inside the ref, so contains() short-circuits).
  • Discard confirmation prevents accidental data loss.
  • Export-as menu groups things sensibly with a section header.
  • The whole thing reads cleanly — easy to follow.

Pushing the fixes in a moment. Thanks for the work, @kix007!

keens007 and others added 2 commits May 17, 2026 22:45
Four review findings on @kix007's refactor (#70):

1. **Discard now actually discards modifications.** The original `onDiscard` replaced `executeQuery(lastSelectQueryRef.current)` with a client-side filter that stripped `_isNew`/`_isModified` flags from existing rows but did NOT revert the actual edited cell values. Nothing in the codebase preserves originals — cell-edit at ResultsPanel.tsx:243-247 just overwrites with `_isModified: true` — so the only way to revert a modification is a server re-fetch. Hybrid handler: re-runs SELECT when there are real modifications, falls back to the cheap client-side filter when only new (client-only) rows need to be dropped. Preserves the perf win for the common case (user added rows, changed their mind) without leaving a phantom-modified state for the edit case.

2. **Save button regains a dirty-row count.** Going icon-only dropped the "SAVE (3)" inline count, which was the only at-a-glance signal of how many rows are pending. Restored as a small emerald badge in the top-right of the Save button. Caps at "99+". Tooltip also reports the live count.

3. **Keyboard navigation in Jump-to-column.** The replaced `<select>` had browser-default keyboard nav; the new dropdown only handled Escape. Added Arrow up/down to move through the filtered list, Enter to jump, with the active item highlighted via `--color-accent`/15 and `scrollIntoView({ block: "nearest" })` to keep it in view. Mouse hover sets the highlight too, so keyboard and mouse cursors stay in sync.

4. **Escape now closes the Export dropdown.** Was inconsistent with the Column dropdown (only that one handled Escape). Added a document-level keydown listener gated on `showExportDropdown` so the dropdown closes on Esc regardless of where focus is.

Note: the stale `1.0.15` release commit from the original branch was dropped during rebase onto main (which already shipped v1.0.15); the CHANGELOG entry will be folded into v1.0.16 at release time.
@NicolaasGrobler

Copy link
Copy Markdown
Collaborator

Pushed fixes in 2fb3c17. The branch is also rebased onto current main (your refactor commit f68b726 cherry-picked clean; dropped the stale chore: release v1.0.15 since main already shipped that).

What changed vs your original:

# Issue Fix
1 Discard didn't actually revert modified rows Hybrid handler — re-runs SELECT when there are real modifications, falls back to the cheap client-side filter when only new rows need to be dropped
2 SAVE button lost the dirty-count Restored as a small emerald badge in the top-right corner (caps at "99+", tooltip also shows live count)
3 Jump-to-column lost keyboard nav from the old <select> Added ArrowUp/ArrowDown to move, Enter to jump, scrollIntoView to keep active item in view, mouse hover syncs the highlight
4 Escape didn't close the Export dropdown Added a document-level Escape listener gated on showExportDropdown

Force-push notice: I had to rewrite history (rebase onto main + drop the release commit + add the fix commit). If you had local commits on this branch, run git fetch && git reset --hard origin/refactor_data_table_layout to sync.

CHANGELOG entry will move to v1.0.16 at release time. Ready to merge from my side — letting Nicolaas drive the merge & release timing.

Two CodeRabbit findings I missed in the first pass:

1. **Jump-to-column was indexing into the wrong array.** The grid renders with `displayColumns || columns` (line 876), but the dropdown was filtering and indexing against `columns` alone. In multi-result mode those diverge, so clicking a column name jumped to the wrong cell. Now consistently uses `activeColumns = displayColumns || columns` for the list, the filter, the no-matches check, and the index passed to `setGridSelection` + `scrollToColumn`.

2. **Discard confirmation message lied.** The dialog said "reload from database" but the hybrid handler only reloads when there are real modifications; for new-rows-only it's a client-side filter. Changed to "Discard all unsaved local changes? This cannot be undone." — accurate for both code paths.
@NicolaasGrobler NicolaasGrobler merged commit de47554 into main May 17, 2026
10 checks passed
@NicolaasGrobler NicolaasGrobler deleted the refactor_data_table_layout branch May 17, 2026 15:01
@NicolaasGrobler NicolaasGrobler mentioned this pull request May 17, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants