Commit 24d9882997
24d9882997bb69cc74a719f3e721c479595d2637
parent: bdc1800126
Unsigned
cmc <hello@cleberg.net> · 2026-03-19 01:07 UTC
Omit resolution when reopening resolved tickets
Layout: unified · split
Hutch/Views/Tickets/TicketDetailView.swift
+1 −4
| @@ -71,10 +71,7 @@ struct TicketDetailView: View { |
| 71 | if ticket.status == .resolved { |
71 | if ticket.status == .resolved { |
| 72 | Button { |
72 | Button { |
| 73 | Task { |
73 | Task { |
| 74 | await viewModel.updateStatus( |
74 | await viewModel.updateStatus(status: .reported) |
| 75 | status: .reported, |
| |
| 76 | resolution: .unresolved |
| |
| 77 | ) |
| |
| 78 | } |
75 | } |
| 79 | } label: { |
76 | } label: { |
| 80 | SwiftUI.Label("Reopen", systemImage: "arrow.uturn.backward") |
77 | SwiftUI.Label("Reopen", systemImage: "arrow.uturn.backward") |
Hutch/Views/Tickets/TicketDetailViewModel.swift
+15 −5
| @@ -130,6 +130,19 @@ final class TicketDetailViewModel { |
| 130 | return lhs.created < rhs.created |
130 | return lhs.created < rhs.created |
| 131 | } |
131 | } |
| 132 | |
132 | |
| |
133 | static func statusUpdateInput( |
| |
134 | status: TicketStatus, |
| |
135 | resolution: TicketResolution? |
| |
136 | ) -> [String: any Sendable] { |
| |
137 | var input: [String: any Sendable] = [ |
| |
138 | "status": status.rawValue |
| |
139 | ] |
| |
140 | if status == .resolved, let resolution { |
| |
141 | input["resolution"] = resolution.rawValue |
| |
142 | } |
| |
143 | return input |
| |
144 | } |
| |
145 | |
| 133 | init(ownerUsername: String, trackerName: String, trackerId: Int, trackerRid: String, ticketId: Int, client: SRHTClient) { |
146 | init(ownerUsername: String, trackerName: String, trackerId: Int, trackerRid: String, ticketId: Int, client: SRHTClient) { |
| 134 | self.ownerUsername = ownerUsername |
147 | self.ownerUsername = ownerUsername |
| 135 | self.trackerName = trackerName |
148 | self.trackerName = trackerName |
| @@ -360,16 +373,13 @@ final class TicketDetailViewModel { |
| 360 | |
373 | |
| 361 | // MARK: - Ticket Actions |
374 | // MARK: - Ticket Actions |
| 362 | |
375 | |
| 363 | func updateStatus(status: TicketStatus, resolution: TicketResolution) async { |
376 | func updateStatus(status: TicketStatus, resolution: TicketResolution? = nil) async { |
| 364 | guard !isPerformingAction else { return } |
377 | guard !isPerformingAction else { return } |
| 365 | isPerformingAction = true |
378 | isPerformingAction = true |
| 366 | error = nil |
379 | error = nil |
| 367 | |
380 | |
| 368 | do { |
381 | do { |
| 369 | let input: [String: any Sendable] = [ |
382 | let input = Self.statusUpdateInput(status: status, resolution: resolution) |
| 370 | "status": status.rawValue, |
| |
| 371 | "resolution": resolution.rawValue |
| |
| 372 | ] |
| |
| 373 | _ = try await client.execute( |
383 | _ = try await client.execute( |
| 374 | service: .todo, |
384 | service: .todo, |
| 375 | query: Self.updateStatusMutation, |
385 | query: Self.updateStatusMutation, |
HutchTests/TicketDetailViewModelTests.swift
added
+30
| @@ -0,0 +1,30 @@ |
| |
1 | import Foundation |
| |
2 | import Testing |
| |
3 | @testable import Hutch |
| |
4 | |
| |
5 | struct TicketDetailViewModelTests { |
| |
6 | |
| |
7 | @Test |
| |
8 | @MainActor |
| |
9 | func reopenStatusInputOmitsResolution() { |
| |
10 | let input = TicketDetailViewModel.statusUpdateInput( |
| |
11 | status: .reported, |
| |
12 | resolution: .unresolved |
| |
13 | ) |
| |
14 | |
| |
15 | #expect(input["status"] as? String == TicketStatus.reported.rawValue) |
| |
16 | #expect(input["resolution"] == nil) |
| |
17 | } |
| |
18 | |
| |
19 | @Test |
| |
20 | @MainActor |
| |
21 | func resolveStatusInputIncludesResolution() { |
| |
22 | let input = TicketDetailViewModel.statusUpdateInput( |
| |
23 | status: .resolved, |
| |
24 | resolution: .fixed |
| |
25 | ) |
| |
26 | |
| |
27 | #expect(input["status"] as? String == TicketStatus.resolved.rawValue) |
| |
28 | #expect(input["resolution"] as? String == TicketResolution.fixed.rawValue) |
| |
29 | } |
| |
30 | } |