Implemented SettingsDialog and BankSettingsDialog
This commit is contained in:
parent
fa9af8155a
commit
78af51984d
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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?";
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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?";
|
||||
|
|
|
@ -17,6 +17,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])
|
||||
|
||||
|
@ -40,6 +42,8 @@ class Mapper {
|
|||
mapped.customerName = customer.customerName
|
||||
mapped.userId = customer.userId
|
||||
mapped.iconUrl = customer.iconUrl
|
||||
|
||||
mapped.userSetDisplayName = customer.userSetDisplayName
|
||||
|
||||
mapped.accounts = NSOrderedSet(array: map(mapped, customer.accounts, context))
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
|
||||
}
|
|
@ -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())
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue