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:
- Header HStack:
"CI Status for \(branch)" + Spacer + relative timestamp "Updated Xs ago" + Refresh button (icon arrow.clockwise) → onRefresh.
- Error banner (if
status == .error(err)): render bannerConfig(for: err) from T-14 — title/message/optional action (Sign in / Retry / SSO URL).
- Workflow sections —
ForEach(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.
- 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.
- 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
Complexity
M
Suggested agent
developer-workflow:swiftui-developer
Module / Layer
GitHubIntegrationFeature / UI (Views)
Description
Create
GitHubIntegrationFeature/Views/GitHubStatusPopover.swift:Layout
VStack inside ScrollView, width 360pt, maxHeight 400pt:
"CI Status for \(branch)"+ Spacer + relative timestamp"Updated Xs ago"+ Refresh button (iconarrow.clockwise) →onRefresh.status == .error(err)): renderbannerConfig(for: err)from T-14 — title/message/optional action (Sign in / Retry / SSO URL).ForEach(workflows):.onTapGesture { onOpenURL(run.htmlURL) }, hover highlight.pullRequest != nil:"Pull Request #\(number): \(title)"link →onOpenURL(pullRequest.htmlURL)"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."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
@Previewscenarios: multi-workflow+PR, empty (no runs), error (.forbidden(.saml)), no PR (Create PR link)onOpenURL(no directNSWorkspace)lastFetchedAtrenders live relative ("Updated 30s ago"/"Updated 2m ago")@Environment(\.accessibilityReduceMotion)respectedaccessibilityLabel+accessibilityHintScrollViewon overflow (tested via preview with 10+ runs)Complexity
M
Suggested agent
developer-workflow:swiftui-developerModule / Layer
GitHubIntegrationFeature/ UI (Views)