Skip to content

Portal v3 task page — join the authored portal experience

Restyle and re-architect the customer task detail / completion page so a project with a published Studio portal presents one cohesive, branded experience from home page to task and back.

Goal

The task page is the last v3 surface still rendering the legacy visual system. A customer moving from a branded portal home (authored chrome, brand wash, themed hero, tokenized cards) into a task today gets: the shell's TopHeader instead of the portal nav, a plain white background instead of the theme wash, 2019-era white cards with hard shadows, --vendor-color (the legacy branding column) instead of the portal brand, and no route back to the portal's pages. This proposal makes the task page a first-class authored-chassis page.

Current state

  • pages/v3/private/pages/project/projectTask/ProjectTask.vue is a port of the legacy page: it still imports TaskOverview, TaskMobileDrawer, TaskReassign, and TaskAssignmentDialog from pages/private/…, and its styles are legacy (box-shadow: rgba(0,0,0,.12)/.24, white cards, --vendor-color buttons, $cp-break-point-* media queries instead of @container portal tiers).
  • authoredChrome.js documents the seam by name: the task detail page "has no authored chrome to replace it, so the shell keeps providing one." On a portal-published project this is exactly the double standard the customer sees.
  • The authored chassis (PortalLayoutShell + PortalNav + PortalFooter + portal-chassis.css) and the theme pipeline (themeToCssVars, usePortalPageBackground, PortalThemeKey) are all host-agnostic and already consumed by ProjectHome, Studio canvas, and previews. Nothing about them is page-specific — the task page can mount the same frame.
  • Navigation into a task comes from WidgetTaskChecklist rows and WidgetNextStep via adapter.openTaskprojectStore.selectNextTask(ref) → the existing v3.portal.project.task route. Routing needs no change.

Design direction

Mockups: three concepts + a shared completion state were explored (scratchpad task-page-mockups/, screenshots in the design thread). Recommendation:

  • Base = Concept A ("portal page"): full authored chassis (PortalNav, brand wash, PortalFooter); a slim context strip (back link, phase · task position, compressed phase segments, next-task action); a brand-gradient task band (hero-family styling, orb/gradient per theme hero_style) carrying eyebrow, title, status/owner/due meta; then a work column (about + steps cards) and a sticky rail (details card, comments card).
  • Concept B is the narrow-container behavior of A, not a separate build: below the lg container tier the rail stacks under the work column and the completion affordance becomes the sticky pill bar.
  • Concept C ("guided workspace", left checklist navigator + work/conversation tabs) is a candidate second iteration — it changes IA (kills prev/next in favor of direct navigation) and should be validated against real playbooks with many tasks before committing. Out of scope here.
  • Completion state: keep the store's transitionToFeedback flow, but the panel becomes a celebration card — check ring, phase progress ("6 of 8 in Configuration & training"), primary CTA to the canonical next task, ghost CTA back to project. Confetti stays.

Architecture

  1. Chrome claim + theme, same contract as ProjectHome. The task page resolves the published config through portalConfigPolicyStore.resolveConfig (request-shared, cached per project), claims useAuthoredChrome from the moment a fetch is in flight (the counted claim absorbs the task↔home route overlap), applies themeToCssVars on a .portal-themed root, and calls usePortalPageBackground for the wash.
  2. Extract the chassis-host pattern. ProjectHome already carries the resolve → claim → theme → shell composition inline; the task page would be its second copy. Extract a PortalChassisHost.vue (or composable usePortalChassisPage) owning: config resolution + loading gate, chrome claim, theme vars, PortalLayoutShell/PortalNav/account-menu wiring, and the no-config fallback slot. ProjectHome migrates onto it in the same PR so there is exactly one implementation.
  3. Brand token scope. The PrimeVue token re-point (--p-primary-color, button family → --portal-brand) currently lives on .portal-page-renderer. The task page's content is not a widget page, so extract that token block into a .portal-brand-scope class in portal-chassis.css (applied by both .portal-page-renderer and the task page root) rather than duplicating the list.
  4. Nav behavior on a task page. PortalNav renders with home-link and the portal's pages; selecting a page routes to project home with that page active (nav emit → router.push home + page id in state/query — small addition to the emit contract, the shell stays dumb).
  5. Steps engine reuse, not rebuild. TaskOverview (+ TaskSteps.js, the subtask/answer-path/forms logic) is the risk center. Phase 1 embeds it unchanged inside the new work card with a scoped restyle layer (tokens, row styling toward PortalTaskRow language). A later phase may rebuild the step rows natively on chassis primitives; that is deliberately not this proposal.
  6. Fallback stays legacy. A project without a published portal (or preview without config) keeps today's shell-chrome render. No change for v2-parity projects; the guard is resolveConfig's answer, mirroring ProjectHome's gate exactly.

Phases

  1. Chassis host extractionPortalChassisHost + ProjectHome migration; no visual change. Unit: chrome-claim behavior (mirror authoredChrome.test.js), fallback path, one-request sharing.
  2. Task page on the chassis — mount the host, add context strip + task band
    • work/rail grid; restyle comments card + details rail; kill legacy TaskNavBar visuals (module progress moves into the context strip). TaskOverview embedded with restyle layer. Container-query tiers, not viewport media queries.
  3. Completion state — celebration card w/ phase progress + next-task routing (uses existing selectNextTask/TaskCompletePanel emits).
  4. Mobile pass — narrow-tier stacking, sticky completion bar, comments below work (drawer retired at this tier if the stack reads well).
  5. Tests + seeds — component tests per phase; one Playwright happy path (open task from checklist → complete → celebration → next task) once the golden seed carries a published v5 portal (see note below).

Out of scope

  • Concept C's navigator-rail IA.
  • Rebuilding the steps/answer-path engine.
  • The Conversations-widget rollup (own proposal) — the task page keeps its task-scoped comments.
  • v2/v1 task pages.

Seed-data note

Local/CI seed portal documents currently published from the remove-sections branch are schema v6 (flat pages[].widgets); main's renderer and contract are v5 (pages[].sections[].widgets). Until PR #10842 merges, a fresh main checkout renders zero widgets for those seeded portals. Any e2e for this page must seed a v5 document (or land after #10842 and seed v6).

Internal documentation — gated behind Cloudflare Access.