wip
This commit is contained in:
@@ -165,4 +165,36 @@ class TaskApi(private val client: HttpClient = ApiClient.httpClient) {
|
|||||||
ApiResult.Error(e.message ?: "Unknown error occurred")
|
ApiResult.Error(e.message ?: "Unknown error occurred")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun archiveTask(token: String, id: Int): ApiResult<TaskCancelResponse> {
|
||||||
|
return try {
|
||||||
|
val response = client.post("$baseUrl/tasks/$id/archive/") {
|
||||||
|
header("Authorization", "Token $token")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status.isSuccess()) {
|
||||||
|
ApiResult.Success(response.body())
|
||||||
|
} else {
|
||||||
|
ApiResult.Error("Failed to archive task", response.status.value)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
ApiResult.Error(e.message ?: "Unknown error occurred")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun unarchiveTask(token: String, id: Int): ApiResult<TaskCancelResponse> {
|
||||||
|
return try {
|
||||||
|
val response = client.post("$baseUrl/tasks/$id/unarchive/") {
|
||||||
|
header("Authorization", "Token $token")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status.isSuccess()) {
|
||||||
|
ApiResult.Success(response.body())
|
||||||
|
} else {
|
||||||
|
ApiResult.Error("Failed to unarchive task", response.status.value)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
ApiResult.Error(e.message ?: "Unknown error occurred")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ fun TaskCard(
|
|||||||
onEditClick: () -> Unit,
|
onEditClick: () -> Unit,
|
||||||
onCancelClick: (() -> Unit)?,
|
onCancelClick: (() -> Unit)?,
|
||||||
onUncancelClick: (() -> Unit)?,
|
onUncancelClick: (() -> Unit)?,
|
||||||
onMarkInProgressClick: (() -> Unit)? = null
|
onMarkInProgressClick: (() -> Unit)? = null,
|
||||||
|
onArchiveClick: (() -> Unit)? = null,
|
||||||
|
onUnarchiveClick: (() -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
@@ -356,6 +358,49 @@ fun TaskCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Archive/Unarchive button row
|
||||||
|
if (task.archived) {
|
||||||
|
if (onUnarchiveClick != null) {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
OutlinedButton(
|
||||||
|
onClick = onUnarchiveClick,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
shape = RoundedCornerShape(12.dp),
|
||||||
|
colors = ButtonDefaults.outlinedButtonColors(
|
||||||
|
contentColor = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Unarchive,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(18.dp)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
|
Text("Unarchive")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (onArchiveClick != null) {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
OutlinedButton(
|
||||||
|
onClick = onArchiveClick,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
shape = RoundedCornerShape(12.dp),
|
||||||
|
colors = ButtonDefaults.outlinedButtonColors(
|
||||||
|
contentColor = MaterialTheme.colorScheme.outline
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Archive,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(18.dp)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
|
Text("Archive")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ fun TaskKanbanView(
|
|||||||
onEditTask: (TaskDetail) -> Unit,
|
onEditTask: (TaskDetail) -> Unit,
|
||||||
onCancelTask: ((TaskDetail) -> Unit)?,
|
onCancelTask: ((TaskDetail) -> Unit)?,
|
||||||
onUncancelTask: ((TaskDetail) -> Unit)?,
|
onUncancelTask: ((TaskDetail) -> Unit)?,
|
||||||
onMarkInProgress: ((TaskDetail) -> Unit)?
|
onMarkInProgress: ((TaskDetail) -> Unit)?,
|
||||||
|
onArchiveTask: ((TaskDetail) -> Unit)?,
|
||||||
|
onUnarchiveTask: ((TaskDetail) -> Unit)?
|
||||||
) {
|
) {
|
||||||
val pagerState = rememberPagerState(pageCount = { 4 })
|
val pagerState = rememberPagerState(pageCount = { 4 })
|
||||||
|
|
||||||
@@ -55,7 +57,9 @@ fun TaskKanbanView(
|
|||||||
onEditTask = onEditTask,
|
onEditTask = onEditTask,
|
||||||
onCancelTask = onCancelTask,
|
onCancelTask = onCancelTask,
|
||||||
onUncancelTask = onUncancelTask,
|
onUncancelTask = onUncancelTask,
|
||||||
onMarkInProgress = onMarkInProgress
|
onMarkInProgress = onMarkInProgress,
|
||||||
|
onArchiveTask = onArchiveTask,
|
||||||
|
onUnarchiveTask = null
|
||||||
)
|
)
|
||||||
1 -> TaskColumn(
|
1 -> TaskColumn(
|
||||||
title = "In Progress",
|
title = "In Progress",
|
||||||
@@ -67,7 +71,9 @@ fun TaskKanbanView(
|
|||||||
onEditTask = onEditTask,
|
onEditTask = onEditTask,
|
||||||
onCancelTask = onCancelTask,
|
onCancelTask = onCancelTask,
|
||||||
onUncancelTask = onUncancelTask,
|
onUncancelTask = onUncancelTask,
|
||||||
onMarkInProgress = null
|
onMarkInProgress = null,
|
||||||
|
onArchiveTask = onArchiveTask,
|
||||||
|
onUnarchiveTask = null
|
||||||
)
|
)
|
||||||
2 -> TaskColumn(
|
2 -> TaskColumn(
|
||||||
title = "Done",
|
title = "Done",
|
||||||
@@ -79,7 +85,9 @@ fun TaskKanbanView(
|
|||||||
onEditTask = onEditTask,
|
onEditTask = onEditTask,
|
||||||
onCancelTask = null,
|
onCancelTask = null,
|
||||||
onUncancelTask = null,
|
onUncancelTask = null,
|
||||||
onMarkInProgress = null
|
onMarkInProgress = null,
|
||||||
|
onArchiveTask = onArchiveTask,
|
||||||
|
onUnarchiveTask = null
|
||||||
)
|
)
|
||||||
3 -> TaskColumn(
|
3 -> TaskColumn(
|
||||||
title = "Archived",
|
title = "Archived",
|
||||||
@@ -91,7 +99,9 @@ fun TaskKanbanView(
|
|||||||
onEditTask = onEditTask,
|
onEditTask = onEditTask,
|
||||||
onCancelTask = null,
|
onCancelTask = null,
|
||||||
onUncancelTask = null,
|
onUncancelTask = null,
|
||||||
onMarkInProgress = null
|
onMarkInProgress = null,
|
||||||
|
onArchiveTask = null,
|
||||||
|
onUnarchiveTask = onUnarchiveTask
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +119,9 @@ private fun TaskColumn(
|
|||||||
onEditTask: (TaskDetail) -> Unit,
|
onEditTask: (TaskDetail) -> Unit,
|
||||||
onCancelTask: ((TaskDetail) -> Unit)?,
|
onCancelTask: ((TaskDetail) -> Unit)?,
|
||||||
onUncancelTask: ((TaskDetail) -> Unit)?,
|
onUncancelTask: ((TaskDetail) -> Unit)?,
|
||||||
onMarkInProgress: ((TaskDetail) -> Unit)?
|
onMarkInProgress: ((TaskDetail) -> Unit)?,
|
||||||
|
onArchiveTask: ((TaskDetail) -> Unit)?,
|
||||||
|
onUnarchiveTask: ((TaskDetail) -> Unit)?
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -202,6 +214,12 @@ private fun TaskColumn(
|
|||||||
} else null,
|
} else null,
|
||||||
onMarkInProgressClick = if (onMarkInProgress != null) {
|
onMarkInProgressClick = if (onMarkInProgress != null) {
|
||||||
{ onMarkInProgress(task) }
|
{ onMarkInProgress(task) }
|
||||||
|
} else null,
|
||||||
|
onArchiveClick = if (onArchiveTask != null) {
|
||||||
|
{ onArchiveTask(task) }
|
||||||
|
} else null,
|
||||||
|
onUnarchiveClick = if (onUnarchiveTask != null) {
|
||||||
|
{ onUnarchiveTask(task) }
|
||||||
} else null
|
} else null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,6 +247,20 @@ fun AllTasksScreen(
|
|||||||
viewModel.loadTasks()
|
viewModel.loadTasks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onArchiveTask = { task ->
|
||||||
|
viewModel.archiveTask(task.id) { success ->
|
||||||
|
if (success) {
|
||||||
|
viewModel.loadTasks()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onUnarchiveTask = { task ->
|
||||||
|
viewModel.unarchiveTask(task.id) { success ->
|
||||||
|
if (success) {
|
||||||
|
viewModel.loadTasks()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -456,6 +456,20 @@ fun ResidenceDetailScreen(
|
|||||||
residenceViewModel.loadResidenceTasks(residenceId)
|
residenceViewModel.loadResidenceTasks(residenceId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onArchiveTask = { task ->
|
||||||
|
taskViewModel.archiveTask(task.id) { success ->
|
||||||
|
if (success) {
|
||||||
|
residenceViewModel.loadResidenceTasks(residenceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onUnarchiveTask = { task ->
|
||||||
|
taskViewModel.unarchiveTask(task.id) { success ->
|
||||||
|
if (success) {
|
||||||
|
residenceViewModel.loadResidenceTasks(residenceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,4 +94,46 @@ class TaskViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun archiveTask(taskId: Int, onComplete: (Boolean) -> Unit) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val token = TokenStorage.getToken()
|
||||||
|
if (token != null) {
|
||||||
|
when (val result = taskApi.archiveTask(token, taskId)) {
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
onComplete(true)
|
||||||
|
}
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
onComplete(false)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
onComplete(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onComplete(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unarchiveTask(taskId: Int, onComplete: (Boolean) -> Unit) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val token = TokenStorage.getToken()
|
||||||
|
if (token != null) {
|
||||||
|
when (val result = taskApi.unarchiveTask(token, taskId)) {
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
onComplete(true)
|
||||||
|
}
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
onComplete(false)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
onComplete(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onComplete(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,16 @@ struct ResidenceDetailView: View {
|
|||||||
},
|
},
|
||||||
onCompleteTask: { task in
|
onCompleteTask: { task in
|
||||||
selectedTaskForComplete = task
|
selectedTaskForComplete = task
|
||||||
|
},
|
||||||
|
onArchiveTask: { task in
|
||||||
|
taskViewModel.archiveTask(id: task.id) { _ in
|
||||||
|
loadResidenceTasks()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onUnarchiveTask: { task in
|
||||||
|
taskViewModel.unarchiveTask(id: task.id) { _ in
|
||||||
|
loadResidenceTasks()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ struct TaskCard: View {
|
|||||||
let onUncancel: (() -> Void)?
|
let onUncancel: (() -> Void)?
|
||||||
let onMarkInProgress: (() -> Void)?
|
let onMarkInProgress: (() -> Void)?
|
||||||
let onComplete: (() -> Void)?
|
let onComplete: (() -> Void)?
|
||||||
|
let onArchive: (() -> Void)?
|
||||||
|
let onUnarchive: (() -> Void)?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 12) {
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
@@ -116,6 +118,28 @@ struct TaskCard: View {
|
|||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
.tint(.blue)
|
.tint(.blue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if task.archived {
|
||||||
|
if let onUnarchive = onUnarchive {
|
||||||
|
Button(action: onUnarchive) {
|
||||||
|
Label("Unarchive", systemImage: "tray.and.arrow.up")
|
||||||
|
.font(.subheadline)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
.tint(.blue)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let onArchive = onArchive {
|
||||||
|
Button(action: onArchive) {
|
||||||
|
Label("Archive", systemImage: "archivebox")
|
||||||
|
.font(.subheadline)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
.tint(.gray)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(16)
|
.padding(16)
|
||||||
@@ -162,7 +186,9 @@ struct TaskCard: View {
|
|||||||
onCancel: {},
|
onCancel: {},
|
||||||
onUncancel: nil,
|
onUncancel: nil,
|
||||||
onMarkInProgress: {},
|
onMarkInProgress: {},
|
||||||
onComplete: {}
|
onComplete: {},
|
||||||
|
onArchive: {},
|
||||||
|
onUnarchive: {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ struct TasksSection: View {
|
|||||||
let onUncancelTask: (TaskDetail) -> Void
|
let onUncancelTask: (TaskDetail) -> Void
|
||||||
let onMarkInProgress: (TaskDetail) -> Void
|
let onMarkInProgress: (TaskDetail) -> Void
|
||||||
let onCompleteTask: (TaskDetail) -> Void
|
let onCompleteTask: (TaskDetail) -> Void
|
||||||
|
let onArchiveTask: (TaskDetail) -> Void
|
||||||
|
let onUnarchiveTask: (TaskDetail) -> Void
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 12) {
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
@@ -32,7 +34,9 @@ struct TasksSection: View {
|
|||||||
onCancelTask: onCancelTask,
|
onCancelTask: onCancelTask,
|
||||||
onUncancelTask: onUncancelTask,
|
onUncancelTask: onUncancelTask,
|
||||||
onMarkInProgress: onMarkInProgress,
|
onMarkInProgress: onMarkInProgress,
|
||||||
onCompleteTask: onCompleteTask
|
onCompleteTask: onCompleteTask,
|
||||||
|
onArchiveTask: onArchiveTask,
|
||||||
|
onUnarchiveTask: onUnarchiveTask
|
||||||
)
|
)
|
||||||
.frame(width: geometry.size.width - 48)
|
.frame(width: geometry.size.width - 48)
|
||||||
|
|
||||||
@@ -47,7 +51,9 @@ struct TasksSection: View {
|
|||||||
onCancelTask: onCancelTask,
|
onCancelTask: onCancelTask,
|
||||||
onUncancelTask: onUncancelTask,
|
onUncancelTask: onUncancelTask,
|
||||||
onMarkInProgress: nil,
|
onMarkInProgress: nil,
|
||||||
onCompleteTask: onCompleteTask
|
onCompleteTask: onCompleteTask,
|
||||||
|
onArchiveTask: onArchiveTask,
|
||||||
|
onUnarchiveTask: onUnarchiveTask
|
||||||
)
|
)
|
||||||
.frame(width: geometry.size.width - 48)
|
.frame(width: geometry.size.width - 48)
|
||||||
|
|
||||||
@@ -62,7 +68,9 @@ struct TasksSection: View {
|
|||||||
onCancelTask: nil,
|
onCancelTask: nil,
|
||||||
onUncancelTask: nil,
|
onUncancelTask: nil,
|
||||||
onMarkInProgress: nil,
|
onMarkInProgress: nil,
|
||||||
onCompleteTask: nil
|
onCompleteTask: nil,
|
||||||
|
onArchiveTask: onArchiveTask,
|
||||||
|
onUnarchiveTask: onUnarchiveTask
|
||||||
)
|
)
|
||||||
.frame(width: geometry.size.width - 48)
|
.frame(width: geometry.size.width - 48)
|
||||||
|
|
||||||
@@ -77,7 +85,9 @@ struct TasksSection: View {
|
|||||||
onCancelTask: nil,
|
onCancelTask: nil,
|
||||||
onUncancelTask: nil,
|
onUncancelTask: nil,
|
||||||
onMarkInProgress: nil,
|
onMarkInProgress: nil,
|
||||||
onCompleteTask: nil
|
onCompleteTask: nil,
|
||||||
|
onArchiveTask: nil,
|
||||||
|
onUnarchiveTask: onUnarchiveTask
|
||||||
)
|
)
|
||||||
.frame(width: geometry.size.width - 48)
|
.frame(width: geometry.size.width - 48)
|
||||||
}
|
}
|
||||||
@@ -100,7 +110,8 @@ struct TasksSection: View {
|
|||||||
summary: CategorizedTaskSummary(
|
summary: CategorizedTaskSummary(
|
||||||
upcoming: 3,
|
upcoming: 3,
|
||||||
inProgress: 1,
|
inProgress: 1,
|
||||||
done: 2
|
done: 2,
|
||||||
|
archived: 0
|
||||||
),
|
),
|
||||||
upcomingTasks: [
|
upcomingTasks: [
|
||||||
TaskDetail(
|
TaskDetail(
|
||||||
@@ -154,6 +165,8 @@ struct TasksSection: View {
|
|||||||
onUncancelTask: { _ in },
|
onUncancelTask: { _ in },
|
||||||
onMarkInProgress: { _ in },
|
onMarkInProgress: { _ in },
|
||||||
onCompleteTask: { _ in }
|
onCompleteTask: { _ in }
|
||||||
|
, onArchiveTask: { _ in }
|
||||||
|
, onUnarchiveTask: { _ in }
|
||||||
)
|
)
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,13 @@ struct AllTasksView: View {
|
|||||||
},
|
},
|
||||||
onCompleteTask: { task in
|
onCompleteTask: { task in
|
||||||
selectedTaskForComplete = task
|
selectedTaskForComplete = task
|
||||||
}
|
},
|
||||||
|
onArchiveTask: { task in
|
||||||
|
taskViewModel.archiveTask(id: task.id) { _ in
|
||||||
|
loadAllTasks()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onUnarchiveTask: nil
|
||||||
)
|
)
|
||||||
.frame(width: geometry.size.width - 48)
|
.frame(width: geometry.size.width - 48)
|
||||||
|
|
||||||
@@ -142,7 +148,13 @@ struct AllTasksView: View {
|
|||||||
onMarkInProgress: nil,
|
onMarkInProgress: nil,
|
||||||
onCompleteTask: { task in
|
onCompleteTask: { task in
|
||||||
selectedTaskForComplete = task
|
selectedTaskForComplete = task
|
||||||
}
|
},
|
||||||
|
onArchiveTask: { task in
|
||||||
|
taskViewModel.archiveTask(id: task.id) { _ in
|
||||||
|
loadAllTasks()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onUnarchiveTask: nil
|
||||||
)
|
)
|
||||||
.frame(width: geometry.size.width - 48)
|
.frame(width: geometry.size.width - 48)
|
||||||
|
|
||||||
@@ -160,7 +172,13 @@ struct AllTasksView: View {
|
|||||||
onCancelTask: nil,
|
onCancelTask: nil,
|
||||||
onUncancelTask: nil,
|
onUncancelTask: nil,
|
||||||
onMarkInProgress: nil,
|
onMarkInProgress: nil,
|
||||||
onCompleteTask: nil
|
onCompleteTask: nil,
|
||||||
|
onArchiveTask: { task in
|
||||||
|
taskViewModel.archiveTask(id: task.id) { _ in
|
||||||
|
loadAllTasks()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onUnarchiveTask: nil
|
||||||
)
|
)
|
||||||
.frame(width: geometry.size.width - 48)
|
.frame(width: geometry.size.width - 48)
|
||||||
|
|
||||||
@@ -178,7 +196,13 @@ struct AllTasksView: View {
|
|||||||
onCancelTask: nil,
|
onCancelTask: nil,
|
||||||
onUncancelTask: nil,
|
onUncancelTask: nil,
|
||||||
onMarkInProgress: nil,
|
onMarkInProgress: nil,
|
||||||
onCompleteTask: nil
|
onCompleteTask: nil,
|
||||||
|
onArchiveTask: nil,
|
||||||
|
onUnarchiveTask: { task in
|
||||||
|
taskViewModel.unarchiveTask(id: task.id) { _ in
|
||||||
|
loadAllTasks()
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.frame(width: geometry.size.width - 48)
|
.frame(width: geometry.size.width - 48)
|
||||||
}
|
}
|
||||||
@@ -269,6 +293,8 @@ struct TaskColumnView: View {
|
|||||||
let onUncancelTask: ((TaskDetail) -> Void)?
|
let onUncancelTask: ((TaskDetail) -> Void)?
|
||||||
let onMarkInProgress: ((TaskDetail) -> Void)?
|
let onMarkInProgress: ((TaskDetail) -> Void)?
|
||||||
let onCompleteTask: ((TaskDetail) -> Void)?
|
let onCompleteTask: ((TaskDetail) -> Void)?
|
||||||
|
let onArchiveTask: ((TaskDetail) -> Void)?
|
||||||
|
let onUnarchiveTask: ((TaskDetail) -> Void)?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
@@ -316,7 +342,9 @@ struct TaskColumnView: View {
|
|||||||
onCancel: onCancelTask != nil ? { onCancelTask?(task) } : nil,
|
onCancel: onCancelTask != nil ? { onCancelTask?(task) } : nil,
|
||||||
onUncancel: onUncancelTask != nil ? { onUncancelTask?(task) } : nil,
|
onUncancel: onUncancelTask != nil ? { onUncancelTask?(task) } : nil,
|
||||||
onMarkInProgress: onMarkInProgress != nil ? { onMarkInProgress?(task) } : nil,
|
onMarkInProgress: onMarkInProgress != nil ? { onMarkInProgress?(task) } : nil,
|
||||||
onComplete: onCompleteTask != nil ? { onCompleteTask?(task) } : nil
|
onComplete: onCompleteTask != nil ? { onCompleteTask?(task) } : nil,
|
||||||
|
onArchive: onArchiveTask != nil ? { onArchiveTask?(task) } : nil,
|
||||||
|
onUnarchive: onUnarchiveTask != nil ? { onUnarchiveTask?(task) } : nil
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ class TaskViewModel: ObservableObject {
|
|||||||
@Published var taskCancelled: Bool = false
|
@Published var taskCancelled: Bool = false
|
||||||
@Published var taskUncancelled: Bool = false
|
@Published var taskUncancelled: Bool = false
|
||||||
@Published var taskMarkedInProgress: Bool = false
|
@Published var taskMarkedInProgress: Bool = false
|
||||||
|
@Published var taskArchived: Bool = false
|
||||||
|
@Published var taskUnarchived: Bool = false
|
||||||
|
|
||||||
// MARK: - Private Properties
|
// MARK: - Private Properties
|
||||||
private let taskApi: TaskApi
|
private let taskApi: TaskApi
|
||||||
@@ -168,6 +170,62 @@ class TaskViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func archiveTask(id: Int32, completion: @escaping (Bool) -> Void) {
|
||||||
|
guard let token = tokenStorage.getToken() else {
|
||||||
|
errorMessage = "Not authenticated"
|
||||||
|
completion(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoading = true
|
||||||
|
errorMessage = nil
|
||||||
|
taskArchived = false
|
||||||
|
|
||||||
|
taskApi.archiveTask(token: token, id: id) { result, error in
|
||||||
|
if result is ApiResultSuccess<TaskCancelResponse> {
|
||||||
|
self.isLoading = false
|
||||||
|
self.taskArchived = true
|
||||||
|
completion(true)
|
||||||
|
} else if let errorResult = result as? ApiResultError {
|
||||||
|
self.errorMessage = errorResult.message
|
||||||
|
self.isLoading = false
|
||||||
|
completion(false)
|
||||||
|
} else if let error = error {
|
||||||
|
self.errorMessage = error.localizedDescription
|
||||||
|
self.isLoading = false
|
||||||
|
completion(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func unarchiveTask(id: Int32, completion: @escaping (Bool) -> Void) {
|
||||||
|
guard let token = tokenStorage.getToken() else {
|
||||||
|
errorMessage = "Not authenticated"
|
||||||
|
completion(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoading = true
|
||||||
|
errorMessage = nil
|
||||||
|
taskUnarchived = false
|
||||||
|
|
||||||
|
taskApi.unarchiveTask(token: token, id: id) { result, error in
|
||||||
|
if result is ApiResultSuccess<TaskCancelResponse> {
|
||||||
|
self.isLoading = false
|
||||||
|
self.taskUnarchived = true
|
||||||
|
completion(true)
|
||||||
|
} else if let errorResult = result as? ApiResultError {
|
||||||
|
self.errorMessage = errorResult.message
|
||||||
|
self.isLoading = false
|
||||||
|
completion(false)
|
||||||
|
} else if let error = error {
|
||||||
|
self.errorMessage = error.localizedDescription
|
||||||
|
self.isLoading = false
|
||||||
|
completion(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func completeTask(taskId: Int32, completion: @escaping (Bool) -> Void) {
|
func completeTask(taskId: Int32, completion: @escaping (Bool) -> Void) {
|
||||||
guard let token = tokenStorage.getToken() else {
|
guard let token = tokenStorage.getToken() else {
|
||||||
errorMessage = "Not authenticated"
|
errorMessage = "Not authenticated"
|
||||||
@@ -215,6 +273,8 @@ class TaskViewModel: ObservableObject {
|
|||||||
taskCancelled = false
|
taskCancelled = false
|
||||||
taskUncancelled = false
|
taskUncancelled = false
|
||||||
taskMarkedInProgress = false
|
taskMarkedInProgress = false
|
||||||
|
taskArchived = false
|
||||||
|
taskUnarchived = false
|
||||||
errorMessage = nil
|
errorMessage = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user