Skip to content

Comments

refactor-frontend#64

Draft
petrubraha wants to merge 14 commits intoplaygroundfrom
60-exit-command
Draft

refactor-frontend#64
petrubraha wants to merge 14 commits intoplaygroundfrom
60-exit-command

Conversation

@petrubraha
Copy link
Owner

@petrubraha petrubraha commented Jan 23, 2026

decoupled the frontend from connection and transmission management.

Summary by CodeRabbit

  • New Features

    • Added chat command support: CLEAR (clears message history) and EXIT (closes the chat session).
    • Redesigned connection modal interface for improved connection setup workflow.
    • Restructured agenda and connection management components for better usability.
  • Improvements

    • Enhanced chat interface with streamlined message input and response handling.
    • Reorganized layout components for improved UI consistency and navigation.

✏️ Tip: You can customize this high-level summary in your review settings.

@petrubraha petrubraha linked an issue Jan 23, 2026 that may be closed by this pull request
@petrubraha petrubraha self-assigned this Jan 23, 2026
@petrubraha petrubraha linked an issue Jan 24, 2026 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review
📝 Walkthrough

Walkthrough

This pull request refactors the frontend UI component architecture, replacing legacy components (Agenda, ModalController, LeftPanel, ConnectionBox) with reorganized alternatives (Modal, AgendaFrame, ConnBox). Updates component APIs, moves PresenceChangeable interface, reorganizes modal views, and adjusts callback patterns throughout the component hierarchy and Layout.

Changes

Cohort / File(s) Summary
Component Removals
src/frontend/components/agenda.py, src/frontend/components/modal_controller.py, src/frontend/left_panel.py, src/frontend/components/members/interfaces.py
Removed legacy UI components and PresenceChangeable interface; ModalController deletion eliminates 135 lines of modal management and error handling logic.
Component Renames & Simplification
src/frontend/components/conn_box.py
Renamed ConnectionBox → ConnBox; simplified constructor from 4 parameters to 3, replacing dual callbacks (on_connection_close, on_agenda_rem) with single on_close.
Chat Component Refactor
src/frontend/components/chat.py
Removed PresenceChangeable inheritance; added exit_cmd_callback parameter and EXIT_CMD/CLEAR_CMD constants; renamed on_submit → add_req, on_response → add_res; updated message bubble width 400 → 300; refactored input handling to support special commands.
New Modal Management
src/frontend/modal.py
New Modal component replacing ModalController, subclasses ft.Container and PresenceChangeable; provides on_continue and switch_view methods for managing connection data entry.
New Agenda Panel
src/frontend/agenda_frame.py
New AgendaFrame component replacing Agenda, subclasses ft.Container; exposes add_box/rem_box methods matching prior Agenda interface.
Layout Reorganization
src/frontend/layout.py, src/frontend/chat_frame.py
Layout updated to accept add_conn_callback and instantiate Modal and AgendaFrame; ChatFrame.rem_chat signature simplified from rem_chat(chat) → rem_chat().
Modal Views Restructuring
src/frontend/modal_views/manual_view.py, src/frontend/modal_views/url_view.py, src/frontend/modal_views/__init__.py
Renamed ManualConnect → ManualView, UrlConnect → UrlView; moved from components.modals to modal_views package; updated import paths and constructor parameter types (ft.Button, ft.IconButton).
Package & Public API Updates
src/frontend/__init__.py, src/frontend/components/__init__.py, src/frontend/components/members/__init__.py
Updated public exports: removed Agenda/ConnectionBox/ModalController/LeftPanel from public surface; added AgendaFrame/Modal/ConnBox; moved PresenceChangeable to frontend.interfaces; reorganized Chat and ConnBox as primary exports.
Interface Relocation
src/frontend/interfaces.py
New file defining PresenceChangeable interface (show/hide methods) moved from components.members; provides visibility toggling for page controls.
Test Removals
tst/frontend/components/members/test_connection_box.py, tst/frontend/components/test_agenda.py, tst/frontend/components/test_modal_controller.py, tst/frontend/test_left_panel.py
Removed 207 lines of tests for deleted components (Agenda, ModalController, LeftPanel, ConnectionBox).
Test Additions & Updates
tst/frontend/test_agenda_frame.py, tst/frontend/test_modal.py, tst/frontend/components/test_conn_box.py
New tests for AgendaFrame, Modal, and ConnBox; validate initialization, callback wiring, and interaction patterns.
Test Migration
tst/frontend/components/test_chat.py, tst/frontend/test_chat_frame.py, tst/frontend/modal_views/test_manual_view.py, tst/frontend/modal_views/test_url_view.py, tst/frontend/test_layout.py, tst/frontend/test_interfaces.py
Updated existing test suites to reflect renamed classes (ManualConnect → ManualView, UrlConnect → UrlView), new method signatures (add_req, add_res, rem_chat()), and reorganized imports; adjusted mocks and patch targets.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 hop hop The old components fade away,
Modal, AgendaFrame arrive to stay,
ConnBox simplified, Chat refactored clean,
Architecture reorganized—a fresh scene!
PresenceChangeable moves to brighter places,
The frontend hops forward with new faces! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 39.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'refactor-frontend' is vague and uses a generic term that doesn't convey specific meaningful information about the changeset beyond indicating a refactoring effort. Consider a more specific title that highlights the main change, such as 'Reorganize frontend components and decouple from connection management' or 'Refactor frontend modal and agenda components'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 60-exit-command

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

