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

LF-4384: End to end animal details #3534

Merged
merged 30 commits into from
Nov 28, 2024

Conversation

SayakaOno
Copy link
Collaborator

@SayakaOno SayakaOno commented Nov 19, 2024

Description

  • Add missing desiredKeys to animalBatchController's editAnimalBatches so that all fields sent to the backend are updated
  • Update getRecordIfExists middleware helper to exclude removed animals
    • Prevents removed animals/batches from being updated
  • Update WithStepperProgressBar not to use FixedHeaderContainer for single step forms which don't have headers
    • Prevents two scrollbars from appearing in SingleAnimalView
  • Update MeatballsMenu and DropdownButton to accept disabled prop
  • Create CustomRouteComponentProps type to override the default history from react-router with the history object from the History library
  • Update parseUniqueDefaultId to handle exception (it was returning NaN when typing a new animal type, causing filteredUses - the animal use options - to be undefined)
  • Adjust the batch count width in AnimalSingleViewHeader. (Counts with more than five digits are not properly handled, but if necessary, we can create a new ticket to address this)
  • Update useAnimalOrBatchRemoval to return the API result
    • Allows SingleAnimalView to handle actions based on the result
  • Update SingleAnimalView to:
    • make the page full-width
    • use FixedHeaderContainer
    • implement functionality for animal removal
    • replace history.push with history.back for navigation
    • redirect to UnknownRecord when no animal or batch is found for the URL
    • disable the menu button when editing
    • hide meatballs menu for removed animals to prevent invalid actions (edit, remove)

NOTE: I didn't implement the floating button, as it was mentioned as a nice-to-have in the Jira ticket.

Jira link: https://lite-farm.atlassian.net/browse/LF-4384

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Passes test case
  • UI components visually reviewed on desktop view
  • UI components visually reviewed on mobile view
  • Other (please explain)

Checklist:

  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • The precommit and linting ran successfully
  • I have added or updated language tags for text that's part of the UI
  • I have added "MISSING" for all new language tags to languages I don't speak
  • I have added the GNU General Public License to all new files

@SayakaOno SayakaOno added enhancement New feature or request Blocked labels Nov 19, 2024
@SayakaOno SayakaOno self-assigned this Nov 19, 2024
@SayakaOno SayakaOno changed the title [WIP] LF-4384: End to end animal details LF-4384: End to end animal details Nov 20, 2024
Base automatically changed from LF-4383-animal-details-form-container-handle-edit-of-animal-details to integration November 21, 2024 14:27
@SayakaOno SayakaOno force-pushed the LF-4384/End-to-End_Animal_Details branch from 8b561f3 to b9d72e3 Compare November 21, 2024 16:29
@SayakaOno SayakaOno marked this pull request as ready for review November 21, 2024 16:30
@SayakaOno SayakaOno requested review from a team as code owners November 21, 2024 16:30
@SayakaOno SayakaOno requested review from antsgar and removed request for a team November 21, 2024 16:30
@Duncan-Brain
Copy link
Collaborator

Duncan-Brain commented Nov 23, 2024

Sorry I haven't gotten very far yet but the uses in read-only seems to not be visible on first visit. On refresh it shows up.

Copy link
Collaborator

@antsgar antsgar left a comment

Choose a reason for hiding this comment

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

Left a few minor comments but this is great, thanks for catching all the little details that were missing to make the feature work!

When an animal is removed from the single animal view, the success toast reads "Successfully removed selected animals". Should we change this to "animal" singular when there's only one animal?

options={options}
classes={{ button: isEditing ? styles.editingStatusButton : '' }}
/>
{!hideMenu && (
Copy link
Collaborator

Choose a reason for hiding this comment

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

NIT but I'd probably reverse the logic here and have a showMenu prop with a default true, just because the combo of hide + negation seems a bit counter intuitive to me

)
}
>
const renderContent = () => (
Copy link
Collaborator

Choose a reason for hiding this comment

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

NIT and not prescriptive, but I'm not a huge fan of render functions because they're "undercover" functional components minus reusability and ability to incorporate state. I'd make this into its own component even if it lives within this same file

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wasn't sure about this... I created a wrapper component, thank you!


const { onConfirmRemoveAnimals, removalModalOpen, setRemovalModalOpen } = useAnimalOrBatchRemoval(
[getInventoryId()],
() => ({}),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this callback just be an optional parameter for the hook?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I didn't feel like adding ? all over the hook 😅 but I agree that's the right thing to do!
I’ve fixed this for now, and the refactor should tidy things up a bit!

};

const getInventoryId = () => {
if (!selectedAnimal && !selectedBatch) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since there's a redirect to another page on the effect above if the batch or animal doesn't exist, is this check necessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think I was hoping to avoid doing (selectedAnimal || selectedBatch)! on line 175. It didn't work as expected, so I removed it!

};

const { onConfirmRemoveAnimals, removalModalOpen, setRemovalModalOpen } = useAnimalOrBatchRemoval(
[getInventoryId()],
Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps we could modify useAnimalOrBatchRemoval to receive the actual entity IDs and whether they're a batch or animal instead of the inventory IDs? Seems more straight forward since here we're generating the inventory ID just to pass it to the hook, and then the hook has to re-parse the actual IDs from it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I hesitated to refactor since it would involve changes to an unrelated file, but it’s true that I wasn’t happy with the inefficiency. Let me open another PR for this!

* Update useInitialAnimalData hook
  - return isFetchingAnimalsOrBatches
  - return defaultFormValues when ready
* Update SingleAnimalView
  - avoid redirecting to UnknownRecord during fetching animals
  - render form when default values are ready
Copy link
Collaborator Author

@SayakaOno SayakaOno left a comment

Choose a reason for hiding this comment

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

Thank you for reviewing!!

The bug Duncan found was caused by defaultValue being set after the ReactSelect was rendered. I’ve updated it to render the form only after the default values are ready.(commit)

Regarding making the success message singular, I noticed Denis created a bug ticket for the inventory view, so I'll leave the fix for that ticket.

I plan to refactor the useAnimalOrBatchRemoval hook in a separate PR, but this one should now be ready for re-reviews. Thank you! 🙏

Update: Here is the PR to refactor the hook

)
}
>
const renderContent = () => (
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wasn't sure about this... I created a wrapper component, thank you!

};

