Skip to content

Migrate catalog app to Kotlin Multiplatform#2940

Open
ellykits wants to merge 27 commits intoohs-foundation:masterfrom
ellykits:catalog-kmp-migration
Open

Migrate catalog app to Kotlin Multiplatform#2940
ellykits wants to merge 27 commits intoohs-foundation:masterfrom
ellykits:catalog-kmp-migration

Conversation

@ellykits
Copy link
Copy Markdown
Contributor

@ellykits ellykits commented Feb 2, 2026

IMPORTANT: All PRs must be linked to an issue (except for extremely trivial and straightforward changes).

Fixes #2941

Description
Clear and concise code change description.

Alternative(s) considered
Have you considered any alternatives? And if so, why have you chosen the approach in this PR?

Type
Choose one: (Bug fix | Feature | Documentation | Testing | Code health | Builds | Releases | Other)

Screenshots (if applicable)

Checklist

  • I have read and acknowledged the Code of conduct.
  • I have read the Contributing page.
  • I have signed the Google Individual CLA, or I am covered by my company's Corporate CLA.
  • I have discussed my proposed solution with code owners in the linked issue(s) and we have agreed upon the general approach.
  • I have run ./gradlew spotlessApply and ./gradlew spotlessCheck to check my code follows the style guide of this project.
  • I have run ./gradlew check and ./gradlew connectedCheck to test my changes locally.
  • I have built and run the demo app(s) to verify my change fixes the issue and/or does not break the demo app(s).

Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
@ellykits ellykits requested review from LZRS and jingtang10 and removed request for LZRS and jingtang10 February 2, 2026 23:37
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
…m factories

Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
@github-project-automation github-project-automation bot moved this from New to PR under Review in Android FHIR SDK Feb 9, 2026
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
@ellykits ellykits marked this pull request as ready for review February 11, 2026 15:06
@ellykits ellykits requested a review from a team as a code owner February 11, 2026 15:06
@ellykits ellykits requested review from ktarasenko and removed request for a team February 11, 2026 15:06
@ellykits
Copy link
Copy Markdown
Contributor Author

Marked this as ready for review and created an issue to track remaining features that aren't blocking testing questionnaires via catalog application here #2942

Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
@ellykits ellykits marked this pull request as draft February 19, 2026 09:49
@ellykits
Copy link
Copy Markdown
Contributor Author

ellykits commented Feb 23, 2026

DataCapture Issues Report

Generated on: 2026-02-23


1. General


2. Components

Slider

  • Creates items above the maximum that is allowed

Label

  • Appear small compared to the previous label widget

Not working

  • Repeated Group
  • Date and Time fields
  • Attachment
  • Locations (Misc)
  • Initial value (Misc)
  • Custom styling (Misc)

Help Icon

  • Do not use filled icon, use outline
  • Has no toggle error state icon

Item Answer Media

  • Not working for both datacapture and datacapture kmp modules

3. Layout

  • Of course, date fields are not working, affecting skip logic
  • Labels are rather darkened or bold
  • Validation dialog not displayed on Default
  • Cannot submit multiple times too
  • No validation happening for paginated UI too
  • Review not pre-populated (On display and on edit)
  • Read-only not working

4. Behaviors

Calculated expression

  • Calculated expression not working (possibly because of a missing
    date time field). Info displayed on top instead of below.

Answer expression

  • Answer expression crashes the app, see log below

Log Snippet

    java.lang.IllegalStateException: XFhirQueryResolver cannot be null. Please provide the XFhirQueryResolver via DataCaptureConfig.
        at com.google.android.fhir.datacapture.expressions.EnabledAnswerOptionsEvaluator.resolveAnswerExpression(EnabledAnswerOptionsEvaluator.kt:200)
        at com.google.android.fhir.datacapture.expressions.EnabledAnswerOptionsEvaluator.answerOptions(EnabledAnswerOptionsEvaluator.kt:133)
        at com.google.android.fhir.datacapture.expressions.EnabledAnswerOptionsEvaluator.evaluate$datacapture_kmp(EnabledAnswerOptionsEvaluator.kt:92)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel.getQuestionnaireAdapterItems(QuestionnaireViewModel.kt:1022)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel.getQuestionnaireAdapterItems(QuestionnaireViewModel.kt:971)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel.getQuestionnaireAdapterItems$default(QuestionnaireViewModel.kt:964)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel.getQuestionnaireState(QuestionnaireViewModel.kt:832)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel.access$getQuestionnaireState(QuestionnaireViewModel.kt:104)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel$questionnaireStateFlow$1.invokeSuspend(QuestionnaireViewModel.kt:654)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel$questionnaireStateFlow$1.invoke(Unknown Source:9)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel$questionnaireStateFlow$1.invoke(Unknown Source:20)

Skip logic

  • Skip logic not working because of a missing date field
  • The info displayed at the top of the progress bar should be
    below, right above the bottom navigation page
  • Skip logic with expression crashes with the log below

Log Snippet

    Process: com.google.android.fhir.catalog, PID: 5853
    java.lang.IllegalStateException: Unknown variable: %has
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitExternalConstantTerm(FhirPathEvaluator.kt:360)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitExternalConstantTerm(FhirPathEvaluator.kt:62)
        at com.google.fhir.fhirpath.parsers.fhirpathParser$ExternalConstantTermContext.accept(fhirpathParser.kt:985)
        at org.antlr.v4.kotlinruntime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.kt:41)
        at com.google.fhir.fhirpath.parsers.fhirpathBaseVisitor.visitTermExpression(fhirpathBaseVisitor.kt:91)
        at com.google.fhir.fhirpath.parsers.fhirpathParser$TermExpressionContext.accept(fhirpathParser.kt:573)
        at org.antlr.v4.kotlinruntime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.kt:11)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitAdditiveExpression(FhirPathEvaluator.kt:164)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitAdditiveExpression(FhirPathEvaluator.kt:62)
        at com.google.fhir.fhirpath.parsers.fhirpathParser$AdditiveExpressionContext.accept(fhirpathParser.kt:284)
        at org.antlr.v4.kotlinruntime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.kt:11)
        at com.google.fhir.fhirpath.FhirPathEngine.evaluateExpression(FhirPathEngine.kt:82)
        at com.google.android.fhir.datacapture.fhirpath.ExpressionEvaluator.evaluateExpression(ExpressionEvaluator.kt:150)
        at com.google.android.fhir.datacapture.enablement.EnablementEvaluator.evaluate(EnablementEvaluator.kt:150)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel.getQuestionnaireAdapterItems(QuestionnaireViewModel.kt:988)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel.getQuestionnaireAdapterItems(QuestionnaireViewModel.kt:971)
        at com.google.android.fhir.datacapture.QuestionnaireViewModel.getQuestionnaireAdapterItems$default(QuestionnaireViewModel.kt:964)

Dynamic question

  • Dynamic question not working, possibly because of the missing
    date time field (should be updated when an option is selected on the
    choose option widget)

Questionnaire constraint

  • Questionnaire constraint not working, failing with the error logs
    below

Log Snippet

    FATAL EXCEPTION: main (Fix with AI)
    Process: com.google.android.fhir.catalog, PID: 5918
    java.lang.IllegalStateException: Unknown variable: %context
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitExternalConstantTerm(FhirPathEvaluator.kt:360)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitExternalConstantTerm(FhirPathEvaluator.kt:62)
        at com.google.fhir.fhirpath.parsers.fhirpathParser$ExternalConstantTermContext.accept(fhirpathParser.kt:985)
        at org.antlr.v4.kotlinruntime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.kt:41)
        at com.google.fhir.fhirpath.parsers.fhirpathBaseVisitor.visitTermExpression(fhirpathBaseVisitor.kt:91)
        at com.google.fhir.fhirpath.parsers.fhirpathParser$TermExpressionContext.accept(fhirpathParser.kt:573)
        at org.antlr.v4.kotlinruntime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.kt:11)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitInvocationExpression(FhirPathEvaluator.kt:110)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitInvocationExpression(FhirPathEvaluator.kt:62)
        at com.google.fhir.fhirpath.parsers.fhirpathParser$InvocationExpressionContext.accept(fhirpathParser.kt:487)
        at org.antlr.v4.kotlinruntime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.kt:11)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitInvocationExpression(FhirPathEvaluator.kt:110)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitInvocationExpression(FhirPathEvaluator.kt:62)
        at com.google.fhir.fhirpath.parsers.fhirpathParser$InvocationExpressionContext.accept(fhirpathParser.kt:487)
        at org.antlr.v4.kotlinruntime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.kt:11)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitEqualityExpression(FhirPathEvaluator.kt:218)
        at com.google.fhir.fhirpath.FhirPathEvaluator.visitEqualityExpression(FhirPathEvaluator.kt:62)
        at com.google.fhir.fhirpath.parsers.fhirpathParser$EqualityExpressionContext.accept(fhirpathParser.kt:516)
        at org.antlr.v4.kotlinruntime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.kt:11)
        at com.google.fhir.fhirpath.FhirPathEngine.evaluateExpression(FhirPathEngine.kt:82)
        at com.google.android.fhir.datacapture.fhirpath.ExpressionEvaluator.evaluateExpression(ExpressionEvaluator.kt:150)
        at com.google.android.fhir.datacapture.fhirpath.ExpressionEvaluator.evaluateExpression$default(ExpressionEvaluator.kt:145)
        at com.google.android.fhir.datacapture.validation.ConstraintItemExtensionValidator.validate(ConstraintItemExtensionValidator.kt:77)
        at com.google.android.fhir.datacapture.validation.QuestionnaireResponseItemValidator.validate(QuestionnaireResponseItemValidator.kt:55)

Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
ellykits and others added 11 commits February 27, 2026 20:50
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Move all the evaluate and support functions to a utility
object to be reused. Also handle exceptions thrown by the Kotlin
fhir path if evaluation fails.

Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
* Multiple fixes

- Fix slider moving maximum set value
- Update answer extension validators to correctly check evaluated cqf-calculatedValue expressions
- Include FileKit in LicenseeConfig

* Fix population of questionnaire initial value

* Replace help icon to outlined

* Fix submit button not accepting subsequent clicks

* Fix ReadOnly review screen

* Fix validation error message dialog not showing

* Update MaxValueValidatorTest and address PR comments

* Remove redundant TestExpressionEvaluator
Delete xml layout, color, style and theme files

Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
…hir into catalog-kmp-migration

Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
* Fix validation on group based questionnaires

* Use LaunchedEffect Unit to set onsubmitclicklistener

* Use layout_review for layout readonly item

* Remove reflection-api based message for sliderviewfactory
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
@ellykits
Copy link
Copy Markdown
Contributor Author

ellykits commented Mar 9, 2026

Catalog app demo in pics and video

Android Emulator demo

catalog_demo.mp4

iOS simulator

Simulator Screenshot - iPhone 16 Pro - 2026-03-09 at 22 14 22

Android

Screenshot from 2026-03-09 22-29-49

Desktop

Screenshot from 2026-03-09 22-30-54

@ellykits ellykits marked this pull request as ready for review March 9, 2026 19:49
ellykits and others added 3 commits March 10, 2026 15:01
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Signed-off-by: Elly Kitoto <junkmailstoelly@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate catalog app to Kotlin Multiplatform

2 participants