Implement transaction editing and deleting
Signed-off-by: Billy Brawner <billy@wbrawner.com>
This commit is contained in:
parent
ad2fb25e9d
commit
df9cec6cf7
11 changed files with 426 additions and 135 deletions
|
@ -7,7 +7,8 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
2821266023555FD300072D52 /* EditTransactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2821265F23555FD300072D52 /* EditTransactionView.swift */; };
|
||||
2821266023555FD300072D52 /* EditTransactionForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2821265F23555FD300072D52 /* EditTransactionForm.swift */; };
|
||||
282126622357E45F00072D52 /* TransactionEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 282126612357E45F00072D52 /* TransactionEditView.swift */; };
|
||||
284102252341998300EAFA29 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 284102242341998300EAFA29 /* ContentView.swift */; };
|
||||
2841022723419A2B00EAFA29 /* TabbedBudgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2841022623419A2B00EAFA29 /* TabbedBudgetView.swift */; };
|
||||
2841022C2342D8E400EAFA29 /* Budget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2841022B2342D8E400EAFA29 /* Budget.swift */; };
|
||||
|
@ -63,7 +64,8 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
2821265F23555FD300072D52 /* EditTransactionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditTransactionView.swift; sourceTree = "<group>"; };
|
||||
2821265F23555FD300072D52 /* EditTransactionForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditTransactionForm.swift; sourceTree = "<group>"; };
|
||||
282126612357E45F00072D52 /* TransactionEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionEditView.swift; sourceTree = "<group>"; };
|
||||
284102242341998300EAFA29 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
2841022623419A2B00EAFA29 /* TabbedBudgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbedBudgetView.swift; sourceTree = "<group>"; };
|
||||
2841022B2342D8E400EAFA29 /* Budget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Budget.swift; sourceTree = "<group>"; };
|
||||
|
@ -246,7 +248,8 @@
|
|||
28FE6B03234449DC00D5543E /* TransactionListView.swift */,
|
||||
28FE6B0523444A9800D5543E /* TransactionDetailsView.swift */,
|
||||
28A1E959235006A300CA57FE /* AddTransactionView.swift */,
|
||||
2821265F23555FD300072D52 /* EditTransactionView.swift */,
|
||||
2821265F23555FD300072D52 /* EditTransactionForm.swift */,
|
||||
282126612357E45F00072D52 /* TransactionEditView.swift */,
|
||||
);
|
||||
path = Transaction;
|
||||
sourceTree = "<group>";
|
||||
|
@ -406,7 +409,8 @@
|
|||
28FE6AFE234428BF00D5543E /* DataStoreProvider.swift in Sources */,
|
||||
28A1E95A235006A300CA57FE /* AddTransactionView.swift in Sources */,
|
||||
28AC94EE233C373900BFB70A /* AppDelegate.swift in Sources */,
|
||||
2821266023555FD300072D52 /* EditTransactionView.swift in Sources */,
|
||||
2821266023555FD300072D52 /* EditTransactionForm.swift in Sources */,
|
||||
282126622357E45F00072D52 /* TransactionEditView.swift in Sources */,
|
||||
28AC94F0233C373900BFB70A /* SceneDelegate.swift in Sources */,
|
||||
28FE6AFC23441E4500D5543E /* CategoryRepository.swift in Sources */,
|
||||
2841022C2342D8E400EAFA29 /* Budget.swift in Sources */,
|
||||
|
|
|
@ -923,8 +923,8 @@
|
|||
filePath = "BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "268"
|
||||
endingLineNumber = "268"
|
||||
startingLineNumber = "290"
|
||||
endingLineNumber = "290"
|
||||
landmarkName = "buildRequest(endPoint:method:data:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
|
@ -939,87 +939,10 @@
|
|||
filePath = "BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "267"
|
||||
endingLineNumber = "267"
|
||||
startingLineNumber = "289"
|
||||
endingLineNumber = "289"
|
||||
landmarkName = "buildRequest(endPoint:method:data:)"
|
||||
landmarkType = "7">
|
||||
<Locations>
|
||||
<Location
|
||||
uuid = "4657DB47-280A-41EE-B534-09C6F57D8DF8 - 662d42a959a71afc"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "closure #2 (Foundation.Data, __C.NSURLResponse) throws -> Foundation.Data in BudgetApp.RequestHelper.(buildRequest in _49C38939E0AD4FDF6F9F222ABD721B8E)<A where A: Swift.Decodable, A: Swift.Encodable>(endPoint: Swift.String, method: Swift.String, data: Swift.Optional<Swift.Encodable>) -> Combine.AnyPublisher<A, BudgetApp.NetworkError>"
|
||||
moduleName = "BudgetApp"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/billy/Projects/Budget/BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "267"
|
||||
endingLineNumber = "267"
|
||||
offsetFromSymbolStart = "540">
|
||||
</Location>
|
||||
<Location
|
||||
uuid = "4657DB47-280A-41EE-B534-09C6F57D8DF8 - 662d42a959a71afc"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "closure #2 (Foundation.Data, __C.NSURLResponse) throws -> Foundation.Data in BudgetApp.RequestHelper.(buildRequest in _49C38939E0AD4FDF6F9F222ABD721B8E)<A where A: Swift.Decodable, A: Swift.Encodable>(endPoint: Swift.String, method: Swift.String, data: Swift.Optional<Swift.Encodable>) -> Combine.AnyPublisher<A, BudgetApp.NetworkError>"
|
||||
moduleName = "BudgetApp"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/billy/Projects/Budget/BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "267"
|
||||
endingLineNumber = "267"
|
||||
offsetFromSymbolStart = "760">
|
||||
</Location>
|
||||
<Location
|
||||
uuid = "4657DB47-280A-41EE-B534-09C6F57D8DF8 - 662d42a959a71afc"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "closure #2 (Foundation.Data, __C.NSURLResponse) throws -> Foundation.Data in BudgetApp.RequestHelper.(buildRequest in _49C38939E0AD4FDF6F9F222ABD721B8E)<A where A: Swift.Decodable, A: Swift.Encodable>(endPoint: Swift.String, method: Swift.String, data: Swift.Optional<Swift.Encodable>) -> Combine.AnyPublisher<A, BudgetApp.NetworkError>"
|
||||
moduleName = "BudgetApp"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/billy/Projects/Budget/BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "267"
|
||||
endingLineNumber = "267"
|
||||
offsetFromSymbolStart = "928">
|
||||
</Location>
|
||||
<Location
|
||||
uuid = "4657DB47-280A-41EE-B534-09C6F57D8DF8 - 662d42a959a71afc"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "closure #2 (Foundation.Data, __C.NSURLResponse) throws -> Foundation.Data in BudgetApp.RequestHelper.(buildRequest in _49C38939E0AD4FDF6F9F222ABD721B8E)<A where A: Swift.Decodable, A: Swift.Encodable>(endPoint: Swift.String, method: Swift.String, data: Swift.Optional<Swift.Encodable>) -> Combine.AnyPublisher<A, BudgetApp.NetworkError>"
|
||||
moduleName = "BudgetApp"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/billy/Projects/Budget/BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "267"
|
||||
endingLineNumber = "267"
|
||||
offsetFromSymbolStart = "1004">
|
||||
</Location>
|
||||
<Location
|
||||
uuid = "4657DB47-280A-41EE-B534-09C6F57D8DF8 - 662d42a959a71afc"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "closure #2 (Foundation.Data, __C.NSURLResponse) throws -> Foundation.Data in BudgetApp.RequestHelper.(buildRequest in _49C38939E0AD4FDF6F9F222ABD721B8E)<A where A: Swift.Decodable, A: Swift.Encodable>(endPoint: Swift.String, method: Swift.String, data: Swift.Optional<Swift.Encodable>) -> Combine.AnyPublisher<A, BudgetApp.NetworkError>"
|
||||
moduleName = "BudgetApp"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/billy/Projects/Budget/BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "267"
|
||||
endingLineNumber = "267"
|
||||
offsetFromSymbolStart = "1176">
|
||||
</Location>
|
||||
</Locations>
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
|
@ -1032,8 +955,8 @@
|
|||
filePath = "BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "271"
|
||||
endingLineNumber = "271"
|
||||
startingLineNumber = "293"
|
||||
endingLineNumber = "293"
|
||||
landmarkName = "buildRequest(endPoint:method:data:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
|
@ -1054,22 +977,6 @@
|
|||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "81B540BD-DA72-4649-9624-E5B94E110061"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "278"
|
||||
endingLineNumber = "278"
|
||||
landmarkName = "buildRequest(endPoint:method:data:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
|
@ -1080,8 +987,8 @@
|
|||
filePath = "BudgetApp/Network/BudgetApiService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "274"
|
||||
endingLineNumber = "274"
|
||||
startingLineNumber = "296"
|
||||
endingLineNumber = "296"
|
||||
landmarkName = "buildRequest(endPoint:method:data:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
|
@ -1128,8 +1035,8 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "131"
|
||||
endingLineNumber = "131"
|
||||
startingLineNumber = "150"
|
||||
endingLineNumber = "150"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
|
@ -1144,8 +1051,8 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "132"
|
||||
endingLineNumber = "132"
|
||||
startingLineNumber = "151"
|
||||
endingLineNumber = "151"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
<Locations>
|
||||
|
@ -1192,8 +1099,8 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "109"
|
||||
endingLineNumber = "109"
|
||||
startingLineNumber = "128"
|
||||
endingLineNumber = "128"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
|
@ -1208,8 +1115,8 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "110"
|
||||
endingLineNumber = "110"
|
||||
startingLineNumber = "129"
|
||||
endingLineNumber = "129"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
|
@ -1224,8 +1131,8 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "85"
|
||||
endingLineNumber = "85"
|
||||
startingLineNumber = "104"
|
||||
endingLineNumber = "104"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
|
@ -1240,8 +1147,8 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "86"
|
||||
endingLineNumber = "86"
|
||||
startingLineNumber = "105"
|
||||
endingLineNumber = "105"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
<Locations>
|
||||
|
@ -1288,8 +1195,8 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "87"
|
||||
endingLineNumber = "87"
|
||||
startingLineNumber = "106"
|
||||
endingLineNumber = "106"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
|
@ -1304,8 +1211,8 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "111"
|
||||
endingLineNumber = "111"
|
||||
startingLineNumber = "130"
|
||||
endingLineNumber = "130"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
|
@ -1320,11 +1227,187 @@
|
|||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "133"
|
||||
endingLineNumber = "133"
|
||||
startingLineNumber = "152"
|
||||
endingLineNumber = "152"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "44E1F344-2A01-41C9-9CEF-3AA78B75786F"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "70"
|
||||
endingLineNumber = "70"
|
||||
landmarkName = "init(_:transactionId:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "F1B20B89-EC27-4275-B5C2-42731837346D"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionDetailsView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "22"
|
||||
endingLineNumber = "22"
|
||||
landmarkName = "body"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "CCDAD304-E9B9-415D-8C32-DD16F0145D35"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionEditView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "29"
|
||||
endingLineNumber = "29"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "1443CC3F-35EB-4BFC-B8A0-AED0967623B3"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionEditView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "28"
|
||||
endingLineNumber = "28"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "72CF2BC4-4793-45C9-AB03-7BF0435C967D"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionEditView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "30"
|
||||
endingLineNumber = "30"
|
||||
landmarkName = "stateContent"
|
||||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "C4EFC6E6-28A6-4526-A39F-9ECBE3FD54C0"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionDataStore.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "104"
|
||||
endingLineNumber = "104"
|
||||
landmarkName = "deleteTransaction(_:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "10E6DF77-55D2-4A3B-9A2D-AB201E442563"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionDataStore.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "98"
|
||||
endingLineNumber = "98"
|
||||
landmarkName = "deleteTransaction(_:)"
|
||||
landmarkType = "7">
|
||||
<Locations>
|
||||
<Location
|
||||
uuid = "10E6DF77-55D2-4A3B-9A2D-AB201E442563 - 2056d968351e5ea4"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "BudgetApp.TransactionDataStore.__allocating_init(BudgetApp.TransactionRepository) -> BudgetApp.TransactionDataStore"
|
||||
moduleName = "BudgetApp"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/billy/Projects/Budget/BudgetApp/Transaction/TransactionDataStore.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "0"
|
||||
endingLineNumber = "0"
|
||||
offsetFromSymbolStart = "18">
|
||||
</Location>
|
||||
<Location
|
||||
uuid = "10E6DF77-55D2-4A3B-9A2D-AB201E442563 - 2dd9a0446d059f36"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "BudgetApp.TransactionDataStore.init(BudgetApp.TransactionRepository) -> BudgetApp.TransactionDataStore"
|
||||
moduleName = "BudgetApp"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/billy/Projects/Budget/BudgetApp/Transaction/TransactionDataStore.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "13"
|
||||
endingLineNumber = "13"
|
||||
offsetFromSymbolStart = "103">
|
||||
</Location>
|
||||
</Locations>
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "196C979E-2C3E-490A-8146-7B292B6271E7"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionDataStore.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "101"
|
||||
endingLineNumber = "101"
|
||||
landmarkName = "deleteTransaction(_:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "9B227992-1D58-4610-82C8-0615315761C3"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "BudgetApp/Transaction/TransactionDataStore.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "100"
|
||||
endingLineNumber = "100"
|
||||
landmarkName = "deleteTransaction(_:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
|
|
@ -240,8 +240,32 @@ class RequestHelper {
|
|||
)
|
||||
}
|
||||
|
||||
func delete<ResultType: Codable>(_ endPoint: String) -> AnyPublisher<ResultType, NetworkError> {
|
||||
return buildRequest(endPoint: endPoint, method: "DELETE")
|
||||
func delete(_ endPoint: String) -> AnyPublisher<Empty, NetworkError> {
|
||||
// Delete requests return no body so they need a special request helper
|
||||
guard let url = URL(string: self.baseUrl + endPoint) else {
|
||||
return Result.Publisher(.failure(.invalidUrl)).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
var request = URLRequest(url: url)
|
||||
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "DELETE"
|
||||
|
||||
let task = URLSession.shared.dataTaskPublisher(for: request)
|
||||
.tryMap { (_, res) -> Empty in
|
||||
guard let response = res as? HTTPURLResponse, 200...299 ~= response.statusCode else {
|
||||
switch (res as? HTTPURLResponse)?.statusCode {
|
||||
case 400: throw NetworkError.badRequest
|
||||
case 401, 403: throw NetworkError.unauthorized
|
||||
case 404: throw NetworkError.notFound
|
||||
default: throw NetworkError.unknown
|
||||
}
|
||||
}
|
||||
return Empty()
|
||||
}
|
||||
.mapError {
|
||||
return NetworkError.jsonParsingFailed($0)
|
||||
}
|
||||
return task.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
private func buildRequest<ResultType: Codable>(
|
||||
|
@ -251,9 +275,7 @@ class RequestHelper {
|
|||
) -> AnyPublisher<ResultType, NetworkError> {
|
||||
|
||||
guard let url = URL(string: self.baseUrl + endPoint) else {
|
||||
return Future<ResultType, NetworkError> { promise in
|
||||
promise(.failure(.invalidUrl))
|
||||
}.eraseToAnyPublisher()
|
||||
return Result.Publisher(.failure(.invalidUrl)).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
var request = URLRequest(url: url)
|
||||
|
@ -308,6 +330,7 @@ enum NetworkError: Error, Equatable {
|
|||
case loading
|
||||
case unknown
|
||||
case notFound
|
||||
case deleted
|
||||
case unauthorized
|
||||
case badRequest
|
||||
case invalidUrl
|
||||
|
|
|
@ -28,7 +28,7 @@ struct AddTransactionView: View {
|
|||
case .failure(.loading):
|
||||
return AnyView(EmbeddedLoadingView())
|
||||
default:
|
||||
return AnyView(EditTransactionView(
|
||||
return AnyView(EditTransactionForm(
|
||||
title: self.$title,
|
||||
description: self.$description,
|
||||
date: self.$date,
|
||||
|
@ -36,7 +36,8 @@ struct AddTransactionView: View {
|
|||
type: self.$type,
|
||||
budgetId: self.$budgetId,
|
||||
categoryId: self.$categoryId,
|
||||
dataStoreProvider: self.dataStoreProvider
|
||||
dataStoreProvider: self.dataStoreProvider,
|
||||
deleteAction: nil
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +64,15 @@ struct AddTransactionView: View {
|
|||
))
|
||||
})
|
||||
}
|
||||
.onDisappear {
|
||||
self.title = ""
|
||||
self.description = ""
|
||||
self.date = Date()
|
||||
self.amount = ""
|
||||
self.type = .expense
|
||||
self.budgetId = nil
|
||||
self.categoryId = nil
|
||||
}
|
||||
}
|
||||
|
||||
@ObservedObject var transactionDataStore: TransactionDataStore
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
struct EditTransactionView: View {
|
||||
struct EditTransactionForm: View {
|
||||
@Binding var title: String
|
||||
@Binding var description: String
|
||||
@Binding var date: Date
|
||||
|
@ -16,7 +16,9 @@ struct EditTransactionView: View {
|
|||
@Binding var type: TransactionType
|
||||
@Binding var budgetId: Int?
|
||||
@Binding var categoryId: Int?
|
||||
@State private var showingAlert = false
|
||||
let dataStoreProvider: DataStoreProvider
|
||||
let deleteAction: (() -> ())?
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
@ -32,6 +34,19 @@ struct EditTransactionView: View {
|
|||
}
|
||||
BudgetPicker(self.dataStoreProvider, budgetId: self.$budgetId)
|
||||
CategoryPicker(self.dataStoreProvider, budgetId: self.$budgetId, categoryId: self.$categoryId)
|
||||
if deleteAction != nil {
|
||||
Button(action: {
|
||||
self.showingAlert = true
|
||||
}) {
|
||||
Text("delete_transaction")
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
.alert(isPresented:$showingAlert) {
|
||||
Alert(title: Text("confirm_delete_transaction"), message: nil, primaryButton: .destructive(Text("delete"), action: deleteAction), secondaryButton: .cancel())
|
||||
}
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,3 +38,17 @@ enum TransactionType: Int, CaseIterable, Identifiable, Hashable {
|
|||
|
||||
var id: TransactionType { self }
|
||||
}
|
||||
|
||||
extension Transaction {
|
||||
var type: TransactionType {
|
||||
if (self.expense) {
|
||||
return .expense
|
||||
} else {
|
||||
return .income
|
||||
}
|
||||
}
|
||||
|
||||
var amountString: String {
|
||||
return String(Double(self.amount) / 100.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,28 @@ class TransactionDataStore: ObservableObject {
|
|||
})
|
||||
}
|
||||
|
||||
func deleteTransaction(_ transactionId: Int) {
|
||||
self.transaction = .failure(.loading)
|
||||
|
||||
_ = self.transactionRepository.deleteTransaction(transactionId)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveCompletion: { completion in
|
||||
switch completion {
|
||||
case .finished:
|
||||
return
|
||||
case .failure(let error):
|
||||
self.transaction = .failure(error)
|
||||
}
|
||||
}, receiveValue: { (empty) in
|
||||
self.transaction = .failure(.deleted)
|
||||
})
|
||||
}
|
||||
|
||||
func reset() {
|
||||
self.transaction = .failure(.unknown)
|
||||
self.transactions = .failure(.loading)
|
||||
}
|
||||
|
||||
let objectWillChange = ObservableObjectPublisher()
|
||||
private let transactionRepository: TransactionRepository
|
||||
init(_ transactionRepository: TransactionRepository) {
|
||||
|
|
|
@ -9,8 +9,17 @@
|
|||
import SwiftUI
|
||||
|
||||
struct TransactionDetailsView: View {
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
@State var shouldNavigateUp: Bool = false
|
||||
var body: some View {
|
||||
stateContent
|
||||
.onAppear {
|
||||
if self.shouldNavigateUp {
|
||||
self.presentationMode.wrappedValue.dismiss()
|
||||
} else {
|
||||
self.transactionDataStore.getTransaction(self.transactionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stateContent: AnyView {
|
||||
|
@ -35,23 +44,33 @@ struct TransactionDetailsView: View {
|
|||
UserLineItem(self.dataStoreProvider, userId: transaction.createdBy)
|
||||
}.padding()
|
||||
}
|
||||
.navigationBarItems(trailing: NavigationLink(destination: EmptyView()) {
|
||||
.navigationBarItems(trailing: NavigationLink(
|
||||
destination: TransactionEditView(
|
||||
self.dataStoreProvider,
|
||||
transaction: transaction,
|
||||
shouldNavigateUp: self.$shouldNavigateUp
|
||||
).navigationBarTitle("edit_transaction")
|
||||
) {
|
||||
Text("edit")
|
||||
}))
|
||||
case .failure(.loading):
|
||||
return AnyView(EmbeddedLoadingView())
|
||||
case.failure(.deleted):
|
||||
self.presentationMode.wrappedValue.dismiss()
|
||||
return AnyView(EmptyView())
|
||||
default:
|
||||
return AnyView(Text("transaction_details_error"))
|
||||
}
|
||||
}
|
||||
|
||||
let dataStoreProvider: DataStoreProvider
|
||||
let transactionId: Int
|
||||
@ObservedObject var transactionDataStore: TransactionDataStore
|
||||
init(_ dataStoreProvider: DataStoreProvider, transactionId: Int) {
|
||||
self.dataStoreProvider = dataStoreProvider
|
||||
let transactionDataStore = dataStoreProvider.transactionDataStore()
|
||||
transactionDataStore.getTransaction(transactionId)
|
||||
self.transactionDataStore = transactionDataStore
|
||||
self.transactionId = transactionId
|
||||
}
|
||||
}
|
||||
|
||||
|
|
89
BudgetApp/Transaction/TransactionEditView.swift
Normal file
89
BudgetApp/Transaction/TransactionEditView.swift
Normal file
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// TransactionEditView.swift
|
||||
// BudgetApp
|
||||
//
|
||||
// Created by Billy Brawner on 10/16/19.
|
||||
// Copyright © 2019 William Brawner. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct TransactionEditView: View {
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
var title: State<String>
|
||||
var description: State<String>
|
||||
var date: State<Date>
|
||||
var amount: State<String>
|
||||
var type: State<TransactionType>
|
||||
var budgetId: State<Int?>
|
||||
var categoryId: State<Int?>
|
||||
let createdBy: Int
|
||||
let id: Int?
|
||||
var shouldNavigateUp: Binding<Bool>
|
||||
|
||||
var stateContent: AnyView {
|
||||
switch transactionDataStore.transaction {
|
||||
case .success(_), .failure(.deleted):
|
||||
self.shouldNavigateUp.wrappedValue = true
|
||||
self.presentationMode.wrappedValue.dismiss()
|
||||
return AnyView(EmptyView())
|
||||
case .failure(.loading):
|
||||
return AnyView(EmbeddedLoadingView())
|
||||
default:
|
||||
return AnyView(EditTransactionForm(
|
||||
title: self.title.projectedValue,
|
||||
description: self.description.projectedValue,
|
||||
date: self.date.projectedValue,
|
||||
amount: self.amount.projectedValue,
|
||||
type: self.type.projectedValue,
|
||||
budgetId: self.budgetId.projectedValue,
|
||||
categoryId: self.categoryId.projectedValue,
|
||||
dataStoreProvider: self.dataStoreProvider,
|
||||
deleteAction: {
|
||||
self.transactionDataStore.deleteTransaction(self.id!)
|
||||
}
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
stateContent
|
||||
.navigationBarItems(trailing: Button("save") {
|
||||
let amount = Double(self.amount.wrappedValue) ?? 0.0
|
||||
self.transactionDataStore.saveTransaction(Transaction(
|
||||
id: self.id,
|
||||
title: self.title.wrappedValue,
|
||||
description: self.description.wrappedValue,
|
||||
date: self.date.wrappedValue,
|
||||
amount: Int(amount * 100.0),
|
||||
categoryId: self.categoryId.wrappedValue,
|
||||
expense: self.type.wrappedValue == TransactionType.expense,
|
||||
createdBy: self.createdBy,
|
||||
budgetId: self.budgetId.wrappedValue!
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@ObservedObject var transactionDataStore: TransactionDataStore
|
||||
let dataStoreProvider: DataStoreProvider
|
||||
init(_ dataStoreProvider: DataStoreProvider, transaction: Transaction, shouldNavigateUp: Binding<Bool>) {
|
||||
self.dataStoreProvider = dataStoreProvider
|
||||
self.transactionDataStore = dataStoreProvider.transactionDataStore()
|
||||
self.createdBy = try! dataStoreProvider.authenticationDataStore().currentUser.get().id!
|
||||
self.id = transaction.id
|
||||
self.title = State<String>(initialValue: transaction.title)
|
||||
self.description = State<String>(initialValue: transaction.description ?? "")
|
||||
self.date = State<Date>(initialValue: transaction.date)
|
||||
self.amount = State<String>(initialValue: transaction.amountString)
|
||||
self.type = State<TransactionType>(initialValue: transaction.type)
|
||||
self.budgetId = State<Int?>(initialValue: transaction.budgetId)
|
||||
self.categoryId = State<Int?>(initialValue: transaction.categoryId)
|
||||
self.shouldNavigateUp = shouldNavigateUp
|
||||
}
|
||||
}
|
||||
|
||||
struct TransactionEditView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
TransactionEditView(MockDataStoreProvider(), transaction: MockTransactionRepository.transaction, shouldNavigateUp: .constant(false))
|
||||
}
|
||||
}
|
|
@ -13,7 +13,9 @@ struct TransactionListView: View {
|
|||
@ObservedObject var transactionDataStore: TransactionDataStore
|
||||
|
||||
var body: some View {
|
||||
stateContent
|
||||
stateContent.onAppear {
|
||||
self.transactionDataStore.getTransactions(self.category)
|
||||
}
|
||||
}
|
||||
|
||||
var stateContent: AnyView {
|
||||
|
@ -37,10 +39,11 @@ struct TransactionListView: View {
|
|||
}
|
||||
|
||||
let dataStoreProvider: DataStoreProvider
|
||||
let category: Category?
|
||||
init(_ dataStoreProvider: DataStoreProvider, category: Category? = nil) {
|
||||
self.dataStoreProvider = dataStoreProvider
|
||||
self.transactionDataStore = dataStoreProvider.transactionDataStore()
|
||||
self.transactionDataStore.getTransactions(category)
|
||||
self.category = category
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ protocol TransactionRepository {
|
|||
func getTransaction(_ transactionId: Int) -> AnyPublisher<Transaction, NetworkError>
|
||||
func createTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError>
|
||||
func updateTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError>
|
||||
func deleteTransaction(_ transactionId: Int) -> AnyPublisher<Empty, NetworkError>
|
||||
}
|
||||
|
||||
class NetworkTransactionRepository: TransactionRepository {
|
||||
|
@ -38,6 +39,10 @@ class NetworkTransactionRepository: TransactionRepository {
|
|||
func updateTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError> {
|
||||
return apiService.updateTransaction(transaction)
|
||||
}
|
||||
|
||||
func deleteTransaction(_ transactionId: Int) -> AnyPublisher<Empty, NetworkError> {
|
||||
return apiService.deleteTransaction(transactionId)
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
@ -69,5 +74,9 @@ class MockTransactionRepository: TransactionRepository {
|
|||
func updateTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError> {
|
||||
return Result.Publisher(MockTransactionRepository.transaction).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func deleteTransaction(_ transactionId: Int) -> AnyPublisher<Empty, NetworkError> {
|
||||
return Result.Publisher(.success(Empty())).eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue