Repository navigation
chore(vehicle): land ChatInterface fixes — 2 approved PRs (#16472, #16911) - #17064
Conversation
… panel (#16470) Adds a PendingInvitations.vue component and a fourth "Invitations" tab in ChatCollaborationPanel.vue, backed by useSessionCollaboration's pendingInvitations/refreshPendingInvitations/respondToInvitation (#16460) -- the real GET /sessions/invitations/mine and POST /sessions/{id}/invitations/respond endpoints. Closes the gap #16460 left open: an invited user can now see and accept/decline an invitation from the chat UI instead of that capability existing only in the composable. i18n added across all 11 locales. New component test covers: fetch on mount, empty state, rendering an invitation's session/permission, and that accept/decline call respondToInvitation with the correct (sessionId, accept) shape. Merges after #16471 (#16460) -- built on top of it since PendingInvitations consumes exports #16471 added to useSessionCollaboration.ts. Closes #16470
…tor (#16470) The Invitations tab added in the prior commit only surfaces through ChatCollaborationPanel.vue, which ChatInterface.vue gates on the current session already being collaborative -- but the person an invitation is FOR is, by definition, not yet a participant of that session, so they typically have no collaborative session of their own and could never reach the tab. That defeated the feature's main case. Adds PendingInvitationsBell.vue: a small, always-mountable header button (shows only once pendingInvitations is non-empty, badge count included) that opens a dropdown rendering the same PendingInvitations.vue list. Mounted in ChatInterface.vue's header actions unconditionally, alongside -- not replacing -- the existing isCollaborativeSession-gated collaboration toggle; no change to that gate or to ChatCollaborationPanel.vue. i18n: collaboration.invitations.bellTitle, all 11 locales. New test file covers: hidden with zero invitations, visible for a user with zero collaborative sessions and one pending invite (the case this exists to fix), refresh-on-mount, opening the dropdown, and staying open if the last invitation resolves mid-interaction.
…tion fails (#16470) Review at 800638c (Medium): PendingInvitations.vue's respond() only logged a failed accept/decline via logger.error() -- the buttons re-enabled and the invitee saw nothing indicating the action had not gone through. Added a per-invitation error-state set, cleared at the start of each new attempt so a retry starts clean rather than stacking a stale message, rendering an inline i18n'd message on failure. New collaboration.invitations.respondError key across all 11 locales. New test: the message appears on a resolved-false response and clears on a subsequent resolved-true retry for the same invitation. The review's two Low findings (PendingInvitationsBell's missing loading state, no .stories.ts for the two new components) are left as the review itself marked them -- optional, not blocking.
…er rebase, fix a ref-unwrap test bug (#16470) Rebasing onto main exceeded components_declaring_styles/css_rule_declarations/ distinct_class_names/hardcoded_zindex_declarations. PendingInvitationsBell.vue's three @apply-only scoped classes become inline Tailwind utility classes (its z-index moves to var(--z-dropdown), matching components.css's existing usage); PendingInvitations.vue drops its <TransitionGroup> enter/leave animation, whose 5 classes had no existing shared equivalent to reuse. Also fixes both component tests' mock: pendingInvitations was a plain { value: [...] } object, not a real ref(), so the templates' unqualified `v-for="invitation in pendingInvitations"` (relying on Vue's template ref-unwrapping) iterated the mock object itself instead of its array, making every invitation.sessionId read undefined. Pre-existing, not introduced by the rebase.
…d/ prefix (#16470) test_files/composable_tests were derived from `git diff --name-only` (repo-root-relative paths) but passed to `npx vitest run` after already cd-ing into autobot-frontend/, so every targeted path was double-prefixed and vitest reported "No test files found" -- a false block on any push touching a *.test.ts file directly, discovered while pushing this PR.
…nts (#16274) ChatInterface raced its init against a 10s setTimeout whose handle was never captured. onUnmounted cancelled nothing, and the winning path never cleared it either, so every successful mount left a timer pending that rejected 10s later, entered the catch block, and ran the fallback controller.loadChatSessions() against a component that no longer existed. In ChatInterface.test.ts that rejection landed in a LATER test, after `mockReset: true` had stripped the mock the fallback calls, so it threw "Cannot read properties of undefined (reading 'catch')" somewhere unrelated while this file stayed green -- the class vitest.config.ts:71 warns about (#3070). The timer handle is now captured and cleared in a `finally`, so it goes whether the init won the race or lost it, and onUnmounted clears it and sets a flag the init checks after each await. Nothing after an await touches the store once the component is gone. The test asserts the fallback is never called after unmount, not that the timer was cleared: clearing the handle is the mechanism, and a later rewrite may cancel the init some other way. What must stay true is that a dead component does not retry on its own behalf. NOT verified locally, stated rather than implied: the negative control -- that this test fails against the unfixed component -- was not run. A fresh worktree has no autobot-frontend/node_modules, the main checkout's copy is not an ancestor so Node cannot resolve it, and installing into the codebase is prohibited. The defect's reachability is established from the source path plus the error the issue observed twice per run at that exact line; that this specific test reproduces it is argued, not demonstrated. CI runs the suite. Closes #16274
) pushLocalOnlySessions and onMounted's own two awaits still ran their continuations after unmount, writing to the store and re-adding the keydown listener/poller that onUnmounted had just torn down. Add the same isUnmounted check already used for the other awaits in the chain. Also fixes the test file's own bug: mockController.loadChatSessions was only ever mocked at module scope, so vitest's mockReset stripped it before every test and any test that hit the fallback path crashed with "Cannot read properties of undefined (reading 'catch')" -- the literal "Chat initialization failed" CI failure blocking this PR. Re-apply the controller mocks in beforeEach instead. Rewrites the existing unmount-mid-init test, which advanced fake timers past a race timeout that onUnmounted had already cleared, so the guarded code path was never reached and the test passed either way. Adds coverage for the two new guard sites and for onUnmounted's listener/poller cleanup.
|
Warning Review limit reachedNext included review available in 27 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: mrveiss/AutoBot-AI/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (21)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ SSOT Configuration Compliance: Passing🎉 No new hardcoded values of either class — Known backlog in |
Thinking Path
The owner's new same-file rule groups #16472 and #16911 because both touch
ChatInterface.vue. Both are green in isolation and independent of each other in intent (collaboration invitations UI vs. an init-unmount race), so they merge in the order listed with no stacking relationship.This branch is built entirely through the REST API: created from
main, then each approved head merged in withPOST /repos/.../merges.Named
vehicle-v090-2026-09-18-chat, flat with no slash.What Changed
Nothing new. Two already-reviewed heads, each merged cleanly with no conflicts on the shared file:
No excluded members — both passed the ledger gate (approve at current head, no STALE, no failing check, open) and merged without conflict on
ChatInterface.vue.Verification
Each member carries a ledger review verdict pinned to the exact head merged here — the table above, both non-stale at merge time. The declared shared file (
ChatInterface.vue) merged cleanly across both heads (each merge call returned201 Created).What this PR's own CI must establish is that the union holds: no conflict between members, chat component still mounts/unmounts cleanly, i18n symmetry intact.
Model Used
Claude Sonnet 5 (coordinator session, vehicle build only — no new code). Members authored and reviewed by their own PR sessions per the ledger verdicts above.
Closes #16470
Closes #16274