Skip to content

(fix) O3-5666: Handle Call action failures in the queue table - #2649

Draft
dkayiwa wants to merge 7 commits into
mainfrom
O3-5666-handle-call-action-errors
Draft

dkayiwa wants to merge 7 commits into
mainfrom
O3-5666-handle-call-action-errors

Conversation

@dkayiwa

@dkayiwa dkayiwa commented Jul 31, 2026

Copy link
Copy Markdown
Member

Requirements

  • This PR has a title that briefly describes the work done including the ticket number.
  • My work is based on designs, which are linked or shown either in the Jira ticket or the description below.
  • My work includes tests or is validated by existing tests.

Summary

Fixes O3-5666.

What was wrong

The call row action in the service queues table (queue-table-action-cell.component.tsx) awaited serveQueueEntry with no rejection handler:

onClick: async (queueEntry: QueueEntry) => {
  const mappedQueueEntry = mapVisitQueueEntryProperties(queueEntry, visitQueueNumberAttributeUuid);
  const callingQueueResponse = await serveQueueEntry(
    mappedQueueEntry.queue.name,
    mappedQueueEntry.visitQueueNumber,
    callingStatus,
  );
  if (callingQueueResponse.ok) { /* ... */ }
}

Both call sites throw the returned promise away — ActionButton awaits it inside a bare try/finally, and ActionOverflowMenuItem passes it straight to a DOM onClick. So any failure from POST /ws/rest/v1/queueutil/assignticket became an unhandled promise rejection:

  • in a development build, React's error overlay turns it into a full-screen "Uncaught runtime errors: TypeError: Failed to fetch" that only a page reload clears;
  • in a production build the overlay is disabled, so the Call button silently appears to do nothing.

Because openmrsFetch rejects on a non-2xx response, the callingQueueResponse.ok branch never actually ran for server errors — it just skipped opening the modal for the (unreachable) non-throwing case.

Separately, the request was posted without checking that the queue name, ticket number and calling status were present. The ticket number comes from a visit attribute, so it is missing whenever a visit was created outside the queue flow. JSON.stringify drops the undefined key, so what actually went over the wire was {"servicePointName":"Outpatient Triage","status":"calling"} — the queue module accepts it, and the "Serve patient" modal opens as though the patient had been called with a number they do not have.

What changed

queue-table/cells/queue-table-action-cell.component.tsx

  • The call action validates the queue name, ticket number and calling status before posting, and shows a red snackbar naming what is missing instead of sending an incomplete request. The message distinguishes the two situations: the ticket number lives on the visit, so a clerk who hits that case cannot fix it by "checking the configuration"; the other case does point at the configuration, and says so in a way that names whose job it is rather than naming the configuration properties.
  • The request is wrapped in try/catch; every failure is surfaced with showSnackbar({ kind: 'error' }) using getErrorMessage() from modals/queue-entry-error.utils, matching how the sibling queue entry mutations (queue-entry-actions-modal.component.tsx, call-queue-entry.modal.tsx) report errors. A response that resolves without a result falls back to the existing unexpectedServerResponse message.
  • A runAction() helper wraps both invocation sites (inline button and overflow menu item) so that a rejection an action does not handle itself is reported rather than escaping as an unhandled rejection. ActionProps.onClick is now typed void | Promise<void> to reflect what it already was.
  • Both invocation sites also share one in-flight guard, useSingleFlight(), so a click that arrives while the previous one's request is still running is discarded. Neither control is disabled while it runs — see the accessibility section — so nothing in the DOM does this, and it has to be a ref rather than state because the second click can arrive before React has re-rendered from the first. On a live queue table the inline button already held (the guard was added with the rest of this change); the overflow menu item did not, and two clicks 85ms apart on it sent two POST /queueutil/assignticket requests for one intended call.
  • The action no longer calls mapVisitQueueEntryProperties, a twenty-five field mapper with date parsing in it, to read two fields on every click. It reads the queue name off the entry and the ticket number through a small shared getVisitQueueNumber, which the mapper itself now uses.
  • The success path is unchanged: on a 2xx the queue entries are re-fetched and the call-queue-entry-modal ("Serve patient") opens as before.

modals/call-modal/call-queue-entry.modal.tsx — the "Serve" button inside that modal fires a second assignticket request, chained off updateQueueEntry's success. A rejection handler passed to .then() does not cover a promise created inside its own fulfilment callback, so this request had no handler at all: the same defect, one click further on. It now has one. Three further things in the same file:

  • All three of the modal's rejection handlers now report through one local reportFailure() that cannot itself throw. The row-action path already guarded its reporting, because a throw while reporting — a snackbar store that is itself the broken thing, say — escapes a rejection handler as exactly the unhandled rejection the report was added to replace. This path did not, so the two behaved differently under the same failure.
  • The requeue and queue-entry-update handlers read error?.message rather than getErrorMessage(error), which showed the wrapper's "Server responded with 500 …" instead of the wording the server itself sent in responseBody, and handed a non-string straight to a snackbar subtitle, where React cannot render it. Both now go through getErrorMessage, like every other queue entry mutation in the app.
  • When only the ticket-display request fails, updateQueueEntry has already succeeded: the queue entry has ended and been replaced by one carrying the transition status. Verified on the running standalone — the newly created entry comes back from the API as "In Service". Reporting that as "Error calling patient" told the user nothing had happened when the patient had in fact moved on, and left the table behind the modal showing a status that is no longer true, with nothing to revalidate it (the queue entries have no refresh interval). It now says "The patient has been moved on in the queue, but the ticket display was not updated" and re-reads the table. Repairing the half-done transition is deliberately still not attempted; see the deferrals below.
  • mutateQueueEntries() was called bare from three promise handlers. It rejects when a re-read fails, so each of those was a floating rejection of its own; they now go through a refetchQueueEntries() that logs instead.

service-queues.resource.tsgetVisitQueueNumber, extracted from the mapper so both callers read the attribute the same way.

modals/queue-entry-error.utils.tsgetErrorMessage declares that it returns a string, but it reads a shape the REST API documents rather than one anything enforces. It now keeps that promise, so a rejection carrying a non-string message produces the caller's generic fallback rather than being handed to a snackbar subtitle, where a non-string is a React render crash.

Five new translation keys: errorCallingPatient, callPatientNoTicketNumber, callPatientMissingConfiguration, queueEntryActionFailed and patientMovedButNotCalled.

Tests

queue-table-action-cell.test.tsx gains fifteen cases and call-queue-entry.test.tsx gains eleven: the success path including the queue re-fetch that precedes the modal; a rejected request; a rejection carrying the server's own message in responseBody; a rejection carrying no message; a rejection whose message is not text; a response that resolves with no result; each of the three missing-detail guards; the same failure launched from the overflow menu; three for the runAction net, one of which fails the reporting itself; the failed Serve request with and without a message; the pending Call button keeping focus and its place in the tab order; a rapid double-click on the overflow menu item, which must send one request and must let a deliberate later click through; the ticket-display failure saying the patient has moved on and re-reading the table; each of the modal's three rejection handlers surviving a snackbar that throws while it reports; the requeue and update handlers showing the server's own message and falling back when it is not text; and a queue re-read that fails.

Twenty-five of those twenty-six fail when the two source files are reverted to main, and Vitest reports eleven unhandled rejections in that run — which is the same defect the user sees as the crash overlay:

 Test Files  2 failed (2)
      Tests  25 failed | 9 passed (34)

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Vitest caught 11 unhandled errors during the test run.

Every guard, catch and fallback this PR adds was then broken deliberately, one at a time — twenty-eight mutants, twenty-eight killed, no survivors. The ten added in this revision: the overflow item losing its in-flight guard, that guard never blocking, that guard never releasing, the inline button losing it, the modal's reporting losing its own guard, the ticket-display failure going back to "Error calling patient", that path not re-reading the table, each of the two handlers going back to error?.message, and the queue re-read's rejection going unhandled.

Coverage over the four touched files puts a test on every line and every branch the PR adds. The uncovered remainder of queue-table-action-cell.component.tsx (82.6% statements, 81.6% branches) is pre-existing unknown-action, showIf and layout guards plus the modal-opening bodies of the unrelated row actions; the uncovered remainder of call-queue-entry.modal.tsx (92.1% statements, 83.3% branches) is the pre-existing identifier list rendering.

Whole package: Test Files 28 passed (28) · Tests 166 passed (166). Repo-wide yarn verify — what CI runs — is green across all 27 tasks, and prettier --check is clean.

Screenshots

No design changes; the visible difference is the failure feedback described in the table below, and the exact snackbar text is quoted there. No images are attached — this description is maintained through the GitHub API, which cannot upload them. Say the word if a reviewer wants screenshots and I will add them through the web UI.

Related Issue

https://openmrs.atlassian.net/browse/O3-5666

Other

How this was verified in a browser

Beyond unit tests, every row below was driven end to end, twice: once with the branch's source and once with the two source files reverted to main.

  • Backend: OpenMRS Reference Application standalone 3.7.1 on http://localhost:8081/openmrs, with the queue module and a live POST /ws/rest/v1/queueutil/assignticket endpoint.
  • Frontend: openmrs develop --port 9000 --backend http://localhost:8081 --sources packages/esm-service-queues-app — a development build, so React's error overlay is active.
  • Fixture: patient Betty Williams, active visit, Visit Queue Number visit attribute TRI-042, queue entry in Outpatient Triage with status Waiting so the Call button renders.
  • Failures were injected with Playwright request interception on **/ws/rest/v1/queueutil/assignticket. The missing-ticket-number case was produced by setting visitQueueNumberAttributeUuid to "", which is how the reference application ships it.
  • The overflow-menu rows need call in actions.overflowMenu, which is not the default, so those runs set queueTables.columnDefinitions to { buttons: ['edit'], overflowMenu: ['call', 'remove'] } through the SPA's own temporary-config store.
Scenario Before (main) After
Call, request aborted 1 dev-overlay iframe; pageerror: TypeError: Failed to fetch; no snackbar Red snackbar "Error calling patient / Failed to fetch"; 0 overlay iframes; no page errors; table still rendered; Call button still focused and operable
Call, server 500 pageerror: Uncaught (in promise) Error: Server responded with 500 (Internal Server Error) for url /openmrs/ws/rest/v1/queueutil/assignticket; no snackbar; nothing opens Red snackbar "Error calling patient / Ticket display service is unavailable" — the server's own message, not the wrapper
Call, visitQueueNumberAttributeUuid blank Request posted as {"servicePointName":"Outpatient Triage","status":"calling"} — no ticket number at all — and the "Serve patient" modal opened as if it had worked No request sent; red snackbar "Error calling patient / This patient's visit has no ticket number, so there is nothing for the queue screen to call."
Serve inside the modal, request aborted 1 dev-overlay iframe; pageerror: TypeError: Failed to fetch; no snackbar 0 overlay iframes; red snackbar naming what happened (row below); no page errors
Serve inside the modal, ticket display returns 500 Snackbar "Error calling patient / …" — claims the call failed, while the API shows the entry has already been ended and replaced by one reading "In Service"; table behind still shows the old status Red snackbar "The patient has been moved on in the queue, but the ticket display was not updated / Ticket display service is unavailable"; the table behind is re-read (two GET /queue-entry); no page errors. Pressing Serve again sends only the endedAt POST and the backend refuses it — "Error updating queue entry / Invalid Submission" — so a second press cannot double-transition the entry
Rapid double-click on the inline Call button (2 clicks 85ms apart, request held for 2s) 1 assignticket POST 1 assignticket POST
Rapid double-click on the Call overflow menu item (same timing) 2 assignticket POSTs, 85ms apart, identical bodies 1 assignticket POST
A deliberate click after the first request has failed and settled, both controls 2 POSTs total, i.e. the guard releases and a retry still works
Call, no interception "Serve patient" modal opens unchanged — "Serve patient" modal opens

In every failing scenario the page stayed interactive and no reload was needed.

The error handler is not allowed to be the next crash

The whole change is failure handling, so the failure was fuzzed: getErrorMessage and both catch blocks were fed the range a rejected openmrsFetch can carry — a plain Error, an empty one, a TypeError, a bare string, a number, null, undefined, false, {}, a Response-like object with and without responseBody, responseBody as a string, error as a string, rawMessage/translatedMessage/message, fieldErrors with no message, a null-prototype object, an array, a frozen error. All of them produce a readable snackbar and nothing escapes.

Two did not, and both are fixed above:

  • a rejection whose message is not a string reached showSnackbar as an object, which React cannot render;
  • a throw inside the reporting — showSnackbar itself failing, say — escaped runAction as an unhandled rejection, putting back the exact crash the net exists to prevent. The reporting is now guarded, so runAction cannot reject.

The last-resort net also only wrote to the console at first. That leaves the production half of the defect — a click that appears to do nothing — in place for any failure an action does not report itself, so it shows a snackbar too.

Accessibility

This change replaces a silent failure with a visible message, so it was checked against what a
keyboard-only and a screen-reader user actually get. Driven on the same standalone with Playwright,
with axe-core 4.12.1 injected into the running page.

Fixed here: the click no longer destroys focus. disabled removes a button from the tab order,
so pressing Call dropped focus onto document.body before the request had even been sent —
measured, not inferred. Getting back to the button to read the outcome or retry then meant tabbing
in from the top of a queue table that is one row per waiting patient. The button now carries
aria-disabled and aria-busy instead; focus was re-measured on the running page and stays on the
Call button through the request and after the failure. The useSingleFlight() ref, not the
attribute, is what discards the second click; because an aria-disabled button is still clickable,
that was re-measured on the running page after this change — a rapid double-click on the inline Call
button sends one request, and a deliberate click once the first has settled sends a second.
Carbon's --btn--disabled class was deliberately not used to keep the greyed-out look, because it
pairs the disabled colour with outline: none on :focus and would hide the focus ring on the
button we are keeping focused; the trade is that a sighted user no longer sees the button dim for
the length of a request.

Not fixed here: the snackbar is announced to nobody. showSnackbar renders Carbon's
ActionableNotification, which defaults to role="alertdialog" — a dialog role, not a live region.
On the running page the snackbar node carries role="alertdialog", no aria-live, and no ancestor
with one anywhere up to <body>; .omrs-snackbars-container has neither a role nor aria-live.
An alertdialog is announced only when focus moves into it, and the Carbon effect that would do
that looks for button.cds--actionable-notification__action-button — which OpenMRS's snackbar never
renders, because it passes actionButtonLabel: ''. Focus was sampled before, during and after the
failure and never entered the notification. axe reports zero violations on the snackbar, which
is exactly the point: the markup is valid ARIA and still silent. If we ship without this, a
screen-reader user on a failed Call is left with precisely the silent no-op O3-5666 set out to
remove, because the message is placed in a role="alertdialog" that nothing ever focuses.
The fix
belongs in @openmrs/esm-styleguide (snackbars/snackbar.component.tsx): a snackbar with no action
button should use Carbon's ToastNotification, whose default role="status" is a live region, or
pass role="alert". That was tried here as an experiment and does reach the DOM — but only because
SnackbarDescriptor's unknown keys happen to be spread onto the Carbon component, so it needs a
type assertion, it leaves Carbon's two focusable "Focus sentinel" spans inside the announced region,
and it would patch three call sites of a defect that affects every snackbar in O3. It was reverted.

Other framework-level findings, all pre-existing and none introduced here:

  • The modal frame has role="dialog" aria-modal="true" and no accessible name — axe
    aria-dialog-name, serious, the only violation inside the Serve modal. createModalFrame in
    esm-styleguide/modals never sets one and ModalProps carries only size. If we ship without
    this, a screen-reader user is told "dialog" with no indication of which one, because the frame
    has no aria-label or aria-labelledby.
  • Nothing moves focus into an OpenMRS modal when it opens, and Tab walks straight out of it into
    the navigation behind. If we ship without this, a keyboard user who opens "Serve patient" is
    still standing on the Call button behind it, because the modal host renders aria-modal="true"
    without a focus trap.
  • .omrs-snackbars-container sits before #omrs-apps-container in the app shell's index.ejs, so
    the snackbar's close button is reached by tabbing forward past the end of the document and
    wrapping. If we ship without this, dismissing an error by keyboard costs a tab through the rest
    of the queue table, because the notification host is at the top of the document.
  • Carbon renders two tabindex="0" role="link" spans reading "Focus sentinel" inside every
    ActionableNotification. If we ship without this, a screen-reader user tabbing past a snackbar
    hears "Focus sentinel, link", because Carbon's default focus wrap uses AT-visible sentinels.

Checked and clean:

  • Overflow menu items activate on both Enter and Space, and focus returns to the overflow trigger
    when the modal they opened closes. Carbon renders them as native <button role="menuitem">, so
    both keys fire click — there is no one-key-only handler here.
  • axe over the queue table with an error snackbar showing: six violations, all in the app shell's
    navigation and landmarks (button-name on the help menu, two main landmarks, the switcher
    list, panel list items). None of them are in the queue table, the action cell or the snackbar.
  • Interpolation: none of the four new keys interpolate, and the server's message goes into the
    snackbar's subtitle while the translated wording goes into its title. No translated fragment
    is concatenated with a server string, so nothing here depends on English word order.

Deferred, and why

Three review rounds accumulated a list of "not fixed, here is why". Each was re-judged on its merits
once the rest of the change was finished; four are now fixed and described above, two stay deferred.