const getInventoryId = () => {
if (!selectedAnimal && !selectedBatch) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think I was hoping to avoid doing (selectedAnimal || selectedBatch)! on line 175. It didn't work as expected, so I removed it!

};

const { onConfirmRemoveAnimals, removalModalOpen, setRemovalModalOpen } = useAnimalOrBatchRemoval(
[getInventoryId()],
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I hesitated to refactor since it would involve changes to an unrelated file, but it’s true that I wasn’t happy with the inefficiency. Let me open another PR for this!


const { onConfirmRemoveAnimals, removalModalOpen, setRemovalModalOpen } = useAnimalOrBatchRemoval(
[getInventoryId()],
() => ({}),
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I didn't feel like adding ? all over the hook 😅 but I agree that's the right thing to do!
I’ve fixed this for now, and the refactor should tidy things up a bit!

antsgar
antsgar previously approved these changes Nov 26, 2024
export enum OrganicStatus {
'NON_ORGANIC' = 'Non-Organic',
'TRANSITIONAL' = 'Transitional',
'ORGANIC' = 'Organic',
}

// Custom RouteComponentProps with a custom history type from the 'history' library
export type CustomRouteComponentProps<T extends { [K in keyof T]?: string | undefined }> = Omit<
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thank you!! ❤️

Duncan-Brain
Duncan-Brain previously approved these changes Nov 26, 2024
Copy link
Collaborator

@Duncan-Brain Duncan-Brain left a comment

Choose a reason for hiding this comment

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

@SayakaOno

Everything is looks great to me thanks for wrapping up! Left a couple small inline comments which aren't blockers.

Only other thing I saw not working was the upload image functionality -- not sure if that is addressable here. nvm gotta start bucket 😂

Feel free to merge!

@@ -109,6 +117,7 @@ export const WithStepperProgressBar = ({
if (isFinalStep) {
setIsSaving(true);
await handleSubmit((data: FieldValues) => onSave(data, onGoForward, setFormResultData))();
reset(getValues());
Copy link
Collaborator

@Duncan-Brain Duncan-Brain Nov 26, 2024

Choose a reason for hiding this comment

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

At first I was worried that this would clear the edited values when unsuccessful (api is down). But instead It kept them? Do you think this is expected?

Screen.Recording.2024-11-26.at.1.07.32.PM.mov

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

reset() will reset the form to the default values. However, reset(getValues()) updates the default values to the current form values before resetting, so this behaviour is expected. You can find a brief explanation in the RULES section on this page.

Thank you Duncan for thoroughly testing this, I don't think reset, setIsSaving and setIsEditing shouldn't be called unless the API call is successful. Let me see if I can fix this!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting use of reset! and sounds good!

@SayakaOno SayakaOno dismissed stale reviews from Duncan-Brain and antsgar via 2325f80 November 27, 2024 17:58
@SayakaOno
Copy link
Collaborator Author

I made some additional changes, thank you!

  • Conflicts were resolved.
  • Revert the onSave change in ContextForm. (removing onGoForward should prevent the crash)
  • Update AnimalBreedSelect to replace undefined with null as value

@@ -96,7 +96,7 @@ export function AnimalBreedSelect<T extends FieldValues>({
placeholder={isTypeSelected ? undefined : t('ADD_ANIMAL.BREED_PLACEHOLDER_DISABLED')}
isDisabled={!isTypeSelected || isDisabled}
onChange={(option) => onChange(option)}
value={value}
value={value || null}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

undefined doesn't clear the select, but null does.

Screen.Recording.2024-11-27.at.9.53.27.AM.mov

@@ -108,10 +107,6 @@ export const ContextForm = ({
setIsEditing={setIsEditing}
showCancelFlow={showCancelFlow}
setShowCancelFlow={setShowCancelFlow}
onSave={(...args: any) => {
setActiveStepIndex(0);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I found this has changed behaviour of the other form (it displays the first page of the form for a second). I believe it's working without it, but if any problems are found, we will need another solution.

Screen.Recording.2024-11-27.at.9.45.35.AM.mov

Copy link
Collaborator

@Duncan-Brain Duncan-Brain left a comment

Choose a reason for hiding this comment

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

Thanks for fixing error behaviour!

Only thing I think I see now is that for some reason the sex_detail input is not allowing enabled in edit mode unless count is changed. We could probably make a bug ticket and just merge this though!

@SayakaOno
Copy link
Collaborator Author

Thank you @Duncan-Brain! I think that's one of the things Denis was mentioning yesterday, let me check with him!

@antsgar
Copy link
Collaborator

antsgar commented Nov 28, 2024

@SayakaOno I'm merging this one and we can create a separate one for the bug if that's okay!

@antsgar antsgar added this pull request to the merge queue Nov 28, 2024
Merged via the queue into integration with commit bd04b17 Nov 28, 2024
5 checks passed
@antsgar antsgar deleted the LF-4384/End-to-End_Animal_Details branch November 28, 2024 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants