Skip to content

Commit d3e873b

Browse files
authored
Merge pull request #8298 from woocommerce/issue/8213-date-range-error-handling
[Analytics Hub] Exit Analytics Hub and display an error if date range selection fails
2 parents 026b088 + 81e9c33 commit d3e873b

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubView.swift

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,39 @@ import SwiftUI
55
/// Hosting Controller for the `AnalyticsHubView` view.
66
///
77
final class AnalyticsHubHostingViewController: UIHostingController<AnalyticsHubView> {
8-
init(siteID: Int64, timeRange: StatsTimeRangeV4) {
8+
9+
/// Presents an error notice in the tab bar context after this `self` is dismissed.
10+
///
11+
private let systemNoticePresenter: NoticePresenter
12+
13+
/// Defines a notice that should be presented after `self` is dismissed.
14+
/// Defaults to `nil`.
15+
///
16+
var notice: Notice?
17+
18+
init(siteID: Int64, timeRange: StatsTimeRangeV4, systemNoticePresenter: NoticePresenter = ServiceLocator.noticePresenter) {
919
let viewModel = AnalyticsHubViewModel(siteID: siteID, statsTimeRange: timeRange)
20+
self.systemNoticePresenter = systemNoticePresenter
1021
super.init(rootView: AnalyticsHubView(viewModel: viewModel))
22+
23+
// Needed to pop the hosting controller from within the SwiftUI view
24+
rootView.dismissWithNotice = { [weak self] notice in
25+
self?.notice = notice
26+
self?.navigationController?.popViewController(animated: true)
27+
}
1128
}
1229

1330
@available(*, unavailable)
1431
required dynamic init?(coder aDecoder: NSCoder) {
1532
fatalError("init(coder:) has not been implemented")
1633
}
34+
35+
override func viewWillDisappear(_ animated: Bool) {
36+
super.viewWillDisappear(animated)
37+
38+
// Show any notice that should be presented after the underlying disappears.
39+
enqueuePendingNotice(notice, using: systemNoticePresenter)
40+
}
1741
}
1842

1943
/// Main Analytics Hub View
@@ -23,6 +47,11 @@ struct AnalyticsHubView: View {
2347
/// Environment safe areas
2448
@Environment(\.safeAreaInsets) var safeAreaInsets: EdgeInsets
2549

50+
/// Set this closure with UIKit code to pop the view controller and display the provided notice.
51+
/// Needed because we need access to the UIHostingController `popViewController` method.
52+
///
53+
var dismissWithNotice: ((Notice) -> Void) = { _ in }
54+
2655
@StateObject var viewModel: AnalyticsHubViewModel
2756

2857
var body: some View {
@@ -81,6 +110,10 @@ struct AnalyticsHubView: View {
81110
.task {
82111
await viewModel.updateData()
83112
}
113+
.onReceive(viewModel.$dismissNotice) { notice in
114+
guard let notice else { return }
115+
dismissWithNotice(notice)
116+
}
84117
}
85118
}
86119

WooCommerce/Classes/ViewRelated/Dashboard/Analytics Hub/AnalyticsHubViewModel.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ final class AnalyticsHubViewModel: ObservableObject {
4747
///
4848
@Published var timeRangeCard: AnalyticsTimeRangeCardViewModel
4949

50+
/// Defines a notice that, when set, dismisses the view and is then displayed.
51+
/// Defaults to `nil`.
52+
///
53+
@Published var dismissNotice: Notice?
54+
5055
// MARK: Private data
5156

5257
/// Order stats for the current selected time period
@@ -67,9 +72,13 @@ final class AnalyticsHubViewModel: ObservableObject {
6772

6873
/// Request stats data from network
6974
///
75+
@MainActor
7076
func updateData() async {
7177
do {
7278
try await retrieveOrderStats()
79+
} catch is AnalyticsHubTimeRangeSelection.TimeRangeGeneratorError {
80+
dismissNotice = Notice(title: Localization.timeRangeGeneratorError, feedbackType: .error)
81+
DDLogWarn("⚠️ Error selecting analytics time range: \(timeRangeSelectionType.description)")
7382
} catch {
7483
await switchToErrorState()
7584
DDLogWarn("⚠️ Error fetching analytics data: \(error)")
@@ -310,5 +319,8 @@ private extension AnalyticsHubViewModel {
310319
value)
311320
}
312321
}
322+
323+
static let timeRangeGeneratorError = NSLocalizedString("Sorry, something went wrong. We can't load analytics for the selected date range.",
324+
comment: "Error shown when there is a problem retrieving the dates for the selected date range.")
313325
}
314326
}

0 commit comments

Comments
 (0)