Skip to content

Commit

Permalink
Results integrated in flow
Browse files Browse the repository at this point in the history
  • Loading branch information
alopezo committed Jan 7, 2025
1 parent 57aa748 commit 4e7b3eb
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 35 deletions.
10 changes: 5 additions & 5 deletions docs/assets/maturity/maturityLevels.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
"id": "clinical",
"question": "How extensively is SNOMED CT implemented across clinical and administrative areas?",
"options": [
{ "id": 1, "text": "Used in only a few isolated areas.", "score": 1 },
{ "id": 2, "text": "Used in several modules but not consistently.", "score": 2 },
{ "id": 3, "text": "Integrated into most clinical areas with documented use.", "score": 3 },
{ "id": 4, "text": "Implemented across both clinical and administrative functions.", "score": 4 },
{ "id": 5, "text": "Fully integrated across all areas with continuous evaluation.", "score": 5 }
{ "id": 1, "text": "Used in only a few isolated areas.", "score": 1, "example": "Only used in the emergy department." },
{ "id": 2, "text": "Used in several modules but not consistently.", "score": 2, "example": "Used in the emergency department and some outpatient clinics." },
{ "id": 3, "text": "Integrated into most clinical areas with documented use.", "score": 3, "example": "Integrated into the EHR and used in most clinical notes." },
{ "id": 4, "text": "Implemented across both clinical and administrative functions.", "score": 4, "example": "Used in clinical notes, billing, and reporting." },
{ "id": 5, "text": "Fully integrated across all areas with continuous evaluation.", "score": 5, "example": "Integrated into EHR, decision support, and analytics." }
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/index.html

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion docs/main.3124b84817e8f9df.js

This file was deleted.

1 change: 1 addition & 0 deletions docs/main.ff1d9a65480d9922.js

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions src/app/maturity/maturity-main/maturity-main.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
display: flex;
justify-content: center;
gap: 16px;
margin-bottom: 16px;
}

.progress-bar {
Expand All @@ -83,6 +84,28 @@
margin-bottom: 20px;
}

.mat-radio-button {
display: flex;
align-items: flex-start; /* Align items to the top of the container */
}

.mat-radio-label-content {
display: flex;
flex-direction: row; /* Stack elements vertically */
margin-top: 8px; /* Add spacing between the radio button and the text */
}

.example-text {
font-size: 0.9rem; /* Optional: Adjust the font size */
color: gray; /* Optional: Dim the color for secondary text */
}

.mat-icon {
font-size: 16px; /* Adjust icon size */
margin-left: 10px; /* Space between the icon and its text */
}


