Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete saved draft feature #3631

Merged
merged 26 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
83dcf5b
Add delete draft workflow
Rkareko Nov 22, 2024
4af60c2
Merge branch 'main' into 3605-feature-delete-draft-form
Rkareko Nov 22, 2024
3085211
Add view model
Rkareko Nov 22, 2024
8f0ab2f
Add logic for soft deleteing drafts
Rkareko Nov 25, 2024
319f62d
Run the search for QuestinnaireResponse in view model scope
Rkareko Nov 25, 2024
efd9e3f
Merge branch 'main' into 3605-feature-delete-draft-form
Rkareko Nov 25, 2024
d734a22
Move searchQuestionnaireResponse function to default repository
Rkareko Nov 26, 2024
d84263d
Use interpolated questionnaire config when launching delete draft fra…
Rkareko Nov 26, 2024
4c5ec7f
Ensure delete draft db calls complete before dialog is dismissed
Rkareko Nov 27, 2024
8014c23
Merge branch 'main' into 3605-feature-delete-draft-form
Rkareko Nov 27, 2024
01417be
Add flag to indicate a drft has been deleted
Rkareko Nov 27, 2024
ca9c159
Use aduti event to keep track of deleted drafts
Rkareko Nov 28, 2024
3271332
Rename delete draft questionnaire workflow
Rkareko Nov 28, 2024
c050cc9
Rename draft dialog fragment and view model
Rkareko Nov 28, 2024
aa33023
Add data class to hold alert dialog button properties
Rkareko Nov 29, 2024
3952876
Fix failing tests
Rkareko Nov 29, 2024
d81f079
Update CHANGELOG.md
Rkareko Nov 29, 2024
2c1ed85
Merge branch 'main' into 3605-feature-delete-draft-form
ndegwamartin Dec 2, 2024
14121ce
Verify filtering by encounter works when when searching for latest QR
Rkareko Dec 2, 2024
5507708
Run spotless Apply
Rkareko Dec 2, 2024
a7e3a83
Update test name
Rkareko Dec 3, 2024
661194b
Add documentation for delete draft functionality
Rkareko Dec 3, 2024
067f0ed
Add qustionnaire draft dialog view tests
Rkareko Dec 3, 2024
1aa6565
Merge branch 'main' into 3605-feature-delete-draft-form
Rkareko Dec 4, 2024
bdeafa9
Run questionnaire soft deletion and audit event creation in a transac…
Rkareko Dec 4, 2024
eb0de4c
Update docs
Rkareko Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1. Added a new class (PdfGenerator) for generating PDF documents from HTML content using Android's WebView and PrintManager
2. Introduced a new class (HtmlPopulator) to populate HTML templates with data from a Questionnaire Response
3. Implemented functionality to launch PDF generation using a configuration setup
- Added Save draft MVP functionality
- Added Save draft MVP functionality
- Added Delete saved draft feature

## [1.1.0] - 2024-02-15

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,7 @@

/** A workflow to launch pdf generation */
LAUNCH_PDF_GENERATION,

/** A workflow to launch delete draft questionnaires */
DELETE_DRAFT_QUESTIONNAIRE,

Check warning on line 67 in android/engine/src/main/java/org/smartregister/fhircore/engine/configuration/workflow/ApplicationWorkflow.kt

View check run for this annotation

Codecov / codecov/patch

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

Added line #L67 was not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ import org.hl7.fhir.r4.model.Group
import org.hl7.fhir.r4.model.IdType
import org.hl7.fhir.r4.model.Location
import org.hl7.fhir.r4.model.Patient
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.Reference
import org.hl7.fhir.r4.model.RelatedPerson
import org.hl7.fhir.r4.model.Resource
Expand Down Expand Up @@ -1292,6 +1294,48 @@ constructor(
)
.mapTo(ArrayDeque()) { it.resource }

/**
* This function searches and returns the latest [QuestionnaireResponse] for the given
* [resourceId] that was extracted from the [Questionnaire] identified as [questionnaireId].
* Returns null if non is found.
*/
suspend fun searchQuestionnaireResponse(
resourceId: String,
resourceType: ResourceType,
questionnaireId: String,
encounterId: String?,
questionnaireResponseStatus: String? = null,
): QuestionnaireResponse? {
val search =
Search(ResourceType.QuestionnaireResponse).apply {
filter(
QuestionnaireResponse.SUBJECT,
{ value = resourceId.asReference(resourceType).reference },
)
filter(
QuestionnaireResponse.QUESTIONNAIRE,
{ value = questionnaireId.asReference(ResourceType.Questionnaire).reference },
)
if (!encounterId.isNullOrBlank()) {
filter(
QuestionnaireResponse.ENCOUNTER,
{
value =
encounterId.extractLogicalIdUuid().asReference(ResourceType.Encounter).reference
},
)
}
if (!questionnaireResponseStatus.isNullOrBlank()) {
filter(
QuestionnaireResponse.STATUS,
{ value = of(questionnaireResponseStatus) },
)
}
}
val questionnaireResponses: List<QuestionnaireResponse> = search(search)
return questionnaireResponses.maxByOrNull { it.meta.lastUpdated }
}

