diff --git a/packages/esm-admin-app/src/components/facility-setup/facility-info.component.tsx b/packages/esm-admin-app/src/components/facility-setup/facility-info.component.tsx new file mode 100644 index 00000000..02c4a44b --- /dev/null +++ b/packages/esm-admin-app/src/components/facility-setup/facility-info.component.tsx @@ -0,0 +1,82 @@ +import React from 'react'; +import { + StructuredListWrapper, + StructuredListHead, + StructuredListRow, + StructuredListCell, + StructuredListBody, +} from '@carbon/react'; +import { useFrontendModules } from '../hook/useFrontendModules'; +import { useDefaultFacility, useSystemSetting } from '../hook/useSystemSetting'; +import styles from './facility-info.scss'; + +const FacilityInfo: React.FC = () => { + const installedModules = useFrontendModules(); + const { defaultFacility, error, isLoading: defaultFacilityLoading } = useDefaultFacility(); + const { mflCodeResource } = useSystemSetting('facility.mflcode'); + const mflCode = mflCodeResource ? `(${mflCodeResource?.value ?? ''})` : ''; + let facilityData = { + mflCode: mflCode || 'N/A', + shaStatus: 'N/A', + name: defaultFacility?.display || 'N/A', + kephLevel: 'N/A', + operationalStatus: defaultFacility?.operationalStatus || 'N/A', + shaContracted: defaultFacility?.shaContracted || 'N/A', + expiryDate: defaultFacility?.shaFacilityExpiryDate || 'N/A', + location1: 'N/A', + location2: 'N/A', + }; + return ( +
+ + + + Property + Value + + + + + + Facility Name + {facilityData.name || 'N/A'} + + + Facility KMHFR Code + {facilityData.mflCode || 'N/A'} + + + Keph Level + {facilityData.kephLevel || 'N/A'} + + + Operational Status + {facilityData.operationalStatus || 'N/A'} + + + SHA Status + {facilityData.shaStatus || 'N/A'} + + + SHA Contracted + {facilityData.shaContracted || 'N/A'} + + + SHA Expiry Date + {facilityData.expiryDate || 'N/A'} + + + Location 1 + {facilityData.location1 || 'N/A'} + + + Location 2 + {facilityData.location2 || 'N/A'} + + + +
+ ); +}; + +export default FacilityInfo; diff --git a/packages/esm-admin-app/src/components/facility-setup/facility-info.scss b/packages/esm-admin-app/src/components/facility-setup/facility-info.scss new file mode 100644 index 00000000..caa326fc --- /dev/null +++ b/packages/esm-admin-app/src/components/facility-setup/facility-info.scss @@ -0,0 +1,42 @@ +@use '@carbon/layout'; +@use '@carbon/type'; +@use '@carbon/colors'; + +.omrs-main-content { + background-color: white; +} + +.bottomBorder{ + margin-bottom: layout.$spacing-05; +} + +.btnLayer { + display: flex; + padding-top: layout.$spacing-05; + padding-right: layout.$spacing-05; + padding-bottom: layout.$spacing-05; + margin-top: layout.$spacing-05; + flex-direction: row; + justify-content: flex-end; + background-color: white; + width: 100%; +} + +.tableLayer { + padding-left: layout.$spacing-05; + padding-right: layout.$spacing-05; + background: white; + padding-top: layout.$spacing-01; +} + +.loading { + display: flex; + padding-top: layout.$spacing-05; + padding-right: layout.$spacing-05; + padding-bottom: layout.$spacing-05; + margin-top: layout.$spacing-05; + flex-direction: row; + justify-content: flex-end; + background-color: white; + width: 100%; +} diff --git a/packages/esm-admin-app/src/components/facility-setup/facility-setup.component.tsx b/packages/esm-admin-app/src/components/facility-setup/facility-setup.component.tsx new file mode 100644 index 00000000..ee5d00b6 --- /dev/null +++ b/packages/esm-admin-app/src/components/facility-setup/facility-setup.component.tsx @@ -0,0 +1,40 @@ +import React, { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Layer, Button, MenuItem, InlineLoading } from '@carbon/react'; +import styles from './facility-setup.scss'; +import { showModal, showSnackbar } from '@openmrs/esm-framework'; +import FacilitySetupHeader from './header/facility-setup-header.component'; +import FrontendModule from './facility-info.component'; + +const FacilitySetup: React.FC = () => { + const { t } = useTranslation(); + const [isLoading, setIsLoading] = useState(false); + const [logData, setLogData] = useState>([]); + const [isRefreshing, setIsRefreshing] = useState(false); + + return ( +
+ + + {isLoading ? ( + + ) : ( + + )} + + + {/* */} + + +
+ ); +}; + +export default FacilitySetup; diff --git a/packages/esm-admin-app/src/components/facility-setup/facility-setup.scss b/packages/esm-admin-app/src/components/facility-setup/facility-setup.scss new file mode 100644 index 00000000..4407b7dd --- /dev/null +++ b/packages/esm-admin-app/src/components/facility-setup/facility-setup.scss @@ -0,0 +1,38 @@ +@use '@carbon/layout'; +@use '@carbon/type'; +@use '@carbon/colors'; + +.omrs-main-content { + background-color: white; +} + +.btnLayer { + display: flex; + padding-top: layout.$spacing-05; + padding-right: layout.$spacing-05; + padding-bottom: layout.$spacing-05; + margin-top: layout.$spacing-05; + flex-direction: row; + justify-content: flex-end; + background-color: white; + width: 100%; +} + +.tableLayer { + padding-left: layout.$spacing-05; + padding-right: layout.$spacing-05; + background: white; + padding-top: layout.$spacing-01; +} + +.loading { + display: flex; + padding-top: layout.$spacing-05; + padding-right: layout.$spacing-05; + padding-bottom: layout.$spacing-05; + margin-top: layout.$spacing-05; + flex-direction: row; + justify-content: flex-end; + background-color: white; + width: 100%; +} diff --git a/packages/esm-admin-app/src/components/facility-setup/header/facility-setup-header.component.tsx b/packages/esm-admin-app/src/components/facility-setup/header/facility-setup-header.component.tsx new file mode 100644 index 00000000..d35d03f4 --- /dev/null +++ b/packages/esm-admin-app/src/components/facility-setup/header/facility-setup-header.component.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Calendar, Location, UserFollow } from '@carbon/react/icons'; +import { formatDate, useSession, PageHeader, ServiceQueuesPictogram } from '@openmrs/esm-framework'; +import styles from './facility-setup-header.scss'; + +interface HeaderProps { + title: string; +} + +const FacilitySetupHeader: React.FC = ({ title }) => { + const { t } = useTranslation(); + const session = useSession(); + const location = session?.sessionLocation?.display; + + return ( +
+
+ +
+

{t('facility', 'Facility')}

+

{title}

+
+
+
+
+

{session?.user?.person?.display}

+ +
+
+ + {location} + · + + {formatDate(new Date(), { mode: 'standard' })} +
+
+
+ ); +}; + +export default FacilitySetupHeader; diff --git a/packages/esm-admin-app/src/components/facility-setup/header/facility-setup-header.scss b/packages/esm-admin-app/src/components/facility-setup/header/facility-setup-header.scss new file mode 100644 index 00000000..7fe6873f --- /dev/null +++ b/packages/esm-admin-app/src/components/facility-setup/header/facility-setup-header.scss @@ -0,0 +1,90 @@ +@use '@carbon/layout'; +@use '@carbon/type'; +@use '@openmrs/esm-styleguide/src/vars' as *; + +.header { + @include type.type-style('body-compact-02'); + color: $text-02; + height: layout.$spacing-12; + background-color: $ui-02; + border-bottom: 1px solid $ui-03; + display: flex; + justify-content: space-between; + padding: layout.$spacing-05; +} + +.leftJustifiedItems { + display: flex; + flex-direction: row; + align-items: center; + cursor: pointer; + align-items: center; +} + +.rightJustifiedItems { + @include type.type-style('body-compact-02'); + color: $text-02; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.pageName { + @include type.type-style('heading-04'); +} + +.pageLabels { + margin: layout.$spacing-05; + + p:first-of-type { + margin-bottom: layout.$spacing-02; + } +} + +.dateAndLocation { + display: flex; + justify-content: flex-end; + align-items: center; +} + +.userContainer { + display: flex; + justify-content: flex-end; + gap: layout.$spacing-05; +} + +.value { + margin-left: layout.$spacing-02; +} + +.middot { + margin: 0 layout.$spacing-03; +} + +.view { + @include type.type-style('label-01'); +} + +// Overriding styles for RTL support +html[dir='rtl'] { + .date-and-location { + & > svg { + order: -1; + } + & > span:nth-child(2) { + order: -2; + } + } +} + +.userIcon { + fill: $ui-05; + margin: layout.$spacing-01; +} + +.svgContainer svg { + width: layout.$spacing-10; + height: layout.$spacing-10; + margin-right: layout.$spacing-06; + fill: var(--brand-03); +} diff --git a/packages/esm-admin-app/src/components/hook/useFrontendModules.tsx b/packages/esm-admin-app/src/components/hook/useFrontendModules.tsx new file mode 100644 index 00000000..c95ef428 --- /dev/null +++ b/packages/esm-admin-app/src/components/hook/useFrontendModules.tsx @@ -0,0 +1,13 @@ +import { useMemo } from 'react'; +import { FrontendModule } from '../../types'; + +export function useFrontendModules() { + return useMemo>(() => { + return (window.installedModules ?? []) + .filter((module) => Boolean(module) && Boolean(module[1])) + .map((module) => ({ + version: module[1].version, + name: module[0].substring(module[0].indexOf('/') + 1), + })); + }, [window.installedModules]); +} diff --git a/packages/esm-admin-app/src/components/hook/useSystemSetting.tsx b/packages/esm-admin-app/src/components/hook/useSystemSetting.tsx new file mode 100644 index 00000000..48ff8ee4 --- /dev/null +++ b/packages/esm-admin-app/src/components/hook/useSystemSetting.tsx @@ -0,0 +1,34 @@ +import { FetchResponse, OpenmrsResource, openmrsFetch, restBaseUrl, useSession } from '@openmrs/esm-framework'; +import useSWRImmutable from 'swr/immutable'; +import useSWR from 'swr'; +import { DefaultFacility } from '../../types'; + +export function useSystemSetting(key: string) { + const { data, isLoading } = useSWRImmutable<{ data: { results: Array } }>( + `/ws/rest/v1/systemsetting?q=${key}&v=full`, + openmrsFetch, + { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }, + ); + + const mflCodeResource = data?.data?.results?.find((resource) => resource.property === 'facility.mflcode'); + + return { mflCodeResource, isLoading }; +} + +export function useDefaultFacility() { + const { authenticated } = useSession(); + const url = `${restBaseUrl}/kenyaemr/default-facility`; + const { data, isLoading, error } = useSWR>( + authenticated ? url : null, + openmrsFetch, + {}, + ); + return { + isLoading, + defaultFacility: data?.data, + error, + }; +} diff --git a/packages/esm-admin-app/src/components/logs-table/operation-log-table.component.tsx b/packages/esm-admin-app/src/components/logs-table/operation-log-table.component.tsx index f572b80e..33e1fb5f 100644 --- a/packages/esm-admin-app/src/components/logs-table/operation-log-table.component.tsx +++ b/packages/esm-admin-app/src/components/logs-table/operation-log-table.component.tsx @@ -49,7 +49,7 @@ const LogTable: React.FC = ({ logData, isLoading }) => { return (
- +
{isLoading && logData.length === 0 ? ( { const spaBasePath = window.spaBase; @@ -26,6 +27,7 @@ const Root: React.FC = () => { } /> } /> } /> + } /> diff --git a/packages/esm-admin-app/src/routes.json b/packages/esm-admin-app/src/routes.json index ac04a8b0..64b48e9a 100755 --- a/packages/esm-admin-app/src/routes.json +++ b/packages/esm-admin-app/src/routes.json @@ -18,6 +18,11 @@ "component": "etlAdministrationLeftPannelLink", "name": "etl-administration-left-panel-link", "slot": "admin-left-panel-slot" + }, + { + "component": "facilitySetupLeftPanelLink", + "name": "facility-setup-left-panel-link", + "slot": "admin-left-panel-slot" } ], "workspaces": [ diff --git a/packages/esm-admin-app/src/types/index.ts b/packages/esm-admin-app/src/types/index.ts index ac81cd6d..a96cc114 100644 --- a/packages/esm-admin-app/src/types/index.ts +++ b/packages/esm-admin-app/src/types/index.ts @@ -10,3 +10,15 @@ export interface DashboardConfig { slot: string; title: string; } +export interface FrontendModule { + name: string; + version?: string; +} +export interface DefaultFacility { + locationId: number; + uuid: string; + display: string; + operationalStatus: string; + shaContracted: string; + shaFacilityExpiryDate: string; +} diff --git a/packages/esm-billing-app/translations/en.json b/packages/esm-billing-app/translations/en.json index 1744a06f..ef6aee76 100644 --- a/packages/esm-billing-app/translations/en.json +++ b/packages/esm-billing-app/translations/en.json @@ -82,7 +82,6 @@ "deleteBill": "Delete Bill", "description": "Description", "diagnoses": "Diagnoses", - "diagnosis": "Diagnosis", "discard": "Discard", "discardClaim": "Discard Claim", "discount": "Discount", @@ -120,13 +119,13 @@ "errorOnLine": "Error on line", "errorRetrievingHIESubscription": "Error retrieving HIE subscription", "exemptionCategory": "Exemption category", - "exemptionSchema": "Exemption Schema", "facility": "Facility", "failedBillPayment": "Bill payment failed", "failure": "Error loading intervensions", "filterBy": "Filter by", "filterByTimesheet": "Filter by timesheet", "filterTable": "Filter table", + "finalDiagnosis": "Final Diagnosis", "formTitle": "Fill in the form details", "generatedMessage": "The invoice has been electronically generated and is a valid document. It was created by {{userName}} on {{date}} at {{time}}", "guaranteeId": "Guarantee Id",