/* Buttons */
button[mat-raised-button] {
margin-top: 16px;
Expand Down
37 changes: 33 additions & 4 deletions src/app/maturity/maturity-main/maturity-main.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,23 @@ <h2>Select Stakeholder</h2>
</div>
</div>

<div class="question-flow-container" *ngIf="currentQuestionIndex >= 0">
<div class="question-flow-container" *ngIf="currentQuestionIndex >= 0 && currentQuestionIndex < allQuestions.length">
<div class="question-container" [formGroup]="responseForm" *ngIf="currentQuestionIndex < allQuestions.length" [@fadeInOut]>
<h2>Stakeholder: {{ allQuestions[currentQuestionIndex].stakeholderName }}</h2>
<mat-progress-bar mode="determinate" [value]="((currentQuestionIndex + 1) / (allQuestions.length + 1)) * 100" class="progress-bar"></mat-progress-bar>
<div class="progress-message">Question {{ currentQuestionIndex + 1 }} of {{ allQuestions.length }}</div>
<h3>Key Process Area: {{ allQuestions[currentQuestionIndex].kpaName }}</h3>
<p class="question-text">{{ allQuestions[currentQuestionIndex].question.question }}</p>
<mat-radio-group [formControl]="currentControl" class="options-container">
<mat-radio-button *ngFor="let option of allQuestions[currentQuestionIndex].question.options" [value]="option.score">
{{ option.text }}
</mat-radio-button>
<mat-radio-button *ngFor="let option of allQuestions[currentQuestionIndex].question.options" [value]="option.score">
<div class="mat-radio-label-content">
{{ option.text }}
<mat-icon *ngIf="option.example" [matTooltip]="option.example" matTooltipPosition="right">
help_outline
</mat-icon>
<!-- <span class="example-text">{{ option.example }}</span> -->
</div>
</mat-radio-button>
</mat-radio-group>
<div class="error-message" *ngIf="currentControl?.invalid && currentControl?.touched">
Please select an option for this question.
Expand All @@ -47,6 +53,29 @@ <h3>Key Process Area: {{ allQuestions[currentQuestionIndex].kpaName }}</h3>
Submit
</button>
</div>
<div class="button-container">
<button mat-flat-button color="primary" (click)="startOver()">
Restart assessment
</button>
</div>
</div>
</div>

<div class="question-flow-container" *ngIf="currentQuestionIndex == allQuestions.length">
<div class="question-container">
<h2>Stakeholder: {{ allQuestions[currentQuestionIndex - 1].stakeholderName }}</h2>
<h3>Maturity assessment results</h3>

<app-maturity-results [maturityResponse]="responseForm.value"></app-maturity-results>

<div class="button-container">
<button mat-flat-button color="primary" (click)="goToPreviousQuestion()" [disabled]="currentQuestionIndex < 1">
Back
</button>
<button mat-flat-button color="primary" (click)="startOver()">
Start over
</button>
</div>
</div>
</div>

15 changes: 11 additions & 4 deletions src/app/maturity/maturity-main/maturity-main.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ export class MaturityMainComponent implements OnInit {
}
}

startOver(): void {
this.currentQuestionIndex = -1;
// reset all responses
this.responseForm.reset();
this.currentControl = this.responseForm.controls['selectedStakeholder'] as FormControl;
}

