From 8914d83ec604840b2a9750818056f3b828019c6a Mon Sep 17 00:00:00 2001 From: dankito Date: Sun, 30 Aug 2020 23:37:49 +0200 Subject: [PATCH] Implemented sorting bank accounts; extracted SectionWithRightAlignedEditButton --- .../dankito/banking/ui/model/BankAccount.kt | 6 ++-- .../net/dankito/banking/ui/model/Customer.kt | 5 +++ .../banking/ui/presenter/BankingPresenter.kt | 1 + .../net/dankito/banking/util/Extensions.kt | 4 +++ .../BankingiOSApp.xcodeproj/project.pbxproj | 4 +++ .../ui/views/BankSettingsDialog.swift | 16 +++++++-- .../SectionWithRightAlignedEditButton.swift | 35 +++++++++++++++++++ .../ui/views/SettingsDialog.swift | 3 +- 8 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 ui/BankingiOSApp/BankingiOSApp/ui/views/SectionWithRightAlignedEditButton.swift diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankAccount.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankAccount.kt index 90d90057..1a263eac 100644 --- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankAccount.kt +++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/BankAccount.kt @@ -25,7 +25,7 @@ open class BankAccount @JvmOverloads constructor( open var supportsInstantPaymentMoneyTransfer: Boolean = false, open var bookedTransactions: List = listOf(), open var unbookedTransactions: List = listOf() -) { +) : OrderedDisplayable { internal constructor() : this(Customer(), null, "") // for object deserializers @@ -45,11 +45,13 @@ open class BankAccount @JvmOverloads constructor( open var userSetDisplayName: String? = null - open val displayName: String + override val displayName: String get() { return userSetDisplayName ?: productName ?: subAccountNumber ?: identifier } + override var displayIndex: Int = 0 + open fun addBookedTransactions(retrievedBookedTransactions: List) { val uniqueTransactions = this.bookedTransactions.toMutableSet() diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/Customer.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/Customer.kt index 64494531..cbac8a6e 100644 --- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/Customer.kt +++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/model/Customer.kt @@ -5,6 +5,7 @@ import net.dankito.utils.multiplatform.sum import net.dankito.banking.ui.model.tan.TanMedium import net.dankito.banking.ui.model.tan.TanMediumStatus import net.dankito.banking.ui.model.tan.TanProcedure +import net.dankito.banking.util.sortedByDisplayIndex import net.dankito.utils.multiplatform.UUID @@ -51,6 +52,10 @@ open class Customer( override var displayIndex: Int = 0 + open val accountsSorted: List + get() = accounts.sortedByDisplayIndex() + + open val balance: BigDecimal get() = accounts.map { it.balance }.sum() diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt index af235c6a..93471c59 100644 --- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt +++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/ui/presenter/BankingPresenter.kt @@ -155,6 +155,7 @@ open class BankingPresenter( newClient.addAccountAsync { response -> val account = response.customer + account.displayIndex = customers.size if (response.isSuccessful) { addClientForAccount(account, newClient) diff --git a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/util/Extensions.kt b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/util/Extensions.kt index 637ee011..420fa1f0 100644 --- a/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/util/Extensions.kt +++ b/ui/BankingUiCommon/src/commonMain/kotlin/net/dankito/banking/util/Extensions.kt @@ -31,6 +31,10 @@ fun Collection.containsExactly(otherCollection: Collection): Boolean { } +fun List.sortedByDisplayIndex(): List { + return this.sortedBy { it.displayIndex } +} + fun Collection.sortedByDisplayIndex(): Collection { return this.sortedBy { it.displayIndex } } \ No newline at end of file diff --git a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj index d8e830a0..22bfde45 100644 --- a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj +++ b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 360782D324F429F80098FEFE /* FlickerCodeStripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 360782D224F429F70098FEFE /* FlickerCodeStripe.swift */; }; 3608D6C224FBA9C6006C93A8 /* TrianglePointingDown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3608D6C124FBA9C6006C93A8 /* TrianglePointingDown.swift */; }; 3608D6C624FBAB41006C93A8 /* TanGeneratorPositionMarker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3608D6C524FBAB41006C93A8 /* TanGeneratorPositionMarker.swift */; }; + 366744E224FC4E96002B235A /* SectionWithRightAlignedEditButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366744E124FC4E96002B235A /* SectionWithRightAlignedEditButton.swift */; }; 366FA4DA24C472A90094F009 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366FA4D924C472A90094F009 /* Extensions.swift */; }; 366FA4DC24C479120094F009 /* BankInfoListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366FA4DB24C479120094F009 /* BankInfoListItem.swift */; }; 366FA4E024C4924A0094F009 /* RemitteeListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366FA4DF24C4924A0094F009 /* RemitteeListItem.swift */; }; @@ -148,6 +149,7 @@ 360782D224F429F70098FEFE /* FlickerCodeStripe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlickerCodeStripe.swift; sourceTree = ""; }; 3608D6C124FBA9C6006C93A8 /* TrianglePointingDown.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrianglePointingDown.swift; sourceTree = ""; }; 3608D6C524FBAB41006C93A8 /* TanGeneratorPositionMarker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TanGeneratorPositionMarker.swift; sourceTree = ""; }; + 366744E124FC4E96002B235A /* SectionWithRightAlignedEditButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionWithRightAlignedEditButton.swift; sourceTree = ""; }; 366FA4D924C472A90094F009 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 366FA4DB24C479120094F009 /* BankInfoListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankInfoListItem.swift; sourceTree = ""; }; 366FA4DF24C4924A0094F009 /* RemitteeListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemitteeListItem.swift; sourceTree = ""; }; @@ -465,6 +467,7 @@ 36E21EDE24DCCC2700649DC8 /* CheckmarkListItem.swift */, 3608D6C124FBA9C6006C93A8 /* TrianglePointingDown.swift */, 3608D6C524FBAB41006C93A8 /* TanGeneratorPositionMarker.swift */, + 366744E124FC4E96002B235A /* SectionWithRightAlignedEditButton.swift */, ); path = views; sourceTree = ""; @@ -638,6 +641,7 @@ 36BE068D24CE41E700CBBB68 /* Styles.swift in Sources */, 36E21ECB24D88DF000649DC8 /* UIKitExtensions.swift in Sources */, 360782C524E541970098FEFE /* ScaleImageView.swift in Sources */, + 366744E224FC4E96002B235A /* SectionWithRightAlignedEditButton.swift in Sources */, 366FA4E224C4ED6C0094F009 /* EnterTanDialog.swift in Sources */, 36FC92DC24B3A4A0002B12E9 /* AccountsTab.swift in Sources */, 36BCF86E24BA691B005BEC29 /* DependencyInjector.swift in Sources */, diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/BankSettingsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/BankSettingsDialog.swift index 78fc3955..5950a1a3 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/BankSettingsDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/BankSettingsDialog.swift @@ -19,6 +19,8 @@ struct BankSettingsDialog: View { @State private var selectedTanProcedure: TanProcedure? + @State private var accountsSorted: [BankAccount] + @State private var askUserToDeleteAccountOrSaveChangesMessage: Message? = nil @@ -39,6 +41,8 @@ struct BankSettingsDialog: View { _password = State(initialValue: bank.password) _selectedTanProcedure = State(initialValue: bank.selectedTanProcedure) + + _accountsSorted = State(initialValue: bank.accountsSorted) } @@ -70,12 +74,13 @@ struct BankSettingsDialog: View { LabelledUIKitTextField(label: "FinTS server address", value: bank.finTsServerAddress) // TODO: senseful? } - Section(header: Text("Accounts")) { - ForEach(bank.accounts.sorted(by: { $0.displayIndex <= $1.displayIndex })) { account in + SectionWithRightAlignedEditButton(sectionTitle: "Accounts") { + ForEach(accountsSorted) { account in NavigationLink(destination: LazyView(BankAccountSettingsDialog(account))) { Text(account.displayName) } } + .onMove(perform: reorderAccounts) } HStack { @@ -94,6 +99,13 @@ struct BankSettingsDialog: View { .showNavigationBarTitle(LocalizedStringKey(bank.displayName)) .setCancelAndDoneNavigationBarButtons(onCancelPressed: cancelPressed, onDonePressed: donePressed) } + + + func reorderAccounts(from source: IndexSet, to destination: Int) { + accountsSorted = accountsSorted.reorder(from: source, to: destination) + + presenter.accountUpdated(account: bank) + } func askUserToDeleteAccount() { diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/SectionWithRightAlignedEditButton.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/SectionWithRightAlignedEditButton.swift new file mode 100644 index 00000000..3863034e --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/SectionWithRightAlignedEditButton.swift @@ -0,0 +1,35 @@ +import SwiftUI + + +struct SectionWithRightAlignedEditButton: View { + + private let sectionTitle: String + + private let content: Content + + + init(sectionTitle: String, @ViewBuilder content: () -> Content) { + self.sectionTitle = sectionTitle + self.content = content() + } + + + var body: some View { + Section(header: EditButton().frame(maxWidth: .infinity, alignment: .trailing) + .overlay(Text(sectionTitle), alignment: .leading)) { + content + } + } + +} + + +struct SectionWithRightAlignedEditButton_Previews: PreviewProvider { + + static var previews: some View { + SectionWithRightAlignedEditButton(sectionTitle: "Section") { + Text("Body") + } + } + +} diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/SettingsDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/SettingsDialog.swift index 3187cfc4..999e575b 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/SettingsDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/SettingsDialog.swift @@ -14,8 +14,7 @@ struct SettingsDialog: View { var body: some View { Form { - Section(header: EditButton().frame(maxWidth: .infinity, alignment: .trailing) - .overlay(Text("Bank Credentials"), alignment: .leading)) { + SectionWithRightAlignedEditButton(sectionTitle: "Bank Credentials") { ForEach(data.banksSorted) { bank in NavigationLink(destination: LazyView(BankSettingsDialog(bank))) { IconedTitleView(bank)