From 66a45086943f65c1ccc2aae22a067cfdd695c142 Mon Sep 17 00:00:00 2001 From: Josh Heald Date: Wed, 18 Jun 2025 16:39:39 +0100 Subject: [PATCH] Remove side by side order form feature flag --- .../DefaultFeatureFlagService.swift | 2 - Modules/Sources/Experiments/FeatureFlag.swift | 4 - .../EditableOrderViewModel.swift | 27 +--- .../Orders/Order Creation/OrderForm.swift | 153 ++++++------------ .../OrderDetailsViewController.swift | 9 +- .../Orders/OrdersRootViewController.swift | 12 +- .../ProductSelector/ProductSelectorView.swift | 47 +----- .../Mocks/MockFeatureFlagService.swift | 5 - .../EditableOrderViewModelTests.swift | 15 +- 9 files changed, 59 insertions(+), 215 deletions(-) diff --git a/Modules/Sources/Experiments/DefaultFeatureFlagService.swift b/Modules/Sources/Experiments/DefaultFeatureFlagService.swift index 7c5b8b081d0..f1e00f73f9e 100644 --- a/Modules/Sources/Experiments/DefaultFeatureFlagService.swift +++ b/Modules/Sources/Experiments/DefaultFeatureFlagService.swift @@ -15,8 +15,6 @@ public struct DefaultFeatureFlagService: FeatureFlagService { return true case .showInboxCTA: return true - case .sideBySideViewForOrderForm: - return true case .updateOrderOptimistically: return buildConfig == .localDeveloper || buildConfig == .alpha case .shippingLabelsOnboardingM1: diff --git a/Modules/Sources/Experiments/FeatureFlag.swift b/Modules/Sources/Experiments/FeatureFlag.swift index 563c9c72123..ef9e36878e3 100644 --- a/Modules/Sources/Experiments/FeatureFlag.swift +++ b/Modules/Sources/Experiments/FeatureFlag.swift @@ -22,10 +22,6 @@ public enum FeatureFlag: Int { /// case showInboxCTA - /// Displays the OrderForm side by side with the Product Selector - /// - case sideBySideViewForOrderForm - /// Enable optimistic updates for orders /// case updateOrderOptimistically diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/EditableOrderViewModel.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/EditableOrderViewModel.swift index 8d47b53d975..238d8418bcf 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/EditableOrderViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/EditableOrderViewModel.swift @@ -85,20 +85,6 @@ final class EditableOrderViewModel: ObservableObject { } } - var sideBySideViewFeatureFlagEnabled: Bool { - featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) - } - - /// Indicates whether the cancel button is visible. - /// - var shouldShowCancelButton: Bool { - // The cancel button is handled by the AdaptiveModalContainer with the side-by-side view enabled, so this one should not be shown. - guard !sideBySideViewFeatureFlagEnabled else { - return false - } - return flow == .creation - } - /// Indicates the customer details screen to be shown. If there's no address added show the customer selector, otherwise the form so it can be edited /// var customerNavigationScreen: CustomerNavigationScreen { @@ -2015,9 +2001,6 @@ private extension EditableOrderViewModel { } func evaluateSelectionSync() { - guard sideBySideViewFeatureFlagEnabled else { - return - } switch selectionSyncApproach { case .immediate: syncOrderItems(products: selectedProducts, variations: selectedProductVariations) @@ -2031,10 +2014,7 @@ private extension EditableOrderViewModel { func forwardSyncApproachToSynchronizer() { $selectionSyncApproach .sink { [weak self] selectionSyncApproach in - guard let self, - sideBySideViewFeatureFlagEnabled else { - return - } + guard let self else { return } orderSynchronizer.updateBlockingBehavior(selectionSyncApproach == .immediate ? .allUpdates : .majorUpdates) } .store(in: &cancellables) @@ -2044,10 +2024,7 @@ private extension EditableOrderViewModel { $selectionSyncApproach .removeDuplicates() .sink { [weak self] selectionSyncApproach in - guard let self, - sideBySideViewFeatureFlagEnabled else { - return - } + guard let self else { return } if selectionSyncApproach != .onSelectorButtonTap || syncRequired { /// When we change from `onSelectorButtonTap`, we would lose unsynced changes if we do nothing. /// `syncRequired` indicates that we have unsynced side-by-side changes, which would be lost when diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/OrderForm.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/OrderForm.swift index ee9ef036bb2..4ae3bfc7767 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/OrderForm.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/OrderForm.swift @@ -124,60 +124,56 @@ struct OrderFormPresentationWrapper: View { @Environment(\.horizontalSizeClass) var horizontalSizeClass var body: some View { - if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) { - AdaptiveModalContainer( - primaryView: { presentProductSelector in - OrderForm(dismissHandler: dismissHandler, - flow: flow, - viewModel: viewModel, - presentProductSelector: presentProductSelector) + AdaptiveModalContainer( + primaryView: { presentProductSelector in + OrderForm(dismissHandler: dismissHandler, + flow: flow, + viewModel: viewModel, + presentProductSelector: presentProductSelector) + // When we're modal-on-modal, show the notices on both screens so they're definitely visible + .if(horizontalSizeClass == .compact, transform: { + $0 + .notice($viewModel.autodismissableNotice) + .notice($viewModel.fixedNotice, autoDismiss: false) + }) + }, + secondaryView: { isShowingProductSelector in + if let productSelectorViewModel = viewModel.productSelectorViewModel { + ProductSelectorView(configuration: .loadConfiguration(for: horizontalSizeClass), + isPresented: isShowingProductSelector, + viewModel: productSelectorViewModel) + .sheet(item: $viewModel.productToConfigureViewModel) { viewModel in + ConfigurableBundleProductView(viewModel: viewModel) + } // When we're modal-on-modal, show the notices on both screens so they're definitely visible .if(horizontalSizeClass == .compact, transform: { $0 .notice($viewModel.autodismissableNotice) .notice($viewModel.fixedNotice, autoDismiss: false) }) - }, - secondaryView: { isShowingProductSelector in - if let productSelectorViewModel = viewModel.productSelectorViewModel { - ProductSelectorView(configuration: .loadConfiguration(for: horizontalSizeClass), - isPresented: isShowingProductSelector, - viewModel: productSelectorViewModel) - .sheet(item: $viewModel.productToConfigureViewModel) { viewModel in - ConfigurableBundleProductView(viewModel: viewModel) - } - // When we're modal-on-modal, show the notices on both screens so they're definitely visible - .if(horizontalSizeClass == .compact, transform: { - $0 - .notice($viewModel.autodismissableNotice) - .notice($viewModel.fixedNotice, autoDismiss: false) - }) - } - }, - dismissBarButton: { - Button { - dismissHandler() - } label: { - switch dismissLabel { - case .cancelButton: - Text(OrderForm.Localization.cancelButton) - case .backButton: - Image(systemName: "chevron.backward") - .headlineLinkStyle() - } + } + }, + dismissBarButton: { + Button { + dismissHandler() + } label: { + switch dismissLabel { + case .cancelButton: + Text(OrderForm.Localization.cancelButton) + case .backButton: + Image(systemName: "chevron.backward") + .headlineLinkStyle() } - .accessibilityIdentifier(OrderForm.Accessibility.cancelButtonIdentifier) - }, - isShowingSecondaryView: $viewModel.isProductSelectorPresented) - // When we're side-by-side, show the notices over the combined screen - .if(horizontalSizeClass == .regular, transform: { - $0 - .notice($viewModel.autodismissableNotice) - .notice($viewModel.fixedNotice, autoDismiss: false) - }) - } else { - OrderForm(dismissHandler: dismissHandler, flow: flow, viewModel: viewModel, presentProductSelector: nil) - } + } + .accessibilityIdentifier(OrderForm.Accessibility.cancelButtonIdentifier) + }, + isShowingSecondaryView: $viewModel.isProductSelectorPresented) + // When we're side-by-side, show the notices over the combined screen + .if(horizontalSizeClass == .regular, transform: { + $0 + .notice($viewModel.autodismissableNotice) + .notice($viewModel.fixedNotice, autoDismiss: false) + }) } } @@ -268,16 +264,11 @@ struct OrderForm: View { } .renderedIf(viewModel.shouldShowNonEditableIndicators) - if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) { - Group { - OrderStatusSection(viewModel: viewModel, topDivider: !viewModel.shouldShowNonEditableIndicators) - Spacer(minLength: Layout.sectionSpacing) - } - .renderedIf(flow == .editing) - } else { + Group { OrderStatusSection(viewModel: viewModel, topDivider: !viewModel.shouldShowNonEditableIndicators) Spacer(minLength: Layout.sectionSpacing) } + .renderedIf(flow == .editing) ProductsSection(scroll: scroll, flow: flow, @@ -429,13 +420,6 @@ struct OrderForm: View { .navigationTitle(viewModel.title) .navigationBarTitleDisplayMode(.inline) .toolbar { - ToolbarItem(placement: .cancellationAction) { - Button(Localization.cancelButton) { - dismissHandler() - } - .accessibilityIdentifier(Accessibility.cancelButtonIdentifier) - .renderedIf(viewModel.shouldShowCancelButton) - } ToolbarItem(placement: .confirmationAction) { switch viewModel.navigationTrailingItem { case .create: @@ -462,13 +446,6 @@ struct OrderForm: View { .onTapGesture { shouldShowInformationalCouponTooltip = false } - // Avoids Notice duplication when the feature flag is enabled. These can be removed when the flag is removed. - .if(!ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm), transform: { - $0.notice($viewModel.autodismissableNotice) - }) - .if(!ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm), transform: { - $0.notice($viewModel.fixedNotice, autoDismiss: false) - }) } @ViewBuilder private var storedTaxRateBottomSheetContent: some View { @@ -640,8 +617,7 @@ private struct ProductsSection: View { Divider() VStack(alignment: .leading, spacing: layoutVerticalSpacing) { - if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) - && presentationStyle == .sideBySide + if presentationStyle == .sideBySide && !viewModel.shouldShowProductsSectionHeader { HStack() { scanProductRow @@ -670,15 +646,6 @@ private struct ProductsSection: View { .accessibilityLabel(OrderForm.Localization.addProductButtonAccessibilityLabel) .id(addProductButton) .accessibilityIdentifier(OrderForm.Accessibility.addProductButtonIdentifier) - } else if !ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) { - Button(action: { - viewModel.toggleProductSelectorVisibility() - }) { - Image(uiImage: .plusImage) - } - .accessibilityLabel(OrderForm.Localization.addProductButtonAccessibilityLabel) - .id(addProductButton) - .accessibilityIdentifier(OrderForm.Accessibility.addProductButtonIdentifier) } } .scaledToFit() @@ -710,13 +677,6 @@ private struct ProductsSection: View { .id(addProductButton) .accessibilityIdentifier(OrderForm.Accessibility.addProductButtonIdentifier) .buttonStyle(PlusButtonStyle()) - } else if !ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) { - Button(OrderForm.Localization.addProducts) { - viewModel.toggleProductSelectorVisibility() - } - .id(addProductButton) - .accessibilityIdentifier(OrderForm.Accessibility.addProductButtonIdentifier) - .buttonStyle(PlusButtonStyle()) } scanProductButton .renderedIf(presentationStyle != .sideBySide) @@ -730,27 +690,6 @@ private struct ProductsSection: View { .sheet(item: $viewModel.configurableScannedProductViewModel) { configurableScannedProductViewModel in ConfigurableBundleProductView(viewModel: configurableScannedProductViewModel) } - .sheet(isPresented: Binding( - get: { viewModel.isProductSelectorPresented && !viewModel.sideBySideViewFeatureFlagEnabled }, - set: { newValue in - viewModel.isProductSelectorPresented = newValue - } - ), onDismiss: { - scroll.scrollTo(addProductButton) - }, content: { - if let productSelectorViewModel = viewModel.productSelectorViewModel { - ProductSelectorNavigationView( - configuration: ProductSelectorView.Configuration.addProductToOrder(), - isPresented: $viewModel.isProductSelectorPresented, - viewModel: productSelectorViewModel) - .onDisappear { - navigationButtonID = UUID() - } - .sheet(item: $viewModel.productToConfigureViewModel) { viewModel in - ConfigurableBundleProductView(viewModel: viewModel) - } - } - }) .actionSheet(isPresented: $showPermissionsSheet, content: { ActionSheet( title: Text(OrderForm.Localization.permissionsTitle), diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/OrderDetailsViewController.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/OrderDetailsViewController.swift index 97d76c4a534..72c482cb613 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/OrderDetailsViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/OrderDetailsViewController.swift @@ -335,13 +335,8 @@ private extension OrderDetailsViewController { private func editOrder() { let viewModel = EditableOrderViewModel(siteID: viewModel.order.siteID, flow: .editing(initialOrder: viewModel.order)) let viewController = OrderFormHostingController(viewModel: viewModel) - if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) { - viewController.modalPresentationStyle = .fullScreen - present(viewController, animated: true) - } else { - let navController = UINavigationController(rootViewController: viewController) - present(navController, animated: true) - } + viewController.modalPresentationStyle = .fullScreen + present(viewController, animated: true) let hasMultipleShippingLines = self.viewModel.order.shippingLines.count > 1 let hasMultipleFeeLines = self.viewModel.order.fees.count > 1 diff --git a/WooCommerce/Classes/ViewRelated/Orders/OrdersRootViewController.swift b/WooCommerce/Classes/ViewRelated/Orders/OrdersRootViewController.swift index ff52508f684..7b25dd5113d 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/OrdersRootViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/OrdersRootViewController.swift @@ -140,9 +140,6 @@ final class OrdersRootViewController: UIViewController { command: OrderSearchUICommand(siteID: siteID, onSelectSearchResult: { [weak self] order, viewController in guard let self else { return } - guard featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) else { - return presentOrder(order, from: viewController) - } navigateToOrderDetail(order) viewController.dismiss(animated: true) }), @@ -230,13 +227,8 @@ final class OrdersRootViewController: UIViewController { } } - if featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) { - viewController.modalPresentationStyle = .overFullScreen - navigationController.present(viewController, animated: true) - } else { - let newOrderNavigationController = WooNavigationController(rootViewController: viewController) - navigationController.present(newOrderNavigationController, animated: true) - } + viewController.modalPresentationStyle = .overFullScreen + navigationController.present(viewController, animated: true) analytics.track(event: .Orders.orderAddNew()) orderDurationRecorder.startRecording() diff --git a/WooCommerce/Classes/ViewRelated/Products/ProductSelector/ProductSelectorView.swift b/WooCommerce/Classes/ViewRelated/Products/ProductSelector/ProductSelectorView.swift index f288bcf1f64..5a20953142a 100644 --- a/WooCommerce/Classes/ViewRelated/Products/ProductSelector/ProductSelectorView.swift +++ b/WooCommerce/Classes/ViewRelated/Products/ProductSelector/ProductSelectorView.swift @@ -67,9 +67,6 @@ struct ProductSelectorView: View { guard viewModel.totalSelectedItemsCount > 0 else { return Localization.doneButton } - guard ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) else { - return viewModel.selectProductsTitle - } return Localization.addProductsText } @@ -77,8 +74,7 @@ struct ProductSelectorView: View { /// private var navigationTitle: String { let narrowView = (horizontalSizeClass == .compact || isViewWidthNarrowerThanConstantRowWidth) - guard ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm), - narrowView, configuration.multipleSelectionEnabled else { + guard narrowView, configuration.multipleSelectionEnabled else { return configuration.title } return viewModel.selectProductsTitle @@ -86,11 +82,7 @@ struct ProductSelectorView: View { var body: some View { VStack(spacing: 0) { - if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.sideBySideViewForOrderForm) { - productSelectorHeader - } else { - legacyProductSelectorHeader - } + productSelectorHeader switch viewModel.syncStatus { case .results: @@ -294,41 +286,6 @@ private extension ProductSelectorView { Divider() } - @ViewBuilder var legacyProductSelectorHeader: some View { - SearchHeader(text: $viewModel.searchTerm, placeholder: Localization.searchPlaceholder, onEditingChanged: { isEditing in - searchHeaderisBeingEdited = isEditing - }) - .padding(.horizontal, insets: safeAreaInsets) - .accessibilityIdentifier("product-selector-search-bar") - Picker(selection: $viewModel.productSearchFilter, label: EmptyView()) { - ForEach(ProductSearchFilter.allCases, id: \.self) { option in Text(option.title) } - } - .pickerStyle(.segmented) - .padding(.leading) - .padding(.trailing) - .renderedIf(searchHeaderisBeingEdited) - - HStack { - Button(Localization.clearSelection) { - viewModel.clearSelection() - } - .buttonStyle(LinkButtonStyle()) - .fixedSize() - .disabled(isClearSelectionDisabled) - .renderedIf(configuration.multipleSelectionEnabled) - - Spacer() - - Button(viewModel.filterButtonTitle) { - showingFilters.toggle() - ServiceLocator.analytics.track(event: .ProductListFilter.productListViewFilterOptionsTapped(source: viewModel.source.filterAnalyticsSource)) - } - .buttonStyle(LinkButtonStyle()) - .fixedSize() - } - .padding(.horizontal, insets: safeAreaInsets) - } - @ViewBuilder private var productSelectorHeaderTitleRow: some View { GeometryReader { geometry in HStack { diff --git a/WooCommerce/WooCommerceTests/Mocks/MockFeatureFlagService.swift b/WooCommerce/WooCommerceTests/Mocks/MockFeatureFlagService.swift index f7f66132308..a9856b68bc6 100644 --- a/WooCommerce/WooCommerceTests/Mocks/MockFeatureFlagService.swift +++ b/WooCommerce/WooCommerceTests/Mocks/MockFeatureFlagService.swift @@ -11,7 +11,6 @@ final class MockFeatureFlagService: FeatureFlagService { var betterCustomerSelectionInOrder: Bool var productBundlesInOrderForm: Bool var isScanToUpdateInventoryEnabled: Bool - var sideBySideViewForOrderForm: Bool var isSubscriptionsInOrderCreationCustomersEnabled: Bool var isPointOfSaleEnabled: Bool var googleAdsCampaignCreationOnWebView: Bool @@ -36,7 +35,6 @@ final class MockFeatureFlagService: FeatureFlagService { betterCustomerSelectionInOrder: Bool = false, productBundlesInOrderForm: Bool = false, isScanToUpdateInventoryEnabled: Bool = false, - sideBySideViewForOrderForm: Bool = false, isSubscriptionsInOrderCreationCustomersEnabled: Bool = false, isPointOfSaleEnabled: Bool = false, googleAdsCampaignCreationOnWebView: Bool = false, @@ -59,7 +57,6 @@ final class MockFeatureFlagService: FeatureFlagService { self.betterCustomerSelectionInOrder = betterCustomerSelectionInOrder self.productBundlesInOrderForm = productBundlesInOrderForm self.isScanToUpdateInventoryEnabled = isScanToUpdateInventoryEnabled - self.sideBySideViewForOrderForm = sideBySideViewForOrderForm self.isSubscriptionsInOrderCreationCustomersEnabled = isSubscriptionsInOrderCreationCustomersEnabled self.isPointOfSaleEnabled = isPointOfSaleEnabled self.googleAdsCampaignCreationOnWebView = googleAdsCampaignCreationOnWebView @@ -101,8 +98,6 @@ final class MockFeatureFlagService: FeatureFlagService { return productBundlesInOrderForm case .scanToUpdateInventory: return isScanToUpdateInventoryEnabled - case .sideBySideViewForOrderForm: - return sideBySideViewForOrderForm case .subscriptionsInOrderCreationCustomers: return isSubscriptionsInOrderCreationCustomersEnabled case .pointOfSale: diff --git a/WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/EditableOrderViewModelTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/EditableOrderViewModelTests.swift index b3393c6d406..1c4934cda23 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/EditableOrderViewModelTests.swift +++ b/WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/EditableOrderViewModelTests.swift @@ -297,8 +297,7 @@ final class EditableOrderViewModelTests: XCTestCase { let product = Product.fake().copy(siteID: sampleSiteID, productID: sampleProductID, purchasable: true) storageManager.insertSampleProduct(readOnlyProduct: product) let viewModel = EditableOrderViewModel(siteID: sampleSiteID, - storageManager: storageManager, - featureFlagService: MockFeatureFlagService(sideBySideViewForOrderForm: true)) + storageManager: storageManager) viewModel.toggleProductSelectorVisibility() viewModel.selectionSyncApproach = .immediate @@ -317,8 +316,7 @@ final class EditableOrderViewModelTests: XCTestCase { let product = Product.fake().copy(siteID: sampleSiteID, productID: sampleProductID, purchasable: true) storageManager.insertSampleProduct(readOnlyProduct: product) let viewModel = EditableOrderViewModel(siteID: sampleSiteID, - storageManager: storageManager, - featureFlagService: MockFeatureFlagService(sideBySideViewForOrderForm: true)) + storageManager: storageManager) viewModel.toggleProductSelectorVisibility() viewModel.selectionSyncApproach = .onRecalculateButtonTap @@ -340,8 +338,7 @@ final class EditableOrderViewModelTests: XCTestCase { func test_doneButtonType_when_custom_amount_using_onRecalculateButtonTap_sync_approach() throws { // Given let viewModel = EditableOrderViewModel(siteID: sampleSiteID, - storageManager: storageManager, - featureFlagService: MockFeatureFlagService(sideBySideViewForOrderForm: true)) + storageManager: storageManager) viewModel.toggleProductSelectorVisibility() viewModel.selectionSyncApproach = .onRecalculateButtonTap @@ -366,8 +363,7 @@ final class EditableOrderViewModelTests: XCTestCase { let product = Product.fake().copy(siteID: sampleSiteID, productID: sampleProductID, purchasable: true) storageManager.insertSampleProduct(readOnlyProduct: product) let viewModel = EditableOrderViewModel(siteID: sampleSiteID, - storageManager: storageManager, - featureFlagService: MockFeatureFlagService(sideBySideViewForOrderForm: true)) + storageManager: storageManager) viewModel.toggleProductSelectorVisibility() viewModel.selectionSyncApproach = .onRecalculateButtonTap @@ -396,8 +392,7 @@ final class EditableOrderViewModelTests: XCTestCase { let product = Product.fake().copy(siteID: sampleSiteID, productID: sampleProductID, purchasable: true) storageManager.insertSampleProduct(readOnlyProduct: product) let viewModel = EditableOrderViewModel(siteID: sampleSiteID, - storageManager: storageManager, - featureFlagService: MockFeatureFlagService(sideBySideViewForOrderForm: true)) + storageManager: storageManager) viewModel.toggleProductSelectorVisibility() viewModel.selectionSyncApproach = .onSelectorButtonTap