Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feature) O3-2750 Service Queues - Configurable queues table to display queue entries by status #968

Closed
wants to merge 5 commits into from

Conversation

chibongho
Copy link
Contributor

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 conforms to the OpenMRS 3.0 Styleguide and design documentation.
  • My work includes tests or is validated by existing tests.

Summary

A new queues table with the following feature:

  • configurable columns in the queues table.
  • For each status available on the selected queue, we show a tab with a table of queue entries of the selected status. (If no queue selected, then statuses from all possible queues are shown.)

This table is a work in progress, and is mounted on an alternate route (/queue-table-by-status). I intend for this table to replace the existing table in the main route (/) when it is feature-complete.

Screenshots

OpenMRS.5.-.-.Microsoft.Edge.2024-02-06.15-43-34.mp4

Related Issue

Other

Copy link
Contributor

github-actions bot commented Feb 6, 2024

Size Change: -53.4 kB (-2%)

Total Size: 2.89 MB

Filename Size Change
packages/esm-service-queues-app/dist/895.js 0 B -52.3 kB (removed) 🏆
ℹ️ View Unchanged
Filename Size Change
packages/esm-active-visits-app/dist/130.js 123 kB 0 B
packages/esm-active-visits-app/dist/255.js 2.21 kB 0 B
packages/esm-active-visits-app/dist/271.js 671 B 0 B
packages/esm-active-visits-app/dist/277.js 12.2 kB 0 B
packages/esm-active-visits-app/dist/316.js 42.9 kB 0 B
packages/esm-active-visits-app/dist/319.js 631 B 0 B
packages/esm-active-visits-app/dist/382.js 1.15 kB 0 B
packages/esm-active-visits-app/dist/448.js 47.1 kB 0 B
packages/esm-active-visits-app/dist/460.js 727 B 0 B
packages/esm-active-visits-app/dist/574.js 545 B 0 B
packages/esm-active-visits-app/dist/588.js 6.66 kB 0 B
packages/esm-active-visits-app/dist/635.js 1.15 kB 0 B
packages/esm-active-visits-app/dist/644.js 671 B 0 B
packages/esm-active-visits-app/dist/729.js 3.1 kB 0 B
packages/esm-active-visits-app/dist/757.js 649 B 0 B
packages/esm-active-visits-app/dist/784.js 2.63 kB 0 B
packages/esm-active-visits-app/dist/788.js 551 B 0 B
packages/esm-active-visits-app/dist/807.js 864 B 0 B
packages/esm-active-visits-app/dist/833.js 669 B 0 B
packages/esm-active-visits-app/dist/879.js 2.94 kB 0 B
packages/esm-active-visits-app/dist/main.js 63.8 kB 0 B
packages/esm-active-visits-app/dist/openmrs-esm-active-visits-app.js 3.33 kB 0 B
packages/esm-appointments-app/dist/130.js 123 kB 0 B
packages/esm-appointments-app/dist/152.js 257 B 0 B
packages/esm-appointments-app/dist/163.js 48.1 kB 0 B
packages/esm-appointments-app/dist/255.js 2.23 kB 0 B
packages/esm-appointments-app/dist/271.js 2.16 kB 0 B
packages/esm-appointments-app/dist/303.js 258 B 0 B
packages/esm-appointments-app/dist/319.js 1.99 kB 0 B
packages/esm-appointments-app/dist/460.js 2.18 kB 0 B
packages/esm-appointments-app/dist/574.js 1.72 kB 0 B
packages/esm-appointments-app/dist/588.js 6.65 kB 0 B
packages/esm-appointments-app/dist/591.js 16.9 kB 0 B
packages/esm-appointments-app/dist/595.js 242 kB 0 B
packages/esm-appointments-app/dist/644.js 2.16 kB 0 B
packages/esm-appointments-app/dist/729.js 3.1 kB 0 B
packages/esm-appointments-app/dist/757.js 1.75 kB 0 B
packages/esm-appointments-app/dist/784.js 2.63 kB 0 B
packages/esm-appointments-app/dist/788.js 1.75 kB 0 B
packages/esm-appointments-app/dist/80.js 2.52 kB 0 B
packages/esm-appointments-app/dist/807.js 2.4 kB 0 B
packages/esm-appointments-app/dist/833.js 1.99 kB 0 B
packages/esm-appointments-app/dist/main.js 294 kB 0 B
packages/esm-appointments-app/dist/openmrs-esm-appointments-app.js 3.29 kB 0 B
packages/esm-patient-list-management-app/dist/130.js 123 kB 0 B
packages/esm-patient-list-management-app/dist/255.js 2.21 kB 0 B
packages/esm-patient-list-management-app/dist/271.js 1.33 kB 0 B
packages/esm-patient-list-management-app/dist/295.js 99.3 kB 0 B
packages/esm-patient-list-management-app/dist/319.js 1.53 kB 0 B
packages/esm-patient-list-management-app/dist/382.js 1.15 kB 0 B
packages/esm-patient-list-management-app/dist/435.js 22.7 kB 0 B
packages/esm-patient-list-management-app/dist/460.js 1.73 kB 0 B
packages/esm-patient-list-management-app/dist/574.js 1.34 kB 0 B
packages/esm-patient-list-management-app/dist/588.js 6.66 kB 0 B
packages/esm-patient-list-management-app/dist/591.js 16.9 kB 0 B
packages/esm-patient-list-management-app/dist/635.js 1.15 kB 0 B
packages/esm-patient-list-management-app/dist/644.js 1.31 kB 0 B
packages/esm-patient-list-management-app/dist/716.js 4.66 kB 0 B
packages/esm-patient-list-management-app/dist/729.js 3.1 kB 0 B
packages/esm-patient-list-management-app/dist/757.js 1.51 kB 0 B
packages/esm-patient-list-management-app/dist/784.js 2.64 kB 0 B
packages/esm-patient-list-management-app/dist/788.js 1.34 kB 0 B
packages/esm-patient-list-management-app/dist/807.js 1.84 kB 0 B
packages/esm-patient-list-management-app/dist/833.js 1.6 kB 0 B
packages/esm-patient-list-management-app/dist/main.js 126 kB 0 B
packages/esm-patient-list-management-app/dist/openmrs-esm-patient-list-management-app.js 3.3 kB 0 B
packages/esm-patient-registration-app/dist/130.js 123 kB 0 B
packages/esm-patient-registration-app/dist/152.js 262 B 0 B
packages/esm-patient-registration-app/dist/209.js 36.4 kB 0 B
packages/esm-patient-registration-app/dist/255.js 2.21 kB 0 B
packages/esm-patient-registration-app/dist/271.js 1.6 kB 0 B
packages/esm-patient-registration-app/dist/303.js 260 B 0 B
packages/esm-patient-registration-app/dist/319.js 1.97 kB 0 B
packages/esm-patient-registration-app/dist/460.js 2.03 kB 0 B
packages/esm-patient-registration-app/dist/537.js 2.34 kB 0 B
packages/esm-patient-registration-app/dist/574.js 1.7 kB 0 B
packages/esm-patient-registration-app/dist/591.js 16.9 kB 0 B
packages/esm-patient-registration-app/dist/62.js 6.86 kB 0 B
packages/esm-patient-registration-app/dist/644.js 1.6 kB 0 B
packages/esm-patient-registration-app/dist/729.js 3.1 kB 0 B
packages/esm-patient-registration-app/dist/730.js 115 kB 0 B
packages/esm-patient-registration-app/dist/735.js 464 B 0 B
packages/esm-patient-registration-app/dist/757.js 1.96 kB 0 B
packages/esm-patient-registration-app/dist/784.js 2.64 kB 0 B
packages/esm-patient-registration-app/dist/788.js 1.63 kB 0 B
packages/esm-patient-registration-app/dist/807.js 2.43 kB 0 B
packages/esm-patient-registration-app/dist/833.js 1.97 kB 0 B
packages/esm-patient-registration-app/dist/879.js 2.94 kB 0 B
packages/esm-patient-registration-app/dist/884.js 6.1 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 3.34 kB 0 B
packages/esm-patient-search-app/dist/130.js 123 kB 0 B
packages/esm-patient-search-app/dist/152.js 261 B 0 B
packages/esm-patient-search-app/dist/255.js 2.21 kB 0 B
packages/esm-patient-search-app/dist/271.js 936 B 0 B
packages/esm-patient-search-app/dist/303.js 260 B 0 B
packages/esm-patient-search-app/dist/319.js 950 B 0 B
packages/esm-patient-search-app/dist/379.js 25.6 kB +128 B (+1%)
packages/esm-patient-search-app/dist/382.js 1.15 kB 0 B
packages/esm-patient-search-app/dist/460.js 1.07 kB 0 B
packages/esm-patient-search-app/dist/564.js 21.8 kB 0 B
packages/esm-patient-search-app/dist/574.js 794 B 0 B
packages/esm-patient-search-app/dist/588.js 6.66 kB 0 B
packages/esm-patient-search-app/dist/591.js 16.9 kB 0 B
packages/esm-patient-search-app/dist/635.js 1.15 kB 0 B
packages/esm-patient-search-app/dist/644.js 936 B 0 B
packages/esm-patient-search-app/dist/729.js 3.1 kB 0 B
packages/esm-patient-search-app/dist/757.js 950 B 0 B
packages/esm-patient-search-app/dist/784.js 2.63 kB 0 B
packages/esm-patient-search-app/dist/788.js 788 B 0 B
packages/esm-patient-search-app/dist/807.js 1.13 kB 0 B
packages/esm-patient-search-app/dist/833.js 982 B 0 B
packages/esm-patient-search-app/dist/main.js 50.6 kB +53 B (0%)
packages/esm-patient-search-app/dist/openmrs-esm-patient-search-app.js 3.34 kB 0 B
packages/esm-service-queues-app/dist/130.js 123 kB 0 B
packages/esm-service-queues-app/dist/152.js 262 B 0 B
packages/esm-service-queues-app/dist/255.js 2.23 kB 0 B
packages/esm-service-queues-app/dist/271.js 3.11 kB 0 B
packages/esm-service-queues-app/dist/303.js 261 B 0 B
packages/esm-service-queues-app/dist/319.js 3.14 kB 0 B
packages/esm-service-queues-app/dist/328.js 3.07 kB 0 B
packages/esm-service-queues-app/dist/389.js 2.42 kB 0 B
packages/esm-service-queues-app/dist/42.js 242 B 0 B
packages/esm-service-queues-app/dist/425.js 2.06 kB 0 B
packages/esm-service-queues-app/dist/460.js 3.96 kB 0 B
packages/esm-service-queues-app/dist/478.js 2.93 kB 0 B
packages/esm-service-queues-app/dist/574.js 3.14 kB +8 B (0%)
packages/esm-service-queues-app/dist/588.js 6.66 kB 0 B
packages/esm-service-queues-app/dist/591.js 16.9 kB 0 B
packages/esm-service-queues-app/dist/613.js 155 kB 0 B
packages/esm-service-queues-app/dist/616.js 2.71 kB 0 B
packages/esm-service-queues-app/dist/644.js 3.06 kB 0 B
packages/esm-service-queues-app/dist/694.js 2.64 kB 0 B
packages/esm-service-queues-app/dist/724.js 54 kB 0 B
packages/esm-service-queues-app/dist/729.js 3.1 kB 0 B
packages/esm-service-queues-app/dist/757.js 3.13 kB 0 B
packages/esm-service-queues-app/dist/784.js 2.63 kB 0 B
packages/esm-service-queues-app/dist/788.js 3.12 kB 0 B
packages/esm-service-queues-app/dist/807.js 4.36 kB 0 B
packages/esm-service-queues-app/dist/833.js 3.62 kB 0 B
packages/esm-service-queues-app/dist/981.js 234 B -2.7 kB (-92%) 🏆
packages/esm-service-queues-app/dist/988.js 300 B 0 B
packages/esm-service-queues-app/dist/main.js 212 kB +1.44 kB (+1%)
packages/esm-service-queues-app/dist/openmrs-esm-service-queues-app.js 3.31 kB +1 B (0%)

compressed-size-action

Copy link
Member

@ibacher ibacher left a comment

Choose a reason for hiding this comment

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

Alright, now that I've actually seen this PR, I'm a little horrified and worried. Some more concrete things below.


const apiUrl = `/ws/rest/v1/visit-queue-entry?location=${queueLocationUuid}&v=full`;
const { t } = useTranslation();
useTranslation();
Copy link
Member

Choose a reason for hiding this comment

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

Is this here intentionally?

?.map(mapVisitQueueEntryProperties)
.filter((data) => data.service == currServiceName);
const mappedVisitQueueEntries = visitQueueEntries?.map(useVisitQueueEntryProperties);
if (currServiceName && currServiceName !== t('all', 'All')) {
Copy link
Member

Choose a reason for hiding this comment

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

On the other hand, it looks like we need the translation hook here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Thanks. Missed this when I was refactoring the function. I'm surprised this didn't given me any errors.

Copy link
Member

Choose a reason for hiding this comment

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

seems odd that we are basing logic on string comparisions to a localized string, but I suspect this is the existing logic, not something you are introducing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

correct. This is old code.

_type: Type.Array,
_description: 'Columns to appear in the queues table.',
_elements: {
id: {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this property? In all of the examples, it ends up being the headerI18nKey...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, we can forgo this. This means requiring the columns headers to be unique, which should be fine.

Comment on lines 98 to 100
export const queueTableName = getSyncLifecycle(QueueTableName, options);
export const queueTablePriority = getSyncLifecycle(QueueTablePriority, options);
export const queueTableStatus = getSyncLifecycle(QueueTableStatus, options);
Copy link
Member

Choose a reason for hiding this comment

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

Use getAsyncLifecycle(). getSyncLifecycle() should basically just be used for links.


const currentStatusIndex = Math.max(0, allowedStatuses?.findIndex((s) => s?.uuid == currentStatusUuid));

const visitedQueueEntriesByLocationAndQueueAndStatus = visitQueueEntriesByLocation
Copy link
Member

Choose a reason for hiding this comment

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

visited?

</TabList>
<TabPanels>
{allowedStatuses?.map((s) => (
<TabPanel key={s?.uuid} style={{ padding: 0 }}>
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't use something as a key if it may be undefined. It would be better to use the index argument, if this may not be set.

Copy link
Member

Choose a reason for hiding this comment

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

When would it be null? I'd think we can just remove the ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, that was sloppy on my part. It should never be undefined/null. I'll remove the ?. I think using index as key is bad unless the same index always corresponds to the same object (which is not the case here).

Copy link
Member

Choose a reason for hiding this comment

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

This does not appear to be fixed yet.

selectedIndex={currentStatusIndex}
onChange={({ selectedIndex }) => setCurrentStatusUuid(allowedStatuses[selectedIndex].uuid)}
className={styles.tabs}>
<TabList style={{ paddingLeft: '1rem' }} aria-label="Outpatient tabs" contained>
Copy link
Member

Choose a reason for hiding this comment

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

It would be better to define a scss file and put this in a class (this should also be a standard Carbon spacing unit).

paginatedQueueEntries?.map((queueEntry) => {
const row = {};
queueTableColumns.forEach((conf) => {
row[conf.id] = <ExtensionSlot name={conf.extensionSlotName} state={{ queueEntry }} />;
Copy link
Member

Choose a reason for hiding this comment

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

Yikes! This is stress-testing the extension system! I was imagining this working as something like a slot-per-column, or, better yet, a simple mapping function rather than a slot-per-cell. I guess we'll see how this works...

Copy link
Member

Choose a reason for hiding this comment

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

For reference, a 20-person queue with just 3 columns is now 60 separate slots with 60 separate extensions.

Copy link
Member

Choose a reason for hiding this comment

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

Is that true? If so, I agree we may need an alternative. Ultimately, we just want to be able to have a list of columnDefinitions that can be configured with a value function or component that takes in a queueEntry as an argument/prop. If there was a straightforward way to register functions or components with a lookup key, and then to refer to these with this key to use when rendering, that's what we need.

It isn't entirely similar, but I'd think this kind of thing could also eliminate the kind of hard-coding that one finds in places like this and this. The similarity is that there is a need to support end-user configuration via a string value, and then have this string value determine what actual component is rendered.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ibacher I did some rough profiling work. Using a table with 10 rows and 3 columns on my computer, I measure the time to render the cells using the components directly vs using <ExtensionSlot> . The direct way has 1ms of time lapse between the useEffect(..., []) calls of the first and the last rendered cells, while via <ExtensionSlot> the time lapse is 20ms. So... technically 20x worse, but still small enough to be acceptable?

Copy link
Member

Choose a reason for hiding this comment

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

Just seeing this thread now, it wasn't visible when I was looking at the PR itself... did we move away from this approach? I agree that having a slot-per-cell seems like a lot, but don't necessarily want to push for a full refactor now if we want to just see how it works in this case.

One goal on my end would be keep the code a simple as possible (the key being "as possible", I know there will be some complexity) from a extension and readability perspective for what I suspect will be the 80% use case for most implementions, just to use the default columns.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't love this approach., but I'm keeping it as is for now (unless others have objection). It's ok performance-wise, but developer experience isn't great as we need somewhat bloated JSON to define the columns. This approach also doesn't address how to go about having the table show different columns at different places. (For example, we might want a "current queue" column when we are looking at queue entries from all queues, but can hide the column if we're only looking at a specific queue.)

Copy link
Member

Choose a reason for hiding this comment

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

@chibongho and I talked more about this today, and we decided we are going to forego the config-based column configurability and move that into a separate draft PR for that POC work, in favor of moving to an approach that allows configurability via props and re-usable components. Stay tuned.

};

export const QueueTablePriority = ({ queueEntry }: { queueEntry: VisitQueueEntry }) => {
return <>{queueEntry.queueEntry.priority.display}</>;
Copy link
Member

Choose a reason for hiding this comment

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

This component really should render a pill, as shown in the designs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll make them pills. We might have to re-think the coloring if we want the flexibility of having available priorities configurable per queue (currently in our spec). I'll worry about that in a later PR.

Copy link
Member

@ibacher ibacher Feb 8, 2024

Choose a reason for hiding this comment

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

Yeah, my original thought was to have the color based a ConceptAttribute, so the queue priorities could tell you how they should appear. Thinking particularly about, e.g., color-based triage systems.

@@ -119,10 +120,10 @@ export const QueueTableByStatus: React.FC = () => {
};

interface QueueTableProps {
visitedQueueEntriesByLocationAndQueueAndStatus: VisitQueueEntry[];
visitQueueEntriesByLocationAndQueueAndStatus: VisitQueueEntry[];
Copy link
Member

Choose a reason for hiding this comment

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

I would expect a QueueTable to take in a queueEntries or visitQueueEntries property. Why are we calling these things ByLocationAndQueueAndStatus? Ideally we'd use the same QueueTable and QueueTable props to render QueueTables in different contexts, with different columns, and with different collections of QueueEntries. In the context above, you might set the queueEntries from visitQueueEntriesByLocationAndQueueAndStatus, but that is only this particular use case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted to make it explicit that this VisitQueueEntry[] has been filtered. You're right that the filtering can be in different contexts and does not necessarily have to be by Location/Queue/Status. I can renamed it to queueEntriesToDisplay.

Copy link
Member

Choose a reason for hiding this comment

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

queueEntriesToDisplay is fine I guess, but I still prefer just queueEntries for readability and consistency. I don't think anyone should have any expectation that this is every queue entry since the beginning of time that is expected to be passed in as a prop. If this was always going to have the same usage, it wouldn't be a prop, you would just retrieve them within the component. Passing it as a prop implies that the queue table takes in a list of queue entries to render, as that's the whole point.

Copy link
Member

Choose a reason for hiding this comment

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

If I'm following correctly :) I agree with Mike's logic here.

</TabList>
<TabPanels>
{allowedStatuses?.map((s) => (
<TabPanel key={s?.uuid} style={{ padding: 0 }}>
Copy link
Member

Choose a reason for hiding this comment

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

This does not appear to be fixed yet.

return <>Loading....</>;
} else if (noStatuses) {
return <>No available statuses configured for queue</>;
Copy link
Member

Choose a reason for hiding this comment

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

All of these messages need to be translated, not hard-coded in English

featureName: 'queue table name column',
moduleName,
},
);
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain why this has been modified like this, instead of just changing "getSyncLifecycle" to "get AsyncLifecycle"?

Copy link
Contributor Author

@chibongho chibongho Feb 7, 2024

Choose a reason for hiding this comment

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

The two functions don't take in the same inputs. getAsyncLifecycle expects a Promise returned by dynamically calling import("***.component"), where ***.component.tsx is usually a file that defines a Component that is exported with default export'. In this case, queue-table-cells.component.tsx has several exports, and therefore no default export, The .then(...) syntax is admittedly uglier than the pattern in other places. The alternative would be to create separate files for each of those 3 components defined in queue-table-cells.component.tsx.

Copy link
Member

Choose a reason for hiding this comment

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

OK, defer to others like @ibacher on this. I don't feel like I tend to see it like this in the code elsewhere, so that might imply that the right thing is to move the components into separate files with default exports?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, generally, the component should be the default export, even if other things are exported (although that sounds suspiciously like code that shouldn't all be in one component file; usually a component file should just define a single React component and if things need to be shared, they go elsewhere).

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I need to refresh my memory on how all this stuff works, more or less defer to @ibacher on this one

<QueueTable
visitedQueueEntriesByLocationAndQueueAndStatus={visitedQueueEntriesByLocationAndQueueAndStatus}
/>
<QueueTable visitQueueEntriesByLocationAndQueueAndStatus={visitQueueEntriesByLocationAndQueueAndStatus} />
Copy link
Member

Choose a reason for hiding this comment

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

The entries we are passing in here have nothing to do with ByLocation, do they? Filtering by Queue and Status is enough. I don't believe we need to do anything with Location?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right now, I'm doing useUnmappedVisitQueueEntries(currentLocationUuid), which is only getting visitQueueEntries from the current location (hard coded to user's session location right now). I haven't done this yet, but I plan to have the list of queues dropdown (from useQueues()) be limited by current location as well, and hook up the location dropdown currently defined in the queue app's home page to control this location.

Copy link
Member

Choose a reason for hiding this comment

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

The whole "mapped" vs "unmapped" visit queue entries thing is a bit confusing to me, to be honest. Do we need to have both of these? I understand the value in having a nicer object to work with than the REST response, but this doesn't feel exactly right. What is done in other esms that have user-friendly objects to work with and map to/from rest representations?

Regarding the other point, this should really depend on the nature of the overall page that is using this component. I would not expect variable names (or assumptions) like this within a "queue-table" component. If there is a page called "queues-for-location", then it would make sense to have variable names in that page that have names like that. But in a generic queue table component - no.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I intend to get rid of the MappedVisitQueueEntry when this new table is more feature complete and can replace the existing table. The existing table uses MappedVisitQueueEntry, so for now supporting both the unmapped and mapped versions is meant to be an un-invasive way to reuse old code while we try to migrate. I can add some comment about that. (@mogoodrich is also getting rid of the similar MappedAppointment type in his other PR)

Copy link
Member

@mogoodrich mogoodrich left a comment

Choose a reason for hiding this comment

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

Sorry for the late review... I added a few comments, though admittedly I'm as up to speed on the queue module to give a 100% review, but overall it looks like. If it works for Ian I'm good to go.

@@ -105,8 +107,8 @@ export interface MappedVisitQueueEntry {
queueComingFrom: string;
}

interface UseVisitQueueEntries {
visitQueueEntries: Array<MappedVisitQueueEntry> | null;
interface UseVisitQueueEntries<T extends MappedVisitQueueEntry | VisitQueueEntry> {
Copy link
Member

Choose a reason for hiding this comment

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

I haven't dove deeplying the queue module yet, so I'm just guessing about this, but if this is anything like the Appointment module, do we want to try to standardized on a single queue entry interface (probably VisitQueueEntry and retire the MappedVisitQueue entry?). Is a lot of this code just stuff to support translating between a mapped and "normal" visit queue entry? (The answer may be yes, but we don't want to tackle it in this commit).

Copy link
Member

Choose a reason for hiding this comment

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

Update: I see the later comments about getting rid of this, +1

?.map(mapVisitQueueEntryProperties)
.filter((data) => data.service == currServiceName);
const mappedVisitQueueEntries = visitQueueEntries?.map(useVisitQueueEntryProperties);
if (currServiceName && currServiceName !== t('all', 'All')) {
Copy link
Member

Choose a reason for hiding this comment

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

seems odd that we are basing logic on string comparisions to a localized string, but I suspect this is the existing logic, not something you are introducing?

featureName: 'queue table name column',
moduleName,
},
);
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I need to refresh my memory on how all this stuff works, more or less defer to @ibacher on this one

@@ -119,10 +120,10 @@ export const QueueTableByStatus: React.FC = () => {
};

interface QueueTableProps {
visitedQueueEntriesByLocationAndQueueAndStatus: VisitQueueEntry[];
visitQueueEntriesByLocationAndQueueAndStatus: VisitQueueEntry[];
Copy link
Member

Choose a reason for hiding this comment

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

If I'm following correctly :) I agree with Mike's logic here.

@chibongho
Copy link
Contributor Author

Ok, updated the PR.

  • Separate each queue table cell component into its own file
  • Separate queue-table-by-status component into its own file, remove location-related code from it
    • For now, there is no UI to filter which queue to look at, so the table renders queue entries from all queues

@mseaton mseaton closed this Feb 12, 2024
@chibongho chibongho deleted the queue-table-by-status branch June 6, 2024 14:49
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.

4 participants