Skip to content

ui: mobile navigation drawer & theme variant refinements#45107

Merged
BunsDev merged 13 commits intomainfrom
ui/theme-variants
Mar 13, 2026
Merged

ui: mobile navigation drawer & theme variant refinements#45107
BunsDev merged 13 commits intomainfrom
ui/theme-variants

Conversation

@BunsDev
Copy link
Copy Markdown
Member

@BunsDev BunsDev commented Mar 13, 2026

Summary

Implements mobile navigation drawer, topnav/sidebar shell restructure, and chat model selection enhancements.

Changes

  • Mobile navigation drawer with refined theme variants
  • Topnav & sidebar shell aligned with reference layout
  • Chat model selection features in mobile view
  • Layout refactor across core CSS and render pipeline
  • Test coverage — 2 new test files + expanded existing tests

Files touched

15 files, +1,359 / -540 lines (5 commits)

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui size: XL maintainer Maintainer-authored PR labels Mar 13, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 637749f55d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-chat.ts Outdated
Comment thread ui/src/ui/app-render.helpers.ts Outdated
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 13, 2026

Greptile Summary

This PR delivers a mobile navigation drawer, a restructured topnav/sidebar shell, and a new in-header chat model picker with supporting test coverage across five areas.

Key changes:

  • Mobile drawer: shell-nav switches from a horizontal bottom rail to a position: fixed slide-over drawer controlled by state.navDrawerOpen and the new shell--nav-drawer-open class. A backdrop button closes it; setTab resets the flag on navigation.
  • Shell restructure: nav-groupnav-section, sidebar-headersidebar-shell__header/body/footer, new topnav-shell wrapper with topbar-nav-toggle. Sidebar drag-to-resize is removed.
  • Chat model picker: renderChatModelSelect / switchChatModel in app-render.helpers.ts, backed by chatModelOverrides (optimistic cache), chatModelCatalog, and resolveModelOverrideValue which now correctly prefers the local cache over stale server data.
  • Delete-confirm positioning: renderDeleteButton now accepts a side argument so the confirm popup appears on the correct side for user vs. assistant messages.
  • Tests: Two new files and many new cases cover the drawer, picker, and delete-confirm behaviour.

One logic issue was found: switchChatModel writes an optimistic chatModelOverrides entry before the RPC but never rolls it back when the call fails, leaving the picker in a permanently incorrect state after any network or server error.

Confidence Score: 3/5

  • Safe to merge after addressing the missing rollback in switchChatModel — all other changes are well-structured and well-tested.
  • The PR is large but coherent, has solid test coverage for the new features, and previously flagged issues (resolveModelOverrideValue priority, dispatchSlashCommand cache sync) have been resolved. The remaining concern — the optimistic chatModelOverrides write not being rolled back on sessions.patch failure — is a real user-facing bug: the model picker will show the wrong model indefinitely after a failed switch. This prevents a confident merge without the fix.
  • ui/src/ui/app-render.helpers.ts — specifically the switchChatModel error path (lines 436–448). ui/src/styles/layout.mobile.css has a duplicate selector (minor).
Prompt To Fix All With AI
This is a comment left during a code review.
Path: ui/src/styles/layout.mobile.css
Line: 223-236

Comment:
**Duplicate selector in same media query**

`.topnav-shell__actions` is declared twice inside the same `@media (max-width: 768px)` block — once for `width` / `justify-content` (line 223) and again for `gap` / `align-items` (line 233). Both sets of declarations apply (the cascade is additive), but having two separate rule sets for the same selector in the same scope makes it harder to trace which properties the element actually receives and is easy to leave in an inconsistent state on future edits. These should be consolidated into a single block:

```suggestion
  .topnav-shell__actions {
    width: 100%;
    justify-content: space-between;
    gap: 10px;
    align-items: stretch;
  }
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: ui/src/ui/app-render.helpers.ts
Line: 436-448

Comment:
**Optimistic override not rolled back on RPC failure**

`state.chatModelOverrides` is written optimistically before the `sessions.patch` call, but the `catch` block only records `state.lastError` — it never restores the previous value. If the RPC throws, the model picker permanently displays the user-selected model string while the server session still holds the old model. This silently shows stale UI until a full refresh or another successful patch.

The fix is to capture the previous override value before the optimistic write and restore it in the `catch` branch:

```ts
const prevOverride = state.chatModelOverrides[targetSessionKey];
state.chatModelOverrides = { ...state.chatModelOverrides, [targetSessionKey]: nextModel || null };
try {
  // ... existing request + refresh ...
} catch (err) {
  // Roll back so the picker reflects the actual server model.
  state.chatModelOverrides = { ...state.chatModelOverrides, [targetSessionKey]: prevOverride };
  state.lastError = `Failed to set model: ${String(err)}`;
}
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: fa65d9b

Comment thread ui/src/ui/app-chat.test.ts
Comment thread ui/src/ui/app-render.helpers.ts
Comment thread ui/src/ui/app-render.helpers.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fa65d9b7e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/styles/layout.mobile.css
Comment thread ui/src/ui/app-render.helpers.ts
Comment thread ui/src/styles/layout.mobile.css Outdated
Comment thread ui/src/ui/app-render.helpers.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8397128565

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.ts
@BunsDev BunsDev self-assigned this Mar 13, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eea1ab3c99

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.ts
Comment on lines +306 to +307
const navDrawerOpen = Boolean(state.navDrawerOpen && !chatFocus && !state.onboarding);
const navCollapsed = Boolean(state.settings.navCollapsed && !navDrawerOpen);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear drawer-open state when not in drawer viewport

The derived nav state keeps state.navDrawerOpen active regardless of viewport width, so if a user opens the drawer on tablet/mobile and then resizes to desktop, navCollapsed is forced false (settings.navCollapsed && !navDrawerOpen) even though desktop has no visible drawer toggle/backdrop to close it. In that state, the sidebar collapse control appears ineffective until some unrelated action (like tab navigation) resets the flag, which is a persistent navigation regression for responsive resize flows.

Useful? React with 👍 / 👎.

@BunsDev BunsDev force-pushed the ui/theme-variants branch from eea1ab3 to 9c34203 Compare March 13, 2026 14:41
@BunsDev BunsDev merged commit ca41473 into main Mar 13, 2026
30 checks passed
@BunsDev BunsDev deleted the ui/theme-variants branch March 13, 2026 14:44
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c342036d1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +331 to +334
// Prefer the local cache — it reflects in-flight patches before sessionsResult refreshes.
const cached = state.chatModelOverrides[state.sessionKey];
if (typeof cached === "string") {
return cached.trim();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Invalidate stale model override cache after reset flows

resolveModelOverrideValue always trusts chatModelOverrides before reading sessionsResult, but this cache is only written (in picker/slash-command paths) and never cleared when the session model is recomputed elsewhere; after a sessions.reset path (for example the chat "Clear history" action), the gateway recomputes model defaults, yet the picker can stay pinned to the old cached override and show the wrong active model until a full reload.

Useful? React with 👍 / 👎.

z-hao-wang pushed a commit to z-hao-wang/openclaw that referenced this pull request Mar 13, 2026
…penclaw#45107) thanks @BunsDev

## Summary

- Mobile navigation drawer with slide-over behavior at ≤1100px
- Topnav & sidebar shell restructure with brand eyebrow
- Chat model selection picker with optimistic caching + rollback
- Nav breakpoint gap fix (769–1100px toggle visibility)
- Skills page autofill pollution fix (autocomplete=off)
- Delete confirm popover positioning (left/right by role)
- Effective collapsed state propagation to nav items in drawer mode
- Duplicate CSS selector consolidation
- Session key race condition fixes in async model patching
- 2 new test files + expanded test coverage (23 tests)

Co-authored-by: Nova <nova@openclaw.ai>
frankekn pushed a commit to xinhuagu/openclaw that referenced this pull request Mar 14, 2026
…penclaw#45107) thanks @BunsDev

## Summary

- Mobile navigation drawer with slide-over behavior at ≤1100px
- Topnav & sidebar shell restructure with brand eyebrow
- Chat model selection picker with optimistic caching + rollback
- Nav breakpoint gap fix (769–1100px toggle visibility)
- Skills page autofill pollution fix (autocomplete=off)
- Delete confirm popover positioning (left/right by role)
- Effective collapsed state propagation to nav items in drawer mode
- Duplicate CSS selector consolidation
- Session key race condition fixes in async model patching
- 2 new test files + expanded test coverage (23 tests)

Co-authored-by: Nova <nova@openclaw.ai>
sbezludny pushed a commit to sbezludny/openclaw that referenced this pull request Mar 27, 2026
…penclaw#45107) thanks @BunsDev

## Summary

- Mobile navigation drawer with slide-over behavior at ≤1100px
- Topnav & sidebar shell restructure with brand eyebrow
- Chat model selection picker with optimistic caching + rollback
- Nav breakpoint gap fix (769–1100px toggle visibility)
- Skills page autofill pollution fix (autocomplete=off)
- Delete confirm popover positioning (left/right by role)
- Effective collapsed state propagation to nav items in drawer mode
- Duplicate CSS selector consolidation
- Session key race condition fixes in async model patching
- 2 new test files + expanded test coverage (23 tests)

Co-authored-by: Nova <nova@openclaw.ai>
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
…penclaw#45107) thanks @BunsDev

## Summary

- Mobile navigation drawer with slide-over behavior at ≤1100px
- Topnav & sidebar shell restructure with brand eyebrow
- Chat model selection picker with optimistic caching + rollback
- Nav breakpoint gap fix (769–1100px toggle visibility)
- Skills page autofill pollution fix (autocomplete=off)
- Delete confirm popover positioning (left/right by role)
- Effective collapsed state propagation to nav items in drawer mode
- Duplicate CSS selector consolidation
- Session key race condition fixes in async model patching
- 2 new test files + expanded test coverage (23 tests)

Co-authored-by: Nova <nova@openclaw.ai>
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…penclaw#45107) thanks @BunsDev

## Summary

- Mobile navigation drawer with slide-over behavior at ≤1100px
- Topnav & sidebar shell restructure with brand eyebrow
- Chat model selection picker with optimistic caching + rollback
- Nav breakpoint gap fix (769–1100px toggle visibility)
- Skills page autofill pollution fix (autocomplete=off)
- Delete confirm popover positioning (left/right by role)
- Effective collapsed state propagation to nav items in drawer mode
- Duplicate CSS selector consolidation
- Session key race condition fixes in async model patching
- 2 new test files + expanded test coverage (23 tests)

Co-authored-by: Nova <nova@openclaw.ai>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…penclaw#45107) thanks @BunsDev

## Summary

- Mobile navigation drawer with slide-over behavior at ≤1100px
- Topnav & sidebar shell restructure with brand eyebrow
- Chat model selection picker with optimistic caching + rollback
- Nav breakpoint gap fix (769–1100px toggle visibility)
- Skills page autofill pollution fix (autocomplete=off)
- Delete confirm popover positioning (left/right by role)
- Effective collapsed state propagation to nav items in drawer mode
- Duplicate CSS selector consolidation
- Session key race condition fixes in async model patching
- 2 new test files + expanded test coverage (23 tests)

Co-authored-by: Nova <nova@openclaw.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui maintainer Maintainer-authored PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant