opensrp / fhircore

FHIR Core / OpenSRP 2 is a Kotlin application for delivering offline-capable, mobile-first healthcare project implementations from local community to national and international scale using FHIR and WHO Smart Guidelines on Android.
https://opensrp.io
Apache License 2.0
59 stars 59 forks source link

MVP drafting feature #3541

Open joyce-x-chen opened 1 month ago

joyce-x-chen commented 1 month ago

Describe the feature request

A few clients, including SID, Columbia, and PAHO have expressed interest in being able to save a draft of a form that is in progress.

Currently, there are two possible outcomes with a form:

  1. Save and submit
  2. Discard (all entered data is lost)

The scope of an MVP feature could be:

Not in scope of the MVP

Example use cases

Acceptance criteria

Implementation plan (For Engineers)

pld commented 1 month ago

this looks like a good mvp, some questions:

  1. for "UI update to indicate forms that are in progress", since we exclude register... forms we don't have to worry about those, a form that we launch the form from the hamburger menu on a profile can be configured to only show once, like an "end ANC form", "record patient death" form or similar. Would we show a UI change for the menu items or would we exclude this drafts from forms opened from a drop down menu and only include those from a profile page, like task-related forms?
  2. If I save a draft, then open a draft, then exit the draft and choose "cancel", does this delete the draft?
joyce-x-chen commented 1 month ago
  1. for "UI update to indicate forms that are in progress", since we exclude register... forms we don't have to worry about those, a form that we launch the form from the hamburger menu on a profile can be configured to only show once, like an "end ANC form", "record patient death" form or similar. Would we show a UI change for the menu items or would we exclude this drafts from forms opened from a drop down menu and only include those from a profile page, like task-related forms?

Good question. I would prioritize a UI update for forms that are displayed in the child's profile, e.g. task-related forms. While there are some forms stored in the overflow menu that might need drafting, they are less likely. The types of forms that are typically accessed in the overflow menu are ones that:

  1. If I save a draft, then open a draft, then exit the draft and choose "cancel", does this delete the draft?

No, if you open a draft form and exit the draft, you get the same 3 options as if you're in a new form: cancel, save as draft, and discard.

pld commented 1 month ago

1) sounds good, let's update the scope for the MVP to be only for non-repeatable forms AND forms displayed in the a profile view.

2) Oh sorry, I confused cancel with discard but that's what I was thinking, which means the way to "delete a draft" is to edit a draft then exit it and choose discard.

If you do that, then you sync, is the expected behavior that a draft you discarded also disappears from other devices when they resync their drafts? That seems reasonable. There might be an edge case where User A discards a draft and it's status is set to deleted and User B, completes and submits a draft so it's status is set to completed, we will have to confirm how this is handled by the FHIR API.

joyce-x-chen commented 1 month ago

I had tried to describe non-repeatable forms here, but maybe the wording isn't so clear? I've edited the description to restrict it to those in the profile view. Feel free to edit for further clarity.

Only relevant to forms that are unique and only expected to be filled out once- i.e. exclude those such as "register client" or "register household" This includes forms that are filled out once per client

Good point on potential conflicts. That's not unique to saving of drafts (can happen due to offline work with new forms and editing of forms too), but we do need to come up with basic rules for how they are handled so it doesn't lead to app crashes or ANRs.

pld commented 1 month ago

Looks good, the wording on non-repeatable was clear, change was to add in profile view, thank you.

f-odhiambo commented 1 month ago

Initial Scoping on Implementation Plan

After initial code review here are my findings

Adding Config

  1. Add config - Already exists

    {
    "trigger": "ON_CLICK",
    "workflow": "LAUNCH_QUESTIONNAIRE",
    "questionnaire": {
      "id": "2b56ce61-6e33-4d40-8edb-7f273cb358dd",
      "title": "{{ questionnaire.title.anc.profile }}",
      "saveButtonText": "{{ submit }}",
      "setPractitionerDetails": true,
      "setOrganizationDetails": true,
      "saveDraft": true,
      "resourceIdentifier": "@{patientId}"
    }
    }
  2. If saveDraft is true, then add QuestionnaireResponse status to in-progress

PS. Everything else after this does not exist

Populate

  1. Add function to populate form once the user re-opens the form (QuestionnaireRersponse with link to Questionnaire ID & Subject ID) if the last QR link has the status in-progress

UI/UX

  1. Message
    • If saveDraft config is provided we need to update the message on the alert dialog from Submit/Discard to SaveDraft/Submit
    • Add a rule that will be used in the profile or register to update the button text for the submit alert dialog
    • We need to override the QuestionnaireView model to override the validate function so that drafts are saved when questions are not validated for required fields/data type
  2. Color
    • If Draft update the Task icon and color
    • Update generateTaskServiceStatus in the rules engine to update the icon and color of the Task.Button in the RulesFactory.kt

Assumptions

  1. You will only have 1 draft per question at a time
  2. You will not be able to save the practitioner detail until submit is pressed
  3. You can track the version history of the resource only on HAPI but not on the app
  4. Tracking of which practitioner is doing the edits is not captured in this initial implementation plan
f-odhiambo commented 3 weeks ago

Open Questions from grooming with @Rkareko

  1. UI/UX - Discard/Cancel - Do we have a single button or multiple? Do we show this dialog only on the back press when you want to exit the form?
  2. QR Status - in-progress | completed | amended | entered-in-error | stopped - which QR status do we use for the different user journey flows?
Rkareko commented 3 weeks ago
  1. UI/UX - Discard/Cancel - Do we have a single button or multiple? Do we show this dialog only on the back press when you want to exit the form?

@f-odhiambo A suggested approach for this using a HouseHold registration form as an example would be to do the following :

  1. The form would have a single button. Add House Hold for this case. Add_household_form
  2. When the Add Household button is called, the SDC would perform validation and if any errors exist the validation error dialog would be displayed. This is the normal flow. add_hh_error_dialog
  3. When the validation errors are fixed or if they don't exist and we have configured our questionnaire to have saveDraft as true then the following dialog would be displayed. save_as_draft_dialog
joyce-x-chen commented 3 weeks ago

Please note that discard and cancel have 2 different functions. Discard = discard the draft. Cancel = go back to the form to continue editing.

f-odhiambo commented 3 weeks ago

Hi @joyce-x-chen unfortunately we can not have an alert dialog with more than 3 buttons to accommodate adding a cancel I wanted to let you know that we’re currently focusing on the heavy lifting of the code for the button. Once that’s done, we’ll revisit the button press functions and make sure everything aligns with your design preferences. We’ll also keep your concerns in mind and try to avoid any changes to the SDK to minimize any potential impact on the overall implementation. Thanks for your patience! 😊

PS. Cancel also introduces a new scope that may get a life of its own. @Rkareko Check if we can be able to add a cancellable property to the alert dialog to take care of the cancel scenario

CC @HenryRae @rowo

f-odhiambo commented 3 weeks ago

@Rkareko Based on the convo we had we need to maintain the QR top and status for the workflows to populate the correct state of data post-submission

  1. Edit - Latest QR + status = completed
  2. Draft - Latest QR + status = in-progress

We need to update the docs to show a clear distinction on how draft vs edit works

HenryRae commented 3 weeks ago

@joyce-x-chen @f-odhiambo we have designs here on how we would like the feature to work. We will definitely need all 3 CTAs.

  1. Save draft - to save users input as a draft
  2. Discard changes - dismisses user's input, and closes the form without saving the draft.
  3. Cancel - dismisses the dialog so user can continue with the form Cc: @rowo
joyce-x-chen commented 3 weeks ago

Thanks so much @f-odhiambo @Rkareko @HenryRae.

@HenryRae

Discard changes - dismisses user's input, and closes the form without saving the draft.

