feat: add mass edit feature for backlog kanban cards#360
Conversation
Add ability to select multiple backlog features and edit their configuration in bulk. Selection is limited to backlog column features in the current branch/worktree only. Changes: - Add selection mode toggle in board controls - Add checkbox selection on kanban cards (backlog only) - Disable drag and drop during selection mode - Hide action buttons during selection mode - Add floating selection action bar with Edit/Clear/Select All - Add mass edit dialog with all configuration options in single scroll view - Add server endpoint for bulk feature updates
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughAdds bulk-update capability for features via a new server API endpoint and mass-edit UI flow. Introduces selection mode to the board view, enabling users to select multiple features and apply batch updates. Adds Docker development infrastructure (Dockerfile.dev, docker-compose.dev.yml, launcher updates) supporting live-reload development. Removes production-start script and updates documentation to reflect development-first workflows. Changes
Sequence DiagramssequenceDiagram
participant User
participant UI as BoardView UI
participant Hook as useSelectionMode
participant Dialog as MassEditDialog
participant Client as HttpApiClient
participant Server as API Server
User->>UI: Toggles selection mode
UI->>Hook: toggleSelectionMode()
Hook-->>UI: isSelectionMode=true
User->>UI: Clicks feature checkboxes
UI->>Hook: toggleFeatureSelection(featureId)
Hook-->>UI: selectedFeatureIds updated
User->>UI: Clicks "Edit Selected" in ActionBar
UI->>Dialog: Opens with selectedFeatures
User->>Dialog: Selects profile & planning mode
Dialog->>Dialog: Updates field apply flags & values
User->>Dialog: Clicks "Apply"
Dialog->>Client: bulkUpdate(projectPath, featureIds, updates)
Client->>Server: POST /api/features/bulk-update
Server->>Server: Iterate featureIds, update each
Server-->>Client: { success, updatedCount, features[] }
Client-->>Dialog: Result received
Dialog->>UI: onApply called
UI->>Hook: exitSelectionMode()
Hook-->>UI: isSelectionMode=false, selections cleared
UI-->>User: Show success toast, refresh board
sequenceDiagram
participant Docker
participant Shell as dev.mjs
participant Launcher as launcher-utils.mjs
participant Compose as docker-compose.dev
Shell->>Launcher: launchDockerDevContainers({ baseDir })
Launcher->>Launcher: Check Dockerfile.dev exists
Launcher->>Docker: Build server & ui images
Docker-->>Launcher: Build complete
Launcher->>Compose: docker-compose up (dev config)
Compose->>Docker: Start server container
Docker->>Docker: Mount volumes, set NODE_ENV=dev
Compose->>Docker: Start ui container
Docker->>Docker: Mount src/, watch for changes
Docker-->>Launcher: Containers running
Launcher->>Launcher: Poll healthcheck
Docker-->>Launcher: /api/health OK
Launcher-->>Shell: Ready (live reload active)
User->>User: Edit source files
Docker->>Docker: Detect volume changes
Docker-->>User: HMR updates (Vite) / watch rebuild (tsx)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
✨ Finishing touches
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (26)
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. Comment |
Summary of ChangesHello @Shironex, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request delivers a highly requested feature: mass editing for backlog Kanban cards. It allows users to efficiently manage multiple features by selecting them and applying configuration changes in bulk through a new, intuitive user interface. This significantly reduces the manual effort required for updating individual cards, thereby boosting productivity. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable mass edit feature for backlog items, which is a great enhancement for user productivity. The implementation is well-structured, including a new backend endpoint, a custom hook for selection management, and several new UI components for the selection and editing process. I've identified two key areas for improvement: one on the backend to enhance performance by parallelizing the update operations, and a correctness issue on the frontend to properly handle partial success scenarios during bulk updates. Addressing these points will make the feature more robust and performant.
| const results: BulkUpdateResult[] = []; | ||
| const updatedFeatures: Feature[] = []; | ||
|
|
||
| for (const featureId of featureIds) { | ||
| try { | ||
| const updated = await featureLoader.update(projectPath, featureId, updates); | ||
| results.push({ featureId, success: true }); | ||
| updatedFeatures.push(updated); | ||
| } catch (error) { | ||
| results.push({ | ||
| featureId, | ||
| success: false, | ||
| error: getErrorMessage(error), | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| const successCount = results.filter((r) => r.success).length; | ||
| const failureCount = results.filter((r) => !r.success).length; |
There was a problem hiding this comment.
The current implementation updates features sequentially in a for...of loop. For a bulk update operation, this can be inefficient if many features are being updated at once, as each update will wait for the previous one to complete. Since featureLoader.update is likely I/O-bound, these operations can be parallelized to improve performance significantly. I suggest using Promise.allSettled to run all update operations in parallel and then process the results. This also allows for calculating success and failure counts in a single pass.
const updatePromises = featureIds.map((featureId) =>
featureLoader.update(projectPath, featureId, updates)
);
const settledResults = await Promise.allSettled(updatePromises);
const results: BulkUpdateResult[] = [];
const updatedFeatures: Feature[] = [];
let successCount = 0;
settledResults.forEach((result, index) => {
const featureId = featureIds[index];
if (result.status === 'fulfilled') {
results.push({ featureId, success: true });
updatedFeatures.push(result.value);
successCount++;
} else {
results.push({
featureId,
success: false,
error: getErrorMessage(result.reason),
});
}
});
const failureCount = featureIds.length - successCount;| // Update local state | ||
| featureIds.forEach((featureId) => { | ||
| updateFeature(featureId, updates); | ||
| }); | ||
| toast.success(`Updated ${result.updatedCount} features`); | ||
| exitSelectionMode(); | ||
| } else { | ||
| toast.error('Failed to update some features', { | ||
| description: `${result.failedCount} features failed to update`, | ||
| }); | ||
| } | ||
| } catch (error) { |
There was a problem hiding this comment.
The current logic for handling the bulk update response only updates the UI if the entire operation was successful (result.success is true). In cases of partial success, where some features are updated but others fail, the UI does not reflect the successful updates, leading to a state mismatch between the frontend and backend. The backend API conveniently returns a features array containing the successfully updated features. You should use this array to update the local state for successful updates, regardless of the overall result.success flag. I've also updated the error toast to be more informative in case of partial failure.
if (result.features && result.features.length > 0) {
// Update local state for successfully updated features
result.features.forEach((feature) => {
updateFeature(feature.id, updates);
});
}
if (result.success) {
toast.success(`Updated ${result.updatedCount} features`);
exitSelectionMode();
} else {
toast.error('Failed to update some features', {
description: `${result.failedCount} features failed to update, while ${result.updatedCount} succeeded.`,
});
}
- Removed advanced options toggle and related state from the mass edit dialog for a cleaner UI. - Replaced ProfileQuickSelect with ProfileSelect for better profile management. - Introduced new PlanningModeSelect and PrioritySelect components for streamlined selection of planning modes and priorities. - Updated imports in shared index to include new select components. - Enhanced the mass edit dialog to utilize the new components, improving user experience during bulk edits.
…ovements - Introduced a new `docker-compose.dev.yml` for development mode, enabling live reload and improved container management. - Updated `dev.mjs` to utilize `launchDockerDevContainers` for starting development containers with live reload capabilities. - Refactored `printModeMenu` to differentiate between development and production Docker options. - Enhanced the `BoardView` and `KanbanBoard` components by streamlining props and improving UI interactions. - Removed the `start.mjs` script, consolidating production launch logic into `dev.mjs` for a more unified approach.
- Updated the logging format in the launchDockerContainers function to enhance readability by breaking long lines into multiple lines. This change improves the clarity of log messages when starting Docker containers.
Add ability to select multiple backlog features and edit their configuration
in bulk. Selection is limited to backlog column features in the current
branch/worktree only.
Changes:
Preview
Summary by CodeRabbit
Release Notes
New Features
Development & Deployment
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.