summaryrefslogtreecommitdiff
path: root/Rune/ViewModels/DomainViewModel.swift
blob: efad5b9c21add0c3450b1e508e52e6da979c0335 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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)
        }
    }
}