To clarify - I was suggesting "discard" to mean discard the entire (draft) form. I do see the value of a "discard changes" option (which would return the draft to the state it was in before the person opened the in-progress form), but then we'd have to find another way to provide the user with the option to discard the entire form. Since we don't want to create a register of in-progress forms for the MVP, there's no "delete" option elsewhere at the moment. If we have to choose between "discard changes" and "discard form", and "discard changes" and "cancel", I think discard form is more valuable. Alternatively, could we add an X button to represent cancel (go back to form to resume editing - no discarding of newly input data)?

Good point though on clarifying whichever we settle on. The label needs to be more specific - i.e. "discard form" or "discard changes" rather than simply "discard."

@f-odhiambo

PS. Cancel also introduces a new scope that may get a life of its own. @Rkareko Check if we can be able to add a cancellable property to the alert dialog to take care of the cancel scenario

I thought cancel is an existing functionality in OpenSRP apps if you try to back out of a form. The current options are "Cancel" and "Discard." The new one would be "Save draft." Here is a screenshot from PATH EIR: Screenshot_20241105-171559_EIR

joyce-x-chen commented 3 weeks ago

Oh never mind @HenryRae I see you've gone above and beyond and suggested more functionalities within the task button! I wasn't even considering this for an MVP implementation. But if there is another way to delete draft, then I like the option of "discard changes" when pressing the back button for an in-progress form. Just not sure how much LOE this adds from an engineering perspective 🙂

image

f-odhiambo commented 3 weeks ago

SubTasks

CC @Rkareko

HenryRae commented 3 weeks ago

These 3 are a must have, for users that are trying to leave an open form.

  1. Save draft
  2. Discard form
  3. Cancel

The options while opening a saved draft i.e open draft, delete draft and cancel, it's fine to drop all them. This means, when someone clicks on a saved draft, we open the draft directly without showing the dialog. When they try to leave the form without submitting, we resurface the same options when saving draft i.e save draft, discard form, cancel. Cc: @joyce-x-chen @f-odhiambo @Rkareko

f-odhiambo commented 3 weeks ago
  1. The SDK supports purge
    The question is whether the purge can be propagated to the server and back down to other devices
  suspend fun purge(resource: Resource, forcePurge: Boolean) {
    try {
      fhirEngine.purge(resource.resourceType, resource.logicalId, forcePurge)
    } catch (resourceNotFoundException: ResourceNotFoundException) {
      Timber.e(
        "Purge failed -> Resource with ID ${resource.logicalId} does not exist",
        resourceNotFoundException,
      )
    }
  }
  1. This may have a negligible impact on storage over time but TBD

CC @joyce-x-chen @HenryRae

FikriMilano commented 6 days ago

I'm not sure if this is supposed to be a bug or we should not do this use case in the first place.

Re-open a completed form, do some changes, and then save as draft; is not working:

  1. Form has been submitted
  2. Open the form again
  3. Pre-fill works ok
  4. Change some answer
  5. Then for some reason tap the back button
  6. Save as draft
  7. Open the form again
  8. No prefill

See this recording (the bug starts at 0:26) https://drive.google.com/file/d/1qSL40LE1obTROEjzM2xfPoMg1DHA3ffx/view?usp=sharing

joyce-x-chen commented 6 days ago

Thanks @FikriMilano. That appears to be a bug, because you should not be able to open a completed form (that would be editing, not drafting). You should only be able to open and edit forms that have been saved as a draft.

However, I observed a missing UI change - after the draft is submitted the first time (as well as any subsequent time), the task should appear as yellow with the in-progress icon as in Henry's designs here cc: @Rkareko @f-odhiambo. Do we need a separate issue for the UI changes? image

joyce-x-chen commented 6 days ago

Next steps from the Engage project standup:

joyce-x-chen commented 4 days ago

@HenryRae would you be ok with us maintaining the + sign for the " in progress" task status (represented by yellow) instead of using the circular progress icon?

Most of the time, the circular progress icon isn't an action button and it's more straightforward to maintain the + button (SDK default). Thank you cc: @rowo