[PM-42025] fix: Show a toast after a vault item is saved - #2993
[PM-42025] fix: Show a toast after a vault item is saved#2993andrebispo5 wants to merge 5 commits into
Conversation
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Reviewed the new Code Review Details
|
There was a problem hiding this comment.
Pull request overview
Adds a new “item saved” delegate signal and per-item-type toast copy so users receive a confirmation toast after successfully saving a vault item (add or update), and prevents the View Item screen from losing its toast when cipher updates stream in.
Changes:
- Introduces
CipherItemOperationDelegate.itemSaved(type:)and triggers it only after successful add/update inAddEditItemProcessor. - Adds
CipherType.savedToastTitleand new localized strings to provide per-type “X saved” toast titles. - Updates Vault list/group/view item processors (and tests) to display and preserve the appropriate save toast.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| BitwardenShared/UI/Vault/VaultItem/ViewItem/ViewItemProcessorTests.swift | Adds coverage for itemSaved(type:) toast and toast persistence on .appeared. |
| BitwardenShared/UI/Vault/VaultItem/ViewItem/ViewItemProcessor.swift | Preserves toast across cipher detail state rebuilds; shows per-type toast on save. |
| BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditItemProcessorTests.swift | Adds tests asserting save notifies delegate with saved type; ensures cancel doesn’t. |
| BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditItemProcessor.swift | Adds new delegate callback and invokes it after successful add/update. |
| BitwardenShared/UI/Vault/Vault/VaultList/VaultListProcessorTests.swift | Adds test verifying list shows per-type saved toast. |
| BitwardenShared/UI/Vault/Vault/VaultList/VaultListProcessor.swift | Implements itemSaved(type:) to show per-type toast. |
| BitwardenShared/UI/Vault/Vault/VaultGroup/VaultGroupProcessorTests.swift | Adds test verifying group shows per-type saved toast and refreshes. |
| BitwardenShared/UI/Vault/Vault/VaultGroup/VaultGroupProcessor.swift | Implements itemSaved(type:) to show per-type toast + refresh. |
| BitwardenShared/Core/Vault/Models/Enum/CipherTypeTests.swift | Adds unit test for savedToastTitle mapping. |
| BitwardenShared/Core/Vault/Models/Enum/CipherType.swift | Adds savedToastTitle mapping from CipherType to localized toast title. |
| BitwardenResources/Localizations/en.lproj/Localizable.strings | Adds new English localization keys for per-type “saved” toasts. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| /// `receive(_:)` with `.dismiss()` navigates to the `.dismiss()` route without notifying the | ||
| /// delegate that the item was saved, so that cancelling doesn't show a confirmation toast. |
| state.toast = Toast(title: Localizations.itemDeleted) | ||
| } | ||
|
|
||
| func itemSaved(type: CipherType) { |
There was a problem hiding this comment.
❓ QUESTION: Was the more-options "Edit" path intentionally left without a toast?
Details
The vault list and group list reach the editor by two routes. Tapping a row goes through ViewItemProcessor, which now shows the toast. But the row's ellipsis → Edit goes through DefaultVaultItemMoreOptionsHelper:
// VaultItemMoreOptionsHelper.swift:230
case let .edit(cipherView):
self.coordinator.navigate(to: .editItem(cipherView), context: self)VaultCoordinator resolves that context with context as? CipherItemOperationDelegate (VaultCoordinator.swift:232), and DefaultVaultItemMoreOptionsHelper does not conform to that protocol, so AddEditItemProcessor.delegate is nil and itemSaved(type:) never fires.
Net effect after this change: adding an item from the vault list shows a toast, editing via row → view → edit shows a toast, but editing via row → ellipsis → Edit → Save shows nothing. Before this PR all three were silent, so the inconsistency is new.
The helper already has a handleDisplayToast channel it uses for copy/archive/unarchive, so wiring the save confirmation through it is one option — happy to defer if this path is planned as follow-up work.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## pm-41957-new-folder-added-snackbar #2993 +/- ##
======================================================================
+ Coverage 79.52% 79.54% +0.01%
======================================================================
Files 1169 1169
Lines 75112 75141 +29
======================================================================
+ Hits 59733 59769 +36
+ Misses 15379 15372 -7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
2edc24a to
8b84dcb
Compare
🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-42025
📔 Objective
itemAdded()also fires when you cancel out of the editor, so the toast couldn't just hang off the existing delegate methods.itemSaved(type:)delegate call that only fires after the item actually saves, plus a per-type title so each type gets its own wording.📸 Screenshots
Before
Screen.Recording.2026-08-26.at.12.57.58.mov
After
Screen.Recording.2026-08-26.at.13.03.43.mov