-
-
Notifications
You must be signed in to change notification settings - Fork 217
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
Make code for Enketo forms reusable outside cht-core #7462
Comments
Yes, good call! I have updated the milestone. |
For the record, after discussing with @garethbowen we have decided not to put the reusable code into The current approach in #7567 is to just refactor the code into Ideally it would be great to have an entirely separate NPM dependency that could be consumed by both cht-core and cht-conf-test-harness that would contain all the resources needed by the test harness (so that it would not need to depend on cht-core at all). However, given the large amount of various files that the test harness is currently using from cht-core, creating such a library is going to be more complex than we want to get into at this time. |
As discussed, not a blocker for 4.0.0. |
I think there are two different possibilities for addressing this issue:
More investigation is necessary here, but my current opinion is that the Angular Library may be the best choice for long-term maintainability (though, of course, at a higher up-front cost). It would seem to involve the least amount of "hacking" and ideally the modular Angular framework could hopefully provide a clean way for the test harness to stub in mock implementations of the required services.... |
Okay, so after a day of investigation and tinkering, I think that the Any solution to this issue is going to have to deal with the fact that all the code around the In https://github.com/medic/cht-core/tree/7462_forms_module I have started working on creating a There are a couple of options for structuring the Another option (and the one I am currently trying in Objectively, it feels like the first option is better, but the reality of our current situation might make the second proposal (leaving all the code in |
Just an additional note on next steps here: I do not think we have enough information yet to put together a proper tech design for solving this. However, I believe I have been able to demonstrate the viability of the Angular Element approach and that it has basic principles necessary to solve the problem! To proceed, I want to confirm stakeholder buy-in for an Angular Element/Web Component based approach. Will try to schedule a brief meeting with @kennsippell and @garethbowen to discuss. |
As I look at carving out code into a reusable component, one thing I have to determine is what code to include in the component and what to stub out. We need to supply all the dependencies of the To help determine which code should be stubbed and which services can actually be depended on by the cht-form component, I have put together this helpful graph:
flowchart LR
subgraph "Direct EnketoService Depenencies"
attachment
cht-script-api([cht-script-api])
contact-summary([contact-summary])
db([db])
enekto-prepopulation-data
enketo-translation
extract-lineage
feedback([feedback])
file-reader
get-report-content
language([language])
lineage-model-generator
search([search])
submit-form-by-sms([submit-form-by-sms])
training-cards([training-cards])
transitions([transitions])
translate
translate-from
user-contact
xml-forms([xml-forms])
z-score([z-score])
get-report-content --> db & file-reader
lineage-model-generator --> db
end
subgraph "Transitive Dependencies"
auth
changes
contact-types
debug
feedback
form2sms
format-date
get-data-records
location
pipes
route-snapshot
session
settings
telemetry
uhc-settings
uhc-stats
user-settings([user-settings])
validation
version
xml-forms-context-utils
end
db -.-> session & location
enekto-prepopulation-data --> language & enketo-translation & user-settings
language -.-> settings & format-date & telemetry
search -.-> db & session & get-data-records & telemetry
submit-form-by-sms -.-> form2sms & settings
user-contact --> user-settings & lineage-model-generator & db
xml-forms -.-> auth & changes & contact-types & db & file-reader & user-contact & xml-forms-context-utils & feedback
z-score -.-> changes & db
contact-summary -.-> settings & pipes & feedback & uhc-settings & uhc-stats & cht-script-api
transitions -.-> settings & validation
feedback -.-> db & session & version & debug & language & telemetry
cht-script-api -.-> settings & changes & session
training-cards -.-> xml-forms & db & session & route-snapshot & feedback
|
Technical DesignTerminology noteFor the purposes of discussing this functionality, I believe the terms "Angular Element", "web component", and "custom element" are roughly equivalent. However:
General Approach
Details
|
@garethbowen @dianabarsan @kennsippell @m5r I have been successful in implementing a rough hard-coded prototype of this Angular Element functionality in https://github.com/medic/cht-core/tree/7462_forms_module (demonstrating the feasibility of encapsulating the Enekto logic in a web component). Based on this effort, I have compiled an initial Technical Design in the comment above. I would love your thoughts/feedback on this design! (Hoping to have any major blockers called out before making it to code review!) |
Thanks for taking the time to write all this up and to solicit feedback! 🙏 |
Very impressive, thanks @jkuester My main concern with the design is the amount of stubbing required. This makes the API very complicated and increases the likelihood of accidentally breaking the compatibility with the harness and other users. If, for example, the CHT changed the API of the feedback service, then all the consumers of this Angular Element would have to update their stubs to match. The list of services required should be reduced as much as possible. This increases the up front effort, but I think will make it much easier to support in the future. There are a bunch of services that are only needed on setup (eg: Language service, script api, zscore, contact summary, search) - if the CHT called these and then passed the data in as params that would reduce a bunch of service level dependencies. The feedback service shouldn't be necessary if we just throw the errors from the component and catch and call feedback from the CHT. I think the DB service can be removed in the same way - do some work to check permissions beforehand, then just return the doc to save/update. Feel free to defer or push back if this is too much work for now, but I think it'll help improve the maintainability of this element as well as the readabilty of the CHT code. |
Your feedback is well received @garethbowen! One clarification I want to make is that, regarding the stubbed services, my thought was that the implementation of those stubbed services would be handled in the Angular Element itself. That implementation would, of course, need to depend on input from the consumer via some formal input parameters in the web component, but the overall structure of the stubbed services would be completely abstracted away from the consumers of the web component. This way, when we inevitably make changes to the services (e.g. add a new service that the That being said, maintaining the stubs in the Angular Element will be the responsibility of cht-core developers and the larger that shared surface area is, the more work it is going to be to keep everything synced up (and the harder it will be to refactor anything). So, I absolutely agree that minimizing the services we need to stub is going to have significant long-term benefits! Before going further with this Angular Element, I will start by trying to reduce the number of services we need to stub by finding any low-hanging fruit that we can easily refactor out of the |
@mrjones-plip sorry for the late response! No, we don't actually want to close this yet since this issue is mainly for the development of the actual Web Component itself. Those changes will be coming in a different PR soon! |
Gotcha - thanks! |
@tatilepizs here are the primary test cases that I think we want to make sure we get covered in the web component tests so we are properly validating the behavior of the component. (A lot of these are probably already covered in the forms you are already testing, but I have just added them all here for completeness.)
In the test code, these attribute values should be set after loading the url in the browser, but before starting to fill out the form:
|
…port (#8153) Co-authored-by: Mokhtar <[email protected]> Co-authored-by: Tatiana Lépiz <[email protected]> Co-authored-by: tatilepizs <[email protected]>
@jkuester Would you mind also adding the new npm run commands to the documentation? |
What feature do you want to improve?
Support
cht-core@^1.14
, in https://github.com/medic/cht-conf-test-harness requires updating the enketo-core version used by the test harness and the surrounding harness code that is used to bootstrap the Enketo forms. Much of the logic needed (in the test harnessform-host
) for bootstrapping enketo matches what we are already doing in cht-core currently in the webapp enketo.service.Going forwards, as we continue to update the version of enketo-core used by the CHT, it will require extra effort to ensure the logic for bootstrapping Enketo remains consistent before cht-core and cht-conf-test-harness.
Describe the improvement you'd like
Much of this ongoing maintenance work could be removed or at least simplified by moving as much of the core logic as possible from the enketo.service into a new shared-libs folder that could also be consumed by the cht-conf-test-harness.
Describe alternatives you've considered
Definitely open to other approaches that might be better for addressing this issue, but this feels like the most straightforward direction that is also inline with patterns we have followed in the past.
Additional context
A proof-of-concept refactoring can be seen in this commit where I tried to just decouple the logic from the Angular dependencies. Ideally it would probably make sense to have this refactoring be more sophisticated and make it easier to consume.
The text was updated successfully, but these errors were encountered: