From d582ea32606a5d4875c605b31ef4a605e5c3632f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Bispo?= Date: Wed, 26 Aug 2026 10:46:18 +0100 Subject: [PATCH 1/3] [PM-36379] fix: Add item type specific saved strings --- ui/src/main/res/values/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 44267d14d45..1402269907c 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -150,6 +150,14 @@ Select Item details Item saved + Bank account saved + Card saved + Identity saved + License saved + Login saved + Passport saved + Secure note saved + SSH key saved Submitting… Syncing… Syncing complete From 2a1a1c53914f73b1726fcd2443dc66714e3911c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Bispo?= Date: Wed, 26 Aug 2026 10:46:29 +0100 Subject: [PATCH 2/3] [PM-36379] fix: Show the item type in the save snackbar --- .../feature/addedit/VaultAddEditViewModel.kt | 19 ++++- .../addedit/VaultAddEditViewModelTest.kt | 84 ++++++++++++++++++- 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt index f587ba19e86..55cc5ba4360 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt @@ -2033,7 +2033,7 @@ class VaultAddEditViewModel @Inject constructor( sendEvent(event = VaultAddEditEvent.ExitApp) } else { snackbarRelayManager.sendSnackbarData( - data = BitwardenSnackbarData(BitwardenString.new_item_created.asText()), + data = BitwardenSnackbarData(state.savedSnackbarMessage), relay = SnackbarRelay.CIPHER_CREATED, ) sendEvent(event = VaultAddEditEvent.NavigateBack) @@ -2066,7 +2066,7 @@ class VaultAddEditViewModel @Inject constructor( sendEvent(event = VaultAddEditEvent.ExitApp) } else { snackbarRelayManager.sendSnackbarData( - data = BitwardenSnackbarData(BitwardenString.item_updated.asText()), + data = BitwardenSnackbarData(state.savedSnackbarMessage), relay = SnackbarRelay.CIPHER_UPDATED, ) sendEvent(event = VaultAddEditEvent.NavigateBack) @@ -2810,6 +2810,21 @@ data class VaultAddEditState( } } + /** + * Helper to determine the snackbar message shown after the item is successfully saved. + */ + val savedSnackbarMessage: Text + get() = when (cipherType) { + VaultItemCipherType.LOGIN -> BitwardenString.login_saved.asText() + VaultItemCipherType.CARD -> BitwardenString.card_saved.asText() + VaultItemCipherType.IDENTITY -> BitwardenString.identity_saved.asText() + VaultItemCipherType.SECURE_NOTE -> BitwardenString.secure_note_saved.asText() + VaultItemCipherType.SSH_KEY -> BitwardenString.ssh_key_saved.asText() + VaultItemCipherType.BANK_ACCOUNT -> BitwardenString.bank_account_saved.asText() + VaultItemCipherType.DRIVERS_LICENSE -> BitwardenString.license_saved.asText() + VaultItemCipherType.PASSPORT -> BitwardenString.passport_saved.asText() + } + /** * Whether the cipher is in a collection. */ diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt index e3626626edd..58268711bb8 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt @@ -961,7 +961,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { } verify(exactly = 1) { snackbarRelayManager.sendSnackbarData( - data = BitwardenSnackbarData(BitwardenString.new_item_created.asText()), + data = BitwardenSnackbarData(BitwardenString.login_saved.asText()), relay = SnackbarRelay.CIPHER_CREATED, ) } @@ -1131,7 +1131,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { assertNotNull(specialCircumstanceManager.specialCircumstance) verify(exactly = 1) { snackbarRelayManager.sendSnackbarData( - data = BitwardenSnackbarData(BitwardenString.new_item_created.asText()), + data = BitwardenSnackbarData(BitwardenString.login_saved.asText()), relay = SnackbarRelay.CIPHER_CREATED, ) } @@ -1514,12 +1514,88 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { } verify(exactly = 1) { snackbarRelayManager.sendSnackbarData( - data = BitwardenSnackbarData(BitwardenString.new_item_created.asText()), + data = BitwardenSnackbarData(BitwardenString.login_saved.asText()), relay = SnackbarRelay.CIPHER_CREATED, ) } } + @Suppress("MaxLineLength") + @Test + fun `in add mode with a card, createCipherInOrganization success should send the card saved snackbar`() = + runTest { + val stateWithName = createVaultAddItemState( + vaultItemCipherType = VaultItemCipherType.CARD, + commonContentViewState = createCommonContentViewState( + name = "mockName-1", + ), + typeContentViewState = VaultAddEditState.ViewState.Content.ItemType.Card(), + ) + + mutableVaultDataFlow.value = DataState.Loaded(createVaultData()) + + val viewModel = createAddVaultItemViewModel( + createSavedStateHandleWithState( + state = stateWithName, + vaultAddEditType = VaultAddEditType.AddItem, + vaultItemCipherType = VaultItemCipherType.CARD, + ), + ) + + coEvery { + vaultRepository.createCipherInOrganization(any(), any()) + } returns CreateCipherResult.Success + viewModel.eventFlow.test { + viewModel.trySendAction(VaultAddEditAction.Common.SaveClick) + assertEquals(VaultAddEditEvent.NavigateBack, awaitItem()) + } + verify(exactly = 1) { + snackbarRelayManager.sendSnackbarData( + data = BitwardenSnackbarData(BitwardenString.card_saved.asText()), + relay = SnackbarRelay.CIPHER_CREATED, + ) + } + } + + @Test + fun `in edit mode with a card, updateCipher success should send the card saved snackbar`() = + runTest { + val cipherView = createMockCipherListView(1) + val stateWithName = createVaultAddItemState( + vaultAddEditType = VaultAddEditType.EditItem(DEFAULT_EDIT_ITEM_ID), + vaultItemCipherType = VaultItemCipherType.CARD, + commonContentViewState = createCommonContentViewState( + name = "mockName-1", + ), + typeContentViewState = VaultAddEditState.ViewState.Content.ItemType.Card(), + ) + + mutableVaultDataFlow.value = + DataState.Loaded(createVaultData(cipherListView = cipherView)) + + val viewModel = createAddVaultItemViewModel( + createSavedStateHandleWithState( + state = stateWithName, + vaultAddEditType = VaultAddEditType.EditItem(DEFAULT_EDIT_ITEM_ID), + vaultItemCipherType = VaultItemCipherType.CARD, + ), + ) + + coEvery { + vaultRepository.updateCipher(any(), any()) + } returns UpdateCipherResult.Success + viewModel.eventFlow.test { + viewModel.trySendAction(VaultAddEditAction.Common.SaveClick) + assertEquals(VaultAddEditEvent.NavigateBack, awaitItem()) + } + verify(exactly = 1) { + snackbarRelayManager.sendSnackbarData( + data = BitwardenSnackbarData(BitwardenString.card_saved.asText()), + relay = SnackbarRelay.CIPHER_UPDATED, + ) + } + } + @Test fun `in edit mode, canDelete should be true when cipher permission is true`() = runTest { @@ -1855,7 +1931,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { } verify(exactly = 1) { snackbarRelayManager.sendSnackbarData( - data = BitwardenSnackbarData(BitwardenString.item_updated.asText()), + data = BitwardenSnackbarData(BitwardenString.login_saved.asText()), relay = SnackbarRelay.CIPHER_UPDATED, ) } From a000c113e138a49faf70cdb6bb7c953412c421e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Bispo?= Date: Thu, 27 Aug 2026 14:29:29 +0100 Subject: [PATCH 3/3] [PM-36379] fix: Remove the unused new_item_created string The item type specific saved strings replaced the only usage of new_item_created in VaultAddEditViewModel, leaving the resource orphaned. Removing it from the base strings file keeps the Crowdin translation source clean. --- ui/src/main/res/values/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 1402269907c..1df9b008a7c 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -120,7 +120,6 @@ Minimum numbers Minimum special Never - Item added There are no cards in your vault. Add card There are no logins in your vault.