summaryrefslogtreecommitdiff
path: root/Rune/ViewModels/DomainViewModel.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Rune/ViewModels/DomainViewModel.swift')
-rw-r--r--Rune/ViewModels/DomainViewModel.swift143
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)
+ }
+ }
+}