From 8622f39ed327e9e7597f04e11cd88c0f69fa5bab Mon Sep 17 00:00:00 2001
From: Arjun G <91885483+Arjun-Go@users.noreply.github.com>
Date: Wed, 17 Jan 2024 18:33:12 +0530
Subject: [PATCH] A-1206201728816127 | Other Attributes handled through
Configuration (#156)
* update. Other information to handle configurable fields
* handle visibilty of other attributes
---
src/api/personApi.js | 13 +
src/components/common/constants.js | 13 +-
src/containers/CreatePerson.css | 6 +
src/containers/CreatePerson.js | 331 +++++++---------------
src/containers/EditPerson.js | 423 ++++++++---------------------
5 files changed, 240 insertions(+), 546 deletions(-)
diff --git a/src/api/personApi.js b/src/api/personApi.js
index 5d95b38..082ab8c 100644
--- a/src/api/personApi.js
+++ b/src/api/personApi.js
@@ -81,3 +81,16 @@ export async function updatePerson(uuid, payload) {
return error.response;
}
}
+
+export async function fetchPersonAttributeConfig() {
+ try {
+ const url = Constants.registrationConfig;
+ return await fetch(url, {
+ method: 'GET',
+ credentials: 'include'
+ });
+ } catch (error) {
+ console.error(error);
+ return error.response;
+ }
+}
diff --git a/src/components/common/constants.js b/src/components/common/constants.js
index ca88590..65e1bf4 100644
--- a/src/components/common/constants.js
+++ b/src/components/common/constants.js
@@ -2,19 +2,12 @@ const hostUrl = localStorage.getItem('host')
? 'https://' + localStorage.getItem('host')
: '';
const RESTWS_V1 = hostUrl + '/openmrs/ws/rest/v1';
+const bahmniConfig = hostUrl + '/bahmni_config';
export const Constants = {
person: RESTWS_V1 + '/person',
- personAttributeType: RESTWS_V1 + '/personattributetype'
+ personAttributeType: RESTWS_V1 + '/personattributetype',
+ registrationConfig: bahmniConfig + '/openmrs/apps/registration/app.json'
};
export const genderOptions = ['', 'Male', 'Female', 'Other'];
-export const personAttributes = {
- organization: 'organization',
- email: 'email',
- mobilePhone: 'mobilePhone',
- workPhone: 'workPhone',
- residencePhone: 'residencePhone',
- otherPhone: 'otherPhone',
- occupation: 'occupationNew'
-};
export const phoneNumberPattern = '[0-9]{10}';
export const emailPattern = '[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,4}$';
diff --git a/src/containers/CreatePerson.css b/src/containers/CreatePerson.css
index 532951b..0f3dd94 100644
--- a/src/containers/CreatePerson.css
+++ b/src/containers/CreatePerson.css
@@ -3,10 +3,16 @@
width: 80%;
}
+.other-attributes {
+ display: flex;
+ flex-wrap: wrap;
+}
+
/* outer flex container with Name, Age, Gender sections */
.flex-container-row {
display: flex;
flex-wrap: wrap;
+ flex: 0 0 50%;
width: 100%;
padding-top: 10px;
}
diff --git a/src/containers/CreatePerson.js b/src/containers/CreatePerson.js
index 6f3e735..11ae611 100644
--- a/src/containers/CreatePerson.js
+++ b/src/containers/CreatePerson.js
@@ -1,17 +1,16 @@
import moment from 'moment';
import React, { Component } from 'react';
-import { getPersonAttributeTypeUuid, savePerson } from '../api/personApi';
+import {
+ getPersonAttributeTypeUuid,
+ savePerson,
+ fetchPersonAttributeConfig
+} from '../api/personApi';
import Button from '../components/common/Button';
import Checkbox from '../components/common/Checkbox';
import Dropdown from '../components/common/Dropdown';
import Input from '../components/common/Input';
import Navbar from '../components/common/Navbar';
-import {
- emailPattern,
- genderOptions,
- personAttributes,
- phoneNumberPattern
-} from '../components/common/constants';
+import { genderOptions } from '../components/common/constants';
import ModalError from '../components/common/modals/ModalError';
import ModalSuccess from '../components/common/modals/ModalSuccess';
import './CreatePerson.css';
@@ -31,61 +30,51 @@ class CreatePerson extends Component {
months: 0,
days: 0
},
- birthdateEstimated: false,
- organization: '',
- email: '',
- mobilePhone: '',
- workPhone: '',
- residencePhone: '',
- otherPhone: '',
- occupation: ''
+ birthdateEstimated: false
},
showModal: false,
isAPIError: false,
isRequestError: false,
isRequestLoading: false,
lastCreatedPerson: '',
- attributes: {
- organizationUuid: '',
- emailUuid: '',
- mobilePhoneUuid: '',
- workPhoneUuid: '',
- residencePhoneUuid: '',
- otherPhoneUuid: '',
- occupationUuid: ''
- }
+ attributes: []
};
this.handleClearForm = this.handleClearForm.bind(this);
}
componentDidMount() {
- this.setPersonAttributeIDs();
- }
+ this.getAttributes().then(response => {
+ const attributes = response.config.personAttributesForRelations.map(
+ async attribute => {
+ const uuid = await getPersonAttributeTypeUuid(
+ attribute.attributeName
+ );
+ return {
+ ...attribute,
+ value: '',
+ uuid: uuid
+ };
+ }
+ );
- setPersonAttributeIDs = async () => {
- this.setState({
- attributes: {
- organizationUuid: await getPersonAttributeTypeUuid(
- personAttributes.organization
- ),
- emailUuid: await getPersonAttributeTypeUuid(personAttributes.email),
- mobilePhoneUuid: await getPersonAttributeTypeUuid(
- personAttributes.mobilePhone
- ),
- workPhoneUuid: await getPersonAttributeTypeUuid(
- personAttributes.workPhone
- ),
- residencePhoneUuid: await getPersonAttributeTypeUuid(
- personAttributes.residencePhone
- ),
- otherPhoneUuid: await getPersonAttributeTypeUuid(
- personAttributes.otherPhone
- ),
- occupationUuid: await getPersonAttributeTypeUuid(
- personAttributes.occupation
- )
- }
+ Promise.all(attributes).then(resolvedAttributes => {
+ this.setState({
+ attributes: resolvedAttributes
+ });
+ });
});
+ }
+
+ getAttributes = async () => {
+ const response = await fetchPersonAttributeConfig();
+ if (response.status === 200) {
+ return response.json();
+ } else {
+ return Promise.reject({
+ status: response.status,
+ statusText: response.statusText
+ });
+ }
};
handleChange = ({ target: input }) => {
@@ -115,6 +104,15 @@ class CreatePerson extends Component {
this.setState({ person });
};
+ handleOtherAttributesChange = ({ target: input }) => {
+ const attributes = [...this.state.attributes];
+ const index = attributes.findIndex(
+ attribute => attribute.name === input.name
+ );
+ attributes[index].value = input.value;
+ this.setState({ attributes });
+ };
+
handleCheckbox = ({ target: input }) => {
const person = { ...this.state.person };
person[input.name] = input.checked;
@@ -133,13 +131,6 @@ class CreatePerson extends Component {
firstName: '',
middleName: '',
lastName: '',
- organization: '',
- email: '',
- mobilePhone: '',
- workPhone: '',
- residencePhone: '',
- otherPhone: '',
- occupation: '',
gender: '',
birthdate: moment(),
age: {
@@ -151,6 +142,10 @@ class CreatePerson extends Component {
},
isRequestError: false
});
+ this.state.attributes.map(attribute => {
+ attribute.value = '';
+ return attribute;
+ });
}
isVoided = value => {
@@ -176,17 +171,20 @@ class CreatePerson extends Component {
middleName,
lastName,
gender,
- organization,
- email,
- mobilePhone,
- workPhone,
- residencePhone,
- otherPhone,
- occupation,
birthdate,
birthdateEstimated
} = this.state.person;
+ const attributes = this.state.attributes.map(attribute => {
+ return {
+ attributeType: {
+ uuid: attribute.uuid
+ },
+ voided: this.isVoided(attribute.value),
+ value: attribute.value
+ };
+ });
+
const formPayload = {
names: [
{
@@ -199,57 +197,7 @@ class CreatePerson extends Component {
birthdate: birthdate + 'T12:00:00.000+0000',
age: moment.duration(moment().diff(birthdate)).years(),
birthdateEstimated,
- attributes: [
- {
- attributeType: {
- uuid: this.state.attributes.organizationUuid
- },
- voided: this.isVoided(organization),
- value: organization
- },
- {
- attributeType: {
- uuid: this.state.attributes.emailUuid
- },
- voided: this.isVoided(email),
- value: email
- },
- {
- attributeType: {
- uuid: this.state.attributes.mobilePhoneUuid
- },
- voided: this.isVoided(mobilePhone),
- value: mobilePhone
- },
- {
- attributeType: {
- uuid: this.state.attributes.workPhoneUuid
- },
- voided: this.isVoided(workPhone),
- value: workPhone
- },
- {
- attributeType: {
- uuid: this.state.attributes.residencePhoneUuid
- },
- voided: this.isVoided(residencePhone),
- value: residencePhone
- },
- {
- attributeType: {
- uuid: this.state.attributes.otherPhoneUuid
- },
- voided: this.isVoided(otherPhone),
- value: otherPhone
- },
- {
- attributeType: {
- uuid: this.state.attributes.occupationUuid
- },
- voided: this.isVoided(occupation),
- value: occupation
- }
- ]
+ attributes: attributes
};
return formPayload;
};
@@ -323,16 +271,10 @@ class CreatePerson extends Component {
middleName,
lastName,
gender,
- organization,
- email,
- mobilePhone,
- workPhone,
- residencePhone,
- otherPhone,
- occupation,
birthdate,
birthdateEstimated
} = this.state.person;
+ const personAttributes = this.state.attributes;
const { years, months, days } = this.state.person.age;
@@ -500,123 +442,54 @@ class CreatePerson extends Component {
-
-
-
diff --git a/src/containers/EditPerson.js b/src/containers/EditPerson.js
index 4e81ebd..6af44cd 100644
--- a/src/containers/EditPerson.js
+++ b/src/containers/EditPerson.js
@@ -3,19 +3,15 @@ import React, { Component } from 'react';
import {
fetchPerson,
getPersonAttributeTypeUuid,
- updatePerson
+ updatePerson,
+ fetchPersonAttributeConfig
} from '../api/personApi';
import Button from '../components/common/Button';
import Checkbox from '../components/common/Checkbox';
import Dropdown from '../components/common/Dropdown';
import Input from '../components/common/Input';
import Navbar from '../components/common/Navbar';
-import {
- emailPattern,
- genderOptions,
- personAttributes,
- phoneNumberPattern
-} from '../components/common/constants';
+import { genderOptions } from '../components/common/constants';
import ModalError from '../components/common/modals/ModalError';
import ModalSuccess from '../components/common/modals/ModalSuccess';
import './EditPerson.css';
@@ -31,62 +27,56 @@ class EditPerson extends Component {
lastName: '',
gender: '',
birthdate: moment(),
- birthdateEstimated: false,
- organization: '',
- email: '',
- mobilePhone: '',
- workPhone: '',
- residencePhone: '',
- otherPhone: '',
- occupation: ''
+ birthdateEstimated: false
},
showModal: false,
isAPIError: false,
isRequestError: false,
isRequestLoading: false,
lastUpdatedPerson: '',
- attributes: {
- organizationUuid: '',
- emailUuid: '',
- mobilePhoneUuid: '',
- workPhoneUuid: '',
- residencePhoneUuid: '',
- otherPhoneUuid: '',
- occupationUuid: ''
- }
+ attributes: [],
+ attributesData: []
};
this.handleClearForm = this.handleClearForm.bind(this);
}
componentDidMount() {
- this.setPersonAttributeIDs();
- this.loadPersonData();
- }
+ this.getAttributes().then(response => {
+ const attributes = response.config.personAttributesForRelations.map(
+ async attribute => {
+ const uuid = await getPersonAttributeTypeUuid(
+ attribute.attributeName
+ );
+ return {
+ ...attribute,
+ value: '',
+ uuid: uuid
+ };
+ }
+ );
- setPersonAttributeIDs = async () => {
- this.setState({
- attributes: {
- organizationUuid: await getPersonAttributeTypeUuid(
- personAttributes.organization
- ),
- emailUuid: await getPersonAttributeTypeUuid(personAttributes.email),
- mobilePhoneUuid: await getPersonAttributeTypeUuid(
- personAttributes.mobilePhone
- ),
- workPhoneUuid: await getPersonAttributeTypeUuid(
- personAttributes.workPhone
- ),
- residencePhoneUuid: await getPersonAttributeTypeUuid(
- personAttributes.residencePhone
- ),
- otherPhoneUuid: await getPersonAttributeTypeUuid(
- personAttributes.otherPhone
- ),
- occupationUuid: await getPersonAttributeTypeUuid(
- personAttributes.occupation
- )
- }
+ Promise.all(attributes)
+ .then(resolvedAttributes => {
+ this.setState({
+ attributes: resolvedAttributes
+ });
+ })
+ .then(() => {
+ this.loadPersonData();
+ });
});
+ }
+
+ getAttributes = async () => {
+ const response = await fetchPersonAttributeConfig();
+ if (response.status === 200) {
+ return response.json();
+ } else {
+ return Promise.reject({
+ status: response.status,
+ statusText: response.statusText
+ });
+ }
};
loadPersonData = async () => {
@@ -119,7 +109,10 @@ class EditPerson extends Component {
birthdateEstimated: data.birthdateEstimated
}
});
- data.attributes && this.setPersonAttributeValues(data.attributes);
+ if (data.attributes != []) {
+ this.setState({ attributesData: data.attributes });
+ this.setPersonAttributeValues(data.attributes);
+ }
});
};
@@ -138,73 +131,16 @@ class EditPerson extends Component {
setPersonAttributeValues = attributes => {
attributes.forEach(attribute => {
- switch (attribute.display.split(' = ')[0]) {
- case personAttributes.organization: {
- this.setState({
- person: {
- ...this.state.person,
- organization: attribute.display.split(' = ')[1]
- }
- });
- break;
- }
- case personAttributes.email: {
- this.setState({
- person: {
- ...this.state.person,
- email: attribute.display.split(' = ')[1]
- }
- });
- break;
- }
- case personAttributes.mobilePhone: {
- this.setState({
- person: {
- ...this.state.person,
- mobilePhone: attribute.display.split(' = ')[1]
- }
- });
- break;
- }
- case personAttributes.workPhone: {
- this.setState({
- person: {
- ...this.state.person,
- workPhone: attribute.display.split(' = ')[1]
- }
- });
- break;
- }
- case personAttributes.residencePhone: {
- this.setState({
- person: {
- ...this.state.person,
- residencePhone: attribute.display.split(' = ')[1]
- }
- });
- break;
- }
- case personAttributes.otherPhone: {
- this.setState({
- person: {
- ...this.state.person,
- otherPhone: attribute.display.split(' = ')[1]
- }
- });
- break;
- }
- case personAttributes.occupation: {
- this.setState({
- person: {
- ...this.state.person,
- occupation: attribute.display.split(' = ')[1]
- }
- });
- break;
- }
- default:
- break;
- }
+ const attributeName = attribute.display.split(' = ')[0];
+ const attributeValue = attribute.display.split(' = ')[1];
+ this.setState(prevState => ({
+ attributes: prevState.attributes.map(stateAttribute => {
+ if (stateAttribute.attributeName === attributeName) {
+ return { ...stateAttribute, value: attributeValue };
+ }
+ return stateAttribute;
+ })
+ }));
});
};
@@ -234,16 +170,8 @@ class EditPerson extends Component {
};
handleClearForm() {
+ this.setPersonAttributeValues(this.state.attributesData);
this.setState({
- person: {
- organization: '',
- email: '',
- mobilePhone: '',
- workPhone: '',
- residencePhone: '',
- otherPhone: '',
- occupation: ''
- },
isRequestError: false
});
}
@@ -258,17 +186,20 @@ class EditPerson extends Component {
middleName,
lastName,
gender,
- organization,
- email,
- mobilePhone,
- workPhone,
- residencePhone,
- otherPhone,
- occupation,
birthdate,
birthdateEstimated
} = this.state.person;
+ const attributes = this.state.attributes.map(attribute => {
+ return {
+ attributeType: {
+ uuid: attribute.uuid
+ },
+ voided: this.isVoided(attribute.value),
+ value: !this.isVoided(attribute.value) ? attribute.value : null
+ };
+ });
+
const formPayload = {
names: [
{
@@ -279,68 +210,11 @@ class EditPerson extends Component {
],
gender,
birthdateEstimated,
- attributes: [
- {
- attributeType: {
- uuid: this.state.attributes.organizationUuid
- },
- voided: this.isVoided(organization),
- value: organization
- },
- {
- attributeType: {
- uuid: this.state.attributes.emailUuid
- },
- voided: this.isVoided(email),
- value: email
- },
- {
- attributeType: {
- uuid: this.state.attributes.mobilePhoneUuid
- },
- voided: this.isVoided(mobilePhone),
- value: mobilePhone
- },
- {
- attributeType: {
- uuid: this.state.attributes.workPhoneUuid
- },
- voided: this.isVoided(workPhone),
- value: workPhone
- },
- {
- attributeType: {
- uuid: this.state.attributes.residencePhoneUuid
- },
- voided: this.isVoided(residencePhone),
- value: residencePhone
- },
- {
- attributeType: {
- uuid: this.state.attributes.otherPhoneUuid
- },
- voided: this.isVoided(otherPhone),
- value: otherPhone
- },
- {
- attributeType: {
- uuid: this.state.attributes.occupationUuid
- },
- voided: this.isVoided(occupation),
- value: occupation
- }
- ]
+ attributes: attributes
};
if (this.isVoided(birthdate)) {
formPayload.birthdate = birthdate + 'T12:00:00.000+0000';
}
- this.isVoided(organization) && delete formPayload.attributes[0].value;
- this.isVoided(email) && delete formPayload.attributes[1].value;
- this.isVoided(mobilePhone) && delete formPayload.attributes[2].value;
- this.isVoided(workPhone) && delete formPayload.attributes[3].value;
- this.isVoided(residencePhone) && delete formPayload.attributes[4].value;
- this.isVoided(otherPhone) && delete formPayload.attributes[5].value;
- this.isVoided(occupation) && delete formPayload.attributes[6].value;
return formPayload;
};
@@ -350,6 +224,15 @@ class EditPerson extends Component {
this.updateRequest(payload);
};
+ handleOtherAttributesChange = ({ target: input }) => {
+ const attributes = [...this.state.attributes];
+ const index = attributes.findIndex(
+ attribute => attribute.name === input.name
+ );
+ attributes[index].value = input.value;
+ this.setState({ attributes });
+ };
+
updateRequest(formPayload) {
const { firstName, lastName } = this.state.person;
this.setState({
@@ -412,13 +295,6 @@ class EditPerson extends Component {
middleName,
lastName,
gender,
- organization,
- email,
- mobilePhone,
- workPhone,
- residencePhone,
- otherPhone,
- occupation,
birthdate,
birthdateEstimated
} = this.state.person;
@@ -430,6 +306,8 @@ class EditPerson extends Component {
lastUpdatedPerson: lastCreatedPerson
} = this.state;
+ const personAttributes = this.state.attributes;
+
const isEnabled = !isRequestLoading;
let modal = null;
@@ -582,123 +460,54 @@ class EditPerson extends Component {
-
-
-
-
+ {personAttributes.length > 0 && (
+
+
+
+
+
+ {personAttributes.map(attribute => {
+ return (
+
+ );
+ })}
+
+
+
-
-
-
-
+ )}
{modal}