Skip to content

(feat) O3-5572: Allow adding non-coded custom diagnoses#3224

Open
ToNyRANDRIAMANANTSOA wants to merge 10 commits into
openmrs:mainfrom
ToNyRANDRIAMANANTSOA:feat/O3-5572-allow-adding-non-coded-custom-diagnoses
Open

(feat) O3-5572: Allow adding non-coded custom diagnoses#3224
ToNyRANDRIAMANANTSOA wants to merge 10 commits into
openmrs:mainfrom
ToNyRANDRIAMANANTSOA:feat/O3-5572-allow-adding-non-coded-custom-diagnoses

Conversation

@ToNyRANDRIAMANANTSOA
Copy link
Copy Markdown

Requirements

  • This PR has a title that briefly describes the work done including the ticket number. If there is a ticket, make sure your PR title includes a conventional commit label. See existing PR titles for inspiration.
  • My work is based on designs, which are linked or shown either in the Jira ticket or the description below. (See also: Styleguide)
  • My work includes tests or is validated by existing tests.

Summary

Hi @O3-Team,

I’m working on improving the Visit Notes and Patient Chart diagnoses data entry experience. Currently, if a clinician cannot find a coded concept, the flow stops at "No results found."

I’m proposing we move toward an inline "Add Custom" dropdown option rather than a separate "Other" free-text field, like what is already available in the allergies form.

The Proposed Approach:

  • The autocomplete displays a virtual option: Add "[Search Term]" as custom diagnosis:

    • If the search term input value isn't already in the selected diagnoses AND
      • when a search returns zero results
      • or if the input value isn't exactly in the available options
  • Selecting this maps the value to the diagnosis.nonCoded attribute.

    • This worked right away because the API already supports nonCoded for Diagnoses.

Screenshots

image chrome_TqlV2bKRIj

Related Issue

Other

Why I think this is a better UX:

  1. Contextual Flow:
    • Clinicians don't have to know in advance they have to search for "Other" when they want to add free-text options.
      • They can just instantly add custom diagnosis when they need to.
      • Thus, less cognitive load for the user.
    • Faster and uninterrupted flow: Instead of the user having to type, then can't find option, delete/stop his input, search 'Other' and then navigate and refill a different input field, the user never leaves the search bar, thus preventing more "interaction cost",
  2. Cleaner UI: Avoids adding additional inputs that may clutter the form 90% of the time.
  3. Data Quality: Encourages searching for a coded concept first before opting for free-text.

Copy link
Copy Markdown
Member

@denniskigen denniskigen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this, @ToNyRANDRIAMANANTSOA! The search-first, custom-fallback UX is a nice improvement over a separate "Other" field.

One note: this adds a new nonCoded diagnosis path (add, remove, duplicate prevention, payload shape) but doesn't add targeted tests for any of it. I'd strongly recommend adding coverage before merge.

// still allow proposing adding it as a custom free-text diagnosis
!searchResults
.map((diagnosis) => diagnosis.display.toLocaleLowerCase())
.includes(value.toLocaleLowerCase()) && (
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition only checks whether the search term appears in the API results. It doesn't check whether the same free-text string has already been selected as a custom diagnosis.

Common scenario: a clinician adds "malaria xyz" as a custom diagnosis, then searches for it again later. The API returns fuzzy coded matches (e.g. "Malaria") but not the exact string. This button reappears and creates a second identical nonCoded diagnosis on the same note.

Please gate this with isDiagnosisNotSelected({ display: value }), the same way the zero-results path does.

const isPrimaryDiagnosisSelected = selectedPrimaryDiagnoses.some((selectedDiagnosis) =>
diagnosis.uuid
? diagnosis.uuid === selectedDiagnosis.diagnosis.coded
: diagnosis.display === selectedDiagnosis.diagnosis.nonCoded,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isDiagnosisNotSelected compares non-coded diagnoses case-sensitively (diagnosis.display === selectedDiagnosis.diagnosis.nonCoded). After adding a custom diagnosis like "Malaria", searching for "malaria" in the zero-results path still allows adding it again because the duplicate check uses strict equality. Please normalize both sides before comparing (e.g. .toLocaleLowerCase()).

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.

2 participants