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

MB-11601 delete shipment #8375

Merged
merged 35 commits into from
Apr 14, 2022
Merged

MB-11601 delete shipment #8375

merged 35 commits into from
Apr 14, 2022

Conversation

ronaktruss
Copy link
Contributor

@ronaktruss ronaktruss commented Apr 4, 2022

Jira ticket for this change

Summary

Is there anything you would like reviewers to give additional scrutiny?

this article explains more about the approach used.

Setup to Run Your Code

💻 You will need to use three separate terminals to test this locally.
Terminal 1

Start the Storybook locally.

make storybook
Terminal 2

Start the UI locally.

make client_run
Terminal 3

Start the Go server locally.

make server_run

Verification Steps for Author

These are to be checked by the author.

  • Tested in the Experimental environment (for changes to containers, app startup, or connection to data stores)
  • Request review from a member of a different team.
  • Have the Jira acceptance criteria been met for this change?

Verification Steps for Reviewers

These are to be checked by a reviewer.

Frontend

  • User facing changes have been reviewed by design.
  • There are no aXe warnings for UI.
  • This works in Supported Browsers and their phone views (Chrome, Firefox, IE, Edge).
  • There are no new console errors in the browser devtools
  • There are no new console errors in the test output
  • If this PR adds a new component to Storybook, it ensures the component is fully responsive, OR if it is intentionally not, a wrapping div using the officeApp class or custom min-width styling is used to hide any states the would not be visible to the user.

Screenshots

Screen Shot 2022-04-08 at 1 59 40 PM
Screen Shot 2022-04-08 at 2 00 21 PM
Screen Shot 2022-04-08 at 2 01 00 PM
Screen Shot 2022-04-08 at 2 01 40 PM
Screen Shot 2022-04-08 at 2 01 53 PM
Screen Shot 2022-04-08 at 2 02 08 PM

@robot-mymove
Copy link

robot-mymove commented Apr 4, 2022

Warnings
⚠️

Files located in legacy directories (src/shared or src/scenes) have
been edited. Are you sure you don’t want to also relocate them to the new file structure?

View the frontend file org ADR for more information

Messages
📖 🔗 MB-11601

Generated by 🚫 dangerJS against 7eaa0d1

@ronaktruss ronaktruss changed the title Rp mb 11601 delete shipment MB-11601 delete shipment Apr 4, 2022
@@ -60,16 +56,29 @@ export const ShipmentListItem = ({
<span className={styles.warningText}>{isOverweight ? 'Over weight' : 'Missing weight'}</span>
</div>
)}
{canEdit ? <FontAwesomeIcon icon="pen" className={styles.edit} /> : <div className={styles.noEdit} />}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm glad we're getting rid of the icon-only button in favor of text 🎉

Comment on lines 61 to 67
<Button className={styles['edit-btn']} onClick={onDeleteClick} type="button">
Delete
</Button>
<div>|</div>
<Button className={styles['edit-btn']} onClick={onShipmentClick} type="button">
Edit
</Button>
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not 100% sure if we should keep using buttons or not for things that are in effect, just links. It's come up in the past but I don't remember the decision in the end. I've started a thread in #prac-frontend asking if others remember what was decided.

.step-container:last-of-type {
margin-bottom: 0;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remove additional whitespace at the bottom of the home page
image

return {
...ownProps,
canMoveNext: true, // TODO: prevent incomplete PPM submission?
canMoveNext: !!Object.keys(mtoShipments).length, // TODO: prevent incomplete PPM submission?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes next button disabled when we delete the last shipment. We still need to handle the scenarios where a PPM is incomplete

Copy link
Contributor

Choose a reason for hiding this comment

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

Heads up I removed this property in my PR that's now in master. I did add a selector to return the shipments similar to what you're doing above. Probably just move this logic to inside the component in conjunction with the check for an incomplete PPM.


await waitFor(() => {
checkShipmentClick('ID-3', 1, SHIPMENT_OPTIONS.NTS);
});

userEvent.click(screen.getByRole('button', { name: /^nts-release /i }));
editBtn = queryByRole(screen.getAllByTestId('shipment-list-item-container')[3], 'button', { name: 'Edit' });

await waitFor(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@felipe-lee Is there a reason that we are using await here as opposed just triggering the click and using expects similar to what is done for the deletes below?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I had been getting console errors without the awaits, but now I don't remember the exact error. You can try removing it and see if you get them. If not, then feel free to change this up.

Comment on lines +10 to +16
useEffect(
() => () => {
// Clear this flash message on unmount (this will happen on navigation or if flash state changes)
clearFlashMessage(flash?.key);
},
[clearFlashMessage, flash?.key],
);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was changed because the previous implementation made it so that if you modified the message multiple times on the same page it would be cleared on alternating notifications. (eg. If you delete two records on the first you would see a message, but on the second the message would disappear. You would then alternate seeing and not seeing it on subsequent triggers.)

Does anyone have context on the reason for this original implementation? If the comment is correct I think this servers to better mimic that description.

Copy link
Contributor

Choose a reason for hiding this comment

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

thought: I don't have any context on this.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know anything about the initial implementation, but I think having a dependency array in useEffect is a good practice, and like you said, seems to match what the comment indicates we want, so I think this change is probably for the best.

@ronaktruss ronaktruss marked this pull request as ready for review April 8, 2022 18:05
Copy link
Contributor

@YanZ777 YanZ777 left a comment

Choose a reason for hiding this comment

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

The changes look good to me, but I would want someone else who has more context of the work to review this.

@@ -40,7 +40,7 @@ describe('Services counselor user', () => {

cy.get('[data-testid="modal"]').should('be.visible');

cy.get('[data-testid="modal"] button').contains('Delete shipment').click();
cy.get('[data-testid="modal"] button').contains('Delete shipment').click({ force: true });
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for adding this!

Comment on lines 14 to 15
onClose={() => {}}
onSubmit={() => {}}
Copy link
Contributor

Choose a reason for hiding this comment

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

Try to define these stories using the newer args pattern so that these props become editable in the Storybook controls panel and you can also use actions so those click events show up in the actions tab too.

display: inline-flex;
flex: 0;
align-items: center;
min-width: auto;
@include u-padding-x(0);
@include u-font('body', 'xs');

button {
padding: 12px;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's good to avoid using pixels and use USWDS tokens whenever possible. You should be able to rewrite this as @include u-padding(1.5) https://designsystem.digital.gov/design-tokens/spacing-units/

@duncan-truss
Copy link
Contributor

I've been testing and things look very good! One minor issue I see is when you delete all of the shipments on the Review page, the next button is still enabled for you to submit the move. I think if you just combine a check for mtoShipments length with the complete PPM conditional in Review.jsx you can fix that disabling.

Screen Shot 2022-04-12 at 5 46 50 PM

@ronaktruss
Copy link
Contributor Author

I've been testing and things look very good! One minor issue I see is when you delete all of the shipments on the Review page, the next button is still enabled for you to submit the move. I think if you just combine a check for mtoShipments length with the complete PPM conditional in Review.jsx you can fix that disabling.

@duncan-truss Yeah I caught this as well when I was working on the cypress tests. I forgot to add this back in when I merged in your code that added the logic for the incomplete PPMs. See commit


await waitFor(() => {
checkShipmentClick('ID-3', 1, SHIPMENT_OPTIONS.NTS);
});

userEvent.click(screen.getByRole('button', { name: /^nts-release /i }));
editBtn = queryByRole(screen.getAllByTestId('shipment-list-item-container')[3], 'button', { name: 'Edit' });

await waitFor(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think I had been getting console errors without the awaits, but now I don't remember the exact error. You can try removing it and see if you get them. If not, then feel free to change this up.

src/components/ShipmentList/ShipmentList.test.jsx Outdated Show resolved Hide resolved
Comment on lines +57 to +62
if (action.type === 'UPDATE_MTO_SHIPMENTS_ENTITIY') {
return {
...state,
mtoShipments: action.entities['mtoShipments'] || {},
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Let me preface this by saying, I don't know much (i.e. next to nothing) about redux or how all these things tie together. But, looking at the existing code, is there a reason we need the new path for updating MTO shipments? It seems like the ADD_ENTITIES path is doing the same thing, at least in the end. It's doing a merge of the original and new, but if the new overwrites the whole of mtoShipments I feel like that should be fine? Again, I could be totally off and if you tried that and it didn't work, then nvm.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ADD_ENTITIES doesn't work because it is doing a merge of the original and new mtoShipments. When we merge it only adds or updates any of the updated or new records (it basically just overrides values in the old with the new if they have the same key or adds entries if the key is new). This means when we delete the original has all of the old values and the new values has one less value. The merge function then doesn't change since the new doesn't have any additional info.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would clarify the purpose some and maybe make it a bit generalized if we called it REPLACE_ENTITY to reflect what it's doing now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As is, I would be hesitant to call it REPLACE_ENTITY since this functionality doesn't work at a general level. It currently only works for mtoShipments.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, you have it hardcoded to the 'mtoShipments' key, you would need to make that use a param. I don't think it's a must have.

Copy link
Contributor

Choose a reason for hiding this comment

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

I started a semi-related thread in #prac-frontend about this and plan on bringing it up at tomorrow's check in.

src/sagas/entities.js Show resolved Hide resolved
@@ -62,7 +62,7 @@ const Review = ({ currentMove, mtoShipments, push, match }) => {
<div className={formStyles.formActions}>
<WizardNavigation
onNextClick={handleNext}
disableNext={!hasCompletedPPMShipments}
disableNext={!hasCompletedPPMShipments || !Object.keys(mtoShipments).length}
Copy link
Contributor

Choose a reason for hiding this comment

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

mtoShipments should be an array of objects coming back from the selectMTOShipmentsForCurrentMove selector or assigned to an empty array by default. I don't think calling Object.keys is necessary here.

Base automatically changed from pm-mb-11673-ppm-delete-backend to master April 13, 2022 15:46
Copy link

@scarequotes scarequotes left a comment

Choose a reason for hiding this comment

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

This PR works as expected for design.

One call-out: Deleted shipments work as expected on this page, but then at least sometimes appear on the review screen. I think there's an existing ticket to fix that as a separate story, but just a heads-up that that will need to be fixed at some point.

Comment on lines +10 to +16
useEffect(
() => () => {
// Clear this flash message on unmount (this will happen on navigation or if flash state changes)
clearFlashMessage(flash?.key);
},
[clearFlashMessage, flash?.key],
);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know anything about the initial implementation, but I think having a dependency array in useEffect is a good practice, and like you said, seems to match what the comment indicates we want, so I think this change is probably for the best.

Comment on lines +360 to +369
{showDeleteSuccessAlert && (
<Alert slim type="success">
The shipment was deleted.
</Alert>
)}
{showDeleteErrorAlert && (
<Alert slim type="error">
Something went wrong, and your changes were not saved. Please try again later or contact your counselor.
</Alert>
)}
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, you might have addressed this somewhere and I missed it, but do we need the separate alerts? Like does <ConnectedFlashMessage /> not work if you're staying on the same page?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not actually clear to me when we use Alert vs ConnectedFlashMessage. I'd assume and it does generally seem to be the case that ConnectedFlashMessage was used when the parent had the ConnectedFlashMessage and the child element would just dispatch the action to update the message. Alerts seem to be used when the update is happening within the same component. With the update above we should be able to use ConnectedFlashMessage if we want.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you're right about the general times we use each. I guess I'd opt for, if the page already has <ConnectedFlashMessage/> to use it, but maybe this is a discussion for FE check in. I'm fine with keeping this as is for now and if we decide to change it, it can be a follow-up later on.

Copy link
Contributor

Choose a reason for hiding this comment

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

I started a thread in #prac-frontend about this and plan on bringing it up at tomorrow's check in.

Copy link
Contributor

@felipe-lee felipe-lee left a comment

Choose a reason for hiding this comment

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

Found a few prop errors in tests, though hopefully they're easy to fix

@@ -13,7 +13,7 @@ const defaultProps = {
shipmentNumber: 1,
shipmentId: '#ABC123K',
shipmentType: 'HHG',
showEditBtn: false,
showEditAndDeleteBtn: false,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm getting a prop type error for tests in this file because they're missing the onDeleteClick prop:

image

@@ -9,7 +9,7 @@ import { formatCustomerDate } from 'utils/formatters';
const defaultProps = {
moveId: 'testMove123',
onEditClick: jest.fn(),
showEditBtn: false,
showEditAndDeleteBtn: false,
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment about the missing onDeleteClick prop

@@ -11,7 +11,7 @@ const defaultProps = {
onEditClick: jest.fn(),
shipmentId: '#ABC123K',
shipmentType: 'HHG_INTO_NTS_DOMESTIC',
showEditBtn: false,
showEditAndDeleteBtn: false,
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment about the missing onDeleteClick prop

@@ -109,7 +109,7 @@ describe('Home component', () => {
mtoShipmentId: testProps.mtoShipments[1].id,
});

wrapper.find('ShipmentListItem').at(0).simulate('click');
wrapper.find('ShipmentListItem').at(0).find('button').at(1).simulate('click');
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm getting a missing prop error from one of the tests in this file, but I think it wasn't one you updated so I don't think it's a blocker for this PR. Just putting the info here in case you want to address it:
image

Copy link
Contributor

@felipe-lee felipe-lee left a comment

Choose a reason for hiding this comment

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

Found a few prop errors in stories

content: 'Some sample description',
submitText: 'YES!',
closeText: 'NO',
onClose: { action: 'close button clicked' },
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm getting a prop type error on this:
image

I think this other story shows an example of actions:

onSubmit: action('submit button clicked'),
onBack: action('back button clicked'),

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooops, this wasn't supposed to be checked in 😅. As a general note thanks for being thorough and providing references/sources.

<ShipmentList
shipments={[{ id: '0001', shipmentType: SHIPMENT_OPTIONS.PPM }]}
onShipmentClick={() => {}}
onDeleteClick={() => {}}
Copy link
Contributor

Choose a reason for hiding this comment

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

This has a prop error from the missing moveSubmitted prop:

image

@@ -18,6 +22,7 @@ export const Basic = () => (
{ id: '0003', shipmentType: SHIPMENT_OPTIONS.PPM },
]}
onShipmentClick={() => {}}
onDeleteClick={() => {}}
Copy link
Contributor

Choose a reason for hiding this comment

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

This one also needs the moveSubmitted prop

Copy link
Contributor

@felipe-lee felipe-lee left a comment

Choose a reason for hiding this comment

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

I think given that some things need to discussed at a FE group level, I'm fine with this as is for now. Well pending those prop error fixes, but I don't want to be a blocker on this once you push those fixes up.

@ronaktruss ronaktruss merged commit 788b170 into master Apr 14, 2022
@ronaktruss ronaktruss deleted the rp-mb-11601-delete-shipment branch April 14, 2022 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants