Skip to content

Conversation

@andyjakubowski
Copy link
Contributor

@andyjakubowski andyjakubowski commented Oct 15, 2025

Ensures overflowing toolbar items get packed into an overflow popup toolbar.

Signed-off-by: Andy Jakubowski hello@andyjakubowski.com

Summary by CodeRabbit

  • Bug Fixes

    • Ensures the notebook picker triggers a resize after being attached so it sizes correctly and avoids initial misalignment, clipping, or overflow.
  • Style

    • Sets the dropdown to a fixed 120px width for consistent appearance.
  • Tests

    • Adds a comprehensive test suite validating rendering, selection behavior, edge cases, and UI updates.
  • Chores

    • Updates test-runner transform configuration and expands spell-check vocabulary.

Signed-off-by: Andy Jakubowski <hello@andyjakubowski.com>
@linear
Copy link

linear bot commented Oct 15, 2025

GRN-4946 Fix toolbar layout on file load

Ensures overflowing toolbar items get packed into an overflow popup toolbar.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 15, 2025

📝 Walkthrough

Walkthrough

  • NotebookPicker: added imports for Widget (@lumino/widgets) and Message/MessageLoop (@lumino/messaging); implemented onAfterAttach to post a ResizeMessage.UnknownSize to the parent via MessageLoop after attachment; changed the select styling from maxWidth to width: 120px.
  • jest.config.js: updated transformIgnorePatterns' esModules set (removed some @jupyter/ entries; added @jupyter, @microsoft, exenv-es6).
  • Tests: added src/__tests__/NotebookPicker.spec.ts which mounts NotebookPicker, simulates user selection, awaits framePromise-driven rendering, and asserts select/options rendering and fromJSON behavior (including handling invalid/empty metadata).
  • cspell.json: added "exenv" to the word list.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User / App
  participant NP as NotebookPicker (Widget)
  participant P as Parent Widget
  participant ML as MessageLoop

  U->>NP: attach to DOM
  activate NP
  NP->>NP: onAfterAttach()
  NP->>ML: postMessage(P, ResizeMessage.UnknownSize)
  deactivate NP

  activate ML
  ML->>P: deliver ResizeMessage.UnknownSize
  deactivate ML

  activate P
  P->>P: perform resize/layout pass
  deactivate P

  note right of NP #DDEBF7: Select uses width: 120px
Loading
sequenceDiagram
  autonumber
  actor T as Test (NotebookPicker.spec.ts)
  participant DOM as DOM
  participant NP as NotebookPicker
  participant Sim as simulate-event

  T->>NP: instantiate
  T->>DOM: attach NP
  T->>NP: wait framePromise / rendering
  activate NP
  NP->>DOM: render select/options
  deactivate NP

  T->>Sim: dispatch change event
  Sim->>NP: user selection
  NP->>NP: call fromJSON (if selection valid)
  T->>T: assert DOM & fromJSON calls
Loading

Possibly related PRs

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The pull request title mentions fixing the toolbar layout on file load, but the changeset focuses on NotebookPicker lifecycle hooks, message scheduling, testing, and configuration updates rather than toolbar behavior. The title does not correspond to any toolbar-related code and is therefore misleading. It should be updated to accurately summarize the modifications in NotebookPicker and related tests. Rename the title to reflect the actual modifications, for example “feat(notebook-picker): trigger resize on attach and add tests” to summarize the main changes to NotebookPicker and related tests.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15169a0 and 02c7ee0.

📒 Files selected for processing (1)
  • src/__tests__/NotebookPicker.spec.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-03T12:54:35.368Z
Learnt from: CR
PR: deepnote/vscode-extension#0
File: .github/instructions/interactiveWindow.instructions.md:0-0
Timestamp: 2025-09-03T12:54:35.368Z
Learning: Applies to src/interactive-window/**/*.ts : Add unit and integration tests for new features and modifications; include performance and cross-platform test coverage

Applied to files:

  • src/__tests__/NotebookPicker.spec.ts
📚 Learning: 2025-10-09T11:21:57.494Z
Learnt from: CR
PR: deepnote/vscode-deepnote#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-09T11:21:57.494Z
Learning: Applies to src/notebooks/deepnote/deepnoteNotebookSelector.ts : deepnoteNotebookSelector.ts implements UI selection logic for Deepnote notebooks

Applied to files:

  • src/__tests__/NotebookPicker.spec.ts
🧬 Code graph analysis (1)
src/__tests__/NotebookPicker.spec.ts (1)
src/components/NotebookPicker.tsx (1)
  • NotebookPicker (9-111)
🪛 ast-grep (0.39.6)
src/__tests__/NotebookPicker.spec.ts

[warning] 49-49: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: document.body.innerHTML = ''
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)


[warning] 99-99: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: document.body.innerHTML = ''
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: check_release
🔇 Additional comments (5)
src/__tests__/NotebookPicker.spec.ts (5)

1-14: LGTM!

Imports and test suite structure are clean and appropriate.


15-52: LGTM!

Setup and teardown are well-structured. Mocking onAfterAttach is appropriate to avoid null parent errors in the test environment.


54-60: LGTM!

Test correctly verifies select rendering and option population.


78-86: LGTM!

Test correctly validates that fromJSON is not called for invalid selections. Mock metadata properly includes both notebooks and notebook_names.


96-110: LGTM!

Test properly handles empty metadata edge case and verifies placeholder rendering.


Comment @coderabbitai help to get the list of available commands and usage tips.

Artmann
Artmann previously approved these changes Oct 15, 2025
@codecov
Copy link

codecov bot commented Oct 15, 2025

Codecov Report

❌ Patch coverage is 40.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.20%. Comparing base (2ff5a4c) to head (02c7ee0).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/components/NotebookPicker.tsx 40.00% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main      #31       +/-   ##
===========================================
+ Coverage   37.29%   50.20%   +12.90%     
===========================================
  Files          13       13               
  Lines         244      249        +5     
  Branches       26       26               
===========================================
+ Hits           91      125       +34     
+ Misses        153      119       -34     
- Partials        0        5        +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea98a58 and 5393cb3.

📒 Files selected for processing (1)
  • src/components/NotebookPicker.tsx (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-09T11:21:57.494Z
Learnt from: CR
PR: deepnote/vscode-deepnote#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-09T11:21:57.494Z
Learning: Applies to src/notebooks/deepnote/deepnoteNotebookSelector.ts : deepnoteNotebookSelector.ts implements UI selection logic for Deepnote notebooks

Applied to files:

  • src/components/NotebookPicker.tsx
📚 Learning: 2025-09-03T12:55:29.175Z
Learnt from: CR
PR: deepnote/vscode-extension#0
File: .github/instructions/ipywidgets.instructions.md:0-0
Timestamp: 2025-09-03T12:55:29.175Z
Learning: Applies to src/notebooks/controllers/notebookIPyWidgetCoordinator.ts : NotebookIPyWidgetCoordinator should manage per-notebook lifecycle, controller selection, webview attachment, and creation of CommonMessageCoordinator instances

Applied to files:

  • src/components/NotebookPicker.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Spell Check
  • GitHub Check: check_release
  • GitHub Check: build
🔇 Additional comments (2)
src/components/NotebookPicker.tsx (2)

6-7: LGTM!

Imports support the new lifecycle hook.


93-93: LGTM!

Fixed width stabilizes layout. Ellipsis handles overflow for long names.

Comment on lines +68 to +73
protected onAfterAttach(msg: Message): void {
super.onAfterAttach(msg);
requestAnimationFrame(() => {
MessageLoop.sendMessage(this.parent!, Widget.ResizeMessage.UnknownSize);
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard against null parent.

this.parent! will throw if no parent exists at attach time. Add a null check.

 protected onAfterAttach(msg: Message): void {
   super.onAfterAttach(msg);
   requestAnimationFrame(() => {
-    MessageLoop.sendMessage(this.parent!, Widget.ResizeMessage.UnknownSize);
+    if (this.parent) {
+      MessageLoop.sendMessage(this.parent, Widget.ResizeMessage.UnknownSize);
+    }
   });
 }
📝 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.

Suggested change
protected onAfterAttach(msg: Message): void {
super.onAfterAttach(msg);
requestAnimationFrame(() => {
MessageLoop.sendMessage(this.parent!, Widget.ResizeMessage.UnknownSize);
});
}
protected onAfterAttach(msg: Message): void {
super.onAfterAttach(msg);
requestAnimationFrame(() => {
if (this.parent) {
MessageLoop.sendMessage(this.parent, Widget.ResizeMessage.UnknownSize);
}
});
}
🤖 Prompt for AI Agents
In src/components/NotebookPicker.tsx around lines 68 to 73, the code uses a
non-null assertion this.parent! when sending a resize message which will throw
if parent is null; update the method to check that this.parent is non-null
before calling MessageLoop.sendMessage (e.g., if (this.parent) {
MessageLoop.sendMessage(this.parent, Widget.ResizeMessage.UnknownSize); }) and
remove the non-null assertion so the resize is only sent when a parent exists.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5393cb3 and 38d4300.

📒 Files selected for processing (2)
  • jest.config.js (1 hunks)
  • src/__tests__/NotebookPicker.spec.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-03T12:54:35.368Z
Learnt from: CR
PR: deepnote/vscode-extension#0
File: .github/instructions/interactiveWindow.instructions.md:0-0
Timestamp: 2025-09-03T12:54:35.368Z
Learning: Applies to src/interactive-window/**/*.ts : Add unit and integration tests for new features and modifications; include performance and cross-platform test coverage

Applied to files:

  • src/__tests__/NotebookPicker.spec.ts
📚 Learning: 2025-10-09T11:21:57.494Z
Learnt from: CR
PR: deepnote/vscode-deepnote#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-09T11:21:57.494Z
Learning: Applies to src/notebooks/deepnote/deepnoteNotebookSelector.ts : deepnoteNotebookSelector.ts implements UI selection logic for Deepnote notebooks

Applied to files:

  • src/__tests__/NotebookPicker.spec.ts
🪛 ast-grep (0.39.6)
src/__tests__/NotebookPicker.spec.ts

[warning] 49-49: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: document.body.innerHTML = ''
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)


[warning] 99-99: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: document.body.innerHTML = ''
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)

🪛 GitHub Actions: Build
src/__tests__/NotebookPicker.spec.ts

[warning] 1-1: Code style issues found in the above file. Run Prettier with --write to fix.

🪛 GitHub Actions: CI
src/__tests__/NotebookPicker.spec.ts

[warning] 1-1: Code style issues found in the above file. Run Prettier with --write to fix.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Spell Check
  • GitHub Check: check_release
🔇 Additional comments (1)
src/__tests__/NotebookPicker.spec.ts (1)

42-46: Override of onAfterAttach in tests is appropriate: in production NotebookPicker is added to JupyterLab’s shell via app.shell.add, so this.parent is never null.

Signed-off-by: Andy Jakubowski <hello@andyjakubowski.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
src/__tests__/NotebookPicker.spec.ts (2)

1-1: Run Prettier to fix formatting.

Pipeline detected code style issues. Run the formatter to ensure consistency.

#!/bin/bash
npx prettier --write src/__tests__/NotebookPicker.spec.ts

88-94: Use consistent event simulation pattern.

Direct property assignment plus simulate without event details differs from other tests. Use the same pattern for clarity.

Apply this diff:

   it('should update UI after selection', async () => {
     const select = document.querySelector('select') as HTMLSelectElement;
-    select.value = 'nb2';
-    simulate(select, 'change');
+    simulate(select, 'change', { target: { value: 'nb2' } });
     await framePromise();
     expect(select.value).toBe('nb2');
   });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38d4300 and 15169a0.

📒 Files selected for processing (2)
  • cspell.json (1 hunks)
  • src/__tests__/NotebookPicker.spec.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-03T12:54:35.368Z
Learnt from: CR
PR: deepnote/vscode-extension#0
File: .github/instructions/interactiveWindow.instructions.md:0-0
Timestamp: 2025-09-03T12:54:35.368Z
Learning: Applies to src/interactive-window/**/*.ts : Add unit and integration tests for new features and modifications; include performance and cross-platform test coverage

Applied to files:

  • src/__tests__/NotebookPicker.spec.ts
🧬 Code graph analysis (1)
src/__tests__/NotebookPicker.spec.ts (1)
src/components/NotebookPicker.tsx (1)
  • NotebookPicker (9-111)
🪛 ast-grep (0.39.6)
src/__tests__/NotebookPicker.spec.ts

[warning] 49-49: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: document.body.innerHTML = ''
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)


[warning] 99-99: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: document.body.innerHTML = ''
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Spell Check
  • GitHub Check: build
  • GitHub Check: check_release
🔇 Additional comments (4)
cspell.json (1)

42-42: LGTM!

Configuration change aligns with exenv-es6 package handling in jest config.

src/__tests__/NotebookPicker.spec.ts (3)

43-44: Good test pattern.

Overriding onAfterAttach avoids null parent errors in test environment while still validating component behavior.


54-60: LGTM!

Test correctly validates select element rendering and option count.


96-110: LGTM!

Test correctly handles empty metadata edge case by validating fallback placeholder option.

Signed-off-by: Andy Jakubowski <hello@andyjakubowski.com>
@andyjakubowski andyjakubowski merged commit 5d0e9b0 into main Oct 16, 2025
13 checks passed
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.

3 participants