@petrubraha petrubraha added the enhancement New feature or request label Jan 24, 2026
@petrubraha petrubraha marked this pull request as ready for review January 24, 2026 20:58
@petrubraha petrubraha moved this from Todo to In Progress in RC-application-planning Jan 24, 2026
Copy link

@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: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/frontend/modal_views/url_view.py (1)

54-67: Add process_redis_url to the core module's exports.

The function process_redis_url is defined in src/util.py but is not re-exported from src/core/__init__.py. The code calls core.process_redis_url(url) at line 63, which will fail with an AttributeError at runtime. Either import and add it to the __all__ list in core/__init__.py, or import directly from util in url_view.py.

🤖 Fix all issues with AI agents
In `@src/frontend/components/chat.py`:
- Around line 86-90: The CLEAR_CMD branch clears self.history_box.controls but
fails to refresh the UI; after calling self.history_box.controls.clear() in the
Chat.CLEAR_CMD handling path, call self.history_box.update() (same pattern used
in add_res) so the UI reflects the cleared history immediately; ensure you
update in the block where Chat.CLEAR_CMD is checked and keep the existing
logger.debug call.
- Around line 96-101: The request bubble is appended to history_box.controls but
never triggers a UI refresh; in the method that adds/prints requests (the code
using self._add_msg_bubble and appending to self.history_box.controls) call
self.history_box.update() immediately after appending the bubble (mirroring
add_res behavior) so the request appears without waiting for the response;
update the method that contains self._on_enter(req) / self._add_msg_bubble(...)
to include this call.

In `@src/frontend/layout.py`:
- Around line 19-25: The Layout constructor now requires an add_conn_callback
(Callable[[tuple], None]); update the call site where Layout() is instantiated
to pass the appropriate callback that accepts a connection tuple (e.g., an
existing add_conn_callback or a thin wrapper function). Locate the Layout class
__init__ in layout.py (which constructs Modal(add_conn_callback=...),
AgendaFrame(show_modal_callback=modal.show), ChatFrame()) and replace the no-arg
Layout() instantiation with Layout(add_conn_callback=your_callback) so the Modal
receives the callback; ensure the passed function matches the signature
Callable[[tuple], None].

In `@src/frontend/modal.py`:
- Around line 7-12: The Modal class docstring contains a typo: change "Though
text field(s) takes connection creation details..." to "Through text field(s)
take connection creation details..." (or "Through text field(s) the modal takes
connection creation details...") to correct grammar; update the docstring in the
Modal class definition (class Modal(ft.Container, PresenceChangeable))
accordingly so the description reads clearly.
- Around line 40-48: The docstring for on_continue is inconsistent with its type
hint: update the parameter description for conn_data in the on_continue method
to match the annotated type (tuple) instead of "arr", and optionally clarify the
tuple contents (e.g., connection parameters) so the docstring and the type hint
align; modify the docstring under the on_continue function accordingly.

In `@tst/frontend/components/test_chat.py`:
- Around line 62-69: The test fails because the EXIT command path returns
immediately after calling _exit_cmd_callback() and never awaits
cmd_input.focus(); update the implementation so that add_req (or
_exit_cmd_callback) calls and awaits self.cmd_input.focus() before returning
(mirroring the CLEAR path) so test_on_submit_exit's assertions on focus succeed;
ensure you modify the EXIT branch in add_req (or inside _exit_cmd_callback) to
await self.cmd_input.focus() after invoking _exit_cmd_callback() and before
returning.
🧹 Nitpick comments (11)
tst/frontend/modal_views/test_url_view.py (1)

6-6: Rename test class to TestUrlView for consistency.

The class under test was renamed from UrlConnect to UrlView, but the test class name remains TestUrlConnect. Update it to maintain naming consistency.

Suggested fix
-class TestUrlConnect(TestCase):
+class TestUrlView(TestCase):

Also update the patcher references on lines 11 and 18:

-        self.mock_process = TestUrlConnect.process_patcher.start()
+        self.mock_process = TestUrlView.process_patcher.start()
-        TestUrlConnect.process_patcher.stop()
+        TestUrlView.process_patcher.stop()
tst/frontend/components/test_conn_box.py (1)

20-23: Index-based control access is fragile.

Accessing self.box.content.controls[1] assumes the IconButton is always at index 1 in the Stack. If the control order changes, this test will break silently or fail unexpectedly. Consider adding a comment documenting this assumption.

Suggested improvement
     def test_on_close(self):
+        # IconButton is the second control in the Stack (index 1)
         icon_btn = self.box.content.controls[1]
         icon_btn.on_click()
         self.on_close.assert_called()
tst/frontend/test_agenda_frame.py (1)

35-42: Consider resetting mock between operations for precise verification.

test_rem_box calls add_box first, which triggers update(). The final assert_called() passes but doesn't specifically verify that rem_box triggered the update. Consider using reset_mock() or checking call count for clearer intent.

Suggested improvement
     def test_rem_box(self):
         mock_box = MagicMock()
         self.agenda_frame.add_box(mock_box)
+        self.agenda_frame.update.reset_mock()
         
         self.agenda_frame.rem_box(mock_box)
         
         self.assertNotIn(mock_box, self.agenda_frame.conn_boxes.controls)
         self.agenda_frame.update.assert_called()
src/frontend/components/chat.py (3)

72-72: Prefix unused event parameter with underscore.

The static analysis tool correctly flags event as unused. Prefix it with an underscore to indicate it's intentionally ignored.

Suggested fix
-    async def add_req(self, event) -> None:
+    async def add_req(self, _event) -> None:

92-94: EXIT command returns before focusing input.

When CLEAR is handled, focus() is called before returning. For EXIT, the method returns immediately without awaiting focus. While this may be intentional (the UI might close anyway), consider whether consistency is desired here.


22-22: Consider adding type hint for exit_cmd_callback.

The on_enter parameter has a type hint Callable[[str], None], but exit_cmd_callback is only typed as Callable. For consistency and clarity, consider specifying the full signature.

Suggested fix
-    def __init__(self, text: str, on_enter: Callable[[str], None], exit_cmd_callback: Callable) -> None:
+    def __init__(self, text: str, on_enter: Callable[[str], None], exit_cmd_callback: Callable[[], None]) -> None:
src/frontend/chat_frame.py (1)

48-53: Update docstring to reflect new signature.

The docstring still says "Removes the specified chat" but rem_chat no longer takes a chat parameter. Consider updating the description to match the new behavior.

Suggested fix
     def rem_chat(self) -> None:
         """
-        Removes the specified chat and reverts to the default layer.
+        Removes the current chat and reverts to the default layer.
         """
         self.content = self.default_layer
         self.update()
src/frontend/__init__.py (1)

8-11: Sort __all__ to satisfy Ruff (RUF022).

♻️ Proposed fix
-__all__ = ["ModalBase", "PresenceChangeable",
-           "Chat", "ConnBox",
-           "AgendaFrame", "ChatFrame", "Layout",
-           "Modal"]
+__all__ = ["AgendaFrame", "Chat", "ChatFrame", "ConnBox",
+           "Layout", "Modal", "ModalBase", "PresenceChangeable"]
tst/frontend/modal_views/test_manual_view.py (1)

4-12: Rename the test class to match ManualView.

♻️ Proposed fix
-class TestManualConnect(TestCase):
+class TestManualView(TestCase):
tst/frontend/test_layout.py (1)

25-28: Consider verifying the show_modal_callback argument passed to AgendaFrame.

Per the Layout implementation in src/frontend/layout.py (lines 22-23), AgendaFrame is initialized with show_modal_callback=modal.show. The current assertion only verifies that AgendaFrame was called, but not with the correct callback.

