Skip to content

Commit 333957c

Browse files
authored
Merge pull request #8140 from woocommerce/issue/8137-update-banner-cta-navigation
2 parents ce065c0 + 5ffc0a3 commit 333957c

File tree

7 files changed

+64
-26
lines changed

7 files changed

+64
-26
lines changed

WooCommerce/Classes/ViewRelated/Dashboard/DashboardViewController.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ final class DashboardViewController: UIViewController {
123123
observeStatsVersionForDashboardUIUpdates()
124124
observeAnnouncements()
125125
observeShowWebViewSheet()
126+
observeAddProductTrigger()
126127
viewModel.syncAnnouncements(for: siteID)
127128
Task { @MainActor in
128129
await reloadDashboardUIStatsVersion(forced: true)
@@ -303,6 +304,28 @@ private extension DashboardViewController {
303304
present(hostingController, animated: true, completion: nil)
304305
}
305306

307+
/// Subscribes to the trigger to start the Add Product flow for products onboarding
308+
///
309+
private func observeAddProductTrigger() {
310+
viewModel.addProductTrigger.sink { [weak self] _ in
311+
self?.startAddProductFlow()
312+
}
313+
.store(in: &subscriptions)
314+
}
315+
316+
/// Starts the Add Product flow (without switching tabs)
317+
///
318+
private func startAddProductFlow() {
319+
guard let announcementView, let navigationController else { return }
320+
let coordinator = AddProductCoordinator(siteID: siteID, sourceView: announcementView, sourceNavigationController: navigationController)
321+
coordinator.onProductCreated = { [weak self] in
322+
guard let self else { return }
323+
self.viewModel.announcementViewModel = nil // Remove the products onboarding banner
324+
self.viewModel.syncAnnouncements(for: self.siteID)
325+
}
326+
coordinator.start()
327+
}
328+
306329
// This is used so we have a specific type for the view while applying modifiers.
307330
struct AnnouncementCardWrapper: View {
308331
let cardView: FeatureAnnouncementCardView

WooCommerce/Classes/ViewRelated/Dashboard/DashboardViewModel.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Yosemite
2+
import Combine
23
import enum Networking.DotcomError
34
import enum Storage.StatsVersion
45
import protocol Experiments.FeatureFlagService
@@ -13,6 +14,10 @@ final class DashboardViewModel {
1314

1415
@Published private(set) var showWebViewSheet: WebViewSheetViewModel? = nil
1516

17+
/// Trigger to start the Add Product flow
18+
///
19+
let addProductTrigger = PassthroughSubject<Void, Never>()
20+
1621
private let stores: StoresManager
1722
private let featureFlagService: FeatureFlagService
1823
private let analytics: Analytics
@@ -154,8 +159,7 @@ final class DashboardViewModel {
154159
guard let self else { return }
155160
if case let .success(isVisible) = result, isVisible {
156161
let viewModel = ProductsOnboardingAnnouncementCardViewModel(onCTATapped: { [weak self] in
157-
self?.announcementViewModel = nil // Dismiss announcement
158-
MainTabBarController.presentAddProductFlow()
162+
self?.addProductTrigger.send()
159163
})
160164
self.announcementViewModel = viewModel
161165
}

WooCommerce/Classes/ViewRelated/MainTabBarController.swift

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -414,19 +414,6 @@ extension MainTabBarController {
414414
}
415415
}
416416

417-
static func presentAddProductFlow() {
418-
navigateTo(.products)
419-
420-
guard let productsViewController: ProductsViewController = childViewController() else {
421-
return
422-
}
423-
424-
// We give some time for the products tab transition to finish, so the add product button is present to start the flow
425-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
426-
productsViewController.addProduct()
427-
}
428-
}
429-
430417
static func presentPayments() {
431418
switchToHubMenuTab()
432419

WooCommerce/Classes/ViewRelated/Products/Add Product/AddProductCoordinator.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ final class AddProductCoordinator: Coordinator {
3030
return controller
3131
}()
3232

33+
/// Assign this closure to be notified when a new product is saved remotely
34+
///
35+
var onProductCreated: () -> Void = {}
36+
3337
init(siteID: Int64,
3438
sourceBarButtonItem: UIBarButtonItem,
3539
sourceNavigationController: UINavigationController,
@@ -211,6 +215,7 @@ private extension AddProductCoordinator {
211215
let viewModel = ProductFormViewModel(product: model,
212216
formType: .add,
213217
productImageActionHandler: productImageActionHandler)
218+
viewModel.onProductCreated = onProductCreated
214219
let viewController = ProductFormViewController(viewModel: viewModel,
215220
eventLogger: ProductFormEventLogger(),
216221
productImageActionHandler: productImageActionHandler,

WooCommerce/Classes/ViewRelated/Products/Edit Product/ProductFormViewModel.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ final class ProductFormViewModel: ProductFormViewModelProtocol {
181181

182182
private let featureFlagService: FeatureFlagService
183183

184+
/// Assign this closure to be notified when a new product is saved remotely
185+
///
186+
var onProductCreated: () -> Void = {}
187+
184188
init(product: EditableProductModel,
185189
formType: ProductFormType,
186190
productImageActionHandler: ProductImageActionHandler,
@@ -432,7 +436,7 @@ extension ProductFormViewModel {
432436
let productWithStatusUpdated = product.product.copy(statusKey: status.rawValue)
433437
return EditableProductModel(product: productWithStatusUpdated)
434438
}()
435-
let remoteActionUseCase = ProductFormRemoteActionUseCase()
439+
let remoteActionUseCase = ProductFormRemoteActionUseCase(stores: stores)
436440
switch formType {
437441
case .add:
438442
let productIDBeforeSave = productModel.productID
@@ -449,6 +453,7 @@ extension ProductFormViewModel {
449453
onCompletion(.success(data.product))
450454
self.replaceProductID(productIDBeforeSave: productIDBeforeSave)
451455
self.saveProductImagesWhenNoneIsPendingUploadAnymore()
456+
self.onProductCreated()
452457
}
453458
}
454459
case .edit:

WooCommerce/Classes/ViewRelated/Products/ProductsViewController.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,6 @@ final class ProductsViewController: UIViewController, GhostableViewController {
220220
}
221221
}
222222

223-
// MARK: - Public API
224-
//
225-
extension ProductsViewController {
226-
/// Adds a new product using the "Add Product" navigation bar button as the source
227-
///
228-
func addProduct() {
229-
addProduct(addProductButton)
230-
}
231-
}
232-
233223
// MARK: - Navigation Bar Actions
234224
//
235225
private extension ProductsViewController {

WooCommerce/WooCommerceTests/ViewRelated/Products/Edit Product/ProductFormViewModelTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,30 @@ final class ProductFormViewModelTests: XCTestCase {
579579
let hasLinkedProducts = try XCTUnwrap(analyticsProvider.receivedProperties.first?["has_linked_products"] as? Bool)
580580
XCTAssertTrue(hasLinkedProducts)
581581
}
582+
583+
func test_onProductCreated_called_when_new_product_saved_remotely() {
584+
// Given
585+
var isCallbackCalled = false
586+
let stores = MockStoresManager(sessionManager: .testingInstance)
587+
let viewModel = createViewModel(product: Product.fake(), formType: .add, stores: stores)
588+
viewModel.onProductCreated = {
589+
isCallbackCalled = true
590+
}
591+
592+
// When
593+
stores.whenReceivingAction(ofType: ProductAction.self) { action in
594+
switch action {
595+
case let .addProduct(product, onCompletion):
596+
onCompletion(.success(product))
597+
default:
598+
XCTFail("Received unsupported action: \(action)")
599+
}
600+
}
601+
viewModel.saveProductRemotely(status: .draft) { _ in }
602+
603+
// Then
604+
XCTAssertTrue(isCallbackCalled)
605+
}
582606
}
583607

584608
private extension ProductFormViewModelTests {

0 commit comments

Comments
 (0)