Skip to content

T-10: Popover UI — workflow groups → jobs → web #227

@kirich1409

Description

@kirich1409

Description

Create GitHubIntegrationFeature/Views/GitHubStatusPopover.swift:

public struct GitHubStatusPopover: View {
    public struct State {
        public let branch: String
        public let status: CIStatusView
        public let workflows: [WorkflowGroup]
        public let pullRequest: GHPullRequestStub?
        public let branchHTMLURL: URL
        public let lastFetchedAt: Date?
    }
    public struct WorkflowGroup: Identifiable {
        public let id: Int64
        public let workflowName: String
        public let runs: [GHWorkflowRun]   // up to 5
    }
    public let state: State
    public let onOpenURL: (URL) -> Void
    public let onRefresh: () -> Void
    public let onSignInTapped: () -> Void
}

Layout

VStack inside ScrollView, width 360pt, maxHeight 400pt:

  1. Header HStack: "CI Status for \(branch)" + Spacer + relative timestamp "Updated Xs ago" + Refresh button (icon arrow.clockwise) → onRefresh.
  2. Error banner (if status == .error(err)): render bannerConfig(for: err) from T-14 — title/message/optional action (Sign in / Retry / SSO URL).
  3. Workflow sectionsForEach(workflows):
    • Section header: workflow name + badge icon (worst conclusion across runs)
    • Rows (max 5): run name, duration, relative age, status icon. .onTapGesture { onOpenURL(run.htmlURL) }, hover highlight.
  4. Pull Request section:
    • If pullRequest != nil: "Pull Request #\(number): \(title)" link → onOpenURL(pullRequest.htmlURL)
    • Else: "No PR for this branch" + "Create PR on GitHub" link → onOpenURL(\(branchHTMLURL)/../compare/\(branch)?expand=1). Wording explicit — this is a browser link, app never creates PR.
  5. Footer: "Open branch on GitHub"branchHTMLURL.

Empty state (no workflows, no error): "No CI runs yet for this branch".

Spec reference

See swarm-report/github-integration-decomposition.md#t-10. BA review corrected dependency — T-10 depends on T-8a + T-14 only, NOT T-9.

Relationships

Acceptance criteria

  • Four @Preview scenarios: multi-workflow+PR, empty (no runs), error (.forbidden(.saml)), no PR (Create PR link)
  • All clicks invoke onOpenURL (no direct NSWorkspace)
  • lastFetchedAt renders live relative ("Updated 30s ago" / "Updated 2m ago")
  • @Environment(\.accessibilityReduceMotion) respected
  • Every interactive element — accessibilityLabel + accessibilityHint
  • maxHeight 400pt + ScrollView on overflow (tested via preview with 10+ runs)
  • Tab-order = visual order

Complexity

M

Suggested agent

developer-workflow:swiftui-developer

Module / Layer

GitHubIntegrationFeature / UI (Views)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions