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

Polish CVR import and export UIs #4047

Merged
merged 7 commits into from
Oct 6, 2023
Merged

Polish CVR import and export UIs #4047

merged 7 commits into from
Oct 6, 2023

Conversation

arsalansufi
Copy link
Contributor

@arsalansufi arsalansufi commented Oct 6, 2023

Easiest reviewed by commit

Overview

Issue links: #3961 + #3967

This PR polishes the CVR import and export UIs. More specifically, it:

  • Removes references to singular CVR files, since CVR exports now consist of multiple files
  • Makes copy and UX more consistent and concise
  • Doesn't allow closing saving/loading modals by clicking outside them
  • Removes uses of the deprecated Prose component and non-libs/ui Loading component

It also restores the ability to manually select a CVR file/directory for import. Something that I'd previously punted on (#3956 (comment)).

Demo Video

VxCentralScan export

vxcentralscan.mov

VxScan export

vxscan.mov

VxAdmin import

vxadmin.mov
vxadmin-2.mov

Testing

  • Updated automated tests
  • Tested the UIs manually

Checklist

  • I have added logging where appropriate to any new user actions, system updates such as file reads or storage writes, or errors introduced N/A
  • I have added a screenshot and/or video to this PR to demo the change
  • I have added the "user_facing_change" label to this PR to automate an announcement in #machine-product-updates

const importResult = await importCastVoteRecords(store, input.path);
const exportDirectoryPath =
// For manual export selection, users must select the contained metadata file as a proxy
// for the export directory since the UI doesn't support directory selection
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Closing the loop on #3956 (comment)!

Whereas you could previously select the top-level cast-vote-record-report.json, you can now select the top-level metadata.json. I couldn't find an easy way to support directory selection. Though non-ideal, we really only use this feature in dev. If an election official were to have to use it, I'd imagine it be in a context where we were guiding them.

Copy link
Collaborator

Choose a reason for hiding this comment

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

🙏 🙏 🙏 🙏 🙏 🙏 🙏 🙏 🙏 🙏

@@ -70,7 +70,7 @@ export function ConfirmRemovingFileModal({

return (
<Modal
centerContent
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seems like we more often left-align our modals than center-align them, so I've made that consistent for CVR modals.

The selected file was ignored as a duplicate of a previously loaded
file.
The selected export was ignored as a duplicate of a previously
loaded export.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because exports are now (and have for a while been) directories instead of single files, I've moved away from "file" as the descriptor for a CVR export and shifted to "export"

</P>
);
}
return <P>The CVRs in the selected export were successfully loaded.</P>;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aside from better handling singular vs. plural cases, I've added content for the basic, no-duplicates success case. We used to have no content for the success case, just a title. Which made the modal look a bit funny IMO. I've added content for consistency with the other cases.

Before / After

before after

@@ -310,6 +315,10 @@ export function ImportCvrFilesModal({ onClose }: Props): JSX.Element | null {
);
}

if (currentState.state === 'loading') {
return <Modal content={<Loading>Loading CVRs</Loading>} />;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that I'm intentionally not specifying an onOverlayClick prop for saving/loading modals so that clicks outside them don't accidentally close them. This came up a few times during the SLI test as a source of confusion. Clicking outside the modal would dismiss it, but the relevant operation would continue behind the scenes, leaving the machine sluggish without any clear indication as to why it was sluggish.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Great.

this USB drive. Save CVR files to this USB drive from the scanner.
Optionally, you may manually select files to load.
No new {headerModeText.toLowerCase()} CVR exports were automatically
found on this USB drive.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Erring on the side of more concise text since I know longer text often isn't read

>
Clear All Tallies and Results
</Button>
</P>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The spacing for this element is off without a <P>

Copy link
Collaborator

Choose a reason for hiding this comment

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

I noticed this on my branch yesterday, thanks for addressing!

@@ -81,12 +81,9 @@ export function ExportResultsModal({ onClose }: Props): JSX.Element {
if (usbDriveStatus === 'ejected') {
return (
<Modal
title="CVRs Saved"
title="USB Drive Ejected"
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've made the CVR export modals in VxCentralScan and VxScan consistent. Prior, there were a number of miscellaneous inconsistencies both within and between the modals. I could of course set up a shared component but decided to punt on that for time's sake

Copy link
Collaborator

Choose a reason for hiding this comment

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

Enough possible divergence that keeping them separate now seems safer.

functions: 70,
lines: 81,
functions: 69,
lines: 80,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These dropped because I got rid of the one-off Prose and Loading components within apps/central-scan/frontend

@arsalansufi arsalansufi requested a review from adghayes October 6, 2023 03:35
@arsalansufi arsalansufi marked this pull request as ready for review October 6, 2023 03:35
@arsalansufi arsalansufi requested a review from a team as a code owner October 6, 2023 03:35
@arsalansufi arsalansufi requested review from carolinemodic and removed request for a team and carolinemodic October 6, 2023 03:35
Copy link
Collaborator

@adghayes adghayes left a comment

Choose a reason for hiding this comment

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

LGTM! Exciting to get to all these polish items.

Two additional polish items I'm thinking of after looking through your PR, both of which predate your work:

  1. Nit: comma-format the numbers in the Load CVRs Modal:
Screen Shot 2023-10-06 at 12 08 51 PM
  1. Allow deleting CVR files individually. See VxAdmin: Allow Deleting CVR Imports Individually #4048. We can have discussion about this on the issue page or take it to Slack.

const importResult = await importCastVoteRecords(store, input.path);
const exportDirectoryPath =
// For manual export selection, users must select the contained metadata file as a proxy
// for the export directory since the UI doesn't support directory selection
Copy link
Collaborator

Choose a reason for hiding this comment

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

🙏 🙏 🙏 🙏 🙏 🙏 🙏 🙏 🙏 🙏

@@ -310,6 +315,10 @@ export function ImportCvrFilesModal({ onClose }: Props): JSX.Element | null {
);
}

if (currentState.state === 'loading') {
return <Modal content={<Loading>Loading CVRs</Loading>} />;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Great.

>
Clear All Tallies and Results
</Button>
</P>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I noticed this on my branch yesterday, thanks for addressing!

@@ -81,12 +81,9 @@ export function ExportResultsModal({ onClose }: Props): JSX.Element {
if (usbDriveStatus === 'ejected') {
return (
<Modal
title="CVRs Saved"
title="USB Drive Ejected"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Enough possible divergence that keeping them separate now seems safer.

Base automatically changed from arsalan/misc-cleanup to main October 6, 2023 15:07
@arsalansufi arsalansufi removed the request for review from carolinemodic October 6, 2023 15:08
- Remove references to singular CVR files, since CVR exports now
  consist of multiple files
- Make copy and UX more consistent and concise
- Don't allow closing saving/loading modals by clicking outside
  them
- Remove uses of deprecated Prose component and non-libs/ui Loading
  component
To account for removal of <Prose> and <Loading>
Also clear error message on subsequent backup attempts
@arsalansufi
Copy link
Contributor Author

@adghayes Good catch re number formatting inside the modal! Added in ef63b3f:

formatting

And re deleting individual CVR imports, makes a lot of sense to me! Continued the discussion on the linked issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants