krz/rune

an ios client for njalla

clone: git clone https://gitbay.org/krz/rune.git

v1.0.0: Rune/Views/Domains/RecordListView.swift · raw

 1import SwiftUI
 2
 3struct RecordListView: View {
 4    let domainName: String
 5    @ObservedObject var viewModel: DomainViewModel
 6    let client: NjallaClient
 7
 8    @State private var showingAddRecord = false
 9
10    var body: some View {
11        Group {
12            if viewModel.isLoadingRecords && viewModel.records.isEmpty {
13                ProgressView()
14            } else if viewModel.records.isEmpty {
15                ContentUnavailableView("No Records", systemImage: "list.bullet", description: Text("No DNS records for this domain."))
16            } else {
17                List(viewModel.records) { record in
18                    NavigationLink {
19                        RecordEditView(domainName: domainName, record: record, viewModel: viewModel, client: client)
20                    } label: {
21                        RecordRow(record: record)
22                    }
23                }
24                .listStyle(.insetGrouped)
25            }
26        }
27        .navigationTitle("DNS Records")
28        .navigationBarTitleDisplayMode(.inline)
29        .toolbar {
30            Button {
31                showingAddRecord = true
32            } label: {
33                Label("Add Record", systemImage: "plus")
34            }
35        }
36        .sheet(isPresented: $showingAddRecord) {
37            NavigationStack {
38                RecordAddView(domainName: domainName, viewModel: viewModel, client: client)
39            }
40        }
41        .task {
42            await viewModel.loadRecords(for: domainName, client: client)
43        }
44        .refreshable {
45            await viewModel.loadRecords(for: domainName, client: client)
46        }
47        .alert("API Error", isPresented: errorBinding) {
48            Button("OK", role: .cancel) {}
49        } message: {
50            Text(viewModel.errorMessage ?? "")
51        }
52    }
53
54    private var errorBinding: Binding<Bool> {
55        Binding(
56            get: { viewModel.errorMessage != nil },
57            set: { newValue in
58                if !newValue {
59                    viewModel.errorMessage = nil
60                }
61            }
62        )
63    }
64}
65
66private struct RecordRow: View {
67    let record: DNSRecord
68
69    var body: some View {
70        VStack(alignment: .leading, spacing: 4) {
71            Text("\(record.type) \(record.name)")
72                .font(.headline)
73            if let detail = [record.content, record.target].compactMap({ $0 }).first, !detail.isEmpty {
74                Text(detail)
75                    .font(.subheadline)
76                    .foregroundStyle(.secondary)
77            }
78        }
79        .padding(.vertical, 4)
80    }
81}