Filtering transactions on click on account item in SideMenu
This commit is contained in:
parent
572bd8e9d8
commit
ce5b99c290
|
@ -6,16 +6,18 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import bankmeister.composeapp.generated.resources.AppIcon
|
||||
import bankmeister.composeapp.generated.resources.Res
|
||||
import kotlinx.coroutines.launch
|
||||
import net.codinux.banking.ui.composables.BanksList
|
||||
import net.codinux.banking.ui.config.Colors
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.model.BankAccountFilter
|
||||
import org.jetbrains.compose.resources.imageResource
|
||||
|
||||
private val uiState = DI.uiState
|
||||
|
@ -34,6 +36,8 @@ private val HeaderBackground = Brush.linearGradient(
|
|||
fun SideMenu(appContent: @Composable () -> Unit) {
|
||||
val drawerState = uiState.drawerState.collectAsState().value
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
ModalDrawer(
|
||||
modifier = Modifier.fillMaxHeight(),
|
||||
drawerState = drawerState,
|
||||
|
@ -59,7 +63,17 @@ fun SideMenu(appContent: @Composable () -> Unit) {
|
|||
Text("Konten", color = Colors.DrawerPrimaryText)
|
||||
}
|
||||
|
||||
BanksList(textColor = Colors.DrawerPrimaryText)
|
||||
BanksList(textColor = Colors.DrawerPrimaryText) { userAccount, bankAccount ->
|
||||
uiState.accountFilter.value = if (userAccount == null) {
|
||||
emptyList()
|
||||
} else {
|
||||
listOf(BankAccountFilter(userAccount, bankAccount))
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
drawerState.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.codinux.banking.ui.composables
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -11,6 +12,8 @@ import androidx.compose.ui.unit.Dp
|
|||
import androidx.compose.ui.unit.dp
|
||||
import bankmeister.composeapp.generated.resources.Res
|
||||
import bankmeister.composeapp.generated.resources.account
|
||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
||||
import net.codinux.banking.ui.config.DI
|
||||
|
||||
private val uiState = DI.uiState
|
||||
|
@ -18,11 +21,22 @@ private val uiState = DI.uiState
|
|||
private val IconTextSpacing = 36.dp
|
||||
|
||||
@Composable
|
||||
fun BanksList(modifier: Modifier = Modifier, itemModifier: Modifier = Modifier.height(48.dp).widthIn(min = 300.dp).padding(start = 8.dp), iconSize: Dp = 24.dp, textColor: Color = Color.White) {
|
||||
fun BanksList(
|
||||
modifier: Modifier = Modifier,
|
||||
iconSize: Dp = 24.dp,
|
||||
textColor: Color = Color.White,
|
||||
itemModifier: Modifier = Modifier.height(48.dp).widthIn(min = 300.dp).padding(start = 8.dp),
|
||||
accountSelected: ((UserAccountEntity?, BankAccountEntity?) -> Unit)? = null
|
||||
) {
|
||||
val userAccounts = uiState.userAccounts.collectAsState()
|
||||
|
||||
Column(modifier) {
|
||||
Row(itemModifier, verticalAlignment = Alignment.CenterVertically) {
|
||||
Row(
|
||||
itemModifier.clickable {
|
||||
accountSelected?.invoke(null, null)
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
BankIcon(null as? String?, Modifier.padding(end = IconTextSpacing), Modifier.size(iconSize), fallbackIcon = Res.drawable.account)
|
||||
|
||||
Text("Alle Konten", color = textColor)
|
||||
|
@ -31,14 +45,24 @@ fun BanksList(modifier: Modifier = Modifier, itemModifier: Modifier = Modifier.h
|
|||
userAccounts.value.forEach { userAccount ->
|
||||
Spacer(Modifier.fillMaxWidth().height(12.dp))
|
||||
|
||||
Row(itemModifier, verticalAlignment = Alignment.CenterVertically) {
|
||||
Row(
|
||||
itemModifier.clickable {
|
||||
accountSelected?.invoke(userAccount, null)
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
BankIcon(userAccount, Modifier.padding(end = IconTextSpacing), Modifier.size(iconSize), fallbackIcon = Res.drawable.account)
|
||||
|
||||
Text(userAccount.bankName, color = textColor)
|
||||
}
|
||||
|
||||
userAccount.accounts.sortedBy { it.displayIndex }.forEach { account ->
|
||||
Column(itemModifier.padding(start = iconSize + IconTextSpacing), verticalArrangement = Arrangement.Center) {
|
||||
Column(
|
||||
itemModifier.clickable {
|
||||
accountSelected?.invoke(userAccount, account)
|
||||
}.padding(start = iconSize + IconTextSpacing),
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(account.productName ?: account.identifier, color = textColor)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ import net.codinux.banking.ui.config.DI
|
|||
import net.codinux.banking.ui.state.UiState
|
||||
import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||
|
||||
private val filterService = DI.bankAccountFilterService
|
||||
|
||||
private val formatUtil = DI.formatUtil
|
||||
|
||||
@Composable
|
||||
|
@ -32,10 +34,16 @@ fun TransactionsList(uiState: UiState) {
|
|||
derivedStateOf { userAccounts.associateBy { it.id } }
|
||||
}
|
||||
|
||||
val accountFilter by uiState.accountFilter.collectAsState()
|
||||
|
||||
val transactions by uiState.transactions.collectAsState()
|
||||
|
||||
val groupedByMonth by remember(transactions) {
|
||||
derivedStateOf { transactions.groupBy { LocalDate(it.valueDate.year, it.valueDate.monthNumber, 1) } }
|
||||
val transactionsToDisplay by remember(accountFilter, transactions) {
|
||||
derivedStateOf { filterService.filterAccounts(transactions, accountFilter) }
|
||||
}
|
||||
|
||||
val groupedByMonth by remember(transactionsToDisplay) {
|
||||
derivedStateOf { transactionsToDisplay.groupBy { LocalDate(it.valueDate.year, it.valueDate.monthNumber, 1) } }
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
|
|
|
@ -24,6 +24,8 @@ object DI {
|
|||
|
||||
val bankIconService = BankIconService()
|
||||
|
||||
val bankAccountFilterService = BankAccountFilterService()
|
||||
|
||||
|
||||
var bankingRepository: BankingRepository = InMemoryBankingRepository(emptyList())
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package net.codinux.banking.ui.model
|
||||
|
||||
import net.codinux.banking.dataaccess.entities.BankAccountEntity
|
||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
||||
|
||||
data class BankAccountFilter(
|
||||
val userAccount: UserAccountEntity,
|
||||
val bankAccount: BankAccountEntity? = null
|
||||
)
|
|
@ -0,0 +1,24 @@
|
|||
package net.codinux.banking.ui.service
|
||||
|
||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||
import net.codinux.banking.ui.model.BankAccountFilter
|
||||
|
||||
class BankAccountFilterService {
|
||||
|
||||
fun filterAccounts(transactions: List<AccountTransactionViewModel>, accountsFilter: List<BankAccountFilter>): List<AccountTransactionViewModel> =
|
||||
if (accountsFilter.isEmpty()) {
|
||||
transactions
|
||||
} else {
|
||||
transactions.filter { matchesFilter(it, accountsFilter) }
|
||||
}
|
||||
|
||||
private fun matchesFilter(transaction: AccountTransactionViewModel, accountsFilter: List<BankAccountFilter>): Boolean =
|
||||
accountsFilter.any { (userAccount, bankAccount) ->
|
||||
if (bankAccount != null) {
|
||||
transaction.bankAccountId == bankAccount.id
|
||||
} else {
|
||||
transaction.userAccountId == userAccount.id
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -6,6 +6,7 @@ import androidx.lifecycle.ViewModel
|
|||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||
import net.codinux.banking.ui.model.BankAccountFilter
|
||||
import net.codinux.banking.ui.model.TanChallengeReceived
|
||||
import net.codinux.banking.ui.model.error.ApplicationError
|
||||
import net.codinux.banking.ui.model.error.BankingClientError
|
||||
|
@ -21,6 +22,9 @@ class UiState : ViewModel() {
|
|||
val drawerState = MutableStateFlow(DrawerState(DrawerValue.Open))
|
||||
|
||||
|
||||
val accountFilter = MutableStateFlow<List<BankAccountFilter>>(emptyList())
|
||||
|
||||
|
||||
val applicationErrorOccurred = MutableStateFlow<ApplicationError?>(null)
|
||||
|
||||
val bankingClientErrorOccurred = MutableStateFlow<BankingClientError?>(null)
|
||||
|
|
Loading…
Reference in New Issue