Skip to content

Conversation

@elianiva
Copy link

@elianiva elianiva commented Sep 6, 2025

Related GitHub Issue

Closes: #7496

Roo Code Task Context (Optional)

Description

This PR introduces a UI for custom reordering of the API profiles in addition to the already existing alphabetical ordering.

Test Procedure

Test the feature as shown in the video below.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

Screen.Recording.2025-09-06.at.10.36.39.mov

Documentation Updates

There should be a section showing off this reordering feature.

Additional Notes

Get in Touch

@elianiva


Important

Adds custom reordering of API profiles in ApiConfigSelector with drag-and-drop support and updates i18n files for localization.

  • Behavior:
    • Adds custom reordering of API profiles in ApiConfigSelector.tsx, supporting both alphabetical and custom order.
    • Implements drag-and-drop functionality for reordering when in custom mode.
  • UI Components:
    • Updates ApiConfigSelector to include drag-and-drop handlers and reorder mode controls.
    • Adds buttons for switching between alphabetical and custom sort modes.
  • Testing:
    • Adds test in ApiConfigSelector.spec.tsx for drag-and-drop reordering functionality.
  • Localization:
    • Updates i18n files for multiple languages to include new strings related to reordering functionality.

This description was created by Ellipsis for 5ce0f51. You can customize this summary. It will automatically update as commits are pushed.

@elianiva elianiva requested review from cte, jr and mrubens as code owners September 6, 2025 04:26
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. UI/UX UI/UX related or focused labels Sep 6, 2025
Copy link

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! I've reviewed the API profile reordering feature and found several issues that need attention before merging.

Critical Issues (Must Fix):

  1. Missing persistence of custom order - The component doesn't persist the custom order to storage. When users reload VSCode, their custom ordering will be lost. The component should communicate with the extension backend to save/load the custom order preference.

  2. Missing parent callback handlers - The component accepts onSortModeChange and onCustomOrderChange props but never calls them. These callbacks should be invoked when the sort mode or custom order changes to notify the parent component (lines 133-140 and 168-180 in ApiConfigSelector.tsx).

Important Suggestions (Should Consider):

  1. Incomplete implementation - The PR only addresses API profiles reordering but issue #7496 also requests mode selector reordering. Should this be addressed in a separate PR or included here?

  2. Accessibility concerns - The drag-and-drop functionality lacks keyboard navigation support. Users who rely on keyboard navigation cannot reorder items. Consider adding keyboard shortcuts (e.g., Ctrl+Up/Down) for accessibility.

  3. UX improvement needed - When switching from custom to alphabetical sort, the custom order is lost without warning. Consider showing a confirmation dialog or preserving the custom order for when users switch back.

Minor Improvements (Nice to Have):

  1. Visual feedback enhancement - The drag-over indicator (border-top) could be improved with a more visible drop zone indicator or preview of where the item will be placed.

  2. Test coverage - While there's a test for drag-and-drop, it could be expanded to cover edge cases like dragging pinned items, canceling reorder mode, and switching between sort modes.

Overall, the implementation is well-structured and the UI looks good. The main concerns are around persistence and parent component integration which are critical for the feature to work properly across sessions.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Sep 6, 2025
@elianiva
Copy link
Author

elianiva commented Sep 6, 2025

ah right forgot about the persistence, brb

@elianiva
Copy link
Author

elianiva commented Sep 6, 2025

I've addressed the critical issues, lmk if we want keyboard navigation.
I tried adding keyboard navigation previously but found several issues with it so I didn't include it in this PR. I'm not sure how important is that :/

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Sep 6, 2025
@elianiva
Copy link
Author

elianiva commented Sep 7, 2025

Screen.Recording.2025-09-07.at.09.12.45.mov

managed to make keyboard navigation works (ignore the pink outline, it's using system's colour, it should be default to blue for most people)

@daniel-lxs daniel-lxs moved this from Triage to PR [Needs Prelim Review] in Roo Code Roadmap Sep 8, 2025
@hannesrudolph hannesrudolph added PR - Needs Preliminary Review and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Sep 8, 2025
@daniel-lxs
Copy link
Member

daniel-lxs commented Sep 8, 2025

Hey @elianiva thank you for your contribution!

One observation about the state management: The dual state approach with persistedCustomOrder and internalCustomOrder (lines 47, 62, 65-66 in ApiConfigSelector.tsx) adds some complexity. Have you considered simplifying this to a single source of truth?

The current pattern could potentially lead to sync issues between the two states. Perhaps you could rely solely on the persisted state from the extension context and update it directly via vscode.postMessage, letting the context update flow back through props. This would eliminate the need for the internal fallback state and make the data flow more predictable.

Just a thought to consider for reducing complexity and potential edge cases! The implementation is solid otherwise.

@daniel-lxs daniel-lxs moved this from PR [Needs Prelim Review] to PR [Changes Requested] in Roo Code Roadmap Sep 8, 2025
@elianiva
Copy link
Author

I've updated so that it uses a single source of truth, also fixed a reordering issue due to unnecessary complexity when using keyboard navigation.

@hannesrudolph
Copy link
Collaborator

@brunobergher before I get the merge conflicts on this fixed, thoughts?

@brunobergher
Copy link
Collaborator

Cool! I didn't realize this need but it makes sense.
I'd just leave the ChatArea dropdowns simple and focused just on use, and move this functionality to the dropdown under settings, which is where I tihnk it makes sense to deeply customize things. I'm even open to making that an already expanded list (say 8-10 items talls) instead of a dropdown in that context.

That way we avoid the always prominent mention of "drag to reorder" for people who just want to switch providers or modes.

Is that fair?

@elianiva
Copy link
Author

Cool! I didn't realize this need but it makes sense. I'd just leave the ChatArea dropdowns simple and focused just on use, and move this functionality to the dropdown under settings, which is where I tihnk it makes sense to deeply customize things. I'm even open to making that an already expanded list (say 8-10 items talls) instead of a dropdown in that context.

That way we avoid the always prominent mention of "drag to reorder" for people who just want to switch providers or modes.

Is that fair?

Ah yes, agreed, if we move it inside the settings then we can directly show the items instead of making it as a dropdown toggle.

@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Sep 29, 2025
@elianiva
Copy link
Author

Screen.Recording.2025-09-29.at.15.02.43.mov

Here's what I came up with based on previous feedback, would love to have some feedback on this.

The delay comes from the fact that we're relying on the server state instead of optimistic UI update. I'm not sure whether if it's worth it to update the UI optimistically and revert on failed call. I chose the simplest implementation first, I can always add it later if it's needed.

@roomote
Copy link

roomote bot commented Nov 6, 2025

Rooviewer Clock   See task on Roo Cloud

Review complete. Found no new issues.

  • Missing keyboard accessibility in ConfigItem component - add tabIndex attribute
  • Unused pinned field in apiConfigsCustomOrder schema creates unnecessary complexity
  • Double selection bug when Enter/Space is pressed in ConfigListItem
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

onSelect(config.id)
}
}}
className={cn(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ConfigItem component lacks keyboard accessibility because it's missing a tabIndex attribute. Users cannot tab to these options when navigating with the keyboard, breaking ARIA listbox patterns. Add tabIndex={0} to the outermost div.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +55 to +63
apiConfigsCustomOrder: z
.array(
z.object({
id: z.string(),
index: z.number(),
pinned: z.boolean(),
}),
)
.optional(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pinned field in apiConfigsCustomOrder is defined but never meaningfully used. In ApiConfigManager.tsx line 172, it's preserved with a default value but the sorting logic only uses the index field. This unused field adds complexity to the data model without providing value. Either implement functionality that uses this field or remove it from the schema to avoid data inconsistencies.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines 204 to 210
onKeyDown={(e) => {
onKeyDown(e, index)
if (!isReorderingMode && (e.key === "Enter" || e.key === " ")) {
e.preventDefault()
onSelectConfig(config.name)
}
}}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double selection bug: When a user presses Enter or Space on a config item in normal mode (not reordering), the onKeyDown callback at line 205 calls onSelectConfig, then the outer onKeyDown at line 204-210 calls it again. This happens because the parent's onKeyDown handler (line 204) doesn't check for isReorderingMode when handling Enter/Space. The parent handler should either check isReorderingMode or the inner handler should call e.stopPropagation() to prevent double-firing.

Fix it with Roo Code or mention @roomote and request a fix.

…e/onCustomOrderChange; fix double-selection keydown in settings; add tests
@hannesrudolph
Copy link
Collaborator

hannesrudolph commented Nov 6, 2025

Summary of fixes and recommendations based on Bruno’s comments:

Implemented:

  • Persistence: when switching to “Custom” sort, current visible order is saved via postMessage type setApiConfigsCustomOrder. UI wires to existing handler in webviewMessageHandler.
  • Parent callbacks: added onSortModeChange and onCustomOrderChange and invoke them on mode switch in ApiConfigSelector.
  • Double-selection bug: prevents duplicate selection on Enter/Space in settings by stopping propagation in ConfigListItem.
  • Tests: added assertions that onSortModeChange fires and persistence message is posted in ApiConfigSelector.spec.tsx.

Recommendations (defer to follow-up PR):

  • Keyboard navigation (a11y):
    • Roving tabindex for list items; ArrowUp/ArrowDown move focus; Ctrl/⌘+ArrowUp/ArrowDown reorders in custom mode; Enter selects.
    • Announce reorder via aria-live (e.g. “Moved X above Y”).
    • Add handlers alongside existing DnD in settings manager (e.g., moveItem) and expose minimal keyboard handlers in ApiConfigSelector.
  • UX when leaving custom sort:
    • Either confirmation dialog before discarding custom order, or preserve apiConfigsCustomOrder and simply hide it in alphabetical so switching back restores.
    • Consider a small toast/snackbar indicating current sort mode and how to revert.
  • Visual DnD affordances:
    • Thicker/high-contrast full-width drop indicator or placeholder row preview.
  • Additional tests:
    • Pinned items handling during reorder (blocked or preserved indices).
    • Toggling reorder mode cancel path (no changes persisted).
    • Switching between modes preserves/restores custom order.
    • Keyboard reordering paths (Up/Down and Ctrl/⌘ modifiers).

All CI checks passed after push; webview-ui test suite green locally.

…controls, prefer saved custom order); Settings always-on reordering with Reset to Alphabetical; update tests; fix lint
@hannesrudolph
Copy link
Collaborator

This PR is very far from being ready. Closing unless you have time to work on it for now.

@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Nov 6, 2025
@github-project-automation github-project-automation bot moved this from PR [Changes Requested] to Done in Roo Code Roadmap Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR - Changes Requested size:XXL This PR changes 1000+ lines, ignoring generated files. UI/UX UI/UX related or focused

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] Allow sorting and pinning for Modes and API Profiles under main input

4 participants