Remove Custom Fields for New Product Editor (#45493)

* Add remove custom field for the new product editor

* Add changelog file

* Show add button when the custom fields are empty

* Ensures to always convert the metas into a string array since it can be anything

* Add changelog file
This commit is contained in:
Maikel Perez 2024-03-13 19:16:12 -03:00 committed by GitHub
parent 3f1dbd5b13
commit 0fc75c5148
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 114 additions and 53 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Remove Custom Fields for New Product Editor

View File

@ -4,6 +4,7 @@
import { Button } from '@wordpress/components';
import { createElement, Fragment, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { closeSmall } from '@wordpress/icons';
import classNames from 'classnames';
/**
@ -21,17 +22,17 @@ export function CustomFields( {
renderActionButtonsWrapper = ( buttons ) => buttons,
...props
}: CustomFieldsProps ) {
const { customFields, addCustomFields, updateCustomField } =
useCustomFields();
const {
customFields,
addCustomFields,
updateCustomField,
removeCustomField,
} = useCustomFields();
const [ showCreateModal, setShowCreateModal ] = useState( false );
const [ selectedCustomField, setSelectedCustomField ] =
useState< Metadata< string > >();
if ( customFields.length === 0 ) {
return <EmptyState />;
}
function handleAddNewButtonClick() {
setShowCreateModal( true );
}
@ -44,6 +45,14 @@ export function CustomFields( {
};
}
function customFieldRemoveButtonClickHandler(
customField: Metadata< string >
) {
return function handleCustomFieldRemoveButtonClick() {
removeCustomField( customField );
};
}
function handleCreateModalCreate( value: Metadata< string >[] ) {
addCustomFields( value );
setShowCreateModal( false );
@ -70,46 +79,61 @@ export function CustomFields( {
</Button>
) }
<table
{ ...props }
className={ classNames(
'woocommerce-product-custom-fields__table',
className
) }
>
<thead>
<tr className="woocommerce-product-custom-fields__table-row">
<th>{ __( 'Name', 'woocommerce' ) }</th>
<th>{ __( 'Value', 'woocommerce' ) }</th>
<th>{ __( 'Actions', 'woocommerce' ) }</th>
</tr>
</thead>
<tbody>
{ customFields.map( ( customField ) => (
<tr
className="woocommerce-product-custom-fields__table-row"
key={ customField.id ?? customField.key }
>
<td className="woocommerce-product-custom-fields__table-datacell">
{ customField.key }
</td>
<td className="woocommerce-product-custom-fields__table-datacell">
{ customField.value }
</td>
<td className="woocommerce-product-custom-fields__table-datacell">
<Button
variant="tertiary"
onClick={ customFieldEditButtonClickHandler(
customField
) }
>
{ __( 'Edit', 'woocommerce' ) }
</Button>
</td>
{ customFields.length === 0 ? (
<EmptyState />
) : (
<table
{ ...props }
className={ classNames(
'woocommerce-product-custom-fields__table',
className
) }
>
<thead>
<tr className="woocommerce-product-custom-fields__table-row">
<th>{ __( 'Name', 'woocommerce' ) }</th>
<th>{ __( 'Value', 'woocommerce' ) }</th>
<th>{ __( 'Actions', 'woocommerce' ) }</th>
</tr>
) ) }
</tbody>
</table>
</thead>
<tbody>
{ customFields.map( ( customField ) => (
<tr
className="woocommerce-product-custom-fields__table-row"
key={ customField.id ?? customField.key }
>
<td className="woocommerce-product-custom-fields__table-datacell">
{ customField.key }
</td>
<td className="woocommerce-product-custom-fields__table-datacell">
{ customField.value }
</td>
<td className="woocommerce-product-custom-fields__table-datacell">
<Button
variant="tertiary"
onClick={ customFieldEditButtonClickHandler(
customField
) }
>
{ __( 'Edit', 'woocommerce' ) }
</Button>
<Button
icon={ closeSmall }
onClick={ customFieldRemoveButtonClickHandler(
customField
) }
aria-label={ __(
'Remove custom field',
'woocommerce'
) }
/>
</td>
</tr>
) ) }
</tbody>
</table>
) }
{ showCreateModal && (
<CreateModal

View File

@ -5,5 +5,5 @@ import { Metadata } from '../../types';
export type DisjoinMetas< T extends Metadata< string > > = {
customFields: T[];
internalMetas: T[];
otherMetas: T[];
};

View File

@ -20,11 +20,11 @@ export function useCustomFields<
'meta_data'
);
const { customFields, internalMetas } = useMemo(
const { customFields, otherMetas } = useMemo(
function extractCustomFieldsFromMetas() {
return metas.reduce( disjoinMetas< T >, {
customFields: [],
internalMetas: [],
otherMetas: [],
} );
},
[ metas ]
@ -34,7 +34,7 @@ export function useCustomFields<
const newValue =
typeof value === 'function' ? value( customFields ) : value;
setMetas( [ ...internalMetas, ...newValue ] );
setMetas( [ ...otherMetas, ...newValue ] );
}
function addCustomFields( value: T[] ) {
@ -52,10 +52,36 @@ export function useCustomFields<
);
}
function removeCustomField( customField: T ) {
setCustomFields( ( current ) => {
// If the id is undefined then it is a local copy.
if ( customField.id === undefined ) {
return current.filter( function isNotEquals( field ) {
return ! (
field.key === customField.key &&
field.value === customField.value
);
} );
}
return current.map( ( field ) => {
if ( field.id === customField.id ) {
return {
...field,
value: null,
};
}
return field;
} );
} );
}
return {
customFields,
addCustomFields,
setCustomFields,
updateCustomField,
removeCustomField,
};
}

View File

@ -4,8 +4,10 @@
import type { Metadata } from '../../../types';
import type { DisjoinMetas } from '../types';
export function isCustomField< T extends Metadata< string > >( value: T ) {
return ! value.key.startsWith( '_' );
export function isCustomField< T extends Metadata< string > >(
customField: T
) {
return ! customField.key.startsWith( '_' ) && customField.value !== null;
}
export function disjoinMetas< T extends Metadata< string > >(
@ -15,7 +17,7 @@ export function disjoinMetas< T extends Metadata< string > >(
if ( isCustomField( meta ) ) {
state.customFields.push( meta );
} else {
state.internalMetas.push( meta );
state.otherMetas.push( meta );
}
return state;
}

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Ensures to always convert the metas into a string array since it can be anything

View File

@ -393,7 +393,8 @@ class Init {
$hidden = get_user_meta( $object['id'], $attr, true );
if ( is_array( $hidden ) ) {
return $hidden;
// Ensures to always return a string array.
return array_values( $hidden );
}
return array( 'postcustom' );