diff --git a/WooCommerce/Classes/Bookings/BookingFilters/BookingDateTimeFilterView.swift b/WooCommerce/Classes/Bookings/BookingFilters/BookingDateTimeFilterView.swift index b93c110b733..2eb7d6a39d2 100644 --- a/WooCommerce/Classes/Bookings/BookingFilters/BookingDateTimeFilterView.swift +++ b/WooCommerce/Classes/Bookings/BookingFilters/BookingDateTimeFilterView.swift @@ -55,6 +55,14 @@ struct BookingDateTimeFilterView: View { .listStyle(.plain) .navigationTitle(Localization.title) .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button(Localization.clear) { + clearDateRange() + } + .renderedIf(selectedFromDate != nil || selectedToDate != nil) + } + } .background(Color(.listBackground)) .environment(\.timeZone, TimeZone(identifier: "UTC")!) // API treats dates as no timezone so use UTC to display and select dates .onChange(of: fromDate) { _, newValue in @@ -157,6 +165,12 @@ private extension BookingDateTimeFilterView { return fromDate...Date.distantFuture } } + + func clearDateRange() { + selectedFromDate = nil + selectedToDate = nil + expandedPicker = nil + } } private extension BookingDateTimeFilterView { @@ -186,6 +200,11 @@ private extension BookingDateTimeFilterView { value: "Time", comment: "Title of the Time row in the date time picker for booking filter" ) + static let clear = NSLocalizedString( + "bookingDateTimeFilterView.clear", + value: "Clear", + comment: "Title of the Clear button in the date time picker for booking filter" + ) } } diff --git a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj index 8cbb193824f..50c1c7c4921 100644 --- a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj +++ b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj @@ -998,6 +998,7 @@ 2D05FE962E8D71EA004111FD /* UpdateAttendanceStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D05FE952E8D71EA004111FD /* UpdateAttendanceStatusView.swift */; }; 2D09E0D12E61BC7F005C26F3 /* ApplicationPasswordsExperimentState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D09E0D02E61BC7D005C26F3 /* ApplicationPasswordsExperimentState.swift */; }; 2D09E0D52E65C9B9005C26F3 /* ApplicationPasswordsExperimentStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D09E0D42E65C9B9005C26F3 /* ApplicationPasswordsExperimentStateTests.swift */; }; + 2D200F072ED7245000DD6EBF /* BookingDateTimeFilterViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D200F062ED7245000DD6EBF /* BookingDateTimeFilterViewTests.swift */; }; 2D7A3E232E7891DB00C46401 /* CIABEligibilityCheckerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D7A3E222E7891D200C46401 /* CIABEligibilityCheckerTests.swift */; }; 2D880B492DFB2F3F00A6FB2C /* OptionalBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D880B482DFB2F3D00A6FB2C /* OptionalBinding.swift */; }; 2D88C1112DF883C300A6FB2C /* AttributedString+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D88C1102DF883BD00A6FB2C /* AttributedString+Helpers.swift */; }; @@ -3885,6 +3886,7 @@ 2D05FE952E8D71EA004111FD /* UpdateAttendanceStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateAttendanceStatusView.swift; sourceTree = ""; }; 2D09E0D02E61BC7D005C26F3 /* ApplicationPasswordsExperimentState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationPasswordsExperimentState.swift; sourceTree = ""; }; 2D09E0D42E65C9B9005C26F3 /* ApplicationPasswordsExperimentStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationPasswordsExperimentStateTests.swift; sourceTree = ""; }; + 2D200F062ED7245000DD6EBF /* BookingDateTimeFilterViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookingDateTimeFilterViewTests.swift; sourceTree = ""; }; 2D49A80B2ECDCD4500AF1749 /* RequestAuthenticatorPressureTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = RequestAuthenticatorPressureTests.xctestplan; path = ../Modules/Tests/NetworkingTests/RequestAuthenticatorPressureTests.xctestplan; sourceTree = ""; }; 2D7A3E222E7891D200C46401 /* CIABEligibilityCheckerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIABEligibilityCheckerTests.swift; sourceTree = ""; }; 2D880B482DFB2F3D00A6FB2C /* OptionalBinding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalBinding.swift; sourceTree = ""; }; @@ -12513,6 +12515,7 @@ DED1E3162E8556270089909C /* Bookings */ = { isa = PBXGroup; children = ( + 2D200F062ED7245000DD6EBF /* BookingDateTimeFilterViewTests.swift */, DE8C39FF2EB3527300C69F35 /* SyncableListSelectorViewModelTests.swift */, DE49CD212E966814006DCB07 /* BookingSearchViewModelTests.swift */, DED1E3152E8556270089909C /* BookingListViewModelTests.swift */, @@ -15954,6 +15957,7 @@ FEEB2F61268A215E0075A6E0 /* StorageEligibilityErrorInfoWooTests.swift in Sources */, 31F21B02263C8E150035B50A /* CardReaderSettingsSearchingViewModelTests.swift in Sources */, DEACB8852A64F74A00253F0F /* MediaPickingCoordinatorTests.swift in Sources */, + 2D200F072ED7245000DD6EBF /* BookingDateTimeFilterViewTests.swift in Sources */, 45EF798624509B4C00B22BA2 /* ArrayIndexPathTests.swift in Sources */, D8610BDD256F5ABF00A5DF27 /* JetpackErrorViewModelTests.swift in Sources */, 746791632108D7C0007CF1DC /* WooAnalyticsTests.swift in Sources */, diff --git a/WooCommerce/WooCommerceTests/ViewRelated/Bookings/BookingDateTimeFilterViewTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/Bookings/BookingDateTimeFilterViewTests.swift new file mode 100644 index 00000000000..1e2f44a58f2 --- /dev/null +++ b/WooCommerce/WooCommerceTests/ViewRelated/Bookings/BookingDateTimeFilterViewTests.swift @@ -0,0 +1,22 @@ +import XCTest +import ViewInspector +import SwiftUI +import Combine +@testable import WooCommerce + +final class BookingDateTimeFilterViewTests: XCTestCase { + func test_clear_button_is_not_rendered_initially_when_no_dates_selected() throws { + let sut = BookingDateTimeFilterView(startDate: nil, endDate: nil, onSelection: { _, _ in }) + let view = try sut.inspect() + + XCTAssertThrowsError(try view.find(button: "Clear")) + } + + func test_clear_button_is_rendered_when_dates_selected() throws { + let date = Date() + let sut = BookingDateTimeFilterView(startDate: date, endDate: date, onSelection: { _, _ in }) + let view = try sut.inspect() + + _ = try view.find(button: "Clear") + } +}