Product Block Editor: tidy product attribute TS types (#46998)

* rename type for item of attribuite input field

* options is not part of the input item

* update type of getProductAttributeObject

* update types

* changelog

* fix eslint issue

* fix test
This commit is contained in:
Damián Suárez 2024-04-30 07:18:03 -04:00 committed by GitHub
parent 35c50ebdb4
commit ee5f12f806
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 58 additions and 55 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: update
Product Block Editor: tidy product attribute types

View File

@ -11,8 +11,7 @@ import {
} from '@woocommerce/components';
import {
EXPERIMENTAL_PRODUCT_ATTRIBUTE_TERMS_STORE_NAME,
ProductProductAttribute,
ProductAttributeTerm,
type ProductAttributeTerm,
} from '@woocommerce/data';
import { Button, Modal, Notice } from '@wordpress/components';
@ -24,8 +23,9 @@ import {
AttributeTermInputField,
CustomAttributeTermInputField,
} from '../attribute-term-input-field';
import { EnhancedProductAttribute } from '../../hooks/use-product-attributes';
import { getProductAttributeObject } from './utils';
import type { AttributeInputFieldItemProps } from '../attribute-input-field/types';
import type { EnhancedProductAttribute } from '../../hooks/use-product-attributes';
type NewAttributeModalProps = {
title?: string;
@ -225,12 +225,7 @@ export const NewAttributeModal: React.FC< NewAttributeModalProps > = ( {
} ) => {
function getAttributeOnChange( index: number ) {
return function handleAttributeChange(
value?:
| Omit<
ProductProductAttribute,
'position' | 'visible' | 'variation'
>
| string
value?: AttributeInputFieldItemProps | string
) {
if (
termsAutoSelection &&

View File

@ -1,7 +1,12 @@
/**
* External dependencies
*/
import { ProductProductAttribute } from '@woocommerce/data';
import type { ProductProductAttribute } from '@woocommerce/data';
/**
* Internal dependencies
*/
import type { AttributeInputFieldItemProps } from '../attribute-input-field/types';
/**
* Returns the attribute key. The key will be the `id` or the `name` when the id is 0.
@ -50,21 +55,21 @@ export function reorderSortableProductAttributePositions(
}
/**
* Helper function to return the product attribute object. If attribute is a string it will create an object.
* Helper function to return an EnhancedProductAttribute object,
* based on the provided attribute object.
*
* If attribute is a string it will create an object.
*
* @param { Object | string } attribute product attribute as string or object.
*/
export function getProductAttributeObject(
attribute:
| string
| Omit< ProductProductAttribute, 'position' | 'visible' | 'variation' >
): Omit< ProductProductAttribute, 'position' | 'visible' | 'variation' > {
attribute: string | AttributeInputFieldItemProps
): AttributeInputFieldItemProps {
return typeof attribute === 'string'
? {
id: 0,
name: attribute,
slug: attribute,
options: [],
}
: attribute;
}

View File

@ -26,7 +26,7 @@ import {
AttributeInputFieldProps,
getItemPropsType,
getMenuPropsType,
NarrowedQueryAttribute,
AttributeInputFieldItemProps,
UseComboboxGetItemPropsOptions,
UseComboboxGetMenuPropsOptions,
} from './types';
@ -65,26 +65,30 @@ export const AttributeInputField: React.FC< AttributeInputFieldProps > = ( {
const markedAttributes = useMemo(
function setDisabledAttribute() {
return (
attributes?.map( ( attribute: NarrowedQueryAttribute ) => ( {
...attribute,
isDisabled: disabledAttributeIds.includes( attribute.id ),
} ) ) ?? []
attributes?.map(
( attribute: AttributeInputFieldItemProps ) => ( {
...attribute,
isDisabled: disabledAttributeIds.includes(
attribute.id
),
} )
) ?? []
);
},
[ attributes, disabledAttributeIds ]
);
function isNewAttributeListItem(
attribute: NarrowedQueryAttribute
attribute: AttributeInputFieldItemProps
): boolean {
return attribute.id === -99;
}
const getFilteredItems = (
allItems: NarrowedQueryAttribute[],
allItems: AttributeInputFieldItemProps[],
inputValue: string
) => {
const ignoreIdsFilter = ( item: NarrowedQueryAttribute ) =>
const ignoreIdsFilter = ( item: AttributeInputFieldItemProps ) =>
ignoredAttributeIds.length
? ! ignoredAttributeIds.includes( item.id )
: true;
@ -117,7 +121,7 @@ export const AttributeInputField: React.FC< AttributeInputFieldProps > = ( {
return filteredItems;
};
const addNewAttribute = ( attribute: NarrowedQueryAttribute ) => {
const addNewAttribute = ( attribute: AttributeInputFieldItemProps ) => {
recordEvent( 'product_attribute_add_custom_attribute', {
source: TRACKS_SOURCE,
} );
@ -130,11 +134,9 @@ export const AttributeInputField: React.FC< AttributeInputFieldProps > = ( {
{
optimisticQueryUpdate: sortCriteria,
}
).then(
( newAttr ) => {
onChange( { ...newAttr, options: [] } );
},
( error ) => {
)
.then( onChange )
.catch( ( error ) => {
let message = __(
'Failed to create new attribute.',
'woocommerce'
@ -146,15 +148,14 @@ export const AttributeInputField: React.FC< AttributeInputFieldProps > = ( {
createErrorNotice( message, {
explicitDismiss: true,
} );
}
);
} );
} else {
onChange( attribute.name );
}
};
return (
<SelectControl< NarrowedQueryAttribute >
<SelectControl< AttributeInputFieldItemProps >
className="woocommerce-attribute-input-field"
items={ markedAttributes || [] }
label={ label || '' }
@ -164,7 +165,7 @@ export const AttributeInputField: React.FC< AttributeInputFieldProps > = ( {
getItemLabel={ ( item ) => item?.name || '' }
getItemValue={ ( item ) => item?.id || '' }
selected={ value }
onSelect={ ( attribute: NarrowedQueryAttribute ) => {
onSelect={ ( attribute: AttributeInputFieldItemProps ) => {
if ( isNewAttributeListItem( attribute ) ) {
addNewAttribute( attribute );
} else {
@ -172,7 +173,6 @@ export const AttributeInputField: React.FC< AttributeInputFieldProps > = ( {
id: attribute.id,
name: attribute.name,
slug: attribute.slug as string,
options: [],
} );
}
} }
@ -186,10 +186,10 @@ export const AttributeInputField: React.FC< AttributeInputFieldProps > = ( {
getMenuProps,
isOpen,
}: {
items: NarrowedQueryAttribute[];
items: AttributeInputFieldItemProps[];
highlightedIndex: number;
getItemProps: (
options: UseComboboxGetItemPropsOptions< NarrowedQueryAttribute >
options: UseComboboxGetItemPropsOptions< AttributeInputFieldItemProps >
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) => any;
getMenuProps: getMenuPropsType;
@ -209,7 +209,7 @@ export const AttributeInputField: React.FC< AttributeInputFieldProps > = ( {
getItemProps={
getItemProps as (
options: UseComboboxGetMenuPropsOptions
) => getItemPropsType< NarrowedQueryAttribute >
) => getItemPropsType< AttributeInputFieldItemProps >
}
/>
) }

View File

@ -10,13 +10,15 @@ import { __experimentalSelectControlMenuItem as MenuItem } from '@woocommerce/co
/**
* Internal dependencies
*/
import {
import type {
MenuAttributeListProps,
NarrowedQueryAttribute,
AttributeInputFieldItemProps,
UseComboboxGetMenuPropsOptions,
} from './types';
function isNewAttributeListItem( attribute: NarrowedQueryAttribute ): boolean {
function isNewAttributeListItem(
attribute: AttributeInputFieldItemProps
): boolean {
return attribute.id === -99;
}

View File

@ -234,7 +234,6 @@ describe( 'AttributeInputField', () => {
id: attributeList[ 0 ].id,
name: attributeList[ 0 ].name,
slug: attributeList[ 0 ].slug,
options: [],
} );
} );
@ -325,7 +324,6 @@ describe( 'AttributeInputField', () => {
name: 'Co',
slug: 'co',
id: 123,
options: [],
} );
} );

View File

@ -1,28 +1,27 @@
/**
* External dependencies
*/
import { ProductAttribute, ProductProductAttribute } from '@woocommerce/data';
import { ProductAttribute } from '@woocommerce/data';
/**
* Internal dependencies
*/
import { EnhancedProductAttribute } from '../../hooks/use-product-attributes';
export type NarrowedQueryAttribute = Pick< ProductAttribute, 'id' | 'name' > & {
/*
* AttributeInputField item props.
*/
export type AttributeInputFieldItemProps = Pick<
ProductAttribute,
'id' | 'name'
> & {
slug?: string;
isDisabled?: boolean;
};
export type AttributeInputFieldProps = {
value?: EnhancedProductAttribute | null;
onChange: (
value?:
| Omit<
ProductProductAttribute,
'position' | 'visible' | 'variation'
>
| string
) => void;
onChange: ( value?: AttributeInputFieldItemProps | string ) => void;
label?: string;
placeholder?: string;
disabled?: boolean;
@ -33,12 +32,12 @@ export type AttributeInputFieldProps = {
};
export type MenuAttributeListProps = {
renderItems: NarrowedQueryAttribute[];
renderItems: AttributeInputFieldItemProps[];
highlightedIndex: number;
disabledAttributeMessage?: string;
getItemProps: (
options: UseComboboxGetMenuPropsOptions
) => getItemPropsType< NarrowedQueryAttribute >;
) => getItemPropsType< AttributeInputFieldItemProps >;
};
export interface GetPropsWithRefKey {