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 @@
1import Foundation
2import Testing
3@testable import Hutch
4
5struct 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}