feat: [#23] vue Labels (toutes les tâches associées à un label)

This commit is contained in:
2026-06-06 06:39:03 +02:00
parent 86aab6c3da
commit 1146b146c0
2 changed files with 98 additions and 0 deletions
@@ -0,0 +1,46 @@
package com.planify.mobile.ui.label
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Label
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import com.planify.mobile.domain.model.Task
import com.planify.mobile.ui.components.EmptyState
import com.planify.mobile.ui.components.TaskRow
@Composable
fun LabelScreen(
labelId: String,
onTaskClick: (Task) -> Unit,
viewModel: LabelViewModel = hiltViewModel(),
) {
LaunchedEffect(labelId) { viewModel.init(labelId) }
val tasks by viewModel.tasks.collectAsState()
if (tasks.isEmpty()) {
EmptyState(
icon = Icons.Outlined.Label,
title = "Aucune tâche",
subtitle = "Aucune tâche n'est associée à ce label",
)
return
}
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(tasks, key = { it.id }) { task ->
TaskRow(
task = task,
onClick = { onTaskClick(task) },
onCheckedChange = { viewModel.toggleTask(task) },
)
}
}
}
@@ -0,0 +1,52 @@
package com.planify.mobile.ui.label
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.planify.mobile.domain.model.Label
import com.planify.mobile.domain.model.Task
import com.planify.mobile.domain.repository.LabelRepository
import com.planify.mobile.domain.repository.TaskRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class LabelViewModel @Inject constructor(
private val taskRepository: TaskRepository,
private val labelRepository: LabelRepository,
) : ViewModel() {
private val _labelId = MutableStateFlow<String?>(null)
@OptIn(ExperimentalCoroutinesApi::class)
val label = _labelId.flatMapLatest { id ->
if (id == null) flowOf(null)
else labelRepository.getAllLabels().flatMapLatest { labels ->
flowOf(labels.find { it.id == id })
}
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), null)
@OptIn(ExperimentalCoroutinesApi::class)
val tasks = label.flatMapLatest { lbl ->
if (lbl == null) flowOf(emptyList())
else taskRepository.getTasksByLabel(lbl.name)
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), emptyList())
fun init(labelId: String) {
_labelId.value = labelId
}
fun toggleTask(task: Task) {
viewModelScope.launch { taskRepository.checkTask(task.id, !task.checked) }
}
fun deleteTask(task: Task) {
viewModelScope.launch { taskRepository.deleteTask(task.id) }
}
}