@kenyaemr/esm-patient-flags-app 5.4.4-pre.96 → 5.4.5-pre.16
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.
- package/package.json +3 -3
- package/src/hooks/useDefaultFacility.ts +17 -8
- package/src/navbar/nav-utils.component.tsx +17 -3
- package/src/navbar/navbar-action-button.component.tsx +4 -2
- package/src/navbar/navbar-action-button.scss +9 -0
- package/src/navbar/navbar-link.component.tsx +60 -26
- package/src/navbar/navbar-link.scss +38 -3
- package/src/navbar/navbar-overlay.component.tsx +44 -11
- package/src/patient-diagnosis/patient-diagnosis.component.tsx +2 -2
- package/src/routes.json +5 -0
- package/translations/am.json +6 -1
- package/translations/en.json +6 -1
- package/translations/fr.json +32 -39
- package/translations/sw.json +6 -1
- package/.turbo/turbo-build.log +0 -6
- package/dist/1074.js +0 -1
- package/dist/1074.js.map +0 -1
- package/dist/12.js +0 -17
- package/dist/12.js.map +0 -1
- package/dist/1311.js +0 -1
- package/dist/1311.js.map +0 -1
- package/dist/1469.js +0 -1
- package/dist/1469.js.map +0 -1
- package/dist/1506.js +0 -13
- package/dist/1506.js.map +0 -1
- package/dist/1718.js +0 -1
- package/dist/1718.js.map +0 -1
- package/dist/1772.js +0 -1
- package/dist/1772.js.map +0 -1
- package/dist/1889.js +0 -1
- package/dist/1889.js.map +0 -1
- package/dist/1990.js +0 -1
- package/dist/1990.js.map +0 -1
- package/dist/2153.js +0 -1
- package/dist/2153.js.map +0 -1
- package/dist/216.js +0 -1
- package/dist/216.js.map +0 -1
- package/dist/2270.js +0 -1
- package/dist/2270.js.map +0 -1
- package/dist/2294.js +0 -1
- package/dist/2294.js.map +0 -1
- package/dist/2345.js +0 -1
- package/dist/2345.js.map +0 -1
- package/dist/2500.js +0 -1
- package/dist/2500.js.map +0 -1
- package/dist/251.js +0 -1
- package/dist/251.js.map +0 -1
- package/dist/2566.js +0 -1
- package/dist/257.js +0 -1
- package/dist/257.js.map +0 -1
- package/dist/2586.js +0 -1
- package/dist/2586.js.map +0 -1
- package/dist/2625.js +0 -1
- package/dist/2625.js.map +0 -1
- package/dist/2652.js +0 -1
- package/dist/2652.js.map +0 -1
- package/dist/2685.js +0 -1
- package/dist/2685.js.map +0 -1
- package/dist/2799.js +0 -1
- package/dist/2799.js.map +0 -1
- package/dist/2826.js +0 -1
- package/dist/2826.js.map +0 -1
- package/dist/2948.js +0 -1
- package/dist/2948.js.map +0 -1
- package/dist/3089.js +0 -1
- package/dist/3089.js.map +0 -1
- package/dist/3190.js +0 -1
- package/dist/3190.js.map +0 -1
- package/dist/3548.js +0 -1
- package/dist/3548.js.map +0 -1
- package/dist/3816.js +0 -1
- package/dist/3816.js.map +0 -1
- package/dist/3906.js +0 -1
- package/dist/3906.js.map +0 -1
- package/dist/3963.js +0 -1
- package/dist/3963.js.map +0 -1
- package/dist/405.js +0 -1
- package/dist/405.js.map +0 -1
- package/dist/4296.js +0 -1
- package/dist/4296.js.map +0 -1
- package/dist/4537.js +0 -1
- package/dist/4537.js.map +0 -1
- package/dist/4613.js +0 -1
- package/dist/4613.js.map +0 -1
- package/dist/4735.js +0 -1
- package/dist/4735.js.map +0 -1
- package/dist/4744.js +0 -1
- package/dist/4744.js.map +0 -1
- package/dist/4813.js +0 -2
- package/dist/4813.js.map +0 -1
- package/dist/4818.js +0 -1
- package/dist/4818.js.map +0 -1
- package/dist/4858.js +0 -1
- package/dist/4858.js.map +0 -1
- package/dist/487.js +0 -1
- package/dist/487.js.map +0 -1
- package/dist/5202.js +0 -1
- package/dist/5202.js.map +0 -1
- package/dist/552.js +0 -1
- package/dist/552.js.map +0 -1
- package/dist/5592.js +0 -1
- package/dist/5592.js.map +0 -1
- package/dist/5669.js +0 -1
- package/dist/5669.js.map +0 -1
- package/dist/6092.js +0 -1
- package/dist/6092.js.map +0 -1
- package/dist/6178.js +0 -1
- package/dist/6178.js.map +0 -1
- package/dist/6456.js +0 -1
- package/dist/6466.js +0 -3
- package/dist/6466.js.map +0 -1
- package/dist/6492.js +0 -1
- package/dist/6492.js.map +0 -1
- package/dist/6495.js +0 -1
- package/dist/6495.js.map +0 -1
- package/dist/6800.js +0 -1
- package/dist/6800.js.map +0 -1
- package/dist/7005.js +0 -1
- package/dist/7005.js.map +0 -1
- package/dist/7201.js +0 -1
- package/dist/7201.js.map +0 -1
- package/dist/7210.js +0 -1
- package/dist/7210.js.map +0 -1
- package/dist/7234.js +0 -1
- package/dist/7234.js.map +0 -1
- package/dist/7261.js +0 -1
- package/dist/7261.js.map +0 -1
- package/dist/7326.js +0 -1
- package/dist/7463.js +0 -1
- package/dist/7463.js.map +0 -1
- package/dist/7591.js +0 -1
- package/dist/7591.js.map +0 -1
- package/dist/7607.js +0 -1
- package/dist/7701.js +0 -1
- package/dist/7701.js.map +0 -1
- package/dist/7717.js +0 -1
- package/dist/7717.js.map +0 -1
- package/dist/7739.js +0 -1
- package/dist/7739.js.map +0 -1
- package/dist/7765.js +0 -1
- package/dist/7765.js.map +0 -1
- package/dist/7820.js +0 -1
- package/dist/7820.js.map +0 -1
- package/dist/7971.js +0 -1
- package/dist/7971.js.map +0 -1
- package/dist/7995.js +0 -1
- package/dist/7995.js.map +0 -1
- package/dist/8159.js +0 -7
- package/dist/8159.js.map +0 -1
- package/dist/8177.js +0 -1
- package/dist/8177.js.map +0 -1
- package/dist/8244.js +0 -1
- package/dist/8244.js.map +0 -1
- package/dist/845.js +0 -1
- package/dist/845.js.map +0 -1
- package/dist/8524.js +0 -1
- package/dist/8524.js.map +0 -1
- package/dist/8570.js +0 -1
- package/dist/8570.js.map +0 -1
- package/dist/87.js +0 -1
- package/dist/87.js.map +0 -1
- package/dist/8727.js +0 -1
- package/dist/906.js +0 -1
- package/dist/9124.js +0 -1
- package/dist/9124.js.map +0 -1
- package/dist/9182.js +0 -1
- package/dist/921.js +0 -1
- package/dist/921.js.map +0 -1
- package/dist/9404.js +0 -1
- package/dist/9404.js.map +0 -1
- package/dist/9406.js +0 -1
- package/dist/9406.js.map +0 -1
- package/dist/9446.js +0 -1
- package/dist/9446.js.map +0 -1
- package/dist/9449.js +0 -1
- package/dist/9449.js.map +0 -1
- package/dist/9566.js +0 -5
- package/dist/9566.js.map +0 -1
- package/dist/9641.js +0 -1
- package/dist/9641.js.map +0 -1
- package/dist/9801.js +0 -1
- package/dist/9801.js.map +0 -1
- package/dist/9835.js +0 -11
- package/dist/9835.js.map +0 -1
- package/dist/9900.js +0 -1
- package/dist/9900.js.map +0 -1
- package/dist/main.js +0 -5
- package/dist/main.js.map +0 -1
- package/dist/openmrs-esm-patient-flags-app.js +0 -5
- package/dist/openmrs-esm-patient-flags-app.js.buildmanifest.json +0 -2480
- package/dist/openmrs-esm-patient-flags-app.js.map +0 -1
- package/dist/routes.json +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kenyaemr/esm-patient-flags-app",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.5-pre.16",
|
|
4
4
|
"description": "Patient flags microfrontend for the OpenMRS SPA",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openmrs"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"build": "rspack --mode=production",
|
|
23
23
|
"coverage": "echo \"Jest has been removed; no unit test runner is configured\" && exit 0",
|
|
24
24
|
"debug": "npm run serve",
|
|
25
|
-
"extract-translations": "i18next 'src/**/*.
|
|
25
|
+
"extract-translations": "i18next 'src/**/*.{ts,tsx}' --config ../../tools/i18next-parser.config.js",
|
|
26
26
|
"lint": "eslint src --ext ts,tsx",
|
|
27
27
|
"serve": "rspack serve --mode=development",
|
|
28
28
|
"start": "openmrs develop",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
-
"stableVersion": "5.4.
|
|
47
|
+
"stableVersion": "5.4.4"
|
|
48
48
|
}
|
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
import { FetchResponse, openmrsFetch, restBaseUrl, useSession } from '@openmrs/esm-framework';
|
|
2
2
|
import useSWR from 'swr';
|
|
3
|
-
import { DefaultFacility } from '../types';
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
type FacilityRegistryStatus = {
|
|
5
|
+
sha_operational_status?: string;
|
|
6
|
+
regulatory_operational_status?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const useFacilityRegistry = () => {
|
|
6
10
|
const { authenticated } = useSession();
|
|
7
|
-
const url = `${restBaseUrl}/
|
|
8
|
-
const { data, isLoading, error } = useSWR<FetchResponse<
|
|
11
|
+
const url = `${restBaseUrl}/virtualclaims/facility-registry`;
|
|
12
|
+
const { data, isLoading, error, mutate } = useSWR<FetchResponse<FacilityRegistryStatus>>(
|
|
9
13
|
authenticated ? url : null,
|
|
10
14
|
openmrsFetch,
|
|
11
|
-
{},
|
|
15
|
+
{ revalidateOnFocus: false },
|
|
12
16
|
);
|
|
17
|
+
|
|
18
|
+
const notYetSynced = (error as any)?.response?.status === 404;
|
|
19
|
+
|
|
13
20
|
return {
|
|
14
21
|
isLoading,
|
|
15
|
-
|
|
16
|
-
error,
|
|
22
|
+
facility: data?.data,
|
|
23
|
+
error: notYetSynced ? null : error,
|
|
24
|
+
notYetSynced,
|
|
25
|
+
mutate,
|
|
17
26
|
};
|
|
18
|
-
}
|
|
27
|
+
};
|
|
@@ -10,9 +10,11 @@ import {
|
|
|
10
10
|
Receipt,
|
|
11
11
|
Renew,
|
|
12
12
|
Report,
|
|
13
|
+
Review,
|
|
13
14
|
User,
|
|
14
15
|
VolumeFileStorage,
|
|
15
16
|
WatsonHealthCrossReference,
|
|
17
|
+
WorkflowAutomation,
|
|
16
18
|
} from '@carbon/react/icons';
|
|
17
19
|
import { CalendarIcon, useConfig } from '@openmrs/esm-framework';
|
|
18
20
|
import React from 'react';
|
|
@@ -26,7 +28,7 @@ const handleClearCache = async () => {
|
|
|
26
28
|
});
|
|
27
29
|
localStorage.clear();
|
|
28
30
|
sessionStorage.clear();
|
|
29
|
-
|
|
31
|
+
globalThis.location.reload();
|
|
30
32
|
};
|
|
31
33
|
|
|
32
34
|
export const useModuleLinks = () => {
|
|
@@ -117,7 +119,7 @@ export const useModuleLinks = () => {
|
|
|
117
119
|
},
|
|
118
120
|
{
|
|
119
121
|
label: t('reports', 'Reports'),
|
|
120
|
-
url:
|
|
122
|
+
url: `${openmrsSpaBase}reporting`,
|
|
121
123
|
icon: <Report size={24} />,
|
|
122
124
|
privilege: 'o3: View Reports',
|
|
123
125
|
},
|
|
@@ -157,7 +159,19 @@ export const useModuleLinks = () => {
|
|
|
157
159
|
icon: <IbmCloudGateKeeper size={24} />,
|
|
158
160
|
privilege: 'o3: View Queue Screen Dashboard',
|
|
159
161
|
},
|
|
162
|
+
{
|
|
163
|
+
label: t('serviceAvailabilityAdmin', 'Service Availability Admin'),
|
|
164
|
+
url: `${openmrsSpaBase}service-available-admin`,
|
|
165
|
+
icon: <Review size={24} />,
|
|
166
|
+
privilege: 'o3: View Service Availability Admin Dashboard',
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
label: t('claimsAdmin', 'Claims Admin'),
|
|
170
|
+
url: `${openmrsSpaBase}claims-admin`,
|
|
171
|
+
icon: <Review size={24} />,
|
|
172
|
+
privilege: 'o3: View Claims Admin Dashboard',
|
|
173
|
+
},
|
|
160
174
|
];
|
|
161
175
|
|
|
162
|
-
return moduleLinks.filter((link) => !excludeLinks.
|
|
176
|
+
return moduleLinks.filter((link) => !excludeLinks.includes(link.label));
|
|
163
177
|
};
|
|
@@ -14,11 +14,13 @@ const DEBOUNCE_TIME = 500;
|
|
|
14
14
|
const NavbarActionButton: React.FC<NavbarActionButtonProps> = () => {
|
|
15
15
|
const { t } = useTranslation();
|
|
16
16
|
const moduleLinks = useModuleLinks();
|
|
17
|
+
const sortedModuleLinks = [...moduleLinks].sort((a, b) => a.label.localeCompare(b.label));
|
|
17
18
|
const { instanceName } = useConfig<ConfigObject>();
|
|
18
19
|
const [showOverlay, setShowOverlay] = React.useState(false);
|
|
19
20
|
const [searchTerm, setSearchTerm] = useState('');
|
|
20
21
|
const title = t('instanceModules', '{{instanceName}}Modules', { instanceName });
|
|
21
22
|
const toggleOverlay = () => {
|
|
23
|
+
setSearchTerm('');
|
|
22
24
|
setShowOverlay((prevState) => !prevState);
|
|
23
25
|
};
|
|
24
26
|
const ref = useOnClickOutside<HTMLDivElement>(toggleOverlay, showOverlay);
|
|
@@ -26,8 +28,8 @@ const NavbarActionButton: React.FC<NavbarActionButtonProps> = () => {
|
|
|
26
28
|
const debounceSearchTerm = useDebounce(searchTerm, DEBOUNCE_TIME);
|
|
27
29
|
const searchResults =
|
|
28
30
|
debounceSearchTerm === ''
|
|
29
|
-
?
|
|
30
|
-
:
|
|
31
|
+
? sortedModuleLinks
|
|
32
|
+
: sortedModuleLinks.filter((item) => item.label.toLowerCase().includes(searchTerm.toLowerCase()));
|
|
31
33
|
|
|
32
34
|
return (
|
|
33
35
|
<div id="module" ref={ref}>
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
display: grid;
|
|
23
23
|
grid-template-rows: auto 1fr auto;
|
|
24
24
|
z-index: 999;
|
|
25
|
+
overflow-y: auto;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
:global(.omrs-breakpoint-lt-small-desktop) .overlay {
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
column-gap: 0.5rem;
|
|
55
56
|
row-gap: 1rem;
|
|
56
57
|
padding: 0 1rem 1rem 1rem;
|
|
58
|
+
overflow-y: auto;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
.navLinkItem {
|
|
@@ -100,3 +102,10 @@
|
|
|
100
102
|
.illo {
|
|
101
103
|
margin-top: layout.$spacing-05;
|
|
102
104
|
}
|
|
105
|
+
|
|
106
|
+
.extensionSlot {
|
|
107
|
+
display: flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
justify-content: center;
|
|
110
|
+
gap: layout.$spacing-03;
|
|
111
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { Warning, CheckmarkFilled } from '@carbon/react/icons';
|
|
3
|
+
import { Tooltip } from '@carbon/react';
|
|
2
4
|
import { navigate } from '@openmrs/esm-framework';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
3
6
|
import styles from './navbar-link.scss';
|
|
4
|
-
import {
|
|
5
|
-
import dayjs from 'dayjs';
|
|
6
|
-
import { Warning } from '@carbon/react/icons';
|
|
7
|
+
import { useFacilityRegistry } from '../hooks/useDefaultFacility';
|
|
7
8
|
|
|
8
9
|
type NavBarLinkItemProps = {
|
|
9
10
|
icon: React.ReactNode;
|
|
@@ -14,41 +15,74 @@ type NavBarLinkItemProps = {
|
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
const NavBarLink: React.FC<NavBarLinkItemProps> = ({ icon, label, url, hideOverlay, onClick }) => {
|
|
17
|
-
const {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
const { t } = useTranslation();
|
|
19
|
+
const { facility, notYetSynced } = useFacilityRegistry();
|
|
20
|
+
|
|
21
|
+
const normalize = (val?: string | null) => val?.toString().trim().toUpperCase() ?? '';
|
|
22
|
+
|
|
23
|
+
const isStatusItem = label === 'System Info';
|
|
24
|
+
const hasFacilityData = !notYetSynced && !!facility;
|
|
25
|
+
|
|
26
|
+
const getFacilityIssues = (): string[] => {
|
|
27
|
+
if (!isStatusItem || !hasFacilityData) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const issues: string[] = [];
|
|
32
|
+
const shaOperational = normalize(facility!.sha_operational_status);
|
|
33
|
+
const regulatoryOperational = normalize(facility!.regulatory_operational_status);
|
|
34
|
+
|
|
35
|
+
if (shaOperational && shaOperational !== 'ACTIVE') {
|
|
36
|
+
issues.push(t('shaOperationalNotActive', 'SHA operational status is not active'));
|
|
29
37
|
}
|
|
30
|
-
|
|
38
|
+
|
|
39
|
+
if (regulatoryOperational && regulatoryOperational !== 'ACTIVE') {
|
|
40
|
+
issues.push(t('regulatoryNotActive', 'Regulatory operational status is not active'));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return issues;
|
|
31
44
|
};
|
|
32
45
|
|
|
33
|
-
const
|
|
46
|
+
const issues = getFacilityIssues();
|
|
47
|
+
const hasError = issues.length > 0;
|
|
48
|
+
const isHealthy = isStatusItem && hasFacilityData && !hasError;
|
|
34
49
|
|
|
35
|
-
const handleClick = (url) => {
|
|
50
|
+
const handleClick = (url?: string) => {
|
|
36
51
|
hideOverlay(false);
|
|
37
52
|
if (!url) {
|
|
38
|
-
return onClick
|
|
53
|
+
return onClick?.();
|
|
39
54
|
}
|
|
40
55
|
navigate({ to: url });
|
|
41
56
|
};
|
|
57
|
+
|
|
58
|
+
const tooltipLabel = issues.length === 1 ? issues[0] : issues.map((issue) => `• ${issue}`).join('\n');
|
|
59
|
+
|
|
60
|
+
const buttonClass = [styles.navLinkItem, hasError && styles.warning, isHealthy && styles.healthy]
|
|
61
|
+
.filter(Boolean)
|
|
62
|
+
.join(' ');
|
|
63
|
+
|
|
42
64
|
return (
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
65
|
+
<button type="button" onClick={() => handleClick(url)} className={buttonClass}>
|
|
66
|
+
{hasError && (
|
|
67
|
+
<Tooltip label={tooltipLabel} align="bottom" className={styles.navErrorTooltip}>
|
|
68
|
+
<span className={styles.navErrorWrapper}>
|
|
69
|
+
<Warning className={styles.navError} />
|
|
70
|
+
</span>
|
|
71
|
+
</Tooltip>
|
|
72
|
+
)}
|
|
73
|
+
{isHealthy && (
|
|
74
|
+
<Tooltip
|
|
75
|
+
label={t('facilityActive', 'Facility is active and operational')}
|
|
76
|
+
align="bottom"
|
|
77
|
+
className={styles.navHealthyTooltip}>
|
|
78
|
+
<span className={styles.navHealthyWrapper}>
|
|
79
|
+
<CheckmarkFilled className={styles.navHealthy} />
|
|
80
|
+
</span>
|
|
81
|
+
</Tooltip>
|
|
82
|
+
)}
|
|
49
83
|
{icon}
|
|
50
84
|
<span>{label}</span>
|
|
51
|
-
</
|
|
85
|
+
</button>
|
|
52
86
|
);
|
|
53
87
|
};
|
|
54
88
|
|
|
@@ -6,19 +6,53 @@
|
|
|
6
6
|
background-color: colors.$red-30 !important;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
.
|
|
9
|
+
.healthy {
|
|
10
|
+
background-color: colors.$green-20 !important;
|
|
11
|
+
|
|
12
|
+
&:hover {
|
|
13
|
+
background-color: colors.$green-30 !important;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.navErrorTooltip {
|
|
18
|
+
position: absolute;
|
|
19
|
+
top: layout.$spacing-01;
|
|
20
|
+
right: layout.$spacing-01;
|
|
21
|
+
z-index: 1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.navHealthyTooltip {
|
|
10
25
|
position: absolute;
|
|
11
|
-
color: colors.$red-70;
|
|
12
26
|
top: layout.$spacing-01;
|
|
13
27
|
right: layout.$spacing-01;
|
|
28
|
+
z-index: 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.navErrorWrapper,
|
|
32
|
+
.navHealthyWrapper {
|
|
33
|
+
display: inline-flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
cursor: help;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.navError {
|
|
40
|
+
color: colors.$red-70;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.navHealthy {
|
|
44
|
+
color: colors.$green-70;
|
|
14
45
|
}
|
|
15
46
|
|
|
16
47
|
.navLinkItem {
|
|
48
|
+
border: none;
|
|
17
49
|
display: flex;
|
|
18
50
|
flex-direction: column;
|
|
19
|
-
align-items: center;
|
|
20
51
|
min-height: layout.$spacing-12;
|
|
21
52
|
min-width: 8.5rem;
|
|
53
|
+
max-width: 8.5rem;
|
|
54
|
+
padding: 0 layout.$spacing-02;
|
|
55
|
+
align-items: center;
|
|
22
56
|
height: 7rem;
|
|
23
57
|
justify-content: center;
|
|
24
58
|
background-color: colors.$cool-gray-10;
|
|
@@ -28,6 +62,7 @@
|
|
|
28
62
|
|
|
29
63
|
& > span {
|
|
30
64
|
@include type.type-style('body-01');
|
|
65
|
+
text-align: center;
|
|
31
66
|
}
|
|
32
67
|
|
|
33
68
|
&:hover {
|
|
@@ -2,7 +2,7 @@ import React, { useCallback, useMemo } from 'react';
|
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import { Button, Layer, Search, Tile } from '@carbon/react';
|
|
4
4
|
import { EmptyDataIllustration } from '@openmrs/esm-patient-common-lib';
|
|
5
|
-
import { UserHasAccess } from '@openmrs/esm-framework';
|
|
5
|
+
import { Extension, ExtensionSlot, useExtensionSlotMeta, UserHasAccess } from '@openmrs/esm-framework';
|
|
6
6
|
import NavBarLink from './navbar-link.component';
|
|
7
7
|
import styles from './navbar-action-button.scss';
|
|
8
8
|
|
|
@@ -23,7 +23,26 @@ interface NavBarOverlayProps {
|
|
|
23
23
|
|
|
24
24
|
const NavBarOverlay: React.FC<NavBarOverlayProps> = ({ setSearchTerm, modules, searchTerm, hideOverlay }) => {
|
|
25
25
|
const { t } = useTranslation();
|
|
26
|
-
|
|
26
|
+
/*
|
|
27
|
+
Note: Extract meta from extensions and looks for search string array which helps resolve the seach on extension links
|
|
28
|
+
All the link extension should be decleared with meta with search array e.g
|
|
29
|
+
{
|
|
30
|
+
"name": "tnt-module-link",
|
|
31
|
+
"slot": "navbar-items-slot",
|
|
32
|
+
"component": "tntNavLink",
|
|
33
|
+
"meta": {
|
|
34
|
+
"search": ["tnt", "Track", "trace"]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
*/
|
|
38
|
+
const meta = useExtensionSlotMeta('navbar-items-slot');
|
|
39
|
+
const { hasCandidateMatchingSearchTerm } = useMemo(() => {
|
|
40
|
+
const slotMeta = Object.entries(meta);
|
|
41
|
+
const allSearchCandidates = slotMeta.flatMap(([slotMeta, meta]) => (meta?.search ?? []) as Array<string>);
|
|
42
|
+
const hasCandidateMatchingSearchTerm =
|
|
43
|
+
allSearchCandidates.findIndex((s) => t(s, s).toLowerCase().includes(searchTerm.toLowerCase())) !== -1;
|
|
44
|
+
return { hasCandidateMatchingSearchTerm, allSearchCandidates };
|
|
45
|
+
}, [meta, searchTerm, t]);
|
|
27
46
|
const handleClearSearch = useCallback(
|
|
28
47
|
(event: React.MouseEvent) => {
|
|
29
48
|
event.stopPropagation();
|
|
@@ -41,15 +60,17 @@ const NavBarOverlay: React.FC<NavBarOverlayProps> = ({ setSearchTerm, modules, s
|
|
|
41
60
|
// Add logic to render module links based on user privileges
|
|
42
61
|
const renderModuleLinks = useMemo(
|
|
43
62
|
() =>
|
|
44
|
-
modules.map((item
|
|
45
|
-
item
|
|
46
|
-
|
|
47
|
-
|
|
63
|
+
modules.map((item) => {
|
|
64
|
+
const key = item.url ?? item.label;
|
|
65
|
+
|
|
66
|
+
return item?.privilege ? (
|
|
67
|
+
<UserHasAccess key={key} privilege={item.privilege}>
|
|
68
|
+
<NavBarLink {...item} hideOverlay={hideOverlay} />
|
|
48
69
|
</UserHasAccess>
|
|
49
70
|
) : (
|
|
50
|
-
<NavBarLink key={
|
|
51
|
-
)
|
|
52
|
-
),
|
|
71
|
+
<NavBarLink key={key} {...item} hideOverlay={hideOverlay} />
|
|
72
|
+
);
|
|
73
|
+
}),
|
|
53
74
|
[modules, hideOverlay],
|
|
54
75
|
);
|
|
55
76
|
|
|
@@ -84,8 +105,20 @@ const NavBarOverlay: React.FC<NavBarOverlayProps> = ({ setSearchTerm, modules, s
|
|
|
84
105
|
onChange={handleSearchChange}
|
|
85
106
|
/>
|
|
86
107
|
|
|
87
|
-
{modules.length === 0 && renderEmptyState()}
|
|
88
|
-
|
|
108
|
+
{modules.length === 0 && !hasCandidateMatchingSearchTerm && renderEmptyState()}
|
|
109
|
+
<div className={styles.navLinks}>
|
|
110
|
+
{renderModuleLinks}
|
|
111
|
+
<ExtensionSlot className={styles.extensionSlot} name="navbar-items-slot">
|
|
112
|
+
{(ext) => {
|
|
113
|
+
const search = (ext.meta?.search ?? []) as Array<string>;
|
|
114
|
+
const show = search.findIndex((s) => t(s, s).toLowerCase().includes(searchTerm.toLowerCase())) !== -1;
|
|
115
|
+
if (show) {
|
|
116
|
+
return <Extension state={{ hideOverlay }} />;
|
|
117
|
+
}
|
|
118
|
+
return <React.Fragment />;
|
|
119
|
+
}}
|
|
120
|
+
</ExtensionSlot>
|
|
121
|
+
</div>
|
|
89
122
|
</div>
|
|
90
123
|
</div>
|
|
91
124
|
);
|
|
@@ -61,8 +61,8 @@ const PatientDiagnosisContent: React.FC<PatientDiagnosisContentProps> = ({ patie
|
|
|
61
61
|
lowContrast={true}
|
|
62
62
|
statusIconDescription="notification"
|
|
63
63
|
subtitle={t(
|
|
64
|
-
'
|
|
65
|
-
'Main diagnosis is required
|
|
64
|
+
'noMainDiagnosisSubtitlecWarning',
|
|
65
|
+
'Main diagnosis is required, please add main diagnosis to the clinical encounter form',
|
|
66
66
|
)}
|
|
67
67
|
title={t('noMainDiagnosis', 'Main diagnosis required')}
|
|
68
68
|
hideCloseButton={true}
|
package/src/routes.json
CHANGED
package/translations/am.json
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
"bedManagement": "የአልጋ አስተዳደር",
|
|
6
6
|
"billingAdmin": "Billing Admin",
|
|
7
7
|
"caseManagement": "Case Management",
|
|
8
|
+
"claimsAdmin": "Claims Admin",
|
|
8
9
|
"clearCache": "መሸጎጫ አጽዳ",
|
|
9
10
|
"clearSearch": "ፍለጋ አጽዳ",
|
|
10
11
|
"crossBorder": "ድንበር ተሻጋሪ",
|
|
11
12
|
"dispensingApp": "የመድኃኒት ማከፋፈያ መተግበሪያ",
|
|
12
13
|
"emptyLinkSearchText": "የፍለጋ መስፈርቶቹን የሚያሟሉ ምንም አገናኞች የሉም",
|
|
13
14
|
"errorPatientFlags": "የታካሚ ባንዲራዎችን በመጫን ላይ ስህተት",
|
|
15
|
+
"facilityActive": "Facility is active and operational",
|
|
14
16
|
"facilityDashboard": "የተቋም ዳሽቦርድ",
|
|
15
17
|
"formBuilder": "የቅጽ ገንቢ",
|
|
16
18
|
"instanceHomeLink": "{{instanceName}}Home",
|
|
@@ -20,12 +22,15 @@
|
|
|
20
22
|
"legacyAdmin": "Legacy Admin",
|
|
21
23
|
"manageStocks": "አክሲዮኖችን አስተዳድር",
|
|
22
24
|
"noMainDiagnosis": "Main diagnosis required",
|
|
23
|
-
"
|
|
25
|
+
"noMainDiagnosisSubtitlecWarning": "Main diagnosis is required, please add main diagnosis to the clinical encounter form",
|
|
24
26
|
"queueScreen": "Queue Screen",
|
|
25
27
|
"referrals": "ሪፈራሎች",
|
|
28
|
+
"regulatoryNotActive": "Regulatory operational status is not active",
|
|
26
29
|
"reports": "ሪፖርቶች",
|
|
27
30
|
"search": "ሞጁል ፈልግ",
|
|
31
|
+
"serviceAvailabilityAdmin": "Service Availability Admin",
|
|
28
32
|
"serviceQueuesAdmin": "የመምሪያ ዘዴዎች አስተዳደር",
|
|
33
|
+
"shaOperationalNotActive": "SHA operational status is not active",
|
|
29
34
|
"suppliesDispensing": "አቅርቦቶች ማከፋፈል",
|
|
30
35
|
"systemInfo": "የስርዓት መረጃ"
|
|
31
36
|
}
|
package/translations/en.json
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
"bedManagement": "Bed Management",
|
|
6
6
|
"billingAdmin": "Billing Admin",
|
|
7
7
|
"caseManagement": "Case Management",
|
|
8
|
+
"claimsAdmin": "Claims Admin",
|
|
8
9
|
"clearCache": "Clear Cache",
|
|
9
10
|
"clearSearch": "Clear search",
|
|
10
11
|
"crossBorder": "Cross Border",
|
|
11
12
|
"dispensingApp": "Dispensing App",
|
|
12
13
|
"emptyLinkSearchText": "There are no links to display that match the search criteria",
|
|
13
14
|
"errorPatientFlags": "Error loading patient flags",
|
|
15
|
+
"facilityActive": "Facility is active and operational",
|
|
14
16
|
"facilityDashboard": "Facility Dashboard",
|
|
15
17
|
"formBuilder": "Form Builder",
|
|
16
18
|
"instanceHomeLink": "{{instanceName}}Home",
|
|
@@ -20,12 +22,15 @@
|
|
|
20
22
|
"legacyAdmin": "Legacy Admin",
|
|
21
23
|
"manageStocks": "Manage Stocks",
|
|
22
24
|
"noMainDiagnosis": "Main diagnosis required",
|
|
23
|
-
"
|
|
25
|
+
"noMainDiagnosisSubtitlecWarning": "Main diagnosis is required, please add main diagnosis to the clinical encounter form",
|
|
24
26
|
"queueScreen": "Queue Screen",
|
|
25
27
|
"referrals": "Referrals",
|
|
28
|
+
"regulatoryNotActive": "Regulatory operational status is not active",
|
|
26
29
|
"reports": "Reports",
|
|
27
30
|
"search": "Search for a module",
|
|
31
|
+
"serviceAvailabilityAdmin": "Service Availability Admin",
|
|
28
32
|
"serviceQueuesAdmin": "Service Queues Admin",
|
|
33
|
+
"shaOperationalNotActive": "SHA operational status is not active",
|
|
29
34
|
"suppliesDispensing": "Supplies Dispensing",
|
|
30
35
|
"systemInfo": "System Info"
|
|
31
36
|
}
|
package/translations/fr.json
CHANGED
|
@@ -1,43 +1,36 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
2
|
+
"administration": "Administration",
|
|
3
|
+
"adrAssessment": "Évaluation des effets indésirables",
|
|
4
|
+
"appointments": "Rendez-vous",
|
|
5
|
+
"bedManagement": "Gestion des lits",
|
|
6
|
+
"billingAdmin": "Services facturables",
|
|
7
|
+
"caseManagement": "Gestion des cas",
|
|
8
|
+
"claimsAdmin": "Administration des sinistres",
|
|
9
|
+
"clearCache": "Vider le cache",
|
|
8
10
|
"clearSearch": "Effacer",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"relationships": "Liens de parenté",
|
|
29
|
-
"resetFields": "Réinitialisation des champs",
|
|
30
|
-
"seachResultsSmall": "Résultats de recherche",
|
|
11
|
+
"crossBorder": "Transfrontalier",
|
|
12
|
+
"dispensingApp": "Dispensation",
|
|
13
|
+
"emptyLinkSearchText": "Aucun lien à afficher correspondant aux critères de recherche",
|
|
14
|
+
"errorPatientFlags": "Erreur lors du chargement des indicateurs du patient",
|
|
15
|
+
"facilityActive": "L’établissement est actif et opérationnel",
|
|
16
|
+
"facilityDashboard": "Tableau de bord",
|
|
17
|
+
"formBuilder": "Gestion des formulaires",
|
|
18
|
+
"instanceHomeLink": "{{instanceName}}Accueil",
|
|
19
|
+
"instanceModules": "{{instanceName}}Modules",
|
|
20
|
+
"kenyaEMRHome": "Accueil EMR",
|
|
21
|
+
"labManifestApp": "Application de manifeste de laboratoire",
|
|
22
|
+
"legacyAdmin": "Administration héritée",
|
|
23
|
+
"manageStocks": "Gestion des stocks",
|
|
24
|
+
"noMainDiagnosis": "Diagnostic principal requis",
|
|
25
|
+
"noMainDiagnosisSubtitlecWarning": "Le diagnostic principal est requis, veuillez ajouter le diagnostic principal au formulaire de consultation clinique",
|
|
26
|
+
"queueScreen": "Écran de file d’attente",
|
|
27
|
+
"referrals": "Références",
|
|
28
|
+
"regulatoryNotActive": "Regulatory operational status is not active",
|
|
29
|
+
"reports": "Rapports",
|
|
31
30
|
"search": "Recherche",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"sex": "Sexe",
|
|
38
|
-
"showAllDetails": "Afficher toutes les informations",
|
|
39
|
-
"showLess": "Afficher moins",
|
|
40
|
-
"trySearchWithPatientUniqueID": "Essayez de chercher par l'identifiant unique du patient",
|
|
41
|
-
"unknown": "Inconnu",
|
|
42
|
-
"year": "Année"
|
|
31
|
+
"serviceAvailabilityAdmin": "Administration de la disponibilité des services",
|
|
32
|
+
"serviceQueuesAdmin": "Gestion des files d’attente",
|
|
33
|
+
"shaOperationalNotActive": "SHA operational status is not active",
|
|
34
|
+
"suppliesDispensing": "Dispensation des fournitures",
|
|
35
|
+
"systemInfo": "Informations système"
|
|
43
36
|
}
|
package/translations/sw.json
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
"bedManagement": "Bed Management",
|
|
6
6
|
"billingAdmin": "Billing Admin",
|
|
7
7
|
"caseManagement": "Case Management",
|
|
8
|
+
"claimsAdmin": "Claims Admin",
|
|
8
9
|
"clearCache": "Clear Cache",
|
|
9
10
|
"clearSearch": "Clear search",
|
|
10
11
|
"crossBorder": "Cross Border",
|
|
11
12
|
"dispensingApp": "Dispensing App",
|
|
12
13
|
"emptyLinkSearchText": "There are no links to display that match the search criteria",
|
|
13
14
|
"errorPatientFlags": "Error loading patient flags",
|
|
15
|
+
"facilityActive": "Facility is active and operational",
|
|
14
16
|
"facilityDashboard": "Facility Dashboard",
|
|
15
17
|
"formBuilder": "Form Builder",
|
|
16
18
|
"instanceHomeLink": "{{instanceName}}Home",
|
|
@@ -20,12 +22,15 @@
|
|
|
20
22
|
"legacyAdmin": "Legacy Admin",
|
|
21
23
|
"manageStocks": "Manage Stocks",
|
|
22
24
|
"noMainDiagnosis": "Main diagnosis required",
|
|
23
|
-
"
|
|
25
|
+
"noMainDiagnosisSubtitlecWarning": "Main diagnosis is required, please add main diagnosis to the clinical encounter form",
|
|
24
26
|
"queueScreen": "Queue Screen",
|
|
25
27
|
"referrals": "Referrals",
|
|
28
|
+
"regulatoryNotActive": "Regulatory operational status is not active",
|
|
26
29
|
"reports": "Reports",
|
|
27
30
|
"search": "Search for a module",
|
|
31
|
+
"serviceAvailabilityAdmin": "Service Availability Admin",
|
|
28
32
|
"serviceQueuesAdmin": "Service Queues Admin",
|
|
33
|
+
"shaOperationalNotActive": "SHA operational status is not active",
|
|
29
34
|
"suppliesDispensing": "Supplies Dispensing",
|
|
30
35
|
"systemInfo": "System Info"
|
|
31
36
|
}
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
[1m[33mWARNING[39m[22m in [33m⚠[0m asset size limit: The following asset(s) exceed the recommended size limit (244.141 KiB). This can impact web performance.
|
|
2
|
-
[33m│[0m Assets:
|
|
3
|
-
[33m│[0m 2625.js (258.661 KiB)
|
|
4
|
-
[0m
|
|
5
|
-
|
|
6
|
-
Rspack compiled with [1m[33m1 warning[39m[22m in 33.59 s
|