Skip to content

Conversation

@matthew-white
Copy link
Member

This PR makes progress on getodk/central#1011 and getodk/central#1030:

  • It adds a mechanism for showing a Call to Action (CTA) in a toast. This is called for in #1011.
  • It adds the specific CTAs listed in #1030. All of them happen to be about refreshing the page, but the CTA mechanism as a whole is generic.

The CTA is not styled/positioned correctly yet. I'll do that in a follow-up PR as I continue working on #1011. I'm making this change now so that I can close out #1030 quickly. This is what the CTA looks like now:

Image

What has been done to verify that this works as intended?

New tests. I also tried out one of the CTAs locally.

Why is this the best possible solution? Were any other approaches considered?

My goal was to make it as simple as possible as possible to add a CTA. I think that's going to be a relatively common pattern. For example, I don't want us to have to write a component/HTML whenever we want to add a CTA. I wanted something generic/reusable.

We also need something that will work outside of component code. For example, src/util/session.js needs to add a CTA.

I'll also add comments explaining individual lines.

Before submitting this PR, please make sure you have:

  • run npm run test and npm run lint and confirmed all checks still pass OR confirm CircleCI build passes
  • verified that any code or assets from external sources are properly credited in comments or that everything is internally sourced

Comment on lines +5 to +10
export const mockLocation = (mockedProperties) => new Proxy({}, {
get: (_, name) =>
(Object.prototype.hasOwnProperty.call(mockedProperties, name)
? mockedProperties[name]
: window.location[name])
});
Copy link
Member Author

Choose a reason for hiding this comment

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

For the tests of the CTAs, I want to mock window.location.reload(). window.location doesn't make that easy for us: sinon.replace() isn't enough. That's why I'm using this proxy. It allows us to mock specific properties like reload while returning actual values from window.location for other properties.

});
await wait();
asyncRoute.should.alert('danger');
asyncRoute.vm.$container.alert.ctaHandler();
Copy link
Member Author

@matthew-white matthew-white May 17, 2025

Choose a reason for hiding this comment

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

Here we call alert.ctaHandler() directly. We can't click .alert-cta because the alert isn't rendered in the DOM. This test just mounts the AsyncRoute component, not the whole app. We independently test alert.ctaHandler() and .alert-cta elsewhere, so I think it's OK to call alert.ctaHandler() directly here.

.afterResponse(app => {
clock.tick(0);
.afterResponse(async (app) => {
await clock.tickAsync(0);
Copy link
Member Author

Choose a reason for hiding this comment

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

tick() needs to become tickAsync() in order to give the DOM a chance to update. We need .alert-cta to be rendered before we click it.

@matthew-white matthew-white marked this pull request as ready for review May 17, 2025 04:35
@matthew-white matthew-white requested a review from ktuite May 17, 2025 04:35
@matthew-white
Copy link
Member Author

@ktuite, I'm thinking it might be easiest to review this one interactively.

@matthew-white matthew-white merged commit 1a313ec into master May 31, 2025
3 checks passed
@matthew-white matthew-white deleted the alert-cta branch May 31, 2025 03:22
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.

3 participants