@@ -14,6 +14,7 @@ struct POSOrderDetailsView: View {
1414 @Environment ( \. siteTimezone) private var siteTimezone
1515 @Environment ( POSOrderListModel . self) private var orderListModel
1616 @Environment ( \. posAnalytics) private var analytics
17+ @Environment ( \. posFeatureFlags) private var featureFlags
1718 @State private var isShowingEmailReceiptView : Bool = false
1819
1920 private var shouldShowBackButton : Bool {
@@ -32,9 +33,7 @@ struct POSOrderDetailsView: View {
3233 title: POSOrderListView . Localization. orderTitle ( order. number) ,
3334 backButtonConfiguration: shouldShowBackButton ? . init( state: . enabled, action: onBack) : nil ,
3435 trailingContent: {
35- if primaryAction != nil || overflowActions. isNotEmpty {
36- actionsSection ( overflowActions)
37- }
36+ actionsSection ( actions: availableActions)
3837 } ,
3938 bottomContent: {
4039 headerBottomContent ( for: order)
@@ -377,87 +376,99 @@ private extension POSOrderDetailsView {
377376
378377// MARK: - Actions
379378private extension POSOrderDetailsView {
380- // Primary action for the header
381- enum POSPrimaryAction {
382- case issueRefund
379+ enum POSAction : Identifiable , CaseIterable {
380+ case issueRefund
381+ case emailReceipt
383382
384- var title : String {
385- switch self {
386- case . issueRefund:
387- Localization . issueRefundActionTitle
388- }
389- }
383+ var id : String { title }
390384
391- func available( for order: POSOrder ) -> Bool {
392- // Adjust the condition as needed
393- return order. status == . completed
394- }
395- }
385+ var title : String {
386+ switch self {
387+ case . issueRefund: Localization . issueRefundActionTitle
388+ case . emailReceipt: Localization . emailReceiptActionTitle
389+ }
390+ }
396391
397- enum POSOverflowAction : Identifiable , CaseIterable {
398- case emailReceipt
392+ var accessibilityHint : String {
393+ switch self {
394+ case . issueRefund: Localization . issueRefundAccessibilityHint
395+ case . emailReceipt: Localization . emailReceiptAccessibilityHint
396+ }
397+ }
399398
400- var id : String { title }
399+ var priority : Int {
400+ switch self {
401+ case . issueRefund: 100
402+ case . emailReceipt: 50
403+ }
404+ }
401405
402- var title : String {
403- switch self {
404- case . emailReceipt:
405- Localization . emailReceiptActionTitle
406+ func isAvailable( for order: POSOrder , flags: POSFeatureFlagProviding ) -> Bool {
407+ guard order. status == . completed else { return false }
408+ switch self {
409+ case . issueRefund:
410+ return flags. isFeatureFlagEnabled ( . pointOfSaleRefundsi1)
411+ case . emailReceipt:
412+ return true
413+ }
406414 }
407415 }
408416
409- func available ( for order : POSOrder ) -> Bool {
410- switch self {
417+ func handler ( for action : POSAction ) -> @ MainActor ( ) -> Void {
418+ switch action {
411419 case . emailReceipt:
412- return order. status == . completed
420+ return {
421+ analytics. track ( event: WooAnalyticsEvent . PointOfSale. orderDetailsEmailReceiptTapped ( ) )
422+ isShowingEmailReceiptView = true
423+ }
424+ case . issueRefund:
425+ return { }
413426 }
414427 }
415- }
416-
417- // Primary + overflow actions (formerly `actions`)
418- var primaryAction : POSPrimaryAction ? {
419- let candidate : POSPrimaryAction = . issueRefund
420- return candidate. available ( for: order) ? candidate : nil
421- }
422428
423- var overflowActions : [ POSOverflowAction ] {
424- POSOverflowAction . allCases. filter { $0. available ( for: order) }
425- }
429+ var availableActions : [ POSAction ] {
430+ POSAction . allCases
431+ . filter { $0. isAvailable ( for: order, flags: featureFlags) }
432+ . sorted { $0. priority > $1. priority }
433+ }
426434
427435 @ViewBuilder
428- func actionsSection( _ actions: [ POSOverflowAction ] ) -> some View {
429- HStack ( spacing: POSSpacing . large) {
430- if let primaryAction {
431- Button ( primaryAction. title) { }
432- . buttonStyle ( POSFilledButtonStyle ( size: . extraSmall) )
433- . accessibilityHint ( Localization . issueRefundAccessibilityHint)
434- . lineLimit ( 1 )
435- . minimumScaleFactor ( 0.5 )
436- }
437-
438- if overflowActions. isNotEmpty {
439- Menu {
440- ForEach ( overflowActions) { action in
441- switch action {
442- case . emailReceipt:
443- Button ( action. title) {
444- analytics. track ( event: WooAnalyticsEvent . PointOfSale. orderDetailsEmailReceiptTapped ( ) )
445- isShowingEmailReceiptView = true
446- }
447- . accessibilityHint ( Localization . emailReceiptAccessibilityHint)
436+ func actionsSection( actions: [ POSAction ] ) -> some View {
437+ if actions. isEmpty {
438+ EmptyView ( )
439+ } else {
440+ HStack ( spacing: POSSpacing . large) {
441+ let primary = actions [ 0 ]
442+ Button ( primary. title, action: handler ( for: primary) )
443+ . buttonStyle ( POSFilledButtonStyle ( size: . extraSmall) )
444+ . accessibilityHint ( primary. accessibilityHint)
445+ . lineLimit ( 1 )
446+ . minimumScaleFactor ( 0.5 )
447+
448+ let overflow = actions. dropFirst ( )
449+ if !overflow. isEmpty {
450+ Menu {
451+ ForEach ( Array ( overflow) ) { action in
452+ Button ( action. title, action: handler ( for: action) )
453+ . accessibilityHint ( action. accessibilityHint)
448454 }
455+ } label: {
456+ Image ( systemName: " ellipsis " )
457+ . font ( . posBodyLargeBold)
458+ . dynamicTypeSize ( ... DynamicTypeSize . accessibility2)
459+ . foregroundColor ( . posOnSurface)
460+ . padding ( POSPadding . small)
449461 }
450- } label: {
451- Image ( systemName: " ellipsis " )
452- . font ( . posBodyLargeBold)
453- . dynamicTypeSize ( ... DynamicTypeSize . accessibility2)
454- . foregroundColor ( . posOnSurface)
455- . padding ( POSPadding . small)
462+ . menuIndicator ( . hidden)
456463 }
457- . menuIndicator ( . hidden)
458464 }
459465 }
460466 }
467+
468+ func emailReceiptAction( ) {
469+ analytics. track ( event: WooAnalyticsEvent . PointOfSale. orderDetailsEmailReceiptTapped ( ) )
470+ isShowingEmailReceiptView = true
471+ }
461472}
462473
463474private extension POSOrderDetailsView {
0 commit comments