Skip to content

Commit 52d06ad

Browse files
authored
Shipping Labels: Fix UI issues with shipping service view (#15718)
2 parents ae05dab + 05dc68a commit 52d06ad

File tree

7 files changed

+66
-18
lines changed

7 files changed

+66
-18
lines changed

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooCarrierPackagesSelectionView.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,16 @@ struct WooCarrierPackagesSelectionView: View {
9999
if viewModel.carrierTabs.isNotEmpty {
100100
TopTabView(tabs: viewModel.carrierTabs,
101101
showContent: false,
102-
selectedTabIndex: $viewModel.selectedCarriersTabIndex,
102+
selectedTabIndex: viewModel.selectedCarriersTabIndex,
103103
tabsContainerHorizontalPadding: nil,
104104
selectedStateColor: Color.accentColor,
105105
unselectedStateColor: .secondary,
106106
selectedTabIndicatorHeight: Constants.selectedTabIndicatorHeight,
107107
tabPadding: Constants.tabPadding,
108108
tabsNameFont: Font.subheadline.bold(),
109109
tabItemContentHorizontalPadding: Constants.tabItemContentHorizontalPadding,
110-
tabItemContentVerticalPadding: Constants.tabItemContentVerticalPadding)
110+
tabItemContentVerticalPadding: Constants.tabItemContentVerticalPadding,
111+
onTabChange: { viewModel.selectedCarriersTabIndex = $0 })
111112
} else if viewModel.isLoadingPackages {
112113
// Loading state
113114
loadingStateView

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingServiceView.swift

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import SwiftUI
55
struct WooShippingServiceView: View {
66
@ObservedObject var viewModel: WooShippingServiceViewModel
77

8-
private var carriers: [TopTabItem<WooShippingServiceCardListView>] {
8+
private var carriers: [TopTabItem<EmptyView>] {
99
viewModel.serviceTabs.map { tab in
1010
TopTabItem(name: tab.id.name,
1111
icon: tab.id.logo) {
12-
WooShippingServiceCardListView(cards: tab.cards)
12+
EmptyView()
1313
}
1414
}
1515
}
@@ -78,12 +78,17 @@ struct WooShippingServiceView: View {
7878
}
7979

8080
var contentView: some View {
81-
TopTabView(tabs: carriers,
82-
tabsContainerHorizontalPadding: 16,
83-
unselectedStateColor: .secondary,
84-
tabsNameFont: .subheadline.bold(),
85-
tabItemContentHorizontalPadding: 6,
86-
tabItemContentVerticalPadding: 12)
81+
VStack(spacing: 0) {
82+
TopTabView(tabs: carriers,
83+
showContent: false,
84+
tabsContainerHorizontalPadding: 16,
85+
unselectedStateColor: .secondary,
86+
tabsNameFont: .subheadline.bold(),
87+
tabItemContentHorizontalPadding: 6,
88+
tabItemContentVerticalPadding: 12,
89+
onTabChange: { viewModel.selectedTabIndex = $0 })
90+
WooShippingServiceCardListView(cards: viewModel.displayedServiceCards)
91+
}
8792
.padding(.horizontal, Layout.padding * -1) // Offset the additional padding in TopTabView
8893
}
8994

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingServiceViewModel.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ final class WooShippingServiceViewModel: ObservableObject {
1717
/// Contains the data about available shipping rates, grouped by carrier.
1818
@Published private(set) var serviceTabs: [WooShippingServiceTab] = []
1919

20+
@Published var selectedTabIndex: Int = 0
21+
22+
@Published private(set) var displayedServiceCards: [WooShippingServiceCardViewModel] = []
23+
2024
/// Selected shipping service rate.
2125
@Published private(set) var selectedRate: WooShippingSelectedRate?
2226

@@ -57,6 +61,7 @@ final class WooShippingServiceViewModel: ObservableObject {
5761
self.stores = stores
5862
self.analytics = analytics
5963
self.onSelectRate = onSelectRate
64+
observeSelectedTab()
6065
}
6166

6267
/// Sorts the shipping services by the provided sort order.
@@ -219,6 +224,14 @@ private extension WooShippingServiceViewModel {
219224
}
220225
loadingState = state
221226
}
227+
228+
func observeSelectedTab() {
229+
$serviceTabs.combineLatest($selectedTabIndex)
230+
.map { tabs, index in
231+
tabs[safe: index]?.cards ?? []
232+
}
233+
.assign(to: &$displayedServiceCards)
234+
}
222235
}
223236

224237
// MARK: Constants

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Split Shipments/WooShippingSplitShipmentsView.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ private extension WooShippingSplitShipmentsView {
108108
TopTabView(tabs: viewModel.topTabItems,
109109
showContent: false,
110110
showDividerBelowTabs: false,
111-
selectedTabIndex: $viewModel.selectedShipmentIndex,
111+
selectedTabIndex: viewModel.selectedShipmentIndex,
112112
tabsContainerHorizontalPadding: nil,
113113
selectedStateColor: .accentColor,
114114
unselectedStateColor: .secondary,
@@ -119,7 +119,8 @@ private extension WooShippingSplitShipmentsView {
119119
tabsIconAlignment: .trailing,
120120
tabsIconForegroundColor: Layout.green,
121121
tabItemContentHorizontalPadding: Layout.tabItemContentHorizontalPadding,
122-
tabItemContentVerticalPadding: Layout.tabItemContentVerticalPadding)
122+
tabItemContentVerticalPadding: Layout.tabItemContentVerticalPadding,
123+
onTabChange: { viewModel.selectedShipmentIndex = $0 })
123124
.overlay(alignment: .trailing) {
124125
LinearGradient(gradient: Gradient(colors: [.clear, Color(.basicBackground)]), startPoint: .leading, endPoint: .center)
125126
.frame(width: Layout.gradientViewWidth)

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsView.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private extension WooShippingCreateLabelsView {
144144
TopTabView(tabs: tabs,
145145
showContent: false,
146146
showDividerBelowTabs: false,
147-
selectedTabIndex: $viewModel.selectedShipmentIndex,
147+
selectedTabIndex: viewModel.selectedShipmentIndex,
148148
tabsContainerHorizontalPadding: nil,
149149
selectedStateColor: .accentColor,
150150
unselectedStateColor: .secondary,
@@ -155,7 +155,8 @@ private extension WooShippingCreateLabelsView {
155155
tabsIconAlignment: .trailing,
156156
tabsIconForegroundColor: Layout.green,
157157
tabItemContentHorizontalPadding: Layout.tabItemContentHorizontalPadding,
158-
tabItemContentVerticalPadding: Layout.tabItemContentVerticalPadding)
158+
tabItemContentVerticalPadding: Layout.tabItemContentVerticalPadding,
159+
onTabChange: { viewModel.selectedShipmentIndex = $0 })
159160
.overlay(alignment: .trailing) {
160161
LinearGradient(gradient: Gradient(colors: [.clear, Color(.basicBackground)]), startPoint: .leading, endPoint: .center)
161162
.frame(width: Layout.gradientViewWidth)

WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/TopTabView.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct TopTabView<Content: View>: View {
2323
case trailing
2424
}
2525

26-
@Binding private var selectedTab: Int
26+
@State private var selectedTab: Int = 0
2727
@State private var underlineOffset: CGFloat = 0
2828
@State private var tabWidths: [CGFloat]
2929
@GestureState private var dragState: DragState = .inactive
@@ -61,11 +61,13 @@ struct TopTabView<Content: View>: View {
6161
let tabItemContentHorizontalPadding: CGFloat?
6262
let tabItemContentVerticalPadding: CGFloat?
6363

64+
let onTabChange: (Int) -> Void
65+
6466
init(tabs: [TopTabItem<Content>],
6567
showTabs: Binding<Bool> = .constant(true),
6668
showContent: Bool = true,
6769
showDividerBelowTabs: Bool = true,
68-
selectedTabIndex: Binding<Int> = .constant(0),
70+
selectedTabIndex: Int = 0,
6971
tabsContainerHorizontalPadding: CGFloat? = 0.0,
7072
selectedStateColor: Color = Colors.selected,
7173
unselectedStateColor: Color = .primary,
@@ -76,12 +78,13 @@ struct TopTabView<Content: View>: View {
7678
tabsIconAlignment: TabsIconAlignment = .leading,
7779
tabsIconForegroundColor: Color? = nil,
7880
tabItemContentHorizontalPadding: CGFloat? = nil,
79-
tabItemContentVerticalPadding: CGFloat? = nil) {
81+
tabItemContentVerticalPadding: CGFloat? = nil,
82+
onTabChange: @escaping (Int) -> Void = { _ in }) {
8083
self.tabs = tabs
8184
self._showTabs = showTabs
8285
self.showContent = showContent
8386
self.showDividerBelowTabs = showDividerBelowTabs
84-
self._selectedTab = selectedTabIndex
87+
self.selectedTab = selectedTabIndex
8588
_tabWidths = State(initialValue: [CGFloat](repeating: 0, count: tabs.count))
8689
self.tabsContainerHorizontalPadding = tabsContainerHorizontalPadding
8790
self.selectedStateColor = selectedStateColor
@@ -94,6 +97,7 @@ struct TopTabView<Content: View>: View {
9497
self.tabsIconForegroundColor = tabsIconForegroundColor
9598
self.tabItemContentHorizontalPadding = tabItemContentHorizontalPadding
9699
self.tabItemContentVerticalPadding = tabItemContentVerticalPadding
100+
self.onTabChange = onTabChange
97101
}
98102

99103
private func tabItemContentView(_ index: Int, selected: Bool) -> some View {
@@ -189,6 +193,7 @@ struct TopTabView<Content: View>: View {
189193
withAnimation {
190194
selectTab(in: scrollViewProxy, at: newSelectedTab)
191195
}
196+
onTabChange(newSelectedTab)
192197
})
193198
.coordinateSpace(name: Constants.tabsHorizontalStackNameSpace)
194199
}

WooCommerce/WooCommerceTests/ViewRelated/Shipping Label/WooShipping Create Shipping Labels/WooShippingServiceViewModelTests.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,28 @@ final class WooShippingServiceViewModelTests: XCTestCase {
295295
// Then
296296
XCTAssertEqual(viewModel.loadingState, .error(.noRatesAvailable(isHAZMAT: true)))
297297
}
298+
299+
func test_switching_tab_updates_the_card_list() {
300+
// Given
301+
let viewModel = WooShippingServiceViewModel(order: Order.fake(),
302+
originAddress: WooShippingAddress.fake(),
303+
destinationAddress: sampleDestinationAddress(),
304+
stores: stores)
305+
306+
// When
307+
viewModel.loadLabelRates(for: samplePackage)
308+
309+
// Then
310+
XCTAssertEqual(viewModel.displayedServiceCards.count, 2)
311+
XCTAssertEqual(viewModel.displayedServiceCards.first?.title, "USPS - Media Mail")
312+
313+
// When
314+
viewModel.selectedTabIndex = 1
315+
316+
// Then
317+
XCTAssertEqual(viewModel.displayedServiceCards.count, 1)
318+
XCTAssertEqual(viewModel.displayedServiceCards.first?.title, "DHL - Next Day")
319+
}
298320
}
299321

300322
private extension WooShippingServiceViewModelTests {

0 commit comments

Comments
 (0)