feat: labels filtrés par projet (releases du projet uniquement)

This commit is contained in:
2026-06-06 10:54:21 +02:00
parent ba9f379100
commit 833a68c06e
6 changed files with 24 additions and 3 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ android {
minSdk = 26 minSdk = 26
targetSdk = 35 targetSdk = 35
versionCode = 1 versionCode = 1
versionName = "0.0.15" versionName = "0.0.16"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -13,6 +13,9 @@ interface LabelDao {
@Query("SELECT * FROM labels WHERE is_deleted = 0 ORDER BY `order` ASC") @Query("SELECT * FROM labels WHERE is_deleted = 0 ORDER BY `order` ASC")
fun getAllLabels(): Flow<List<LabelEntity>> fun getAllLabels(): Flow<List<LabelEntity>>
@Query("SELECT * FROM labels WHERE is_deleted = 0 AND source_id = :sourceId ORDER BY `order` ASC")
fun getLabelsBySourceId(sourceId: String): Flow<List<LabelEntity>>
@Query("SELECT * FROM labels WHERE id = :id") @Query("SELECT * FROM labels WHERE id = :id")
suspend fun getById(id: String): LabelEntity? suspend fun getById(id: String): LabelEntity?
@@ -16,6 +16,9 @@ class LabelRepositoryImpl @Inject constructor(
override fun getAllLabels(): Flow<List<Label>> = override fun getAllLabels(): Flow<List<Label>> =
dao.getAllLabels().map { it.map { e -> e.toDomain() } } dao.getAllLabels().map { it.map { e -> e.toDomain() } }
override fun getLabelsByProject(projectId: String): Flow<List<Label>> =
dao.getLabelsBySourceId(projectId).map { it.map { e -> e.toDomain() } }
override suspend fun getLabelById(id: String): Label? = dao.getById(id)?.toDomain() override suspend fun getLabelById(id: String): Label? = dao.getById(id)?.toDomain()
override suspend fun insertLabel(label: Label) = dao.insert(label.toEntity()) override suspend fun insertLabel(label: Label) = dao.insert(label.toEntity())
override suspend fun updateLabel(label: Label) = dao.update(label.toEntity()) override suspend fun updateLabel(label: Label) = dao.update(label.toEntity())
@@ -5,6 +5,7 @@ import kotlinx.coroutines.flow.Flow
interface LabelRepository { interface LabelRepository {
fun getAllLabels(): Flow<List<Label>> fun getAllLabels(): Flow<List<Label>>
fun getLabelsByProject(projectId: String): Flow<List<Label>>
suspend fun getLabelById(id: String): Label? suspend fun getLabelById(id: String): Label?
suspend fun insertLabel(label: Label) suspend fun insertLabel(label: Label)
suspend fun updateLabel(label: Label) suspend fun updateLabel(label: Label)
@@ -28,31 +28,44 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.compose.runtime.LaunchedEffect
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.planify.mobile.domain.model.Label import com.planify.mobile.domain.model.Label
import com.planify.mobile.domain.repository.LabelRepository import com.planify.mobile.domain.repository.LabelRepository
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class LabelPickerViewModel @Inject constructor( class LabelPickerViewModel @Inject constructor(
labelRepository: LabelRepository, private val labelRepository: LabelRepository,
) : ViewModel() { ) : ViewModel() {
val labels = labelRepository.getAllLabels() private val _projectId = MutableStateFlow("")
val labels = _projectId
.flatMapLatest { projectId ->
if (projectId.isNotBlank()) labelRepository.getLabelsByProject(projectId)
else labelRepository.getAllLabels()
}
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), emptyList()) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), emptyList())
fun setProjectId(projectId: String) { _projectId.value = projectId }
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun LabelPickerSheet( fun LabelPickerSheet(
projectId: String,
selectedLabels: List<String>, selectedLabels: List<String>,
onConfirm: (List<String>) -> Unit, onConfirm: (List<String>) -> Unit,
onDismiss: () -> Unit, onDismiss: () -> Unit,
viewModel: LabelPickerViewModel = hiltViewModel(), viewModel: LabelPickerViewModel = hiltViewModel(),
) { ) {
LaunchedEffect(projectId) { viewModel.setProjectId(projectId) }
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val labels by viewModel.labels.collectAsState() val labels by viewModel.labels.collectAsState()
var selected by remember { mutableStateOf(selectedLabels.toSet()) } var selected by remember { mutableStateOf(selectedLabels.toSet()) }
@@ -194,6 +194,7 @@ fun TaskEditSheet(
} }
if (showLabelPicker) { if (showLabelPicker) {
LabelPickerSheet( LabelPickerSheet(
projectId = projectId,
selectedLabels = state.labels, selectedLabels = state.labels,
onConfirm = { viewModel.setLabels(it); showLabelPicker = false }, onConfirm = { viewModel.setLabels(it); showLabelPicker = false },
onDismiss = { showLabelPicker = false }, onDismiss = { showLabelPicker = false },