[PM-37992] fix: Show subscription attention card in empty vault and suppress conflicting CTAs#2867
[PM-37992] fix: Show subscription attention card in empty vault and suppress conflicting CTAs#2867KatherineInCode wants to merge 10 commits into
Conversation
…tView to #Preview macros
…conflicting CTAs - Add subscriptionNeedsAttentionActionCard to emptyVault so past-due users with 0-4 vault items see the card - Suppress importLoginsActionCard and archiveOnboardingActionCard when subscription attention card is showing (priority suppression, not dismissal) - Add ViewInspector tests for all new states - Replace deleted _allPreviews snapshot catch-all with individual disabled snapshot tests for each uncovered state
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2867 +/- ##
==========================================
+ Coverage 81.27% 81.65% +0.38%
==========================================
Files 1028 1028
Lines 66164 65827 -337
==========================================
- Hits 53773 53750 -23
+ Misses 12391 12077 -314 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
… priority cascade Add VaultListActionCard enum and activeActionCard computed property to VaultListState, implementing an explicit priority ordering (upgradedToPremium > upgradeNeeded > subscriptionNeedsAttention > introducingArchive > importItems). Replace the five individual @ViewBuilder card properties with a single actionCard view that switches on activeActionCard, so only one card is ever rendered at a time.
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Reviewed the QA follow-up to #2823, which consolidates the five separate action-card view builders into a single priority-driven Code Review Details
|
| assertSnapshots(of: subject, as: [.defaultPortrait, .defaultPortraitDark]) | ||
| } | ||
|
|
||
| // The following tests have no direct preview counterpart. |
There was a problem hiding this comment.
⛏️ Is this still needed?
| /// `activeActionCard` returns the highest-priority active card across all 32 flag combinations, | ||
| /// or `nil` when no flags are set. | ||
| @Test(arguments: allCardSubsets) |
| if shouldShowPremiumUpgradeActionCard { return .upgradeNeeded } | ||
| if shouldShowSubscriptionAttentionCard { return .subscriptionNeedsAttention } | ||
| if shouldShowArchiveOnboardingActionCard { return .introducingArchive } | ||
| if shouldShowImportLoginsActionCard { return .importItems } |
There was a problem hiding this comment.
❓ QUESTION: Import logins card can now appear in a populated vault, which wasn't possible before this refactor.
Details
Previously importLoginsActionCard was rendered only in emptyVault, while vaultContents rendered the premium/subscription/upgrade/archive cards. Both now share actionCard, which resolves through activeActionCard. Because importItems is in the priority chain, a user with importLoginsSetupProgress == .incomplete and a populated vault (and no higher-priority card active) will now see the import logins card in vaultContents — where it never appeared before.
importLoginsSetupProgress is driven by account setup progress (set to .incomplete during onboarding, cleared on dismiss/completion), independent of whether the vault has items, so this state combination is reachable.
Is showing the import logins card in a populated vault the intended behavior? If not, importItems should likely remain gated to the empty-vault path.
🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-37992
📔 Objective
QA follow-up on #2823. Two failures were found:
Card missing for empty/near-empty vaults —
subscriptionNeedsAttentionActionCardwas only rendered insidevaultContents(with:), which only displays when the vault has items. Users with 0–4 vault items sawemptyVaultinstead, where the card was absent. Fixed by adding the card toemptyVault.Subscription attention card and archive onboarding card appear simultaneously — When a past-due user had an undismissed archive onboarding CTA, both cards showed at once. Fixed by suppressing
archiveOnboardingActionCard(andimportLoginsActionCardin the empty vault) when the subscription attention card is visible.Also converts
VaultListViewpreviews fromPreviewProviderto#Previewmacros, and adds previews for the two failing states.📸 Screenshots