133 lines
4.3 KiB
Swift
133 lines
4.3 KiB
Swift
// CxLLM Studio — iOS Application
|
|
// Views/AWS/AWSView.swift — AWS DevOps dashboard for iOS
|
|
|
|
import SwiftUI
|
|
import CxAWS
|
|
|
|
struct AWSView: View {
|
|
@Environment(AWSService.self) private var aws
|
|
@State private var selectedSection: AWSSection = .overview
|
|
|
|
enum AWSSection: String, CaseIterable, Identifiable {
|
|
case overview, repos, pipelines, builds
|
|
var id: String { rawValue }
|
|
}
|
|
|
|
var body: some View {
|
|
List {
|
|
Picker("Section", selection: $selectedSection) {
|
|
ForEach(AWSSection.allCases) { s in
|
|
Text(s.rawValue.capitalized).tag(s)
|
|
}
|
|
}
|
|
.pickerStyle(.segmented)
|
|
.listRowBackground(Color.clear)
|
|
|
|
switch selectedSection {
|
|
case .overview: overviewSection
|
|
case .repos: reposSection
|
|
case .pipelines: pipelinesSection
|
|
case .builds: buildsSection
|
|
}
|
|
}
|
|
.task {
|
|
await aws.loadRepositories()
|
|
await aws.loadPipelines()
|
|
}
|
|
}
|
|
|
|
// MARK: - Overview
|
|
|
|
@ViewBuilder
|
|
private var overviewSection: some View {
|
|
Section("Status") {
|
|
LabeledContent("Connection") {
|
|
HStack {
|
|
Circle()
|
|
.fill(aws.isConnected ? .green : .red)
|
|
.frame(width: 8, height: 8)
|
|
Text(aws.isConnected ? "Connected" : "Offline")
|
|
}
|
|
}
|
|
LabeledContent("Region", value: aws.healthStatus?.region ?? "us-east-2")
|
|
LabeledContent("Repositories", value: "\(aws.repositories.count)")
|
|
LabeledContent("Pipelines", value: "\(aws.pipelines.count)")
|
|
}
|
|
|
|
if let error = aws.error {
|
|
Section("Error") {
|
|
Text(error)
|
|
.foregroundStyle(.red)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Repos
|
|
|
|
@ViewBuilder
|
|
private var reposSection: some View {
|
|
Section("CodeCommit Repositories") {
|
|
if aws.repositories.isEmpty {
|
|
ContentUnavailableView("No Repositories", systemImage: "chevron.left.forwardslash.chevron.right")
|
|
} else {
|
|
ForEach(aws.repositories.indices, id: \.self) { idx in
|
|
let repo = aws.repositories[idx]
|
|
VStack(alignment: .leading) {
|
|
Text(repo["repositoryName"] as? String ?? "Unknown")
|
|
.font(.headline)
|
|
Text(repo["repositoryId"] as? String ?? "")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Pipelines
|
|
|
|
@ViewBuilder
|
|
private var pipelinesSection: some View {
|
|
Section("CodePipeline") {
|
|
if aws.pipelines.isEmpty {
|
|
ContentUnavailableView("No Pipelines", systemImage: "arrow.triangle.branch")
|
|
} else {
|
|
ForEach(aws.pipelines.indices, id: \.self) { idx in
|
|
let pipeline = aws.pipelines[idx]
|
|
HStack {
|
|
VStack(alignment: .leading) {
|
|
Text(pipeline["name"] as? String ?? "Unknown")
|
|
.font(.headline)
|
|
Text("Version \(pipeline["version"] as? Int ?? 0)")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
Spacer()
|
|
Button("Start") {
|
|
Task {
|
|
try? await aws.startPipeline(pipeline["name"] as? String ?? "")
|
|
}
|
|
}
|
|
.buttonStyle(.bordered)
|
|
.tint(.green)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Builds
|
|
|
|
@ViewBuilder
|
|
private var buildsSection: some View {
|
|
Section("CodeBuild") {
|
|
Button {
|
|
Task { _ = try? await aws.startBuild("cxllm-studio-build") }
|
|
} label: {
|
|
Label("Start Build", systemImage: "hammer.fill")
|
|
}
|
|
.buttonStyle(.borderedProminent)
|
|
}
|
|
}
|
|
}
|