(fix) O3-4320: Remove Irrelevant Properties When Changing Question Type#391
(fix) O3-4320: Remove Irrelevant Properties When Changing Question Type#391Bharath-K-Shetty wants to merge 14 commits intoopenmrs:mainfrom
Conversation
|
@NethmiRodrigo review required..! |
src/components/interactive-builder/modals/question/question.modal.tsx
Outdated
Show resolved
Hide resolved
NethmiRodrigo
left a comment
There was a problem hiding this comment.
Thanks @Bharath-K-Shetty! A couple of suggestions:
src/components/interactive-builder/modals/question/question.modal.tsx
Outdated
Show resolved
Hide resolved
src/components/interactive-builder/modals/question/question.modal.tsx
Outdated
Show resolved
Hide resolved
src/components/interactive-builder/modals/question/question.modal.tsx
Outdated
Show resolved
Hide resolved
613401b to
e4b491f
Compare
e4b491f to
a360ece
Compare
|
@NethmiRodrigo updated the pr..! |
NethmiRodrigo
left a comment
There was a problem hiding this comment.
@Bharath-K-Shetty left a few comments. Please add unit tests to cover this scenario
src/components/interactive-builder/modals/question/question.modal.tsx
Outdated
Show resolved
Hide resolved
src/components/interactive-builder/modals/question/question.modal.tsx
Outdated
Show resolved
Hide resolved
8462b2d to
94aaba8
Compare
src/components/interactive-builder/modals/question/question.modal.tsx
Outdated
Show resolved
Hide resolved
src/components/interactive-builder/modals/question/question.modal.tsx
Outdated
Show resolved
Hide resolved
...components/interactive-builder/modals/question/question-form/question/question.component.tsx
Outdated
Show resolved
Hide resolved
src/components/interactive-builder/modals/question/question-form/question/question.test.tsx
Outdated
Show resolved
Hide resolved
src/components/interactive-builder/modals/question/question-form/question/question.test.tsx
Outdated
Show resolved
Hide resolved
src/components/interactive-builder/modals/question/question-utils.ts
Outdated
Show resolved
Hide resolved
...components/interactive-builder/modals/question/question-form/question/question.component.tsx
Outdated
Show resolved
Hide resolved
e399f65 to
2df050e
Compare
NethmiRodrigo
left a comment
There was a problem hiding this comment.
@Bharath-K-Shetty looks like this isn't as simple as what I had initially thought. While this is halfway there, we have to consider the propeties specific for renderingTypes as well (as per https://openmrs.atlassian.net/wiki/spaces/docs/pages/68681754/Field+Types+Reference), which means there needs to be a bit more rework that needs to be done on this PR. You can do it and I can guide you through it, but if its a hassle, I can do it. What do you prefer?
|
Hey @NethmiRodrigo i think for cleanup of rendering Type there is a separate ticket focusing on that can you please clarify once.Ticket:https://openmrs.atlassian.net/browse/O3-4319 |
Yeah, I thought we could handle it separately, but now seeing it in action, I don't think we can do them seperately |
NethmiRodrigo
left a comment
There was a problem hiding this comment.
@Bharath-K-Shetty you'd have to reconsider the properties you added for questionType since some of them are for renderingType
| encounterLocation: [], | ||
| encounterProvider: [], | ||
| encounterRole: [], | ||
| obs: ['required'], |
There was a problem hiding this comment.
'required` is a common property
There was a problem hiding this comment.
Please see this comment again
src/constants.ts
Outdated
| Mapping of allowed keys for the nested questionOptions object per question type. | ||
| */ | ||
| export const allowedQuestionOptionsMapping: Record<string, string[]> = { | ||
| control: ['rendering', 'minLength', 'maxLength'], |
There was a problem hiding this comment.
'minLength', 'maxLength' are properties relevant to text rendering type and not specific to the control question type
src/constants.ts
Outdated
| encounterDatetime: ['rendering'], | ||
| encounterLocation: ['rendering'], | ||
| encounterProvider: ['rendering'], | ||
| encounterRole: ['rendering', 'isSearchable'], |
There was a problem hiding this comment.
Similarly, isSearchable is for ui-select-extended rendering type
|
@Bharath-K-Shetty So what I do to find the correct properties is, I go through the FormField type definition - https://github.com/openmrs/openmrs-esm-form-engine-lib/blob/d28f37f92cff6c6e97b3339113d921e880400855/src/types/schema.ts#L60 because most often than not they are pretty self explanatory. Similarly, - https://openmrs.atlassian.net/wiki/spaces/docs/pages/68681754/Field+Types+Reference for |
1d30f27 to
9269ac7
Compare
9269ac7 to
5a35b81
Compare
NethmiRodrigo
left a comment
There was a problem hiding this comment.
@Bharath-K-Shetty I've left a few comments, but the more I think about this, the more this approach seems to be unscalable, especially because I was thinking of all the possible combinations of questionType to renderingType we'd have to consider. Seems like the best way forward is to rework this to:
- When changing the question type or rendering type, we just remove all the properties except id, label and required
- Show a info tooltip next to the question type and rendering type that on hover would show a warning that changing the type would remove properties.
Over time, we'll probably evolve this into a better solution, but I think this proposed approach would be a much better and less complex task (and easier to test).
Sorry about the iterative changes, this is a ticket that I hadn't thought about in such depth until now
There was a problem hiding this comment.
Since these test cases are explicitly for testing the functions within the question-utils file and doesn't test anything within the question.component itself, it would be better to add these to a question-utils.test file. A test case that you could write for the question.component would be something like loading a formField like:
const formField: FormField = {
id: 'testQuestion',
label: 'Test Question',
type: 'obs',
questionOptions: {
rendering: 'radio',
concept: '12345',
answers: [
{ concept: '111', label: 'Yes' },
{ concept: '222', label: 'No' },
],
},
required: true,
};
and then rendering the question component, and then clicking on the Select Type and changing the type and then checking if setFormField gets called with the unnecessary properties removed
| // Assert that id remains. | ||
| expect(cleaned.id).toBe('testQuestion'); | ||
|
|
||
| // In our design, label is required for all question types, so it should remain. |
There was a problem hiding this comment.
Actually, the label property is not required for questions that have the renderingType markdown
| // In our design, label is required for all question types, so it should remain. |
| expect(cleaned.label).toBe('Test Question'); | ||
|
|
||
| // Irrelevant nested properties should be removed. | ||
| expect(cleaned.questionOptions).toHaveProperty('rendering', 'markdown'); | ||
| expect(cleaned.questionOptions).not.toHaveProperty('concept'); | ||
| expect(cleaned.questionOptions).not.toHaveProperty('answers'); |
There was a problem hiding this comment.
Instead of asserting property by property, can't we have a result object and assert that the cleaned object is equal to that, i.e:
const expectedObjectAfterClean = {
id: 'testQuestion',
type: 'control',
questionOptions: {
rendering: 'markdown',
concept: '12345',
},
required: true,
}
expect(cleaned).toEqual(expectedObjectAfterClean);
| encounterLocation: [], | ||
| encounterProvider: [], | ||
| encounterRole: [], | ||
| obs: ['required'], |
There was a problem hiding this comment.
Please see this comment again
| toggle: ['rendering', 'concept', 'toggleOptions'], | ||
| 'ui-select-extended': ['rendering', 'concept', 'isSearchable'], | ||
| 'workspace-launcher': ['rendering', 'concept'], | ||
| markdown: ['rendering', 'concept'], |
There was a problem hiding this comment.
| markdown: ['rendering', 'concept'], | |
| markdown: ['rendering'], |
| 'ui-select-extended': ['rendering', 'concept', 'isSearchable'], | ||
| 'workspace-launcher': ['rendering', 'concept'], | ||
| markdown: ['rendering', 'concept'], | ||
| 'extension-widget': ['rendering', 'concept'], |
There was a problem hiding this comment.
The following are types relevant to this:
extensionId?: string;
extensionSlotName?: string;
| 'fixed-value': ['rendering', 'concept'], | ||
| file: ['rendering', 'concept'], | ||
| group: ['rendering', 'concept'], | ||
| number: ['rendering', 'concept', 'min', 'max'], |
There was a problem hiding this comment.
Also relevant type: step?: number;
| number: ['rendering', 'concept', 'min', 'max'], | ||
| problem: ['rendering', 'concept'], | ||
| radio: ['rendering', 'concept', 'answers'], | ||
| repeating: ['rendering', 'concept'], |
There was a problem hiding this comment.
Relevant to this: repeatOptions?: RepeatOptions;
| 'encounter-provider': ['rendering', 'concept'], | ||
| 'encounter-role': ['rendering', 'concept', 'isSearchable'], | ||
| 'fixed-value': ['rendering', 'concept'], | ||
| file: ['rendering', 'concept'], |
There was a problem hiding this comment.
allowedFileTypes?: Array<string>;
| obsGroup: ['questions'], | ||
| patientIdentifier: [], | ||
| testOrder: [], | ||
| programState: [], |
There was a problem hiding this comment.
programUuid?: string;
workflowUuid?: string;
|
What's the status of this @Bharath-K-Shetty? |
Requirements
Summary
This PR implements functionality to clean up form field data when a user changes a question's type in the form builder. A mapping of allowed properties for each question type is defined, and a helper function (cleanFormFieldForType) ensures that only the properties relevant to the newly selected question type are retained. The solution also cleans the nested questionOptions object based on a separate mapping, ensuring required keys like "rendering" remain intact.
Screenshots
Screen.Recording.2025-02-10.183846.mp4
Related Issue
https://openmrs.atlassian.net/browse/O3-4320
Other