Skip to content

Commit

Permalink
Added facility setup page
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix Kiprotich committed Jan 15, 2025
1 parent b317d1d commit 5c62c26
Show file tree
Hide file tree
Showing 14 changed files with 406 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -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 (
<div className={styles.bottomBorder}>
<StructuredListWrapper>
<StructuredListHead>
<StructuredListRow head>
<StructuredListCell head>Property</StructuredListCell>
<StructuredListCell head>Value</StructuredListCell>
</StructuredListRow>
</StructuredListHead>

<StructuredListBody>
<StructuredListRow>
<StructuredListCell>Facility Name</StructuredListCell>
<StructuredListCell>{facilityData.name || 'N/A'}</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell>Facility KMHFR Code</StructuredListCell>
<StructuredListCell>{facilityData.mflCode || 'N/A'}</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell>Keph Level</StructuredListCell>
<StructuredListCell>{facilityData.kephLevel || 'N/A'}</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell>Operational Status</StructuredListCell>
<StructuredListCell>{facilityData.operationalStatus || 'N/A'}</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell>SHA Status</StructuredListCell>
<StructuredListCell>{facilityData.shaStatus || 'N/A'}</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell>SHA Contracted</StructuredListCell>
<StructuredListCell>{facilityData.shaContracted || 'N/A'}</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell>SHA Expiry Date</StructuredListCell>
<StructuredListCell>{facilityData.expiryDate || 'N/A'}</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell>Location 1</StructuredListCell>
<StructuredListCell>{facilityData.location1 || 'N/A'}</StructuredListCell>
</StructuredListRow>
<StructuredListRow>
<StructuredListCell>Location 2</StructuredListCell>
<StructuredListCell>{facilityData.location2 || 'N/A'}</StructuredListCell>
</StructuredListRow>
</StructuredListBody>
</StructuredListWrapper>
</div>
);
};

export default FacilityInfo;
Original file line number Diff line number Diff line change
@@ -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%;
}
Original file line number Diff line number Diff line change
@@ -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<Array<any>>([]);
const [isRefreshing, setIsRefreshing] = useState(false);

return (
<div className="omrs-main-content">
<FacilitySetupHeader title={t('facilitySetupTitle', 'Facility Setup')} />
<Layer className={styles.btnLayer}>
{isLoading ? (
<InlineLoading
description={t('synchronizingFacilityData', 'Please wait, Synchronizing Info.')}
size="md"
className={styles.loading}
withOverlay
/>
) : (
<Button kind="secondary" onClick={close}>
{t('synchronizeInfo', 'Synchronize Info')}
</Button>
)}
</Layer>
<Layer className={styles.tableLayer}>
{/* <LogTable logData={logData} isLoading={isRefreshing} /> */}
<FrontendModule />
</Layer>
</div>
);
};

export default FacilitySetup;
Original file line number Diff line number Diff line change
@@ -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%;
}
Original file line number Diff line number Diff line change
@@ -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<HeaderProps> = ({ title }) => {
const { t } = useTranslation();
const session = useSession();
const location = session?.sessionLocation?.display;

return (
<div className={styles.header} id="admin-header">
<div className={styles.leftJustifiedItems}>
<ServiceQueuesPictogram />
<div className={styles.pageLabels}>
<p>{t('facility', 'Facility')}</p>
<p className={styles.pageName}>{title}</p>
</div>
</div>
<div className={styles.rightJustifiedItems}>
<div className={styles.userContainer}>
<p>{session?.user?.person?.display}</p>
<UserFollow size={16} className={styles.userIcon} />
</div>
<div className={styles.dateAndLocation}>
<Location size={16} />
<span className={styles.value}>{location}</span>
<span className={styles.middot}>&middot;</span>
<Calendar size={16} />
<span className={styles.value}>{formatDate(new Date(), { mode: 'standard' })}</span>
</div>
</div>
</div>
);
};

export default FacilitySetupHeader;
Original file line number Diff line number Diff line change
@@ -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);
}
13 changes: 13 additions & 0 deletions packages/esm-admin-app/src/components/hook/useFrontendModules.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useMemo } from 'react';
import { FrontendModule } from '../../types';

export function useFrontendModules() {
return useMemo<Array<FrontendModule>>(() => {
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]);
}
34 changes: 34 additions & 0 deletions packages/esm-admin-app/src/components/hook/useSystemSetting.tsx
Original file line number Diff line number Diff line change
@@ -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<OpenmrsResource> } }>(
`/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<FetchResponse<DefaultFacility>>(
authenticated ? url : null,
openmrsFetch,
{},
);
return {
isLoading,
defaultFacility: data?.data,
error,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const LogTable: React.FC<LogTableProps> = ({ logData, isLoading }) => {

return (
<div className={styles.table}>
<CardHeader title={t('etlOperationLog', 'ETL Operations Log')} children={''} />
<CardHeader title={t('facilityInfo', 'Facility Info')} children={''} />
<div className={styles.logTable}>
{isLoading && logData.length === 0 ? (
<DataTableSkeleton
Expand Down
Loading

0 comments on commit 5c62c26

Please sign in to comment.