Skip to content

fix(workspace): Overview layout — activity + recent work share a 50/50 row, asks move below, avatars get an edge #2169

Description

@trinity-ability

Summary

Three layout/polish defects on the Workspace client surface, all in the agent page Overview and the shared avatar:

  1. The two-column split is conditional on data. In PortalAgentPage.vue the Overview grid is <div class="mb-6 grid gap-6" :class="{ 'lg:grid-cols-2': asks.length }"> — the second column only exists when the agent has open asks. An agent with nothing waiting collapses to a single stacked column, so the page reflows into a different shape depending on whether a transient operator-queue item happens to be open. The structure should be stable; only the content should vary.

  2. Wrong things are sharing the row, in the wrong order. Today the row is Waiting on you (left) | Recent work (right), with the activity chart sitting alone above in a max-w-2xl section. The intended layout is: activity chart and recent work share one 50/50 row, and asks ("Waiting on you") move below that row, full width, rendered only when there are asks.

  3. The agent avatar has no edge. PortalAvatar.vue renders a bare rounded-full span with no border. Against the sidebar and chat backgrounds — and especially for image avatars whose own edges are light — the avatar bleeds into the surface. It needs a thin border in both places it appears (sidebar roster and chat rows), which is one change in the shared component.

Context

Follow-up to #2161, which restructured this Overview (moved asks into the grid, reused the shared chart). The layout that landed keys its column count off asks.length, which is exactly the instability being reported here. Same file family, same reviewer context.

Target layout:

┌───────────────────────────┬───────────────────────────┐
│ Activity · last {window}  │ Recent work               │   <- always two columns
└───────────────────────────┴───────────────────────────┘
┌───────────────────────────────────────────────────────┐
│ Waiting on you                                        │   <- only when asks.length
└───────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────┐
│ Your chats with {agent}                               │
└───────────────────────────────────────────────────────┘

Note that the target layout resolves the stability complaint by construction: both columns of the top row (activity, recent work) always exist and already have their own empty states ("No activity in this window." / "Nothing yet."), so the split never has to collapse.

Acceptance Criteria

  • The Overview top row is a 50/50 two-column grid holding activity chart (left) and Recent work (right); the column count does not depend on asks.length or on either section having data

  • Both columns render their existing empty states in place rather than collapsing the grid — an agent with no executions and no activity still shows two columns

  • "Waiting on you" moves below that row, full width, and is rendered only when asks.length > 0 (no empty-state placeholder — an agent with nothing waiting should not advertise the section)

  • The activity section's max-w-2xl constraint is removed or re-scoped so the chart fills its column

  • The grid collapses to a single stacked column below the xl breakpoint (narrow viewports keep today's stacking behaviour) — layout stability applies within a breakpoint, not across them

    Amended from lg to xl during planning, on measurement. lg was written from intent, not arithmetic. At 1024px, dropping the activity section's max-w-2xl and splitting 50/50 takes the chart from 672px to 332px (sidebar w-72 + px-6 + gap-6) — the 30-day x-axis truncates to nothing and the 9-bucket legend wraps to 3–5 lines. StackedBarChart is pure CSS/flexbox, so the theme criterion below would still pass while the left column became unreadable. Recorded here so a later reader does not "fix" it back to lg.

  • PortalAvatar.vue renders a thin border on every instance, visible in both light and dark themes, using semantic tokens (no raw palette classes, no hardcoded hex)

  • The border does not change the component's outer footprint or clip the image fill — verify the avatar still aligns in the sidebar roster rows and the chat rows at every size it is used with

  • Verified in the browser on the agent page in both themes: with asks and without, with executions and without

Technical Notes

  • src/frontend/src/components/portal/PortalAgentPage.vue — the Overview <template v-else-if="tab === 'overview'"> block holds the activity <section class="mb-6 max-w-2xl">, the conditional grid, and the chats section
  • src/frontend/src/components/portal/PortalAvatar.vue — single shared component; both the sidebar (PortalSidebar.vue) and chat (PortalChatRow.vue / PortalConversation.vue) consume it, so the border is one edit, not three
  • Read docs/memory/design-system-contract.md before touching either file (semantic tokens only, both themes first-class, layout stability)
  • No backend change; no new endpoint. Pure frontend layout.

Planning decision — mobile ask-priority (recorded, reversible)

Moving "Waiting on you" below the row applies at every breakpoint, so on a stacked narrow viewport the asks sit under activity + recent work. This was raised as a blocking objection during plan review and is implemented as specified — the layout was an explicit instruction and an acceptance criterion is not the planner's to overrule.

Mitigations already present: the section is conditional (absent when there are no asks) and the Overview tab carries a count badge. The costed alternative (a ~3-line mobile-only order swap) is noted in the PR body so it can be reversed in one commit if the stacked ordering proves wrong in use.

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions