Skip to content

Mobile support for the agent dashboard: PoC proposal #470

Description

@pat-s

I run a self-hosted libredesk instance and wanted to be able to triage tickets from my phone.
Rather than open a feature request, I built it and deployed it, so I am able to showcase the result directly instead of discussing about theoretical concepts.

I want to be upfront that I understand the current behaviour is deliberate, not an oversight.
The widget app uses width=device-width while the dashboard pins width=1280, initial-scale=0.29, and SmallScreenOverlay.vue exists with a scale(3) tuned specifically to cancel that out.
So the question here is not "you forgot about mobile", it is "would you consider changing your mind, and would you take a PR for it".

Related: #106 asked for this and was closed by the stale bot without a reply, so I could not tell what your position actually is.

What it looks like

Screenshots (based on v2.6.1):

Details Image Image Image

What works

The full triage loop on a phone, with no pinch-zooming: log in, reach an inbox via the drawer, read the conversation list, open a conversation and read the whole thread, write and send a reply, open an attachment, go back to the list.

How it is built

The interesting part is how little of this is new code.
Most of the machinery is already in the repo and simply unreachable while the viewport is pinned:

  • The mobile drawer already exists. shared-ui/components/ui/sidebar/Sidebar.vue renders a Sheet when isMobile, driven by the useMediaQuery('(max-width: 768px)') in SidebarProvider.vue, and the SidebarTriggers are already mounted in PageHeader.vue and ConversationList.vue. It never fires because the media query cannot match at a fixed 1280px layout viewport. The main blocker was collapsible="none" on the icon rail in App.vue, which short-circuits the Sheet branch.
  • The inbox router is already nested. router/index.js makes the conversation a real grandchild route with its own URL, so list-to-detail push navigation on mobile needed no router changes at all.
  • tailwind.config.cjs already maps h-screen to 100dvh.
  • DataTable.vue already uses [@media(hover:hover)] for touch, so I followed that existing pattern rather than inventing one.

The genuinely new work is the two nested ResizablePanelGroups in InboxLayout.vue and ConversationDetailView.vue.
Their minimum sizes are percentages of the window, so at 390px the thread pane computes to roughly 205px and the contact sidebar to roughly 117px.
That cannot be fixed with utility classes, so below the breakpoint the splitters are replaced by a route-driven single pane, and the contact sidebar becomes a Sheet driven by the existing CONVERSATION_SIDEBAR_TOGGLE emitter.

Everything is frontend-only.
No Go, no schema, no API changes.

If you are open to it

I would rather send this as a few reviewable PRs than one large diff.
Conveniently, most of it is desktop-neutral by construction and could land independently of the more opinionated inbox restructure:

  1. An isMobile composable, plus removing some scoped CSS in Sidebar.vue/App.vue that hardcodes desktop sidebar positioning and would misposition a SheetContent.
  2. Responsive insets and scrolling on DialogContent/AlertDialogContent, which currently go edge-to-edge with no max-h on a narrow viewport.
  3. Touch-visible variants of the actions that are currently opacity-0 group-hover:opacity-100 and therefore unreachable on touch: deleting a private note, downloading an attachment, editing a custom attribute, and the conversation-list selection checkbox that gates all bulk actions.
  4. The inbox layout restructure.
  5. Flipping the viewport meta and removing SmallScreenOverlay.vue.

Steps 1 to 3 are arguably worth having regardless of whether you want mobile, particularly step 3.

Happy to adjust the approach, split it differently, or drop it entirely if this is not a direction you want to go.
Thanks for libredesk either way!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions