Repository navigation
feat(results): bulk delete selected rows, and bump to 0.4.1 - #7
Merged
Merged
Conversation
Deleting was one row at a time: the trash button, a confirmation, repeat.
Cleaning up a few hundred DocuSign statuses or ApexLogs meant a few
hundred round trips through that dialog.
Selection. A checkbox column appears whenever the rows are deletable —
same rule as the trash button: the result's org is the active one and
it has a FROM-object. Shift-click ticks a range in displayed order, the
header box selects every row or clears them. The selection lives on the
tab, keyed by record Id like pendingEdits, so sorting can't shift it
onto other rows and switching tabs doesn't drop it. A re-run or an org
switch clears it: a selection is the input to a delete, and it should
only ever hold rows picked from what's on screen.
Deleting. "Delete N" in the toolbar, or Delete / Backspace anywhere in
the grid except while a cell editor has focus, opens the confirmation —
now one dialog for a single row and for a selection. Up to five records,
and every Tooling API result (there is no Tooling Bulk API), go one
`sf data delete record` call at a time with progress and a Stop button.
Anything bigger runs as a single Bulk API 2.0 job via
`sf data delete bulk`: a couple of seconds per record doesn't scale, a
Bulk job's fixed overhead (create, upload, 5s status polls) does. A Bulk
job has no Stop — once uploaded it runs in the org whether or not sf is
still waiting on it.
Outcomes. Deleted rows leave the grid by Id rather than by row index —
a Bulk job finishes long after positions were captured — so the store's
deleteTabRecord(rowIdx) becomes removeTabRecords(ids), dropping staged
edits and selection ticks along with the rows. Failures stay selected
and the dialog lists each with its error; its button retries just
those. ENTITY_IS_DELETED counts as deleted: the record is already in the
Recycle Bin, which is what was asked for. If a Bulk job fails as a whole
(an object the Bulk API won't take, a missing permission) the dialog
offers "Delete one at a time" instead. If sf can't say which rows went —
the 10-minute wait ran out, or an older CLI without per-record results —
nothing is removed and the dialog says to re-run the query.
CLI bridge. Bulk DML runs to completion and then sets exit code 1 when
any row failed, so its envelope is `{ "status": 1, "result": {...} }`
with no error name. run_sf_json flattened that into a bare "(no message)"
error, losing the per-row outcomes. run_sf_json_partial_ok keeps the
result of a command that completed; one that threw is still an error,
and every existing caller keeps the strict behavior. The upload CSV uses
the platform line ending, because sf declares CRLF to the Bulk API on
Windows and LF elsewhere.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bulk delete
Deleting was one row at a time: trash button, confirm, repeat. Clearing out a few hundred DocuSign statuses or ApexLogs meant a few hundred trips through that dialog.
Selecting. A checkbox column appears whenever the rows are deletable — the same rule as the trash button (the result's org is the active one, and it has a FROM-object). Shift-click ticks a range in displayed order, so it follows the current sort. The header box selects every row or clears them. The toolbar shows N selected · Delete N · Clear, and Delete / Backspace in the grid does the same, except while a cell editor has focus.
The selection lives on the tab, keyed by record Id like
pendingEdits, so sorting can't shift it onto other rows and switching tabs doesn't drop it. A re-run or an org switch clears it.Deleting. Single rows and selections now share one confirmation dialog. The path depends on size:
sf data delete recordper recordsf data delete bulkTooling results always go per record because there's no Tooling Bulk API. The threshold is
PER_RECORD_DELETE_MAXinResultsGrid.tsx: a couple of seconds per record stops scaling quickly, while a Bulk job's fixed overhead (create, upload, 5s status polls) doesn't grow with the count.After a delete:
deleteTabRecord(rowIdx)becomesremoveTabRecords(ids), which also drops those rows' staged edits and selection ticks.ENTITY_IS_DELETEDcounts as deleted, since the record is already in the Recycle Bin.CLI bridge
Bulk DML runs to completion and then sets exit code 1 if any row failed, so its envelope is
{ "status": 1, "result": {…} }with no errorname.run_sf_jsonflattened that into a bare "(no message)" error and lost the per-row outcomes.run_sf_json_partial_okkeeps the result of a command that completed. A command that threw is still an error, and every existing caller keeps the strict behavior. The envelope check moved into a pureunwrap_envelopeso both modes are unit-tested.The upload CSV uses the platform's line ending. sf declares CRLF to the Bulk API on Windows and LF elsewhere, and a mismatch leaves a stray
\ron every id.0.4.1
This release also ships the light-mode context-menu hover fix from #6. The installed 0.4.0 predates it, which is why hovered menu items still render near-black under near-black text there.
Verification
tsc,cargo fmt --check,cargo clippy -D warnings, andcargo test(41 pass) are green. New tests cover the envelope handling in both modes, the upload CSV, and parsing Bulk results: per-record outcomes, a job still running, and output that isn't recognized.🤖 Generated with Claude Code