diff options
Diffstat (limited to 'Rune/ViewModels/DomainViewModel.swift')
| -rw-r--r-- | Rune/ViewModels/DomainViewModel.swift | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/Rune/ViewModels/DomainViewModel.swift b/Rune/ViewModels/DomainViewModel.swift new file mode 100644 index 0000000..efad5b9 --- /dev/null +++ b/Rune/ViewModels/DomainViewModel.swift @@ -0,0 +1,143 @@ +import Combine +import Foundation + +@MainActor +final class DomainViewModel: ObservableObject { + @Published private(set) var domains: [Domain] = [] + @Published private(set) var selectedDomain: Domain? + @Published private(set) var records: [DNSRecord] = [] + @Published private(set) var isLoadingDomains = false + @Published private(set) var isLoadingDetail = false + @Published private(set) var isLoadingRecords = false + @Published private(set) var isSaving = false + @Published var errorMessage: String? + + func reset() { + domains = [] + selectedDomain = nil + records = [] + isLoadingDomains = false + isLoadingDetail = false + isLoadingRecords = false + isSaving = false + errorMessage = nil + } + + func loadDomains(client: NjallaClient) async { + isLoadingDomains = true + defer { + isLoadingDomains = false + } + + do { + domains = try await client.listDomains().sorted { + $0.name.localizedCaseInsensitiveCompare($1.name) == .orderedAscending + } + errorMessage = nil + } catch is CancellationError { + return + } catch { + if (error as? URLError)?.code == .cancelled { + return + } + errorMessage = error.localizedDescription + } + } + + func loadDomainDetail(named name: String, client: NjallaClient) async { + isLoadingDetail = true + defer { + isLoadingDetail = false + } + + do { + let domain = try await client.getDomain(named: name) + selectedDomain = domain + if let index = domains.firstIndex(where: { $0.name == name }) { + domains[index] = domain + } + errorMessage = nil + } catch is CancellationError { + return + } catch { + if (error as? URLError)?.code == .cancelled { + return + } + errorMessage = error.localizedDescription + } + } + + func updateDomain(named name: String, request: DomainUpdateRequest, client: NjallaClient) async throws { + isSaving = true + defer { + isSaving = false + } + + let updated = try await client.editDomain(named: name, request: request) + selectedDomain = updated + if let index = domains.firstIndex(where: { $0.name == updated.name }) { + domains[index] = updated + } + errorMessage = nil + } + + func loadRecords(for domain: String, client: NjallaClient) async { + isLoadingRecords = true + defer { + isLoadingRecords = false + } + + do { + records = try await client.listRecords(for: domain).sorted { + ($0.name, $0.type, $0.id) < ($1.name, $1.type, $1.id) + } + errorMessage = nil + } catch is CancellationError { + return + } catch { + if (error as? URLError)?.code == .cancelled { + return + } + errorMessage = error.localizedDescription + } + } + + func addRecord(for domain: String, draft: DNSRecordDraft, client: NjallaClient) async throws { + isSaving = true + defer { + isSaving = false + } + + _ = try await client.addRecord(for: domain, draft: draft) + try await reloadRecords(for: domain, client: client) + errorMessage = nil + } + + func editRecord(for domain: String, recordID: String, draft: DNSRecordDraft, client: NjallaClient) async throws { + isSaving = true + defer { + isSaving = false + } + + _ = try await client.editRecord(for: domain, id: recordID, draft: draft) + try await reloadRecords(for: domain, client: client) + errorMessage = nil + } + + func removeRecord(_ record: DNSRecord, client: NjallaClient) async throws { + isSaving = true + defer { + isSaving = false + } + + try await client.removeRecord(record) + try await reloadRecords(for: record.domain, client: client) + errorMessage = nil + } + + private func reloadRecords(for domain: String, client: NjallaClient) async throws { + records = try await client.listRecords(for: domain).sorted { + ($0.name, $0.type, $0.id) < ($1.name, $1.type, $1.id) + } + } +} |