Fixed in this revision.

  1. The overflow menu item had no in-flight guard. The same defect class this PR exists to fix, on
    the other of the two call sites it touches. Measured, not argued: two clicks 85ms apart sent two
    assignticket POSTs for one intended call. Fixed by sharing useSingleFlight() between both
    sites, and the inline button's guard was re-measured because R3 changed it from disabled to
    aria-disabled and an aria-disabled button is still clickable.
  2. The modal's rejection handlers were not guarded against showSnackbar throwing. The earlier
    reason — a broken snackbar store breaks every modal equally — is true but beside the point: this
    PR already guards the row-action path, so leaving this one unguarded meant the two paths it
    touches behaved differently under the same failure. Now they do not.
  3. The user-facing message for the half-done Serve transition. Repairing the transition itself is
    still deferred: it needs either a compensating request or a different call order, and neither is
    error handling. Both are also a worse trade than they look — a compensating "un-transition" is
    itself a request that can fail, and calling the ticket display first would only move the
    inconsistency to the other side. What is fixed is the part that was actively misleading: the
    message no longer claims nothing happened when the entry has in fact moved, and the table behind
    the modal is re-read rather than left showing a status that is no longer true. The bound on the
    damage was also checked on the running standalone rather than assumed: pressing Serve again sends
    only the endedAt POST, which the backend refuses, so a second press cannot double-transition.
  4. The two other rejection handlers used error?.message. Fixed with the rest of item 2. This
    was not only an inconsistency in wording: error?.message is the wrapper's "Server responded with
    500 …" rather than the server's own text, and it is not guaranteed to be a string — which is the
    React render crash this PR fixes for the other path and left in place here.

Still deferred.

  1. getErrorMessage is not total — an error object with a throwing property getter still makes it
    throw. Left alone, because there is no producer. openmrsFetch rejects with OpenmrsFetchError,
    which assigns message and responseBody as plain own data properties, or with a TypeError
    from fetch; neither carries an accessor. R2 fuzzed 25 shapes a rejection can actually carry and
    this was not among them. Every call site the PR touches is now inside a guard that would catch it
    anyway, so making it total would add a branch nothing can reach and no test can honestly kill.
  2. useActionPropsByKey() runs three times per row — once for the cell, once for the inline
    button, once for the menu item. Measured before deciding, in the package's own test environment:
    two extra calls cost 3.7µs per row taken as a best-of-41 and 6.8µs as a median over 200 rows,
    against 700–900µs per row for the action cell's own render (Carbon Button plus
    OverflowMenu), which is itself one of seven columns. So the saving is under 1% of the one cell it
    lives in — around a third of a millisecond on a fifty-row table — and it sits inside the run-to-run
    noise of the same measurement. Not worth restructuring three components for. Dropped.

Found while measuring the above, and not fixed here

The overflow menu never closes when an action is chosen. ActionOverflowMenuItem is a wrapper
around Carbon's OverflowMenuItem, and OverflowMenu injects four props into whatever its direct
child is — closeMenu, handleOverflowMenuItemFocus, index and a ref — none of which the
wrapper forwards. Carbon says so itself, on every render, in the development console: "<OverflowMenuItem>
detected missing closeMenu prop. closeMenu is required to let <OverflowMenu> close the menu upon
actions on <OverflowMenuItem>."
Measured on the running page, the trigger keeps aria-expanded="true"
and the items stay mounted after one is clicked, so the menu hangs open behind whatever modal the
action opened. If we ship without this, choosing an overflow action leaves the menu open on top of
the row it belongs to, and arrow-key navigation inside the menu has nothing to drive it, because the
wrapper swallows the props Carbon uses for both.

It is one prop passthrough and it was tried: forwarding closeMenu alone also brings the
double-click down to one request, because the item unmounts before the second click lands. It was
reverted and is not in this PR, for three reasons. It is a pre-existing defect of the wrapper,
not of the failure handling O3-5666 is about. It changes the behaviour of every overflow action in
every queue table, and the focus consequences would need re-measuring — R3's finding that focus
returns to the overflow trigger when a modal closes was measured under the current behaviour. And it
would fix the duplicate request only as a side effect of unmount timing, where the in-flight guard
fixes it directly and also covers the inline button. It wants its own ticket.

Corrections to earlier revisions of this description

  • An earlier revision said visitQueueNumberAttributeUuid defaults to null. That is the per-column override in queueTables.columnDefinitions; the top-level element this code reads defaults to c0c579b0-8e59-401d-8a4a-976a0b183519, a real "Visit Queue Number" visit attribute type in the demo data. The reference application does ship the top-level element as "" in appdata/frontend/referenceapplication/config.json, though that standalone's index.html carries configUrls: [], so at runtime it falls back to the schema default. Either way the guard is warranted: the value is per-visit, not per-installation.
  • An earlier revision quoted the blank-visitQueueNumberAttributeUuid case as producing "The queue name, ticket number, or calling status is missing." That message no longer exists; that case produces the ticket-number message, as the table above now shows.
  • An earlier revision said the Call button is "re-enabled" after a failure. It is no longer disabled at all; see the accessibility section.
  • An earlier revision quoted the missing-configuration message as "The queue name or calling status is missing. Check the service queues configuration." That wording named a configuration property a triage clerk has no word for and sent them to a page they cannot change; it now reads "Calling patients is not set up for this queue. Ask your system administrator to check the service queues configuration."
  • An earlier revision described the server-500 case as "same crash" as the offline one. It is an unhandled rejection either way, but only the aborted request produced a dev-overlay iframe in these runs; the 500 surfaced as a page error with no overlay.
  • An earlier revision said "four new translation keys". There are five; the fifth is patientMovedButNotCalled.
  • An earlier revision quoted the fixture's ticket number as TRI-007. The visit attribute on the standalone reads TRI-042; that is the value in the request bodies quoted above.
  • An earlier revision described the failed Serve request inside the modal as producing "Error calling patient / Failed to fetch". It now produces the moved-on message quoted in the table above, because by that point the patient has moved on.

The `call` row action awaited `serveQueueEntry` with no rejection handler,
and both call sites (the inline button and the overflow menu item) discard
the promise the handler returns. Any failure — a dropped network, a server
error, a missing ticket number — therefore became an unhandled rejection:
a full-screen "Uncaught runtime errors" overlay in development builds, and
nothing at all in production builds.

The action now validates the queue name, ticket number and calling status
before posting, reports every failure through `showSnackbar` the way the
sibling queue entry mutations do, and leaves the row usable so the user can
retry without reloading. `runAction` wraps both invocation sites so a
rejection an action does not handle itself is logged rather than escaping.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwrMcxXwSx8rPmMZu2VigK
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 7.32 MB