♻️ Proposed enhancement
 def test_init(self):
     self.mock_chatframe_cls.assert_called()
     self.mock_modal_cls.assert_called_with(add_conn_callback=self.add_conn_callback)
-    self.mock_agendaframe_cls.assert_called()
+    self.mock_agendaframe_cls.assert_called_with(
+        show_modal_callback=self.mock_modal_cls.return_value.show
+    )
src/frontend/modal.py (1)

14-38: Potential issue: referencing self.hide before superclass initialization.

On line 15, self.hide is passed to the close button's on_click handler before ft.Container.__init__ is called on line 27. While Python allows method references on partially constructed objects, this pattern can be fragile. In this case it works because hide is inherited from PresenceChangeable and doesn't depend on Container state at binding time, but consider initializing the container first for clarity.

♻️ Proposed reorder
 def __init__(self, add_conn_callback: Callable[[tuple], None]) -> None:
+    ft.Container.__init__(
+        self,
+        expand=True,
+        bgcolor=ft.Colors.BLACK_54,
+        alignment=ft.Alignment.CENTER,
+        visible=False
+    )
+    
     close_btn = ft.IconButton(ft.Icons.CLOSE, on_click=self.hide, tooltip="Close")
     url_view = UrlView(
         on_continue=self.on_continue,
         switch_btn=ft.Button("Switch to manual mode", on_click=self.switch_view),
         close_btn=close_btn
     )
     manual_view = ManualView(
         on_continue=self.on_continue,
         switch_btn=ft.Button("Switch to URL mode", on_click=self.switch_view),
         close_btn=close_btn
     )
     
-    ft.Container.__init__(
-        self,
-        content=url_view,
-        expand=True,
-        bgcolor=ft.Colors.BLACK_54,
-        alignment=ft.Alignment.CENTER,
-        visible=False
-    )
+    self.content = url_view
     self.is_manual = False
     self.url_view = url_view
     self.manual_view = manual_view
     self._add_conn_callback = add_conn_callback

Comment on lines +86 to +90
# Handle special cases.
if req.upper() == Chat.CLEAR_CMD:
self.history_box.controls.clear()
logger.debug("Cleaned chat history.")
return
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing update() call after clearing history.

After clearing history_box.controls, the UI won't refresh until the next interaction. The add_res method correctly calls self.history_box.update() after modifying controls, but this path does not.

Suggested fix
         if req.upper() == Chat.CLEAR_CMD:
             self.history_box.controls.clear()
+            self.history_box.update()
             logger.debug("Cleaned chat history.")
             return
📝 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
# Handle special cases.
if req.upper() == Chat.CLEAR_CMD:
self.history_box.controls.clear()
logger.debug("Cleaned chat history.")
return
# Handle special cases.
if req.upper() == Chat.CLEAR_CMD:
self.history_box.controls.clear()
self.history_box.update()
logger.debug("Cleaned chat history.")
return
🤖 Prompt for AI Agents
In `@src/frontend/components/chat.py` around lines 86 - 90, The CLEAR_CMD branch
clears self.history_box.controls but fails to refresh the UI; after calling
self.history_box.controls.clear() in the Chat.CLEAR_CMD handling path, call
self.history_box.update() (same pattern used in add_res) so the UI reflects the
cleared history immediately; ensure you update in the block where Chat.CLEAR_CMD
is checked and keep the existing logger.debug call.

Comment on lines +96 to 101
# Was not a special case, forwards the request to the network layer.
logger.debug(f"Frontend printing of the request: {req}.")
self._on_enter(req)
await self.cmd_input.focus()
self.cmd_input.value = ""

bubble = self._add_msg_bubble(req, ft.MainAxisAlignment.END, ft.Colors.BLUE_600)
self.history_box.controls.append(bubble)
logger.debug("Request printed.")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing update() after appending request bubble.

Similar to the CLEAR case, after appending a bubble to history_box.controls, there's no update() call. The add_res method calls self.history_box.update() after appending, but add_req does not. This inconsistency may cause the request bubble to not appear until the response arrives.

Suggested fix
         self._on_enter(req)
         bubble = self._add_msg_bubble(req, ft.MainAxisAlignment.END, ft.Colors.BLUE_600)
         self.history_box.controls.append(bubble)
+        self.history_box.update()
         logger.debug("Request printed.")
