diff --git a/src/app/clinic-dashboard/hiv/ahd-report/ahd-report.component.ts b/src/app/clinic-dashboard/hiv/ahd-report/ahd-report.component.ts new file mode 100644 index 000000000..514b45194 --- /dev/null +++ b/src/app/clinic-dashboard/hiv/ahd-report/ahd-report.component.ts @@ -0,0 +1,45 @@ +import { Component, OnInit } from '@angular/core'; +import { AhdReportBaseComponent } from 'src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component'; +import { Router, ActivatedRoute } from '@angular/router'; +import { AhdResourceService } from 'src/app/etl-api/ahd-resource.service'; +import * as Moment from 'moment'; +@Component({ + selector: 'ahd-reports', + templateUrl: + '../../../hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.html' +}) +export class AhdReportComponent + extends AhdReportBaseComponent + implements OnInit { + constructor( + public router: Router, + public route: ActivatedRoute, + public ahdReport: AhdResourceService + ) { + super(router, route, ahdReport); + } + public params: any; + public prepReportSummaryData: any = []; + public columnDefs: any = []; + + public statusError = false; + public errorMessage = ''; + public showInfoMessage = false; + public isLoading = false; + ngOnInit() { + this.params = { _month: Moment().format('YYYY-MM-DD') }; + this.route.queryParams.subscribe( + (params: any) => { + if (params && params.month) { + this.isLoading = true; + this.params = params; + this.generateReport(); + } + }, + (error) => { + console.error('Error', error); + this.showInfoMessage = true; + } + ); + } +} diff --git a/src/app/clinic-dashboard/hiv/hiv-program.module.ts b/src/app/clinic-dashboard/hiv/hiv-program.module.ts index d7b942b0e..4edf7fd68 100644 --- a/src/app/clinic-dashboard/hiv/hiv-program.module.ts +++ b/src/app/clinic-dashboard/hiv/hiv-program.module.ts @@ -69,6 +69,7 @@ import { BsDatepickerModule } from 'ngx-bootstrap'; import { ClinicDashboardRetentionReportComponent } from './retention-report/clinic-dashboard-retention-report.component'; import { ClinicDashboardCaseManagementComponent } from './case-management/clinic-dashboard-case-management.component'; import { PrepReportComponent } from './prep-report/prep-report.component'; +import { AhdReportComponent } from './ahd-report/ahd-report.component'; import { ClinicDashboardHeiReportComponent } from './clinic-dashboard-hei-indicators-report/clinic-dashboard-hei-report.component'; import { ClinicDashboardPmtctRriReportComponent } from './clinic-dashboard-pmtct-rri-report/clinic-dashboard-pmtct-rri-report.component'; @@ -178,6 +179,7 @@ import { PlhivNcdV2ReportComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v2-re ClinicDashboardRetentionReportComponent, ClinicDashboardCaseManagementComponent, PrepReportComponent, + AhdReportComponent, ClinicDashboardHeiReportComponent, ClinicDashboardPmtctRriReportComponent, HIVListsMicroFrontendComponent, diff --git a/src/app/clinic-dashboard/hiv/hiv-program.routes.ts b/src/app/clinic-dashboard/hiv/hiv-program.routes.ts index ea7c4bfe6..0d8ccb538 100644 --- a/src/app/clinic-dashboard/hiv/hiv-program.routes.ts +++ b/src/app/clinic-dashboard/hiv/hiv-program.routes.ts @@ -40,6 +40,8 @@ import { ChartAbstractionPatientlistComponent } from 'src/app/hiv-care-lib/dqa-r import { ClinicDashboardCaseManagementComponent } from './case-management/clinic-dashboard-case-management.component'; import { PrepReportComponent } from './prep-report/prep-report.component'; import { PrepReportPatientListComponent } from 'src/app/hiv-care-lib/prep-report/prep-report-patient-list/prep-report-patient-list.component'; +import { AhdReportComponent } from './ahd-report/ahd-report.component'; +import { AhdMonthlyReportPatientlistComponent } from 'src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component'; import { MonthlyReportComponent } from 'src/app/hiv-care-lib/monthly-report/monthly-report.component'; // tslint:disable-next-line: max-line-length import { ClinicDashboardGainsAndLossesComponent } from './patient-gain-and-loses-report/clinic-dashboard-gains-and-losses.component'; @@ -487,6 +489,19 @@ const routes: Routes = [ component: PlhivNcdV2ReportPatientListComponent } ] + }, + { + path: 'ahd-monthly-report', + children: [ + { + path: '', + component: AhdReportComponent + }, + { + path: 'patient-list', + component: AhdMonthlyReportPatientlistComponent + } + ] } ] }, diff --git a/src/app/data-analytics-dashboard/hiv/ahd-report/ahd-report.component.ts b/src/app/data-analytics-dashboard/hiv/ahd-report/ahd-report.component.ts new file mode 100644 index 000000000..052afc7fe --- /dev/null +++ b/src/app/data-analytics-dashboard/hiv/ahd-report/ahd-report.component.ts @@ -0,0 +1,93 @@ +import { Router, ActivatedRoute } from '@angular/router'; +import { Component, OnInit } from '@angular/core'; +import { Location } from '@angular/common'; +import { take } from 'rxjs/operators'; +import * as rison from 'rison-node'; +import * as Moment from 'moment'; + +import { AhdReportBaseComponent } from 'src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component'; +import { DataAnalyticsDashboardService } from '../../services/data-analytics-dashboard.services'; +import { AhdResourceService } from 'src/app/etl-api/ahd-resource.service'; + +@Component({ + selector: 'ahd-report', + templateUrl: + '../../../hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.html' +}) +export class AhdReportComponent + extends AhdReportBaseComponent + implements OnInit { + public enabledControls = 'locationControl,monthControl'; + + constructor( + public router: Router, + public route: ActivatedRoute, + public ahdReport: AhdResourceService, + private dataAnalyticsDashboardService: DataAnalyticsDashboardService, + private location: Location + ) { + super(router, route, ahdReport); + } + + public ngOnInit() { + this.loadReportParamsFromUrl(); + } + + public generateReport() { + this.setSelectedLocation(); + this.storeParamsInUrl(); + + if (Array.isArray(this.locationUuids) && this.locationUuids.length > 0) { + this.params = { + locationUuids: this.getSelectedLocations(this.locationUuids), + month: this._month + }; + super.generateReport(); + super.showDraftReportAlert(this._month); + } else { + this.errorMessage = 'Locations are required!'; + } + } + + public storeParamsInUrl() { + const state = { + locationUuids: this.getSelectedLocations(this.locationUuids), + month: this._month + }; + const stateUrl = rison.encode(state); + const path = this.router.parseUrl(this.location.path()); + path.queryParams = { + state: stateUrl + }; + + this.location.replaceState(path.toString()); + } + + public loadReportParamsFromUrl() { + const path = this.router.parseUrl(this.location.path()); + if (path.queryParams['state']) { + const state = rison.decode(path.queryParams['state']); + this.locationUuids = state.locations; + this.month = state.month; + } + + if (path.queryParams['state']) { + this.generateReport(); + } + } + + public setSelectedLocation() { + this.dataAnalyticsDashboardService + .getSelectedLocations() + .pipe(take(1)) + .subscribe((data) => { + if (data) { + this.locationUuids = data.locations; + } + }); + } + + private getSelectedLocations(locationUuids: Array): string { + return locationUuids.map((location) => location.value).join(','); + } +} diff --git a/src/app/data-analytics-dashboard/hiv/data-analytics-hiv.module.ts b/src/app/data-analytics-dashboard/hiv/data-analytics-hiv.module.ts index dc1451ca9..f0664f9b7 100644 --- a/src/app/data-analytics-dashboard/hiv/data-analytics-hiv.module.ts +++ b/src/app/data-analytics-dashboard/hiv/data-analytics-hiv.module.ts @@ -42,6 +42,7 @@ import { TxNewReportComponent } from './datim-reports/tx-new-report/tx-new-repor import { TxCurrReportComponent } from './datim-reports/tx-curr-report.component'; import { TxMmdReportComponent } from './datim-reports/tx-mmd-report.component'; import { TxRttReportComponent } from './datim-reports/tx-rtt-report.component'; +import { AhdReportComponent } from './ahd-report/ahd-report.component'; import { PlhivNcdV2ReportComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v2-report.component'; @NgModule({ @@ -95,7 +96,8 @@ import { PlhivNcdV2ReportComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v2-re TxCurrReportComponent, TxMmdReportComponent, TxRttReportComponent, - PlhivNcdV2ReportComponent + PlhivNcdV2ReportComponent, + AhdReportComponent ], providers: [ DataAnalyticsDashboardService, diff --git a/src/app/data-analytics-dashboard/hiv/data-analytics-hiv.routes.ts b/src/app/data-analytics-dashboard/hiv/data-analytics-hiv.routes.ts index 8e4662166..e9e7a5919 100644 --- a/src/app/data-analytics-dashboard/hiv/data-analytics-hiv.routes.ts +++ b/src/app/data-analytics-dashboard/hiv/data-analytics-hiv.routes.ts @@ -53,6 +53,8 @@ import { TxMmdReportPatientListComponent } from 'src/app/hiv-care-lib/tx-mmd-rep import { TxMmdReportComponent } from './datim-reports/tx-mmd-report.component'; import { TxRttReportComponent } from './datim-reports/tx-rtt-report.component'; import { TxRttReportPatientListComponent } from 'src/app/hiv-care-lib/tx-rtt-report/tx-rtt-report-patient-list/tx-rtt-report-patient-list.component'; +import { AhdReportComponent } from './ahd-report/ahd-report.component'; +import { AhdMonthlyReportPatientlistComponent } from 'src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component'; import { PlhivNcdV2ReportPatientListComponent } from 'src/app/hiv-care-lib/plhiv-ncd-v2-report/plhiv-ncd-v2-report-patient-list/plhiv-ncd-v2-report-patient-list.component'; import { PlhivNcdV2ReportComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v2-report.component'; @@ -267,6 +269,19 @@ const routes: Routes = [ component: PlhivNcdV2ReportPatientListComponent } ] + }, + { + path: 'ahd-monthly-report', + children: [ + { + path: '', + component: AhdReportComponent + }, + { + path: 'patient-list', + component: AhdMonthlyReportPatientlistComponent + } + ] } ] }, diff --git a/src/app/data-analytics-dashboard/hiv/monthly-reports-dashboard/data-analytics-monthly-reports.component.ts b/src/app/data-analytics-dashboard/hiv/monthly-reports-dashboard/data-analytics-monthly-reports.component.ts index 6c6935072..b65d97dff 100644 --- a/src/app/data-analytics-dashboard/hiv/monthly-reports-dashboard/data-analytics-monthly-reports.component.ts +++ b/src/app/data-analytics-dashboard/hiv/monthly-reports-dashboard/data-analytics-monthly-reports.component.ts @@ -50,6 +50,12 @@ export class DataAnalyticsMonthlyReportComponent implements OnInit { description: '', url: 'plhiv-ncd-v2-monthly-report', icon: 'fa' + }, + { + title: 'AHD Monthly Report', + description: '', + url: 'ahd-monthly-report', + icon: 'fa' } ]; } diff --git a/src/app/etl-api/ahd-resource.service.ts b/src/app/etl-api/ahd-resource.service.ts new file mode 100644 index 000000000..526c1496c --- /dev/null +++ b/src/app/etl-api/ahd-resource.service.ts @@ -0,0 +1,109 @@ +import { Injectable } from '@angular/core'; +import { AppSettingsService } from '../app-settings/app-settings.service'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import * as Moment from 'moment'; +import { catchError, map } from 'rxjs/operators'; +@Injectable({ + providedIn: 'root' +}) +export class AhdResourceService { + public get url(): string { + return this.appSettingsService.getEtlRestbaseurl().trim(); + } + constructor( + public http: HttpClient, + public appSettingsService: AppSettingsService + ) {} + public getAhdMonthlyReport(params: any): Observable { + // tslint:disable-next-line: max-line-length + + const stardDate = this.getDates(params.month).currentMonthFirstDate; + return this.http + .get( + `${this.url}ahd-monthly-summary?endDate=${params.month}&startDate=${stardDate}&locationUuids=${params.locationUuids}` + ) + .pipe( + catchError((err: any) => { + const error: any = err; + const errorObj = { + error: error.status, + message: error.statusText + }; + return Observable.of(errorObj); + }), + map((response: Response) => { + return response; + }) + ); + } + public getDates(currentEndDate) { + // Convert the currentEndDate string to a Date object + const currentDate = new Date(currentEndDate); + + // Get the current month and year + const currentMonth = currentDate.getMonth(); + const currentYear = currentDate.getFullYear(); + + // Calculate the previous month's last date + const previousMonthLastDate = new Date( + currentYear, + currentMonth, + 0 + ).getDate(); + + // Calculate the current month's end date + const currentMonthEndDate = new Date( + currentYear, + currentMonth + 1, + 0 + ).getDate(); + + // Calculate the current month's first date + const currentMonthFirstDate = new Date(currentYear, currentMonth, 1); + + // Format the dates as strings in the "YYYY-MM-DD" format + const previousMonthLastDateString = + currentYear + + '-' + + currentMonth.toString().padStart(2, '0') + + '-' + + previousMonthLastDate.toString().padStart(2, '0'); + + const currentMonthEndDateString = currentEndDate; + const currentMonthFirstDateString = + currentMonthFirstDate.getFullYear() + + '-' + + (currentMonthFirstDate.getMonth() + 1).toString().padStart(2, '0') + + '-' + + currentMonthFirstDate.getDate().toString().padStart(2, '0'); + + // Return the formatted dates + return { + currentMonthFirstDate: currentMonthFirstDateString + }; + } + + public getAhdPatientList(params: any, locationUuid: string): Observable { + // tslint:disable-next-line: max-line-length + const stardDate = this.getDates(params.month).currentMonthFirstDate; + + return this.http + .get( + `${this.url}ahd-monthly-summary-patient-list?indicators=${params.indicators}&startDate=${stardDate}&endDate=${params.month}&locationUuids=${params.locationUuids}` + ) + .pipe( + catchError((err: any) => { + const error: any = err; + const errorObj = { + error: error.status, + message: error.statusText + }; + return Observable.of(errorObj); + }), + map((response: Response) => { + return response; + }) + ); + } +} diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.css b/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.html b/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.html new file mode 100644 index 000000000..75e3b97c3 --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.html @@ -0,0 +1,34 @@ +
+ +
+
+ Loading... +
+

+ {{ selectedIndicatorGender }} {{ selectedIndicator }} patient list +

+
+ + +
+

+ + All records loaded {{ '[ ' + patientData.length + ' ]' }} +

+ +

+
+ +
+

Error loading patient list.

+
diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.spec.ts b/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.spec.ts new file mode 100644 index 000000000..e01fa98c3 --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AhdMonthlyReportPatientlistComponent } from './ahd-monthly-report-patientlist.component'; + +describe('AhdMonthlyReportPatientlistComponent', () => { + let component: AhdMonthlyReportPatientlistComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [AhdMonthlyReportPatientlistComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AhdMonthlyReportPatientlistComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.ts b/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.ts new file mode 100644 index 000000000..c6e037ab2 --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component.ts @@ -0,0 +1,122 @@ +import { Component, OnInit } from '@angular/core'; + +import { AhdResourceService } from 'src/app/etl-api/ahd-resource.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Location } from '@angular/common'; + +@Component({ + selector: 'app-ahd-monthly-report-patientlist', + templateUrl: './ahd-monthly-report-patientlist.component.html', + styleUrls: ['./ahd-monthly-report-patientlist.component.css'] +}) +export class AhdMonthlyReportPatientlistComponent implements OnInit { + public params: any; + public patientData: any; + public extraColumns: Array = []; + public isLoading = true; + public overrideColumns: Array = []; + public selectedIndicator: string; + public selectedIndicatorGender: string; + public hasLoadedAll = false; + public hasError = false; + public selectedMonth: String; + locationUuid: string; + + constructor( + private router: Router, + private route: ActivatedRoute, + private _location: Location, + public ahdResourceService: AhdResourceService + ) {} + ngOnInit() { + this.route.params.subscribe((params) => { + this.locationUuid = params['location_uuid']; + }); + + this.route.queryParams.subscribe( + (params) => { + // if (params && params.sDate) { + if (params) { + this.params = params; + this.selectedIndicator = params.indicatorHeader; + this.selectedIndicatorGender = params.indicatorGender; + this.getPatientList(params, this.locationUuid); + } + }, + (error) => { + console.error('Error', error); + } + ); + + this.addExtraColumns(); + } + + private getPatientList(params: any, location: string) { + this.ahdResourceService + .getAhdPatientList(params, location) + .subscribe((data) => { + this.isLoading = false; + this.patientData = data.results.results; + this.hasLoadedAll = true; + }); + } + + public addExtraColumns() { + const extraColumns = { + phone_number: 'Phone', + enrollment_date: 'Enrollment Date', + + who_stage: 'WHO stage', + + arv_first_regimen_start_date: 'First ARV start date', + cur_meds: 'Current Regimen', + cur_arv_line: 'Current ARV Line', + cd4_date: 'CD4 Date', + cd4_results: 'CD4 Results' + }; + const status = this.selectedIndicatorGender.split(' - ')[0]; + if (status === 'Died') { + Object.assign(extraColumns, { + death_date: 'Death Date', + cause_of_death: 'Cause of Death' + }); + } else if (status === 'Transferred Out') { + Object.assign(extraColumns, { + transfer_out_date_v1: 'Transfer out date' + }); + } + for (const indicator in extraColumns) { + if (indicator) { + this.extraColumns.push({ + headerName: extraColumns[indicator], + field: indicator + }); + } + } + + this.overrideColumns.push( + { + field: 'identifiers', + cellRenderer: (column) => { + return ( + '' + + column.value + + '' + ); + } + }, + { + field: 'last_appointment', + width: 200 + }, + { + field: 'cur_prep_meds_names', + width: 160 + } + ); + } + + public goBack() { + this._location.back(); + } +} diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.css b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.html b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.html new file mode 100644 index 000000000..01883f94c --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.html @@ -0,0 +1,54 @@ +

+ AHD Report +

+ +
+ Loading... +
+ + +
+ + + + +
+
+ +
+ × +

+ An + error occurred while trying to load the report. Please try again. +

+

+ {{ errorMessage }} +

+
+
+ Viewing a Draft Version of the Report for the chosen month. + This report is likely to change without warning. +
+
+ + + + + +
diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.spec.ts b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.spec.ts new file mode 100644 index 000000000..9a365e22f --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AhdReportBaseComponent } from './ahd-report-base.component'; + +describe('AhdReportBaseComponent', () => { + let component: AhdReportBaseComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [AhdReportBaseComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AhdReportBaseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.ts b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.ts new file mode 100644 index 000000000..f8d1aaba3 --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-base/ahd-report-base.component.ts @@ -0,0 +1,162 @@ +import { Component, OnInit, Output } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import * as _ from 'lodash'; +import * as Moment from 'moment'; +import { AhdResourceService } from 'src/app/etl-api/ahd-resource.service'; +@Component({ + selector: 'app-ahd-report-base', + templateUrl: './ahd-report-base.component.html', + styleUrls: ['./ahd-report-base.component.css'] +}) +export class AhdReportBaseComponent implements OnInit { + @Output() + public params: any; + public indicators: string; + public selectedIndicators = []; + public ahdReportSummaryData: any = []; + public columnDefs: any = []; + public reportName = 'Ahd Report'; + public currentView = 'monthly'; + public currentViewBelow = 'pdf'; + public month: string; + + public statusError = false; + public errorMessage = ''; + public showInfoMessage = false; + public isLoading = false; + public reportHead: any; + public pinnedBottomRowData: any = []; + public enabledControls = 'monthControl'; + public _month: string; + public isReleased = true; + + public _locationUuids: any = []; + public get locationUuids(): Array { + return this._locationUuids; + } + + public set locationUuids(v: Array) { + const locationUuids = []; + _.each(v, (location: any) => { + if (location.value) { + locationUuids.push(location); + } + }); + this._locationUuids = locationUuids; + } + + constructor( + public router: Router, + public route: ActivatedRoute, + public ahdReport: AhdResourceService + ) { + this.route.queryParams.subscribe((data) => { + data.month === undefined + ? (this._month = Moment() + .subtract(1, 'M') + .endOf('month') + .format('YYYY-MM-DD')) + : (this._month = data.month); + + this.showDraftReportAlert(this._month); + }); + } + + ngOnInit() {} + + public onMonthChange(value): any { + this._month = Moment(value).endOf('month').format('YYYY-MM-DD'); + } + + public generateReport() { + this.route.parent.parent.params.subscribe((params: any) => { + this.storeParamsInUrl(params.location_uuid); + }); + this.ahdReportSummaryData = []; + this.getAhdMonthlyReport(this.params); + } + + public storeParamsInUrl(param) { + this.params = { + locationUuids: param, + _month: Moment(this._month).endOf('month').format('YYYY-MM-DD'), + month: Moment(this._month).endOf('month').format('YYYY-MM-DD'), + reportName: this.reportName, + _date: Moment(this._month).format('DD-MM-YYYY') + }; + this.router.navigate([], { + relativeTo: this.route, + queryParams: this.params + }); + } + public getAhdMonthlyReport(params: any) { + this.isLoading = true; + this.ahdReport.getAhdMonthlyReport(params).subscribe((data) => { + if (data.error) { + this.showInfoMessage = true; + this.errorMessage = `There has been an error while loading the report, please retry again`; + this.isLoading = false; + } else { + this.showInfoMessage = false; + this.columnDefs = data.sectionDefinitions; + this.ahdReportSummaryData = data.result; + this.calculateTotalSummary(); + this.isLoading = false; + this.showDraftReportAlert(this._month); + } + }); + } + + public calculateTotalSummary() { + const totalsRow = []; + if (this.ahdReportSummaryData.length > 0) { + const totalObj = { + location: 'Totals' + }; + _.each(this.ahdReportSummaryData, (row) => { + Object.keys(row).map((key) => { + if (Number.isInteger(row[key]) === true) { + if (totalObj[key]) { + totalObj[key] = row[key] + totalObj[key]; + } else { + totalObj[key] = row[key]; + } + } else { + if (Number.isNaN(totalObj[key])) { + totalObj[key] = 0; + } + if (totalObj[key] === null) { + totalObj[key] = 0; + } + totalObj[key] = 0 + totalObj[key]; + } + }); + }); + totalObj.location = 'Totals'; + totalsRow.push(totalObj); + this.pinnedBottomRowData = totalsRow; + } + } + public onIndicatorSelected(value) { + console.log('value', value); + this.router.navigate(['patient-list'], { + relativeTo: this.route, + queryParams: { + indicators: value.field, + indicatorHeader: value.headerName, + indicatorGender: value.gender, + month: Moment(this._month).endOf('month').format('YYYY-MM-DD'), + locationUuids: value.location, + currentView: this.currentView + } + }); + } + + public showDraftReportAlert(date) { + if (date != null && date >= Moment().endOf('month').format('YYYY-MM-DD')) { + this.isReleased = false; + } else { + this.isReleased = true; + } + } +} diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.css b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.css new file mode 100644 index 000000000..24561dab6 --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.css @@ -0,0 +1,87 @@ +table { + width: 100%; + table-layout: auto; + white-space: nowrap; + border-collapse: separate; + margin: 5px; +} + +.header { + background-color: #337ab7; + color: white; + font-weight: bold; +} + +td { + padding: 10px; + border: 1px solid #090909; + text-align: centre; + font-size: auto; +} +th { + padding: 10px; + border: 1px solid #090909; + text-align: left; + font-size: 11px; +} +.first { + padding: 10px; + position: absolute; + border: 1px solid #090909; + text-align: left; + font-size: 18px; +} +.labels tr td { + background-color: #2cc16a; + font-weight: bold; + color: #fff; +} + +.label tr td label { + display: block; +} +caption { + padding-top: inherit; + padding-bottom: 8px; + color: #ffffff; + background: #3498db; + font-size: medium; + font-weight: bold; + text-align: center; +} + +[data-toggle='toggle'] { + display: none; +} +.value { + cursor: pointer; +} +.value:hover { + background-color: #337ab7a8; + color: white; +} +.padding { + margin: 2.5px; +} + +td, +th { + margin: 0; + border: 1px solid grey; + white-space: pre-line; + border-top-width: 0px; +} + +.headcol { + position: absolute; + width: 2em; + left: 0; + top: auto; + border-top-width: 1px; + /*only relevant for first row*/ + margin-top: -1px; + /*compensate for top border*/ +} +.table-content-class { + overflow-x: scroll; +} diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.html b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.html new file mode 100644 index 000000000..ef150b266 --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.html @@ -0,0 +1,240 @@ +
+
+
+ + + {{ reportDetails.reportName }} +
+ +
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + +
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{ grid.headerName }} +
Location{{ val.value[0] }} + Total +
< 15> 15
FMFM
+ +   {{ col.refno }} + + +   {{ col.headerName }} + + {{ val.value[0] }} + + {{ val.value[1] }} + + {{ val.value[2] }} + + {{ val.value[3] }} + + {{ col.total.value }} +
Facility Total + {{ val.value[0] }} + + {{ col.total.value }} +
+
+
+
+
+
+
diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.spec.ts b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.spec.ts new file mode 100644 index 000000000..bef6a4b66 --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AhdReportViewComponent } from './ahd-report-view.component'; + +describe('AhdReportViewComponent', () => { + let component: AhdReportViewComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [AhdReportViewComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AhdReportViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.ts b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.ts new file mode 100644 index 000000000..1c7caf2e9 --- /dev/null +++ b/src/app/hiv-care-lib/ahd-monthly-report/ahd-report-view/ahd-report-view.component.ts @@ -0,0 +1,494 @@ +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + OnChanges, + SimpleChanges +} from '@angular/core'; +import * as pdfMake from 'pdfmake/build/pdfmake.js'; +import { Observable, Subject } from 'rxjs'; +import { first, take } from 'rxjs/operators'; +import { SafeResourceUrl, DomSanitizer } from '@angular/platform-browser'; +import { PDFDocumentProxy } from 'pdfjs-dist'; +import * as _ from 'lodash'; +import { CollapseDirective } from 'ngx-bootstrap'; +@Component({ + selector: 'app-ahd-report-view', + templateUrl: './ahd-report-view.component.html', + styleUrls: ['./ahd-report-view.component.css'] +}) +export class AhdReportViewComponent implements OnInit { + @Input() SummaryData = []; + @Input() sectionDefs: any; + @Input() reportDetails: any = []; + @Input() reportHeader: any; + + @Output() + public indicatorSelected = new EventEmitter(); + private _rowDefs: Array; + public test = []; + public gridOptions: any = { + columnDefs: [] + }; + public pdfvalue: any; + public pdfSrc: string = null; + public isBusy = false; + public multipleLocations = false; + public headers = []; + public sectionIndicatorsValues: Array; + public pdfWidth = 1; + public page = 1; + public selectedResult: string; + public selectedIndicatorsList = []; + public errorFlag = false; + public securedUrl: SafeResourceUrl; + public pdfProxy: PDFDocumentProxy = null; + public pdfMakeProxy: any = null; + + @Output() + public CellSelection = new EventEmitter(); + constructor(private domSanitizer: DomSanitizer) {} + + ngOnInit() {} + // tslint:disable-next-line: use-life-cycle-interface + public ngOnChanges(changes: SimpleChanges) { + if (changes.SummaryData) { + this.sectionIndicatorsValues = this.SummaryData; + + this.setColumns(this.sectionDefs); + } + } + public setColumns(sectionsData: Array) { + this.headers = []; + const defs = []; + let sumOfValue = []; + let locations = []; + + for (let i = 0; i < sectionsData.length; i++) { + const section = sectionsData[i]; + const created: any = {}; + created.headerName = section.sectionTitle; + const header = { + label: section.sectionTitle, + value: i + }; + this.headers.push(header); + created.children = []; + + for (let j = 0; j < section.indicators.length; j++) { + const indicator = section.indicators[j]; + const isArrayIndicator = Array.isArray(indicator.indicator); + let u15_f_indicatorDefinition, + u15_m_indicatorDefinition, + o15_f_indicatorDefinition, + o15_m_indicatorDefinition, + totalDefinition, + percentageDefinition; + + if (isArrayIndicator) { + u15_f_indicatorDefinition = indicator.indicator[0]; + u15_m_indicatorDefinition = indicator.indicator[1]; + o15_f_indicatorDefinition = indicator.indicator[2]; + o15_m_indicatorDefinition = indicator.indicator[3]; + totalDefinition = indicator.indicator[4]; + percentageDefinition = indicator.indicator[5]; + } else { + totalDefinition = indicator.indicator; + } + + const child: any = { + headerName: indicator.label, + refno: indicator.refno, + field: indicator.indicator, + description: indicator.description, + value: [], + width: 360, + total: 0 + }; + + this.sectionIndicatorsValues.forEach((element) => { + const val = { + location: element['location_uuid'], + mfl_code: element['mfl_code'], + county: element['county'], + facility: element['facility'], + value: ['-', '-', '-', '-', '-', '-'] + }; + if (isArrayIndicator) { + if ( + (element[u15_m_indicatorDefinition] || + element[u15_m_indicatorDefinition] === 0) && + (element[u15_f_indicatorDefinition] || + element[u15_f_indicatorDefinition] === 0) && + (element[o15_m_indicatorDefinition] || + element[o15_m_indicatorDefinition] === 0) && + (element[o15_f_indicatorDefinition] || + element[o15_f_indicatorDefinition] === 0) + ) { + val.value[0] = element[u15_f_indicatorDefinition]; + val.value[1] = element[u15_m_indicatorDefinition]; + val.value[2] = element[o15_f_indicatorDefinition]; + val.value[3] = element[o15_m_indicatorDefinition]; + // val.value[4] = element[totalDefinition]; + // val.value[5] = element[percentageDefinition]; + + sumOfValue.push(val.value[0]); + sumOfValue.push(val.value[1]); + sumOfValue.push(val.value[2]); + sumOfValue.push(val.value[3]); + // sumOfValue.push(val.value[4]); + // sumOfValue.push(val.value[5]); + locations.push(element['location_uuid']); + } + + child.value.push(val); + } else { + if (element[totalDefinition] || element[totalDefinition] === 0) { + val.value[0] = element[totalDefinition]; + sumOfValue.push(val.value[0]); + locations.push(element['location_uuid']); + } + + child.value.push(val); + } + }); + + if (this.sectionIndicatorsValues.length > 0) { + this.multipleLocations = true; + + this.pdfWidth = 2; + + const sum = sumOfValue.reduce((partial_sum, a) => partial_sum + a, 0); + + if (_.isString(sum)) { + child.total = { + location: locations, + value: 'Total' + }; + } else { + child.total = { + location: locations, + value: sum + }; + } + + sumOfValue = []; + locations = []; + } + + created.children.push(child); + } + + defs.push(created); + } + + this.gridOptions.columnDefs = defs; + } + public setCellSelection(col, val, arrayPosition, grid) { + const gender = `${grid.headerName} - ${this.checkGender(arrayPosition)}`; + + const arraypos = arrayPosition; + + const selectedIndicator = { + headerName: col.headerName, + field: col.field[arraypos], + gender: gender, + location: this.reportDetails.locationUuids + }; + this.CellSelection.emit(selectedIndicator); + } + public checkGender(arrayPosition) { + if (arrayPosition === 0) { + return 'Female'; + } else if (arrayPosition === 1) { + return 'Male'; + } else if (arrayPosition === 3) { + return 'Facility'; + } else { + return 'Cummulative'; + } + } + public searchIndicator() { + this.setColumns(this.sectionDefs); + if (this.selectedResult.length > 0) { + this.gridOptions.columnDefs.forEach((object) => { + const make = { + headerName: '', + children: [] + }; + object.children.forEach((object2) => { + if ( + object2['headerName'].toLowerCase().match(this.selectedResult) !== + null + ) { + make.headerName = object['headerName']; + make.children.push(object2); + } + }); + if (make.headerName !== '') { + this.test.push(make); + } + }); + this.gridOptions.columnDefs = []; + this.gridOptions.columnDefs = this.test; + this.test = []; + } else { + this.setColumns(this.sectionDefs); + } + } + public selectedIndicators() { + this.setColumns(this.sectionDefs); + const value = []; + if (this.selectedIndicatorsList.length) { + this.selectedIndicatorsList.forEach((indicator) => { + value.push(this.gridOptions.columnDefs[indicator]); + }); + this.gridOptions.columnDefs = value; + } else { + this.setColumns(this.sectionDefs); + } + } + public downloadCSV() { + const title = this.reportHeader; + const array = JSON.parse(JSON.stringify(this.gridOptions.columnDefs)); + const regex = /TX_MMD|TX_ML/; + + const data = []; + array[0].children[0].value.forEach(function (item, index) { + array.slice(1).forEach(function (filteredItem, index1) { + const obj = {}; + obj['County'] = index1 === 0 ? item.county : ''; + obj['Clinic'] = index1 === 0 ? item.value[0] : ''; + obj['Facility'] = index1 === 0 ? item.facility : ''; + obj['Mfl Code'] = index1 === 0 ? item.mfl_code : ''; + if (regex.test(title)) { + obj['Indicator'] = filteredItem.headerName; + } + + filteredItem.children.forEach(function (ageSeg) { + if (!ageSeg.headerName.includes('Total')) { + obj[`${ageSeg.headerName} (Female)`] = Array.isArray( + ageSeg.value[index].value[0] + ) + ? JSON.stringify(ageSeg.value[index].value[0][0]) + : ageSeg.value[index].value[0]; + obj[`${ageSeg.headerName} (Male)`] = Array.isArray( + ageSeg.value[index].value[0] + ) + ? JSON.stringify(ageSeg.value[index].value[1][0]) + : ageSeg.value[index].value[1]; + } else { + obj[`${ageSeg.headerName}`] = Array.isArray( + ageSeg.value[index].value[0] + ) + ? JSON.stringify(ageSeg.value[index].value[0][0]) + : ageSeg.value[index].value[0]; + } + }); + data.push(obj); + }); + }); + + this.exportToCSV(data, title); + } + + public exportToCSV(data, title) { + let titleaddons; + if ( + this.reportDetails.year !== undefined && + this.reportDetails.year !== null + ) { + const { quarter, year } = this.reportDetails; + titleaddons = `${title} for ${quarter} - ${year}`; + } else { + const date = new Date(this.reportDetails.month); + const formattedDate = date.toLocaleString('en-US', { + month: 'long', + year: 'numeric' + }); + titleaddons = `${title} for ${formattedDate}`; + } + + const csvRows = []; + + // Add a blank row + csvRows.push(''); + + // Title row + csvRows.push(titleaddons); + + // Header row + const headers = Object.keys(data[0]); + csvRows.push(headers.join(',')); + + // Data rows + data.forEach((row) => { + const values = Object.values(row); + csvRows.push(values.join(',')); + }); + + // Combine rows into a single string + const csvString = csvRows.join('\n'); + + // Create a download link for the CSV file + const link = document.createElement('a'); + link.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csvString); + link.download = `${title}.csv`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + + public generatePdf(): Observable { + const width: any = ['*', '*']; + this.sectionIndicatorsValues.forEach((element) => { + width.push('*'); + }); + const dd: any = { + content: [ + { + text: this.reportDetails.reportName.toUpperCase(), + margin: [0, 20, 0, 8], + style: 'title' + }, + { + text: + this.reportDetails.year_week === undefined + ? this.reportDetails._date + : this.reportDetails.year_week, + margin: [0, 8, 0, 8], + style: 'title' + }, + { + style: 'tableExample', + table: { + headerRows: 2, + widths: width, + body: this.pdfvalue + }, + layout: { + fillColor: function (rowIndex, node, columnIndex) { + return rowIndex % 2 === 0 ? '#CCCCCC' : null; + } + } + } + ], + styles: { + header: { + fontSize: 12, + bold: true, + margin: [0, 0, 0, 10] + }, + total: { + fontSize: 9, + bold: true, + margin: [0, 10, 0, 5] + }, + title: { + fontSize: 8, + bold: true + }, + subheader: { + fontSize: 7, + bold: true, + margin: [0, 1, 0, 1] + }, + tableExample: { + fontSize: 9, + margin: [5, 0, 0, 5] + }, + tableHeader: { + bold: true, + fontSize: 10, + color: 'white' + } + }, + defaultStyle: { + // alignment: 'justify' + } + }; + if (this.sectionIndicatorsValues.length >= 10) { + dd.pageOrientation = 'landscape'; + } + const pdfStructure = dd; + return Observable.create((observer: Subject) => { + // JSON stringify and parse was done to handle a potential bug in pdfMake + const p = JSON.stringify(pdfStructure); + const x = JSON.parse(p); + const pdfProxy = pdfMake.createPdf(x); + pdfProxy.getBase64((output) => { + const int8Array: Uint8Array = this._base64ToUint8Array(output); + const blob = new Blob([int8Array], { + type: 'application/pdf' + }); + observer.next({ + pdfSrc: URL.createObjectURL(blob), + pdfDefinition: pdfStructure, + pdfProxy: pdfProxy + }); + }); + }).pipe(first()); + } + private _base64ToUint8Array(base64: any): Uint8Array { + const raw = atob(base64); + const uint8Array = new Uint8Array(raw.length); + for (let i = 0; i < raw.length; i++) { + uint8Array[i] = raw.charCodeAt(i); + } + return uint8Array; + } + public bodyValues() { + const body = []; + // let span = 0; + this.gridOptions.columnDefs.forEach((columnDefs) => { + const head = []; + const part = { + text: columnDefs.headerName, + style: 'tableHeader', + fillColor: '#337ab7', + colSpan: this.sectionIndicatorsValues.length + this.pdfWidth, + alignment: 'left' + }; + head.push(part); + body.push(head); + columnDefs.children.forEach((col) => { + const sec = []; + const test = { + text: col.headerName, + style: 'subheader', + alignment: 'left' + }; + sec.push(test); + col.value.forEach((element) => { + const value = { + text: element.value, + style: 'subheader', + alignment: 'center' + }; + sec.push(value); + }); + if (this.multipleLocations) { + sec.push({ + text: col.total.value, + style: 'title', + alignment: 'centre' + }); + } + body.push(sec); + }); + }); + return body; + } + + public nextPage(): void { + this.page++; + } + public prevPage(): void { + this.page--; + } + public downloadPdfView(): void { + this.pdfMakeProxy.download(this.reportDetails.reportName + '.pdf'); + } +} diff --git a/src/app/hiv-care-lib/hiv-care-lib.module.ts b/src/app/hiv-care-lib/hiv-care-lib.module.ts index e45a9b00b..a8c45d4f9 100644 --- a/src/app/hiv-care-lib/hiv-care-lib.module.ts +++ b/src/app/hiv-care-lib/hiv-care-lib.module.ts @@ -142,6 +142,9 @@ import { TxMmdReportBaseComponent } from './tx-mmd-report/tx-mmd-report-base/tx- import { TxMmdReportPatientListComponent } from './tx-mmd-report/tx-mmd-report-patient-list/tx-mmd-report-patient-list.component'; import { TxRttReportBaseComponent } from './tx-rtt-report/tx-rtt-report-base/tx-rtt-report-base.component'; import { TxRttReportPatientListComponent } from './tx-rtt-report/tx-rtt-report-patient-list/tx-rtt-report-patient-list.component'; +import { AhdReportBaseComponent } from './ahd-monthly-report/ahd-report-base/ahd-report-base.component'; +import { AhdReportViewComponent } from './ahd-monthly-report/ahd-report-view/ahd-report-view.component'; +import { AhdMonthlyReportPatientlistComponent } from './ahd-monthly-report/ahd-monthly-report-patientlist/ahd-monthly-report-patientlist.component'; import { PlhivNcdV2ReportBaseComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v2-report-base/plhiv-ncd-v2-report-base.component'; import { PlhivNcdV2ReportPatientListComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v2-report-patient-list/plhiv-ncd-v2-report-patient-list.component'; import { PlhivNcdV2ReportViewComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v2-report-view/plhiv-ncd-v2-report-view.component'; @@ -247,6 +250,7 @@ import { PlhivNcdV2ReportViewComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v Covid19TabularViewComponent, PrepMonthlyReportViewComponent, TxMlReportViewComponent, + AhdReportViewComponent, PlhivNcdV2ReportViewComponent ], declarations: [ @@ -339,6 +343,9 @@ import { PlhivNcdV2ReportViewComponent } from './plhiv-ncd-v2-report/plhiv-ncd-v TxMmdReportPatientListComponent, TxRttReportBaseComponent, TxRttReportPatientListComponent, + AhdReportBaseComponent, + AhdReportViewComponent, + AhdMonthlyReportPatientlistComponent, PlhivNcdV2ReportBaseComponent, PlhivNcdV2ReportPatientListComponent, PlhivNcdV2ReportViewComponent diff --git a/src/app/hiv-care-lib/monthly-report/monthly-report.component.ts b/src/app/hiv-care-lib/monthly-report/monthly-report.component.ts index 2664dca0c..5f0060722 100644 --- a/src/app/hiv-care-lib/monthly-report/monthly-report.component.ts +++ b/src/app/hiv-care-lib/monthly-report/monthly-report.component.ts @@ -50,6 +50,12 @@ export class MonthlyReportComponent implements OnInit { url: 'covid-19-monthly-report', icon: 'fa' }, + { + title: 'AHD Monthly Report', + description: '', + url: 'ahd-monthly-report', + icon: 'fa' + }, { title: 'PLHIV NCD Monthly Report', description: '', diff --git a/src/app/navigation/side-navigation/patient-side-nav/patient-side-nav-routes.factory.ts b/src/app/navigation/side-navigation/patient-side-nav/patient-side-nav-routes.factory.ts index 523d713bf..424b6d435 100644 --- a/src/app/navigation/side-navigation/patient-side-nav/patient-side-nav-routes.factory.ts +++ b/src/app/navigation/side-navigation/patient-side-nav/patient-side-nav-routes.factory.ts @@ -17,7 +17,7 @@ export class PatientRoutesFactory { patientRoutesConfig = this.processSharedRoutes(patientRoutesConfig); const routes: RouteModel[] = []; - if (Moment().diff(Moment(patient.person.birthdate), 'months') <= 18) { + if (patient.enrolledPrograms[26].isEnrolled) { patientRoutesConfig.sharedRoutes.hiv[3] = { url: 'hiv-summary', label: 'HEI Summary', diff --git a/version.js b/version.js index 6fccff0ad..d77de4a1a 100644 --- a/version.js +++ b/version.js @@ -17,4 +17,4 @@ export const VERSION = ${JSON.stringify(gitInfo, null, 4)}; /* tslint:enable */ `, { encoding: 'utf-8' }); -console.log(`Wrote version info ${gitInfo.raw} to ${relative(resolve(__dirname, '..'), file)}`); \ No newline at end of file +console.log(`Wrote version info ${gitInfo.raw} to ${relative(resolve(__dirname, '..'), file)}`);