@@ -54,15 +54,15 @@ import androidx.compose.ui.unit.dp
5454import androidx.compose.ui.window.Dialog
5555import androidx.compose.ui.window.DialogProperties
5656import com.google.android.fhir.datacapture.R
57+ import com.google.android.fhir.datacapture.extensions.displayString
5758import com.google.android.fhir.datacapture.extensions.itemAnswerOptionImage
5859import com.google.android.fhir.datacapture.extensions.optionExclusive
5960import com.google.android.fhir.datacapture.extensions.toAnnotatedString
60- import com.google.android.fhir.datacapture.views.factories.OptionSelectOption
61- import com.google.android.fhir.datacapture.views.factories.SelectedOptions
6261import java.util.concurrent.atomic.AtomicInteger
62+ import org.hl7.fhir.r4.model.Questionnaire
6363
6464@Composable
65- fun DialogSelect (
65+ fun OptionDialogSelect (
6666 context : Context ,
6767 title : AnnotatedString ,
6868 multiSelect : Boolean ,
@@ -88,10 +88,6 @@ fun DialogSelect(
8888 val showAddAnother =
8989 remember(otherOptionRowSelected, multiSelect) { otherOptionRowSelected && multiSelect }
9090 val listState = rememberLazyListState()
91- remember(multiSelect, otherOptionsAllowed, selectedOptions) {
92- val rows = selectedOptions.toOptionRows(multiSelect, otherOptionsAllowed).toTypedArray()
93- mutableStateListOf(* rows)
94- }
9591
9692 LaunchedEffect (otherOptionRowSelected, otherOptionEditTexts.size) {
9793 if (otherOptionRowSelected) {
@@ -343,6 +339,23 @@ internal fun OptionChoice(
343339 }
344340}
345341
342+ data class SelectedOptions (
343+ val options : List <OptionSelectOption >,
344+ val otherOptions : List <String >,
345+ ) {
346+ val selectedSummary: String =
347+ (options.filter { it.selected }.map { it.displayString } + otherOptions).joinToString()
348+ }
349+
350+ /* * Represents selectable options in the multi-select page. */
351+ data class OptionSelectOption (
352+ val item : Questionnaire .QuestionnaireItemAnswerOptionComponent ,
353+ val selected : Boolean ,
354+ val context : Context ,
355+ ) {
356+ val displayString: String = item.value.displayString(context)
357+ }
358+
346359/* * Sealed class representing different types of rows in the option select dialog. */
347360internal sealed class OptionSelectRow {
348361 /* * A predefined option. */
@@ -378,65 +391,5 @@ internal sealed class OptionSelectRow {
378391 }
379392}
380393
381- /* * Converts the initial SelectedOptions state into rows to display * */
382- internal fun SelectedOptions.toOptionRows (
383- multiSelect : Boolean ,
384- otherOptionsAllowed : Boolean ,
385- ): List <OptionSelectRow > = buildList {
386- addAll(options.map { OptionSelectRow .Option (it) })
387- if (! otherOptionsAllowed) return @buildList
388-
389- // Show "Other" option and select if other options list is not empty
390- add(OptionSelectRow .OtherRow (selected = otherOptions.isNotEmpty()))
391-
392- if (otherOptions.isNotEmpty()) {
393- check(multiSelect || otherOptions.size == 1 ) {
394- " Multiple 'Other' options selected in single-select mode: $otherOptions "
395- }
396- addAll(otherOptions.map { OptionSelectRow .OtherEditText .fromText(it) })
397- }
398-
399- sanitizeOtherOptionRows(multiSelectEnabled = multiSelect)
400- }
401-
402- internal fun List<OptionSelectRow>.sanitizeOtherOptionRows (
403- multiSelectEnabled : Boolean ,
404- ): List <OptionSelectRow > {
405- // Now that we've set the selected states properly, we need to make sure that the "Other" rows
406- // are showing in their correct state
407- val isOtherRowSelected = this .any { it is OptionSelectRow .OtherRow && it.selected }
408- return when {
409- isOtherRowSelected && multiSelectEnabled && this .last() !is OptionSelectRow .OtherAddAnother -> {
410- // In multi-select with Other enabled, we need the last row to be an AddAnother button
411- this + OptionSelectRow .OtherAddAnother
412- }
413- isOtherRowSelected &&
414- ! multiSelectEnabled &&
415- this .last() !is OptionSelectRow .OtherAddAnother -> {
416- // In single-select with Other enabled, the last row should just be an OtherEditText
417- this + OptionSelectRow .OtherEditText .fromText(" " )
418- }
419- ! isOtherRowSelected -> {
420- // We should not show the "Other" edit-texts or Add Another buttons, so return a sub-list with
421- // those items dropped
422- this .dropLastWhile {
423- it is OptionSelectRow .OtherEditText || it is OptionSelectRow .OtherAddAnother
424- }
425- }
426- else -> this
427- }
428- }
429-
430- /* * Converts rows back to SelectedOptions for saving. */
431- internal fun List<OptionSelectRow>.toSelectedOptions (): SelectedOptions {
432- return SelectedOptions (
433- options = filterIsInstance<OptionSelectRow .Option >().map { it.option },
434- otherOptions =
435- filterIsInstance<OptionSelectRow .OtherEditText >()
436- .filter { it.currentText.isNotBlank() }
437- .map { it.currentText },
438- )
439- }
440-
441394internal const val OPTION_CHOICE_TAG = " dialog_select_option_choice"
442395internal const val OTHER_OPTION_TEXT_FIELD_TAG = " other_option_edit_text_field"
0 commit comments