11import UIKit
22import WordPressUI
33import Yosemite
4+ import Combine
45
56import class AutomatticTracks. CrashLogging
67
@@ -9,7 +10,7 @@ import class AutomatticTracks.CrashLogging
910///
1011final class ProductsViewController : UIViewController , GhostableViewController {
1112
12- let viewModel : ProductListViewModel = . init ( )
13+ let viewModel : ProductListViewModel
1314
1415 /// Main TableView
1516 ///
@@ -194,6 +195,8 @@ final class ProductsViewController: UIViewController, GhostableViewController {
194195 ///
195196 private var hasErrorLoadingData : Bool = false
196197
198+ private var subscriptions : Set < AnyCancellable > = [ ]
199+
197200 deinit {
198201 NotificationCenter . default. removeObserver ( self )
199202 }
@@ -202,6 +205,7 @@ final class ProductsViewController: UIViewController, GhostableViewController {
202205
203206 init ( siteID: Int64 ) {
204207 self . siteID = siteID
208+ self . viewModel = . init( siteID: siteID, stores: ServiceLocator . stores)
205209 super. init ( nibName: type ( of: self ) . nibName, bundle: nil )
206210
207211 configureTabBarItem ( )
@@ -296,7 +300,11 @@ private extension ProductsViewController {
296300 }
297301 coordinatingController. start ( )
298302 }
303+ }
299304
305+ // MARK: - Bulk Editing flows
306+ //
307+ private extension ProductsViewController {
300308 @objc func startBulkEditing( ) {
301309 tableView. setEditing ( true , animated: true )
302310
@@ -328,8 +336,8 @@ private extension ProductsViewController {
328336 @objc func openBulkEditingOptions( sender: UIButton ) {
329337 let actionSheet = UIAlertController ( title: nil , message: nil , preferredStyle: . actionSheet)
330338
331- let updateStatus = UIAlertAction ( title: Localization . bulkEditingStatusOption, style: . default) { _ in
332- // TODO-8519: show UI for status update
339+ let updateStatus = UIAlertAction ( title: Localization . bulkEditingStatusOption, style: . default) { [ weak self ] _ in
340+ self ? . showStatusBulkEditingModal ( )
333341 }
334342 let updatePrice = UIAlertAction ( title: Localization . bulkEditingPriceOption, style: . default) { _ in
335343 // TODO-8520: show UI for price update
@@ -347,6 +355,71 @@ private extension ProductsViewController {
347355
348356 present ( actionSheet, animated: true )
349357 }
358+
359+ func showStatusBulkEditingModal( ) {
360+ let initialStatus = viewModel. commonStatusForSelectedProducts
361+ let command = ProductStatusSettingListSelectorCommand ( selected: initialStatus)
362+ let listSelectorViewController = ListSelectorViewController ( command: command) { _ in
363+ // view dismiss callback - no-op
364+ }
365+ listSelectorViewController. navigationItem. leftBarButtonItem = UIBarButtonItem ( barButtonSystemItem: . cancel,
366+ target: self ,
367+ action: #selector( dismissModal) )
368+
369+ let applyButton = UIBarButtonItem ( title: Localization . bulkEditingApply)
370+ applyButton. on ( call: { [ weak self] _ in
371+ self ? . applyBulkEditingStatus ( newStatus: command. selected, modalVC: listSelectorViewController)
372+ } )
373+ command. $selected. sink { newStatus in
374+ if let newStatus, newStatus != initialStatus {
375+ applyButton. isEnabled = true
376+ } else {
377+ applyButton. isEnabled = false
378+ }
379+ } . store ( in: & subscriptions)
380+ listSelectorViewController. navigationItem. rightBarButtonItem = applyButton
381+
382+ self . present ( WooNavigationController ( rootViewController: listSelectorViewController) , animated: true )
383+ }
384+
385+ @objc func dismissModal( ) {
386+ dismiss ( animated: true )
387+ }
388+
389+ func applyBulkEditingStatus( newStatus: ProductStatus ? , modalVC: UIViewController ) {
390+ guard let newStatus else { return }
391+
392+ displayProductsSavingInProgressView ( on: modalVC)
393+ viewModel. updateSelectedProducts ( with: newStatus) { [ weak self] result in
394+ guard let self else { return }
395+
396+ self . dismiss ( animated: true , completion: nil )
397+ switch result {
398+ case . success:
399+ self . finishBulkEditing ( )
400+ self . presentNotice ( title: Localization . statusUpdatedNotice)
401+ case . failure:
402+ self . presentNotice ( title: Localization . updateErrorNotice)
403+ }
404+ }
405+ }
406+
407+ func displayProductsSavingInProgressView( on vc: UIViewController ) {
408+ let viewProperties = InProgressViewProperties ( title: Localization . productsSavingTitle, message: Localization . productsSavingMessage)
409+ let inProgressViewController = InProgressViewController ( viewProperties: viewProperties)
410+ inProgressViewController. modalPresentationStyle = . fullScreen
411+
412+ vc. present ( inProgressViewController, animated: true , completion: nil )
413+ }
414+
415+ func presentNotice( title: String ) {
416+ let contextNoticePresenter : NoticePresenter = {
417+ let noticePresenter = DefaultNoticePresenter ( )
418+ noticePresenter. presentingViewController = tabBarController
419+ return noticePresenter
420+ } ( )
421+ contextNoticePresenter. enqueue ( notice: . init( title: title) )
422+ }
350423}
351424
352425// MARK: - View Configuration
@@ -1218,5 +1291,17 @@ private extension ProductsViewController {
12181291 " %1$@ selected " ,
12191292 comment: " Title that appears on top of the Product List screen during bulk editing. Reads like: 2 selected "
12201293 )
1294+
1295+ static let bulkEditingApply = NSLocalizedString ( " Apply " , comment: " Title for the button to apply bulk editing changes to selected products. " )
1296+
1297+ static let productsSavingTitle = NSLocalizedString ( " Updating your products... " ,
1298+ comment: " Title of the in-progress UI while bulk updating selected products remotely " )
1299+ static let productsSavingMessage = NSLocalizedString ( " Please wait while we update these products on your store " ,
1300+ comment: " Message of the in-progress UI while bulk updating selected products remotely " )
1301+
1302+ static let statusUpdatedNotice = NSLocalizedString ( " Status updated " ,
1303+ comment: " Title of the notice when a user updated status for selected products " )
1304+ static let updateErrorNotice = NSLocalizedString ( " Cannot update products " ,
1305+ comment: " Title of the notice when there is an error updating selected products " )
12211306 }
12221307}
0 commit comments