/**
* A wrapper data class to hold search results. All related resources are flattened into one Map
* including the nested related resources as required by the Rules Engine facts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@

data class AlertDialogListItem(val key: String, val value: String)

data class AlertDialogButton(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice refactor!

val listener: ((d: DialogInterface) -> Unit)? = null,
@StringRes val text: Int? = null,
val color: Int? = null,
)

object AlertDialogue {
private val ITEMS_LIST_KEY = "alert_dialog_items_list"

Expand All @@ -51,12 +57,9 @@
alertIntent: AlertIntent,
message: CharSequence,
title: String? = null,
confirmButtonListener: ((d: DialogInterface) -> Unit)? = null,
@StringRes confirmButtonText: Int = R.string.questionnaire_alert_confirm_button_title,
neutralButtonListener: ((d: DialogInterface) -> Unit)? = null,
@StringRes neutralButtonText: Int = R.string.questionnaire_alert_neutral_button_title,
negativeButtonListener: ((d: DialogInterface) -> Unit)? = null,
@StringRes negativeButtonText: Int = R.string.questionnaire_alert_negative_button_title,
confirmButton: AlertDialogButton? = null,
neutralButton: AlertDialogButton? = null,
negativeButton: AlertDialogButton? = null,
cancellable: Boolean = false,
options: Array<AlertDialogListItem>? = null,
): AlertDialog {
Expand All @@ -67,22 +70,48 @@
setView(view)
title?.let { setTitle(it) }
setCancelable(cancellable)
neutralButtonListener?.let {
setNeutralButton(neutralButtonText) { d, _ -> neutralButtonListener.invoke(d) }
neutralButton?.listener?.let {
setNeutralButton(
neutralButton.text ?: R.string.questionnaire_alert_neutral_button_title,
) { d, _ ->
neutralButton.listener.invoke(d)

Check warning on line 77 in android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt#L77

Added line #L77 was not covered by tests
}
}
confirmButtonListener?.let {
setPositiveButton(confirmButtonText) { d, _ -> confirmButtonListener.invoke(d) }
confirmButton?.listener?.let {
setPositiveButton(
confirmButton.text ?: R.string.questionnaire_alert_confirm_button_title,
) { d, _ ->
confirmButton.listener.invoke(d)

Check warning on line 84 in android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt#L84

Added line #L84 was not covered by tests
}
}
negativeButtonListener?.let {
setNegativeButton(negativeButtonText) { d, _ -> negativeButtonListener.invoke(d) }
negativeButton?.listener?.let {
setNegativeButton(
negativeButton.text ?: R.string.questionnaire_alert_negative_button_title,
) { d, _ ->
negativeButton.listener.invoke(d)

Check warning on line 91 in android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt#L91

Added line #L91 was not covered by tests
}
}
options?.run { setSingleChoiceItems(options.map { it.value }.toTypedArray(), -1, null) }
}
.show()

val neutralButtonColor = neutralButton?.color ?: R.color.grey_text_color
dialog
.getButton(AlertDialog.BUTTON_NEUTRAL)
.setTextColor(ContextCompat.getColor(context, R.color.grey_text_color))
.setTextColor(ContextCompat.getColor(context, neutralButtonColor))

if (confirmButton?.color != null) {
dialog
.getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(context, confirmButton.color))

Check warning on line 106 in android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt#L104-L106

Added lines #L104 - L106 were not covered by tests
}

if (negativeButton?.color != null) {
dialog
.getButton(AlertDialog.BUTTON_NEGATIVE)
.setTextColor(ContextCompat.getColor(context, negativeButton.color))

Check warning on line 112 in android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt#L110-L112

Added lines #L110 - L112 were not covered by tests
}

dialog.findViewById<View>(R.id.pr_circular)?.apply {
if (alertIntent == AlertIntent.PROGRESS) {
this.show()
Expand Down Expand Up @@ -115,8 +144,11 @@
alertIntent = AlertIntent.INFO,
message = message,
title = title,
confirmButtonListener = confirmButtonListener,
confirmButtonText = confirmButtonText,
confirmButton =
AlertDialogButton(
listener = confirmButtonListener,
text = confirmButtonText,
),
)
}

Expand All @@ -126,8 +158,11 @@
alertIntent = AlertIntent.ERROR,
message = message,
title = title,
confirmButtonListener = { d -> d.dismiss() },
confirmButtonText = R.string.questionnaire_alert_ack_button_title,
confirmButton =
AlertDialogButton(
listener = { d -> d.dismiss() },

Check warning on line 163 in android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt#L163

Added line #L163 was not covered by tests
text = R.string.questionnaire_alert_ack_button_title,
),
)
}

Expand Down Expand Up @@ -160,25 +195,28 @@
alertIntent = AlertIntent.CONFIRM,
message = context.getString(message),
title = title?.let { context.getString(it) },
confirmButtonListener = confirmButtonListener,
confirmButtonText = confirmButtonText,
neutralButtonListener = { d -> d.dismiss() },
neutralButtonText = R.string.questionnaire_alert_neutral_button_title,
confirmButton =
AlertDialogButton(
listener = confirmButtonListener,
text = confirmButtonText,
),
neutralButton =
AlertDialogButton(
listener = { d -> d.dismiss() },

Check warning on line 205 in android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt#L205

Added line #L205 was not covered by tests
text = R.string.questionnaire_alert_neutral_button_title,
),
cancellable = false,
options = options?.toTypedArray(),
)
}

fun showCancelAlert(
fun showThreeButtonAlert(
context: Context,
@StringRes message: Int,
@StringRes title: Int? = null,
confirmButtonListener: ((d: DialogInterface) -> Unit),
@StringRes confirmButtonText: Int,
neutralButtonListener: ((d: DialogInterface) -> Unit),
@StringRes neutralButtonText: Int,
negativeButtonListener: ((d: DialogInterface) -> Unit),
@StringRes negativeButtonText: Int,
confirmButton: AlertDialogButton? = null,
neutralButton: AlertDialogButton? = null,
negativeButton: AlertDialogButton? = null,

Check warning on line 219 in android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/ui/base/AlertDialogue.kt#L217-L219

Added lines #L217 - L219 were not covered by tests
cancellable: Boolean = true,
options: List<AlertDialogListItem>? = null,
): AlertDialog {
Expand All @@ -187,12 +225,9 @@
alertIntent = AlertIntent.CONFIRM,
message = context.getString(message),
title = title?.let { context.getString(it) },
confirmButtonListener = confirmButtonListener,
confirmButtonText = confirmButtonText,
neutralButtonListener = neutralButtonListener,
neutralButtonText = neutralButtonText,
negativeButtonListener = negativeButtonListener,
negativeButtonText = negativeButtonText,
confirmButton = confirmButton,
neutralButton = neutralButton,
negativeButton = negativeButton,
cancellable = cancellable,
options = options?.toTypedArray(),
)
Expand Down
4 changes: 4 additions & 0 deletions android/engine/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
<string name="questionnaire_alert_invalid_message">Given details have validation errors. Resolve errors and submit again</string>
<string name="questionnaire_alert_invalid_title">Validation Failed</string>
<string name="questionnaire_alert_ack_button_title">OK</string>
<string name="questionnaire_alert_open_draft_button_title">Open draft</string>
<string name="questionnaire_alert_delete_draft_button_title">Delete draft</string>
<string name="username">Username</string>
<string name="password">Password</string>
<string name="forgot_password">Forgot Password</string>
Expand Down Expand Up @@ -202,4 +204,6 @@
<string name="apply_filter">APPLY FILTER</string>
<string name="questionnaire_save_draft_title">Save draft changes</string>
<string name="questionnaire_save_draft_message">Do you want to save draft changes?</string>
<string name="open_draft_changes_title">Open draft changes</string>
<string name="open_draft_changes_message">You can reopen a saved draft form to continue or delete it</string>
</resources>
Loading
Loading