uploadFile(event: any) {
if (event.target.files.length !== 1) {
Expand All @@ -117,10 +123,11 @@ export class MaturityMainComponent implements OnInit {
}

submitStakeholderResponses(): void {
this.dialog.open(MaturityResultsDialogComponent, {
width: '1600px',
data: { maturityResponse: this.responseForm.value }
});
this.currentQuestionIndex++;
// this.dialog.open(MaturityResultsDialogComponent, {
// width: '1600px',
// data: { maturityResponse: this.responseForm.value }
// });
}

getStakeholderFormGroup(stakeholderName: string): FormGroup {
Expand Down
13 changes: 12 additions & 1 deletion src/app/maturity/maturity-results/maturity-results.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,15 @@
.chart-container {
display: flex;
justify-content: center;
}
}

.centered-box {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid #000; /* Adjust the border color and width as needed */
padding: 10px; /* Adjust the padding as needed */
margin: 20px auto; /* Center the element horizontally */
width: fit-content; /* Adjust the width as needed */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Optional: Add a subtle shadow */
}
16 changes: 2 additions & 14 deletions src/app/maturity/maturity-results/maturity-results.component.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<h3 class="centered-box">Overall calculated maturity score: {{ calculateOverallAverage(maturityResponse) }}</h3>
<table class="bordered-table">
<thead>
<tr>
<th>Stakeholder</th>
<th>KPA</th>
<th>Result</th>
<!-- <th>Question</th>
<th>Response</th> -->
</tr>
</thead>
<tbody>
Expand All @@ -14,27 +12,17 @@
<ng-container *ngFor="let kpa of getKpas(maturityResponse, stakeholder)">
<ng-container *ngFor="let question of getQuestions(maturityResponse, stakeholder, kpa) | keyvalue; let i = index">
<tr>
<!-- Stakeholder Column -->
<td *ngIf="isFirstRowInStakeholder(i, stakeholder, kpa)"
[attr.rowspan]="getStakeholderRowSpan(maturityResponse, stakeholder)">
{{ stakeholder }}
</td>

<!-- KPA Column -->
<td *ngIf="isFirstRowInKpa(i)"
[attr.rowspan]="getKpaRowSpan(maturityResponse, stakeholder, kpa)">
{{ kpa }}
{{ kpa | titlecase }}
</td>

<!-- Result Column -->
<td *ngIf="isFirstRowInKpa(i)"
[attr.rowspan]="getKpaRowSpan(maturityResponse, stakeholder, kpa)">
{{ calculateAverage(getQuestions(maturityResponse, stakeholder, kpa)) | number: '1.2-2' }}
</td>

<!-- Question and Response Columns -->
<!-- <td>{{ question.key }}</td>
<td>{{ question.value }}</td> -->
</tr>
</ng-container>
</ng-container>
Expand Down
30 changes: 30 additions & 0 deletions src/app/maturity/maturity-results/maturity-results.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component, ElementRef, Input, ViewChild, OnChanges, SimpleChanges, AfterViewInit } from '@angular/core';
import { Chart, registerables } from 'chart.js';
import { TitleCasePipe } from '@angular/common';
Chart.register(...registerables);

@Component({
Expand Down Expand Up @@ -137,5 +138,34 @@ export class MaturityResultsComponent implements OnChanges, AfterViewInit {
const sum = values.reduce((acc, val) => acc + val, 0);
return values.length > 0 ? sum / values.length : 0;
}

calculateOverallAverage(data: Record<string, any>): number {
// Object to group values by KPA
const kpas: { [key: string]: number[] } = {};

// Process the data to group scores by KPA
for (const key in data) {
if (data.hasOwnProperty(key) && data[key] !== null && key !== 'selectedStakeholder') {
const kpa = key.split('.')[1]; // Extract the KPA from the key
if (!kpas[kpa]) {
kpas[kpa] = [];
}
kpas[kpa].push(data[key]);
}
}

// Calculate the average for each KPA
const kpaAverages = Object.keys(kpas).map(kpa => {
const values = kpas[kpa];
return values.reduce((sum, value) => sum + value, 0) / values.length;
});

// Calculate the overall average of the KPA averages
const overallAverage =
kpaAverages.reduce((sum, avg) => sum + avg, 0) / kpaAverages.length;

return overallAverage;
}


}
10 changes: 5 additions & 5 deletions src/assets/maturity/maturityLevels.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
"id": "clinical",
"question": "How extensively is SNOMED CT implemented across clinical and administrative areas?",
"options": [
{ "id": 1, "text": "Used in only a few isolated areas.", "score": 1 },
{ "id": 2, "text": "Used in several modules but not consistently.", "score": 2 },
{ "id": 3, "text": "Integrated into most clinical areas with documented use.", "score": 3 },
{ "id": 4, "text": "Implemented across both clinical and administrative functions.", "score": 4 },
{ "id": 5, "text": "Fully integrated across all areas with continuous evaluation.", "score": 5 }
{ "id": 1, "text": "Used in only a few isolated areas.", "score": 1, "example": "Only used in the emergy department." },
{ "id": 2, "text": "Used in several modules but not consistently.", "score": 2, "example": "Used in the emergency department and some outpatient clinics." },
{ "id": 3, "text": "Integrated into most clinical areas with documented use.", "score": 3, "example": "Integrated into the EHR and used in most clinical notes." },
{ "id": 4, "text": "Implemented across both clinical and administrative functions.", "score": 4, "example": "Used in clinical notes, billing, and reporting." },
{ "id": 5, "text": "Fully integrated across all areas with continuous evaluation.", "score": 5, "example": "Integrated into EHR, decision support, and analytics." }
]
},
{
Expand Down

0 comments on commit 4e7b3eb

Please sign in to comment.