Skip to content

Commit

Permalink
(feat) Update diagnosis to support rank and certainty (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
donaldkibet authored Oct 4, 2023
1 parent 1fc39ee commit 25977c8
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,8 @@ export class QuestionFactory {
}

switch (renderType) {
case 'diagnosis':
return this.toDiagnosisQuestion(schema);
case 'select':
return this.toSelectQuestion(schema);
case 'single-select':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@

<div *ngSwitchCase="'radio'">
<ofe-radio-button
[id]="node.question.key + 'id'"
[id]="node.question.key + 'id' + controlId"
[formControlName]="node.question.key"
[options]="node.question.options"
[allowUnselect]="node.question.allowUnselect"
Expand Down Expand Up @@ -519,6 +519,36 @@ <h4 style="margin: 2px; font-weight: bold">
/>
</div>
</div>
<div *ngSwitchCase="'diagnosisGroup'" style="margin-bottom: 20px">
<div *ngFor="let child of node.children; let i = index">
<ofe-form-renderer
*ngFor="let question of child.question.questions"
[parentComponent]="this"
[node]="child.children[question.key]"
[parentGroup]="child.control"
[labelMap]="labelMap"
[controlId]="i"
></ofe-form-renderer>
<button
type="button"
style="width: 100px"
class="cds--btn cds--btn--danger cds--btn--sm"
(click)="node.removeAt(i)"
>
{{ 'remove' | translate }}
</button>
<br />
<hr
style="
margin-left: -2px;
margin-right: -2px;
margin-bottom: 4px;
margin-top: 8px;
border-width: 1px;
"
/>
</div>
</div>
</div>
<button
type="button"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ArrayNode, LeafNode } from '../form-factory/form-node';

export function processFormNode(formNode, key, formDiagnosisNodes) {
if (!formNode.children) return;

const { children } = formNode;

// Condition for diagnosisGroup nodes
const childNodeForKey = children[key];
if (
childNodeForKey instanceof ArrayNode &&
childNodeForKey.question.extras.type === 'diagnosisGroup'
) {
return [...Object.values(childNodeForKey.children)];
}

// Condition for diagnosis nodes
Object.values(children).forEach((child: LeafNode) => {
const { question, nodeIndex } = child;
if (
question.extras?.type === 'diagnosis' &&
!formDiagnosisNodes.some((x) => x.nodeIndex === nodeIndex)
) {
return child;
}
});
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Injectable } from '@angular/core';

import * as _ from 'lodash';
import { Form } from '../form-factory/form';
import { ValueAdapter } from './value.adapter';
import { ArrayNode, GroupNode, LeafNode } from '../form-factory/form-node';

@Injectable()
export class DiagnosisValueAdapter implements ValueAdapter {
Expand Down Expand Up @@ -31,26 +34,68 @@ export class DiagnosisValueAdapter implements ValueAdapter {
form.existingDiagnoses,
2
);
this.setDiagnosisGroupValue(
this.formDiagnosisNodes,
form.existingDiagnoses
);
}

private _createDiagnosesPayload(diagnosisNodes, existingDiagnoses) {
const payload: Array<DiagnosisPayload> = [];
let deletedDiagnoses: Array<DiagnosisPayload> = [];

diagnosisNodes?.forEach((node) => {
node.control.value
.filter((v) => v[node.question.key])
.forEach((value) => {
// Create Payload
const payloadDiagnosis = this._createPayloadDiagnosis(
value[node.question.key],
node.question.extras
);
// Validate if is new value
payload.push(payloadDiagnosis);
if (node instanceof ArrayNode) {
node.control.value
.filter((v) => v[node.question.key])
.forEach((value) => {
// Create Payload
const payloadDiagnosis = this._createPayloadDiagnosis(
value[node.question.key],
node.question.extras
);
// Validate if is new value
payload.push(payloadDiagnosis);
});
}

if (node instanceof ArrayNode) {
const groupNodeArray = node.children;
groupNodeArray.forEach((groupNode) => {
if (this.hasDiagnosisNodeChanged(groupNode)) {
const diagnosisPayload: Partial<DiagnosisPayload> = {};
Object.values(groupNode.children).forEach((childNode: LeafNode) => {
const {
diagnosisType
} = childNode.question.extras.questionOptions;
switch (diagnosisType) {
case 'rank':
diagnosisPayload.rank =
parseInt(childNode.control.value, 10) ?? 1;
break;
case 'certainty':
diagnosisPayload.certainty = childNode.control.value;
break;
case 'diagnosis':
diagnosisPayload.diagnosis = {
coded: childNode.control.value
};
break;
default:
break;
}
});
if (_.isEmpty(diagnosisPayload)) {
return null;
}
if (groupNode.question.defaultValue?.uuid) {
diagnosisPayload.uuid = groupNode.question.defaultValue.uuid;
}
diagnosisPayload.voided = false;
payload.push(diagnosisPayload as DiagnosisPayload);
}
});
}
});

this._updatedOldDiagnoses(payload, existingDiagnoses);
deletedDiagnoses = this._getDeletedDiagnoses(payload, existingDiagnoses);
return payload.concat(deletedDiagnoses);
Expand Down Expand Up @@ -122,6 +167,38 @@ export class DiagnosisValueAdapter implements ValueAdapter {
});
}

private setDiagnosisGroupValue(
formDiagnosisNodes,
existingDiagnoses: Array<Diagnosis>
) {
for (const diagnosis of existingDiagnoses) {
for (const diagnosisNode of formDiagnosisNodes) {
if (diagnosisNode.question.extras.type !== 'diagnosisGroup') break;
const groupNode = diagnosisNode.createChildNode() as GroupNode;

groupNode.question.defaultValue = { uuid: diagnosis.uuid };
for (const child of Object.values(groupNode.children) as LeafNode[]) {
const diagnosisType =
child.question.extras.questionOptions.diagnosisType;
switch (diagnosisType) {
case 'diagnosis':
child.initialValue = diagnosis.diagnosis.coded?.uuid;
child.control.setValue(diagnosis.diagnosis.coded?.uuid);
break;
case 'rank':
child.initialValue = diagnosis.rank;
child.control.setValue(diagnosis.rank);
break;
case 'certainty':
child.initialValue = diagnosis.certainty;
child.control.setValue(diagnosis.certainty);
break;
}
}
}
}
}

private _findDiagnosisQuestionNodes(formNode) {
if (formNode.children) {
if (formNode.children instanceof Object) {
Expand All @@ -139,20 +216,31 @@ export class DiagnosisValueAdapter implements ValueAdapter {
break;
case 'repeating':
if (formNode.children) {
const { children } = formNode;
// Condition for diagnosisGroup nodes
for (const node in formNode.children) {
const question = formNode.children[node].question;
const index = formNode.children[node].nodeIndex;
const questionExtras =
formNode.children[node].question.extras;
if (questionExtras.type === 'diagnosisGroup') {
const arrayNode = formNode.children[node] as ArrayNode;
this.formDiagnosisNodes.push(arrayNode);
break;
}
}
// Condition for diagnosis nodes
Object.values(children).forEach((child: LeafNode) => {
const { question, nodeIndex } = child;
if (
question.extras &&
question.extras.type === 'diagnosis' &&
question.extras?.type === 'diagnosis' &&
!this.formDiagnosisNodes.some(
(x) => index === x.nodeIndex
(x) => x.nodeIndex === nodeIndex
)
) {
this.formDiagnosisNodes.push(formNode.children[node]);
this.formDiagnosisNodes.push(child);
}
}
});
}

break;
default:
break;
Expand All @@ -177,6 +265,20 @@ export class DiagnosisValueAdapter implements ValueAdapter {
voided: diagnosis.voided
};
}

hasDiagnosisNodeChanged(nodeAsGroup: GroupNode): boolean {
const childrenNodes = Object.values(nodeAsGroup.children) as Array<
LeafNode
>;

for (let childNode of childrenNodes) {
if (childNode.control.value !== childNode.initialValue) {
return true;
}
}

return false;
}
}

export interface Diagnosis {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export class EncounterAdapter implements ValueAdapter {

populateForm(form: Form, payload) {
this.populateNode(form.rootNode, payload);

if (Array.isArray(payload.orders)) {
this.ordersAdapter.populateForm(form, payload);
}
Expand Down
75 changes: 75 additions & 0 deletions src/app/adult-1.6.json
Original file line number Diff line number Diff line change
Expand Up @@ -8077,6 +8077,81 @@
]
}
]
},
{
"label": "Combined Diagnosis, Certainty, and Rank",
"sections": [
{
"label": "Diagnosis Group",
"isExpanded": "true",
"questions": [
{
"isExpanded": "true",
"questions": [
{
"label": "Diagnoses",
"type": "diagnosisGroup",
"questionOptions": {
"rendering": "repeating"
},
"questions": [
{
"label": "Diagnosis",
"id": "primaryDiagnosisId",
"type": "diagnosis",
"questionOptions": {
"rendering": "diagnosis",
"diagnosisType": "diagnosis"
},
"validators": []
},
{
"id": "DiagnosisCertainty",
"label": "Diagnosis Certainty",
"type": "diagnosis",
"questionOptions": {
"rendering": "radio",
"diagnosisType": "certainty",
"answers": [
{
"concept": "CONFIRMED",
"label": "Confirmed"
},
{
"concept": "PROVISIONAL",
"label": "Provisional"
}
]
},
"validators": []
},
{
"id": "DiagnosisRank",
"label": "Diagnosis Rank",
"type": "diagnosis",
"questionOptions": {
"rendering": "radio",
"diagnosisType": "rank",
"answers": [
{
"concept": 1,
"label": "Primary"
},
{
"concept": 2,
"label": "Secondary"
}
]
},
"validators": []
}
]
}
]
}
]
}
]
}
]
}

0 comments on commit 25977c8

Please sign in to comment.