diff options
| author | Christian Cleberg <[email protected]> | 2026-04-01 22:03:14 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-01 22:03:14 -0500 |
| commit | 902055d5eaa7f5512b76e22f57df3939f956181f (patch) | |
| tree | 08b7bb220b980adc9eaa9c195dc26e846707b311 /Hutch/Views/Tickets/TicketDetailViewModel.swift | |
| parent | 209155dc431cf70d9c8dba20625bab7e3b1a5085 (diff) | |
| download | hutch-2.7.0.tar.gz hutch-2.7.0.tar.bz2 hutch-2.7.0.zip | |
Add tracker management (delete/update, ACLs, labels)v2.7.0
- Add swipe actions (delete/edit) to tracker list
- Add tracker settings menu on detail screen
- Implement updateTracker and deleteTracker mutations
- Implement ACL management (updateUserACL, updateTrackerACL, deleteACL)
- Implement label management (createLabel, updateLabel, deleteLabel)
- Add dedicated UI flows for ACLs and labels
- Ensure state refresh after mutations
- Handle loading, errors, and destructive confirmations
Implements: https://todo.sr.ht/~ccleberg/Hutch/12
Diffstat (limited to 'Hutch/Views/Tickets/TicketDetailViewModel.swift')
| -rw-r--r-- | Hutch/Views/Tickets/TicketDetailViewModel.swift | 124 |
1 files changed, 54 insertions, 70 deletions
diff --git a/Hutch/Views/Tickets/TicketDetailViewModel.swift b/Hutch/Views/Tickets/TicketDetailViewModel.swift index 142c62b..999374b 100644 --- a/Hutch/Views/Tickets/TicketDetailViewModel.swift +++ b/Hutch/Views/Tickets/TicketDetailViewModel.swift @@ -3,10 +3,6 @@ import Foundation // MARK: - Response types (file-private to avoid @MainActor Decodable issues) private struct TicketDetailResponse: Decodable, Sendable { - let user: UserTrackerTicketWrapper -} - -private struct UserTrackerTicketWrapper: Decodable, Sendable { let tracker: TrackerTicketWrapper } @@ -85,10 +81,6 @@ private struct CreateLabelResponse: Decodable, Sendable { } private struct TrackerLabelsResponse: Decodable, Sendable { - let user: UserTrackerLabelsWrapper -} - -private struct UserTrackerLabelsWrapper: Decodable, Sendable { let tracker: TrackerLabelsWrapper } @@ -155,57 +147,55 @@ final class TicketDetailViewModel { // MARK: - Queries private static let detailQuery = """ - query ticket($owner: String!, $tracker: String!, $ticketId: Int!) { - user(username: $owner) { - tracker(name: $tracker) { - ticket(id: $ticketId) { - id - created - updated - title: subject - description: body - status - resolution - authenticity - submitter { canonicalName } - assignees { canonicalName } - labels { id name backgroundColor foregroundColor } - events { - results { - id - created - changes { - eventType - ... on Comment { - author { canonicalName } - text - authenticity - } - ... on StatusChange { - oldStatus - newStatus - } - ... on LabelUpdate { - labeler { canonicalName } - label { name } - } - ... on Assignment { - assigner { canonicalName } - assignee { canonicalName } - } - ... on TicketMention { - mentioned { id } - } - ... on UserMention { - mentioned { canonicalName } - } - ... on Created { - author { canonicalName } - } + query ticket($rid: ID!, $ticketId: Int!) { + tracker(rid: $rid) { + ticket(id: $ticketId) { + id + created + updated + title: subject + description: body + status + resolution + authenticity + submitter { canonicalName } + assignees { canonicalName } + labels { id name backgroundColor foregroundColor } + events { + results { + id + created + changes { + eventType + ... on Comment { + author { canonicalName } + text + authenticity + } + ... on StatusChange { + oldStatus + newStatus + } + ... on LabelUpdate { + labeler { canonicalName } + label { name } + } + ... on Assignment { + assigner { canonicalName } + assignee { canonicalName } + } + ... on TicketMention { + mentioned { id } + } + ... on UserMention { + mentioned { canonicalName } + } + ... on Created { + author { canonicalName } } } - cursor } + cursor } } } @@ -268,12 +258,10 @@ final class TicketDetailViewModel { """ private static let trackerLabelsQuery = """ - query trackerLabels($owner: String!, $tracker: String!) { - user(username: $owner) { - tracker(name: $tracker) { - labels { - results { id name backgroundColor foregroundColor } - } + query trackerLabels($rid: ID!) { + tracker(rid: $rid) { + labels { + results { id name backgroundColor foregroundColor } } } } @@ -302,13 +290,12 @@ final class TicketDetailViewModel { service: .todo, query: Self.detailQuery, variables: [ - "owner": ownerUsername, - "tracker": trackerName, + "rid": trackerRid, "ticketId": ticketId ], responseType: TicketDetailResponse.self ) - let payload = result.user.tracker.ticket + let payload = result.tracker.ticket ticket = TicketDetail( id: payload.id, created: payload.created, @@ -579,13 +566,10 @@ final class TicketDetailViewModel { let result = try await client.execute( service: .todo, query: Self.trackerLabelsQuery, - variables: [ - "owner": ownerUsername, - "tracker": trackerName - ], + variables: ["rid": trackerRid], responseType: TrackerLabelsResponse.self ) - trackerLabels = result.user.tracker.labels.results + trackerLabels = result.tracker.labels.results } catch { self.error = error.userFacingMessage } |
