Skip to content

OBPIH-6108 Default Preference Type section (fixes after QA)#4536

Merged
kchelstowski merged 7 commits intofeature/product-supplier-list-redesignfrom
OBPIH-6108-add-preference-type-section-with-inputs
Mar 8, 2024
Merged

OBPIH-6108 Default Preference Type section (fixes after QA)#4536
kchelstowski merged 7 commits intofeature/product-supplier-list-redesignfrom
OBPIH-6108-add-preference-type-section-with-inputs

Conversation

@drodzewicz
Copy link
Collaborator

@drodzewicz drodzewicz commented Mar 8, 2024

There is a bit of a refactor that I did on the validation schema that allowed me to add a custom refine() validation on the whole section.
Additionally, I believe that separating our validations schema into smaller subsections will be a lot more readable and maintainable. I believe we already talked about this and since there aren't any tickets that will have conflicts with these changes Id decided to proceed with this refactor.

So what has changed?

  • I have split all of the fields in the validations schema into smaller subsections just like we have in the UI and imported them in the main schema
 z
      .object({
        id: z
          .string()
          .optional(),
        basicDetails: basicDetailsSchema,
        additionalDetails: additionalDetailsSchema,
        defaultPreferenceType: defaultPreferenceTypeSchema,
        productSupplierPreferences: z.array(productSupplierPreferenceSchema),
        packageSpecification: packageSpecificationSchema,
        fixedPrice: fixedPriceSchema,
        attributes: z.object(attributesValidationSchema),
      });
  • Because of these changes I have modified getProductSource, submitted payload and field name attributes accordingly.
  • I have created a generic FormErrorPropType which is repeated in all of our error props.
  • I have also decided to export the whole errors propType object from subsections and import it in the sections, to avoid any propType inconsistencies and code repetition when defining prop types.
  • Modified onClear function for the date - it looks like we have to assign undefined instead of null because we have .coerce.date() defined on validation schema for date which parses null to some date value like 1970
  • I have also moved out logic for calculating each price into a separate hook useCalculateEachPrice which I believe will declutter the main sources form hook

Comment on lines 108 to +110
export default AdditionalDetails;

export const additionalDetailsFormErrors = PropTypes.shape({
Copy link
Collaborator

Choose a reason for hiding this comment

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

Eslint doesn't shout at it? I remember there was a restriction about using default export and normal export in one 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 had no such lint errors? Do we have this rule in our eslint config?

Comment on lines +158 to +162
...omitEmptyValues(values.basicDetails),
...omitEmptyValues(values.additionalDetails),
...omitEmptyValues(values.defaultPreferenceType),
...omitEmptyValues(values.packageSpecification),
...omitEmptyValues(values.fixedPrice),
Copy link
Collaborator

Choose a reason for hiding this comment

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

It could be better to use object restructuring. The value is repeated many times... but as I know the onSubmit will be refactored, so I don't know if this change is needed at this point.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree with @alannadolny and was about to point out the same thing, but anyway this method will be refactored, so there is no need to spend time on that now imho.

Comment on lines +1 to +6
import PropTypes from 'prop-types';

// eslint-disable-next-line import/prefer-default-export
export const FormErrorPropType = PropTypes.shape({
message: PropTypes.string,
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

so if this file will be used for defining our custom propTypes, you can use default export like that:

Suggested change
import PropTypes from 'prop-types';
// eslint-disable-next-line import/prefer-default-export
export const FormErrorPropType = PropTypes.shape({
message: PropTypes.string,
});
import PropTypes from 'prop-types';
const FormErrorPropType = PropTypes.shape({
message: PropTypes.string,
});
export default propTypes = {
// Add here newly created custom propTypes
FormErrorPropType,
};

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this was intentional from my side.
The above example with default export will not get optimized by webpack treeshaking algorithm which should omit the unused code from being included in the bundle.
So in such cases, it is best to export it individually.

const defaultPreferenceType = useWatch({ control, name: 'defaultPreferenceType' });
useEffect(() => {
trigger('defaultPreferenceType.preferenceType');
}, [defaultPreferenceType]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't know if it's expected, but if defaultPreferenceType is an object, it would trigger the useEffect whenever the component re-renders, not when the defaultPreferenceType changes. It is because objects are compared by reference in JS, not by its values.
I think currently it might run more times than we would expect it to run.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this was the point, we want to trigger this validation when any of the values in the default preference type subsection changes.
I tested dit with console logs on this useEffect and everything seems to work as expected.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I know, but I meant that even if none values change, and something else triggers the re-render, this useEffect would anyway be triggered, because a reference of the object would change.

Comment on lines +158 to +162
...omitEmptyValues(values.basicDetails),
...omitEmptyValues(values.additionalDetails),
...omitEmptyValues(values.defaultPreferenceType),
...omitEmptyValues(values.packageSpecification),
...omitEmptyValues(values.fixedPrice),
Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree with @alannadolny and was about to point out the same thing, but anyway this method will be refactored, so there is no need to spend time on that now imho.

) {
return !!subsectionData.preferenceType;
}
return true;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I kinda don't get what it does. I thought that it should return true (so that it requires the preferenceType to be chosen) when any of other values are specified.
So wouldn't this line mean, that if none of other values are specified, we are still requiring the preference type to be chosen?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

if any other field is filled in then preferenceType is required.

the boolean values return true if field is valid and false if it is invalid, which means that

true - field is not required (everything is alright)
false - field should be required (validation failed)

Copy link
Collaborator

Choose a reason for hiding this comment

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

could you add this comment above the method? I think the name requirePreferenceType suggests that if it returns true, then it means that we require a preference type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added comments and changed the name, I hope there is no more confusion

@kchelstowski
Copy link
Collaborator

A general comment is that I feel uncomfortable with such refactors at the end of the feature development. There were many edge cases where something in schema was/was not needed or it was intentionally done as null or '' instead of undefined etc.
I hope no regression issues will come up, but yeah...

- added comments and renamed validation function for Preference type
- moved validation trigger to onBlur on other fields rather than useEffect
@drodzewicz drodzewicz force-pushed the OBPIH-6108-add-preference-type-section-with-inputs branch from 5ed5d6c to cdc6bc4 Compare March 8, 2024 13:46
@drodzewicz drodzewicz requested a review from kchelstowski March 8, 2024 13:46
@kchelstowski kchelstowski merged commit 2f932bc into feature/product-supplier-list-redesign Mar 8, 2024
@kchelstowski kchelstowski deleted the OBPIH-6108-add-preference-type-section-with-inputs branch March 8, 2024 13:54
awalkowiak pushed a commit that referenced this pull request Mar 12, 2024
* OBPIH-6108 Refactor validation schema  sections into separate schemas

* OBPIH-6108 export error types from subsections

* OBPIH-6108 Move Each price calculation into separate hook

* OBPIH-6108 trigger validation on preference type fields when default preference sections has changed

* OBPIH-6108 refactor default values for product sources create form

* OBPIH-6108 Fix issue with clearing default prefference type select

* OBPIH-6108 Fixes after review
- added comments and renamed validation function for Preference type
- moved validation trigger to onBlur on other fields rather than useEffect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants