feat(combos): add select all / unselect all in Browse Catalog (#8526)

* feat(combos): add select all / unselect all in Browse Catalog

* fix(dashboard): guard combo Select all + test the real batch handlers (#8526)

Select all had no cap — with "Show configured only" off, or a large
provider catalog, one click could add hundreds of models to a combo.
ModelSelectModal now confirms above SELECT_ALL_CONFIRM_THRESHOLD (20)
before batch-adding, matching the native confirm() pattern already
used for bulk/destructive actions elsewhere in the dashboard.

Also extracts ComboFormModal's handleAddModels/handleDeselectModels
batching logic into computeBatchAddModelSteps/computeBatchDeselectModelSteps
(src/lib/combos/builderDraft.ts) so unit tests exercise the real
implementation instead of a hand-maintained mirror that could drift
from the component and stay green while production code broke.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
This commit is contained in:
Joshim Uddin
2026-07-26 21:10:44 +06:00
committed by GitHub
parent 5552650a4f
commit 63341f2aed
9 changed files with 717 additions and 15 deletions

View File

@@ -73,3 +73,23 @@ export function buildNodeAliasModels(
source: "alias" as const,
}));
}
/**
* "Select all" adds every currently-visible model to the combo in one click,
* with no cap — turning off "Show configured only" (or just having a large
* provider catalog) can put hundreds of candidates behind a single click.
* Above this threshold the caller must confirm before batch-adding (#8526).
*
* A native `confirm()` — not a bespoke modal — matches the existing bulk /
* destructive-action pattern already used in this codebase (e.g.
* `ReasoningRoutingRules.tsx::deleteConfirm`, `combos/page.tsx::deleteConfirm`),
* so no new UI primitive is needed for this one interaction.
*/
export const SELECT_ALL_CONFIRM_THRESHOLD = 20;
export function shouldConfirmSelectAll(
candidateCount: number,
threshold: number = SELECT_ALL_CONFIRM_THRESHOLD
): boolean {
return Number.isFinite(candidateCount) && candidateCount > threshold;
}