Skip to content

fix(lightspeed): fixed newchat cta behavior#2449

Open
debsmita1 wants to merge 3 commits intoredhat-developer:mainfrom
debsmita1:lightspeed-fixes
Open

fix(lightspeed): fixed newchat cta behavior#2449
debsmita1 wants to merge 3 commits intoredhat-developer:mainfrom
debsmita1:lightspeed-fixes

Conversation

@debsmita1
Copy link
Member

@debsmita1 debsmita1 commented Mar 4, 2026

Hey, I just made a Pull Request!

Resolves:

Solution description:

  • Fixed "new chat" cta behavior to show the cta button only when there’s an existing conversation or when the current new chat already has messages. It is hidden when the conversation hasn’t started yet (empty new chat)
  • Added vertical scroll when too many models are available. The model dropdown now uses different scroll thresholds by display mode:
    Overlay mode: scrollable when models.length > 8
    Docked and fullscreen: scrollable when models.length > 10
  • Removed model grouping/categories in the model selector dropdown

Screenshots/GIF:

Screen.Recording.2026-03-04.at.10.30.48.PM.mov

✔️ Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or Updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)

@rhdh-gh-app
Copy link

rhdh-gh-app bot commented Mar 4, 2026

Changed Packages

Package Name Package Path Changeset Bump Current Version
app workspaces/lightspeed/packages/app none v0.0.0
@red-hat-developer-hub/backstage-plugin-lightspeed workspaces/lightspeed/plugins/lightspeed patch v1.3.0

@rhdh-qodo-merge
Copy link

Review Summary by Qodo

Fix new chat CTA behavior and model dropdown scrolling

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Fixed "new chat" CTA button visibility logic
• Added vertical scrolling for model dropdown with display-mode-aware thresholds
• Removed model grouping by provider in selector dropdown
• Refactored React imports to use named imports instead of namespace
Diagram
flowchart LR
  A["New Chat CTA Logic"] -->|Show only with| B["Existing conversation or messages"]
  C["Model Dropdown"] -->|Add scrolling when| D["Models exceed threshold"]
  D -->|Overlay mode| E["8+ models"]
  D -->|Docked/Fullscreen| F["10+ models"]
  G["Model Grouping"] -->|Remove| H["Flat model list"]
Loading

Grey Divider

File Changes

1. workspaces/lightspeed/plugins/lightspeed/src/hooks/useConversationMessages.ts Formatting +11/-11

Refactor React imports to named imports

• Changed React namespace import to named imports for RefObject, useCallback, useEffect,
 useRef, useState
• Updated all React.useRef, React.useState, React.useEffect, React.useCallback calls to use
 named imports
• Updated type annotation from React.RefObject to RefObject

workspaces/lightspeed/plugins/lightspeed/src/hooks/useConversationMessages.ts


2. workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx 🐞 Bug fix +4/-1

Fix new chat CTA visibility logic

• Refactored new chat initialization logic to check user and ready state first
• Fixed CTA button visibility to show only when conversation exists or has messages
• Simplified conditional logic with early return pattern

workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx


3. workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBoxHeader.tsx ✨ Enhancement +19/-38

Remove model grouping and add dropdown scrolling

• Removed model grouping logic that organized models by provider
• Removed useMemo import as it's no longer needed
• Added display-mode-aware scroll threshold calculation (8 for overlay, 10 for docked/fullscreen)
• Added isScrollable and maxMenuHeight props to Dropdown component
• Flattened model dropdown to show all models without grouping

workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBoxHeader.tsx


View more (1)
4. workspaces/lightspeed/.changeset/smart-turkeys-watch.md 📝 Documentation +7/-0

Add changeset for lightspeed plugin updates

• Added changeset file documenting patch version changes
• Listed three main fixes: new chat CTA behavior, model dropdown scrolling, and removal of model
 grouping

workspaces/lightspeed/.changeset/smart-turkeys-watch.md


Grey Divider

Qodo Logo

@rhdh-qodo-merge
Copy link

rhdh-qodo-merge bot commented Mar 4, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Unkeyed fragment in models map 🐞 Bug ✓ Correctness
Description
The model dropdown renders a list via models.map(...) but returns an unkeyed fragment
(<>...</>), so React cannot correctly reconcile items. Additionally, the only provided key is on
an inner DropdownGroup and uses model.label, which may be non-unique, increasing the chance of
incorrect selection/rendering when models change.
Code

workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBoxHeader.tsx[R144-156]

+          {models.map(model => (
+            <>
+              <DropdownGroup className={styles.groupTitle} key={model.label}>
+                <DropdownItem
+                  value={model.value}
+                  key={model.value}
+                  isSelected={selectedModel === model.value}
                >
-                  {providerModels.map(model => (
-                    <DropdownItem value={model.value} key={model.value}>
-                      {model.label}
-                    </DropdownItem>
-                  ))}
-                </DropdownGroup>
-                {index < Object.entries(groupedModels).length - 1 && (
-                  <Divider component="li" />
-                )}
-              </>
-            ),
-          )}
+                  {model.label}
+                </DropdownItem>
+              </DropdownGroup>
+            </>
+          ))}
Evidence
In the mapped list, the top-level returned element is a fragment with no key. React requires the
key on the top-level element returned from the map to reliably track list items; placing the key
on a nested child does not satisfy this requirement. Using model.label as the key also risks
collisions if two models share a label.

workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBoxHeader.tsx[143-156]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The model dropdown renders `models.map(...)` items using an unkeyed fragment (`&lt;&gt;...&lt;/&gt;`). React keys must be applied to the *top-level* element returned by the map, otherwise reconciliation can misbehave and warnings are emitted. Also, `key={model.label}` may not be unique.

## Issue Context
This is in the model selector dropdown list rendering.

## Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBoxHeader.tsx[143-156]

## Suggested change
- Replace the `&lt;&gt;...&lt;/&gt;` wrapper with either:
 - a single `DropdownItem` directly (recommended), with `key={model.value}`; or
 - `&lt;Fragment key={model.value}&gt;...&lt;/Fragment&gt;` (and remove/avoid conflicting nested keys).
- Avoid using `model.label` for keys; use `model.value`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +144 to +156
{models.map(model => (
<>
<DropdownGroup className={styles.groupTitle} key={model.label}>
<DropdownItem
value={model.value}
key={model.value}
isSelected={selectedModel === model.value}
>
{providerModels.map(model => (
<DropdownItem value={model.value} key={model.value}>
{model.label}
</DropdownItem>
))}
</DropdownGroup>
{index < Object.entries(groupedModels).length - 1 && (
<Divider component="li" />
)}
</>
),
)}
{model.label}
</DropdownItem>
</DropdownGroup>
</>
))}

Choose a reason for hiding this comment

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

Action required

1. Unkeyed fragment in models map 🐞 Bug ✓ Correctness

The model dropdown renders a list via models.map(...) but returns an unkeyed fragment
(<>...</>), so React cannot correctly reconcile items. Additionally, the only provided key is on
an inner DropdownGroup and uses model.label, which may be non-unique, increasing the chance of
incorrect selection/rendering when models change.
Agent Prompt
## Issue description
The model dropdown renders `models.map(...)` items using an unkeyed fragment (`<>...</>`). React keys must be applied to the *top-level* element returned by the map, otherwise reconciliation can misbehave and warnings are emitted. Also, `key={model.label}` may not be unique.

## Issue Context
This is in the model selector dropdown list rendering.

## Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBoxHeader.tsx[143-156]

## Suggested change
- Replace the `<>...</>` wrapper with either:
  - a single `DropdownItem` directly (recommended), with `key={model.value}`; or
  - `<Fragment key={model.value}>...</Fragment>` (and remove/avoid conflicting nested keys).
- Avoid using `model.label` for keys; use `model.value`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Contributor

@HusneShabbir HusneShabbir left a comment

Choose a reason for hiding this comment

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

Changes look good to me, looking into the CI failure

…remove button dependency

Made-with: Cursor
@HusneShabbir
Copy link
Contributor

@Debsmita please merge this PR — it will fix CI with the incoming changes: debsmita1#8

…lts-without-button

fix(lightspeed): verify no-results message by heading and text only, remove button dependency
@debsmita1 debsmita1 requested a review from aprilma419 March 5, 2026 07:12
Copy link
Contributor

@HusneShabbir HusneShabbir left a comment

Choose a reason for hiding this comment

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

/lgtm

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 5, 2026

@aprilma419
Copy link

LGTM. @debsmita1 One question - can we make the toggle bar slightly wider so it matches the maximum width of the selected option?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants