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

MF-798: Add swr to appointments widget #400

Merged
merged 2 commits into from
Oct 1, 2021
Merged

MF-798: Add swr to appointments widget #400

merged 2 commits into from
Oct 1, 2021

Conversation

denniskigen
Copy link
Member

@denniskigen denniskigen commented Sep 25, 2021

Requirements

  • This PR has a title that briefly describes the work done, including the ticket number if there is a ticket.
  • My work conforms to the OpenMRS 3.0 Styleguide.
  • I checked for feature overlap with existing widgets.

Summary

This PR:

  1. Adds SWR data fetching hooks to the Appointments widget.
  2. Refactors the existing components to reuse these hooks.
  3. Refactors existing tests to work within the SWR paradigm.
  4. Renames components to use the plural form 'appointments' as their file name prefix.
  5. Adds the extract-translations task to the package.json file in the appointments microfrontend.
  6. Adds empty states to the past and upcoming appointments data tables.

Issue

https://issues.openmrs.org/browse/MF-798

@denniskigen denniskigen changed the title MF 798: Add swr to appointments widget MF-798: Add swr to appointments widget Sep 25, 2021
@openmrs openmrs deleted a comment from HerbertYiga Sep 28, 2021
1. Refactor the appointments Form logic to:

  - Use SWR for data fetching.
  - Add a call to mutate so that the appointments widgets get a trigger to revalidate their data when a new appointment is successfully scheduled.
  - Simplify state change handlers so it's absolutely clear what's changing at any given time.
  - Render a SearchSkeleton instead of a DataTableSkeleton when the form is loading after launch.

2. Rename the appointments form workspace extension slot to the plural form `appointment-form-workspace`.
3. Move the useAppointmentService hook to the appointments resource.
<section className={styles.formGroup}>
<span>{t('location', 'Location')}</span>
<Select
id="location"
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's pick a stronger ID. These need to be globally unique, right?

Suggested change
id="location"
id="appointmentLocation"

Comment on lines +27 to +37
jest.mock('@openmrs/esm-framework', () => {
const originalModule = jest.requireActual('@openmrs/esm-framework');

return {
...originalModule,
detach: jest.fn(),
useLocations: jest.fn().mockImplementation(() => mockLocations),
useSessionUser: jest.fn().mockImplementation(() => mockSessionDataResponse.data),
showToast: jest.fn(),
};
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Just for my understanding, why do we do this?

Copy link
Member Author

Choose a reason for hiding this comment

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

I want to mock only a small subset of functions that the module provides. Here I'm saying I want to mock detach and showToast without actually overriding their implementations. This is because I want to be able to track calls to those functions so that I can assert that they were called a certain number of times and that they were called with certain arguments. For useLocations and useSessionUser, I want to override their implementations so that all the tests in my suite get access to the same locations and session data.

Comment on lines +127 to +134
userEvent.clear(dateInput);
userEvent.type(dateInput, '4/4/2021');
userEvent.clear(timeInput);
userEvent.type(timeInput, '09:30');
userEvent.selectOptions(timeFormat, 'AM');
userEvent.selectOptions(serviceSelect, ['Outpatient']);
userEvent.selectOptions(serviceTypeSelect, ['Chemotherapy']);
userEvent.selectOptions(appointmentTypeSelect, ['Scheduled']);
Copy link
Contributor

Choose a reason for hiding this comment

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

Yesssssss 👨‍🍳 👌


export function useAppointments(patientUuid: string, startDate: string, abortController: AbortController) {
/*
SWR isn't meant to make POST requests for data fetching. This is a consequence of the API only exposing this resource via POST.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why... is the API like that...???

Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like a good workaround, anyway, assuming it's a fake POST (doesn't actually do any mutation)

Copy link
Contributor

Choose a reason for hiding this comment

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

But yeah, who do we talk to to fix that

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't know, I think I fielded this same question on a squad call in the past even.

Copy link
Contributor

@brandones brandones Oct 1, 2021

Choose a reason for hiding this comment

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

Who owns that API?

EDIT: Oh sorry, you just said, unknown. Let's try and find that out?

: null;

const pastAppointments = appointments?.filter((appointment) =>
dayjs((appointment.startDateTime / 1000) * 1000).isBefore(dayjs()),
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the math do?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmmm, good question. Doesn't seem to do anything. I'll remove it in a future PR.

Copy link
Contributor

@brandones brandones left a comment

Choose a reason for hiding this comment

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

I have a few questions, but this looks good!

@brandones brandones merged commit edd05b6 into master Oct 1, 2021
@brandones brandones deleted the MF-798 branch October 1, 2021 03:17
@denniskigen
Copy link
Member Author

denniskigen commented Oct 1, 2021

I have a few questions, but this looks good!

Thanks, Brandon!

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