ℹ️ View Unchanged
Filename Size Change
packages/esm-active-visits-app/dist/282.js 603 B 0 B
packages/esm-active-visits-app/dist/434.js 603 B 0 B
packages/esm-active-visits-app/dist/466.js 2.58 kB 0 B
packages/esm-active-visits-app/dist/556.js 602 B 0 B
packages/esm-active-visits-app/dist/636.js 8.64 kB 0 B
packages/esm-active-visits-app/dist/689.js 42.5 kB 0 B
packages/esm-active-visits-app/dist/903.js 604 B 0 B
packages/esm-active-visits-app/dist/997.js 692 B 0 B
packages/esm-active-visits-app/dist/1339.js 477 B 0 B
packages/esm-active-visits-app/dist/1480.js 874 B 0 B
packages/esm-active-visits-app/dist/1646.js 696 B 0 B
packages/esm-active-visits-app/dist/1789.js 5.6 kB 0 B
packages/esm-active-visits-app/dist/1869.js 604 B 0 B
packages/esm-active-visits-app/dist/1877.js 707 B 0 B
packages/esm-active-visits-app/dist/2317.js 740 B 0 B
packages/esm-active-visits-app/dist/2342.js 13.3 kB 0 B
packages/esm-active-visits-app/dist/2368.js 69.7 kB 0 B
packages/esm-active-visits-app/dist/2416.js 605 B 0 B
packages/esm-active-visits-app/dist/2881.js 605 B 0 B
packages/esm-active-visits-app/dist/3378.js 1.66 kB 0 B
packages/esm-active-visits-app/dist/3671.js 579 B 0 B
packages/esm-active-visits-app/dist/3720.js 477 B 0 B
packages/esm-active-visits-app/dist/3760.js 365 kB 0 B
packages/esm-active-visits-app/dist/3958.js 628 B 0 B
packages/esm-active-visits-app/dist/3963.js 699 B 0 B
packages/esm-active-visits-app/dist/3989.js 3.06 kB 0 B
packages/esm-active-visits-app/dist/3996.js 15.3 kB 0 B
packages/esm-active-visits-app/dist/4106.js 605 B 0 B
packages/esm-active-visits-app/dist/4111.js 684 B 0 B
packages/esm-active-visits-app/dist/4348.js 604 B 0 B
packages/esm-active-visits-app/dist/4383.js 604 B 0 B
packages/esm-active-visits-app/dist/4658.js 605 B 0 B
packages/esm-active-visits-app/dist/4928.js 697 B 0 B
packages/esm-active-visits-app/dist/5117.js 605 B 0 B
packages/esm-active-visits-app/dist/5132.js 712 B 0 B
packages/esm-active-visits-app/dist/5145.js 705 B 0 B
packages/esm-active-visits-app/dist/5503.js 604 B 0 B
packages/esm-active-visits-app/dist/5644.js 805 B 0 B
packages/esm-active-visits-app/dist/5697.js 3.02 kB 0 B
packages/esm-active-visits-app/dist/5940.js 942 B 0 B
packages/esm-active-visits-app/dist/6047.js 690 B 0 B
packages/esm-active-visits-app/dist/6371.js 845 B 0 B
packages/esm-active-visits-app/dist/6377.js 604 B 0 B
packages/esm-active-visits-app/dist/6444.js 873 B 0 B
packages/esm-active-visits-app/dist/6508.js 705 B 0 B
packages/esm-active-visits-app/dist/6724.js 605 B 0 B
packages/esm-active-visits-app/dist/6904.js 605 B 0 B
packages/esm-active-visits-app/dist/7045.js 816 B 0 B
packages/esm-active-visits-app/dist/7175.js 604 B 0 B
packages/esm-active-visits-app/dist/7182.js 605 B 0 B
packages/esm-active-visits-app/dist/7742.js 807 B 0 B
packages/esm-active-visits-app/dist/7912.js 711 B 0 B
packages/esm-active-visits-app/dist/8358.js 605 B 0 B
packages/esm-active-visits-app/dist/8359.js 907 B 0 B
packages/esm-active-visits-app/dist/8695.js 787 B 0 B
packages/esm-active-visits-app/dist/9061.js 2.22 kB 0 B
packages/esm-active-visits-app/dist/9072.js 603 B 0 B
packages/esm-active-visits-app/dist/9771.js 3.01 kB 0 B
packages/esm-active-visits-app/dist/9806.js 641 B 0 B
packages/esm-active-visits-app/dist/main.js 26.1 kB 0 B
packages/esm-active-visits-app/dist/openmrs-esm-active-visits-app.js 25.3 kB 0 B
packages/esm-appointments-app/dist/282.js 2.39 kB 0 B
packages/esm-appointments-app/dist/434.js 2.39 kB 0 B
packages/esm-appointments-app/dist/466.js 2.58 kB 0 B
packages/esm-appointments-app/dist/556.js 2.39 kB 0 B
packages/esm-appointments-app/dist/635.js 529 B 0 B
packages/esm-appointments-app/dist/689.js 42.5 kB 0 B
packages/esm-appointments-app/dist/903.js 2.39 kB 0 B
packages/esm-appointments-app/dist/1339.js 473 B 0 B
packages/esm-appointments-app/dist/1465.js 2.4 kB 0 B
packages/esm-appointments-app/dist/1480.js 2.96 kB 0 B
packages/esm-appointments-app/dist/1646.js 2.39 kB 0 B
packages/esm-appointments-app/dist/1789.js 5.6 kB 0 B
packages/esm-appointments-app/dist/1869.js 2.39 kB 0 B
packages/esm-appointments-app/dist/1877.js 2.75 kB 0 B
packages/esm-appointments-app/dist/1884.js 404 B 0 B
packages/esm-appointments-app/dist/1962.js 3.36 kB 0 B
packages/esm-appointments-app/dist/2048.js 359 kB 0 B
packages/esm-appointments-app/dist/2317.js 2.79 kB 0 B
packages/esm-appointments-app/dist/2416.js 2.39 kB 0 B
packages/esm-appointments-app/dist/2495.js 7.08 kB 0 B
packages/esm-appointments-app/dist/2539.js 712 B 0 B
packages/esm-appointments-app/dist/2620.js 13.9 kB 0 B
packages/esm-appointments-app/dist/2717.js 24 kB 0 B
packages/esm-appointments-app/dist/2881.js 2.39 kB 0 B
packages/esm-appointments-app/dist/3220.js 7.58 kB 0 B
packages/esm-appointments-app/dist/3378.js 2.39 kB 0 B
packages/esm-appointments-app/dist/3720.js 474 B 0 B
packages/esm-appointments-app/dist/3930.js 94.3 kB 0 B
packages/esm-appointments-app/dist/3963.js 2.75 kB 0 B
packages/esm-appointments-app/dist/3989.js 3.06 kB 0 B
packages/esm-appointments-app/dist/4106.js 2.39 kB 0 B
packages/esm-appointments-app/dist/4111.js 2.7 kB 0 B
packages/esm-appointments-app/dist/4307.js 6.79 kB 0 B
packages/esm-appointments-app/dist/4348.js 2.39 kB 0 B
packages/esm-appointments-app/dist/4383.js 2.39 kB 0 B
packages/esm-appointments-app/dist/4658.js 2.39 kB 0 B
packages/esm-appointments-app/dist/4928.js 2.56 kB 0 B
packages/esm-appointments-app/dist/5117.js 2.39 kB 0 B
packages/esm-appointments-app/dist/5132.js 2.7 kB 0 B
packages/esm-appointments-app/dist/5145.js 2.85 kB 0 B
packages/esm-appointments-app/dist/5503.js 2.39 kB 0 B
packages/esm-appointments-app/dist/5640.js 4.69 kB 0 B
packages/esm-appointments-app/dist/5644.js 2.84 kB 0 B
packages/esm-appointments-app/dist/5940.js 2.92 kB 0 B
packages/esm-appointments-app/dist/6047.js 2.62 kB 0 B
packages/esm-appointments-app/dist/6236.js 2.77 kB 0 B
packages/esm-appointments-app/dist/6371.js 2.99 kB 0 B
packages/esm-appointments-app/dist/6377.js 2.39 kB 0 B
packages/esm-appointments-app/dist/6444.js 2.85 kB 0 B
packages/esm-appointments-app/dist/6508.js 2.82 kB 0 B
packages/esm-appointments-app/dist/6724.js 2.39 kB 0 B
packages/esm-appointments-app/dist/6789.js 10.4 kB 0 B
packages/esm-appointments-app/dist/6904.js 2.39 kB 0 B
packages/esm-appointments-app/dist/6973.js 94.5 kB 0 B
packages/esm-appointments-app/dist/7045.js 2.81 kB 0 B
packages/esm-appointments-app/dist/7138.js 34.2 kB 0 B
packages/esm-appointments-app/dist/7159.js 1.29 kB 0 B
packages/esm-appointments-app/dist/7175.js 2.39 kB 0 B
packages/esm-appointments-app/dist/7182.js 2.39 kB 0 B
packages/esm-appointments-app/dist/7357.js 3.74 kB 0 B
packages/esm-appointments-app/dist/7609.js 585 B 0 B
packages/esm-appointments-app/dist/7654.js 4.51 kB 0 B
packages/esm-appointments-app/dist/7742.js 2.84 kB 0 B
packages/esm-appointments-app/dist/7912.js 2.71 kB 0 B
packages/esm-appointments-app/dist/8063.js 22.5 kB 0 B
packages/esm-appointments-app/dist/8346.js 12.8 kB 0 B
packages/esm-appointments-app/dist/8358.js 2.39 kB 0 B
packages/esm-appointments-app/dist/8359.js 3.13 kB 0 B
packages/esm-appointments-app/dist/8695.js 2.56 kB 0 B
packages/esm-appointments-app/dist/8937.js 465 B 0 B
packages/esm-appointments-app/dist/8981.js 9.38 kB 0 B
packages/esm-appointments-app/dist/9061.js 2.21 kB 0 B
packages/esm-appointments-app/dist/9072.js 2.39 kB 0 B
packages/esm-appointments-app/dist/9282.js 688 B 0 B
packages/esm-appointments-app/dist/9399.js 26.8 kB 0 B
packages/esm-appointments-app/dist/9443.js 10.8 kB 0 B
packages/esm-appointments-app/dist/9581.js 3.36 kB 0 B
packages/esm-appointments-app/dist/9712.js 26.4 kB 0 B
packages/esm-appointments-app/dist/9771.js 3.01 kB 0 B
packages/esm-appointments-app/dist/9806.js 2.39 kB 0 B
packages/esm-appointments-app/dist/main.js 28.6 kB 0 B
packages/esm-appointments-app/dist/openmrs-esm-appointments-app.js 25.3 kB 0 B
packages/esm-bed-management-app/dist/282.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/377.js 87.1 kB 0 B
packages/esm-bed-management-app/dist/434.js 1.24 kB 0 B
packages/esm-bed-management-app/dist/466.js 2.58 kB 0 B
packages/esm-bed-management-app/dist/556.js 1.24 kB 0 B
packages/esm-bed-management-app/dist/689.js 42.5 kB 0 B
packages/esm-bed-management-app/dist/903.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/1339.js 477 B 0 B
packages/esm-bed-management-app/dist/1480.js 1.6 kB 0 B
packages/esm-bed-management-app/dist/1646.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/1744.js 2.45 kB 0 B
packages/esm-bed-management-app/dist/1789.js 5.6 kB 0 B
packages/esm-bed-management-app/dist/1869.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/1877.js 1.44 kB 0 B
packages/esm-bed-management-app/dist/1893.js 2.19 kB 0 B
packages/esm-bed-management-app/dist/2257.js 362 kB 0 B
packages/esm-bed-management-app/dist/2317.js 1.45 kB 0 B
packages/esm-bed-management-app/dist/2416.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/2881.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/3081.js 1.9 kB 0 B
packages/esm-bed-management-app/dist/3090.js 48.2 kB 0 B
packages/esm-bed-management-app/dist/3302.js 516 B 0 B
packages/esm-bed-management-app/dist/3378.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/3636.js 2.43 kB 0 B
packages/esm-bed-management-app/dist/3720.js 477 B 0 B
packages/esm-bed-management-app/dist/3963.js 1.46 kB 0 B
packages/esm-bed-management-app/dist/3989.js 3.06 kB 0 B
packages/esm-bed-management-app/dist/4106.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/4111.js 1.39 kB 0 B
packages/esm-bed-management-app/dist/4348.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/4383.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/4658.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/4928.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/5117.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/5120.js 1.55 kB 0 B
packages/esm-bed-management-app/dist/5132.js 1.41 kB 0 B
packages/esm-bed-management-app/dist/5145.js 1.43 kB 0 B
packages/esm-bed-management-app/dist/5175.js 2.12 kB 0 B
packages/esm-bed-management-app/dist/5503.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/5644.js 1.43 kB 0 B
packages/esm-bed-management-app/dist/5697.js 3.02 kB 0 B
packages/esm-bed-management-app/dist/5940.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/6047.js 1.36 kB 0 B
packages/esm-bed-management-app/dist/6168.js 2.19 kB 0 B
packages/esm-bed-management-app/dist/6220.js 2.79 kB 0 B
packages/esm-bed-management-app/dist/6371.js 1.44 kB 0 B
packages/esm-bed-management-app/dist/6377.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/6444.js 1.37 kB 0 B
packages/esm-bed-management-app/dist/6508.js 1.53 kB 0 B
packages/esm-bed-management-app/dist/6724.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/6904.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/6979.js 1.9 kB 0 B
packages/esm-bed-management-app/dist/7045.js 1.33 kB 0 B
packages/esm-bed-management-app/dist/7121.js 395 B 0 B
packages/esm-bed-management-app/dist/7175.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/7182.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/7546.js 1.56 kB 0 B
packages/esm-bed-management-app/dist/7742.js 1.43 kB 0 B
packages/esm-bed-management-app/dist/7912.js 1.39 kB 0 B
packages/esm-bed-management-app/dist/8358.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/8359.js 1.7 kB 0 B
packages/esm-bed-management-app/dist/8695.js 1.48 kB 0 B
packages/esm-bed-management-app/dist/8702.js 22.2 kB 0 B
packages/esm-bed-management-app/dist/9061.js 2.21 kB 0 B
packages/esm-bed-management-app/dist/9072.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/9677.js 10.9 kB 0 B
packages/esm-bed-management-app/dist/9712.js 26.4 kB 0 B
packages/esm-bed-management-app/dist/9771.js 3.01 kB 0 B
packages/esm-bed-management-app/dist/9806.js 1.25 kB 0 B
packages/esm-bed-management-app/dist/main.js 27 kB 0 B
packages/esm-bed-management-app/dist/openmrs-esm-bed-management-app.js 25.5 kB 0 B
packages/esm-home-app/dist/279.js 367 kB 0 B
packages/esm-home-app/dist/282.js 342 B 0 B
packages/esm-home-app/dist/434.js 342 B 0 B
packages/esm-home-app/dist/466.js 2.57 kB 0 B
packages/esm-home-app/dist/556.js 342 B 0 B
packages/esm-home-app/dist/689.js 42.5 kB 0 B
packages/esm-home-app/dist/903.js 343 B 0 B
packages/esm-home-app/dist/1097.js 11.4 kB 0 B
packages/esm-home-app/dist/1339.js 470 B 0 B
packages/esm-home-app/dist/1480.js 343 B 0 B
packages/esm-home-app/dist/1646.js 344 B 0 B
packages/esm-home-app/dist/1789.js 5.59 kB 0 B
packages/esm-home-app/dist/1869.js 343 B 0 B
packages/esm-home-app/dist/1877.js 385 B 0 B
packages/esm-home-app/dist/2317.js 343 B 0 B
packages/esm-home-app/dist/2416.js 344 B 0 B
packages/esm-home-app/dist/2881.js 343 B 0 B
packages/esm-home-app/dist/3378.js 344 B 0 B
packages/esm-home-app/dist/3720.js 471 B 0 B
packages/esm-home-app/dist/3963.js 343 B 0 B
packages/esm-home-app/dist/3989.js 3.06 kB 0 B
packages/esm-home-app/dist/4106.js 343 B 0 B
packages/esm-home-app/dist/4111.js 344 B 0 B
packages/esm-home-app/dist/4348.js 343 B 0 B
packages/esm-home-app/dist/4383.js 343 B 0 B
packages/esm-home-app/dist/4658.js 344 B 0 B
packages/esm-home-app/dist/4928.js 344 B 0 B
packages/esm-home-app/dist/4944.js 46.8 kB 0 B
packages/esm-home-app/dist/5117.js 343 B 0 B
packages/esm-home-app/dist/5132.js 344 B 0 B
packages/esm-home-app/dist/5145.js 400 B 0 B
packages/esm-home-app/dist/5503.js 344 B 0 B
packages/esm-home-app/dist/5644.js 439 B 0 B
packages/esm-home-app/dist/5940.js 343 B 0 B
packages/esm-home-app/dist/6047.js 343 B 0 B
packages/esm-home-app/dist/6371.js 344 B 0 B
packages/esm-home-app/dist/6377.js 343 B 0 B
packages/esm-home-app/dist/6444.js 343 B 0 B
packages/esm-home-app/dist/6508.js 403 B 0 B
packages/esm-home-app/dist/6724.js 343 B 0 B
packages/esm-home-app/dist/6904.js 344 B 0 B
packages/esm-home-app/dist/7045.js 450 B 0 B
packages/esm-home-app/dist/7175.js 343 B 0 B
packages/esm-home-app/dist/7182.js 343 B 0 B
packages/esm-home-app/dist/7742.js 439 B 0 B
packages/esm-home-app/dist/7912.js 388 B 0 B
packages/esm-home-app/dist/8358.js 343 B 0 B
packages/esm-home-app/dist/8359.js 503 B 0 B
packages/esm-home-app/dist/8695.js 344 B 0 B
packages/esm-home-app/dist/9061.js 2.21 kB 0 B
packages/esm-home-app/dist/9072.js 342 B 0 B
packages/esm-home-app/dist/9712.js 26.4 kB 0 B
packages/esm-home-app/dist/9771.js 3 kB 0 B
packages/esm-home-app/dist/9806.js 343 B 0 B
packages/esm-home-app/dist/main.js 127 kB 0 B
packages/esm-home-app/dist/openmrs-esm-home-app.js 25.4 kB 0 B
packages/esm-patient-list-management-app/dist/282.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/296.js 2.56 kB 0 B
packages/esm-patient-list-management-app/dist/434.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/466.js 2.58 kB 0 B
packages/esm-patient-list-management-app/dist/532.js 1.79 kB 0 B
packages/esm-patient-list-management-app/dist/556.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/689.js 42.5 kB 0 B
packages/esm-patient-list-management-app/dist/903.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/1033.js 2.32 kB 0 B
packages/esm-patient-list-management-app/dist/1040.js 2.83 kB 0 B
packages/esm-patient-list-management-app/dist/1339.js 482 B 0 B
packages/esm-patient-list-management-app/dist/1480.js 2.01 kB 0 B
packages/esm-patient-list-management-app/dist/1646.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/1735.js 526 B 0 B
packages/esm-patient-list-management-app/dist/1789.js 5.61 kB 0 B
packages/esm-patient-list-management-app/dist/1869.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/1877.js 1.73 kB 0 B
packages/esm-patient-list-management-app/dist/2317.js 1.82 kB 0 B
packages/esm-patient-list-management-app/dist/2416.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/2872.js 12.6 kB 0 B
packages/esm-patient-list-management-app/dist/2881.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/3378.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/3528.js 40.2 kB 0 B
packages/esm-patient-list-management-app/dist/3660.js 3.21 kB 0 B
packages/esm-patient-list-management-app/dist/3720.js 482 B 0 B
packages/esm-patient-list-management-app/dist/3852.js 4.22 kB 0 B
packages/esm-patient-list-management-app/dist/3963.js 1.67 kB 0 B
packages/esm-patient-list-management-app/dist/3989.js 3.07 kB 0 B
packages/esm-patient-list-management-app/dist/4106.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/4111.js 1.7 kB 0 B
packages/esm-patient-list-management-app/dist/4348.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/4383.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/4399.js 363 kB 0 B
packages/esm-patient-list-management-app/dist/4540.js 78.1 kB 0 B
packages/esm-patient-list-management-app/dist/4658.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/4928.js 1.57 kB 0 B
packages/esm-patient-list-management-app/dist/5117.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/5132.js 1.73 kB 0 B
packages/esm-patient-list-management-app/dist/5145.js 1.81 kB 0 B
packages/esm-patient-list-management-app/dist/5503.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/5644.js 1.79 kB 0 B
packages/esm-patient-list-management-app/dist/5694.js 13 kB 0 B
packages/esm-patient-list-management-app/dist/5810.js 8.63 kB 0 B
packages/esm-patient-list-management-app/dist/5919.js 4.99 kB 0 B
packages/esm-patient-list-management-app/dist/5940.js 2.01 kB 0 B
packages/esm-patient-list-management-app/dist/6047.js 1.61 kB 0 B
packages/esm-patient-list-management-app/dist/6371.js 1.95 kB 0 B
packages/esm-patient-list-management-app/dist/6377.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/6444.js 1.75 kB 0 B
packages/esm-patient-list-management-app/dist/6508.js 1.8 kB 0 B
packages/esm-patient-list-management-app/dist/6724.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/6904.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/7045.js 1.89 kB 0 B
packages/esm-patient-list-management-app/dist/7175.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/7182.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/7476.js 11 kB 0 B
packages/esm-patient-list-management-app/dist/7742.js 1.79 kB 0 B
packages/esm-patient-list-management-app/dist/7912.js 1.73 kB 0 B
packages/esm-patient-list-management-app/dist/8358.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/8359.js 2.09 kB 0 B
packages/esm-patient-list-management-app/dist/8695.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/9061.js 2.22 kB 0 B
packages/esm-patient-list-management-app/dist/9072.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/9526.js 1.76 kB 0 B
packages/esm-patient-list-management-app/dist/9712.js 26.4 kB 0 B
packages/esm-patient-list-management-app/dist/9771.js 3.01 kB 0 B
packages/esm-patient-list-management-app/dist/9806.js 1.5 kB 0 B
packages/esm-patient-list-management-app/dist/main.js 26.7 kB 0 B
packages/esm-patient-list-management-app/dist/openmrs-esm-patient-list-management-app.js 25.4 kB 0 B
packages/esm-patient-registration-app/dist/282.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/434.js 2.22 kB 0 B
packages/esm-patient-registration-app/dist/466.js 2.58 kB 0 B
packages/esm-patient-registration-app/dist/527.js 456 B 0 B
packages/esm-patient-registration-app/dist/555.js 11.1 kB 0 B
packages/esm-patient-registration-app/dist/556.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/689.js 42.5 kB 0 B
packages/esm-patient-registration-app/dist/903.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/1339.js 483 B 0 B
packages/esm-patient-registration-app/dist/1480.js 2.79 kB 0 B
packages/esm-patient-registration-app/dist/1646.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/1789.js 5.61 kB 0 B
packages/esm-patient-registration-app/dist/1869.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/1877.js 2.61 kB 0 B
packages/esm-patient-registration-app/dist/2317.js 2.52 kB 0 B
packages/esm-patient-registration-app/dist/2416.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/2881.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/3378.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/3720.js 483 B 0 B
packages/esm-patient-registration-app/dist/3906.js 25.6 kB 0 B
packages/esm-patient-registration-app/dist/3963.js 2.38 kB 0 B
packages/esm-patient-registration-app/dist/3989.js 3.07 kB 0 B
packages/esm-patient-registration-app/dist/4106.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/4111.js 2.5 kB 0 B
packages/esm-patient-registration-app/dist/4348.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/4383.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/4658.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/4928.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/5117.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/5132.js 2.53 kB 0 B
packages/esm-patient-registration-app/dist/5145.js 2.7 kB 0 B
packages/esm-patient-registration-app/dist/5208.js 358 kB 0 B
packages/esm-patient-registration-app/dist/5280.js 5.15 kB 0 B
packages/esm-patient-registration-app/dist/5395.js 63.9 kB 0 B
packages/esm-patient-registration-app/dist/5503.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/5644.js 2.67 kB 0 B
packages/esm-patient-registration-app/dist/5697.js 3.03 kB 0 B
packages/esm-patient-registration-app/dist/5940.js 2.86 kB 0 B
packages/esm-patient-registration-app/dist/6047.js 2.43 kB 0 B
packages/esm-patient-registration-app/dist/6371.js 2.71 kB 0 B
packages/esm-patient-registration-app/dist/6377.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/6388.js 310 B 0 B
packages/esm-patient-registration-app/dist/6444.js 2.44 kB 0 B
packages/esm-patient-registration-app/dist/6508.js 2.64 kB 0 B
packages/esm-patient-registration-app/dist/6724.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/6904.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/7045.js 2.62 kB 0 B
packages/esm-patient-registration-app/dist/7175.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/7182.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/7464.js 69.1 kB 0 B
packages/esm-patient-registration-app/dist/7649.js 784 B 0 B
packages/esm-patient-registration-app/dist/7742.js 2.67 kB 0 B
packages/esm-patient-registration-app/dist/7912.js 2.59 kB 0 B
packages/esm-patient-registration-app/dist/8358.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/8359.js 3 kB 0 B
packages/esm-patient-registration-app/dist/8695.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/9061.js 2.22 kB 0 B
packages/esm-patient-registration-app/dist/9072.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/9397.js 530 B 0 B
packages/esm-patient-registration-app/dist/9712.js 26.4 kB 0 B
packages/esm-patient-registration-app/dist/9771.js 3.02 kB 0 B
packages/esm-patient-registration-app/dist/9806.js 2.23 kB 0 B
packages/esm-patient-registration-app/dist/9816.js 3.26 kB 0 B
packages/esm-patient-registration-app/dist/main.js 153 kB 0 B
packages/esm-patient-registration-app/dist/openmrs-esm-patient-registration-app.js 25.5 kB 0 B
packages/esm-patient-search-app/dist/282.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/434.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/466.js 2.58 kB 0 B
packages/esm-patient-search-app/dist/556.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/590.js 1.92 kB 0 B
packages/esm-patient-search-app/dist/689.js 42.5 kB 0 B
packages/esm-patient-search-app/dist/903.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/965.js 6.49 kB 0 B
packages/esm-patient-search-app/dist/997.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/1118.js 1.31 kB 0 B
packages/esm-patient-search-app/dist/1339.js 476 B 0 B
packages/esm-patient-search-app/dist/1480.js 1.36 kB 0 B
packages/esm-patient-search-app/dist/1646.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/1789.js 5.6 kB 0 B
packages/esm-patient-search-app/dist/1869.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/1877.js 1.22 kB 0 B
packages/esm-patient-search-app/dist/1994.js 5.28 kB 0 B
packages/esm-patient-search-app/dist/2317.js 1.25 kB 0 B
packages/esm-patient-search-app/dist/2328.js 363 kB 0 B
packages/esm-patient-search-app/dist/2416.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/2825.js 886 B 0 B
packages/esm-patient-search-app/dist/2881.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/3378.js 3.27 kB 0 B
packages/esm-patient-search-app/dist/3720.js 477 B 0 B
packages/esm-patient-search-app/dist/3963.js 1.24 kB 0 B
packages/esm-patient-search-app/dist/3989.js 3.06 kB 0 B
packages/esm-patient-search-app/dist/4106.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/4111.js 1.19 kB 0 B
packages/esm-patient-search-app/dist/4145.js 8.99 kB 0 B
packages/esm-patient-search-app/dist/4348.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/4383.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/4399.js 1.12 kB 0 B
packages/esm-patient-search-app/dist/4658.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/4726.js 7.76 kB 0 B
packages/esm-patient-search-app/dist/4777.js 4.65 kB 0 B
packages/esm-patient-search-app/dist/4928.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/4959.js 10.7 kB 0 B
packages/esm-patient-search-app/dist/5117.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/5132.js 1.24 kB 0 B
packages/esm-patient-search-app/dist/5145.js 1.28 kB 0 B
packages/esm-patient-search-app/dist/5503.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/5644.js 1.33 kB 0 B
packages/esm-patient-search-app/dist/5882.js 36.1 kB 0 B
packages/esm-patient-search-app/dist/5940.js 1.36 kB 0 B
packages/esm-patient-search-app/dist/6047.js 1.16 kB 0 B
packages/esm-patient-search-app/dist/6371.js 1.33 kB 0 B
packages/esm-patient-search-app/dist/6377.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/6444.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/6508.js 1.28 kB 0 B
packages/esm-patient-search-app/dist/6541.js 1.08 kB 0 B
packages/esm-patient-search-app/dist/6724.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/6904.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/7045.js 1.29 kB 0 B
packages/esm-patient-search-app/dist/7118.js 65.4 kB 0 B
packages/esm-patient-search-app/dist/7175.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/7182.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/7742.js 1.33 kB 0 B
packages/esm-patient-search-app/dist/7912.js 1.23 kB 0 B
packages/esm-patient-search-app/dist/8358.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/8359.js 1.51 kB 0 B
packages/esm-patient-search-app/dist/8383.js 5.99 kB 0 B
packages/esm-patient-search-app/dist/8695.js 1.06 kB 0 B
packages/esm-patient-search-app/dist/9061.js 2.21 kB 0 B
packages/esm-patient-search-app/dist/9072.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/9712.js 26.4 kB 0 B
packages/esm-patient-search-app/dist/9771.js 3.01 kB 0 B
packages/esm-patient-search-app/dist/9806.js 1.05 kB 0 B
packages/esm-patient-search-app/dist/main.js 26.4 kB 0 B
packages/esm-patient-search-app/dist/openmrs-esm-patient-search-app.js 25.4 kB 0 B
packages/esm-service-queues-app/dist/106.js 6.22 kB 0 B
packages/esm-service-queues-app/dist/257.js 3.57 kB 0 B
packages/esm-service-queues-app/dist/282.js 2.86 kB 0 B
packages/esm-service-queues-app/dist/434.js 2.86 kB 0 B
packages/esm-service-queues-app/dist/466.js 2.58 kB 0 B
packages/esm-service-queues-app/dist/556.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/689.js 42.5 kB 0 B
packages/esm-service-queues-app/dist/714.js 641 B 0 B
packages/esm-service-queues-app/dist/903.js 2.86 kB 0 B
packages/esm-service-queues-app/dist/1093.js 3.46 kB 0 B
packages/esm-service-queues-app/dist/1251.js 21.6 kB 0 B
packages/esm-service-queues-app/dist/1295.js 406 B 0 B
packages/esm-service-queues-app/dist/1480.js 3.73 kB 0 B
packages/esm-service-queues-app/dist/1646.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/1744.js 2.46 kB 0 B
packages/esm-service-queues-app/dist/1789.js 5.6 kB 0 B
packages/esm-service-queues-app/dist/1869.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/1877.js 3.34 kB 0 B
packages/esm-service-queues-app/dist/1974.js 2.96 kB 0 B
packages/esm-service-queues-app/dist/2136.js 579 B 0 B
packages/esm-service-queues-app/dist/2150.js 1.97 kB 0 B
packages/esm-service-queues-app/dist/2317.js 3.32 kB 0 B
packages/esm-service-queues-app/dist/2369.js 17.9 kB +7 B (+0.04%)
packages/esm-service-queues-app/dist/2416.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/2433.js 2.7 kB 0 B
packages/esm-service-queues-app/dist/2471.js 19 kB 0 B
packages/esm-service-queues-app/dist/2640.js 87.2 kB 0 B
packages/esm-service-queues-app/dist/2825.js 8.37 kB 0 B
packages/esm-service-queues-app/dist/2853.js 3.3 kB 0 B
packages/esm-service-queues-app/dist/2881.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/3049.js 7.53 kB 0 B
packages/esm-service-queues-app/dist/3211.js 35.5 kB +623 B (+1.79%)
packages/esm-service-queues-app/dist/3311.js 5.01 kB 0 B
packages/esm-service-queues-app/dist/3378.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/3580.js 2.71 kB 0 B
packages/esm-service-queues-app/dist/3598.js 22.1 kB 0 B
packages/esm-service-queues-app/dist/3720.js 481 B 0 B
packages/esm-service-queues-app/dist/3733.js 11 kB 0 B
packages/esm-service-queues-app/dist/3735.js 513 B 0 B
packages/esm-service-queues-app/dist/3963.js 3.44 kB 0 B
packages/esm-service-queues-app/dist/3989.js 3.07 kB 0 B
packages/esm-service-queues-app/dist/4106.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/4111.js 3.33 kB 0 B
packages/esm-service-queues-app/dist/4343.js 9.3 kB +635 B (+7.33%) 🔍
packages/esm-service-queues-app/dist/4348.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/4383.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/4598.js 1.9 kB 0 B
packages/esm-service-queues-app/dist/4658.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/4661.js 4.04 kB +8 B (+0.2%)
packages/esm-service-queues-app/dist/4928.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/5117.js 3 kB +160 B (+5.63%) 🔍
packages/esm-service-queues-app/dist/5132.js 3.31 kB 0 B
packages/esm-service-queues-app/dist/5145.js 3.53 kB 0 B
packages/esm-service-queues-app/dist/5316.js 581 B 0 B
packages/esm-service-queues-app/dist/5407.js 409 B 0 B
packages/esm-service-queues-app/dist/5503.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/5553.js 219 B 0 B
packages/esm-service-queues-app/dist/5644.js 3.53 kB 0 B
packages/esm-service-queues-app/dist/5894.js 3.59 kB 0 B
packages/esm-service-queues-app/dist/5940.js 3.53 kB 0 B
packages/esm-service-queues-app/dist/6047.js 3.21 kB 0 B
packages/esm-service-queues-app/dist/6138.js 3.79 kB 0 B
packages/esm-service-queues-app/dist/6371.js 3.61 kB 0 B
packages/esm-service-queues-app/dist/6377.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/6444.js 3.1 kB 0 B
packages/esm-service-queues-app/dist/6508.js 3.51 kB 0 B
packages/esm-service-queues-app/dist/6724.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/6775.js 3.17 kB 0 B
packages/esm-service-queues-app/dist/6904.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/7045.js 3.44 kB 0 B
packages/esm-service-queues-app/dist/7175.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/7182.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/7296.js 1.81 kB 0 B
packages/esm-service-queues-app/dist/7654.js 6.66 kB 0 B
packages/esm-service-queues-app/dist/7742.js 3.54 kB 0 B
packages/esm-service-queues-app/dist/7912.js 3.4 kB 0 B
packages/esm-service-queues-app/dist/7919.js 360 kB 0 B
packages/esm-service-queues-app/dist/7953.js 10.7 kB 0 B
packages/esm-service-queues-app/dist/8010.js 10.8 kB 0 B
packages/esm-service-queues-app/dist/8358.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/8359.js 4.02 kB 0 B
packages/esm-service-queues-app/dist/8385.js 5.32 kB 0 B
packages/esm-service-queues-app/dist/8585.js 1.78 kB 0 B
packages/esm-service-queues-app/dist/8695.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/8833.js 8.26 kB 0 B
packages/esm-service-queues-app/dist/8990.js 452 B 0 B
packages/esm-service-queues-app/dist/9061.js 2.5 kB 0 B
packages/esm-service-queues-app/dist/9072.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/9084.js 5.29 kB 0 B
packages/esm-service-queues-app/dist/9183.js 11 kB 0 B
packages/esm-service-queues-app/dist/9204.js 5.33 kB 0 B
packages/esm-service-queues-app/dist/9412.js 5.12 kB 0 B
packages/esm-service-queues-app/dist/9712.js 26.4 kB 0 B
packages/esm-service-queues-app/dist/9721.js 6.03 kB +8 B (+0.13%)
packages/esm-service-queues-app/dist/9769.js 1.97 kB 0 B
packages/esm-service-queues-app/dist/9771.js 3.01 kB 0 B
packages/esm-service-queues-app/dist/9806.js 2.87 kB 0 B
packages/esm-service-queues-app/dist/9982.js 2.69 kB 0 B
packages/esm-service-queues-app/dist/main.js 28.5 kB 0 B
packages/esm-service-queues-app/dist/openmrs-esm-service-queues-app.js 25.4 kB 0 B
packages/esm-ward-app/dist/282.js 2.4 kB 0 B
packages/esm-ward-app/dist/388.js 18.4 kB 0 B
packages/esm-ward-app/dist/434.js 2.4 kB 0 B
packages/esm-ward-app/dist/466.js 2.57 kB 0 B
packages/esm-ward-app/dist/502.js 317 B 0 B
packages/esm-ward-app/dist/556.js 2.4 kB 0 B
packages/esm-ward-app/dist/582.js 452 B 0 B
packages/esm-ward-app/dist/689.js 42.5 kB 0 B
packages/esm-ward-app/dist/833.js 12.4 kB 0 B
packages/esm-ward-app/dist/903.js 2.4 kB 0 B
packages/esm-ward-app/dist/992.js 12.5 kB 0 B
packages/esm-ward-app/dist/1070.js 1.32 kB 0 B
packages/esm-ward-app/dist/1480.js 2.96 kB 0 B
packages/esm-ward-app/dist/1646.js 2.4 kB 0 B
packages/esm-ward-app/dist/1664.js 313 B 0 B
packages/esm-ward-app/dist/1780.js 23.6 kB 0 B
packages/esm-ward-app/dist/1789.js 5.59 kB 0 B
packages/esm-ward-app/dist/1869.js 2.4 kB 0 B
packages/esm-ward-app/dist/1877.js 2.84 kB 0 B
packages/esm-ward-app/dist/1978.js 1.69 kB 0 B
packages/esm-ward-app/dist/2101.js 5.86 kB 0 B
packages/esm-ward-app/dist/2162.js 8.14 kB 0 B
packages/esm-ward-app/dist/2317.js 2.4 kB 0 B
packages/esm-ward-app/dist/2416.js 2.4 kB 0 B
packages/esm-ward-app/dist/2495.js 3.24 kB 0 B
packages/esm-ward-app/dist/2881.js 2.4 kB 0 B
packages/esm-ward-app/dist/2898.js 7.35 kB 0 B
packages/esm-ward-app/dist/3378.js 2.4 kB 0 B
packages/esm-ward-app/dist/3560.js 3.89 kB 0 B
packages/esm-ward-app/dist/3720.js 470 B 0 B
packages/esm-ward-app/dist/3852.js 4.2 kB 0 B
packages/esm-ward-app/dist/3963.js 2.72 kB 0 B
packages/esm-ward-app/dist/3989.js 3.06 kB 0 B
packages/esm-ward-app/dist/4064.js 365 kB 0 B
packages/esm-ward-app/dist/4106.js 2.4 kB 0 B
packages/esm-ward-app/dist/4111.js 2.72 kB 0 B
packages/esm-ward-app/dist/4348.js 2.4 kB 0 B
packages/esm-ward-app/dist/4383.js 2.4 kB 0 B
packages/esm-ward-app/dist/4658.js 2.4 kB 0 B
packages/esm-ward-app/dist/4928.js 2.4 kB 0 B
packages/esm-ward-app/dist/5117.js 2.4 kB 0 B
packages/esm-ward-app/dist/5132.js 2.4 kB 0 B
packages/esm-ward-app/dist/5145.js 2.99 kB 0 B
packages/esm-ward-app/dist/5503.js 2.4 kB 0 B
packages/esm-ward-app/dist/5509.js 3.87 kB 0 B
packages/esm-ward-app/dist/5576.js 1.92 kB 0 B
packages/esm-ward-app/dist/5644.js 2.59 kB 0 B
packages/esm-ward-app/dist/5773.js 9.93 kB 0 B
packages/esm-ward-app/dist/5940.js 2.4 kB 0 B
packages/esm-ward-app/dist/6047.js 2.6 kB 0 B
packages/esm-ward-app/dist/6089.js 11 kB 0 B
packages/esm-ward-app/dist/6174.js 6.02 kB 0 B
packages/esm-ward-app/dist/6270.js 404 B 0 B
packages/esm-ward-app/dist/6371.js 2.4 kB 0 B
packages/esm-ward-app/dist/6377.js 2.4 kB 0 B
packages/esm-ward-app/dist/6418.js 9.77 kB 0 B
packages/esm-ward-app/dist/6444.js 2.4 kB 0 B
packages/esm-ward-app/dist/6508.js 2.75 kB 0 B
packages/esm-ward-app/dist/6673.js 64.7 kB 0 B
packages/esm-ward-app/dist/6703.js 3.69 kB 0 B
packages/esm-ward-app/dist/6724.js 2.4 kB 0 B
packages/esm-ward-app/dist/6802.js 271 B 0 B
packages/esm-ward-app/dist/6904.js 2.4 kB 0 B
packages/esm-ward-app/dist/7045.js 2.4 kB 0 B
packages/esm-ward-app/dist/7175.js 2.4 kB 0 B
packages/esm-ward-app/dist/7182.js 2.4 kB 0 B
packages/esm-ward-app/dist/7249.js 609 B 0 B
packages/esm-ward-app/dist/7330.js 23.7 kB 0 B
packages/esm-ward-app/dist/7742.js 2.58 kB 0 B
packages/esm-ward-app/dist/7912.js 2.73 kB 0 B
packages/esm-ward-app/dist/8340.js 312 B 0 B
packages/esm-ward-app/dist/8358.js 2.4 kB 0 B
packages/esm-ward-app/dist/8359.js 3.38 kB 0 B
packages/esm-ward-app/dist/8417.js 5.35 kB 0 B
packages/esm-ward-app/dist/8424.js 11.5 kB 0 B
packages/esm-ward-app/dist/8493.js 246 B 0 B
packages/esm-ward-app/dist/8695.js 2.81 kB 0 B
packages/esm-ward-app/dist/9011.js 2.46 kB 0 B
packages/esm-ward-app/dist/9061.js 2.5 kB 0 B
packages/esm-ward-app/dist/9072.js 2.4 kB 0 B
packages/esm-ward-app/dist/9080.js 8.25 kB 0 B
packages/esm-ward-app/dist/9427.js 396 B 0 B
packages/esm-ward-app/dist/9712.js 26.4 kB 0 B
packages/esm-ward-app/dist/9771.js 3 kB 0 B
packages/esm-ward-app/dist/9806.js 2.4 kB 0 B
packages/esm-ward-app/dist/9983.js 7.7 kB 0 B
packages/esm-ward-app/dist/main.js 26.9 kB 0 B
packages/esm-ward-app/dist/openmrs-esm-ward-app.js 25.4 kB 0 B

