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-4158: Create animal creation details cards for animal #3192

Merged

Conversation

SayakaOno
Copy link
Collaborator

@SayakaOno SayakaOno commented Apr 15, 2024

Description

Create a pure component for animal details view. This is such a huge PR... I would scan the code briefly and check stories if components look okay. Thank you for reviewing!

  • Update Input component to validate input when the field is cleared.
  • Create ImagePicker component and story. (it has MediaWithAuthentication container, so I made it a container, but does it mean a component that uses ImagePicker needs to be a container?)
    It is almost a copy of FarmImagePicker.tsx, but the major difference is a removal of isImageRemoved. Whether to show a preview depends on the existence of previewUrl, and unless previewUrl is updated, the preview is shown with MediaWithAuthentication.
    @navDhammu It would be appreciated if you could take a look at this component! 🙏
  • Create details cards and stories. Some logic that should be in a container can be found in stories. Error messages should be shown for invalid inputs. (text max length)
    • General (animal, batch)
      • By selecting Sex "Male", an extra radio group shows up.
      • Inputs for sex for batch will be implemented in LF-4159 which is a ticket for batch's details view.
    • Origin (for both animal and batch)
      • Based on the selected radio button, the rest fields show up.
    • Origin (animal, batch)
    • Unique (for animal)
      • By selecting "Other" for tag type, an extra input shows up.
      • By selecting "Other" for tag placement, an extra input shows up.
      • (Tag placement options won't change depending on the selected tag type.)
  • Create a AddAnimalsDetails component that holds the four details cards.
    • Only one card should be expanded at a time. (The story is just for testing this behaviour. Each card doesn't work)

NOTE:
I had to pass t to the four detail cards because doing useTranslation([...]) (especially with more than two namespaces) in mui's Collapse caused Maximum update depth exceeded error.

Jira link: https://lite-farm.atlassian.net/browse/LF-4158, a little bit of https://lite-farm.atlassian.net/browse/LF-4159

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 the enhancement New feature or request label Apr 15, 2024
@SayakaOno SayakaOno self-assigned this Apr 15, 2024
@SayakaOno SayakaOno force-pushed the LF-4158/Create_Animal_creation_details_cards_for_animal branch from 594690f to 93df228 Compare April 20, 2024 00:21
@SayakaOno SayakaOno marked this pull request as ready for review April 22, 2024 21:12
@SayakaOno SayakaOno requested review from a team as code owners April 22, 2024 21:12
@SayakaOno SayakaOno requested review from kathyavini and removed request for a team April 22, 2024 21:12
Copy link
Collaborator

@kathyavini kathyavini left a comment

Choose a reason for hiding this comment

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

It looks GREAT!! (And huge!)

I left some minor comments but the only two vaguely important ones were:

  1. The field named USED_FOR_PRODUCTION -- I think that one was meant to be USED_FOR_REPRODUCTION throughout
  2. Whether writing for react-hook-form's <FormProvider /> to start with might be a better idea. That would clean up the prop drilling of formMethods and also future-proof for using MultiStepForm once that PR is merged

packages/webapp/public/locales/en/translation.json Outdated Show resolved Hide resolved
];

export const sexOptions = [
{ value: 0, label: `I don't know` },
Copy link
Collaborator

@kathyavini kathyavini Apr 24, 2024

Choose a reason for hiding this comment

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

It's not a question for this PR, but regarding my backend ticket... 'I don't know' is just a frontend implementation of null, right? We don't have to add a key in the animal_sexes table for it?

Edit: I should also say, I prefer it to be merely a frontend implementation of null 😂

Copy link
Collaborator Author

@SayakaOno SayakaOno Apr 26, 2024

Choose a reason for hiding this comment

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

Thank you for bringing this up!
I didn't think we would need to add a key in the table, but I started feeling we should differentiate "undefined" and "unknown"! If we didn't have the key, "sex" would be "I don't know" in the read-only view when the user didn't select anything.

Do you agree with adding unknown to animal_sex table?

Oh you edited your comment 😂

Copy link
Collaborator

@kathyavini kathyavini Apr 30, 2024

Choose a reason for hiding this comment

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

If we didn't have the key, "sex" would be "I don't know" in the read-only view when the user didn't select anything.

@SayakaOno yes, I think I prefer this!!

I think I also just saw something similar in another place on the AddAnimal flow -- maybe an "I don't know" breed? -- and I could have sworn we scrapped the idea of an UNKNOWN breed key at one point in discussion 😅 At least for sure they didn't make it into the tables.

Let's revisit after soil amendment!

@navDhammu
Copy link
Collaborator

@SayakaOno I don't think the ImagePicker should be a container because it's mainly a UI component. I think we might be able to refactor the MediaWithAuthenticaion out of it and have it accept the authenticated url as a prop maybe? I don't exactly remember how I implemented the farm image picker component but I'll have a closer look on Tuesday.

@SayakaOno
Copy link
Collaborator Author

@navDhammu!
I will leave refactoring of MediaWithAuthenticaion for later but moved ImagePicker to /component.
Thank you for your input and review!

kathyavini
kathyavini previously approved these changes Apr 30, 2024
{previewUrl ? (
<div className={styles.imageContainer}>
{previewUrl === defaultUrl ? (
<MediaWithAuthentication fileUrls={[defaultUrl]} alt="image thumbnail" />
Copy link
Collaborator

Choose a reason for hiding this comment

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

This can probably be removed along with previewUrl === defaultUrl. The parent component can use the useMediaWithAuthentication hook to fetch the private image url and pass it as defaultUrl to ImagePicker.

component: ImagePicker,
decorators: [
...componentDecorators,
(Story) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we really need this decorator? The behavior isn't dependant on react hook form and it works without it.

type Story = StoryObj<typeof ImagePicker>;

export const Default: Story = {
render: (args, context) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it possible to just use args for these stories instead of the render method?

@SayakaOno
Copy link
Collaborator Author

@navDhammu Thank you so much for your input, the component and stories look much better now.
It would be appreciated if you could re-review!

Copy link
Collaborator

@navDhammu navDhammu left a comment

Choose a reason for hiding this comment

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

This looks good! Although I didn't review all the files but the stories are working well. I left some minor comments to possibly clean up the stories a bit.

Note:- I created components for animal type and breed selects in (#3201) that could be used here maybe once that is approved. This is the file containing the inputs


export const Animal: Story = {
args: {
...commonProps,
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not necessary to spread the common props in each story - you can just put them in the global meta object and they will be applied to every story

import * as commonProps from './mockData

const meta: Meta<GeneralDetailsProps> = {
    args: commonProps
     // other code
}

...commonProps,
animalOrBatch: AnimalOrBatchKeys.BATCH,
},
render: (args, context) => <GeneralDetails {...args} {...context} />,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think these render functions on stories can be removed if you have one render in the meta object, and then also the decorator can be removed. Like:


const meta: Meta<GeneralDetailsProps> = {
  title: 'Components/AddAnimalsDetails/General',
  component: GeneralDetails,
  render: (args) => {
    const { t } = useTranslation();
    const formMethods = useForm({ mode: 'onBlur' });
    const sex = formMethods.watch(DetailsFields.SEX);
    const isMaleSelected = sex === 1;

    return (
      <FormProvider {...formMethods}>
        <GeneralDetails {...args} t={t} isMaleSelected={isMaleSelected} />
      </FormProvider>
    );
  },
  args: commonProps,
  decorators: componentDecorators,
  // avoid "Maximum update depth exceeded" https://github.com/storybookjs/storybook/issues/12306
  parameters: { docs: { source: { type: 'code' } } },
};

@navDhammu
Copy link
Collaborator

Something else I noticed while using the stories - the Expandable component doesn't expand if you click on it - you have to click on the chevron down icon. Is that the expected behaviour? Normally as a user I would expect that it expands anywhere I click on it, and also that I can open it with just the keyboard by tabbing and pressing enter.

@SayakaOno
Copy link
Collaborator Author

@navDhammu Thank you for the comments!
I have a ticket for batch details, so I will replace type & breed selects and clean up stories when I work on it.
For the Expandable behaviour, I forgot to pass a prop! Thank you for catching. I will also create a ticket for accessibility improvement :)

@SayakaOno SayakaOno added this pull request to the merge queue May 1, 2024
Merged via the queue into integration with commit 5a05f55 May 1, 2024
5 checks passed
@SayakaOno SayakaOno deleted the LF-4158/Create_Animal_creation_details_cards_for_animal branch May 1, 2024 21:22
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.

3 participants