@kenyaemr/esm-billing-app 5.4.2-pre.2835 → 5.4.2-pre.2843

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":{"kenyaemr":"^19.0.0"},"pages":[{"component":"billableServicesHome","route":"billable-services"},{"component":"requirePaymentModal","routeRegex":"^patient/.+/chart","online":true,"offline":false},{"component":"billingAdmin","route":"billing-admin"}],"extensions":[{"component":"accountingDashboardLink","name":"accounting-dashboard-link","slots":["homepage-dashboard-slot"],"meta":{"name":"accounting","slot":"accounting-dashboard-slot","title":"Accounting"}},{"name":"billing-dashboard","component":"billingDashboard","slot":"accounting-dashboard-slot"},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","meta":{"name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot","path":"insurance-benefits","columns":1,"columnSpan":1},"featureFlag":"healthInformationExchange"},{"component":"benefitsPackage","name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot"},{"component":"root","name":"billing-dashboard-root","slot":"billing-dashboard-slot"},{"component":"benefitsEligibilyRequestForm","name":"benefits-eligibility-request-form"},{"component":"benefitsPreAuthForm","name":"benefits-pre-auth-form"},{"name":"billing-patient-summary","component":"billingPatientSummary","slot":"patient-chart-billing-dashboard-slot","order":10,"meta":{"columnSpan":4}},{"name":"billing-summary-dashboard-link","component":"billingSummaryDashboardLink","order":11,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-billing-dashboard-slot","path":"Billing","layoutMode":"anchored"}},{"name":"billing-check-in-form","slot":"extra-visit-attribute-slot","component":"billingCheckInForm"},{"name":"patient-banner-billing-tags","component":"visitAttributeTags","slot":"patient-banner-tags-slot","order":2},{"name":"initiate-payment-modal","component":"initiatePaymentDialog"},{"name":"delete-billableservice-modal","component":"deleteBillableServiceModal"},{"name":"refund-bill-modal","component":"refundBillModal"},{"name":"delete-bill-modal","component":"deleteBillModal"},{"name":"lab-order-billable-item","component":"labOrder","slot":"top-of-lab-order-form-slot"},{"name":"procedure-order-billable-item","component":"procedureOrder","slot":"top-of-procedure-order-form-slot"},{"name":"imaging-order-billable-item","component":"imagingOrder","slot":"top-of-imaging-order-form-slot"},{"name":"price-info-order","component":"priceInfoOrder"},{"name":"drug-order-billable-item","component":"drugOrder","slot":"medication-info-slot"},{"name":"order-action-button","component":"orderActionButton","slots":["prescription-action-button-slot","imaging-orders-action","procedure-orders-action","tests-ordered-actions-slot"],"order":0},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"claimsOverview","name":"claims-overview-dashboard-link","slot":"claims-management-overview-slot"},{"component":"waiveBillActionButton","name":"waive-bill-action-button","slot":"bill-actions-slot"},{"component":"deleteBillActionButton","name":"delete-bill-action-button","slot":"bill-actions-slot"},{"component":"refundLineItem","name":"refund-line-item","slot":"bill-actions-overflow-menu-slot"},{"name":"edit-line-item","component":"editLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"cancel-line-item","component":"cancelLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"patient-info-sha-status","component":"patientBannerShaStatus","slot":"patient-banner-tags-slot"},{"name":"payments-points-dashboard-link","component":"paymentPointDashboardLink","slot":"billing-admin-dashboard-slot","meta":{"name":"cashier-points","title":"Payment Point","slot":"payment-point-dashboard-slot"}},{"name":"payment-points-dashboard","component":"paymentPoints","slot":"payment-point-dashboard-slot"},{"name":"payment-mode-dashboard-link","component":"paymentModeLink","slot":"billing-admin-dashboard-slot","meta":{"name":"payment-modes","title":"Payment Mode","slot":"payment-mode-dashboard-slot"}},{"name":"payment-mode-dashboard","component":"paymentModeDashboard","slot":"payment-mode-dashboard-slot"},{"name":"bill-deposit-dashboard-link","component":"billDepositDashboardLink","slot":"billing-admin-dashboard-slot","meta":{"name":"bill-deposit","title":"Bill Deposit","slot":"billing-deposit-dashboard-slot"}},{"name":"bill-deposit-dashboard","component":"billDepositDashboard","slot":"billing-deposit-dashboard-slot"},{"name":"billable-exemptions-dashboard-link","component":"billableExemptionsLink","slot":"billing-admin-dashboard-slot","meta":{"name":"billable-exemptions","title":"Billable Exemptions","slot":"billing-exemptions-dashboard-slot"}},{"name":"billable-exemptions-dashboard","component":"billableExemptions","slot":"billing-exemptions-dashboard-slot"},{"name":"clinical-charges-dashboard-link","component":"clinicalChargesLink","slot":"billing-admin-dashboard-slot","meta":{"name":"clinical-charges","title":"Clinical Charges","slot":"clinical-charges-dashboard-slot"}},{"name":"clinical-charges-dashboard","component":"clinicalCharges","slot":"clinical-charges-dashboard-slot"},{"name":"payment-history-dashboard-link","component":"paymentHistoryLink","slot":"billing-admin-dashboard-slot","meta":{"name":"payment-history","title":"Payment History","slot":"payment-history-dashboard-slot"}},{"name":"payment-history-dashboard","component":"paymentHistoryDashboard","slot":"payment-history-dashboard-slot"},{"name":"patient-billing-dashboard-link","component":"patientBillingLink","slot":"billing-admin-dashboard-slot","meta":{"name":"patient-billing","title":"Patient Billing","slot":"patient-billing-dashboard-slot"}},{"name":"patient-billing-dashboard","component":"patientBilling","slot":"patient-billing-dashboard-slot"}],"workspaces":[{"name":"create-bill-workspace","component":"createBillWorkspace","title":"Create Bill Workspace","type":"other-form"},{"name":"waive-bill-form","component":"waiveBillForm","title":"Waive Bill Form","type":"other-form"},{"name":"edit-bill-form","component":"editBillForm","title":"Edit Bill Form","type":"other-form"},{"name":"billable-service-form","component":"addServiceForm","title":"Create Charge Item Form","type":"other-form"},{"name":"commodity-form","component":"commodityForm","title":"Charge Commodity Form","type":"other-form"},{"name":"billing-form","component":"billingForm","title":"Billing Form","type":"other-form","width":"extra-wide"},{"name":"payment-mode-workspace","component":"paymentModeWorkspace","title":"Payment Mode Workspace","type":"other-form"},{"name":"cancel-bill-workspace","component":"cancelBillWorkspace","title":"Cancel Bill Workspace","type":"other-form"},{"name":"add-deposit-workspace","component":"addDepositWorkspace","title":"Add Deposit","type":"other-form"},{"name":"deposit-transaction-workspace","component":"depositTransactionWorkspace","title":"Deposit Transaction","type":"other-form"},{"name":"payment-workspace","component":"paymentWorkspace","title":"Payment Workspace","type":"other-form"}],"modals":[{"name":"create-payment-point","component":"createPaymentPoint"},{"name":"clock-out-modal","component":"clockOut"},{"name":"bulk-import-billable-services-modal","component":"bulkImportBillableServicesModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"manage-claim-request-modal","component":"manageClaimRequestModal"},{"name":"claim-summary-modal","component":"claimSummaryModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"},{"name":"delete-deposit-modal","component":"deleteDepositModal"},{"name":"reverse-transaction-modal","component":"reverseTransactionModal"},{"name":"print-preview-modal","component":"printPreviewModal"},{"name":"bill-action-modal","component":"billActionModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"version":"5.4.2-pre.2835"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemr":"^19.0.0"},"pages":[{"component":"billableServicesHome","route":"billable-services"},{"component":"requirePaymentModal","routeRegex":"^patient/.+/chart","online":true,"offline":false},{"component":"billingAdmin","route":"billing-admin"}],"extensions":[{"component":"accountingDashboardLink","name":"accounting-dashboard-link","slots":["homepage-dashboard-slot"],"meta":{"name":"accounting","slot":"accounting-dashboard-slot","title":"Accounting"}},{"name":"billing-dashboard","component":"billingDashboard","slot":"accounting-dashboard-slot"},{"component":"benefitsPackageDashboardLink","name":"benefits-package-dashboard-link","meta":{"name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot","path":"insurance-benefits","columns":1,"columnSpan":1},"featureFlag":"healthInformationExchange"},{"component":"benefitsPackage","name":"benefits-package","slot":"patient-chart-benefits-dashboard-slot"},{"component":"root","name":"billing-dashboard-root","slot":"billing-dashboard-slot"},{"component":"benefitsEligibilyRequestForm","name":"benefits-eligibility-request-form"},{"component":"benefitsPreAuthForm","name":"benefits-pre-auth-form"},{"name":"billing-patient-summary","component":"billingPatientSummary","slot":"patient-chart-billing-dashboard-slot","order":10,"meta":{"columnSpan":4}},{"name":"billing-summary-dashboard-link","component":"billingSummaryDashboardLink","order":11,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-billing-dashboard-slot","path":"Billing","layoutMode":"anchored"}},{"name":"billing-check-in-form","slot":"extra-visit-attribute-slot","component":"billingCheckInForm"},{"name":"patient-banner-billing-tags","component":"visitAttributeTags","slot":"patient-banner-tags-slot","order":2},{"name":"initiate-payment-modal","component":"initiatePaymentDialog"},{"name":"delete-billableservice-modal","component":"deleteBillableServiceModal"},{"name":"refund-bill-modal","component":"refundBillModal"},{"name":"delete-bill-modal","component":"deleteBillModal"},{"name":"lab-order-billable-item","component":"labOrder","slot":"top-of-lab-order-form-slot"},{"name":"procedure-order-billable-item","component":"procedureOrder","slot":"top-of-procedure-order-form-slot"},{"name":"imaging-order-billable-item","component":"imagingOrder","slot":"top-of-imaging-order-form-slot"},{"name":"price-info-order","component":"priceInfoOrder"},{"name":"drug-order-billable-item","component":"drugOrder","slot":"medication-info-slot"},{"name":"order-action-button","component":"orderActionButton","slots":["prescription-action-button-slot","imaging-orders-action","procedure-orders-action","tests-ordered-actions-slot"],"order":0},{"component":"claimsManagementOverviewDashboardLink","name":"claims-management-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"preAuthRequestsDashboardLink","name":"preauthrequest-overview-link","slots":["claims-management-dashboard-link-slot"]},{"component":"claimsOverview","name":"claims-overview-dashboard-link","slot":"claims-management-overview-slot"},{"component":"waiveBillActionButton","name":"waive-bill-action-button","slot":"bill-actions-slot"},{"component":"deleteBillActionButton","name":"delete-bill-action-button","slot":"bill-actions-slot"},{"component":"refundLineItem","name":"refund-line-item","slot":"bill-actions-overflow-menu-slot"},{"name":"edit-line-item","component":"editLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"cancel-line-item","component":"cancelLineItem","slot":"bill-actions-overflow-menu-slot"},{"name":"patient-info-sha-status","component":"patientBannerShaStatus","slot":"patient-banner-tags-slot"},{"name":"payments-points-dashboard-link","component":"paymentPointDashboardLink","slot":"billing-admin-dashboard-slot","meta":{"name":"cashier-points","title":"Payment Point","slot":"payment-point-dashboard-slot"}},{"name":"payment-points-dashboard","component":"paymentPoints","slot":"payment-point-dashboard-slot"},{"name":"payment-mode-dashboard-link","component":"paymentModeLink","slot":"billing-admin-dashboard-slot","meta":{"name":"payment-modes","title":"Payment Mode","slot":"payment-mode-dashboard-slot"}},{"name":"payment-mode-dashboard","component":"paymentModeDashboard","slot":"payment-mode-dashboard-slot"},{"name":"bill-deposit-dashboard-link","component":"billDepositDashboardLink","slot":"billing-admin-dashboard-slot","meta":{"name":"bill-deposit","title":"Bill Deposit","slot":"billing-deposit-dashboard-slot"}},{"name":"bill-deposit-dashboard","component":"billDepositDashboard","slot":"billing-deposit-dashboard-slot"},{"name":"billable-exemptions-dashboard-link","component":"billableExemptionsLink","slot":"billing-admin-dashboard-slot","meta":{"name":"billable-exemptions","title":"Billable Exemptions","slot":"billing-exemptions-dashboard-slot"}},{"name":"billable-exemptions-dashboard","component":"billableExemptions","slot":"billing-exemptions-dashboard-slot"},{"name":"clinical-charges-dashboard-link","component":"clinicalChargesLink","slot":"billing-admin-dashboard-slot","meta":{"name":"clinical-charges","title":"Clinical Charges","slot":"clinical-charges-dashboard-slot"}},{"name":"clinical-charges-dashboard","component":"clinicalCharges","slot":"clinical-charges-dashboard-slot"},{"name":"payment-history-dashboard-link","component":"paymentHistoryLink","slot":"billing-admin-dashboard-slot","meta":{"name":"payment-history","title":"Payment History","slot":"payment-history-dashboard-slot"}},{"name":"payment-history-dashboard","component":"paymentHistoryDashboard","slot":"payment-history-dashboard-slot"},{"name":"patient-billing-dashboard-link","component":"patientBillingLink","slot":"billing-admin-dashboard-slot","meta":{"name":"patient-billing","title":"Patient Billing","slot":"patient-billing-dashboard-slot"}},{"name":"patient-billing-dashboard","component":"patientBilling","slot":"patient-billing-dashboard-slot"}],"workspaces":[{"name":"create-bill-workspace","component":"createBillWorkspace","title":"Create Bill Workspace","type":"other-form"},{"name":"waive-bill-form","component":"waiveBillForm","title":"Waive Bill Form","type":"other-form"},{"name":"edit-bill-form","component":"editBillForm","title":"Edit Bill Form","type":"other-form"},{"name":"billable-service-form","component":"addServiceForm","title":"Create Charge Item Form","type":"other-form"},{"name":"commodity-form","component":"commodityForm","title":"Charge Commodity Form","type":"other-form"},{"name":"billing-form","component":"billingForm","title":"Billing Form","type":"other-form","width":"extra-wide"},{"name":"payment-mode-workspace","component":"paymentModeWorkspace","title":"Payment Mode Workspace","type":"other-form"},{"name":"cancel-bill-workspace","component":"cancelBillWorkspace","title":"Cancel Bill Workspace","type":"other-form"},{"name":"add-deposit-workspace","component":"addDepositWorkspace","title":"Add Deposit","type":"other-form"},{"name":"deposit-transaction-workspace","component":"depositTransactionWorkspace","title":"Deposit Transaction","type":"other-form"},{"name":"payment-workspace","component":"paymentWorkspace","title":"Payment Workspace","type":"other-form"}],"modals":[{"name":"create-payment-point","component":"createPaymentPoint"},{"name":"clock-out-modal","component":"clockOut"},{"name":"bulk-import-billable-services-modal","component":"bulkImportBillableServicesModal"},{"name":"delete-payment-mode-modal","component":"deletePaymentModeModal"},{"name":"manage-claim-request-modal","component":"manageClaimRequestModal"},{"name":"claim-summary-modal","component":"claimSummaryModal"},{"name":"clock-in-modal","component":"clockIn"},{"name":"create-bill-item-modal","component":"createBillItemModal"},{"name":"delete-deposit-modal","component":"deleteDepositModal"},{"name":"reverse-transaction-modal","component":"reverseTransactionModal"},{"name":"print-preview-modal","component":"printPreviewModal"},{"name":"bill-action-modal","component":"billActionModal"},{"name":"require-billing-modal","component":"requirePaymentModal"}],"version":"5.4.2-pre.2843"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-billing-app",
3
- "version": "5.4.2-pre.2835",
3
+ "version": "5.4.2-pre.2843",
4
4
  "description": "Billing app for KenyaEMR",
5
5
  "keywords": [
6
6
  "openmrs"
@@ -1,6 +1,6 @@
1
- import React, { type HTMLAttributes, useEffect, useRef, useState } from 'react';
2
1
  import { Layer, Search } from '@carbon/react';
3
2
  import classNames from 'classnames';
3
+ import React, { type HTMLAttributes, ReactNode, useEffect, useRef, useState } from 'react';
4
4
  import styles from './autosuggest.scss';
5
5
 
6
6
  // FIXME Temporarily included types from Carbon
@@ -104,6 +104,8 @@ interface AutosuggestProps extends SearchProps {
104
104
  onSuggestionSelected: (field: string, value: string) => void;
105
105
  invalid?: boolean | undefined;
106
106
  invalidText?: string | undefined;
107
+ renderEmptyState?: (searchValue: string) => ReactNode;
108
+ renderSuggestionItem?: (item: any) => ReactNode;
107
109
  }
108
110
 
109
111
  export const Autosuggest: React.FC<AutosuggestProps> = ({
@@ -113,9 +115,12 @@ export const Autosuggest: React.FC<AutosuggestProps> = ({
113
115
  onSuggestionSelected,
114
116
  invalid,
115
117
  invalidText,
118
+ renderEmptyState,
119
+ renderSuggestionItem,
116
120
  ...searchProps
117
121
  }) => {
118
122
  const [suggestions, setSuggestions] = useState([]);
123
+ const [showEmptyState, setShowEmptyState] = useState(false);
119
124
  const searchBox = useRef(null);
120
125
  const wrapper = useRef(null);
121
126
  const { id: name, labelText } = searchProps;
@@ -131,6 +136,7 @@ export const Autosuggest: React.FC<AutosuggestProps> = ({
131
136
  const handleClickOutsideComponent = (e) => {
132
137
  if (wrapper.current && !wrapper.current.contains(e.target)) {
133
138
  setSuggestions([]);
139
+ setShowEmptyState(false);
134
140
  }
135
141
  };
136
142
 
@@ -140,6 +146,7 @@ export const Autosuggest: React.FC<AutosuggestProps> = ({
140
146
 
141
147
  if (query) {
142
148
  getSearchResults(query).then((suggestions) => {
149
+ setShowEmptyState(suggestions.length < 1);
143
150
  setSuggestions(suggestions);
144
151
  });
145
152
  } else {
@@ -175,12 +182,21 @@ export const Autosuggest: React.FC<AutosuggestProps> = ({
175
182
  {suggestions.length > 0 && (
176
183
  <ul className={styles.suggestions}>
177
184
  {suggestions.map((suggestion, index) => (
178
- <li key={index} onClick={(e) => handleClick(index)} role="presentation">
179
- {getDisplayValue(suggestion)}
185
+ <li
186
+ key={index}
187
+ onClick={(e) => handleClick(index)}
188
+ role="presentation"
189
+ className={typeof renderSuggestionItem !== 'function' && styles.displayText}>
190
+ {typeof renderSuggestionItem === 'function'
191
+ ? renderSuggestionItem(suggestion)
192
+ : getDisplayValue(suggestion)}
180
193
  </li>
181
194
  ))}
182
195
  </ul>
183
196
  )}
197
+ {showEmptyState && searchBox.current?.value?.length >= 3 && typeof renderEmptyState === 'function' && (
198
+ <span className={styles.suggestions}>{renderEmptyState(searchBox.current?.value)}</span>
199
+ )}
184
200
  {invalid ? <label className={classNames(styles.invalidMsg)}>{invalidText}</label> : <></>}
185
201
  </div>
186
202
  );
@@ -1,6 +1,7 @@
1
- @use '@carbon/styles/scss/spacing';
2
- @use '@carbon/styles/scss/type';
3
- @use '@openmrs/esm-styleguide/src/vars' as *;
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
+ @use '@carbon/colors';
4
+ @use '~@openmrs/esm-styleguide/src/vars' as *;
4
5
 
5
6
  .label01 {
6
7
  @include type.type-style('label-01');
@@ -11,32 +12,35 @@
11
12
  border-top-width: 0;
12
13
  list-style: none;
13
14
  margin-top: 0;
14
- max-height: 143px;
15
+ max-height: 400px;
15
16
  overflow-y: auto;
16
17
  padding-left: 0;
17
18
  width: 100%;
18
19
  position: absolute;
19
20
  left: 0;
20
- background-color: #fff;
21
+ background-color: colors.$white;
21
22
  margin-bottom: 20px;
22
23
  z-index: 99;
24
+ box-shadow: layout.$spacing-03 layout.$spacing-03 layout.$spacing-03 layout.$spacing-03 colors.$gray-30;
23
25
  }
24
26
 
25
27
  .suggestions li {
26
- padding: spacing.$spacing-05;
27
- line-height: 1.29;
28
- color: #525252;
29
- border-bottom: 1px solid #8d8d8d;
28
+ color: colors.$gray-70;
29
+ border-bottom: 1px solid colors.$gray-50;
30
+ }
31
+
32
+ .displayText {
33
+ padding: layout.$spacing-05;
30
34
  }
31
35
 
32
36
  .suggestions li:hover {
33
37
  background-color: #e5e5e5;
34
- color: #161616;
38
+ color: colors.$gray-100;
35
39
  cursor: pointer;
36
40
  }
37
41
 
38
42
  .suggestions li:not(:last-of-type) {
39
- border-bottom: 1px solid #999;
43
+ border-bottom: 1px solid colors.$gray-40-hover;
40
44
  }
41
45
 
42
46
  .autocomplete {
@@ -53,10 +57,12 @@
53
57
  }
54
58
 
55
59
  .invalid input {
56
- outline: 2px solid var(--cds-support-error, #da1e28);
60
+ outline: 2px solid var(--cds-support-error, colors.$red-60);
57
61
  outline-offset: -2px;
62
+ margin-bottom: layout.$spacing-02;
58
63
  }
59
64
 
60
65
  .invalidMsg {
61
- color: var(--cds-text-error, #da1e28);
66
+ color: var(--cds-text-error, colors.$red-60);
67
+ font-size: small;
62
68
  }
@@ -0,0 +1,29 @@
1
+ import { Tag, Tile } from '@carbon/react';
2
+ import { Patient, PatientPhoto } from '@openmrs/esm-framework';
3
+ import React from 'react';
4
+ import styles from './patient-search-info.scss';
5
+ type PatientSearchInfoProps = {
6
+ patient: Patient;
7
+ };
8
+
9
+ const PatientSearchInfo: React.FC<PatientSearchInfoProps> = ({ patient }) => {
10
+ return (
11
+ <Tile className={styles.patientInfo}>
12
+ <div className={styles.patientAvatar} role="img">
13
+ <PatientPhoto patientUuid={patient.uuid} patientName={patient.person.display} />
14
+ </div>
15
+ <div className={styles.patientDetails}>
16
+ <h2 className={styles.patientName}>{patient.person.display}</h2>
17
+ <div className={styles.demographics}>
18
+ {patient?.person?.gender} <span className={styles.middot}>&middot;</span> {patient?.person?.age}
19
+ <span className={styles.middot}>&middot;</span>
20
+ <Tag>
21
+ OpenmrsId:{patient.identifiers.find((id) => id.identifierType.display === 'OpenMRS ID')?.identifier}
22
+ </Tag>
23
+ </div>
24
+ </div>
25
+ </Tile>
26
+ );
27
+ };
28
+
29
+ export default PatientSearchInfo;
@@ -0,0 +1,37 @@
1
+ @use '@carbon/colors';
2
+ @use '@carbon/layout';
3
+ @use '@carbon/type';
4
+
5
+ .patientInfo {
6
+ display: flex;
7
+ justify-content: space-between;
8
+ align-items: flex-start;
9
+ gap: 2rem;
10
+ background-color: colors.$white;
11
+ }
12
+
13
+ .patientInfo:hover {
14
+ background-color: colors.$gray-10;
15
+ }
16
+
17
+ .patientDetails {
18
+ flex: 1;
19
+ }
20
+
21
+ .patientName {
22
+ @include type.type-style('heading-02');
23
+ color: colors.$gray-70;
24
+ margin-bottom: layout.$spacing-02;
25
+ }
26
+
27
+ .demographics {
28
+ display: flex;
29
+ align-items: center;
30
+ margin-bottom: layout.$spacing-02;
31
+ color: colors.$gray-70;
32
+ text-transform: uppercase;
33
+ }
34
+
35
+ .middot {
36
+ margin: 0 0.25rem;
37
+ }
@@ -0,0 +1,27 @@
1
+ import { Button, Tile } from '@carbon/react';
2
+ import { Add } from '@carbon/react/icons';
3
+ import { EmptyDataIllustration } from '@openmrs/esm-patient-common-lib';
4
+ import React from 'react';
5
+ import styles from './search-empty-state.scss';
6
+
7
+ type SearchEmptyStateProps = {
8
+ searchValue?: string;
9
+ message: string;
10
+ onAdd?: () => void;
11
+ };
12
+
13
+ const SearchEmptyState: React.FC<SearchEmptyStateProps> = ({ searchValue, message, onAdd }) => {
14
+ return (
15
+ <Tile className={styles.container}>
16
+ <EmptyDataIllustration height="50" width="50" />
17
+ <p>{message}</p>
18
+ {typeof onAdd === 'function' && (
19
+ <Button kind="ghost" renderIcon={Add} onClick={onAdd}>
20
+ Create patient
21
+ </Button>
22
+ )}
23
+ </Tile>
24
+ );
25
+ };
26
+
27
+ export default SearchEmptyState;
@@ -0,0 +1,18 @@
1
+ @use '@carbon/layout';
2
+ @use '@carbon/colors';
3
+
4
+ .container {
5
+ display: flex;
6
+ flex-direction: column;
7
+ align-items: center;
8
+ justify-content: center;
9
+ gap: layout.$spacing-01;
10
+ font-size: xx-small;
11
+ background-color: colors.$white;
12
+ border: solid 1px colors.$gray-30;
13
+ color: colors.$gray-50;
14
+ }
15
+
16
+ .emptyIllustration {
17
+ color: colors.$teal-70;
18
+ }
@@ -12,31 +12,33 @@ import {
12
12
  } from '@carbon/react';
13
13
  import { DocumentAttachment } from '@carbon/react/icons';
14
14
  import { zodResolver } from '@hookform/resolvers/zod';
15
- import { DefaultWorkspaceProps, showSnackbar, useSession } from '@openmrs/esm-framework';
15
+ import { DefaultWorkspaceProps, Patient, restBaseUrl, showSnackbar, useSession } from '@openmrs/esm-framework';
16
16
  import { ErrorState } from '@openmrs/esm-patient-common-lib';
17
- import React, { useEffect, useRef, useState } from 'react';
17
+ import React, { FC, useEffect, useRef, useState } from 'react';
18
18
  import { Controller, FormProvider, useForm } from 'react-hook-form';
19
19
  import { useTranslation } from 'react-i18next';
20
20
  import { z } from 'zod';
21
+ import { Autosuggest } from '../../autosuggest/autosuggest.component';
22
+ import PatientSearchInfo from '../../autosuggest/patient-search-info.component';
23
+ import SearchEmptyState from '../../autosuggest/search-empty-state.component';
21
24
  import { useVisit } from '../../claims/dashboard/form/claims-form.resource';
22
25
  import { MAX_ALLOWED_FILE_SIZE } from '../../constants';
23
26
  import { useSystemSetting } from '../../hooks/getMflCode';
24
27
  import usePatientDiagnosis from '../../hooks/usePatientDiagnosis';
25
28
  import useProvider from '../../hooks/useProvider';
26
- import { PatientBenefit } from '../../types';
27
29
  import { preAuthenticateBenefit, preauthSchema } from '../benefits-package.resources';
28
30
  import styles from './benefits-pre-auth-form.scss';
29
31
  import SHABenefitPackangesAndInterventions from './packages-and-interventions-form.component';
32
+ import { searchPatient } from './preauth.resources';
33
+ import { mutate } from 'swr';
30
34
 
31
35
  type BenefitsPreAuth = z.infer<typeof preauthSchema>;
32
36
 
33
- interface BenefitPreAuthFormProps extends DefaultWorkspaceProps {
37
+ interface BenefitPreAuthFormProps extends Pick<DefaultWorkspaceProps, 'closeWorkspace'> {
34
38
  patientUuid: string;
35
- benefit: PatientBenefit;
36
- onSuccess: (benefits: Array<PatientBenefit>) => void;
37
39
  }
38
40
 
39
- const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace, patientUuid }) => {
41
+ const FormFields: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace, patientUuid }) => {
40
42
  const { t } = useTranslation();
41
43
  const { visits: recentVisit, isLoading, error: visitError } = useVisit(patientUuid);
42
44
  const { isLoading: diagnosesLoading, diagnoses } = usePatientDiagnosis(patientUuid);
@@ -93,6 +95,9 @@ const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace,
93
95
  try {
94
96
  await preAuthenticateBenefit(values, recentVisit, mflCodeValue);
95
97
  showSnackbar({ title: 'Success', kind: 'success', subtitle: 'Preauth Approved succesfully' });
98
+ mutate((key) => {
99
+ return typeof key === 'string' && key.startsWith(`${restBaseUrl}/claim`);
100
+ });
96
101
  closeWorkspace();
97
102
  } catch (error) {
98
103
  showSnackbar({ title: 'Failure', kind: 'error', subtitle: 'Error requesting Eligibility' });
@@ -251,4 +256,37 @@ const BenefitPreAuthForm: React.FC<BenefitPreAuthFormProps> = ({ closeWorkspace,
251
256
  );
252
257
  };
253
258
 
259
+ const BenefitPreAuthForm: FC<DefaultWorkspaceProps> = ({ closeWorkspace }) => {
260
+ const { t } = useTranslation();
261
+ const [patientUuid, setPatientUuid] = useState<string | null>(null);
262
+
263
+ return (
264
+ <>
265
+ {patientUuid ? (
266
+ <FormFields patientUuid={patientUuid} closeWorkspace={closeWorkspace} />
267
+ ) : (
268
+ <div className={styles.input}>
269
+ <Autosuggest
270
+ labelText={t('patient', 'Patient')}
271
+ placeholder={t('patientPlaceHolder', 'Search patient')}
272
+ getDisplayValue={(item: Patient) => item.person.display}
273
+ renderSuggestionItem={(item: Patient) => <PatientSearchInfo patient={item} />}
274
+ getFieldValue={(item: Patient) => item.uuid}
275
+ getSearchResults={searchPatient}
276
+ renderEmptyState={(value) => (
277
+ <SearchEmptyState searchValue={value} message={t('patientNotFound', 'Patient Not Found')} />
278
+ )}
279
+ onClear={() => setPatientUuid(null)}
280
+ onSuggestionSelected={(_, value) => {
281
+ if (value) {
282
+ setPatientUuid(value);
283
+ }
284
+ }}
285
+ />
286
+ </div>
287
+ )}
288
+ </>
289
+ );
290
+ };
291
+
254
292
  export default BenefitPreAuthForm;
@@ -60,3 +60,7 @@
60
60
  padding-left: layout.$spacing-05;
61
61
  }
62
62
  }
63
+
64
+ .input {
65
+ margin: 0 layout.$spacing-05 0 layout.$spacing-05;
66
+ }
@@ -0,0 +1,17 @@
1
+ import { openmrsFetch, Patient, restBaseUrl } from '@openmrs/esm-framework';
2
+
3
+ export async function fetchPerson(query: string, abortController: AbortController) {
4
+ const customREp = 'custom:(uuid,identifiers,person:(uuid,display,gender,age,birthdate,attributes))';
5
+ const patientsRes = await openmrsFetch<{ results: Array<Patient> }>(
6
+ `${restBaseUrl}/patient?q=${query}&v=${customREp}`,
7
+ {
8
+ signal: abortController.signal,
9
+ },
10
+ );
11
+ return patientsRes?.data?.results ?? [];
12
+ }
13
+
14
+ export const searchPatient = async (query: string) => {
15
+ const abortController = new AbortController();
16
+ return await fetchPerson(query, abortController);
17
+ };
@@ -45,6 +45,7 @@ const ClaimsTable: React.FC<TableProps> = ({
45
45
  emptyStateHeader,
46
46
  includeClaimCode = false,
47
47
  use = 'claim',
48
+ renderActionButton,
48
49
  }) => {
49
50
  const { claims, isLoading } = useFacilityClaims();
50
51
  const { t } = useTranslation();
@@ -140,6 +141,7 @@ const ClaimsTable: React.FC<TableProps> = ({
140
141
  if (claimsByUse.length === 0) {
141
142
  return (
142
143
  <div className={styles.claimsTable}>
144
+ <div className={styles.actionsContainer}>{renderActionButton && renderActionButton()}</div>
143
145
  <EmptyState displayText={t(emptyStateText)} headerTitle={t(emptyStateHeader)} />
144
146
  </div>
145
147
  );
@@ -219,6 +221,7 @@ const ClaimsTable: React.FC<TableProps> = ({
219
221
 
220
222
  return (
221
223
  <div className={styles.dataTableSkeleton}>
224
+ <div className={styles.actionsContainer}>{renderActionButton && renderActionButton()}</div>
222
225
  <div className={styles.tableHeader}>
223
226
  <CardHeader title={t(title)}>{''}</CardHeader>
224
227
  <ClaimsFilterHeader
@@ -26,6 +26,14 @@
26
26
  padding: layout.$spacing-05;
27
27
  }
28
28
 
29
+ .actionsContainer {
30
+ display: flex;
31
+ justify-content: flex-end;
32
+ align-items: center;
33
+ gap: layout.$spacing-05;
34
+ margin-bottom: layout.$spacing-03;
35
+ }
36
+
29
37
  .claimStatus {
30
38
  display: flex;
31
39
  align-items: center;
@@ -1,7 +1,17 @@
1
1
  import React from 'react';
2
2
  import ClaimsTable from './claim-table.component';
3
+ import { Button } from '@carbon/react';
4
+ import { launchWorkspace } from '@openmrs/esm-framework';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { Add } from '@carbon/react/icons';
3
7
 
4
8
  const PreauthTableTemporary: React.FC = () => {
9
+ const handleLaunchPreAuthForm = () => {
10
+ launchWorkspace('benefits-pre-auth-form', {
11
+ workspaceTitle: t('preAuthForm', 'Pre Auth Form'),
12
+ });
13
+ };
14
+ const { t } = useTranslation();
5
15
  return (
6
16
  <ClaimsTable
7
17
  title="preauthsRequests"
@@ -9,6 +19,11 @@ const PreauthTableTemporary: React.FC = () => {
9
19
  emptyStateHeader="Preauth"
10
20
  includeClaimCode={false}
11
21
  use="preauthorization"
22
+ renderActionButton={() => (
23
+ <Button kind="primary" renderIcon={Add} onClick={handleLaunchPreAuthForm}>
24
+ {t('addPreauthRequest', 'Add Preauth Request')}
25
+ </Button>
26
+ )}
12
27
  />
13
28
  );
14
29
  };
@@ -621,6 +621,7 @@ export interface TableProps {
621
621
  emptyStateHeader: string;
622
622
  includeClaimCode?: boolean;
623
623
  use?: string;
624
+ renderActionButton?: () => React.ReactNode;
624
625
  }
625
626
 
626
627
  export interface ProgressTracker {