diff options
| author | Christian Cleberg <[email protected]> | 2026-03-22 20:42:53 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-03-22 20:42:53 -0500 |
| commit | 82e54ad018ae5fa5cdf90c0d763e09e99bc0e933 (patch) | |
| tree | cafdbc8f4116af5cc6e0ca706e05ced599e26570 /Hutch/Views/Home/HomeView.swift | |
| parent | 1f8b7a23529462c3c332753d33810b5c9f692bbc (diff) | |
| download | hutch-82e54ad018ae5fa5cdf90c0d763e09e99bc0e933.tar.gz hutch-82e54ad018ae5fa5cdf90c0d763e09e99bc0e933.tar.bz2 hutch-82e54ad018ae5fa5cdf90c0d763e09e99bc0e933.zip | |
feat: swipe actions on tickets, pastes, builds, and home dashboard
Diffstat (limited to 'Hutch/Views/Home/HomeView.swift')
| -rw-r--r-- | Hutch/Views/Home/HomeView.swift | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/Hutch/Views/Home/HomeView.swift b/Hutch/Views/Home/HomeView.swift index 55ec41e..d3d370a 100644 --- a/Hutch/Views/Home/HomeView.swift +++ b/Hutch/Views/Home/HomeView.swift @@ -1,6 +1,7 @@ import SwiftUI struct HomeView: View { + @AppStorage(AppStorageKeys.swipeActionsEnabled) private var swipeActionsEnabled = true @Environment(AppState.self) private var appState @State private var viewModel: HomeViewModel? private let previewLimit = 4 @@ -109,6 +110,23 @@ struct HomeView: View { } label: { HomeAssignedTicketRow(ticket: ticket) } + .swipeActions(edge: .leading, allowsFullSwipe: true) { + if swipeActionsEnabled { + ticketLeadingSwipeAction(ticket, viewModel: viewModel) + } + } + .swipeActions(edge: .trailing, allowsFullSwipe: false) { + if swipeActionsEnabled { + Button { + Task { + await viewModel.unassignFromMe(ticket) + } + } label: { + Label("Unassign Me", systemImage: "person.badge.minus") + } + .tint(.orange) + } + } } } } header: { @@ -142,6 +160,19 @@ struct HomeView: View { } label: { HomeBuildRow(build: build) } + .swipeActions(edge: .leading, allowsFullSwipe: true) { + if swipeActionsEnabled, build.job.status.isCancellable { + Button { + Task { + await viewModel.cancelBuild(build) + } + } + label: { + Label("Cancel", systemImage: "xmark.circle") + } + .tint(.red) + } + } } } } header: { @@ -151,6 +182,32 @@ struct HomeView: View { } } + @ViewBuilder + private func ticketLeadingSwipeAction( + _ ticket: HomeAssignedTicket, + viewModel: HomeViewModel + ) -> some View { + if ticket.ticket.status.isOpen { + Button { + Task { + await viewModel.resolveTicket(ticket) + } + } label: { + Label("Resolve", systemImage: "checkmark.circle") + } + .tint(.green) + } else { + Button { + Task { + await viewModel.reopenTicket(ticket) + } + } label: { + Label("Reopen", systemImage: "arrow.uturn.backward") + } + .tint(.blue) + } + } + } private struct HomeInboxToolbarIcon: View { @@ -367,6 +424,7 @@ private struct HomeSectionActionHeader: View { private struct HomeAssignedTicketsListView: View { let viewModel: HomeViewModel + @AppStorage(AppStorageKeys.swipeActionsEnabled) private var swipeActionsEnabled = true var body: some View { List { @@ -382,6 +440,35 @@ private struct HomeAssignedTicketsListView: View { } label: { HomeAssignedTicketRow(ticket: ticket) } + .swipeActions(edge: .leading, allowsFullSwipe: true) { + if swipeActionsEnabled { + if ticket.ticket.status.isOpen { + Button { + Task { await viewModel.resolveTicket(ticket) } + } label: { + Label("Resolve", systemImage: "checkmark.circle") + } + .tint(.green) + } else { + Button { + Task { await viewModel.reopenTicket(ticket) } + } label: { + Label("Reopen", systemImage: "arrow.uturn.backward") + } + .tint(.blue) + } + } + } + .swipeActions(edge: .trailing, allowsFullSwipe: false) { + if swipeActionsEnabled { + Button { + Task { await viewModel.unassignFromMe(ticket) } + } label: { + Label("Unassign Me", systemImage: "person.badge.minus") + } + .tint(.orange) + } + } } if !viewModel.isLoadingAssignedTickets && viewModel.assignedTickets.isEmpty { |