compressed-size-action

dkayiwa and others added 6 commits July 31, 2026 14:35
Reviewing the first commit turned up one more copy of the defect and four
guards no test was holding down.

The "Serve" button inside the modal the Call action opens fires a second
`assignticket` request, chained off `updateQueueEntry`'s success, so the
rejection handler on that first request never covered it. Driving it in a
browser with the request aborted produced exactly what the ticket reports:
one full-screen overlay iframe, `pageerror: TypeError: Failed to fetch`, no
snackbar. It now reports the failure the way the Call action does.

The last-resort `runAction` net only wrote to the console, which leaves the
production half of the defect in place — a click that appears to do nothing.
It now shows a snackbar too, and two tests hold it there; before, removing
the net entirely broke no test at all.

Mutation testing the rest found three more survivors: nothing covered a
missing queue name, a missing calling status, or the fallback used when a
failure carries no message. Fourteen deliberate breakages now each fail at
least one test.

The action no longer runs `mapVisitQueueEntryProperties`, a twenty-five
field mapper with date parsing in it, to read two fields on every click. It
reads the queue name off the entry and the ticket number through a small
shared `getVisitQueueNumber`, which the mapper now uses too. That also moves
the work behind the guard, where a throw is reported rather than swallowed.

Finally, the missing-details message told the user to check the service
queues configuration. The value that is actually missing in ordinary use is
the ticket number, which comes from a visit attribute, so a clerk looking at
a visit created outside the queue flow was being sent to a configuration
page they cannot change. That case now names the visit instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwrMcxXwSx8rPmMZu2VigK
Fuzzing the failure path with the range of values `openmrsFetch` can reject
with turned up two ways the handling added for this ticket could itself fail,
which is the original defect wearing the error handler's clothes.

`getErrorMessage` promises a `string`, but reads a shape the REST API
documents rather than one anything enforces, so a rejection carrying a
non-string `message` was handed straight to a snackbar subtitle — a React
render crash. It now keeps its word and lets the caller's fallback speak.

`runAction` is the last thing between a failed action and an unhandled
rejection, and it reported failures without protecting the reporting. A throw
from the snackbar store, or from reading the rejected value, escaped as the
very rejection the net exists to catch. The reporting is now guarded, so
`runAction` cannot reject.

Also covers the generic-message fallback on the Serve request, the last
branch this ticket added that no test reached.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwrMcxXwSx8rPmMZu2VigK
…ess path

Re-running the mutation set found one survivor: deleting the
`await mutateQueueEntries()` that precedes the modal broke no test, because
the hook's mock was an anonymous `vi.fn()` nobody could see. The entry's
status has changed on the server by that point, so without the re-fetch the
"Serve patient" modal opens on top of a table still showing "Waiting".

The mock is now a visible spy and the success-path test asserts it, which
takes the set to eighteen mutants and no survivors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwrMcxXwSx8rPmMZu2VigK
…light

`disabled` takes a button out of the tab order, so the moment a keyboard user
presses Call the browser drops focus onto `document.body` — measured on the
standalone, before the request has even been sent. Getting back to the button
to read the outcome or retry then means tabbing in from the top of a queue
table that is one row per waiting patient. That is the failure this PR's
visible error message exists to prevent, reintroduced by the debounce.

