From 1515302e658811dd0ae38cb788ef74f01b6311d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vorburger=20=E2=9B=91=EF=B8=8F?= Date: Wed, 27 Sep 2023 14:21:36 +0200 Subject: [PATCH 01/15] Enable Dependency Graph generation (fixes #2194) (#2208) --- .github/actions/commonSetup/action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/commonSetup/action.yml b/.github/actions/commonSetup/action.yml index e481396b14..621d1f2081 100644 --- a/.github/actions/commonSetup/action.yml +++ b/.github/actions/commonSetup/action.yml @@ -15,6 +15,8 @@ runs: - name: "Setup Gradle" uses: gradle/gradle-build-action@v2 with: + # See https://github.com/marketplace/actions/gradle-build-action#enable-dependency-graph-generation-for-a-workflow + dependency-graph: generate-and-submit # Limit the size of the cache entry. # These directories contain instrumented/transformed dependency jars which can be reconstructed relatively quickly. gradle-home-cache-excludes: | From b860a2993f5afc14882bccd8d7147d30dd028529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vorburger=20=E2=9B=91=EF=B8=8F?= Date: Thu, 28 Sep 2023 12:25:52 +0200 Subject: [PATCH 02/15] clean: Remove double copyright header (#2212) --- buildSrc/src/main/kotlin/Dependencies.kt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 8816648053..99fbb87fc8 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -17,22 +17,6 @@ import org.gradle.api.artifacts.Configuration import org.gradle.kotlin.dsl.exclude -/* - * Copyright 2022 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - object Dependencies { object Androidx { From c4ed544e28b0424160538ee8dd35b5e2c5eec22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vorburger=20=E2=9B=91=EF=B8=8F?= Date: Fri, 29 Sep 2023 19:07:30 +0200 Subject: [PATCH 03/15] Bump com.android.tools.build:gradle from 8.1.1 to 8.1.2 (#2219) --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 495fa527bb..01550c144c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -11,7 +11,7 @@ repositories { dependencies { implementation("com.diffplug.spotless:spotless-plugin-gradle:6.21.0") - implementation("com.android.tools.build:gradle:8.1.1") + implementation("com.android.tools.build:gradle:8.1.2") implementation("app.cash.licensee:licensee-gradle-plugin:1.3.0") implementation("com.osacky.flank.gradle:fladle:0.17.4") From e9e5af380895e4b2c71b5cfc2a8846bf0ee2f565 Mon Sep 17 00:00:00 2001 From: Maimoona Kausar <4829880+maimoonak@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:16:47 +0500 Subject: [PATCH 04/15] Answer expression catalog (#1960) * Answer expression catalog * Spotless apply * Remove unneccessary files * simplify data bundle entries * Update catalog/src/main/java/com/google/android/fhir/catalog/CatalogApplication.kt Co-authored-by: santosh-pingle <86107848+santosh-pingle@users.noreply.github.com> * covid questionnaire test * remove test only mode * fix spot less issues * revert variable test change * Simplify the answer expression questionnaire --------- Co-authored-by: Benjamin Mwalimu Co-authored-by: santosh-pingle <86107848+santosh-pingle@users.noreply.github.com> Co-authored-by: Francis Odhiambo Otieno <4540684+f-odhiambo@users.noreply.github.com> Co-authored-by: Jing Tang --- catalog/build.gradle.kts | 1 + catalog/src/main/AndroidManifest.xml | 1 + .../assets/behavior_answer_expression.json | 34 +++++ .../src/main/assets/resource_data_bundle.json | 116 ++++++++++++++++++ .../fhir/catalog/BehaviorListViewModel.kt | 5 + .../fhir/catalog/CatalogApplication.kt | 60 +++++++++ .../fhir/catalog/DemoQuestionnaireFragment.kt | 12 +- .../main/res/drawable/ic_answers_behavior.xml | 23 ++++ catalog/src/main/res/values/strings.xml | 1 + 9 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 catalog/src/main/assets/behavior_answer_expression.json create mode 100644 catalog/src/main/assets/resource_data_bundle.json create mode 100644 catalog/src/main/java/com/google/android/fhir/catalog/CatalogApplication.kt create mode 100644 catalog/src/main/res/drawable/ic_answers_behavior.xml diff --git a/catalog/build.gradle.kts b/catalog/build.gradle.kts index a0b2e2b91a..e4bb7a4373 100644 --- a/catalog/build.gradle.kts +++ b/catalog/build.gradle.kts @@ -56,6 +56,7 @@ dependencies { implementation(Dependencies.Navigation.navUiKtx) implementation(project(path = ":datacapture")) + implementation(project(path = ":engine")) implementation(project(path = ":contrib:barcode")) testImplementation(Dependencies.junit) diff --git a/catalog/src/main/AndroidManifest.xml b/catalog/src/main/AndroidManifest.xml index 342b41fba5..17469a9339 100644 --- a/catalog/src/main/AndroidManifest.xml +++ b/catalog/src/main/AndroidManifest.xml @@ -24,6 +24,7 @@ /> bufferedReader.readText() } + .let { stringValue -> + FhirContext.forR4Cached().newJsonParser().parseResource(stringValue) as Bundle + } + .entry + .map { bundleEntryComponent -> bundleEntryComponent.resource } + .let { resources -> fhirEngine.create(*resources.toTypedArray()) } + } + } + + override fun getDataCaptureConfig(): DataCaptureConfig = dataCaptureConfig +} diff --git a/catalog/src/main/java/com/google/android/fhir/catalog/DemoQuestionnaireFragment.kt b/catalog/src/main/java/com/google/android/fhir/catalog/DemoQuestionnaireFragment.kt index fa7bfdecba..cbc0e6f49b 100644 --- a/catalog/src/main/java/com/google/android/fhir/catalog/DemoQuestionnaireFragment.kt +++ b/catalog/src/main/java/com/google/android/fhir/catalog/DemoQuestionnaireFragment.kt @@ -34,12 +34,14 @@ import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs +import ca.uhn.fhir.context.FhirContext import com.google.android.fhir.catalog.ModalBottomSheetFragment.Companion.BUNDLE_ERROR_KEY import com.google.android.fhir.catalog.ModalBottomSheetFragment.Companion.REQUEST_ERROR_KEY import com.google.android.fhir.datacapture.QuestionnaireFragment import com.google.android.fhir.datacapture.QuestionnaireFragment.Companion.SUBMIT_REQUEST_KEY import com.google.android.material.card.MaterialCardView import kotlinx.coroutines.launch +import org.hl7.fhir.r4.model.Patient class DemoQuestionnaireFragment : Fragment() { private val viewModel: DemoQuestionnaireViewModel by viewModels() @@ -164,7 +166,15 @@ class DemoQuestionnaireFragment : Fragment() { setReorderingAllowed(true) replace( R.id.container, - QuestionnaireFragment.builder().setQuestionnaire(questionnaireJsonString).build(), + QuestionnaireFragment.builder() + .setQuestionnaire(questionnaireJsonString) + .setQuestionnaireLaunchContexts( + FhirContext.forR4Cached() + .newJsonParser() + .encodeResourceToString(Patient().apply { id = "P1" }) + .let { listOf(it) }, + ) + .build(), QUESTIONNAIRE_FRAGMENT_TAG, ) } diff --git a/catalog/src/main/res/drawable/ic_answers_behavior.xml b/catalog/src/main/res/drawable/ic_answers_behavior.xml new file mode 100644 index 0000000000..b7d4ed1bec --- /dev/null +++ b/catalog/src/main/res/drawable/ic_answers_behavior.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/catalog/src/main/res/values/strings.xml b/catalog/src/main/res/values/strings.xml index 1429f57926..3371f69d71 100644 --- a/catalog/src/main/res/values/strings.xml +++ b/catalog/src/main/res/values/strings.xml @@ -58,6 +58,7 @@ Calculated Expression + Answer Expression Structured data capture \n Catalog Date: Mon, 2 Oct 2023 22:06:18 +0300 Subject: [PATCH 05/15] add cancel button in QuestionareFragment (#1837) * add cancel button in QuestionareFragment * sync coverage * add confirmation dialog before canceling the questionnaire * Run spotless * Remove incorrect string in styles.xml * Remove duplicate layout style attributes * Use Android system strings for ok/cancel * Remove duplicate review mode * Fix build * Fix cancel string * Remove reading visibility of buttons from theme * Set show cancel button default value to false * Fix build warnings * Remove incorrect use of custom view * Remove unnecessary cancel button handler in the catalog app * Remove duplicate code * Remove duplicate code --------- Co-authored-by: Jing Tang --- .../QuestionnaireCancelDialogFragment.kt | 49 ++ .../fhir/datacapture/QuestionnaireFragment.kt | 48 +- .../datacapture/QuestionnaireViewModel.kt | 32 +- .../res/layout/questionnaire_fragment.xml | 52 +- .../questionnaire_validation_dialog.xml | 5 +- datacapture/src/main/res/values/attrs.xml | 3 + datacapture/src/main/res/values/strings.xml | 6 + datacapture/src/main/res/values/styles.xml | 13 +- .../datacapture/QuestionnaireViewModelTest.kt | 615 ++++++++++++------ .../android/fhir/demo/AddPatientFragment.kt | 17 +- .../android/fhir/demo/EditPatientFragment.kt | 14 +- 11 files changed, 613 insertions(+), 241 deletions(-) create mode 100644 datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireCancelDialogFragment.kt diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireCancelDialogFragment.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireCancelDialogFragment.kt new file mode 100644 index 0000000000..0235d1eb5f --- /dev/null +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireCancelDialogFragment.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2022-2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.fhir.datacapture + +import android.app.Dialog +import android.os.Bundle +import androidx.core.os.bundleOf +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.setFragmentResult +import com.google.android.material.dialog.MaterialAlertDialogBuilder + +internal class QuestionnaireCancelDialogFragment : DialogFragment() { + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return MaterialAlertDialogBuilder(requireContext()) + .setMessage(R.string.questionnaire_cancel_text) + .setPositiveButton(android.R.string.ok) { dialog, _ -> + setFragmentResult(REQUEST_KEY, bundleOf(RESULT_KEY to RESULT_YES)) + dialog?.dismiss() + } + .setNegativeButton(android.R.string.cancel) { dialog, _ -> + setFragmentResult(REQUEST_KEY, bundleOf(RESULT_KEY to RESULT_NO)) + dialog?.dismiss() + } + .create() + } + + companion object { + const val TAG = "QuestionnaireCancelDialogFragment" + const val REQUEST_KEY = "request-key" + const val RESULT_KEY = "result-key" + const val RESULT_NO = "no" + const val RESULT_YES = "yes" + } +} diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireFragment.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireFragment.kt index 6af20abaee..19cfaf8609 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireFragment.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/QuestionnaireFragment.kt @@ -97,6 +97,11 @@ class QuestionnaireFragment : Fragment() { paginationPreviousButton.setOnClickListener { viewModel.goToPreviousPage() } val paginationNextButton = view.findViewById(R.id.pagination_next_button) paginationNextButton.setOnClickListener { viewModel.goToNextPage() } + view.findViewById