feat: dashboard edits#267
Conversation
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
|
Warning Review limit reached
More reviews will be available in 50 minutes and 44 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds label-condition-based evidence scoping, suggestion group editing, and filter-merge generalization to the dashboard suggestions feature. New types, endpoint helpers, and utility functions are defined in ChangesDashboard Suggestion Editing, Filter Generalization, and Label Condition Builder
Sequence Diagram(s)sequenceDiagram
participant User
participant SuggestionsView
participant SuggestionScopeDialog
participant SuggestionEditDialog
participant useDashboardSuggestions
participant BackendAPI
rect rgba(100, 149, 237, 0.5)
Note over User,BackendAPI: Filter Merge Generalization
User->>SuggestionsView: clicks "Suggest filter merges"
SuggestionsView->>useDashboardSuggestions: generalizeSuggestions()
useDashboardSuggestions->>BackendAPI: POST generalize endpoint
BackendAPI-->>useDashboardSuggestions: { candidates, inserted }
useDashboardSuggestions->>BackendAPI: refreshPendingSuggestions()
SuggestionsView->>SuggestionsView: show toast (inserted/candidates counts)
end
rect rgba(144, 238, 144, 0.5)
Note over User,BackendAPI: Suggestion Group Editing
User->>SuggestionsView: clicks Edit on pending group
SuggestionsView->>SuggestionEditDialog: openEditDialog(group)
User->>SuggestionEditDialog: edits title, label rows, controls
SuggestionEditDialog-->>SuggestionsView: emits save(EditDashboardSuggestionGroupPayload)
SuggestionsView->>useDashboardSuggestions: editSuggestionGroup(payload)
useDashboardSuggestions->>BackendAPI: POST edit-group endpoint
useDashboardSuggestions->>BackendAPI: refreshPendingSuggestions()
end
rect rgba(255, 200, 100, 0.5)
Note over User,BackendAPI: Generate with Label Conditions
User->>SuggestionsView: opens SuggestionScopeDialog
SuggestionsView->>useDashboardSuggestions: refreshLabelKeys()
useDashboardSuggestions->>BackendAPI: GET label-keys endpoint
User->>SuggestionScopeDialog: enters conditions and constraints
SuggestionScopeDialog->>BackendAPI: POST preview with scope + constraints
User->>SuggestionScopeDialog: clicks Generate
SuggestionScopeDialog-->>SuggestionsView: emits generate(scope, constraints)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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 |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/views/dashboard/partials/dashboard-suggestions.ts`:
- Around line 183-187: The condition in the baselineRow find method currently
excludes empty objects as valid baselines because of the Object.keys length
check. An empty object {} should be treated as a valid baseline rather than "no
baseline". Remove the length check on
Object.keys(s.originalProposedFilterLabelSet) and simply verify that
originalProposedFilterLabelSet exists (is not undefined or null). Apply the same
fix to the similar code block at lines 211-213 that has the same pattern.
In `@src/views/dashboard/partials/SuggestionEditDialog.vue`:
- Around line 253-257: The addControlKeys mapping in the submit() method
unconditionally re-qualifies control IDs using buildControlKey(), but
addControlIds may already contain catalog-qualified keys from SuggestionsView.
This double qualification breaks the API contract. Check whether each controlId
in addControlIds.value is already a qualified key before processing it. If it's
already qualified, use it directly in the returned array. If it's not qualified,
then call buildControlKey() with the catalog ID and control ID to qualify it.
This ensures you don't emit invalid re-qualified control keys.
In `@src/views/dashboard/SuggestionsView.vue`:
- Around line 1040-1047: The saveGroupEdit function catches errors and only sets
scopeCeilingError.value, which is scoped to SuggestionScopeDialog, causing edit
failures to become silent in the edit dialog path. In addition to extracting the
error message and setting scopeCeilingError.value, also set an error state
variable that is connected to the edit dialog display (such as an editError or
similar variable) so that users receive visible feedback when the group edit
save operation fails.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 97f1dd49-4f9b-4ada-a8d9-62b0002e8bfc
📒 Files selected for processing (11)
src/composables/useDashboardSuggestions.tssrc/views/dashboard/SuggestionsView.vuesrc/views/dashboard/__tests__/SuggestionsView.spec.tssrc/views/dashboard/partials/LabelConditionBuilder.vuesrc/views/dashboard/partials/SuggestionEditDialog.vuesrc/views/dashboard/partials/SuggestionScopeDialog.vuesrc/views/dashboard/partials/__tests__/LabelConditionBuilder.spec.tssrc/views/dashboard/partials/__tests__/SuggestionEditDialog.spec.tssrc/views/dashboard/partials/__tests__/SuggestionScopeDialog.spec.tssrc/views/dashboard/partials/__tests__/dashboard-suggestions.spec.tssrc/views/dashboard/partials/dashboard-suggestions.ts
| const baselineRow = suggestions.find( | ||
| (s) => | ||
| s.originalProposedFilterLabelSet && | ||
| Object.keys(s.originalProposedFilterLabelSet).length > 0, | ||
| ); |
There was a problem hiding this comment.
Handle empty AI baselines as valid baselines in diff computation
originalProposedFilterLabelSet: {} is currently treated as “no baseline” because of the length check, so edited labels render as unchanged instead of added.
Suggested patch
- const baselineRow = suggestions.find(
- (s) =>
- s.originalProposedFilterLabelSet &&
- Object.keys(s.originalProposedFilterLabelSet).length > 0,
- );
- const baseline = baselineRow?.originalProposedFilterLabelSet;
+ const baseline = suggestions.find(
+ (s) => s.originalProposedFilterLabelSet !== undefined,
+ )?.originalProposedFilterLabelSet;
+ const hasBaseline = baseline !== undefined;
@@
- ...(baseline ? Object.keys(baseline) : []),
+ ...(hasBaseline ? Object.keys(baseline) : []),
@@
- if (!baseline) {
+ if (!hasBaseline) {
labelChips.push({ text: `${key}=${current}`, kind: 'unchanged' });Also applies to: 211-213
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/views/dashboard/partials/dashboard-suggestions.ts` around lines 183 -
187, The condition in the baselineRow find method currently excludes empty
objects as valid baselines because of the Object.keys length check. An empty
object {} should be treated as a valid baseline rather than "no baseline".
Remove the length check on Object.keys(s.originalProposedFilterLabelSet) and
simply verify that originalProposedFilterLabelSet exists (is not undefined or
null). Apply the same fix to the similar code block at lines 211-213 that has
the same pattern.
| const addControlKeys = addControlIds.value.map((controlId) => { | ||
| const catalogId = | ||
| props.resolveCatalogId?.(controlId) || groupCatalogId.value; | ||
| return buildControlKey(catalogId, controlId); | ||
| }); |
There was a problem hiding this comment.
Avoid re-qualifying control keys in edit payload
addControlIds may already contain catalog-qualified keys from SuggestionsView (optionValue = controlOptions.value), but submit() always runs buildControlKey(...) again. This can emit invalid addControlKeys and break the API contract.
Suggested patch
- const addControlKeys = addControlIds.value.map((controlId) => {
- const catalogId =
- props.resolveCatalogId?.(controlId) || groupCatalogId.value;
- return buildControlKey(catalogId, controlId);
- });
+ const addControlKeys = addControlIds.value.map((controlKeyOrId) => {
+ if (controlKeyOrId.includes(':')) {
+ return controlKeyOrId;
+ }
+ const catalogId =
+ props.resolveCatalogId?.(controlKeyOrId) || groupCatalogId.value;
+ return catalogId
+ ? buildControlKey(catalogId, controlKeyOrId)
+ : controlKeyOrId;
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const addControlKeys = addControlIds.value.map((controlId) => { | |
| const catalogId = | |
| props.resolveCatalogId?.(controlId) || groupCatalogId.value; | |
| return buildControlKey(catalogId, controlId); | |
| }); | |
| const addControlKeys = addControlIds.value.map((controlKeyOrId) => { | |
| if (controlKeyOrId.includes(':')) { | |
| return controlKeyOrId; | |
| } | |
| const catalogId = | |
| props.resolveCatalogId?.(controlKeyOrId) || groupCatalogId.value; | |
| return catalogId | |
| ? buildControlKey(catalogId, controlKeyOrId) | |
| : controlKeyOrId; | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/views/dashboard/partials/SuggestionEditDialog.vue` around lines 253 -
257, The addControlKeys mapping in the submit() method unconditionally
re-qualifies control IDs using buildControlKey(), but addControlIds may already
contain catalog-qualified keys from SuggestionsView. This double qualification
breaks the API contract. Check whether each controlId in addControlIds.value is
already a qualified key before processing it. If it's already qualified, use it
directly in the returned array. If it's not qualified, then call
buildControlKey() with the catalog ID and control ID to qualify it. This ensures
you don't emit invalid re-qualified control keys.
Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
Summary by CodeRabbit