Implemented setting banks' display order
This commit is contained in:
parent
f75db3f827
commit
34cb8617f8
|
@ -19,7 +19,7 @@ open class Customer(
|
|||
open var userId: String = customerId,
|
||||
open var iconUrl: String? = null,
|
||||
open var accounts: List<BankAccount> = listOf()
|
||||
) {
|
||||
) : OrderedDisplayable {
|
||||
|
||||
|
||||
internal constructor() : this("", "", "", "", "", "", "") // for object deserializers
|
||||
|
@ -45,9 +45,11 @@ open class Customer(
|
|||
|
||||
open var userSetDisplayName: String? = null
|
||||
|
||||
open val displayName: String
|
||||
override val displayName: String
|
||||
get() = userSetDisplayName ?: bankName
|
||||
|
||||
override var displayIndex: Int = 0
|
||||
|
||||
|
||||
open val balance: BigDecimal
|
||||
get() = accounts.map { it.balance }.sum()
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package net.dankito.banking.ui.model
|
||||
|
||||
|
||||
interface Displayable {
|
||||
|
||||
val displayName: String
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package net.dankito.banking.ui.model
|
||||
|
||||
|
||||
interface OrderedDisplayable : Displayable {
|
||||
|
||||
var displayIndex: Int
|
||||
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
package net.dankito.banking.ui.model.tan
|
||||
|
||||
import net.dankito.banking.ui.model.Displayable
|
||||
|
||||
|
||||
open class TanMedium(
|
||||
val displayName: String,
|
||||
override val displayName: String,
|
||||
val status: TanMediumStatus
|
||||
) {
|
||||
) : Displayable {
|
||||
|
||||
|
||||
internal constructor() : this("", TanMediumStatus.Available) // for object deserializers
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
package net.dankito.banking.ui.model.tan
|
||||
|
||||
import net.dankito.banking.ui.model.Displayable
|
||||
|
||||
|
||||
open class TanProcedure(
|
||||
val displayName: String,
|
||||
override val displayName: String,
|
||||
val type: TanProcedureType,
|
||||
val bankInternalProcedureCode: String,
|
||||
val maxTanInputLength: Int? = null,
|
||||
val allowedTanFormat: AllowedTanFormat = AllowedTanFormat.Alphanumeric
|
||||
) {
|
||||
) : Displayable {
|
||||
|
||||
|
||||
internal constructor() : this("", TanProcedureType.EnterTan, "") // for object deserializers
|
||||
|
|
|
@ -381,6 +381,12 @@ open class BankingPresenter(
|
|||
}
|
||||
|
||||
|
||||
open fun allAccountsUpdated() {
|
||||
customers.forEach { account ->
|
||||
accountUpdated(account)
|
||||
}
|
||||
}
|
||||
|
||||
open fun accountUpdated(account: Customer) {
|
||||
persistAccount(account)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package net.dankito.banking.util
|
||||
|
||||
import net.dankito.banking.ui.model.OrderedDisplayable
|
||||
|
||||
|
||||
fun String.ofMaxLength(maxLength: Int): String {
|
||||
if(this.length > maxLength && maxLength > 0) {
|
||||
|
@ -26,4 +28,9 @@ fun <T> Collection<T>.containsExactly(otherCollection: Collection<T>): Boolean {
|
|||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
fun <T : OrderedDisplayable> Collection<T>.sortedByDisplayIndex(): Collection<T> {
|
||||
return this.sortedBy { it.displayIndex }
|
||||
}
|
|
@ -42,6 +42,7 @@
|
|||
<attribute name="balance" attributeType="Decimal" defaultValueString="0.0"/>
|
||||
<attribute name="currency" attributeType="String"/>
|
||||
<attribute name="customerId" attributeType="String"/>
|
||||
<attribute name="displayIndex" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="haveAllTransactionsBeenFetched" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="iban" optional="YES" attributeType="String"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
|
@ -63,6 +64,7 @@
|
|||
<attribute name="bic" attributeType="String"/>
|
||||
<attribute name="customerId" attributeType="String"/>
|
||||
<attribute name="customerName" attributeType="String"/>
|
||||
<attribute name="displayIndex" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="finTsServerAddress" attributeType="String"/>
|
||||
<attribute name="iconUrl" optional="YES" attributeType="String"/>
|
||||
<attribute name="password" attributeType="String"/>
|
||||
|
|
|
@ -7,6 +7,7 @@ class AppData : ObservableObject {
|
|||
@Inject private var presenter: BankingPresenterSwift
|
||||
|
||||
@Published var banks: [Customer] = []
|
||||
@Published var banksSorted: [Customer] = []
|
||||
|
||||
@Published var hasAtLeastOneAccountBeenAdded: Bool = false
|
||||
|
||||
|
@ -24,9 +25,15 @@ class AppData : ObservableObject {
|
|||
|
||||
private func setFieldsForBanks(_ banks: [Customer]) {
|
||||
self.banks = presenter.customers
|
||||
self.banksSorted = banks.sortedByDisplayIndex()
|
||||
|
||||
hasAtLeastOneAccountBeenAdded = banks.isNotEmpty
|
||||
hasAccountsThatSupportTransferringMoney = banks.flatMap { $0.accounts }.first(where: { $0.supportsTransferringMoney }) != nil
|
||||
}
|
||||
|
||||
|
||||
func banksDisplayIndexChanged() {
|
||||
self.banksSorted = banks.sortedByDisplayIndex()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,27 @@ extension Array where Element == AccountTransaction {
|
|||
|
||||
}
|
||||
|
||||
extension Array where Element: OrderedDisplayable {
|
||||
|
||||
func sortedByDisplayIndex() -> [Element] {
|
||||
return self.sorted { $0.displayIndex <= $1.displayIndex }
|
||||
}
|
||||
|
||||
|
||||
func reorder(from sourceIndices: IndexSet, to destinationIndex: Int) -> [Element] {
|
||||
var elements = self
|
||||
|
||||
elements.move(fromOffsets: sourceIndices, toOffset: destinationIndex)
|
||||
|
||||
for (index, element) in elements.enumerated() {
|
||||
element.displayIndex = Int32(index)
|
||||
}
|
||||
|
||||
return elements.sortedByDisplayIndex()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension BankInfo : Identifiable {
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import BankingUiSwift
|
|||
|
||||
|
||||
class Mapper {
|
||||
|
||||
|
||||
/* Cache mapped object to not save them twice */
|
||||
private var mappedBanks = [Customer:PersistedCustomer]()
|
||||
|
||||
|
@ -19,14 +19,17 @@ class Mapper {
|
|||
let mapped = Customer(bankCode: map(customer.bankCode), customerId: map(customer.customerId), password: map(customer.password), finTsServerAddress: map(customer.finTsServerAddress), bankName: map(customer.bankName), bic: map(customer.bic), customerName: map(customer.customerName), userId: map(customer.userId), iconUrl: customer.iconUrl, accounts: [])
|
||||
|
||||
mapped.userSetDisplayName = customer.userSetDisplayName
|
||||
mapped.displayIndex = customer.displayIndex
|
||||
|
||||
mapped.accounts = map(mapped, customer.accounts?.array as? [PersistedBankAccount])
|
||||
|
||||
mappedBanks[mapped] = customer
|
||||
|
||||
mapped.supportedTanProcedures = map(customer.supportedTanProcedures?.array as? [PersistedTanProcedure])
|
||||
mapped.selectedTanProcedure = mapped.supportedTanProcedures.first(where: { $0.bankInternalProcedureCode == customer.selectedTanProcedureCode })
|
||||
|
||||
mapped.technicalId = customer.objectIDAsString
|
||||
|
||||
mappedBanks[mapped] = customer
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
||||
|
@ -44,6 +47,7 @@ class Mapper {
|
|||
mapped.iconUrl = customer.iconUrl
|
||||
|
||||
mapped.userSetDisplayName = customer.userSetDisplayName
|
||||
mapped.displayIndex = customer.displayIndex
|
||||
|
||||
mapped.accounts = NSOrderedSet(array: map(mapped, customer.accounts, context))
|
||||
|
||||
|
@ -66,9 +70,12 @@ class Mapper {
|
|||
mapped.haveAllTransactionsBeenFetched = account.haveAllTransactionsBeenFetched
|
||||
|
||||
mapped.userSetDisplayName = account.userSetDisplayName
|
||||
mapped.displayIndex = account.displayIndex
|
||||
|
||||
mapped.bookedTransactions = map(mapped, account.transactions as? Set<PersistedAccountTransaction>)
|
||||
|
||||
mapped.technicalId = account.objectIDAsString
|
||||
|
||||
mappedAccounts[mapped] = account
|
||||
|
||||
return mapped
|
||||
|
@ -101,6 +108,7 @@ class Mapper {
|
|||
mapped.haveAllTransactionsBeenFetched = account.haveAllTransactionsBeenFetched
|
||||
|
||||
mapped.userSetDisplayName = account.userSetDisplayName
|
||||
mapped.displayIndex = account.displayIndex
|
||||
|
||||
mapped.transactions = NSSet(array: map(mapped, account.bookedTransactions, context))
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ struct AccountsTab: View {
|
|||
Form {
|
||||
AllBanksListItem(banks: data.banks)
|
||||
|
||||
ForEach(data.banks) { bank in
|
||||
ForEach(data.banks.sortedByDisplayIndex()) { bank in
|
||||
BankListItem(bank: bank)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,6 @@ struct SettingsDialog: View {
|
|||
@Inject var presenter: BankingPresenterSwift
|
||||
|
||||
|
||||
private var banksSorted: [Customer] {
|
||||
return data.banks.sorted { $0.displayIndex <= $1.displayIndex }
|
||||
}
|
||||
|
||||
|
||||
@State private var askToDeleteAccountMessage: Message? = nil
|
||||
|
||||
|
||||
|
@ -21,11 +16,12 @@ struct SettingsDialog: View {
|
|||
Form {
|
||||
Section(header: EditButton().frame(maxWidth: .infinity, alignment: .trailing)
|
||||
.overlay(Text("Bank Credentials"), alignment: .leading)) {
|
||||
ForEach(banksSorted) { bank in
|
||||
ForEach(data.banksSorted) { bank in
|
||||
NavigationLink(destination: LazyView(BankSettingsDialog(bank))) {
|
||||
IconedTitleView(bank)
|
||||
}
|
||||
}
|
||||
.onMove(perform: reorderBanks)
|
||||
.onDelete(perform: deleteBanks)
|
||||
}
|
||||
}
|
||||
|
@ -36,9 +32,17 @@ struct SettingsDialog: View {
|
|||
}
|
||||
|
||||
|
||||
func reorderBanks(from sourceIndices: IndexSet, to destinationIndex: Int) {
|
||||
let _ = data.banksSorted.reorder(from: sourceIndices, to: destinationIndex)
|
||||
|
||||
data.banksDisplayIndexChanged()
|
||||
|
||||
presenter.allAccountsUpdated()
|
||||
}
|
||||
|
||||
func deleteBanks(at offsets: IndexSet) {
|
||||
for offset in offsets {
|
||||
let bankToDelete = banksSorted[offset]
|
||||
let bankToDelete = data.banksSorted[offset]
|
||||
askUserToDeleteAccount(bankToDelete)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,7 +91,13 @@ open class fints4kModelMapper {
|
|||
|
||||
|
||||
open fun mapBankAccounts(customer: Customer, accountData: List<AccountData>): List<BankAccount> {
|
||||
return accountData.map { mapBankAccount(customer, it) }
|
||||
return accountData.mapIndexed { index, account ->
|
||||
val mappedAccount = mapBankAccount(customer, account)
|
||||
|
||||
mappedAccount.displayIndex = index
|
||||
|
||||
mappedAccount
|
||||
}
|
||||
}
|
||||
|
||||
open fun mapBankAccount(customer: Customer, accountData: AccountData): BankAccount {
|
||||
|
|
Loading…
Reference in New Issue