Skip to content

feat(lightspeed): implement Notebooks list/dashboard view#2537

Open
lokanandaprabhu wants to merge 1 commit intoredhat-developer:mainfrom
lokanandaprabhu:lightspeed-notebooks-updates
Open

feat(lightspeed): implement Notebooks list/dashboard view#2537
lokanandaprabhu wants to merge 1 commit intoredhat-developer:mainfrom
lokanandaprabhu:lightspeed-notebooks-updates

Conversation

@lokanandaprabhu
Copy link
Member

@lokanandaprabhu lokanandaprabhu commented Mar 13, 2026

Hey, I just made a Pull Request!

NOTE: This PR is dependent on #2499

Story

https://issues.redhat.com/browse/RHIDP-12349

Summary

  • Add notebooks tab UI with empty state, cards, and actions
  • Add notebooks API client + hooks for list/rename/delete
  • Update modal styling and tabs behavior for fullscreen

Screenshots

Screen.Recording.2026-03-13.at.2.28.41.PM.mov
Screenshot 2026-03-13 at 2 27 22 PM Screenshot 2026-03-13 at 2 27 32 PM Screenshot 2026-03-13 at 2 27 48 PM Screenshot 2026-03-13 at 2 28 09 PM Screenshot 2026-03-13 at 2 29 48 PM

✔️ 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 13, 2026

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-lightspeed workspaces/lightspeed/plugins/lightspeed minor v1.4.0

@rhdh-qodo-merge
Copy link

Review Summary by Qodo

Implement AI notebooks dashboard with list, rename, and delete functionality

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add notebooks API client with list/rename/delete operations
• Implement custom hooks for notebook sessions management
• Create notebooks UI tab with cards, empty state, and actions
• Add comprehensive i18n translations for notebooks feature
• Implement rename and delete modals with error handling
Diagram
flowchart LR
  API["NotebooksApiClient<br/>list/rename/delete"]
  HOOKS["Custom Hooks<br/>useNotebookSessions<br/>useRenameNotebook<br/>useDeleteNotebook"]
  UI["Notebooks UI<br/>Cards, Empty State<br/>Modals"]
  TRANS["i18n Translations<br/>6 languages"]
  
  API -- "provides API methods" --> HOOKS
  HOOKS -- "manages state & queries" --> UI
  TRANS -- "localizes content" --> UI
Loading

Grey Divider

File Changes

1. workspaces/lightspeed/plugins/lightspeed/src/api/notebooksApi.ts ✨ Enhancement +37/-0

Define notebooks API interface and reference

workspaces/lightspeed/plugins/lightspeed/src/api/notebooksApi.ts


2. workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts ✨ Enhancement +112/-0

Implement notebooks API client with HTTP methods

workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts


3. workspaces/lightspeed/plugins/lightspeed/src/hooks/useNotebookSessions.ts ✨ Enhancement +36/-0

Add hook for fetching notebook sessions list

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


View more (16)
4. workspaces/lightspeed/plugins/lightspeed/src/hooks/useRenameNotebook.ts ✨ Enhancement +48/-0

Add hook for renaming notebook sessions

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


5. workspaces/lightspeed/plugins/lightspeed/src/hooks/useDeleteNotebook.ts ✨ Enhancement +43/-0

Add hook for deleting notebook sessions

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


6. workspaces/lightspeed/plugins/lightspeed/src/hooks/index.ts ✨ Enhancement +3/-0

Export new notebook-related hooks

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


7. workspaces/lightspeed/plugins/lightspeed/src/types.ts ✨ Enhancement +25/-0

Add notebook session and metadata type definitions

workspaces/lightspeed/plugins/lightspeed/src/types.ts


8. workspaces/lightspeed/plugins/lightspeed/src/plugin.ts ✨ Enhancement +11/-0

Register notebooks API factory in plugin

workspaces/lightspeed/plugins/lightspeed/src/plugin.ts


9. workspaces/lightspeed/plugins/lightspeed/src/components/RenameNotebookModal.tsx ✨ Enhancement +202/-0

Create modal for renaming notebooks with validation

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


10. workspaces/lightspeed/plugins/lightspeed/src/components/DeleteNotebookModal.tsx ✨ Enhancement +161/-0

Create modal for deleting notebooks with confirmation

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


11. workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx ✨ Enhancement +508/-115

Add notebooks tab UI with cards and empty state

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


12. workspaces/lightspeed/plugins/lightspeed/src/translations/ref.ts 📝 Documentation +26/-0

Add English translation keys for notebooks feature

workspaces/lightspeed/plugins/lightspeed/src/translations/ref.ts


13. workspaces/lightspeed/plugins/lightspeed/src/translations/de.ts 📝 Documentation +26/-0

Add German translations for notebooks feature

workspaces/lightspeed/plugins/lightspeed/src/translations/de.ts


14. workspaces/lightspeed/plugins/lightspeed/src/translations/es.ts 📝 Documentation +26/-0

Add Spanish translations for notebooks feature

workspaces/lightspeed/plugins/lightspeed/src/translations/es.ts


15. workspaces/lightspeed/plugins/lightspeed/src/translations/fr.ts 📝 Documentation +26/-0

Add French translations for notebooks feature

workspaces/lightspeed/plugins/lightspeed/src/translations/fr.ts


16. workspaces/lightspeed/plugins/lightspeed/src/translations/it.ts 📝 Documentation +26/-0

Add Italian translations for notebooks feature

workspaces/lightspeed/plugins/lightspeed/src/translations/it.ts


17. workspaces/lightspeed/plugins/lightspeed/src/translations/ja.ts 📝 Documentation +26/-0

Add Japanese translations for notebooks feature

workspaces/lightspeed/plugins/lightspeed/src/translations/ja.ts


18. workspaces/lightspeed/plugins/lightspeed/src/components/__tests__/LightspeedChat.test.tsx 🧪 Tests +94/-6

Add tests for notebook updated labels formatting

workspaces/lightspeed/plugins/lightspeed/src/components/tests/LightspeedChat.test.tsx


19. workspaces/lightspeed/.changeset/notebooks-dashboard-rename-delete.md 📝 Documentation +5/-0

Add changeset for notebooks feature release

workspaces/lightspeed/.changeset/notebooks-dashboard-rename-delete.md


Grey Divider

Qodo Logo

@rhdh-qodo-merge
Copy link

rhdh-qodo-merge bot commented Mar 13, 2026

Code Review by Qodo

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

Grey Divider


Action required

1. Create button does nothing 🐞 Bug ✓ Correctness
Description
The Notebooks panel renders “Create a new notebook” buttons without any onClick behavior, so the
primary call-to-action is non-functional.
Code

workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[R1117-1148]

+              {hasNotebooks && (
+                <Button
+                  variant="primary"
+                  className={classes.notebooksAction}
+                  icon={<PlusCircleIcon />}
+                >
+                  {t('notebooks.empty.action')}
+                </Button>
+              )}
+            </div>
+            {!hasNotebooks ? (
+              <div className={classes.notebooksEmptyState}>
+                <CatalogIcon className={classes.notebooksIcon} />
+                <Typography
+                  variant="h6"
+                  className={classes.notebooksHeadingEmpty}
+                >
+                  {t('notebooks.empty.title')}
+                </Typography>
+                <Typography
+                  variant="body2"
+                  color="textSecondary"
+                  className={classes.notebooksDescription}
+                >
+                  {t('notebooks.empty.description')}
+                </Typography>
+                <Button
+                  variant="primary"
+                  className={classes.notebooksActionEmpty}
+                >
+                  {t('notebooks.empty.action')}
+                </Button>
Evidence
Both the header CTA and the empty-state CTA render PatternFly Buttons but do not provide an onClick
handler (or navigation), so user interaction cannot trigger notebook creation.

workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[1117-1125]
workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[1143-1148]

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 notebooks CTA buttons are clickable but have no behavior, making the primary action in the notebooks view non-functional.

### Issue Context
Both the header and empty-state CTAs render `&lt;Button&gt;` without `onClick`.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[1117-1148]

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


2. Delete spammable 🐞 Bug ⛯ Reliability
Description
DeleteNotebookModal does not disable the Delete button during an in-flight mutation, allowing
multiple rapid clicks that can submit multiple DELETE requests.
Code

workspaces/lightspeed/plugins/lightspeed/src/components/DeleteNotebookModal.tsx[R141-149]

+      <DialogActions className={classes.dialogActions}>
+        <Button
+          variant="contained"
+          color="error"
+          className={classes.deleteButton}
+          onClick={handleDelete}
+        >
+          {t('notebooks.delete.action')}
+        </Button>
Evidence
The modal’s delete button is always enabled, unlike the existing conversation DeleteModal which uses
an isPending flag to prevent repeated submissions.

workspaces/lightspeed/plugins/lightspeed/src/components/DeleteNotebookModal.tsx[91-101]
workspaces/lightspeed/plugins/lightspeed/src/components/DeleteNotebookModal.tsx[141-149]
workspaces/lightspeed/plugins/lightspeed/src/components/DeleteModal.tsx[43-48]
workspaces/lightspeed/plugins/lightspeed/src/components/DeleteModal.tsx[107-114]

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 delete action can be triggered multiple times because the Delete button remains enabled while the async mutation is running.

### Issue Context
Conversation deletion already prevents this by disabling the confirm button using `isPending`; notebooks deletion should follow the same pattern.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/DeleteNotebookModal.tsx[89-158]
- workspaces/lightspeed/plugins/lightspeed/src/hooks/useDeleteNotebook.ts[27-42]
- workspaces/lightspeed/plugins/lightspeed/src/components/DeleteModal.tsx[43-48]
- workspaces/lightspeed/plugins/lightspeed/src/components/DeleteModal.tsx[107-114]

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



Remediation recommended

3. Hidden notebooks fetch 🐞 Bug ➹ Performance
Description
LightspeedChat enables useNotebookSessions based only on activeTab===1, but the notebooks panel is
rendered only when isFullscreenMode is true, so leaving fullscreen while on the Notebooks tab can
keep fetching sessions in the background while the UI is hidden.
Code

workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[R325-336]

+  const [activeTab, setActiveTab] = useState<number>(0);
+  const { data: notebooks = [], refetch: refetchNotebooks } =
+    useNotebookSessions(activeTab === 1);
+  const hasNotebooks = notebooks.length > 0;
+  const [openNotebookMenuId, setOpenNotebookMenuId] = useState<string | null>(
+    null,
+  );
+  const [renameNotebookId, setRenameNotebookId] = useState<string | null>(null);
+  const [deleteNotebookId, setDeleteNotebookId] = useState<string | null>(null);
  const [conversationId, setConversationId] = useState<string>('');
  const [newChatCreated, setNewChatCreated] = useState<boolean>(false);
  const [isSendButtonDisabled, setIsSendButtonDisabled] =
Evidence
The sessions query is enabled when activeTab is 1, but the notebooks UI is additionally gated on
isFullscreenMode; displayMode can be switched away from embedded (fullscreen) without resetting
activeTab, making the query potentially run when the notebooks UI cannot be shown.

workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[325-356]
workspaces/lightspeed/plugins/lightspeed/src/hooks/useNotebookSessions.ts[24-35]
workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBoxHeader.tsx[118-128]

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 notebooks sessions query can remain enabled when the Notebooks UI is not renderable (e.g., user leaves fullscreen while activeTab remains 1), causing background API calls.

### Issue Context
`useNotebookSessions` is currently enabled solely by `activeTab === 1`, while the notebooks panel is gated by `isFullscreenMode`.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[325-356]
- workspaces/lightspeed/plugins/lightspeed/src/hooks/useNotebookSessions.ts[24-35]
- workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBoxHeader.tsx[118-128]

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


4. Duplicate notebooks requests 🐞 Bug ➹ Performance
Description
handleNotebookTabSelect sets activeTab to 1 and also calls refetchNotebooks(), which can cause
redundant listSessions requests on tab switch.
Code

workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[R358-367]

+  const handleNotebookTabSelect = (
+    _event: React.MouseEvent<any>,
+    tabIndex: number | string,
+  ) => {
+    const nextTab = Number(tabIndex);
+    setActiveTab(nextTab);
+    if (nextTab === 1) {
+      refetchNotebooks();
+    }
+  };
Evidence
The handler explicitly refetches on selecting the notebooks tab, while the query itself is
controlled via an enabled flag tied to activeTab === 1, creating overlapping fetch triggers.

workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[358-367]
workspaces/lightspeed/plugins/lightspeed/src/hooks/useNotebookSessions.ts[24-35]

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

### Issue description
Tab selection triggers `refetchNotebooks()` while also enabling the query, which can result in redundant requests.

### Issue Context
There are two fetch triggers: query enablement via `activeTab === 1` and manual `refetchNotebooks()`.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[325-367]
- workspaces/lightspeed/plugins/lightspeed/src/hooks/useNotebookSessions.ts[24-35]

ⓘ 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

@lokanandaprabhu lokanandaprabhu force-pushed the lightspeed-notebooks-updates branch from c76966f to da5dbb1 Compare March 13, 2026 09:43
Comment on lines +1117 to +1148
{hasNotebooks && (
<Button
variant="primary"
className={classes.notebooksAction}
icon={<PlusCircleIcon />}
>
{t('notebooks.empty.action')}
</Button>
)}
</div>
{!hasNotebooks ? (
<div className={classes.notebooksEmptyState}>
<CatalogIcon className={classes.notebooksIcon} />
<Typography
variant="h6"
className={classes.notebooksHeadingEmpty}
>
{t('notebooks.empty.title')}
</Typography>
<Typography
variant="body2"
color="textSecondary"
className={classes.notebooksDescription}
>
{t('notebooks.empty.description')}
</Typography>
<Button
variant="primary"
className={classes.notebooksActionEmpty}
>
{t('notebooks.empty.action')}
</Button>

Choose a reason for hiding this comment

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

Action required

1. Create button does nothing 🐞 Bug ✓ Correctness

The Notebooks panel renders “Create a new notebook” buttons without any onClick behavior, so the
primary call-to-action is non-functional.
Agent Prompt
### Issue description
The notebooks CTA buttons are clickable but have no behavior, making the primary action in the notebooks view non-functional.

### Issue Context
Both the header and empty-state CTAs render `<Button>` without `onClick`.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx[1117-1148]

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

Comment on lines +141 to +149
<DialogActions className={classes.dialogActions}>
<Button
variant="contained"
color="error"
className={classes.deleteButton}
onClick={handleDelete}
>
{t('notebooks.delete.action')}
</Button>

Choose a reason for hiding this comment

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

Action required

2. Delete spammable 🐞 Bug ⛯ Reliability

DeleteNotebookModal does not disable the Delete button during an in-flight mutation, allowing
multiple rapid clicks that can submit multiple DELETE requests.
Agent Prompt
### Issue description
The delete action can be triggered multiple times because the Delete button remains enabled while the async mutation is running.

### Issue Context
Conversation deletion already prevents this by disabling the confirm button using `isPending`; notebooks deletion should follow the same pattern.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/DeleteNotebookModal.tsx[89-158]
- workspaces/lightspeed/plugins/lightspeed/src/hooks/useDeleteNotebook.ts[27-42]
- workspaces/lightspeed/plugins/lightspeed/src/components/DeleteModal.tsx[43-48]
- workspaces/lightspeed/plugins/lightspeed/src/components/DeleteModal.tsx[107-114]

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

@lokanandaprabhu lokanandaprabhu force-pushed the lightspeed-notebooks-updates branch from da5dbb1 to 403832d Compare March 13, 2026 09:48
@sonarqubecloud
Copy link

@lokanandaprabhu
Copy link
Member Author

/cc @ShiranHi @its-mitesh-kumar

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant