Ownership should be common values only displayed when creating a cipher (#365)

This commit is contained in:
David Perez 2023-12-11 13:24:36 -06:00 committed by Álison Fernandes
parent 82d7c307ff
commit dd37721e51
6 changed files with 86 additions and 73 deletions

View file

@ -21,7 +21,7 @@ import kotlinx.collections.immutable.toImmutableList
@Composable @Composable
fun AddEditItemContent( fun AddEditItemContent(
viewState: VaultAddItemState.ViewState.Content, viewState: VaultAddItemState.ViewState.Content,
shouldShowTypeSelector: Boolean, isAddItemMode: Boolean,
onTypeOptionClicked: (VaultAddItemState.ItemTypeOption) -> Unit, onTypeOptionClicked: (VaultAddItemState.ItemTypeOption) -> Unit,
loginItemTypeHandlers: VaultAddLoginItemTypeHandlers, loginItemTypeHandlers: VaultAddLoginItemTypeHandlers,
secureNotesTypeHandlers: VaultAddSecureNotesItemTypeHandlers, secureNotesTypeHandlers: VaultAddSecureNotesItemTypeHandlers,
@ -38,7 +38,7 @@ fun AddEditItemContent(
.padding(horizontal = 16.dp), .padding(horizontal = 16.dp),
) )
} }
if (shouldShowTypeSelector) { if (isAddItemMode) {
item { item {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
TypeOptionsItem( TypeOptionsItem(
@ -53,6 +53,7 @@ fun AddEditItemContent(
is VaultAddItemState.ViewState.Content.Login -> { is VaultAddItemState.ViewState.Content.Login -> {
addEditLoginItems( addEditLoginItems(
state = viewState, state = viewState,
isAddItemMode = isAddItemMode,
loginItemTypeHandlers = loginItemTypeHandlers, loginItemTypeHandlers = loginItemTypeHandlers,
) )
} }
@ -68,6 +69,7 @@ fun AddEditItemContent(
is VaultAddItemState.ViewState.Content.SecureNotes -> { is VaultAddItemState.ViewState.Content.SecureNotes -> {
addEditSecureNotesItems( addEditSecureNotesItems(
state = viewState, state = viewState,
isAddItemMode = isAddItemMode,
secureNotesTypeHandlers = secureNotesTypeHandlers, secureNotesTypeHandlers = secureNotesTypeHandlers,
) )
} }

View file

@ -32,6 +32,7 @@ import kotlinx.collections.immutable.toImmutableList
@Suppress("LongMethod") @Suppress("LongMethod")
fun LazyListScope.addEditLoginItems( fun LazyListScope.addEditLoginItems(
state: VaultAddItemState.ViewState.Content.Login, state: VaultAddItemState.ViewState.Content.Login,
isAddItemMode: Boolean,
loginItemTypeHandlers: VaultAddLoginItemTypeHandlers, loginItemTypeHandlers: VaultAddLoginItemTypeHandlers,
) { ) {
item { item {
@ -255,25 +256,29 @@ fun LazyListScope.addEditLoginItems(
) )
} }
item { if (isAddItemMode) {
Spacer(modifier = Modifier.height(24.dp)) item {
BitwardenListHeaderText( Spacer(modifier = Modifier.height(24.dp))
label = stringResource(id = R.string.ownership), BitwardenListHeaderText(
modifier = Modifier label = stringResource(id = R.string.ownership),
.fillMaxWidth() modifier = Modifier
.padding(horizontal = 16.dp), .fillMaxWidth()
) .padding(horizontal = 16.dp),
} )
}
item { item {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
BitwardenMultiSelectButton( BitwardenMultiSelectButton(
label = stringResource(id = R.string.who_owns_this_item), label = stringResource(id = R.string.who_owns_this_item),
options = state.availableOwners.toImmutableList(), options = state.availableOwners.toImmutableList(),
selectedOption = state.ownership, selectedOption = state.ownership,
onOptionSelected = loginItemTypeHandlers.onOwnershipTextChange, onOptionSelected = loginItemTypeHandlers.onOwnershipTextChange,
modifier = Modifier.padding(horizontal = 16.dp), modifier = Modifier
) .fillMaxWidth()
.padding(horizontal = 16.dp),
)
}
} }
item { item {

View file

@ -27,6 +27,7 @@ import kotlinx.collections.immutable.toImmutableList
@Suppress("LongMethod") @Suppress("LongMethod")
fun LazyListScope.addEditSecureNotesItems( fun LazyListScope.addEditSecureNotesItems(
state: VaultAddItemState.ViewState.Content.SecureNotes, state: VaultAddItemState.ViewState.Content.SecureNotes,
isAddItemMode: Boolean,
secureNotesTypeHandlers: VaultAddSecureNotesItemTypeHandlers, secureNotesTypeHandlers: VaultAddSecureNotesItemTypeHandlers,
) { ) {
item { item {
@ -142,26 +143,29 @@ fun LazyListScope.addEditSecureNotesItems(
) )
} }
item { if (isAddItemMode) {
Spacer(modifier = Modifier.height(24.dp)) item {
BitwardenListHeaderText( Spacer(modifier = Modifier.height(24.dp))
label = stringResource(id = R.string.ownership), BitwardenListHeaderText(
modifier = Modifier label = stringResource(id = R.string.ownership),
.fillMaxWidth() modifier = Modifier
.padding(horizontal = 16.dp), .fillMaxWidth()
) .padding(horizontal = 16.dp),
} )
}
item { item {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
BitwardenMultiSelectButton( BitwardenMultiSelectButton(
label = stringResource(id = R.string.who_owns_this_item), label = stringResource(id = R.string.who_owns_this_item),
options = state.availableOwners.toImmutableList(), options = state.availableOwners.toImmutableList(),
selectedOption = state.ownership, selectedOption = state.ownership,
onOptionSelected = secureNotesTypeHandlers.onOwnershipTextChange, onOptionSelected = secureNotesTypeHandlers.onOwnershipTextChange,
modifier = Modifier modifier = Modifier
.padding(horizontal = 16.dp), .fillMaxWidth()
) .padding(horizontal = 16.dp),
)
}
} }
item { item {

View file

@ -95,7 +95,7 @@ fun VaultAddItemScreen(
is VaultAddItemState.ViewState.Content -> { is VaultAddItemState.ViewState.Content -> {
AddEditItemContent( AddEditItemContent(
viewState = viewState, viewState = viewState,
shouldShowTypeSelector = state.shouldShowTypeSelector, isAddItemMode = state.isAddItemMode,
onTypeOptionClicked = remember(viewModel) { onTypeOptionClicked = remember(viewModel) {
{ viewModel.trySendAction(VaultAddItemAction.TypeOptionSelect(it)) } { viewModel.trySendAction(VaultAddItemAction.TypeOptionSelect(it)) }
}, },

View file

@ -188,7 +188,7 @@ class VaultAddItemViewModel @Inject constructor(
} }
is VaultAddItemAction.ItemType.LoginType.UriTextChange -> { is VaultAddItemAction.ItemType.LoginType.UriTextChange -> {
handleLoginURITextInputChange(action) handleLoginUriTextInputChange(action)
} }
is VaultAddItemAction.ItemType.LoginType.FolderChange -> { is VaultAddItemAction.ItemType.LoginType.FolderChange -> {
@ -269,7 +269,7 @@ class VaultAddItemViewModel @Inject constructor(
} }
} }
private fun handleLoginURITextInputChange( private fun handleLoginUriTextInputChange(
action: VaultAddItemAction.ItemType.LoginType.UriTextChange, action: VaultAddItemAction.ItemType.LoginType.UriTextChange,
) { ) {
updateLoginContent { loginType -> updateLoginContent { loginType ->
@ -598,15 +598,9 @@ data class VaultAddItemState(
} }
/** /**
* Helper to determine if the UI should display the type selector. * Helper to determine if the UI should display the content in add item mode.
*/ */
val shouldShowTypeSelector: Boolean get() = vaultAddEditType == VaultAddEditType.AddItem val isAddItemMode: Boolean get() = vaultAddEditType == VaultAddEditType.AddItem
/**
* Provides a list of available item types for the vault.
*/
val typeOptions: List<ItemTypeOption>
get() = ItemTypeOption.entries.toList()
/** /**
* Enum representing the main type options for the vault, such as LOGIN, CARD, etc. * Enum representing the main type options for the vault, such as LOGIN, CARD, etc.
@ -658,6 +652,21 @@ data class VaultAddItemState(
*/ */
abstract val name: String abstract val name: String
/**
* Indicates if a master password reprompt is required.
*/
abstract val masterPasswordReprompt: Boolean
/**
* The ownership email associated with the login item.
*/
abstract val ownership: String
/**
* A list of available owners.
*/
abstract val availableOwners: List<String>
/** /**
* Represents the login item information. * Represents the login item information.
* *
@ -666,11 +675,8 @@ data class VaultAddItemState(
* @property uri The URI associated with the login item. * @property uri The URI associated with the login item.
* @property folderName The folder used for the login item * @property folderName The folder used for the login item
* @property favorite Indicates whether this login item is marked as a favorite. * @property favorite Indicates whether this login item is marked as a favorite.
* @property masterPasswordReprompt Indicates if a master password reprompt is required.
* @property notes Any additional notes or comments associated with the login item. * @property notes Any additional notes or comments associated with the login item.
* @property ownership The ownership email associated with the login item.
* @property availableFolders Retrieves a list of available folders. * @property availableFolders Retrieves a list of available folders.
* @property availableOwners Retrieves a list of available owners.
*/ */
@Parcelize @Parcelize
data class Login( data class Login(
@ -680,9 +686,8 @@ data class VaultAddItemState(
val uri: String = "", val uri: String = "",
val folderName: Text = DEFAULT_FOLDER, val folderName: Text = DEFAULT_FOLDER,
val favorite: Boolean = false, val favorite: Boolean = false,
val masterPasswordReprompt: Boolean = false, override val masterPasswordReprompt: Boolean = false,
val notes: String = "", val notes: String = "",
val ownership: String = DEFAULT_OWNERSHIP,
// TODO: Update this property to get available owners from the data layer (BIT-501) // TODO: Update this property to get available owners from the data layer (BIT-501)
val availableFolders: List<Text> = listOf( val availableFolders: List<Text> = listOf(
"Folder 1".asText(), "Folder 1".asText(),
@ -690,14 +695,10 @@ data class VaultAddItemState(
"Folder 3".asText(), "Folder 3".asText(),
), ),
// TODO: Update this property to get available owners from the data layer (BIT-501) // TODO: Update this property to get available owners from the data layer (BIT-501)
val availableOwners: List<String> = listOf("a@b.com", "c@d.com"), override val ownership: String = DEFAULT_OWNERSHIP,
override val availableOwners: List<String> = listOf("a@b.com", "c@d.com"),
) : Content() { ) : Content() {
override val displayStringResId: Int get() = ItemTypeOption.LOGIN.labelRes override val displayStringResId: Int get() = ItemTypeOption.LOGIN.labelRes
companion object {
private val DEFAULT_FOLDER: Text = R.string.folder_none.asText()
private const val DEFAULT_OWNERSHIP: String = "placeholder@email.com"
}
} }
/** /**
@ -706,6 +707,9 @@ data class VaultAddItemState(
@Parcelize @Parcelize
data class Card( data class Card(
override val name: String = "", override val name: String = "",
override val masterPasswordReprompt: Boolean = false,
override val ownership: String = DEFAULT_OWNERSHIP,
override val availableOwners: List<String> = listOf("a@b.com", "c@d.com"),
) : Content() { ) : Content() {
override val displayStringResId: Int get() = ItemTypeOption.CARD.labelRes override val displayStringResId: Int get() = ItemTypeOption.CARD.labelRes
} }
@ -716,6 +720,9 @@ data class VaultAddItemState(
@Parcelize @Parcelize
data class Identity( data class Identity(
override val name: String = "", override val name: String = "",
override val masterPasswordReprompt: Boolean = false,
override val ownership: String = DEFAULT_OWNERSHIP,
override val availableOwners: List<String> = listOf("a@b.com", "c@d.com"),
) : Content() { ) : Content() {
override val displayStringResId: Int get() = ItemTypeOption.IDENTITY.labelRes override val displayStringResId: Int get() = ItemTypeOption.IDENTITY.labelRes
} }
@ -725,33 +732,30 @@ data class VaultAddItemState(
* *
* @property folderName The folder used for the SecureNotes item * @property folderName The folder used for the SecureNotes item
* @property favorite Indicates whether this SecureNotes item is marked as a favorite. * @property favorite Indicates whether this SecureNotes item is marked as a favorite.
* @property masterPasswordReprompt Indicates if a master password reprompt is required.
* @property notes Notes or comments associated with the SecureNotes item. * @property notes Notes or comments associated with the SecureNotes item.
* @property ownership The ownership email associated with the SecureNotes item.
* @property availableFolders A list of available folders. * @property availableFolders A list of available folders.
* @property availableOwners A list of available owners.
*/ */
@Parcelize @Parcelize
data class SecureNotes( data class SecureNotes(
override val name: String = "", override val name: String = "",
val folderName: Text = DEFAULT_FOLDER, val folderName: Text = DEFAULT_FOLDER,
val favorite: Boolean = false, val favorite: Boolean = false,
val masterPasswordReprompt: Boolean = false, override val masterPasswordReprompt: Boolean = false,
val notes: String = "", val notes: String = "",
val ownership: String = DEFAULT_OWNERSHIP,
val availableFolders: List<Text> = listOf( val availableFolders: List<Text> = listOf(
"Folder 1".asText(), "Folder 1".asText(),
"Folder 2".asText(), "Folder 2".asText(),
"Folder 3".asText(), "Folder 3".asText(),
), ),
val availableOwners: List<String> = listOf("a@b.com", "c@d.com"), override val ownership: String = DEFAULT_OWNERSHIP,
override val availableOwners: List<String> = listOf("a@b.com", "c@d.com"),
) : Content() { ) : Content() {
override val displayStringResId: Int get() = ItemTypeOption.SECURE_NOTES.labelRes override val displayStringResId: Int get() = ItemTypeOption.SECURE_NOTES.labelRes
}
companion object { companion object {
private val DEFAULT_FOLDER: Text = R.string.folder_none.asText() private val DEFAULT_FOLDER: Text = R.string.folder_none.asText()
private const val DEFAULT_OWNERSHIP: String = "placeholder@email.com" private const val DEFAULT_OWNERSHIP: String = "placeholder@email.com"
}
} }
} }
} }

View file

@ -356,7 +356,6 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
assertEquals(expectedState, viewModel.stateFlow.value) assertEquals(expectedState, viewModel.stateFlow.value)
} }
@Suppress("MaxLineLength")
@Test @Test
fun `OwnershipChange should update ownership in LoginItem`() = runTest { fun `OwnershipChange should update ownership in LoginItem`() = runTest {
val viewModel = createAddVaultItemViewModel() val viewModel = createAddVaultItemViewModel()
@ -593,7 +592,6 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
assertEquals(expectedState, viewModel.stateFlow.value) assertEquals(expectedState, viewModel.stateFlow.value)
} }
@Suppress("MaxLineLength")
@Test @Test
fun `OwnershipChange should update ownership in SecureNotesItem`() = runTest { fun `OwnershipChange should update ownership in SecureNotesItem`() = runTest {
val action = val action =