📝 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
# Was not a special case, forwards the request to the network layer.
logger.debug(f"Frontend printing of the request: {req}.")
self._on_enter(req)
await self.cmd_input.focus()
self.cmd_input.value = ""
bubble = self._add_msg_bubble(req, ft.MainAxisAlignment.END, ft.Colors.BLUE_600)
self.history_box.controls.append(bubble)
logger.debug("Request printed.")
# Was not a special case, forwards the request to the network layer.
logger.debug(f"Frontend printing of the request: {req}.")
self._on_enter(req)
bubble = self._add_msg_bubble(req, ft.MainAxisAlignment.END, ft.Colors.BLUE_600)
self.history_box.controls.append(bubble)
self.history_box.update()
logger.debug("Request printed.")
🤖 Prompt for AI Agents
In `@src/frontend/components/chat.py` around lines 96 - 101, The request bubble is
appended to history_box.controls but never triggers a UI refresh; in the method
that adds/prints requests (the code using self._add_msg_bubble and appending to
self.history_box.controls) call self.history_box.update() immediately after
appending the bubble (mirroring add_res behavior) so the request appears without
waiting for the response; update the method that contains self._on_enter(req) /
self._add_msg_bubble(...) to include this call.

Comment on lines +19 to 25
def __init__(self, add_conn_callback: Callable[[tuple], None]) -> None:
"""
Initializes the layout controls, including Agenda, ChatFrame, and ModalController.
Initializes the layout controls, including Agenda, ChatFrame, and Modal.
"""

agenda = Agenda()
modal = Modal(add_conn_callback=add_conn_callback)
agenda_frame = AgendaFrame(show_modal_callback=modal.show)
chat_frame = ChatFrame()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find Layout instantiations and confirm add_conn_callback is supplied.
rg -nP --type=py -C2 '\bLayout\s*\('

Repository: petru-braha/RC-application

Length of output: 931


Fix Layout() instantiation in src/main.py:47 to pass the required add_conn_callback parameter. This call currently has no arguments but the constructor now requires add_conn_callback: Callable[[tuple], None].

🤖 Prompt for AI Agents
In `@src/frontend/layout.py` around lines 19 - 25, The Layout constructor now
requires an add_conn_callback (Callable[[tuple], None]); update the call site
where Layout() is instantiated to pass the appropriate callback that accepts a
connection tuple (e.g., an existing add_conn_callback or a thin wrapper
function). Locate the Layout class __init__ in layout.py (which constructs
Modal(add_conn_callback=...), AgendaFrame(show_modal_callback=modal.show),
ChatFrame()) and replace the no-arg Layout() instantiation with
Layout(add_conn_callback=your_callback) so the Modal receives the callback;
ensure the passed function matches the signature Callable[[tuple], None].

Comment on lines +7 to +12
class Modal(ft.Container, PresenceChangeable):
"""
Though text field(s) takes connection creation details and forwards them to the reactor.
- url view - only one text field for the url
- manual view - the user has to insert the host, port, and other data
"""
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Minor typo in docstring.

The docstring has a typo: "Though text field(s)" should likely be "Through text field(s)".

📝 Proposed fix
 class Modal(ft.Container, PresenceChangeable):
     """
-    Though text field(s) takes connection creation details and forwards them to the reactor.
+    Through text field(s) takes connection creation details and forwards them to the reactor.
     - url view - only one text field for the url
     - manual view - the user has to insert the host, port, and other data
     """
📝 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
class Modal(ft.Container, PresenceChangeable):
"""
Though text field(s) takes connection creation details and forwards them to the reactor.
- url view - only one text field for the url
- manual view - the user has to insert the host, port, and other data
"""
class Modal(ft.Container, PresenceChangeable):
"""
Through text field(s) takes connection creation details and forwards them to the reactor.
- url view - only one text field for the url
- manual view - the user has to insert the host, port, and other data
"""
🤖 Prompt for AI Agents
In `@src/frontend/modal.py` around lines 7 - 12, The Modal class docstring
contains a typo: change "Though text field(s) takes connection creation
details..." to "Through text field(s) take connection creation details..." (or
"Through text field(s) the modal takes connection creation details...") to
correct grammar; update the docstring in the Modal class definition (class
Modal(ft.Container, PresenceChangeable)) accordingly so the description reads
clearly.

