@kenyaemr/esm-admin-app 5.4.2-pre.2375 → 5.4.2-pre.2378

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/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemrCharts":"^1.6.7"},"extensions":[{"component":"adminLeftPanelLink","name":"admin-left-panel-link","slot":"admin-left-panel-slot"},{"component":"userManagementLeftPannelLink","name":"user-management-left-panel-link","slot":"admin-left-panel-slot"},{"component":"etlAdministrationLeftPannelLink","name":"etl-administration-left-panel-link","slot":"admin-left-panel-slot"},{"component":"locationsLeftPanelLink","name":"locations-left-panel-link","slot":"admin-left-panel-slot"},{"component":"facilitySetupLeftPanelLink","name":"facility-setup-left-panel-link","slot":"admin-left-panel-slot"}],"workspaces":[{"name":"manage-user-workspace","component":"manageUserWorkspace","title":"Manage User Workspace","type":"other-form","canMaximize":true,"width":"extra-wide"},{"name":"user-role-scope-workspace","component":"userRoleScopeWorkspace","title":"User Rple Scope Workspace","type":"other-form","canMaximize":true,"width":"extra-wide"},{"name":"add-location-workspace","title":"Add Location","component":"addLocation","type":"workspace"},{"name":"search-location-workspace","title":"Search Location","component":"searchLocationWorkspace","type":"workspace"},{"name":"hwr-sync-workspace","title":"HWR Sync Workspace","component":"hwrSyncWorkspace","type":"other-form"},{"name":"hwr-sync-modal","title":"HWR Sync Modal","component":"hwrSyncModal","type":"modal"}],"modals":[{"component":"operationConfirmationModal","name":"operation-confirmation-modal"},{"component":"hwrConfirmationModal","name":"hwr-confirmation-modal"},{"component":"hwrEmptyModal","name":"hwr-empty-modal"},{"component":"hwrSyncModal","name":"hwr-syncing-modal"}],"pages":[{"component":"root","route":"admin"}],"version":"5.4.2-pre.2375"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemrCharts":"^1.6.7"},"extensions":[{"component":"adminLeftPanelLink","name":"admin-left-panel-link","slot":"admin-left-panel-slot"},{"component":"userManagementLeftPannelLink","name":"user-management-left-panel-link","slot":"admin-left-panel-slot"},{"component":"etlAdministrationLeftPannelLink","name":"etl-administration-left-panel-link","slot":"admin-left-panel-slot"},{"component":"locationsLeftPanelLink","name":"locations-left-panel-link","slot":"admin-left-panel-slot"},{"component":"facilitySetupLeftPanelLink","name":"facility-setup-left-panel-link","slot":"admin-left-panel-slot"}],"workspaces":[{"name":"manage-user-workspace","component":"manageUserWorkspace","title":"Manage User Workspace","type":"other-form","canMaximize":true,"width":"extra-wide"},{"name":"user-role-scope-workspace","component":"userRoleScopeWorkspace","title":"User Rple Scope Workspace","type":"other-form","canMaximize":true,"width":"extra-wide"},{"name":"add-location-workspace","title":"Add Location","component":"addLocation","type":"workspace"},{"name":"search-location-workspace","title":"Search Location","component":"searchLocationWorkspace","type":"workspace"},{"name":"hwr-sync-workspace","title":"HWR Sync Workspace","component":"hwrSyncWorkspace","type":"other-form"},{"name":"hwr-sync-modal","title":"HWR Sync Modal","component":"hwrSyncModal","type":"modal"}],"modals":[{"component":"operationConfirmationModal","name":"operation-confirmation-modal"},{"component":"hwrConfirmationModal","name":"hwr-confirmation-modal"},{"component":"hwrEmptyModal","name":"hwr-empty-modal"},{"component":"hwrSyncModal","name":"hwr-syncing-modal"}],"pages":[{"component":"root","route":"admin"}],"version":"5.4.2-pre.2378"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-admin-app",
3
- "version": "5.4.2-pre.2375",
3
+ "version": "5.4.2-pre.2378",
4
4
  "description": "Facilitates the management of ETL tables",
5
5
  "browser": "dist/kenyaemr-esm-admin-app.js",
6
6
  "main": "src/index.ts",
@@ -3,8 +3,8 @@ import { HWR_API_NO_CREDENTIALS, PROVIDER_NOT_FOUND, RESOURCE_NOT_FOUND, UNKNOWN
3
3
  import useSWR from 'swr';
4
4
  import { useState } from 'react';
5
5
 
6
- export const searchHealthCareWork = async (identifierType: string, identifierNumber: string) => {
7
- const url = `${restBaseUrl}/kenyaemr/practitionersearch?identifierType=${identifierType}&identifierNumber=${identifierNumber}`;
6
+ export const searchHealthCareWork = async (identifierType: string, identifierNumber: string, regulator: string) => {
7
+ const url = `${restBaseUrl}/kenyaemr/practitionersearch?identifierType=${identifierType}&identifierNumber=${identifierNumber}&regulator=${regulator}`;
8
8
  const response = await fetch(makeUrl(url));
9
9
  if (response.ok) {
10
10
  const responseData = await response.json();
@@ -31,6 +31,7 @@ const HWRSyncModal: React.FC<HWRSyncModalProps> = ({ close, provider }) => {
31
31
  providerAddressUuid,
32
32
  providerHieFhirReference,
33
33
  providerUniqueIdentifierAttributeTypeUuid,
34
+ regulatorOptions,
34
35
  } = config;
35
36
 
36
37
  const attributeMapping = {
@@ -45,6 +46,7 @@ const HWRSyncModal: React.FC<HWRSyncModalProps> = ({ close, provider }) => {
45
46
  const [searchHWR, setSearchHWR] = useState({
46
47
  identifierType: identifierTypes[0]?.key,
47
48
  identifier: attributeMapping[identifierTypes[0]?.key],
49
+ regulator: regulatorOptions[0]?.key,
48
50
  });
49
51
 
50
52
  const handleIdentifierTypeChange = (selectedItem: { key: string; name: string } | null) => {
@@ -56,16 +58,25 @@ const HWRSyncModal: React.FC<HWRSyncModalProps> = ({ close, provider }) => {
56
58
  }));
57
59
  };
58
60
 
61
+ const handleRegulatorChange = (selectedItem: { key: string; name: string } | null) => {
62
+ const selectedKey = selectedItem?.key ?? '';
63
+ setSearchHWR((prev) => ({
64
+ ...prev,
65
+ regulator: selectedKey,
66
+ }));
67
+ };
68
+
59
69
  const isSearchDisabled = () => !searchHWR.identifier;
60
70
 
61
71
  const handleSync = async () => {
62
72
  try {
63
73
  setSyncLoading(true);
64
-
65
74
  const healthWorker: PractitionerResponse = await searchHealthCareWork(
66
75
  searchHWR.identifierType,
67
76
  searchHWR.identifier,
77
+ searchHWR.regulator,
68
78
  );
79
+
69
80
  const resource = healthWorker.entry[0]?.resource;
70
81
 
71
82
  const extractedAttributes = {
@@ -99,7 +110,17 @@ const HWRSyncModal: React.FC<HWRSyncModalProps> = ({ close, provider }) => {
99
110
  { attributeType: licenseExpiryDateUuid, value: parseDate(extractedAttributes.licenseDate) },
100
111
  { attributeType: phoneNumberUuid, value: extractedAttributes.phoneNumber },
101
112
  { attributeType: qualificationUuid, value: extractedAttributes.qualification },
102
- { attributeType: providerHieFhirReference, value: JSON.stringify(healthWorker) },
113
+ {
114
+ attributeType: providerHieFhirReference,
115
+ // Include regulator info in the health worker reference
116
+ value: JSON.stringify({
117
+ ...healthWorker,
118
+ searchParameters: {
119
+ regulator: searchHWR.regulator,
120
+ identifierType: searchHWR.identifierType,
121
+ },
122
+ }),
123
+ },
103
124
  { attributeType: providerAddressUuid, value: extractedAttributes.email },
104
125
  { attributeType: providerNationalIdUuid, value: extractedAttributes.nationalId },
105
126
  {
@@ -165,6 +186,18 @@ const HWRSyncModal: React.FC<HWRSyncModalProps> = ({ close, provider }) => {
165
186
  className={styles.ComboBox}
166
187
  />
167
188
  </Column>
189
+ <Column className={styles.identifierTypeColumn}>
190
+ <ComboBox
191
+ onChange={({ selectedItem }) => handleRegulatorChange(selectedItem)}
192
+ id="regulatorOptions"
193
+ titleText={t('regulator', 'Regulator')}
194
+ placeholder={t('chooseRegulator', 'Choose regulator')}
195
+ initialSelectedItem={regulatorOptions.find((item) => item.key === searchHWR.regulator)}
196
+ items={regulatorOptions}
197
+ itemToString={(item) => (item ? item.name : '')}
198
+ className={styles.ComboBox}
199
+ />
200
+ </Column>
168
201
  <Column className={styles.identifierTypeColumn}>
169
202
  <span className={styles.identifierTypeHeader}>{t('identifierNumber', 'Identifier number*')}</span>
170
203
  <Search
@@ -85,6 +85,7 @@ const ManageUserWorkspace: React.FC<ManageUserWorkspaceProps> = ({
85
85
  const { rolesConfig, error } = useSystemUserRoleConfigSetting();
86
86
  const {
87
87
  identifierTypes,
88
+ regulatorOptions,
88
89
  licenseBodyUuid,
89
90
  passportNumberUuid,
90
91
  personEmailAttributeUuid,
@@ -100,10 +101,12 @@ const ManageUserWorkspace: React.FC<ManageUserWorkspaceProps> = ({
100
101
  } = useConfig<ConfigObject>();
101
102
  const [searchHWR, setSearchHWR] = useState({
102
103
  identifierType: identifierTypes[0]?.key ?? '',
104
+ regulator: regulatorOptions[0]?.key ?? '',
103
105
  identifier: '',
104
106
  isHWRLoading: false,
105
107
  });
106
108
  const defaultIdentifierType = identifierTypes.find((item) => item.key === searchHWR.identifierType);
109
+ const defaultRegulator = regulatorOptions.find((item) => item.key === searchHWR.regulator);
107
110
 
108
111
  const attributeTypeMapping = useMemo(() => {
109
112
  return {
@@ -259,6 +262,7 @@ const ManageUserWorkspace: React.FC<ManageUserWorkspaceProps> = ({
259
262
  const fetchedHealthWorker: PractitionerResponse = await searchHealthCareWork(
260
263
  searchHWR.identifierType,
261
264
  searchHWR.identifier,
265
+ searchHWR.regulator,
262
266
  );
263
267
  if (!fetchedHealthWorker?.entry || fetchedHealthWorker.entry.length === 0) {
264
268
  showModal('hwr-empty-modal', { errorCode: t('noResults', 'No results found') });
@@ -616,6 +620,19 @@ const ManageUserWorkspace: React.FC<ManageUserWorkspaceProps> = ({
616
620
  itemToString={(item) => (item ? item.name : '')}
617
621
  />
618
622
  </Column>
623
+ <Column>
624
+ <ComboBox
625
+ onChange={({ selectedItem }) => {
626
+ setSearchHWR({ ...searchHWR, regulator: selectedItem?.key ?? '' });
627
+ }}
628
+ id="formRegulatorOptions"
629
+ titleText={t('regulator', 'Regulator')}
630
+ placeholder={t('chooseRegulatorType', 'Choose regulator option')}
631
+ initialSelectedItem={defaultRegulator}
632
+ items={regulatorOptions}
633
+ itemToString={(item) => (item ? item.name : '')}
634
+ />
635
+ </Column>
619
636
  <Column>
620
637
  <span className={styles.formIdentifierType}>
621
638
  {t('identifierNumber', 'Identifier number*')}
@@ -635,6 +652,13 @@ const ManageUserWorkspace: React.FC<ManageUserWorkspaceProps> = ({
635
652
  kind="secondary"
636
653
  size="md"
637
654
  renderIcon={Query}
655
+ disabled={
656
+ !searchHWR.identifier ||
657
+ searchHWR.isHWRLoading ||
658
+ !searchHWR.identifierType ||
659
+ !searchHWR.regulator
660
+ }
661
+ iconDescription={t('search', 'Search')}
638
662
  hasIconOnly
639
663
  className={styles.formSearchButton}
640
664
  onClick={handleSearch}
@@ -78,6 +78,27 @@ export const configSchema = {
78
78
  ],
79
79
  _description: 'List of identifier types with unique keys for each.',
80
80
  },
81
+ regulatorOptions: {
82
+ _type: Type.Array,
83
+ _elements: {
84
+ _type: Type.Object,
85
+ properties: {
86
+ key: { _type: Type.String },
87
+ name: { _type: Type.String },
88
+ },
89
+ },
90
+ _default: [
91
+ { key: 'Clinical Officers Council', name: 'Clinical Officers Council' },
92
+ { key: 'Pharmacy and Poisons Board', name: 'Pharmacy and Poisons Board' },
93
+ { key: 'Nursing Council', name: 'Nursing Council' },
94
+ { key: 'KMPDC', name: 'Kenya Medical Practitioners and Dentists Council (KMPDC)' },
95
+ {
96
+ key: 'Kenya Medical Laboratory Technicians & Technologists Board',
97
+ name: 'Kenya Medical Laboratory Technicians & Technologists Board',
98
+ },
99
+ ],
100
+ _description: 'List of regulator options with unique keys for each.',
101
+ },
81
102
  };
82
103
 
83
104
  export interface UserProperties {
@@ -102,4 +123,8 @@ export interface ConfigObject {
102
123
  key: string;
103
124
  name: string;
104
125
  }>;
126
+ regulatorOptions: Array<{
127
+ key: string;
128
+ name: string;
129
+ }>;
105
130
  }