Implemented SettingsDialog and BankSettingsDialog

This commit is contained in:
dankito 2020-08-08 18:28:15 +02:00
parent fa9af8155a
commit 78af51984d
9 changed files with 358 additions and 29 deletions

View File

@ -61,6 +61,14 @@
36C4009D24D3236B005227AD /* UrlUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36C4009C24D3236B005227AD /* UrlUtil.swift */; };
36E21ECB24D88DF000649DC8 /* UIKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21ECA24D88DF000649DC8 /* UIKitExtensions.swift */; };
36E21ECF24DA0EEE00649DC8 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21ECE24DA0EEE00649DC8 /* IconView.swift */; };
36E21ED124DC540400649DC8 /* SettingsDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21ED024DC540400649DC8 /* SettingsDialog.swift */; };
36E21ED524DC549800649DC8 /* BankSettingsDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21ED424DC549800649DC8 /* BankSettingsDialog.swift */; };
36E21ED724DC617200649DC8 /* BankAccountSettingsDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21ED624DC617200649DC8 /* BankAccountSettingsDialog.swift */; };
36E21EDB24DC990300649DC8 /* LabelledUIKitTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21EDA24DC990300649DC8 /* LabelledUIKitTextField.swift */; };
36E21EDD24DCA89100649DC8 /* TanProcedurePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21EDC24DCA89100649DC8 /* TanProcedurePicker.swift */; };
36E21EDF24DCCC2700649DC8 /* CheckmarkListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21EDE24DCCC2700649DC8 /* CheckmarkListItem.swift */; };
36E21EE324DEC7A700649DC8 /* CoreDataBankingPersistenceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21EE224DEC7A700649DC8 /* CoreDataBankingPersistenceTest.swift */; };
36E21EE524DEC89400649DC8 /* CoreDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E21EE424DEC89400649DC8 /* CoreDataManager.swift */; };
36E7BA1424B3D05C00757859 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E7BA1324B3D05C00757859 /* ViewExtensions.swift */; };
36FC929C24B39A05002B12E9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FC929B24B39A05002B12E9 /* AppDelegate.swift */; };
36FC929E24B39A05002B12E9 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FC929D24B39A05002B12E9 /* SceneDelegate.swift */; };
@ -164,6 +172,14 @@
36C4009C24D3236B005227AD /* UrlUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlUtil.swift; sourceTree = "<group>"; };
36E21ECA24D88DF000649DC8 /* UIKitExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitExtensions.swift; sourceTree = "<group>"; };
36E21ECE24DA0EEE00649DC8 /* IconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconView.swift; sourceTree = "<group>"; };
36E21ED024DC540400649DC8 /* SettingsDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDialog.swift; sourceTree = "<group>"; };
36E21ED424DC549800649DC8 /* BankSettingsDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankSettingsDialog.swift; sourceTree = "<group>"; };
36E21ED624DC617200649DC8 /* BankAccountSettingsDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankAccountSettingsDialog.swift; sourceTree = "<group>"; };
36E21EDA24DC990300649DC8 /* LabelledUIKitTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelledUIKitTextField.swift; sourceTree = "<group>"; };
36E21EDC24DCA89100649DC8 /* TanProcedurePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TanProcedurePicker.swift; sourceTree = "<group>"; };
36E21EDE24DCCC2700649DC8 /* CheckmarkListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckmarkListItem.swift; sourceTree = "<group>"; };
36E21EE224DEC7A700649DC8 /* CoreDataBankingPersistenceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataBankingPersistenceTest.swift; sourceTree = "<group>"; };
36E21EE424DEC89400649DC8 /* CoreDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataManager.swift; sourceTree = "<group>"; };
36E7BA1324B3D05C00757859 /* ViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewExtensions.swift; sourceTree = "<group>"; };
36E7BA1824B9E70C00757859 /* xcode-frameworks */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "xcode-frameworks"; path = "../../tools/BankFinder/build/xcode-frameworks"; sourceTree = "<group>"; };
36FC929824B39A05002B12E9 /* BankingiOSApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BankingiOSApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -221,6 +237,21 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
3607829424DF05460098FEFE /* BankIconFinder */ = {
isa = PBXGroup;
children = (
36C4009724D23580005227AD /* SwiftBankIconFinderTest.swift */,
);
path = BankIconFinder;
sourceTree = "<group>";
};
3607829524DF05660098FEFE /* fints4k */ = {
isa = PBXGroup;
children = (
);
path = fints4k;
sourceTree = "<group>";
};
36BCF87924BFA679005BEC29 /* persistence */ = {
isa = PBXGroup;
children = (
@ -246,6 +277,15 @@
path = BankIconFinder;
sourceTree = "<group>";
};
36E21EE024DEC70C00649DC8 /* persistence */ = {
isa = PBXGroup;
children = (
36E21EE224DEC7A700649DC8 /* CoreDataBankingPersistenceTest.swift */,
36E21EE424DEC89400649DC8 /* CoreDataManager.swift */,
);
path = persistence;
sourceTree = "<group>";
};
36FC928F24B39A05002B12E9 = {
isa = PBXGroup;
children = (
@ -300,6 +340,9 @@
36FC92B424B39A08002B12E9 /* BankingiOSAppTests */ = {
isa = PBXGroup;
children = (
3607829524DF05660098FEFE /* fints4k */,
3607829424DF05460098FEFE /* BankIconFinder */,
36E21EE024DEC70C00649DC8 /* persistence */,
36FC92B524B39A08002B12E9 /* BankingiOSAppTests.swift */,
36FC92B724B39A08002B12E9 /* Info.plist */,
);
@ -355,6 +398,8 @@
36BE069024CEF52800CBBB68 /* UpdateButton.swift */,
36BE06B424CF85A300CBBB68 /* AmountLabel.swift */,
36BE06C724D0DE7400CBBB68 /* UIKitTextField.swift */,
36E21EDA24DC990300649DC8 /* LabelledUIKitTextField.swift */,
36E21EDC24DCA89100649DC8 /* TanProcedurePicker.swift */,
);
path = ui;
sourceTree = "<group>";
@ -368,19 +413,22 @@
36BCF88224C098BB005BEC29 /* BankListItem.swift */,
36BCF88424C098C8005BEC29 /* BankAccountListItem.swift */,
36BCF88A24C0BD2D005BEC29 /* AccountTransactionsDialog.swift */,
36C4009724D23580005227AD /* SwiftBankIconFinderTest.swift */,
36BE066424CDE62800CBBB68 /* AccountTransactionListItem.swift */,
36BCF88C24C1C1EA005BEC29 /* TransferMoneyDialog.swift */,
366FA4DB24C479120094F009 /* BankInfoListItem.swift */,
366FA4DF24C4924A0094F009 /* RemitteeListItem.swift */,
366FA4E124C4ED6C0094F009 /* EnterTanDialog.swift */,
36BE064E24C9A17F00CBBB68 /* ImageTanView.swift */,
36E21ED024DC540400649DC8 /* SettingsDialog.swift */,
36E21ED424DC549800649DC8 /* BankSettingsDialog.swift */,
36E21ED624DC617200649DC8 /* BankAccountSettingsDialog.swift */,
36BE065624C9E04800CBBB68 /* UIKitImageView.swift */,
36BE065824CA3CAB00CBBB68 /* UIKitSearchBar.swift */,
36BE065A24CA4B3500CBBB68 /* SelectBankDialog.swift */,
36BE065C24CB08FB00CBBB68 /* LazyView.swift */,
36C4009A24D2F9E4005227AD /* IconedTitleView.swift */,
36E21ECE24DA0EEE00649DC8 /* IconView.swift */,
36E21EDE24DCCC2700649DC8 /* CheckmarkListItem.swift */,
);
path = views;
sourceTree = "<group>";
@ -550,6 +598,7 @@
36BE065924CA3CAB00CBBB68 /* UIKitSearchBar.swift in Sources */,
36BE06C824D0DE7400CBBB68 /* UIKitTextField.swift in Sources */,
36BE064F24C9A17F00CBBB68 /* ImageTanView.swift in Sources */,
36E21EDB24DC990300649DC8 /* LabelledUIKitTextField.swift in Sources */,
36BE068D24CE41E700CBBB68 /* Styles.swift in Sources */,
36E21ECB24D88DF000649DC8 /* UIKitExtensions.swift in Sources */,
366FA4E224C4ED6C0094F009 /* EnterTanDialog.swift in Sources */,
@ -565,11 +614,14 @@
36BE06B324CF133400CBBB68 /* JsonEncoderSerializer.swift in Sources */,
36BE06BA24D0783900CBBB68 /* FaviconFinder.swift in Sources */,
36BCF89524C31F02005BEC29 /* AppData.swift in Sources */,
36E21EDD24DCA89100649DC8 /* TanProcedurePicker.swift in Sources */,
36BE065B24CA4B3500CBBB68 /* SelectBankDialog.swift in Sources */,
36E21ED524DC549800649DC8 /* BankSettingsDialog.swift in Sources */,
36BE068924CE288800CBBB68 /* CollapsibleText.swift in Sources */,
36BE06B524CF85A300CBBB68 /* AmountLabel.swift in Sources */,
36BCF88324C098BB005BEC29 /* BankListItem.swift in Sources */,
36BCF88D24C1C1EA005BEC29 /* TransferMoneyDialog.swift in Sources */,
36E21EDF24DCCC2700649DC8 /* CheckmarkListItem.swift in Sources */,
36E7BA1424B3D05C00757859 /* ViewExtensions.swift in Sources */,
36BCF88924C0A7D7005BEC29 /* Message.swift in Sources */,
366FA4E024C4924A0094F009 /* RemitteeListItem.swift in Sources */,
@ -586,9 +638,11 @@
36C4009B24D2F9E4005227AD /* IconedTitleView.swift in Sources */,
36BE065724C9E04800CBBB68 /* UIKitImageView.swift in Sources */,
36BCF88724C0A310005BEC29 /* PreviewData.swift in Sources */,
36E21ED724DC617200649DC8 /* BankAccountSettingsDialog.swift in Sources */,
366FA4DA24C472A90094F009 /* Extensions.swift in Sources */,
36BE068F24CEE1BD00CBBB68 /* AllBanksListItem.swift in Sources */,
36BE069124CEF52800CBBB68 /* UpdateButton.swift in Sources */,
36E21ED124DC540400649DC8 /* SettingsDialog.swift in Sources */,
366FA4DC24C479120094F009 /* BankInfoListItem.swift in Sources */,
36FC929E24B39A05002B12E9 /* SceneDelegate.swift in Sources */,
36E21ECF24DA0EEE00649DC8 /* IconView.swift in Sources */,
@ -605,6 +659,8 @@
files = (
36C4009824D23580005227AD /* SwiftBankIconFinderTest.swift in Sources */,
36FC92B624B39A08002B12E9 /* BankingiOSAppTests.swift in Sources */,
36E21EE524DEC89400649DC8 /* CoreDataManager.swift in Sources */,
36E21EE324DEC7A700649DC8 /* CoreDataBankingPersistenceTest.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -52,6 +52,7 @@
<attribute name="supportsRetrievingBalance" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="supportsTransferringMoney" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="type" attributeType="String"/>
<attribute name="userSetDisplayName" optional="YES" attributeType="String"/>
<relationship name="customer" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PersistedCustomer" inverseName="accounts" inverseEntity="PersistedCustomer"/>
<relationship name="transactions" toMany="YES" deletionRule="Cascade" destinationEntity="PersistedAccountTransaction" inverseName="account" inverseEntity="PersistedAccountTransaction"/>
</entity>

View File

@ -1,6 +1,7 @@
"OK" = "OK";
"Cancel" = "Cancel";
"Done" = "Done";
"Add" = "Add";
"New" = "New";
@ -15,6 +16,12 @@
"All accounts" = "All accounts";
"Add account" = "Add account";
"IBAN" = "IBAN";
"BIC" = "BIC";
"Bank Code" = "Bank Code";
"Settings" = "Settings";
/* SelectBankDialog */
@ -73,3 +80,14 @@
"TAN medium change" = "TAN medium change";
"TAN medium successfully changed to %@." = "TAN medium successfully changed to '%@'.";
"Could not change TAN medium to %@. Error: %@." = "Could not change TAN medium to '%@'.\n\nError message from your bank:\n\n%@.";
/* BankSettingsDialog */
"Credentials" = "Credentials";
"Customer name" = "Customer name";
"FinTS server address" = "FinTS server address";
"Unsaved changes" = "Unsaved changes";
"Changed data hasn't been saved. Are you sure you want to discard them?" = "Changed data hasn't been saved. Are you sure you want to discard them?";

View File

@ -29,6 +29,7 @@ struct ContentView: View {
@State private var navigationBarTitle = ""
@State private var leadingNavigationBarItem: AnyView? = nil
@State private var trailingNavigationBarItem: AnyView? = nil
@State private var showNewOptionsActionSheet = false
@ -53,10 +54,6 @@ struct ContentView: View {
.onAppear {
self.savelySetAccountsTabNavigationBar()
}
.onDisappear {
self.navigationBarTitle = ""
self.leadingNavigationBarItem = nil
}
.tabItem {
VStack {
Image("accounts")
@ -80,6 +77,9 @@ struct ContentView: View {
self.generateNewActionSheet()
})
}
.onAppear {
self.resetNavigationBar()
}
.tabItem {
VStack {
Image(systemName: "plus.circle.fill")
@ -88,10 +88,23 @@ struct ContentView: View {
}
.tag(Self.OverlayTabIndex)
/* Third tab: Settings dialog */
SettingsDialog(data: data)
.onAppear {
self.savelySetSettingsTabNavigationBar()
}
.tabItem {
VStack {
Image("gear.fill")
Text("Settings")
}
}
.tag(2)
}
.navigationBarHidden(false)
.navigationBarTitle(navigationBarTitle.localize())
.navigationBarItems(leading: leadingNavigationBarItem)
.showNavigationBarTitle(LocalizedStringKey(navigationBarTitle))
}
}
@ -122,23 +135,41 @@ struct ContentView: View {
self.selectedTab = self.previousSelectedTab
}
private func savelySetAccountsTabNavigationBar() {
setAccountsTabNavigationBar()
let leadingItem = data.hasAtLeastOneAccountBeenAdded == false ? nil : AnyView(UpdateButton { _ in
self.presenter.updateAccountsTransactionsAsync { _ in }
})
savelySetNavigationBar("Accounts", leadingItem)
}
private func savelySetSettingsTabNavigationBar() {
savelySetNavigationBar("Settings", nil, nil)
}
private func savelySetNavigationBar(_ title: String, _ leadingNavigationBarItem: AnyView? = nil, _ trailingNavigationBarItem: AnyView? = nil) {
setNavigationBar(title, leadingNavigationBarItem, trailingNavigationBarItem)
DispatchQueue.main.async { // when pressing 'Cancel' on ActionSheet navigation bar has to be set asynchronously (why, SwiftUI?)
self.setAccountsTabNavigationBar()
self.setNavigationBar(title, leadingNavigationBarItem, trailingNavigationBarItem)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { // can't believe it, sometimes even DispatchQueue.main.async() doesn't work. Ok, so let's do it 1 second later again, then it works
self.setNavigationBar(title, leadingNavigationBarItem, trailingNavigationBarItem)
}
}
private func setAccountsTabNavigationBar() {
private func setNavigationBar(_ title: String, _ leadingNavigationBarItem: AnyView? = nil, _ trailingNavigationBarItem: AnyView? = nil) {
// due to a SwiftUI bug this cannot be set in AccountsTab directly, so i have to do it via the indirection of navigationBarTitle property
self.navigationBarTitle = "Accounts"
self.navigationBarTitle = title
if data.hasAtLeastOneAccountBeenAdded {
self.leadingNavigationBarItem = AnyView(UpdateButton { _ in
self.presenter.updateAccountsTransactionsAsync { _ in }
})
}
self.leadingNavigationBarItem = leadingNavigationBarItem
self.trailingNavigationBarItem = trailingNavigationBarItem
}
private func resetNavigationBar() {
self.setNavigationBar("", nil, nil)
}
}

View File

@ -1,6 +1,7 @@
"OK" = "OK";
"Cancel" = "Abbrechen";
"Done" = "Fertig";
"Add" = "Hinzufügen";
"New" = "Neu";
@ -15,6 +16,12 @@
"All accounts" = "Alle Konten";
"Add account" = "Konto hinzufügen";
"IBAN" = "IBAN";
"BIC" = "BIC";
"Bank Code" = "Bankleitzahl";
"Settings" = "Einstellungen";
/* SelectBankDialog */
@ -73,3 +80,14 @@
"TAN medium change" = "TAN Medium Wechsel";
"TAN medium successfully changed to %@." = "TAN Medium erfolgreich zu '%@' geändert.";
"Could not change TAN medium to %@. Error: %@." = "TAN medium konnte nicht zu '%@' geändert werden.\n\nFehlermeldung Ihrer Bank:\n\n%@.";
/* BankSettingsDialog */
"Credentials" = "Zugangsdaten";
"Customer name" = "Kontoinhaber";
"FinTS server address" = "FinTS Server";
"Unsaved changes" = "Nicht gespeicherte Änderungen";
"Changed data hasn't been saved. Are you sure you want to discard them?" = "Es wurden nicht alle Änderungen gespeichert. Sind Sie sich sicher, dass Sie sie verwerfen möchten?";

View File

@ -18,6 +18,8 @@ class Mapper {
func map(_ customer: PersistedCustomer) -> Customer {
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.accounts = map(mapped, customer.accounts?.array as? [PersistedBankAccount])
mappedBanks[mapped] = customer
@ -41,6 +43,8 @@ class Mapper {
mapped.userId = customer.userId
mapped.iconUrl = customer.iconUrl
mapped.userSetDisplayName = customer.userSetDisplayName
mapped.accounts = NSOrderedSet(array: map(mapped, customer.accounts, context))
mappedBanks[customer] = mapped
@ -59,6 +63,8 @@ class Mapper {
func map(_ customer: Customer, _ account: PersistedBankAccount) -> BankAccount {
let mapped = BankAccount(customer: customer, identifier: map(account.identifier), accountHolderName: map(account.accountHolderName), iban: account.iban, subAccountNumber: account.subAccountNumber, customerId: map(account.customerId), balance: map(account.balance), currency: map(account.currency), type: map(account.type), productName: account.productName, accountLimit: account.accountLimit, lastRetrievedTransactionsTimestamp: map(account.lastRetrievedTransactionsTimestamp), supportsRetrievingAccountTransactions: account.supportsRetrievingAccountTransactions, supportsRetrievingBalance: account.supportsRetrievingBalance, supportsTransferringMoney: account.supportsTransferringMoney, supportsInstantPaymentMoneyTransfer: account.supportsInstantPaymentMoneyTransfer, bookedTransactions: [], unbookedTransactions: [])
mapped.userSetDisplayName = account.userSetDisplayName
mapped.bookedTransactions = map(mapped, account.transactions as? Set<PersistedAccountTransaction>)
mappedAccounts[mapped] = account
@ -90,6 +96,8 @@ class Mapper {
mapped.supportsTransferringMoney = account.supportsTransferringMoney
mapped.supportsInstantPaymentMoneyTransfer = account.supportsInstantPaymentMoneyTransfer
mapped.userSetDisplayName = account.userSetDisplayName
mapped.transactions = NSSet(array: map(mapped, account.bookedTransactions, context))
mappedAccounts[account] = mapped

View File

@ -16,23 +16,43 @@ extension View {
.navigationBarTitle(title, displayMode: displayMode)
}
func customNavigationBarBackButton(onBackButtonPressed: @escaping () -> Void) -> some View {
return self
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: Button(action: onBackButtonPressed) {
HStack {
Image(systemName: "chevron.left")
.font(.headline)
.padding(.horizontal, 0)
Text("Cancel")
.padding(.leading, 0)
}
.edgesIgnoringSafeArea(.leading)
.padding(.leading, 0)
})
.navigationBarItems(leading: createCancelButton(onBackButtonPressed))
}
func setCancelAndDoneNavigationBarButtons(onCancelPressed: @escaping () -> Void, onDonePressed: @escaping () -> Void) -> some View {
return self
.navigationBarHidden(false)
.navigationBarItems(leading: createCancelButton(onCancelPressed), trailing: createDoneButton(onDonePressed))
}
func createDoneButton(_ onDoneButtonPressed: @escaping () -> Void) -> some View {
return Button(action: onDoneButtonPressed) {
Text("Done")
.edgesIgnoringSafeArea(.leading)
.padding(.leading, 0)
}
}
func createCancelButton(_ onCancelButtonPressed: @escaping () -> Void) -> some View {
return Button(action: onCancelButtonPressed) {
HStack {
Image(systemName: "chevron.left")
.font(.headline)
.padding(.horizontal, 0)
Text("Cancel")
.padding(.leading, 0)
}
.edgesIgnoringSafeArea(.leading)
.padding(.leading, 0)
}
}
func detailForegroundColor() -> some View {
return self
.foregroundColor(Color.secondary)
@ -117,3 +137,25 @@ extension Binding {
}
}
extension NumberFormatter {
static var currency: NumberFormatter {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
return formatter
}
static func decimal(_ countMaxDecimalPlaces: Int) -> NumberFormatter {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = countMaxDecimalPlaces
return formatter
}
}

View File

@ -0,0 +1,124 @@
import SwiftUI
import BankingUiSwift
import UIKit
struct BankSettingsDialog: View {
@Environment(\.presentationMode) var presentation
@Inject private var presenter: BankingPresenterSwift
private let bank: Customer
@State private var displayName: String
@State private var customerId: String
@State private var password: String
@State private var selectedTanProcedure: TanProcedure?
@State private var unsavedChangesMessage: Message? = nil
private var hasUnsavedData: Bool {
return bank.displayName != displayName
|| bank.customerId != customerId
|| bank.password != password
|| bank.selectedTanProcedure != selectedTanProcedure
}
init(_ bank: Customer) {
self.bank = bank
_displayName = State(initialValue: bank.displayName)
_customerId = State(initialValue: bank.customerId)
_password = State(initialValue: bank.password)
_selectedTanProcedure = State(initialValue: bank.selectedTanProcedure)
}
var body: some View {
Form {
Section {
LabelledUIKitTextField(label: "Name", text: $displayName)
}
Section(header: Text("Credentials")) {
LabelledUIKitTextField(label: "Online banking login name", text: $customerId)
LabelledUIKitTextField(label: "Online banking login password", text: $password, isPasswordField: true)
}
Section {
TanProcedurePicker(bank) { selectedTanProcedure in
self.selectedTanProcedure = selectedTanProcedure
}
}
Section {
LabelledUIKitTextField(label: "Bank Code", value: bank.bankCode)
LabelledUIKitTextField(label: "BIC", value: bank.bic)
LabelledUIKitTextField(label: "Customer name", value: bank.customerName) // TODO: senseful?
LabelledUIKitTextField(label: "FinTS server address", value: bank.finTsServerAddress) // TODO: senseful?
}
Section(header: Text("Accounts")) {
ForEach(bank.accounts) { account in
Text(account.displayName)
}
}
}
.alert(item: $unsavedChangesMessage) { message in
Alert(title: message.title, message: message.message, primaryButton: message.primaryButton, secondaryButton: message.secondaryButton!)
}
.showNavigationBarTitle(LocalizedStringKey(bank.displayName))
.setCancelAndDoneNavigationBarButtons(onCancelPressed: cancelPressed, onDonePressed: donePressed)
}
private func cancelPressed() {
if hasUnsavedData {
self.unsavedChangesMessage = Message(title: Text("Unsaved changes"), message: Text("Changed data hasn't been saved. Are you sure you want to discard them?"), primaryButton: .ok(closeDialog), secondaryButton: .cancel())
}
else {
closeDialog()
}
}
private func donePressed() {
if hasUnsavedData {
bank.userSetDisplayName = displayName
bank.customerId = customerId
bank.password = password
bank.selectedTanProcedure = selectedTanProcedure
presenter.accountUpdated(account: bank)
}
closeDialog()
}
private func closeDialog() {
presentation.wrappedValue.dismiss()
}
}
struct BankSettingsDialog_Previews: PreviewProvider {
static var previews: some View {
BankSettingsDialog(previewBanks[0])
}
}

View File

@ -0,0 +1,31 @@
import SwiftUI
import BankingUiSwift
struct SettingsDialog: View {
@ObservedObject var data: AppData
@Inject var presenter: BankingPresenterSwift
var body: some View {
Form {
ForEach(data.banks.sorted(by: { $0.displayIndex >= $1.displayIndex })) { bank in
NavigationLink(destination: LazyView(BankSettingsDialog(bank))) {
IconedTitleView(bank)
}
}
}
}
}
struct SettingsDialog_Previews: PreviewProvider {
static var previews: some View {
SettingsDialog(data: AppData())
}
}