OBPIH-7186 Display lot numbers expiration date mismatch in modal#5575
OBPIH-7186 Display lot numbers expiration date mismatch in modal#5575alannadolny merged 5 commits intodevelopfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #5575 +/- ##
============================================
- Coverage 9.12% 8.50% -0.62%
+ Complexity 1170 1113 -57
============================================
Files 701 707 +6
Lines 45281 45448 +167
Branches 10851 10885 +34
============================================
- Hits 4131 3867 -264
- Misses 40497 41007 +510
+ Partials 653 574 -79 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
kchelstowski
left a comment
There was a problem hiding this comment.
I still need more time for this one, but will submit my initial review
src/css/main.scss
Outdated
| &__header { | ||
| display: flex; | ||
| flex-direction: column; | ||
| margin-left: 6px; |
There was a problem hiding this comment.
I am against using margins. Can we somehow use padding instead?
| display: flex; | ||
| justify-content: flex-end; | ||
| gap: 8px; | ||
| } |
There was a problem hiding this comment.
a question to all of those styles - don't they impact all modals in the system?
There was a problem hiding this comment.
Those styles shouldn’t affect all modals in the system because they don’t have classNames like modal-content__header, modal-content__main etc.
| import useConfirmExpirationDateModal from 'hooks/useConfirmExpirationDateModal'; | ||
| import useTranslate from 'hooks/useTranslate'; | ||
|
|
||
| const ConfirmExpirationDateModal = ({ |
There was a problem hiding this comment.
it feels like this could be a reusable modal with a table inside, so how about making it a reusable component like ModalWithTable/ModalTable/TableBasedModal - let's decide on the naming .
I mean - we can take the common part to the reusable component, but keep the ConfirmExpirationDateModal component for things that are "unique" for this modal, so calling all the hooks etc. but then just call the reusable component with proper props
| const itemsWithMismatchedExpiry = []; | ||
|
|
||
| lines.map((line) => { | ||
| const oldItem = _.find(this.state.formValues.lines, (item) => |
There was a problem hiding this comment.
you shouldn't call .find in a loop. The map should be built above so that you have O(1) access here.
(No need to refactor it here as it was existing code)
| return new Promise((resolve) => { | ||
| this.setState({ | ||
| isExpirationModalOpen: true, | ||
| resolveExpirationModal: resolve, |
There was a problem hiding this comment.
this feels weird, I would like to understand more context of it that we set a state with a promise 🤔
There was a problem hiding this comment.
I know it looks a bit weird, but we store the resolve function in the state so that onSave can await the modal response:
const shouldUpdateExpirationDate =
await this.confirmExpirationDateSave(itemsWithMismatchedExpiry);
if (!shouldUpdateExpirationDate) {
return Promise.reject();
}
When the user responds in the modal ("No"/"Yes"), method handleExpirationModalResponse calls:
// Resolve the promise returned by confirmExpirationDateSave.
if (this.state.resolveExpirationModal) {
this.state.resolveExpirationModal(shouldUpdate);
}
and this works because we passed "resolve" reference in method confirmExpirationDateSave to this resolveExpirationModal state
and after this we reset the modal state:
// Close the modal and reset its state.
this.setState({
isExpirationModalOpen: false,
resolveExpirationModal: null,
itemsWithMismatchedExpiry: [],
});
I actually was inspired by a similar pattern in AddItemsPage.jsx (inbound return), where confirmAlert returns a Promise and resolves it directly via button callbacks, for example:
confirmExpirationDateSave() {
return new Promise((resolve) => {
confirmAlert({
title: this.props.translate('react.inboundReturns.message.confirmSave.label', 'Confirm save'),
message: this.props.translate(
'react.stockMovement.confirmExpiryDateUpdate.message',
'This will update the expiry date across all depots in the system. Are you sure you want to proceed?',
),
willUnmount: () => resolve(false),
buttons: [
{
label: this.props.translate('react.default.yes.label', 'Yes'),
onClick: () => resolve(true),
},
{
label: this.props.translate('react.default.no.label', 'No'),
onClick: () => resolve(false),
},
],
});
});
}
but I can't (probably) do the same here so I needed to store the resolve in state
There was a problem hiding this comment.
thanks for the explanation @SebastianLib. I still don't like it, but on the other hand I don't have any quick idea how to resolve this issue in those old class components.
| // After finding at least a single instance where expiration date we are trying to save | ||
| // does not match the existing inventoryItem expiration date, we want to inform the user | ||
| // that certain updates to th expiration date in the system will be performed | ||
| const shouldUpdateLotExpirationDate = |
There was a problem hiding this comment.
decide on the naming, either use the *expirationDate everywhere only or *lotExpirationDate
| react.confirmExpirationDate.modal.title.label=Confirm save | ||
| react.confirmExpirationDate.modal.subtitle.label=This will update the expiry date across all depots in the system for the lots listed below. Are you sure you want to proceed? | ||
| react.confirmExpirationDate.modal.code.label=Code | ||
| react.confirmExpirationDate.modal.productName.label=Product Name | ||
| react.confirmExpirationDate.modal.lot.label=Lot | ||
| react.confirmExpirationDate.modal.previousExpiry.label=Previous Expiry | ||
| react.confirmExpirationDate.modal.newExpiry.label=New Expiry |
There was a problem hiding this comment.
Are those translations fetched?
There was a problem hiding this comment.
I didn't fetch translations, but I will change that
# Conflicts: # grails-app/i18n/messages.properties
# Conflicts: # grails-app/i18n/messages.properties
c31fe4b to
aa61976
Compare
aa61976 to
158e6c8
Compare
| return new Promise((resolve) => { | ||
| this.setState({ | ||
| isExpirationModalOpen: true, | ||
| resolveExpirationModal: resolve, |
There was a problem hiding this comment.
thanks for the explanation @SebastianLib. I still don't like it, but on the other hand I don't have any quick idea how to resolve this issue in those old class components.
✨ Description of Change
Link to GitHub issue or Jira ticket:
https://pihemr.atlassian.net/browse/OBPIH-7186
Description:
At this moment, in this PR I didn't add this functionality to the old inbound, because it will be replaced by the new inbound. Once this PR is merged, I will create a new ticket to add this functionality to the new inbound refactor as well.
📷 Screenshots & Recordings (optional)