Skip to content

Commit

Permalink
Refactor getValidationError and getValidationErrorId selectors in…
Browse files Browse the repository at this point in the history
… `wc/store/validation` data store (woocommerce#7146)

* Convert checkout context to data store - part 1 (woocommerce#6232)

* Add checkout data store

* wip on checkout data store

* CheckoutContext now uses the checkout store

* Investigated and removed setting the redirectUrl on the default state

* update extension and address hooks to use checkout data store

* use checkout data store in checkout-processor and use-checkout-button

* trim useCheckoutContext from use-payment-method-interface && use-store-cart-item-quantity

* Remove useCheckoutContext from shipping provider

* Remove isCalculating from state

* Removed useCheckoutContext from lots of places

* Remove useCheckoutContext from checkout-payment-block

* Remove useCheckoutContext in checkout-shipping-methods-block and checkout-shipping-address-block

* add isCart selector and action and update the checkoutstate context

* Fixed redirectUrl bug by using thunks

* Remove dispatchActions from checkout-state

* Change SET_HAS_ERROR action to be neater

* Thomas' feedback

* Tidy up

* Oops, deleted things I shouldn't have

* Typescript

* Fix types

* Fix tests

* Remove isCart

* Update docs and remove unecessary getRedirectUrl() selector

* set correct type for preloadedCheckoutData

* Remove duplicate Address type

* Fix missing addresses from type-defs index

* Update docs/block-client-apis/checkout/checkout-api.md

Co-authored-by: Thomas Roberts <[email protected]>

* Update docs/block-client-apis/checkout/checkout-api.md

Co-authored-by: Thomas Roberts <[email protected]>

* Update docs

* Update docs/block-client-apis/checkout/checkout-api.md

Co-authored-by: Thomas Roberts <[email protected]>

* Update docs/block-client-apis/checkout/checkout-api.md

Co-authored-by: Thomas Roberts <[email protected]>

* Revert feedback changes

* REvert feedback formatting

* Update docs formatting

* Delete empty types.ts file

* remove merge conflict from docs

* Correct linting in docs

Co-authored-by: Thomas Roberts <[email protected]>

* Move checkout state code into thunks and rename `CheckoutState` context to `CheckoutEvents` (woocommerce#6455)

* Add checkout data store

* wip on checkout data store

* CheckoutContext now uses the checkout store

* Investigated and removed setting the redirectUrl on the default state

* update extension and address hooks to use checkout data store

* use checkout data store in checkout-processor and use-checkout-button

* trim useCheckoutContext from use-payment-method-interface && use-store-cart-item-quantity

* Remove useCheckoutContext from shipping provider

* Remove isCalculating from state

* Removed useCheckoutContext from lots of places

* Remove useCheckoutContext from checkout-payment-block

* Remove useCheckoutContext in checkout-shipping-methods-block and checkout-shipping-address-block

* add isCart selector and action and update the checkoutstate context

* Fixed redirectUrl bug by using thunks

* Remove dispatchActions from checkout-state

* Change SET_HAS_ERROR action to be neater

* Thomas' feedback

* Tidy up

* Oops, deleted things I shouldn't have

* Typescript

* Fix types

* Fix tests

* Remove isCart

* Update docs and remove unecessary getRedirectUrl() selector

* validate event emitter button

* Added thunks in a separate file

* Call thunks from checkout-state

* Checkout logic tested and working

* Remove dependency injection as much as poss, tidy up and fix some TS errors

* Fix types in thunks.ts

* Fixed some ts errors

* WIP

* Fixed bug

* Shift side effects from checkout-state to checkout-processor

* Revert "Shift side effects from checkout-state to checkout-processor"

This reverts commit 059533d.

* Rename CheckoutState to CheckoutEvents

* Move status check outside the thunk

* remove duplicate EVENTS constant

* remove temp buttons

* Remove console logs

* Augment @wordpress/data package with our new store types

* Add correct type for CheckoutAction

* Remove createErrorNotice arg from runCheckoutAfterProcessingWithErrorObservers

* Remove createErrorNotice from emit event types

* Use type keyword when importing types

* Add correct types for dispatch and select in thunks

* Update wordpress/data types

* Replace store creation with new preferred method

* Set correct action type on reducer

* Remove unnecessary async from thunk

* add CHECKOUT_ prefix to checkout events again

* export EVENTS with eveything else in checkout0-events/event-emit

* Remove duplicate SelectFromMap and TailParameters

* Updated type for paymentStatus

* TODO remove wp/data experimental thunks

* Remove `setCustomerId` from events and `processCheckoutResponseHeaders` (woocommerce#6586)

* Prevent passing dispatch, instead get actions direct from store

* Get setCustomerId from the store instead of passing it to processCheckoutResponseHeaders

* Revert "Prevent passing dispatch, instead get actions direct from store"

This reverts commit 4479a2e.

* Auto stash before revert of "Prevent passing dispatch, instead get actions direct from store"

* Remove duplicate dispatch

* Fix unit tests

Co-authored-by: Thomas Roberts <[email protected]>
Co-authored-by: Thomas Roberts <[email protected]>

* Refactor selectors to not return functions anymore

This is a poor DevEx and naming did not reflect what the selector was returning.

* Update combobox to be more explicit when selecting validation error

* Update useValidation to use the new getValidationError selector

* Include @woocommerce/base-hooks in tsconfig

* Update ValidationInputError to use new selector

* Update ValidatedTextInput to use new selectors

* Prevent reference errors when getting validation errors in ComboBox

* Defend against case where message prop of error object is undefined

* Fix totals/coupon to use new validation selector

* Use validation data store in CheckoutTerms block

* Update AddressForm to use new validation selector

* Update AttributeSelectControl to use new validation selector

* Fix syntax error in ValidatedTextInput

* Fix multiple import error from rebase

* Fix lint issue in useStoreCartItemQantity

* Fix tests to reflect new selector API

* Remove unused validation prop from CheckoutTermsBlock

* Change CheckoutTermsBlock unit tests to use validation data store

* Fix JSDOC syntax

* fix merge conflict in checkout-api.md

Co-authored-by: Alex Florisca <[email protected]>
Co-authored-by: Niels Lange <[email protected]>
  • Loading branch information
3 people authored and senadir committed Nov 12, 2022
1 parent af6ff87 commit 905dcaa
Show file tree
Hide file tree
Showing 14 changed files with 64,705 additions and 47,307 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,27 @@ const AttributeSelectControl = ( {
} ) => {
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
=======
const { setValidationErrors, clearValidationError } = useDispatch(
VALIDATION_STORE_KEY
);
=======
=======
const errorId = attributeName;

>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
const { setValidationErrors, clearValidationError } =
useDispatch( VALIDATION_STORE_KEY );
>>>>>>> 4ff656e4c (Feature: Data Store Migration - Payments (#6619))

const { getValidationError } = useSelect( ( select ) => {
const { error } = useSelect( ( select ) => {
const store = select( VALIDATION_STORE_KEY );
return {
getValidationError: store.getValidationError(),
error: store.getValidationError( errorId ) || {},
};
} );
<<<<<<< HEAD
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
const errorId = attributeName;

Expand All @@ -60,6 +66,8 @@ const AttributeSelectControl = ( {
error: store.getValidationError( errorId ) || {},
};
} );
=======
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))

useEffect( () => {
if ( value ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,15 @@ const AddressForm = ( {
}: AddressFormProps ): JSX.Element => {
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
const validationErrorId = 'shipping-missing-country';
const { setValidationErrors, clearValidationError } =
useDispatch( VALIDATION_STORE_KEY );

const countryValidationError = useSelect( ( select ) => {
<<<<<<< HEAD
const store = select( VALIDATION_STORE_KEY );
return store.getValidationError( validationErrorId );
=======
Expand All @@ -117,6 +121,10 @@ const AddressForm = ( {
const store = select( VALIDATION_STORE_KEY );
return store.getValidationError();
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
=======
const store = select( VALIDATION_STORE_KEY );
return store.getValidationError( validationErrorId );
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
} );

const currentFields = useShallowEqual( fields );
Expand Down
14 changes: 14 additions & 0 deletions assets/js/base/components/cart-checkout/totals/coupon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const TotalsCoupon = ( {
}: TotalsCouponProps ): JSX.Element => {
const [ couponValue, setCouponValue ] = useState( '' );
const currentIsLoading = useRef( false );
<<<<<<< HEAD
<<<<<<< HEAD

const validationErrorKey = 'coupon';
Expand All @@ -81,6 +82,19 @@ export const TotalsCoupon = ( {

const validationError = getValidationError( 'coupon' );
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
=======

const validationErrorKey = 'coupon';
const textInputId = `wc-block-components-totals-coupon__input-${ instanceId }`;

const { validationError, validationErrorId } = useSelect( ( select ) => {
const store = select( VALIDATION_STORE_KEY );
return {
validationError: store.getValidationError( validationErrorKey ),
validationErrorId: store.getValidationErrorId( textInputId ),
};
} );
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))

useEffect( () => {
if ( currentIsLoading.current !== isLoading ) {
Expand Down
3 changes: 3 additions & 0 deletions assets/js/base/components/combobox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const Combobox = ( {
autoComplete = 'off',
}: ComboboxProps ): JSX.Element => {
<<<<<<< HEAD
<<<<<<< HEAD
=======
const { setValidationErrors, clearValidationError } = useDispatch(
VALIDATION_STORE_KEY
Expand All @@ -69,6 +70,8 @@ const Combobox = ( {
} );

>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
=======
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
const controlRef = useRef< HTMLDivElement >( null );
const controlId = id || 'control-' + instanceId;
const errorId = incomingErrorId || controlId;
Expand Down
3 changes: 2 additions & 1 deletion assets/js/base/components/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"../../atomic/utils",
"../../atomic/blocks/component-init.js",
"../../data",
"../../shared/context"
"../../shared/context",
"../hooks/index.js"
],
"exclude": [ "**/test/**" ]
}
24 changes: 10 additions & 14 deletions assets/js/base/components/validation-input-error/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,25 @@ export const ValidationInputError = ( {
propertyName = '',
elementId = '',
}: ValidationInputErrorProps ): JSX.Element | null => {
const { getValidationError, getValidationErrorId } = useSelect(
( select ) => {
const store = select( VALIDATION_STORE_KEY );
return {
getValidationError: store.getValidationError(),
getValidationErrorId: store.getValidationErrorId(),
};
}
);
const validationError = getValidationError( propertyName );
const { validationError, validationErrorId } = useSelect( ( select ) => {
const store = select( VALIDATION_STORE_KEY );
return {
validationError: store.getValidationError( propertyName ),
validationErrorId: store.getValidationErrorId( elementId ),
};
} );

if ( ! errorMessage || typeof errorMessage !== 'string' ) {
const error = validationError || {};
if ( error.message && ! error.hidden ) {
errorMessage = error.message;
if ( validationError?.message && ! validationError?.hidden ) {
errorMessage = validationError.message;
} else {
return null;
}
}

return (
<div className="wc-block-components-validation-error" role="alert">
<p id={ getValidationErrorId( elementId ) }>{ errorMessage }</p>
<p id={ validationErrorId }>{ errorMessage }</p>
</div>
);
};
Expand Down
24 changes: 20 additions & 4 deletions assets/js/base/context/hooks/use-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,34 @@ export const useValidation = (): ValidationData => {
const { clearValidationError, hideValidationError, setValidationErrors } =
useDispatch( VALIDATION_STORE_KEY );

<<<<<<< HEAD
=======
const {
clearValidationError,
hideValidationError,
setValidationErrors,
} = useDispatch( VALIDATION_STORE_KEY );
=======
const prefix = 'extensions-errors';

>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
const { hasValidationErrors, getValidationError } = useSelect(
( select ) => {
const store = select( VALIDATION_STORE_KEY );
( mapSelect ) => {
const store = mapSelect( VALIDATION_STORE_KEY );
return {
hasValidationErrors: store.hasValidationErrors,
getValidationError: store.getValidationError(),
hasValidationErrors: store.hasValidationErrors(),
getValidationError: ( validationErrorId: string ) =>
store.getValidationError(
`${ prefix }-${ validationErrorId }`
),
};
}
);
<<<<<<< HEAD
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
const prefix = 'extensions-errors';
=======
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))

const { hasValidationErrors, getValidationError } = useSelect(
( mapSelect ) => {
Expand All @@ -49,6 +60,7 @@ export const useValidation = (): ValidationData => {
);

return {
<<<<<<< HEAD
<<<<<<< HEAD
hasValidationErrors,
getValidationError,
Expand All @@ -60,6 +72,10 @@ export const useValidation = (): ValidationData => {
[ getValidationError ]
),
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
=======
hasValidationErrors,
getValidationError,
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
clearValidationError: useCallback(
( validationErrorId: string ) =>
clearValidationError( `${ prefix }-${ validationErrorId }` ),
Expand Down
4 changes: 4 additions & 0 deletions assets/js/data/checkout/reducers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/**
* External dependencies
*/
<<<<<<< HEAD
=======
import type { Reducer } from 'redux';
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
import { PaymentResult } from '@woocommerce/types';

/**
Expand Down
3 changes: 2 additions & 1 deletion assets/js/data/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"../base/context/providers/cart-checkout/payment-methods/**.ts",
"../utils/notices.ts",
"../base/context/providers/cart-checkout/checkout-events/**.ts",
"../base/context/event-emit"
"../base/context/event-emit",
"../base/context/providers/cart-checkout/checkout-state/utils.ts"
],
"exclude": [ "**/test/**" ]
}
4 changes: 4 additions & 0 deletions assets/js/data/validation/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ const reducer: Reducer< Record< string, FieldValidationStatus > > = (
switch ( action.type ) {
case types.SET_VALIDATION_ERRORS:
const newErrors = pickBy( action.errors, ( error, property ) => {
<<<<<<< HEAD
<<<<<<< HEAD
if ( typeof error?.message !== 'string' ) {
=======
if ( typeof error.message !== 'string' ) {
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
=======
if ( typeof error?.message !== 'string' ) {
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
return false;
}
if ( state.hasOwnProperty( property ) ) {
Expand Down
14 changes: 14 additions & 0 deletions assets/js/data/validation/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import type { State } from './reducers';

<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
/**
* Gets a validation error by ID.
*
Expand All @@ -26,6 +29,7 @@ export const getValidationErrorId = ( state: State, errorId: string ) => {
return;
}
return `validate-error-${ errorId }`;
<<<<<<< HEAD
};

/**
Expand All @@ -47,6 +51,16 @@ export const getValidationErrorId = ( state: State ) => {
};
};
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
=======
};

/**
* Whether the store has validation errors.
*
* @param { State } state The current state.
* @return { boolean } Whether the store has validation errors or not.
*/
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
export const hasValidationErrors = ( state: State ) => {
return Object.keys( state ).length > 0;
};
9 changes: 9 additions & 0 deletions assets/js/data/validation/test/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ describe( 'Validation selectors', () => {
hidden: false,
},
};
<<<<<<< HEAD
<<<<<<< HEAD
const validationError = getValidationError( state, 'validationError' );
=======
const validationError = getValidationError( state )(
'validationError'
);
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
=======
const validationError = getValidationError( state, 'validationError' );
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
expect( validationError ).toEqual( {
message: 'This is a test message',
hidden: false,
Expand All @@ -36,12 +40,17 @@ describe( 'Validation selectors', () => {
hidden: false,
},
};
<<<<<<< HEAD
<<<<<<< HEAD
const validationErrorID = getValidationErrorId(
state,
=======
const validationErrorID = getValidationErrorId( state )(
>>>>>>> 0cfb0ee6d (Convert validation context to data store (#6402))
=======
const validationErrorID = getValidationErrorId(
state,
>>>>>>> 257114e23 (Refactor `getValidationError` and `getValidationErrorId` selectors in `wc/store/validation` data store (#7146))
'validationError'
);
expect( validationErrorID ).toEqual( `validate-error-validationError` );
Expand Down
Loading

0 comments on commit 905dcaa

Please sign in to comment.