Skip to content

Conversation

@MuriloFP
Copy link
Contributor

@MuriloFP MuriloFP commented Jul 31, 2025

Related GitHub Issue

Closes: #6502

Roo Code Task Context (Optional)

No Roo Code task context for this PR

Description

This PR adds visual indicators to the ModeSelector component to distinguish between global and project-based custom modes, addressing user confusion when multiple modes share the same name.

Implementation approach:

  • Added helper functions in ModeSelector component:
    • getModeSource(): Determines if a mode is custom and returns its source
    • renderSourceIndicator(): Returns localized indicator JSX based on mode source
  • Updated the mode display in both the dropdown list and selected mode trigger
  • Used subtle styling with text-vscode-descriptionForeground for indicators
  • Implemented backward compatibility by defaulting to "global" for modes without a source field

Key design decisions:

  • Used short indicators "(G)" and "(P)" in the dropdown to save space
  • Used full text "(Global)" and "(Project)" in the selected mode display for clarity
  • Leveraged existing customMode.source field - no backend changes required
  • Added comprehensive translations for all 18 supported languages

Review Fixes Applied:

  • Fixed test translation mocking to return actual values instead of keys
  • Refactored IIFE usage to a separate renderSourceIndicator helper function for better readability
  • All tests pass after refactoring

Test Procedure

Unit Testing:

  • Added 3 new test cases to ModeSelector.spec.tsx covering:
    • Custom modes with source indicators
    • Built-in modes without indicators
    • Backward compatibility for modes without source field
  • All tests pass: cd webview-ui && npx vitest run src/components/chat/__tests__/ModeSelector.spec.tsx

Manual Testing Steps:

  1. Create both global and project custom modes with the same name
  2. Open the mode selector dropdown
  3. Verify that custom modes show "(G)" or "(P)" indicators in the list
  4. Select a custom mode
  5. Verify the selected mode shows "(Global)" or "(Project)" in the trigger button
  6. Switch between different VSCode themes to ensure indicators remain visible
  7. Change the UI language and verify translations work correctly

Test Environment:

  • VSCode with Roo Code extension
  • Multiple custom modes configured (both global and project-based)
  • Tested with light and dark themes

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

Screenshots would be added here showing:

  1. Mode selector dropdown with "(G)" and "(P)" indicators
  2. Selected mode display showing "(Global)" or "(Project)"
  3. Comparison of built-in modes (no indicators) vs custom modes (with indicators)

Documentation Updates

  • Yes, documentation updates are required.
    • The custom modes documentation should be updated to explain the new visual indicators
    • User guide should mention how to distinguish between global and project modes

Additional Notes

All code quality issues identified during internal review have been addressed:

  • Test translation mocking has been updated to return actual values
  • IIFE usage has been refactored to a separate renderSourceIndicator helper function
  • Code is now cleaner and more maintainable

Get in Touch

Discord username to be provided


Important

Adds visual indicators to distinguish global and project custom modes in ModeSelector, with updated translations and tests.

  • Behavior:
    • Adds visual indicators to ModeSelector for global and project custom modes using getModeSource() and renderSourceIndicator() functions.
    • Updates mode display in dropdown and selected mode trigger with subtle styling.
    • Defaults to "global" for modes without a source field for backward compatibility.
  • Translations:
    • Adds translations for indicators in 18 languages in respective chat.json files.
  • Testing:
    • Adds tests in ModeSelector.spec.tsx for custom modes with indicators, built-in modes without indicators, and backward compatibility.
  • Misc:
    • Refactors IIFE to renderSourceIndicator function for readability.
    • Fixes test translation mocking to return actual values.

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

MuriloFP and others added 30 commits July 3, 2025 15:26
@MuriloFP MuriloFP requested review from cte, jr and mrubens as code owners July 31, 2025 22:46
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. UI/UX UI/UX related or focused labels Jul 31, 2025
@MuriloFP MuriloFP marked this pull request as draft July 31, 2025 22:48
Copy link
Contributor

@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 changes and the implementation looks solid. The visual indicators for global/project custom modes are well-implemented with good backward compatibility and comprehensive i18n support. I've left some suggestions inline that could improve type safety and maintainability.

const getModeSource = (mode: ModeConfig): string | null => {
const isCustom = customModes?.some((m) => m.slug === mode.slug)
if (!isCustom) return null
return mode.source || "global" // Default to global if source is undefined
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider extracting the source type for better type safety. You could define:

Then use it in the ModeConfig interface. This would prevent typos and make the code more maintainable.

const getModeSource = (mode: ModeConfig): string | null => {
const isCustom = customModes?.some((m) => m.slug === mode.slug)
if (!isCustom) return null
return mode.source || "global" // Default to global if source is undefined
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider extracting this default value to a constant:

This would make it easier to maintain and update if needed.

const renderSourceIndicator = (mode: ModeConfig, isShort: boolean = false) => {
const source = getModeSource(mode)
if (!source) return null
return <span className="ml-1 text-vscode-descriptionForeground">({getSourceDisplayText(source, isShort)})</span>
Copy link
Contributor

Choose a reason for hiding this comment

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

For better accessibility, consider adding an aria-label to help screen reader users:
custom mode

<div className="font-bold truncate">{mode.name}</div>
<div className="font-bold truncate">
{mode.name}
{renderSourceIndicator(mode, true)}
Copy link
Contributor

Choose a reason for hiding this comment

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

If the mode list grows significantly, you might want to consider memoizing these source indicators to avoid recalculating them on every render. Though the current performance impact is minimal.

expect(trigger).toHaveTextContent("Old Custom Mode")
expect(trigger).toHaveTextContent("(Global)")
})
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Good test coverage! Consider adding an edge case test for when the prop is undefined/null to ensure the helper functions handle this gracefully.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Jul 31, 2025
@daniel-lxs daniel-lxs moved this from Triage to PR [Draft / In Progress] in Roo Code Roadmap Aug 1, 2025
@hannesrudolph hannesrudolph added PR - Draft / In Progress and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Aug 1, 2025
@github-project-automation github-project-automation bot moved this from PR [Draft / In Progress] to Done in Roo Code Roadmap Sep 22, 2025
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Sep 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR - Draft / In Progress size:L This PR changes 100-499 lines, ignoring generated files. UI/UX UI/UX related or focused

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add visual indicator to show if a mode is global or project-based in the mode edit screen

2 participants