Skip to content

FEAT [GUI] Add Home landing page and fix empty-chat message#1750

Open
romanlutz wants to merge 4 commits into
microsoft:mainfrom
romanlutz:romanlutz/gui-home-landing-page
Open

FEAT [GUI] Add Home landing page and fix empty-chat message#1750
romanlutz wants to merge 4 commits into
microsoft:mainfrom
romanlutz:romanlutz/gui-home-landing-page

Conversation

@romanlutz
Copy link
Copy Markdown
Contributor

Description

The Co-PyRIT GUI dropped users straight into the chat view with no guidance, and the chat empty state showed a generic "Welcome to PyRIT" screen even when an attack was explicitly opened from History. That made it impossible to tell whether the attack had actually loaded (it just had zero stored messages, e.g. an errored or pending one).

This PR adds a proper Home landing view (now the default) and fixes the misleading chat empty state.

Home view

A new tab is prepended to the sidebar with a HomeRegular icon. The Home page contains:

  • A welcome hero.
  • A Labels card that reuses LabelsBar so users can review/update operator, operation, and any custom labels before kicking off an attack.
  • A Target card showing the active target (or an empty hint), with a button that jumps to the Target Configuration page.
  • A Recent operations grid: we fetch the last 50 attacks via attacksApi.listAttacks, group them client-side by the operation label, and render up to 5 most-recent operation cards. Each card lists the 3 most recent attacks for that operation, click-to-open. Loading, error, and empty states are all handled.

App.tsx is the central state container, so labels, active target, onNavigate, and onOpenAttack are shared between Home and Chat without duplication.

Chat empty state

MessageList.tsx no longer renders the "Welcome to PyRIT" screen on messages.length === 0. It now shows "There are no messages in this conversation yet." which reads correctly both for brand-new chats and for historical attacks with no stored messages.

Notable details

  • During screenshot capture I caught a latent layout bug: LabelsBar uses flex: 1 1 0 (sized for the horizontal chat ribbon) and collapsed to zero height inside Home's column-flex card. Fixed by wrapping it in a labelsRow flex container with a small min-height (commit 2).
  • Several existing App / e2e tests assumed Chat was the default view. They now navigate to the Chat tab first or assert against a stable sidebar selector (getByTitle("Chat")).
  • Two label-merging tests in App.test.tsx were racing the async initLabels effect against a view-change re-render that consumed the mockResolvedValueOnce override. They now assert on Home''s labels prop directly, no view switch required.

Tests and Documentation

  • New unit tests: Home.test.tsx (11 tests covering hero, target card, navigation, empty / loading / error / grouped data states, and the "open attack" callback).
  • Updated unit tests: App.test.tsx, Navigation.test.tsx, MessageList.test.tsx.
  • Updated e2e specs (chat, api, accessibility, errors) for the new default view.
  • Full frontend suite: 598/598 passing, npm run lint clean. Global coverage 92.95% / 86.14% / 91.62% / 95.34% (above the 85/85/90/90 thresholds).
  • No backend or notebook changes; JupyText not applicable.

Screenshots

Home view (dark, with seeded recent operations):

home-dark

Home view (light theme):

home-light

Home view with no attacks yet (empty Recent operations state):

home-empty-recent

Sidebar with the new Home button at the top:

sidebar-with-home

Chat empty state with the new copy (also shown for historical attacks with zero stored messages, which used to fall back to the misleading "Welcome to PyRIT" screen):

chat-empty-state

Same empty-state copy when an attack is opened from Home / History but has no messages:

chat-empty-historical-attack

romanlutz and others added 4 commits May 18, 2026 06:38
- Add a new Home view as the default landing page in Co-PyRIT GUI.
  The Home page shows a hero, the LabelsBar so users can set global
  labels (operator, operation), a Target card with a button to the
  Target Configuration page, and a Recent Operations grid that fetches
  the latest attacks via attacksApi.listAttacks and groups them by
  the operation label.

- Add 'home' to the ViewName union and prepend a Home button in the
  sidebar Navigation (uses HomeRegular icon).

- Replace MessageList's misleading "Welcome to PyRIT" empty state with
  "There are no messages in this conversation yet." so that opening a
  historical attack with zero stored messages reads correctly instead
  of looking like a brand-new chat.

- Update App, Navigation, MessageList unit tests and e2e specs that
  previously assumed chat was the default view.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
LabelsBar's root sets `flex: 1 1 0` which assumes a horizontal flex
parent. Inside Home's column-flex card the LabelsBar collapsed to
zero height so the operator/operation chips were invisible. Wrap
LabelsBar in a dedicated row container with an explicit min-height
so the chips render.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three Playwright e2e tests broke when the Home landing page replaced

Chat as the initial view:

- chat.spec.ts `should disable input when no target is active`: navigate

  to Chat before asserting the no-target-banner, since Home does not

  render that element.

- config.spec.ts `should enable chat input after a target is set`: same

  Chat navigation before the no-target-banner assertion.

- accessibility.spec.ts `should be navigable with keyboard`: wait for

  the Home sidebar button to render and dispatch the initial Tab through

  `body` so the focus advances into the DOM reliably under parallel

  worker load.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant