Skip to content

Commit

Permalink
feat: [ANDROAPP-5688] update legend value after half second (#3776)
Browse files Browse the repository at this point in the history
* feat: [ANDROAPP-5688] update legend value after half second

* fix: [ANDROAPP-5688] maintain cursor selection when updating field

* ci: [ANDROAPP-5688] Add test for legend refresh on value changed

* chore: [ANDROAPP-5688] refactor

---------

Co-authored-by: Xavier Molloy <[email protected]>
  • Loading branch information
mmmateos and xavimolloy authored Sep 6, 2024
1 parent 8ec6ec6 commit 843505e
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 39 deletions.
1 change: 1 addition & 0 deletions form/src/main/java/org/dhis2/form/data/FormRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ interface FormRepository {
fun clearFocusItem()
fun storeFile(id: String, filePath: String?): StoreResult?
fun areSectionCollapsable(): Boolean
fun hasLegendSet(dataElementUid: String): Boolean
}
3 changes: 3 additions & 0 deletions form/src/main/java/org/dhis2/form/data/FormRepositoryImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,9 @@ class FormRepositoryImpl(
return disableCollapsableSections ?: false
}

override fun hasLegendSet(dataElementUid: String): Boolean =
legendValueProvider.hasLegendSet(dataElementUid)

override fun setFocusedItem(action: RowAction) {
focusedItemId = when (action.type) {
ActionType.ON_NEXT -> getNextItem(action.id)
Expand Down
14 changes: 13 additions & 1 deletion form/src/main/java/org/dhis2/form/ui/FormViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.dhis2.form.ui

import android.os.Handler
import android.os.Looper
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
Expand Down Expand Up @@ -93,6 +95,8 @@ class FormViewModel(
onBufferOverflow = BufferOverflow.DROP_OLDEST,
)

private val handler = Handler(Looper.getMainLooper())

init {
viewModelScope.launch {
_pendingIntents
Expand Down Expand Up @@ -162,6 +166,12 @@ class FormViewModel(
Timber.d("${result.first.id} is changing its value")
_queryData.value = it
}
if (repository.hasLegendSet(result.first.id)) {
handler.removeCallbacksAndMessages(null)
handler.postDelayed({
processCalculatedItems(skipProgramRules = true)
}, 500L)
}
}

ValueStoreResult.FINISH -> {
Expand Down Expand Up @@ -358,7 +368,9 @@ class FormViewModel(

private fun checkAutoCompleteForLastFocusedItem(fieldUidModel: FieldUiModel) =
getLastFocusedTextItem()?.let {
if (fieldUidModel.renderingType == UiRenderType.AUTOCOMPLETE && !fieldUidModel.value.isNullOrEmpty() && fieldUidModel.value?.trim()?.length != 0) {
if (fieldUidModel.renderingType == UiRenderType.AUTOCOMPLETE &&
!fieldUidModel.value.isNullOrEmpty() && fieldUidModel.value?.trim()?.length != 0
) {
val autoCompleteValues =
getListFromPreference(fieldUidModel.uid)
if (!autoCompleteValues.contains(fieldUidModel.value)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import org.dhis2.form.model.LegendValue
interface LegendValueProvider {

fun provideLegendValue(dataElementUid: String, value: String?): LegendValue?
fun hasLegendSet(dataElementUid: String): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,13 @@ class LegendValueProviderImpl(
}
}
}

override fun hasLegendSet(dataElementUid: String): Boolean {
return d2.dataElementModule().dataElements()
.byUid().eq(dataElementUid)
.withLegendSets()
.one().blockingGet()
?.legendSets()?.isNotEmpty()
?: false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -541,13 +541,15 @@ private fun ProvideIntegerPositive(
focusManager: FocusManager,
onNextClicked: () -> Unit,
) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputPositiveInteger(
modifier = modifier.fillMaxWidth(),
inputStyle = inputStyle,
Expand All @@ -560,6 +562,7 @@ private fun ProvideIntegerPositive(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand All @@ -585,11 +588,14 @@ private fun ProvideIntegerPositiveOrZero(
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputPositiveIntegerOrZero(
Expand All @@ -604,6 +610,7 @@ private fun ProvideIntegerPositiveOrZero(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand All @@ -629,11 +636,14 @@ private fun ProvidePercentage(
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputPercentage(
Expand All @@ -648,6 +658,7 @@ private fun ProvidePercentage(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand All @@ -673,11 +684,14 @@ private fun ProvideNumber(
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputNumber(
Expand All @@ -692,6 +706,7 @@ private fun ProvideNumber(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand All @@ -718,10 +733,13 @@ private fun ProvideIntegerNegative(
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}
var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value?.replace("-", "") ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value?.replace("-", "") ?: "", savedTextSelection))
}

InputNegativeInteger(
Expand All @@ -736,6 +754,7 @@ private fun ProvideIntegerNegative(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand All @@ -761,13 +780,15 @@ private fun ProvideLongText(
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputLongText(
modifier = modifier.fillMaxWidth(),
inputStyle = inputStyle,
Expand All @@ -780,6 +801,7 @@ private fun ProvideLongText(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand All @@ -806,12 +828,15 @@ private fun ProvideLetter(
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}
InputLetter(
modifier = modifier.fillMaxWidth(),
inputStyle = inputStyle,
Expand All @@ -824,6 +849,7 @@ private fun ProvideLetter(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand All @@ -849,10 +875,14 @@ private fun ProvideInteger(
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputInteger(
Expand All @@ -867,6 +897,7 @@ private fun ProvideInteger(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand All @@ -892,11 +923,14 @@ private fun ProvideEmail(
focusManager: FocusManager,
onNextClicked: () -> Unit,
) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputEmail(
Expand All @@ -911,6 +945,7 @@ private fun ProvideEmail(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand Down Expand Up @@ -946,11 +981,14 @@ private fun ProvideInputPhoneNumber(
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputPhoneNumber(
Expand All @@ -965,6 +1003,7 @@ private fun ProvideInputPhoneNumber(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand Down Expand Up @@ -998,13 +1037,15 @@ private fun ProvideInputLink(
uiEventHandler: (RecyclerViewUiEvents) -> Unit,
focusManager: FocusManager,
onNextClicked: () -> Unit,

) {
val textSelection =
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0)
var savedTextSelection by remember {
mutableStateOf(
TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0),
)
}

var value by remember(fieldUiModel.value) {
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection))
mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", savedTextSelection))
}

InputLink(
Expand All @@ -1019,6 +1060,7 @@ private fun ProvideInputLink(
onNextClicked = onNextClicked,
onValueChanged = {
value = it ?: TextFieldValue()
savedTextSelection = it?.selection ?: TextRange.Zero
intentHandler(
FormIntent.OnTextChange(
fieldUiModel.uid,
Expand Down
Loading

0 comments on commit 843505e

Please sign in to comment.