Skip to content

Commit

Permalink
Form Patching Support
Browse files Browse the repository at this point in the history
  • Loading branch information
Shade authored and Shade committed Nov 22, 2024
1 parent 8378dd8 commit 3b3e1b4
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 25 deletions.
2 changes: 2 additions & 0 deletions src/main/kotlin/repository/creditcard/CreditCardRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ interface CreditCardRepository {

suspend fun save(creditCardDto: CreditCardDto): Result<Boolean>

suspend fun update(id: UUID, user: String, creditCardDto: CreditCardDto): Result<Boolean>

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import repository.creditcard.CreditCard
import repository.creditcard.CreditCardRepository
import repository.creditcard.CreditCardTable
import repository.creditcard.projection.CreditCardSummary
import java.time.LocalDateTime
import java.util.*

class CreditCardRepositoryImpl(
Expand Down Expand Up @@ -92,6 +93,30 @@ class CreditCardRepositoryImpl(
}
}

override suspend fun update(id: UUID, user: String, creditCardDto: CreditCardDto): Result<Boolean> {
return try {
return transaction(db) {
CreditCard.findById(id)?.let {
it.owner = creditCardDto.owner
it.name = creditCardDto.name
it.number = creditCardDto.number
it.cvc = creditCardDto.cvc
it.pin = creditCardDto.pin
it.notes = creditCardDto.notes
it.expiryDate = creditCardDto.expiryDate
it.lastUpdateDateTime = LocalDateTime.now()
it.lastUpdatedBy = user
it.version += 1
}
}.let {
Result.Success(true)
}
} catch (e: Exception) {
logger.error(e.message, e)
Result.Error(DatabaseError.fromException(e).extractMessage())
}
}

private fun toSort(sort: CredentialSort): Expression<*> {
return when (sort) {
CredentialSort.NAME -> CreditCardTable.name
Expand Down
4 changes: 3 additions & 1 deletion src/main/kotlin/repository/password/PasswordRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import core.models.Result
import core.models.criteria.CredentialSearchCriteria
import core.models.dto.PasswordDto
import repository.password.projection.PasswordSummary
import java.util.UUID
import java.util.*

interface PasswordRepository {

Expand All @@ -14,4 +14,6 @@ interface PasswordRepository {

suspend fun save(password: PasswordDto): Result<Boolean>

suspend fun update(id: UUID, user: String, password: PasswordDto): Result<Boolean>

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import repository.password.Password
import repository.password.PasswordRepository
import repository.password.PasswordsTable
import repository.password.projection.PasswordSummary
import java.time.LocalDateTime
import java.util.*

class PasswordRepositoryImpl(
Expand Down Expand Up @@ -56,7 +57,11 @@ class PasswordRepositoryImpl(
query.orderBy(toSort(searchCriteria.sort), toOrder(searchCriteria.sort)).map { resultRow ->
PasswordSummary(
id = resultRow[PasswordsTable.id].value,
name = resultRow[PasswordsTable.name].replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() },
name = resultRow[PasswordsTable.name].replaceFirstChar {
if (it.isLowerCase()) it.titlecase(
Locale.getDefault()
) else it.toString()
},
username = resultRow[PasswordsTable.username],
email = resultRow[PasswordsTable.email],
favorite = resultRow[PasswordsTable.favorite]
Expand Down Expand Up @@ -92,6 +97,29 @@ class PasswordRepositoryImpl(
}
}

override suspend fun update(id: UUID, user: String, password: PasswordDto): Result<Boolean> {
return try {
return transaction(db) {
Password.findById(id)?.let {
it.username = password.userName?.lowercase()
it.email = password.email
it.password = password.password
it.name = password.name.lowercase()
it.website = password.website
it.websiteIcon = password.icon
it.lastUpdatedBy = user
it.lastUpdateDateTime = LocalDateTime.now()
it.version += 1
}
}.let {
Result.Success(true)
}
} catch (e: Exception) {
logger.error(e.message, e)
Result.Error(DatabaseError.fromException(e).extractMessage())
}
}

private fun toSort(sort: CredentialSort): Expression<*> {
return when (sort) {
CredentialSort.NAME -> PasswordsTable.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.dokar.sonner.Toaster
import com.dokar.sonner.rememberToasterState
import core.form.validation.FormValidator
import core.models.FormType
import core.models.FormType.CREATION
import core.models.UiState
import kotlinx.coroutines.delay
import repository.creditcard.CreditCard
Expand Down Expand Up @@ -142,8 +143,8 @@ class CreditCardForm(creditCard: CreditCard?, formType: FormType) : Screen {
) {
Header(
creditCardButtonShown = false,
notesButtonShown = (formType == FormType.CREATION),
title = if (formType == FormType.CREATION) "Create Credit Card" else "Update Credit Card"
notesButtonShown = (formType == CREATION),
title = if (formType == CREATION) "Create Credit Card" else "Update Credit Card"
)
}

Expand Down Expand Up @@ -330,11 +331,13 @@ class CreditCardForm(creditCard: CreditCard?, formType: FormType) : Screen {
Footer(
{
screenModel.saveCreditCard(
_creditCard?.id?.value,
toCreditCardDto(
formValidator,
screenModel.getAuthenticatedUser(),
selectedItem?.id!!
)
),
formType
)
},
{ navigator?.popUntil { screen: Screen -> screen.key == SecVaultScreen().key } },
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/ui/screens/PasswordMgntScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class PasswordMgntScreen(password: Password?, formType: FormType) : Screen {
formValidator,
screenModel,
isFormValid,
onSaveClick = { password: PasswordDto -> screenModel.savePassword(password) },
onSaveClick = { password: PasswordDto -> screenModel.savePassword(_password?.id?.value, password, _formType) },
onCancelClick = { navigator?.pop() },
_formType
)
Expand Down
63 changes: 44 additions & 19 deletions src/main/kotlin/viewmodel/PasswordMgntScreenModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package viewmodel
import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.screenModelScope
import core.AppState
import core.models.FormType
import core.models.Result
import core.models.UiState
import core.models.dto.CreditCardDto
Expand All @@ -17,6 +18,7 @@ import repository.creditcard.CreditCardRepository
import repository.password.PasswordRepository
import repository.user.User
import repository.user.UserRepository
import java.util.*

class PasswordMgntScreenModel(
private val passwordRepository: PasswordRepository,
Expand All @@ -29,30 +31,30 @@ class PasswordMgntScreenModel(
private val _passwordState = MutableStateFlow<UiState<Boolean>>(UiState.Idle)
val passwordState: StateFlow<UiState<Boolean>> = _passwordState.asStateFlow()

fun savePassword(password: PasswordDto) {
screenModelScope.launch(dispatcher) {
_passwordState.value = UiState.Loading

when (val result = passwordRepository.save(password)) {
is Result.Success -> _passwordState.value = UiState.Success(result.data)
is Result.Error -> _passwordState.value = UiState.Error(result.message)
}
}
fun savePassword(id: UUID?, password: PasswordDto, formType: FormType) {
saveOrUpdate(
id = id,
dto = password,
formType = formType,
saveAction = passwordRepository::save,
updateAction = passwordRepository::update,
stateUpdater = { _passwordState.value = it }
)
}

fun saveCreditCard(creditCardDto: CreditCardDto) {
screenModelScope.launch(dispatcher) {
_passwordState.value = UiState.Loading

when (val result = creditCardRepository.save(creditCardDto)) {
is Result.Success -> _passwordState.value = UiState.Success(result.data)
is Result.Error -> _passwordState.value = UiState.Error(result.message)
}
}
fun saveCreditCard(id: UUID?, creditCardDto: CreditCardDto, formType: FormType) {
saveOrUpdate(
id = id,
dto = creditCardDto,
formType = formType,
saveAction = creditCardRepository::save,
updateAction = creditCardRepository::update,
stateUpdater = { _passwordState.value = it }
)
}

fun fetchUsers(): List<User> {
return userRepository.findAll();
return userRepository.findAll()
}

fun getAuthenticatedUser(): User {
Expand All @@ -63,4 +65,27 @@ class PasswordMgntScreenModel(
_passwordState.value = UiState.Idle
}

private fun <T, R> saveOrUpdate(
id: UUID?,
dto: T,
formType: FormType,
saveAction: suspend (T) -> Result<R>,
updateAction: suspend (UUID, String, T) -> Result<R>,
stateUpdater: (UiState<R>) -> Unit
) {
screenModelScope.launch(dispatcher) {
stateUpdater(UiState.Loading)

val result = when (formType) {
FormType.CREATION -> saveAction(dto)
FormType.MODIFIATION -> updateAction(id!!, appState.userName, dto)
}

when (result) {
is Result.Success -> stateUpdater(UiState.Success(result.data))
is Result.Error -> stateUpdater(UiState.Error(result.message))
}
}
}

}

0 comments on commit 3b3e1b4

Please sign in to comment.