(feat) O3-3367 Add support for person attributes#423
(feat) O3-3367 Add support for person attributes#423CynthiaKamau wants to merge 3 commits intomainfrom
Conversation
|
Size Change: -265 kB (-17.25%) 👏 Total Size: 1.27 MB
ℹ️ View Unchanged
|
be9d967 to
48be05c
Compare
7b25040 to
ebf119f
Compare
ebf119f to
f95290b
Compare
|
So the immediate thing I see here is that we're embedding "format" in the form. I don't really love when we duplicate metadata like this in forms. Just load the format from the backend definition of the attribute type, so we don't face weird issues where changing an attribute type causes forms to break. |
8ac443b to
e0f7bcc
Compare
e0f7bcc to
e9aa02e
Compare
samuelmale
left a comment
There was a problem hiding this comment.
Nice work @CynthiaKamau! Any chance we can have some integrational test cases covering all supported rendering types?
| export const PersonAttributesAdapter: FormFieldValueAdapter = { | ||
| transformFieldValue: function (field: FormField, value: any, context: FormContextProps) { | ||
| clearSubmission(field); | ||
| if (field.meta?.previousValue?.value === value || isEmpty(value)) { |
There was a problem hiding this comment.
What happens if the user tries to delete an attribute in edit mode?
if (field.meta?.previousValue && isEmpty(value)) {
// should we void the attribute?
}| import { clearSubmission } from '../utils/common-utils'; | ||
| import { isEmpty } from '../validators/form-validator'; | ||
|
|
||
| export const PersonAttributesAdapter: FormFieldValueAdapter = { |
There was a problem hiding this comment.
Are you planning on adding some test coverage for this adapter?
| async fetchData(searchTerm: string, config?: Record<string, any>, uuid?: string): Promise<any[]> { | ||
| const rep = 'v=custom:(uuid,display)'; | ||
| const url = `${restBaseUrl}/location?${rep}`; | ||
| const { data } = await openmrsFetch(searchTerm ? `${url}&q=${searchTerm}` : url); | ||
|
|
||
| return data?.results; | ||
| } |
There was a problem hiding this comment.
This data source seems to just load locations (not tied down to the "attribute" model). Anything stopping you from reusing the existing location DS`?
src/components/inputs/ui-select-extended/ui-select-extended.component.tsx
Outdated
Show resolved
Hide resolved
| async fetchData(searchTerm: string, config?: Record<string, any>, uuid?: string): Promise<any[]> { | ||
| const rep = 'v=custom:(uuid,display)'; | ||
| const url = `${restBaseUrl}/location?${rep}`; | ||
| const { data } = await openmrsFetch(searchTerm ? `${url}&q=${searchTerm}` : url); | ||
|
|
||
| return data?.results; | ||
| } |
|
|
||
| fetchData(searchTerm: string, config?: Record<string, any>): Promise<any[]> { | ||
| const apiUrl = this.url.replace('conceptUuid', config.referencedValue || config.concept); | ||
| const apiUrl = this.url.replace('conceptUuid', config.concept || config.referencedValue); |
src/hooks/usePersonAttributes.tsx
Outdated
| if (patientUuid) { | ||
| openmrsFetch(`${restBaseUrl}/patient/${patientUuid}?v=custom:(attributes)`) | ||
| .then((response) => { | ||
| setPersonAttributes(response?.data?.attributes); |
There was a problem hiding this comment.
| setPersonAttributes(response?.data?.attributes); | |
| setPersonAttributes(response.data?.attributes); |
There was a problem hiding this comment.
Is there some reason we're not using SWR here?
| ...controlTemplates.map((template) => ({ | ||
| name: template.name, | ||
| component: templateToComponentMap.find((component) => component.name === template.name).baseControlComponent, | ||
| component: templateToComponentMap.find((component) => component.name === template.name)?.baseControlComponent, |
There was a problem hiding this comment.
Don't really understand why we need the ? here?
|
|
||
| transformers.push(...inbuiltFormTransformers.map((inbuiltTransformer) => inbuiltTransformer.component)); | ||
|
|
||
| const inbuiltTransformersPromises = inbuiltFormTransformers.map(async (inbuiltTransformer) => { | ||
| const transformer = inbuiltTransformer.component; | ||
| if (transformer instanceof Promise) { | ||
| return await transformer; | ||
| } | ||
| return transformer; | ||
| }); | ||
| const resolvedInbuiltTransformers = await Promise.all(inbuiltTransformersPromises); | ||
| transformers.push(...resolvedInbuiltTransformers); | ||
| transformers.forEach((transformer) => { | ||
| const inbuiltTransformer = inbuiltFormTransformers.find((t) => t.component === transformer); | ||
| registryCache.formSchemaTransformers[inbuiltTransformer.name] = transformer; | ||
| if (inbuiltTransformer) { | ||
| registryCache.formSchemaTransformers[inbuiltTransformer.name] = transformer; | ||
| } |
There was a problem hiding this comment.
Could we refactor this? The code is way more complicated than it needs to be and has way more iterations than it needs to. For example:
transformers = transformers.concat(inbuildFormTransformers.map((transformer) => transformer.component ? ({...transformer, component: Promise.resolve(transformer.component)}) : null).filter(Boolean).map(async (transformer) => {
const theTransformer = await transformer.component;
registryCache.formSchemaTransformers[transformer.name] = theTransformer;
return theTransformer;
}));e967865 to
cb6a495
Compare
a920aa0 to
6776aac
Compare
Requirements
Summary
Add support for person attributes
Schema :
Screenshots
Screen.Recording.2024-11-21.at.13.54.06.mov
Related Issue
Other