Added a filter bar to filter transactions by date
This commit is contained in:
parent
77c944d33b
commit
43bd89a047
|
@ -51,6 +51,8 @@ fun App() {
|
|||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
|
||||
val showFilterBar = uiState.showFilterBar.collectAsState()
|
||||
|
||||
var isInitialized by remember { mutableStateOf(false) }
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
@ -98,6 +100,10 @@ fun App() {
|
|||
DesktopLayout(scaffoldPadding, uiState, uiSettings, snackbarHostState, desktopDrawerWidth)
|
||||
}
|
||||
}
|
||||
|
||||
if (showFilterBar.value) {
|
||||
FilterBar()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ fun BottomBar(showMenuDrawer: Boolean = true) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (userAccounts.isNotEmpty()) {
|
||||
if (showSearchbar == false) {
|
||||
Row(Modifier.fillMaxHeight().widthIn(IconWidth, IconWidth), verticalAlignment = Alignment.CenterVertically) {
|
||||
|
@ -137,6 +138,10 @@ fun BottomBar(showMenuDrawer: Boolean = true) {
|
|||
}
|
||||
|
||||
Row(Modifier.fillMaxHeight().widthIn(IconWidth.times(2), IconWidth.times(2)), verticalAlignment = Alignment.CenterVertically) {
|
||||
IconButton({ uiState.showFilterBar.value = !!!uiState.showFilterBar.value }, Modifier.width(IconWidth)) {
|
||||
Icon(imageResource(Res.drawable.filter_alt), "Kontoumsätze nach Konto, Zeitraum oder Betrag filtern", Modifier.size(24.dp))
|
||||
}
|
||||
|
||||
IconButton({ coroutineScope.launch { DI.bankingService.updateAccountTransactions() } }, Modifier.width(IconWidth)) { // TODO: use sync, cached or autorenew as icon?
|
||||
Icon(Icons.Filled.Refresh, contentDescription = "Neue Kontoumsätze abholen")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package net.codinux.banking.ui.appskeleton
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.zIndex
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.forms.RoundedCornersCard
|
||||
import net.codinux.banking.ui.forms.Select
|
||||
|
||||
private val uiState = DI.uiState
|
||||
|
||||
private val uiSettings = DI.uiSettings
|
||||
|
||||
val labelsWidth = 60.dp
|
||||
|
||||
val selectBoxesWidth = 154.dp
|
||||
|
||||
val horizontalPadding = 6.dp
|
||||
|
||||
@Composable
|
||||
fun FilterBar() {
|
||||
val transactions = uiState.transactions.collectAsState()
|
||||
|
||||
val transactionsFilter = uiState.transactionsFilter.collectAsState()
|
||||
|
||||
val filterService = DI.accountTransactionsFilterService
|
||||
|
||||
val years by remember(transactions) { derivedStateOf { filterService.getYearForWhichWeHaveTransactions(transactions.value).sorted() + listOf(null as? Int) } }
|
||||
|
||||
val months = listOf("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" /*, "1. Quartal", "2. Quartal", "3. Quartal", "4. Quartal" */, null)
|
||||
|
||||
Box(
|
||||
contentAlignment = Alignment.BottomEnd,
|
||||
modifier = Modifier.fillMaxSize().zIndex(1100f)
|
||||
.padding(bottom = 64.dp, end = 74.dp)
|
||||
) {
|
||||
Column(Modifier.height(166.dp).width(390.dp)) {
|
||||
RoundedCornersCard(cornerSize = 4.dp, shadowElevation = 24.dp) {
|
||||
Column(Modifier.fillMaxWidth().background(Color.White).padding(16.dp)) {
|
||||
Row(Modifier.fillMaxWidth().padding(top = 8.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Text("Zeitraum", Modifier.width(labelsWidth))
|
||||
|
||||
Select(
|
||||
label = "Jahr",
|
||||
items = years,
|
||||
selectedItem = transactionsFilter.value.year,
|
||||
onSelectedItemChanged = { year -> transactionsFilter.value.year = year },
|
||||
getItemDisplayText = { year -> if (year == null) "" else year.toString() },
|
||||
modifier = Modifier.width(selectBoxesWidth).padding(horizontal = horizontalPadding)
|
||||
)
|
||||
|
||||
if (transactionsFilter.value.year != null) {
|
||||
Select(
|
||||
label ="Monat",
|
||||
items = months,
|
||||
selectedItem = transactionsFilter.value.month?.let { months[it - 1] },
|
||||
onSelectedItemChanged = { month -> transactionsFilter.value.month = months.indexOf(month) + 1 },
|
||||
getItemDisplayText = { month -> if (month == null) "" else month },
|
||||
modifier = Modifier.width(selectBoxesWidth)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -120,7 +120,7 @@ fun TransferMoneyDialog(
|
|||
"Konto",
|
||||
accountsSupportingTransferringMoney, senderAccount, { senderAccount = it },
|
||||
{ account -> "${accountsToUserAccount[account]?.displayName} ${account.displayName}" },
|
||||
{ BankIcon(accountsToUserAccount[senderAccount]) }
|
||||
leadingIcon = { BankIcon(accountsToUserAccount[senderAccount]) }
|
||||
) { account ->
|
||||
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
||||
BankIcon(accountsToUserAccount[account], Modifier.padding(end = 6.dp))
|
||||
|
|
|
@ -13,12 +13,13 @@ fun <T> Select(
|
|||
selectedItem: T,
|
||||
onSelectedItemChanged: (T) -> Unit,
|
||||
getItemDisplayText: (T) -> String,
|
||||
modifier: Modifier = Modifier,
|
||||
leadingIcon: @Composable (() -> Unit)? = null,
|
||||
dropDownItemContent: @Composable ((T) -> Unit)? = null
|
||||
) {
|
||||
var showDropDownMenu by remember { mutableStateOf(false) }
|
||||
|
||||
ExposedDropdownMenuBox(showDropDownMenu, { isExpanded -> showDropDownMenu = isExpanded }, Modifier.fillMaxWidth()) {
|
||||
ExposedDropdownMenuBox(showDropDownMenu, { isExpanded -> showDropDownMenu = isExpanded }, modifier.fillMaxWidth()) {
|
||||
OutlinedTextField(
|
||||
value = getItemDisplayText(selectedItem),
|
||||
onValueChange = { },
|
||||
|
|
|
@ -7,7 +7,7 @@ import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
|||
class AccountTransactionsFilter {
|
||||
|
||||
val noFiltersApplied: Boolean
|
||||
get() = showAllAccounts && noSearchTermApplied
|
||||
get() = showAllAccounts && noSearchTermApplied && noDateFilterApplied
|
||||
|
||||
|
||||
var selectedAccounts = mutableStateOf<List<BankAccountFilter>>(emptyList())
|
||||
|
@ -37,4 +37,13 @@ class AccountTransactionsFilter {
|
|||
fun updateSearchTerm(searchTerm: String) {
|
||||
this.searchTerm = searchTerm
|
||||
}
|
||||
|
||||
|
||||
var year by mutableStateOf<Int?>(null)
|
||||
|
||||
var month by mutableStateOf<Int?>(null)
|
||||
|
||||
val noDateFilterApplied: Boolean
|
||||
get() = year == null && month == null
|
||||
|
||||
}
|
|
@ -8,14 +8,20 @@ import net.codinux.banking.ui.model.BankAccountFilter
|
|||
|
||||
class AccountTransactionsFilterService {
|
||||
|
||||
fun filterAccounts(transactions: List<AccountTransactionViewModel>, transactionsFilter: AccountTransactionsFilter): List<AccountTransactionViewModel> {
|
||||
val appliedAccountFilter = if (transactionsFilter.showAllAccounts) {
|
||||
fun filterAccounts(transactions: List<AccountTransactionViewModel>, filter: AccountTransactionsFilter): List<AccountTransactionViewModel> {
|
||||
var appliedAccountFilter = if (filter.showAllAccounts) {
|
||||
transactions
|
||||
} else {
|
||||
transactions.filter { matchesFilter(it, transactionsFilter.selectedAccounts.value) }
|
||||
transactions.filter { matchesFilter(it, filter.selectedAccounts.value) }
|
||||
}
|
||||
|
||||
val searchTerm = transactionsFilter.searchTerm
|
||||
filter.year?.let { year ->
|
||||
val month = filter.month
|
||||
|
||||
appliedAccountFilter = appliedAccountFilter.filter { it.valueDate.year == year && (month == null || it.valueDate.monthNumber == month) }
|
||||
}
|
||||
|
||||
val searchTerm = filter.searchTerm
|
||||
return if (searchTerm.isBlank()) {
|
||||
appliedAccountFilter
|
||||
} else {
|
||||
|
@ -57,4 +63,8 @@ class AccountTransactionsFilterService {
|
|||
return filter?.bankAccount == bankAccount
|
||||
}
|
||||
|
||||
|
||||
fun getYearForWhichWeHaveTransactions(transactions: List<AccountTransactionViewModel>): List<Int> =
|
||||
transactions.map { it.valueDate.year }.toSet().sortedDescending()
|
||||
|
||||
}
|
|
@ -38,6 +38,8 @@ class UiState : ViewModel() {
|
|||
|
||||
val transactionsFilter = MutableStateFlow(AccountTransactionsFilter())
|
||||
|
||||
var showFilterBar = MutableStateFlow(false)
|
||||
|
||||
|
||||
val showAddAccountDialog = MutableStateFlow(false)
|
||||
|
||||
|
|
Loading…
Reference in New Issue