Request tags only when we need them (#47068)

* Get Tags conditionally

* Create file types.ts

* Add changelog

* Fix tests
This commit is contained in:
Fernando Marichal 2024-05-06 15:54:18 -03:00 committed by GitHub
parent b7e30ea5b3
commit e5e78a33bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 54 additions and 32 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: dev
Request tags only when we need them #47068

View File

@ -19,7 +19,7 @@
"type": "string"
}
},
"usesContext": [ "postType" ],
"usesContext": [ "postType", "isInSelectedTab" ],
"supports": {
"align": false,
"html": false,

View File

@ -21,13 +21,13 @@ import { ProductEditorBlockEditProps } from '../../../types';
export function Edit( {
attributes,
context,
context: { postType, isInSelectedTab },
}: ProductEditorBlockEditProps< BlockAttributes > ) {
const blockProps = useWooBlockProps( attributes );
const { name, label, placeholder } = attributes;
const [ tags, setTags ] = useEntityProp<
Pick< ProductTag, 'id' | 'name' >[]
>( 'postType', context.postType || 'product', name || 'tags' );
>( 'postType', postType || 'product', name || 'tags' );
const tagFieldId = useInstanceId( BaseControl, 'tag-field' ) as string;
@ -36,6 +36,7 @@ export function Edit( {
{
<TagField
id={ tagFieldId }
isVisible={ isInSelectedTab }
label={ label || __( 'Tags', 'woocommerce' ) }
placeholder={
placeholder ||

View File

@ -15,12 +15,7 @@ import {
* Internal dependencies
*/
import { TRACKS_SOURCE } from '../../constants';
type CreateTagModalProps = {
initialTagName?: string;
onCancel: () => void;
onCreate: ( newTag: ProductTag ) => void;
};
import { CreateTagModalProps } from './types';
export const CreateTagModal: React.FC< CreateTagModalProps > = ( {
initialTagName,

View File

@ -2,7 +2,12 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState, createElement, Fragment } from '@wordpress/element';
import {
useEffect,
useState,
createElement,
Fragment,
} from '@wordpress/element';
import {
TreeItemType,
__experimentalSelectTreeControl as SelectTree,
@ -18,26 +23,19 @@ import { useDebounce } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { useTagSearch, ProductTagNode } from './use-tag-search';
import { useTagSearch } from './use-tag-search';
import { TRACKS_SOURCE } from '../../constants';
import { CreateTagModal } from './create-tag-modal';
import { ProductTagNodeProps, TagFieldProps } from './types';
type TagFieldProps = {
id: string;
label: string;
placeholder: string;
value?: ProductTagNode[];
onChange: ( value: ProductTagNode[] ) => void;
};
export function mapFromTagToTreeItem( val: ProductTagNode ): TreeItemType {
export function mapFromTagToTreeItem( val: ProductTagNodeProps ): TreeItemType {
return {
value: String( val.id ),
label: val.name,
};
}
export function mapFromTreeItemToTag( val: TreeItemType ): ProductTagNode {
export function mapFromTreeItemToTag( val: TreeItemType ): ProductTagNodeProps {
return {
id: +val.value,
name: val.label,
@ -45,19 +43,20 @@ export function mapFromTreeItemToTag( val: TreeItemType ): ProductTagNode {
}
export function mapFromTagsToTreeItems(
tags: ProductTagNode[]
tags: ProductTagNodeProps[]
): TreeItemType[] {
return tags.map( mapFromTagToTreeItem );
}
export function mapFromTreeItemsToTags(
tags: TreeItemType[]
): ProductTagNode[] {
): ProductTagNodeProps[] {
return tags.map( mapFromTreeItemToTag );
}
export const TagField: React.FC< TagFieldProps > = ( {
id,
isVisible = false,
label,
placeholder,
value = [],
@ -80,6 +79,12 @@ export const TagField: React.FC< TagFieldProps > = ( {
setNewInputValue( searchString );
};
useEffect( () => {
if ( isVisible ) {
searchTags();
}
}, [ isVisible ] );
const searchDelayed = useDebounce( onInputChange, 150 );
const onSave = async () => {
@ -132,7 +137,7 @@ export const TagField: React.FC< TagFieldProps > = ( {
selected={ mapFromTagsToTreeItems( value ) }
onSelect={ ( selectedItems ) => {
if ( Array.isArray( selectedItems ) ) {
const newItems: ProductTagNode[] =
const newItems: ProductTagNodeProps[] =
mapFromTreeItemsToTags(
selectedItems.filter(
( { value: selectedItemValue } ) =>

View File

@ -10,7 +10,7 @@ import { createElement } from '@wordpress/element';
* Internal dependencies
*/
import { TagField } from '../tag-field';
import { ProductTagNode } from '../use-tag-search';
import { ProductTagNodeProps } from '../types';
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
@ -37,9 +37,10 @@ describe( 'TagField', () => {
{ ( { getInputProps }: FormContextType< Product > ) => (
<TagField
id="tag-field"
isVisible={ true }
label="Tags"
placeholder="Search or create tag…"
{ ...getInputProps< ProductTagNode[] >( 'tags' ) }
{ ...getInputProps< ProductTagNodeProps[] >( 'tags' ) }
/>
) }
</Form>
@ -61,9 +62,10 @@ describe( 'TagField', () => {
{ ( { getInputProps }: FormContextType< Product > ) => (
<TagField
id="another-tag-field"
isVisible={ true }
label="Tags"
placeholder="Search or create tag…"
{ ...getInputProps< ProductTagNode[] >( 'tags' ) }
{ ...getInputProps< ProductTagNodeProps[] >( 'tags' ) }
/>
) }
</Form>

View File

@ -0,0 +1,19 @@
/**
* External dependencies
*/
import { ProductTag } from '@woocommerce/data';
export type CreateTagModalProps = {
initialTagName?: string;
onCancel: () => void;
onCreate: ( newTag: ProductTag ) => void;
};
export type ProductTagNodeProps = Pick< ProductTag, 'id' | 'name' >;
export type TagFieldProps = {
id: string;
isVisible?: boolean;
label: string;
placeholder: string;
value?: ProductTagNodeProps[];
onChange: ( value: ProductTagNodeProps[] ) => void;
};

View File

@ -1,15 +1,13 @@
/**
* External dependencies
*/
import { useEffect, useState } from '@wordpress/element';
import { useState } from '@wordpress/element';
import { resolveSelect } from '@wordpress/data';
import {
EXPERIMENTAL_PRODUCT_TAGS_STORE_NAME,
ProductTag,
} from '@woocommerce/data';
export type ProductTagNode = Pick< ProductTag, 'id' | 'name' >;
/**
* A hook used to handle all the search logic for the tag search component.
*/
@ -30,8 +28,6 @@ export const useTagSearch = () => {
} );
};
useEffect( fetchProductTags, [] );
return {
searchTags: fetchProductTags,
tagsSelectList: fetchedTags,