`aria-disabled` plus `aria-busy` says the same thing to a screen reader without
removing the button from the tab order, and `handleClick`'s `isPendingRef`
guard — not the attribute — is already what discards the second click. Carbon's
own `--btn--disabled` class was not used to keep the greyed-out look, because
it pairs the disabled colour with `outline: none` on `:focus` and would hide
the focus ring on the button we are deliberately keeping focused; the trade is
that a sighted user no longer sees the button dim for the length of a request.

Also rewrites `callPatientMissingConfiguration`. "Calling status" is the name of
a configuration property rather than anything a triage clerk has a word for, and
neither that nor the queue's name is something they can go and change, so the
message now says whose job it is.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwrMcxXwSx8rPmMZu2VigK
The overflow menu item had no in-flight guard, so two clicks 85ms apart on
its Call item sent two POST /queueutil/assignticket requests for one intended
call — measured on a running queue table, not inferred. Neither control is
`disabled` while its request runs, because that drops a keyboard user's focus
mid-request, so nothing in the DOM discards the second click.

The inline button's guard is extracted into a `useSingleFlight()` hook that
both call sites now share, and the button's guard was re-measured on the same
page because `aria-disabled` leaves a button clickable. Both send one request
for a rapid double-click and release afterwards, so a deliberate retry works.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwrMcxXwSx8rPmMZu2VigK
The row action guards its own error reporting, because a throw while reporting
a failure escapes a rejection handler as exactly the unhandled rejection the
report replaces. The three rejection handlers in the Serve patient modal — the
other path this change touches — did not, so the two behaved differently under
the same failure. They now report through one guarded helper.

Two of them also read `error?.message`, which shows the wrapper's "Server
responded with 500 ..." instead of the wording the server sent, and hands a
non-string straight to a snackbar subtitle where React cannot render it. Both
now use `getErrorMessage`, like every other queue entry mutation.

When only the ticket-display request fails, `updateQueueEntry` has already
succeeded: the entry has ended and been replaced by one reading "In Service",
confirmed against the API on a running standalone. Reporting that as "Error
calling patient" told the user nothing had happened, and left the table behind
the modal showing a status that is no longer true with nothing to revalidate
it. It now names what happened and re-reads the table. Repairing the half-done
transition still needs a compensating request and is not attempted here; a
second Serve press cannot make it worse, because the backend refuses to end an
entry that has already ended.

`mutateQueueEntries()` was also called bare from three promise handlers, each a
floating rejection of its own; they now go through a helper that logs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwrMcxXwSx8rPmMZu2VigK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant