Skip to content

Commit d5addab

Browse files
authored
Merge branch 'main' into bugfix/3821-fix-auth-server-connection-crash
2 parents 77ff7b4 + ea9e12f commit d5addab

12 files changed

Lines changed: 350 additions & 5 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2021-2024 Ona Systems, Inc
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.smartregister.fhircore.engine.configuration
18+
19+
import android.os.Parcelable
20+
import kotlinx.parcelize.Parcelize
21+
import kotlinx.serialization.Serializable
22+
23+
@Serializable
24+
@Parcelize
25+
data class ExternalAppConfig(
26+
val id: String,
27+
val label: String,
28+
val packageName: String,
29+
val playStoreUrl: String? = null,
30+
) : Parcelable

android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/workflow/ApplicationWorkflow.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,7 @@ enum class ApplicationWorkflow {
6868

6969
/** A workflow that launches report indicators screen */
7070
LAUNCH_REPORT_INDICATORS,
71+
72+
/** A workflow that launches an external application via Intent */
73+
LAUNCH_EXTERNAL_APP,
7174
}

android/engine/src/main/java/org/smartregister/fhircore/engine/domain/model/ActionConfig.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import kotlinx.parcelize.Parcelize
2222
import kotlinx.serialization.Serializable
2323
import org.hl7.fhir.r4.model.Enumerations
2424
import org.hl7.fhir.r4.model.ResourceType
25+
import org.smartregister.fhircore.engine.configuration.ExternalAppConfig
2526
import org.smartregister.fhircore.engine.configuration.PdfConfig
2627
import org.smartregister.fhircore.engine.configuration.QuestionnaireConfig
2728
import org.smartregister.fhircore.engine.configuration.profile.ManagingEntityConfig
@@ -44,6 +45,7 @@ data class ActionConfig(
4445
val popNavigationBackStack: Boolean? = null,
4546
val multiSelectViewConfig: MultiSelectViewConfig? = null,
4647
val pdfConfig: PdfConfig? = null,
48+
val externalAppConfig: ExternalAppConfig? = null,
4749
) : Parcelable, java.io.Serializable {
4850
fun paramsBundle(computedValuesMap: Map<String, Any> = emptyMap()): Bundle =
4951
Bundle().apply {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="512" android:viewportWidth="512" android:width="24dp">
2+
3+
<path android:fillColor="#020202" android:pathData="m251.79,75.05c-20.35,3.18 -40.04,15.23 -59,22.96 -43.24,17.62 -85.84,36.78 -129,54.59 -19.05,7.86 -52.29,14.92 -57.49,38.01 -7.09,31.49 24.97,40.19 47.49,49.85 47.55,20.41 95.47,39.98 143,60.43 21.59,9.29 46.65,25.08 71,21.28 23.13,-3.61 46.58,-17.58 68,-26.71 40.28,-17.16 80.8,-33.78 121,-51.13 18.88,-8.15 51.16,-14.58 56.47,-37.72 7.2,-31.38 -25.16,-40.35 -47.47,-49.85 -47.63,-20.29 -95.39,-40.26 -143,-60.57 -21.54,-9.19 -46.74,-24.93 -71,-21.14m220,185.56c-5.06,2.7 -15.77,4.57 -18.97,9.42 -4.49,6.78 1.53,18.02 -1.63,25.37 -1.43,3.32 -5.66,4.84 -8.07,7.39 -4.39,4.66 -7.14,11.43 -7.28,17.82 -0.15,7.51 9.07,17.29 7.78,23 -0.87,3.87 -4.73,7.11 -6.08,11 -3.09,8.94 -5.89,37.91 2.45,44.27 5.22,3.98 13.66,2.73 19.79,2.73 7.45,0 18.47,1.92 24.89,-2.73 7.62,-5.51 5.53,-32.76 3.58,-41.27 -1.15,-5 -7.42,-10.32 -7.42,-15 0,-3.41 4.21,-6.95 5.6,-10 2.91,-6.38 3.23,-14.41 0.79,-21 -2.75,-7.43 -12.29,-11.1 -14.12,-18.04 -2.72,-10.34 2.85,-23.03 -1.32,-32.96m-372,23v62c0,17.08 -0.42,33.5 10.16,48 14.01,19.21 43.03,29.06 64.84,36.33 56.94,18.98 117.31,17.58 174,-1.33 19.3,-6.44 45.28,-15.91 58.53,-32 12.95,-15.73 12.47,-33.77 12.47,-53v-60c-13.97,3.32 -27.82,11.05 -41,16.72 -22.27,9.58 -44.69,18.8 -67,28.28 -16.54,7.03 -33.56,15.92 -52,15.92 -17.56,0 -33.16,-8.31 -49,-14.72 -23.81,-9.63 -47.4,-19.92 -71,-30.05 -12.88,-5.53 -26.35,-12.92 -40,-16.15z" android:strokeColor="#00000000"/>
4+
5+
</vector>

android/quest/src/main/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
<uses-feature android:name="android.hardware.camera" />
1313
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" android:foregroundServiceType="dataSync" />
1414

15+
<!-- Required for Android 11+ to query if external apps are installed -->
16+
<queries>
17+
<intent>
18+
<action android:name="android.intent.action.MAIN" />
19+
<category android:name="android.intent.category.LAUNCHER" />
20+
</intent>
21+
</queries>
22+
1523
<application
1624
android:name=".QuestApplication"
1725
android:allowBackup="false"

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/components/AppDrawer.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ fun AppDrawer(
181181
}
182182

183183
// Display list of configurable client registers
184-
items(navigationConfiguration.clientRegisters, { it.id }) { navigationMenu ->
184+
items(navigationConfiguration.clientRegisters.filter { it.visible }, { it.id }) {
185+
navigationMenu ->
185186
SideMenuItem(
186187
imageConfig = navigationMenu.menuIconConfig,
187188
title = navigationMenu.display,
@@ -217,7 +218,8 @@ fun AppDrawer(
217218
item { Divider(color = DividerColor) }
218219

219220
// Display list of configurable static menu
220-
items(navigationConfiguration.staticMenu, { it.id }) { navigationMenu ->
221+
items(navigationConfiguration.staticMenu.filter { it.visible }, { it.id }) { navigationMenu,
222+
->
221223
SideMenuItem(
222224
imageConfig = navigationMenu.menuIconConfig,
223225
title = navigationMenu.display,
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2021-2024 Ona Systems, Inc
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.smartregister.fhircore.quest.util
18+
19+
import android.content.ActivityNotFoundException
20+
import android.content.Context
21+
import android.content.Intent
22+
import android.net.Uri.parse
23+
import android.widget.Toast
24+
import org.smartregister.fhircore.engine.configuration.ExternalAppConfig
25+
import org.smartregister.fhircore.quest.R
26+
27+
fun openExternalApp(context: Context, config: ExternalAppConfig) {
28+
if (config.packageName.isBlank()) {
29+
Toast.makeText(
30+
context,
31+
context.getString(R.string.external_app_invalid_config),
32+
Toast.LENGTH_SHORT,
33+
)
34+
.show()
35+
return
36+
}
37+
38+
val launchIntent = context.packageManager.getLaunchIntentForPackage(config.packageName)
39+
if (launchIntent != null) {
40+
context.startActivity(launchIntent)
41+
} else {
42+
if (!config.playStoreUrl.isNullOrBlank()) {
43+
try {
44+
val browserIntent = Intent(Intent.ACTION_VIEW, parse(config.playStoreUrl))
45+
context.startActivity(browserIntent)
46+
} catch (e: ActivityNotFoundException) {
47+
Toast.makeText(
48+
context,
49+
context.getString(R.string.external_app_not_installed),
50+
Toast.LENGTH_SHORT,
51+
)
52+
.show()
53+
}
54+
} else {
55+
Toast.makeText(
56+
context,
57+
context.getString(R.string.external_app_not_installed),
58+
Toast.LENGTH_SHORT,
59+
)
60+
.show()
61+
}
62+
}
63+
}

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import org.smartregister.fhircore.quest.navigation.MainNavigationScreen
6262
import org.smartregister.fhircore.quest.navigation.NavigationArg
6363
import org.smartregister.fhircore.quest.ui.pdf.PdfLauncherFragment
6464
import org.smartregister.fhircore.quest.ui.shared.QuestionnaireHandler
65+
import org.smartregister.fhircore.quest.util.openExternalApp
6566
import org.smartregister.p2p.utils.startP2PScreen
6667

6768
const val PRACTITIONER_ID = "practitionerId"
@@ -227,6 +228,11 @@ fun ActionConfig.handleClickEvent(
227228
Toast.LENGTH_LONG,
228229
)
229230
}
231+
ApplicationWorkflow.LAUNCH_EXTERNAL_APP -> {
232+
actionConfig.externalAppConfig?.let { config ->
233+
openExternalApp(navController.context, config)
234+
}
235+
}
230236
ApplicationWorkflow.LAUNCH_LOCATION_SELECTOR -> {
231237
val args =
232238
bundleOf(

android/quest/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,6 @@
164164
<string name="no_encounter_data_available">No data available</string>
165165
<string name="no_data_available_for_period">No data available for this period</string>
166166
<string name="reports_suffix">Reports</string>
167+
<string name="external_app_not_installed">The app is not installed. Please contact your administrator.</string>
168+
<string name="external_app_invalid_config">Invalid app configuration. Please contact your administrator.</string>
167169
</resources>

android/quest/src/test/java/org/smartregister/fhircore/quest/ui/report/indicator/ReportIndicatorViewModelTest.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,12 @@ class ReportIndicatorViewModelTest : RobolectricTest() {
263263
val ranges = viewModel.reportPeriodRange.value
264264
val years = ranges.keys.toList()
265265

266+
val currentYear = Calendar.getInstance().get(Calendar.YEAR)
267+
266268
assertTrue(years.size >= 2)
267-
assertEquals("2025", years[0])
268-
assertEquals("2024", years[1])
269-
assertEquals("2023", years[2])
269+
assertEquals(currentYear.toString(), years[0])
270+
assertTrue(years.contains("2024"))
271+
assertTrue(years.contains("2023"))
270272
}
271273

272274
@Test

0 commit comments

Comments
 (0)