Skip to content
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

Add support to attributes for the patient groups #62

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion src/add-group-modal/AddGroupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ import {
} from "@carbon/react";
import { TrashCan } from "@carbon/react/icons";
import { useTranslation } from "react-i18next";
import { ExtensionSlot, showToast } from "@openmrs/esm-framework";
import { ExtensionSlot, showToast, useConfig } from "@openmrs/esm-framework";
import styles from "./styles.scss";
import GroupFormWorkflowContext from "../context/GroupFormWorkflowContext";
import { usePostCohort } from "../hooks";
import GroupAttributeComponent, {
CohortAttribute,
} from "./cohort-attribute-component/GroupAttributeComponent";

const MemExtension = React.memo(ExtensionSlot);

Expand Down Expand Up @@ -79,6 +82,8 @@ const NewGroupForm = (props) => {
errors,
validate,
removePatient,
groupAttributes,
onCohortAttributeValueChange,
} = props;
const { t } = useTranslation();

Expand All @@ -103,6 +108,10 @@ const NewGroupForm = (props) => {
: errors.name}
</p>
)}
<GroupAttributeComponent
cohortAttributeTypes={groupAttributes}
onChange={onCohortAttributeValueChange}
/>
<FormLabel>
{patientList.length} {t("patientsInGroup", "Patients in group")}
</FormLabel>
Expand Down Expand Up @@ -147,13 +156,19 @@ const AddGroupModal = ({
isOpen,
handleCancel,
onPostSubmit,
attributes = undefined,
}) => {
const { setGroup } = useContext(GroupFormWorkflowContext);
const { t } = useTranslation();
const [errors, setErrors] = useState({});
const [name, setName] = useState(groupName);
const [patientList, setPatientList] = useState(patients || []);
const { post, result, error } = usePostCohort();
const { groupAttributesConfig } = useConfig();
const [groupAttributes, setGroupAttributes] = useState<CohortAttribute[]>([]);

console.log("result", result);
console.log("groupName", groupName);

const removePatient = useCallback(
(patientUuid: string) =>
Expand Down Expand Up @@ -205,11 +220,52 @@ const AddGroupModal = ({
[setPatientList]
);

useMemo(() => {
setGroupAttributes(
groupAttributesConfig?.map((config) => {
const attribute = attributes?.find(
(a) => a.attributeType.uuid == config.uuid
);
return {
uuid: attribute?.uuid,
labelCode: config.labelCode,
value: attribute?.value,
attributeType: {
name: config.name,
type: config.type,
uuid: config.uuid,
},
};
})
);
}, [groupAttributesConfig, attributes]);

const onCohortAttributeValueChange = (attributeId: string, value: any) => {
const updatedAttributes = [...groupAttributes];
updatedAttributes.find(
(a: CohortAttribute) => a.attributeType.uuid == attributeId
).value = value;
setGroupAttributes(updatedAttributes);
};

const getAttributesPayload = () => {
return groupAttributes.map((a: CohortAttribute) => {
return {
uuid: a.uuid,
value: a.value,
attributeType: {
uuid: a.attributeType.uuid,
},
};
});
};

const handleSubmit = () => {
if (validate()) {
post({
uuid: cohortUuid,
name: name,
attributes: getAttributesPayload(),
cohortMembers: patientList.map((p) => ({ patient: p.uuid })),
});
if (onPostSubmit) {
Expand Down Expand Up @@ -269,6 +325,8 @@ const AddGroupModal = ({
errors,
validate,
removePatient,
groupAttributes,
onCohortAttributeValueChange,
}}
/>
</ModalBody>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from "react";
import { TextInput, Checkbox } from "@carbon/react";
import { useTranslation } from "react-i18next";
import styles from "./styles.scss";

interface GroupAttributeComponentProps {
cohortAttributeTypes: CohortAttribute[];
onChange: any;
}
const GroupAttributeComponent: React.FC<GroupAttributeComponentProps> = (
props
) => {
const { cohortAttributeTypes, onChange } = props;
const { t } = useTranslation();

return (
<>
{cohortAttributeTypes.map((attribute) => {
switch (attribute.attributeType.type) {
case "org.openmrs.customdatatype.datatype.FreeTextDatatype":
return (
<TextInput
id={attribute.attributeType.uuid}
labelText={t(attribute.labelCode, attribute.attributeType.name)}
value={attribute.value}
type="text"
onChange={(event) => {
onChange(event.target.id, event.target.value);
}}
/>
);
case "org.openmrs.customdatatype.datatype.BooleanDatatype":
return (
<Checkbox
id={attribute.attributeType.uuid}
labelText={t(attribute.labelCode, attribute.attributeType.name)}
checked={attribute.value} // Set to true for a pre-checked checkbox
onChange={(event) => {
onChange(event.target.id, event.target.checked);
}}
/>
);
default:
break;
}
})}
</>
);
};
export default GroupAttributeComponent;

export type CohortAttribute = {
uuid?: string;
labelCode?: string;
value?: any;
attributeType: {
uuid: string;
name: string;
type: string;
};
};
3 changes: 3 additions & 0 deletions src/add-group-modal/cohort-attribute-component/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@use '@carbon/styles/scss/spacing';
@use '@carbon/colors';

52 changes: 52 additions & 0 deletions src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,48 @@ export const configSchema = {
_default: "fa8fedc0-c066-4da3-8dc1-2ad8621fc480",
},
},
groupAttributesConfig: {
_type: Type.Array,
_description:
"List of group attributes, must correspond to an Cohort Attribute Type on the database",
_elements: {
uuid: {
_type: Type.String,
_description: "UUID of the Cohort Attribute Type",
},
name: {
_type: Type.String,
_description: "Name of the Cohort Attribute Type",
},
id: {
_type: Type.String,
_description: "ID of the attribute.",
},
labelCode: {
_type: Type.String,
_description: "Code to be use in translation.",
},
type: {
_type: Type.String,
_description:
"Datatype of the Cohort Attribute Type, acceptable values are 'FreeTextDatatype' | 'BooleanDatatype'",
},
},
_default: [
{
uuid: "09790099-9190-429d-811a-aac9edb8d98a",
name: "Test 01",
labelCode: "test01",
type: "org.openmrs.customdatatype.datatype.FreeTextDatatype",
},
{
uuid: "09790099-9190-429d-811a-aac9edb8d98d",
name: "Close Group",
labelCode: "closeGroup",
type: "org.openmrs.customdatatype.datatype.BooleanDatatype",
},
],
},
};

export type Form = {
Expand All @@ -94,7 +136,17 @@ export type Category = {
forms: Array<Form>;
};

export type CohortAttributeTypeConfig = {
uuid: string;
name: string;
labelCode: string;
type:
| "org.openmrs.customdatatype.datatype.FreeTextDatatype"
| "org.openmrs.customdatatype.datatype.BooleanDatatype";
};

export type Config = {
formCategories: Array<Category>;
formCategoriesToShow: Array<string>;
groupAttributesConfig: Array<CohortAttributeTypeConfig>;
};
5 changes: 5 additions & 0 deletions src/context/GroupFormWorkflowContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface GroupType {
id: string;
name: string;
members: Array<Type.Object>;
attributes: Array<Type.Object>;
}
export interface MetaType {
sessionName: string;
Expand Down Expand Up @@ -56,6 +57,7 @@ export const initialWorkflowState = {
activeGroupUuid: null, // pseudo field from state[activeFormUuid].groupUuid
activeGroupName: null, // pseudo field from state[activeFormUuid].groupName
activeGroupMembers: [], // pseudo field from state[activeFormUuid].groupMembers
activeGroupAttributes: [], // pseudo field from state[activeFormUuid].groupAttributes
activeSessionMeta: {
sessionName: null,
practitionerName: null,
Expand Down Expand Up @@ -162,6 +164,9 @@ const GroupFormWorkflowProvider = ({ children }) => {
activeGroupMembers:
state.forms?.[state.activeFormUuid]?.groupMembers ??
initialWorkflowState.activeGroupMembers,
activeGroupAttributes:
state.forms?.[state.activeFormUuid]?.groupAttributes ??
initialWorkflowState.activeGroupAttributes,
activeSessionMeta:
state.forms?.[state.activeFormUuid]?.sessionMeta ??
initialWorkflowState.activeSessionMeta,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,12 @@ const PatientRow = ({ patient }) => {

const AttendanceTable = ({ patients }) => {
const { t } = useTranslation();
const { activeGroupUuid, activeGroupName, activeGroupMembers } = useContext(
GroupFormWorkflowContext
);
const {
activeGroupUuid,
activeGroupName,
activeGroupAttributes,
activeGroupMembers,
} = useContext(GroupFormWorkflowContext);

const [isOpen, setOpen] = useState(false);

Expand Down Expand Up @@ -118,6 +121,7 @@ const AttendanceTable = ({ patients }) => {
isOpen: isOpen,
handleCancel: handleCancel,
onPostSubmit: onPostSubmit,
attributes: activeGroupAttributes,
}}
/>
<Table>
Expand Down
2 changes: 2 additions & 0 deletions src/group-form-entry-workflow/group-search/GroupSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const GroupSearch: React.FC<GroupSearchProps> = ({
},
});

console.log("results", results);

const lastItem = useRef(null);
const observer = useRef(null);
const loadingRef = useCallback(
Expand Down