mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 20:23:36 +00:00
feat: implement bulk feature verification and enhance selection mode
- Added functionality for bulk verifying features in the BoardView, allowing users to mark multiple features as verified at once. - Introduced a selection target mechanism to differentiate between 'backlog' and 'waiting_approval' features during selection mode. - Updated the KanbanCard and SelectionActionBar components to support the new selection target logic, improving user experience for bulk actions. - Enhanced the UI to provide appropriate actions based on the current selection target, including verification options for waiting approval features.
This commit is contained in:
@@ -187,6 +187,7 @@ export function BoardView() {
|
||||
// Selection mode hook for mass editing
|
||||
const {
|
||||
isSelectionMode,
|
||||
selectionTarget,
|
||||
selectedFeatureIds,
|
||||
selectedCount,
|
||||
toggleSelectionMode,
|
||||
@@ -684,6 +685,67 @@ export function BoardView() {
|
||||
isPrimaryWorktreeBranch,
|
||||
]);
|
||||
|
||||
// Get waiting_approval feature IDs in current branch for "Select All"
|
||||
const allSelectableWaitingApprovalFeatureIds = useMemo(() => {
|
||||
return hookFeatures
|
||||
.filter((f) => {
|
||||
// Only waiting_approval features
|
||||
if (f.status !== 'waiting_approval') return false;
|
||||
|
||||
// Filter by current worktree branch
|
||||
const featureBranch = f.branchName;
|
||||
if (!featureBranch) {
|
||||
// No branch assigned - only selectable on primary worktree
|
||||
return currentWorktreePath === null;
|
||||
}
|
||||
if (currentWorktreeBranch === null) {
|
||||
// Viewing main but branch hasn't been initialized
|
||||
return currentProject?.path
|
||||
? isPrimaryWorktreeBranch(currentProject.path, featureBranch)
|
||||
: false;
|
||||
}
|
||||
// Match by branch name
|
||||
return featureBranch === currentWorktreeBranch;
|
||||
})
|
||||
.map((f) => f.id);
|
||||
}, [
|
||||
hookFeatures,
|
||||
currentWorktreePath,
|
||||
currentWorktreeBranch,
|
||||
currentProject?.path,
|
||||
isPrimaryWorktreeBranch,
|
||||
]);
|
||||
|
||||
// Handler for bulk verifying multiple features
|
||||
const handleBulkVerify = useCallback(async () => {
|
||||
if (!currentProject || selectedFeatureIds.size === 0) return;
|
||||
|
||||
try {
|
||||
const api = getHttpApiClient();
|
||||
const featureIds = Array.from(selectedFeatureIds);
|
||||
const updates = { status: 'verified' as const };
|
||||
|
||||
// Use bulk update API for efficient batch processing
|
||||
const result = await api.features.bulkUpdate(currentProject.path, featureIds, updates);
|
||||
|
||||
if (result.success) {
|
||||
// Update local state for all features
|
||||
featureIds.forEach((featureId) => {
|
||||
updateFeature(featureId, updates);
|
||||
});
|
||||
toast.success(`Verified ${result.updatedCount} features`);
|
||||
exitSelectionMode();
|
||||
} else {
|
||||
toast.error('Failed to verify some features', {
|
||||
description: `${result.failedCount} features failed to verify`,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Bulk verify failed:', error);
|
||||
toast.error('Failed to verify features');
|
||||
}
|
||||
}, [currentProject, selectedFeatureIds, updateFeature, exitSelectionMode]);
|
||||
|
||||
// Handler for addressing PR comments - creates a feature and starts it automatically
|
||||
const handleAddressPRComments = useCallback(
|
||||
async (worktree: WorktreeInfo, prInfo: PRInfo) => {
|
||||
@@ -1448,6 +1510,7 @@ export function BoardView() {
|
||||
pipelineConfig={pipelineConfig}
|
||||
onOpenPipelineSettings={() => setShowPipelineSettings(true)}
|
||||
isSelectionMode={isSelectionMode}
|
||||
selectionTarget={selectionTarget}
|
||||
selectedFeatureIds={selectedFeatureIds}
|
||||
onToggleFeatureSelection={toggleFeatureSelection}
|
||||
onToggleSelectionMode={toggleSelectionMode}
|
||||
@@ -1463,11 +1526,23 @@ export function BoardView() {
|
||||
{isSelectionMode && (
|
||||
<SelectionActionBar
|
||||
selectedCount={selectedCount}
|
||||
totalCount={allSelectableFeatureIds.length}
|
||||
onEdit={() => setShowMassEditDialog(true)}
|
||||
onDelete={handleBulkDelete}
|
||||
totalCount={
|
||||
selectionTarget === 'waiting_approval'
|
||||
? allSelectableWaitingApprovalFeatureIds.length
|
||||
: allSelectableFeatureIds.length
|
||||
}
|
||||
onEdit={selectionTarget === 'backlog' ? () => setShowMassEditDialog(true) : undefined}
|
||||
onDelete={selectionTarget === 'backlog' ? handleBulkDelete : undefined}
|
||||
onVerify={selectionTarget === 'waiting_approval' ? handleBulkVerify : undefined}
|
||||
onClear={clearSelection}
|
||||
onSelectAll={() => selectAll(allSelectableFeatureIds)}
|
||||
onSelectAll={() =>
|
||||
selectAll(
|
||||
selectionTarget === 'waiting_approval'
|
||||
? allSelectableWaitingApprovalFeatureIds
|
||||
: allSelectableFeatureIds
|
||||
)
|
||||
}
|
||||
mode={selectionTarget === 'waiting_approval' ? 'waiting_approval' : 'backlog'}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user