@ampath/esm-dha-workflow-app 4.0.0-next.28 → 4.0.0-next.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/710.js +1 -1
  2. package/dist/752.js +1 -1
  3. package/dist/752.js.map +1 -1
  4. package/dist/810.js +2 -0
  5. package/dist/{972.js.LICENSE.txt → 810.js.LICENSE.txt} +15 -0
  6. package/dist/810.js.map +1 -0
  7. package/dist/907.js +1 -1
  8. package/dist/907.js.map +1 -1
  9. package/dist/91.js +1 -1
  10. package/dist/91.js.map +1 -1
  11. package/dist/93.js +1 -1
  12. package/dist/93.js.map +1 -1
  13. package/dist/943.js +1 -0
  14. package/dist/943.js.map +1 -0
  15. package/dist/esm-dha-workflow-app.js +1 -1
  16. package/dist/esm-dha-workflow-app.js.buildmanifest.json +56 -56
  17. package/dist/main.js +1 -1
  18. package/dist/main.js.map +1 -1
  19. package/dist/routes.json +1 -1
  20. package/package.json +1 -1
  21. package/src/bookings/daily/daily-bookings.component.scss +38 -0
  22. package/src/bookings/daily/daily-bookings.component.tsx +138 -0
  23. package/src/bookings/daily/daily-bookings.resource.ts +27 -0
  24. package/src/bookings/daily/filters/daily-bookings-filter.component.scss +15 -0
  25. package/src/bookings/daily/filters/daily-bookings-filter.component.tsx +80 -0
  26. package/src/bookings/daily/patient-list/daily-bookings-patient-list.component.tsx +97 -0
  27. package/src/bookings/types/index.ts +68 -0
  28. package/src/config-schema.ts +19 -1
  29. package/src/index.ts +1 -1
  30. package/src/registry/registry.resource.ts +7 -4
  31. package/src/resources/patient-resource.ts +3 -1
  32. package/src/root.component.tsx +2 -0
  33. package/src/service-queues/service-queues.resource.ts +3 -2
  34. package/src/shared/constants/index.ts +1 -3
  35. package/src/shared/utils/get-base-url.ts +17 -0
  36. package/src/side-nav-menu/nav-link-config.ts +10 -0
  37. package/src/triage/triage.resource.ts +2 -2
  38. package/dist/105.js +0 -1
  39. package/dist/105.js.map +0 -1
  40. package/dist/972.js +0 -2
  41. package/dist/972.js.map +0 -1
@@ -0,0 +1,80 @@
1
+ import React, { useRef } from 'react';
2
+ import { Button, DatePicker, DatePickerInput, Dropdown, type OnChangeData } from '@carbon/react';
3
+ import styles from './daily-bookings-filter.component.scss';
4
+ import { type BookingFilter } from '../../types';
5
+ import { useSession } from '@openmrs/esm-framework';
6
+
7
+ interface DailyBookingsFilterProps {
8
+ filterSelected: (filters: BookingFilter) => void;
9
+ }
10
+ const DailyBookingsFilter: React.FC<DailyBookingsFilterProps> = ({ filterSelected }) => {
11
+ const dateRef = useRef<string>('');
12
+ const departmentRef = useRef<string>();
13
+ const session = useSession();
14
+ const locationUuid = session.sessionLocation.uuid;
15
+ const handleDateChange = (dateSelected: Date[]) => {
16
+ dateRef.current = new Date(dateSelected[0]).toISOString().split('T')[0];
17
+ };
18
+ const handleDepartmentChange = (selectedDept: OnChangeData<{ text: string }>) => {
19
+ departmentRef.current = selectedDept.selectedItem.text;
20
+ };
21
+ const handeleGenerateFilters = () => {
22
+ const filters: BookingFilter = {
23
+ startDate: dateRef.current,
24
+ department: departmentRef.current,
25
+ locationUuids: locationUuid,
26
+ };
27
+ filterSelected(filters);
28
+ };
29
+ return (
30
+ <>
31
+ <div className={styles.filterLayout}>
32
+ <div className={styles.filterRow}>
33
+ <div className={styles.filterFormGroup}>
34
+ <DatePicker
35
+ datePickerType="single"
36
+ locale="en"
37
+ onChange={handleDateChange}
38
+ onClose={() => {}}
39
+ onOpen={() => {}}
40
+ >
41
+ <DatePickerInput id="date-picker-single" labelText="Date" placeholder="mm/dd/yyyy" />
42
+ </DatePicker>
43
+ </div>
44
+ <div className={styles.filterFormGroup}>
45
+ <Dropdown
46
+ id="department"
47
+ invalidText="invalid selection"
48
+ itemToString={(item) => item.text}
49
+ onChange={handleDepartmentChange}
50
+ items={[
51
+ {
52
+ text: 'HIV',
53
+ },
54
+ {
55
+ text: 'CDM',
56
+ },
57
+ {
58
+ text: 'ONCOLOGY',
59
+ },
60
+ ]}
61
+ label="Select Department"
62
+ titleText="Department"
63
+ type="default"
64
+ warnText=""
65
+ />
66
+ </div>
67
+ </div>
68
+ <div className={styles.filterRow}>
69
+ <div className={styles.filterFormGroup}>
70
+ <Button kind="primary" onClick={handeleGenerateFilters}>
71
+ Generate
72
+ </Button>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </>
77
+ );
78
+ };
79
+
80
+ export default DailyBookingsFilter;
@@ -0,0 +1,97 @@
1
+ import React from 'react';
2
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@carbon/react';
3
+ import { type DailyBookingsResult } from '../../types';
4
+
5
+ interface DailiyBookingsPatientListProps {
6
+ patientListData: DailyBookingsResult[];
7
+ }
8
+ const DailiyBookingsPatientList: React.FC<DailiyBookingsPatientListProps> = ({ patientListData }) => {
9
+ if (!patientListData || patientListData.length === 0) {
10
+ return <>No Data</>;
11
+ }
12
+ return (
13
+ <>
14
+ <Table>
15
+ <TableHead>
16
+ <TableRow>
17
+ <TableHeader>No</TableHeader>
18
+ <TableHeader>CCC Number</TableHeader>
19
+ <TableHeader>UPI Number</TableHeader>
20
+ <TableHeader>Program</TableHeader>
21
+ <TableHeader>RTC Date</TableHeader>
22
+ <TableHeader>Med Pickup Date</TableHeader>
23
+ <TableHeader>ARV Start Date</TableHeader>
24
+ <TableHeader>HIV Disclosure Status</TableHeader>
25
+ <TableHeader>Height</TableHeader>
26
+ <TableHeader>Weight</TableHeader>
27
+ <TableHeader>Stage</TableHeader>
28
+ <TableHeader>Patient Categorization</TableHeader>
29
+ <TableHeader>Service Delivery Model</TableHeader>
30
+ <TableHeader>DSD Model</TableHeader>
31
+ <TableHeader>CD4 Date</TableHeader>
32
+ <TableHeader>CD4 Results</TableHeader>
33
+ <TableHeader>Gender</TableHeader>
34
+ <TableHeader>Birthdate</TableHeader>
35
+ <TableHeader>Age</TableHeader>
36
+ <TableHeader>Patient Name</TableHeader>
37
+ <TableHeader>Identifiers</TableHeader>
38
+ <TableHeader>Phone Number</TableHeader>
39
+ <TableHeader>Latest RTC Date</TableHeader>
40
+ <TableHeader>Latest VL</TableHeader>
41
+ <TableHeader>VL Category</TableHeader>
42
+ <TableHeader>Latest VL Date</TableHeader>
43
+ <TableHeader>Last Appointment</TableHeader>
44
+ <TableHeader>Visit Type</TableHeader>
45
+ <TableHeader>Current Meds</TableHeader>
46
+ <TableHeader>Covid-19 Vaccination</TableHeader>
47
+ <TableHeader>TB Screening Date</TableHeader>
48
+ <TableHeader>TB Screening Result</TableHeader>
49
+ <TableHeader>Patient Category</TableHeader>
50
+ </TableRow>
51
+ </TableHead>
52
+
53
+ <TableBody>
54
+ {patientListData &&
55
+ patientListData.map((val, index) => (
56
+ <TableRow key={val.patient_uuid ?? index}>
57
+ <TableCell>{index + 1}</TableCell>
58
+ <TableCell>{val.ccc_number}</TableCell>
59
+ <TableCell>{val.upi_number}</TableCell>
60
+ <TableCell>{val.program}</TableCell>
61
+ <TableCell>{val.rtc_date}</TableCell>
62
+ <TableCell>{val.med_pick_up_date}</TableCell>
63
+ <TableCell>{val.arv_first_regimen_start_date}</TableCell>
64
+ <TableCell>{val.hiv_disclosure_status}</TableCell>
65
+ <TableCell>{val.height}</TableCell>
66
+ <TableCell>{val.weight}</TableCell>
67
+ <TableCell>{val.stage}</TableCell>
68
+ <TableCell>{val.patient_categorization}</TableCell>
69
+ <TableCell>{val.service_delivery_model}</TableCell>
70
+ <TableCell>{val.dsd_model}</TableCell>
71
+ <TableCell>{val.cd4_date}</TableCell>
72
+ <TableCell>{val.cd4_results}</TableCell>
73
+ <TableCell>{val.gender}</TableCell>
74
+ <TableCell>{val.birthdate}</TableCell>
75
+ <TableCell>{val.age}</TableCell>
76
+ <TableCell>{val.person_name}</TableCell>
77
+ <TableCell>{val.identifiers}</TableCell>
78
+ <TableCell>{val.phone_number}</TableCell>
79
+ <TableCell>{val.latest_rtc_date}</TableCell>
80
+ <TableCell>{val.latest_vl}</TableCell>
81
+ <TableCell>{val.vl_category}</TableCell>
82
+ <TableCell>{val.latest_vl_date}</TableCell>
83
+ <TableCell>{val.last_appointment}</TableCell>
84
+ <TableCell>{val.visit_type}</TableCell>
85
+ <TableCell>{val.cur_meds}</TableCell>
86
+ <TableCell>{val.covid_19_vaccination_status}</TableCell>
87
+ <TableCell>{val.tb_screening_date}</TableCell>
88
+ <TableCell>{val.tb_screening_result}</TableCell>
89
+ <TableCell>{val.patient_category}</TableCell>
90
+ </TableRow>
91
+ ))}
92
+ </TableBody>
93
+ </Table>
94
+ </>
95
+ );
96
+ };
97
+ export default DailiyBookingsPatientList;
@@ -0,0 +1,68 @@
1
+ export type BookingFilter = {
2
+ startDate: string;
3
+ department: string;
4
+ locationUuids: string;
5
+ };
6
+
7
+ export type BookingDto = BookingFilter & {
8
+ startIndex: string;
9
+ limit: string;
10
+ };
11
+
12
+ export type DailyBookingsResult = {
13
+ ccc_number: string;
14
+ ovcid_id: string;
15
+ upi_number: string;
16
+ program: string;
17
+ rtc_date: string;
18
+ med_pick_up_date: string;
19
+ arv_first_regimen_start_date: string;
20
+ hiv_disclosure_status: string;
21
+ height: number;
22
+ weight: number;
23
+ stage: number;
24
+ patient_categorization: string;
25
+ service_delivery_model: string;
26
+ dsd_model: string;
27
+ cd4_date: string;
28
+ cd4_results: number;
29
+ patient_uuid: string;
30
+ gender: string;
31
+ birthdate: string;
32
+ age: number;
33
+ person_name: string;
34
+ identifiers: string;
35
+ phone_number: string;
36
+ latest_rtc_date: string;
37
+ latest_vl: number;
38
+ vl_category: string;
39
+ latest_vl_date: string;
40
+ last_appointment: string;
41
+ visit_type: string;
42
+ cur_meds: string;
43
+ previous_vl: number;
44
+ previous_vl_date: string;
45
+ nearest_center: string;
46
+ covid_19_vaccination_status: string;
47
+ sms_consent_provided: string;
48
+ sms_receive_time: string;
49
+ sms_delivery_status: string;
50
+ tb_screening_date: string;
51
+ patient_category: string;
52
+ tb_screening_result: string;
53
+ cervical_screening_date: string;
54
+ cervical_screening_method: string;
55
+ cervical_screening_result: string;
56
+ };
57
+
58
+ export type DailyBookingsReponse = {
59
+ schemas: any;
60
+ sqlQuery: string;
61
+ result: DailyBookingsResult[];
62
+ };
63
+
64
+ export enum DailyBookingType {
65
+ Appointments = 'daily-appointments',
66
+ Visits = 'daily-visits',
67
+ HasNotReturned = 'daily-has-not-returned',
68
+ }
@@ -1,7 +1,7 @@
1
1
  import { Type, validator } from '@openmrs/esm-framework';
