10000 Support an intent group nested one level inside a field-list by lognaturel · Pull Request #6696 · getodk/collect · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Support an intent group nested one level inside a field-list #6696

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

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

lognaturel
Copy link
Member
@lognaturel lognaturel commented Apr 15, 2025

Closes #6695

On this branch, it should now be possible to have any other number of groups and questions along with a single intent group in a field-list. An intent group has an app launch button at the top and all of the fields contained directly in it are read-only. When answers are returned from an external app, any related questions in the field-list get updated. It should still be possible to have the whole field list be an intent group in which case all questions are read-only and the launch button is at the very top.

Why is this the best possible solution? Were any other approaches considered?

I believe this is the simplest approach. I kept everything about how field-lists are rendered and about how recomputation happens within a field-list the same and looked for the intent attribute one level inside the field-list. We now save a FormEntryCaption representing the intent group on the ODKView. Ideally a lot of the logic in the view would be moved out to a ViewModel but that felt like too much expanded scope to take on without clear user benefit right now.

I have some uneasiness about how heavily everything about field list recomputation relies on mutation and knowing the right indexes of views in different lists. I considered deeper changes like hiding and mutating views instead of removing and adding them in widgetList. I think that would be pretty invasive and risky even if it might make more sense overall.

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

I think the biggest risk is a hit on performance for rendering any question view. I tried to be really careful to always first check if there's an intent group before doing any logic related to that. That would be a good thing to double check in review.

I changed how readOnlyOverride works for widgets. Now we can check whether a widget is in an intent group to decide whether to force the field to be read-only. I think that's easy to understand but there may be some risk there? Though there's so much test coverage it'd be hard to imagine what I could have missed.

Do we need any specific form for testing your changes? If so, please attach one.

person_registration.xlsx is the form used in the test. I think I tested all interesting cases on it but maybe not. It might be useful to try some with other logic in the field list.

Does this change require updates to documentation? If so, please file an issue here and include the link below.

getodk/docs#1942

Before submitting this PR, please make sure you have:

  • added or modified tests for any new or changed behavior
  • run ./gradlew connectedAndroidTest (or ./gradlew testLab) and confirmed all checks still pass
  • added a comment above any new strings describing it for translators
  • added any new strings with date formatting to DateFormatsTest
  • verified that any code or assets from external sources are properly credited in comments and/or in the about file.
  • verified that any new UI elements use theme colors. UI Components Style guidelines

@seadowg
Copy link
Member
seadowg commented May 5, 2025

I'm marking this "needs testing" early as it'd be good to see if we can find any problems, before getting to settled on the approach. I've had a skim, but should be able to take a proper look in the next few days.

@seadowg
Copy link
Member
seadowg commented May 7, 2025

@lognaturel In familiarizing myself (again) with the field list implementation to be able to understand all this, I ended up with a few questions about the logic in FormFillingActivity:

  1. Could the display logic (most of updateFieldListQuestions) be moved to ODKView so that it, and only it controls the layout of the list QuestionWidget based on the list of questions? This was kind of inspired by the direction you'd taken on handling the intent group logic inside ODKView.
  2. Could then save logic for field lists be moved to FormEntryViewModel?
  3. If both of the above are answered yes, could the whole widgetValueChanged callback loop be replaced with some unidirectional data flow/reactive display magic?

I took a couple of hours and have some pretty nice little changes that deal with 1 and 2, but I think 3 is probably another days work at least, so I'll pause. I basically ended up reducing updateFieldListQuestions to:

private void updateFieldListQuestions(FormIndex lastChangedIndex) throws RepeatsInFieldListException {
    ODKView odkView = getCurrentViewIfODKView();
    if (odkView == null) {
        return;
    }

    FormEntryPrompt[] questionsAfterSave = formEntryViewModel.saveFieldList(odkView.getAnswers());
    this.odkView.onUpdated(lastChangedIndex, questionsAfterSave);
}

Are you OK for me to merge those changes in? It felt hard not to do once I had my head around it, and I think it's a nice piece of positive progress to include with this new feature.

@lognaturel
Copy link
Member Author

Love it! Yes, please commit away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow other, user-answerable questions in a field-list with an external app call that returns multiple values
2 participants
0