Comment on lines +40 to +48
def on_continue(self, conn_data: tuple) -> None:
"""
Forwards the connection data and closes the modal.

Args:
conn_data (arr): Data to instantiate the connection object.
"""
self._add_conn_callback(conn_data)
self.hide()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Docstring inconsistency: "arr" vs "tuple".

The docstring says conn_data (arr) but the type hint indicates tuple. Update for consistency.

📝 Proposed fix
     def on_continue(self, conn_data: tuple) -> None:
         """
         Forwards the connection data and closes the modal.

         Args:
-            conn_data (arr): Data to instantiate the connection object.
+            conn_data (tuple): Data to instantiate the connection object.
         """
📝 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
def on_continue(self, conn_data: tuple) -> None:
"""
Forwards the connection data and closes the modal.
Args:
conn_data (arr): Data to instantiate the connection object.
"""
self._add_conn_callback(conn_data)
self.hide()
def on_continue(self, conn_data: tuple) -> None:
"""
Forwards the connection data and closes the modal.
Args:
conn_data (tuple): Data to instantiate the connection object.
"""
self._add_conn_callback(conn_data)
self.hide()
🤖 Prompt for AI Agents
In `@src/frontend/modal.py` around lines 40 - 48, The docstring for on_continue is
inconsistent with its type hint: update the parameter description for conn_data
in the on_continue method to match the annotated type (tuple) instead of "arr",
and optionally clarify the tuple contents (e.g., connection parameters) so the
docstring and the type hint align; modify the docstring under the on_continue
function accordingly.

Comment on lines +62 to +69
def test_on_submit_exit(self):
self.chat.cmd_input.value = "EXIT"

asyncio.run(self.chat.add_req(None))

self.on_exit.assert_called()
self.on_enter.assert_not_called()
self.chat.cmd_input.focus.assert_called()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Test assertion may fail: EXIT command doesn't call focus().

Looking at src/frontend/components/chat.py lines 92-94, the EXIT command returns immediately after calling _exit_cmd_callback() without awaiting focus(). This test expects focus to be called, which will fail.

Either update the test to match the actual behavior, or update the implementation to call focus() before returning (for consistency with the CLEAR path).

Option 1: Update test to match implementation
     def test_on_submit_exit(self):
         self.chat.cmd_input.value = "EXIT"
         
         asyncio.run(self.chat.add_req(None))
         
         self.on_exit.assert_called()
         self.on_enter.assert_not_called()
-        self.chat.cmd_input.focus.assert_called()
+        self.chat.cmd_input.focus.assert_not_called()
Option 2: Update implementation to call focus (in chat.py)
         if req.upper() == Chat.EXIT_CMD:
+            await self.cmd_input.focus()
             self._exit_cmd_callback()
             return
📝 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
def test_on_submit_exit(self):
self.chat.cmd_input.value = "EXIT"
asyncio.run(self.chat.add_req(None))
self.on_exit.assert_called()
self.on_enter.assert_not_called()
self.chat.cmd_input.focus.assert_called()
def test_on_submit_exit(self):
self.chat.cmd_input.value = "EXIT"
asyncio.run(self.chat.add_req(None))
self.on_exit.assert_called()
self.on_enter.assert_not_called()
self.chat.cmd_input.focus.assert_not_called()
🤖 Prompt for AI Agents
In `@tst/frontend/components/test_chat.py` around lines 62 - 69, The test fails
because the EXIT command path returns immediately after calling
_exit_cmd_callback() and never awaits cmd_input.focus(); update the
implementation so that add_req (or _exit_cmd_callback) calls and awaits
self.cmd_input.focus() before returning (mirroring the CLEAR path) so
test_on_submit_exit's assertions on focus succeed; ensure you modify the EXIT
branch in add_req (or inside _exit_cmd_callback) to await self.cmd_input.focus()
after invoking _exit_cmd_callback() and before returning.

@petrubraha petrubraha changed the title frontend-refactor refactor: frontend Jan 24, 2026
@petrubraha petrubraha changed the title refactor: frontend refactor-frontend Jan 25, 2026
@petrubraha petrubraha changed the base branch from main to playground January 25, 2026 12:43
@petrubraha petrubraha marked this pull request as draft February 6, 2026 16:37
Copy link
Owner Author

@petrubraha petrubraha left a comment

Choose a reason for hiding this comment

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

this can't be merged.

Ran 146 tests in 0.278s

FAILED (errors=3)

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

Labels

enhancement New feature or request

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

exit-command clear-command

1 participant