2
2
 
3
3
  export const configSchema = {
4
- concepts: {
4
+ concepts: {
5
5
  defaultPriorityConceptUuid: {
6
6
  _type: Type.ConceptUuid,
7
7
  _default: false,
@@ -77,6 +77,21 @@ export const configSchema = {
77
77
  _default: '5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
78
78
  },
79
79
  },
80
+ subDomainUrl: {
81
+ _type: Type.String,
82
+ _description: 'Subdomain e.g training,staging',
83
+ _default: '',
84
+ },
85
+ etlBaseUrl: {
86
+ _type: Type.String,
87
+ _description: 'ETL Endpoint',
88
+ _default: '',
89
+ },
90
+ hieBaseUrl: {
91
+ _type: Type.String,
92
+ _description: 'HIE Endpoint',
93
+ _default: '',
94
+ },
80
95
  };
81
96
 
82
97
  export type Config = {
@@ -118,6 +133,9 @@ export interface ConfigObject {
118
133
  showRecommendedVisitTypeTab: boolean;
119
134
  visitQueueNumberAttributeUuid: string | null;
120
135
  visitTypeResourceUrl: string;
136
+ subDomainUrl: string;
137
+ etlBaseUrl: string;
138
+ hieBaseUrl: string;
121
139
  // vitals: VitalsConfigObject;
122
140
  }
123
141
 
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  import { getAsyncLifecycle, defineConfigSchema, getSyncLifecycle } from '@openmrs/esm-framework';
8
8
  import { configSchema } from './config-schema';
9
9
 
10
- const moduleName = '@ampath/openmrs-esm-home-app.js';
10
+ export const moduleName = '@ampath/esm-dha-workflow-app';
11
11
 
12
12
  const options = {
13
13
  featureName: 'Consulation Workflow',
@@ -1,4 +1,4 @@
1
- import { HIE_BASE_URL } from '../shared/constants';
1
+ import { getHieBaseUrl } from '../shared/utils/get-base-url';
2
2
  import {
3
3
  type ClientRegistrySearchRequest,
4
4
  type RequestCustomOtpDto,
@@ -25,7 +25,8 @@ async function postJson<T>(url: string, payload: unknown): Promise<T> {
25
25
  }
26
26
 
27
27
  export async function requestCustomOtp(payload: RequestCustomOtpDto): Promise<RequestCustomOtpResponse> {
28
- const url = `${HIE_BASE_URL}/client/send-custom-otp`;
28
+ const hieBaseUrl = await getHieBaseUrl();
29
+ const url = `${hieBaseUrl}/client/send-custom-otp`;
29
30
  const formattedPayload = {
30
31
  identificationNumber: payload.identificationNumber,
31
32
  identificationType: payload.identificationType,
@@ -35,7 +36,8 @@ export async function requestCustomOtp(payload: RequestCustomOtpDto): Promise<Re
35
36
  }
36
37
 
37
38
  export async function validateCustomOtp(payload: ValidateHieCustomOtpDto): Promise<ValidateCustomOtpResponse> {
38
- const url = `${HIE_BASE_URL}/client/validate-custom-otp`;
39
+ const hieBaseUrl = await getHieBaseUrl();
40
+ const url = `${hieBaseUrl}/client/validate-custom-otp`;
39
41
  const formattedPayload = {
40
42
  sessionId: payload.sessionId,
41
43
  otp: payload.otp,
@@ -47,7 +49,8 @@ export async function validateCustomOtp(payload: ValidateHieCustomOtpDto): Promi
47
49
  export async function fetchClientRegistryData(
48
50
  payload: ClientRegistrySearchRequest,
49
51
  ): Promise<ClientRegistrySearchResponse> {
50
- const url = `${HIE_BASE_URL}/client/search`;
52
+ const hieBaseUrl = await getHieBaseUrl();
53
+ const url = `${hieBaseUrl}/client/search`;
51
54
  const formattedPayload = {
52
55
  identificationNumber: payload.identificationNumber,
53
56
  identificationType: payload.identificationType,
@@ -2,6 +2,7 @@ import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
2
  import { type HieClient, type CreatePatientDto, HieIdentificationType } from '../registry/types';
3
3
  import { IdentifierTypesUuids } from './identifier-types';
4
4
  import { getAmrsIdentifierTypeUuid } from '../registry/utils/hie-client-adapter';
5
+ import { getSubDomainUrl } from '../shared/utils/get-base-url';
5
6
 
6
7
  export async function createPatient(payload: CreatePatientDto) {
7
8
  return await openmrsFetch(`${restBaseUrl}/patient`, {
@@ -44,8 +45,9 @@ export function generateAmrsCreatePatientIdentifiersPayload(hieClient: HieClient
44
45
  }
45
46
 
46
47
  export async function generateAmrsUniversalIdentifier() {
48
+ const subDomainUrl = await getSubDomainUrl();
47
49
  const abortController = new AbortController();
48
- const resp = await openmrsFetch(`https://staging.ampath.or.ke/amrs-id-generator/generateidentifier`, {
50
+ const resp = await openmrsFetch(`${subDomainUrl}/amrs-id-generator/generateidentifier`, {
49
51
  headers: {
50
52
  'Content-Type': 'application/json',
51
53
  },
@@ -11,6 +11,7 @@ import PharmacyComponent from './pharmacy/pharmacy.component';
11
11
  import Consultation from './service-queues/consultation/consultation.component';
12
12
  import Dashboard from './dashboard/dashboard.component';
13
13
  import AccountingComponent from './accounting/accounting.component';
14
+ import DailyBookings from './bookings/daily/daily-bookings.component';
14
15
 
15
16
  const Root: React.FC = () => {
16
17
  const spaBasePath = window.spaBase;
@@ -32,6 +33,7 @@ const Root: React.FC = () => {
32
33
  <Route path="pharmacy" element={<PharmacyComponent />} />
33
34
  <Route path="appointments" element={<AppointmentsComponent />} />
34
35
  <Route path="accounting" element={<AccountingComponent />} />
36
+ <Route path="bookings/daily" element={<DailyBookings />} />
35
37
  <Route path="*" element={<RegistryComponent />} />
36
38
  </Routes>
37
39
  </main>
@@ -9,8 +9,8 @@ import {
9
9
  import dayjs from 'dayjs';
10
10
  import useSWR from 'swr';
11
11
  import { useMemo } from 'react';
12
- import { ETL_BASE_URL } from '../shared/constants';
13
12
  import { type QueueEntryResult } from '../registry/types';
13
+ import { getEtlBaseUrl } from '../shared/utils/get-base-url';
14
14
 
15
15
  export function serveQueueEntry(servicePointName: string, ticketNumber: string, status: string) {
16
16
  const abortController = new AbortController();
@@ -148,7 +148,8 @@ export async function getServiceQueueByLocationUuid(
148
148
  serviceUuid: string,
149
149
  locationUuid: string,
150
150
  ): Promise<QueueEntryResult[]> {
151
- const queueEntryUrl = `${ETL_BASE_URL}/queue-entry`;
151
+ const etlBaseUrl = await getEtlBaseUrl();
152
+ const queueEntryUrl = `${etlBaseUrl}/queue-entry`;
152
153
  const params = {
153
154
  locationUuid: locationUuid,
154
155
  serviceUuid: serviceUuid,
@@ -1,3 +1 @@
1
- export const HIE_BASE_URL = 'https://staging.ampath.or.ke/hie';
2
- export const OPENMRS_BASE_URL = 'https://staging.ampath.or.ke/openmrs/ws/rest/v1';
3
- export const ETL_BASE_URL = 'https://staging.ampath.or.ke/etl-staging/etl';
1
+
@@ -0,0 +1,17 @@
1
+ import { getConfig } from '@openmrs/esm-framework';
2
+ import { moduleName } from '../..';
3
+
4
+ export async function getSubDomainUrl() {
5
+ const { subDomainUrl } = await getConfig(moduleName);
6
+ return subDomainUrl ?? null;
7
+ }
8
+
9
+ export async function getEtlBaseUrl() {
10
+ const { etlBaseUrl } = await getConfig(moduleName);
11
+ return etlBaseUrl ?? null;
12
+ }
13
+
14
+ export async function getHieBaseUrl() {
15
+ const { hieBaseUrl } = await getConfig(moduleName);
16
+ return hieBaseUrl ?? null;
17
+ }
@@ -73,4 +73,14 @@ export const navLinksConfig = [
73
73
  to: 'bookings',
74
74
  title: 'Bookings',
75
75
  },
76
+ {
77
+ to: 'bookings',
78
+ title: 'Bookings',
79
+ children: [
80
+ {
81
+ to: 'daily',
82
+ title: 'Daily',
83
+ },
84
+ ],
85
+ },
76
86
  ];
@@ -1,10 +1,10 @@
1
1
  import useSWR from 'swr';
2
- import { openmrsFetch } from '@openmrs/esm-framework';
2
+ import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
3
3
 
4
4
  import { type Patient } from './types';
5
5
  export default function useTriagePatients(locationUuid: string) {
6
6
  const { data, error, isLoading } = useSWR(
7
- `https://staging.ampath.or.ke/openmrs/ws/rest/v1/queue-entry?v=custom:(uuid,display,queue:(display,uuid,location:(display,uuid)),status:(display),patient:(uuid,person:(gender,age)))&totalCount=true&isEnded=false&location=${locationUuid}`,
7
+ `${restBaseUrl}/queue-entry?v=custom:(uuid,display,queue:(display,uuid,location:(display,uuid)),status:(display),patient:(uuid,person:(gender,age)))&totalCount=true&isEnded=false&location=${locationUuid}`,
8
8
  (url: string) =>
9
9
  openmrsFetch<{
10
10
  results: Array<Patient>;