mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 18:15:23 +00:00
fix(ui): improve bulk actions UX in provider editor
- move BulkActionBar above account list (was at bottom) - only show bar when selections exist (cleaner default) - add selection checkbox to each AccountItem - highlight selected accounts with ring + background
This commit is contained in:
1 parent
eb053425c0
commit
6021c10ddc
2 files changed
+34
-13
No files matched your search
@@ -27,6 +27,7 @@ import {
|
|||||||
AlertCircle,
|
AlertCircle,
|
||||||
AlertTriangle,
|
AlertTriangle,
|
||||||
FolderCode,
|
FolderCode,
|
||||||
|
Check,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
cn,
|
cn,
|
||||||
@@ -97,6 +98,9 @@ export function AccountItem({
|
|||||||
isPausingAccount,
|
isPausingAccount,
|
||||||
privacyMode,
|
privacyMode,
|
||||||
showQuota,
|
showQuota,
|
||||||
|
selectable,
|
||||||
|
selected,
|
||||||
|
onSelectChange,
|
||||||
}: AccountItemProps) {
|
}: AccountItemProps) {
|
||||||
// Fetch runtime stats to get actual lastUsedAt (more accurate than file state)
|
// Fetch runtime stats to get actual lastUsedAt (more accurate than file state)
|
||||||
const { data: stats } = useCliproxyStats(showQuota);
|
const { data: stats } = useCliproxyStats(showQuota);
|
||||||
@@ -124,11 +128,28 @@ export function AccountItem({
|
|||||||
className={cn(
|
className={cn(
|
||||||
'flex flex-col gap-2 p-3 rounded-lg border transition-colors',
|
'flex flex-col gap-2 p-3 rounded-lg border transition-colors',
|
||||||
account.isDefault ? 'border-primary/30 bg-primary/5' : 'border-border hover:bg-muted/30',
|
account.isDefault ? 'border-primary/30 bg-primary/5' : 'border-border hover:bg-muted/30',
|
||||||
account.paused && 'opacity-75'
|
account.paused && 'opacity-75',
|
||||||
|
selected && 'ring-2 ring-primary/50 bg-primary/5'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
|
{/* Selection checkbox for bulk actions */}
|
||||||
|
{selectable && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => onSelectChange?.(!selected)}
|
||||||
|
className={cn(
|
||||||
|
'flex items-center justify-center w-5 h-5 rounded border-2 transition-colors shrink-0',
|
||||||
|
selected
|
||||||
|
? 'bg-primary border-primary text-primary-foreground'
|
||||||
|
: 'border-muted-foreground/30 hover:border-primary/50'
|
||||||
|
)}
|
||||||
|
aria-label={selected ? 'Deselect account' : 'Select account'}
|
||||||
|
>
|
||||||
|
{selected && <Check className="w-3 h-3" />}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
{/* Pause/Resume toggle button - visible left of avatar */}
|
{/* Pause/Resume toggle button - visible left of avatar */}
|
||||||
{onPauseToggle && (
|
{onPauseToggle && (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
|
|||||||
@@ -153,6 +153,18 @@ export function AccountsSection({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Bulk Action Bar - shows when accounts selected (positioned at TOP for visibility) */}
|
||||||
|
{isSelectable && selectedCount > 0 && (
|
||||||
|
<BulkActionBar
|
||||||
|
selectedCount={selectedCount}
|
||||||
|
onPauseSelected={handleBulkPause}
|
||||||
|
onResumeSelected={handleBulkResume}
|
||||||
|
onClearSelection={deselectAll}
|
||||||
|
isPausing={!!isBulkPausing}
|
||||||
|
isResuming={!!isBulkResuming}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{accounts.length > 0 ? (
|
{accounts.length > 0 ? (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{accounts.map((account) => (
|
{accounts.map((account) => (
|
||||||
@@ -184,18 +196,6 @@ export function AccountsSection({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Bulk Action Bar - shows when accounts selected */}
|
|
||||||
{isSelectable && (
|
|
||||||
<BulkActionBar
|
|
||||||
selectedCount={selectedCount}
|
|
||||||
onPauseSelected={handleBulkPause}
|
|
||||||
onResumeSelected={handleBulkResume}
|
|
||||||
onClearSelection={deselectAll}
|
|
||||||
isPausing={!!isBulkPausing}
|
|
||||||
isResuming={!!isBulkResuming}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Kiro-specific: Incognito browser setting - users complain "it keeps opening incognito" */}
|
{/* Kiro-specific: Incognito browser setting - users complain "it keeps opening incognito" */}
|
||||||
{isKiro && onKiroNoIncognitoChange && (
|
{isKiro && onKiroNoIncognitoChange && (
|
||||||
<div className="mt-3 pt-3 border-t border-dashed">
|
<div className="mt-3 pt-3 border-t border-dashed">
|
||||||
|
|||||||
Reference in new issue
Block a user