Request tags only when we need them (#47068)
* Get Tags conditionally * Create file types.ts * Add changelog * Fix tests
This commit is contained in:
parent
b7e30ea5b3
commit
e5e78a33bf
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: dev
|
||||
|
||||
Request tags only when we need them #47068
|
|
@ -19,7 +19,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"usesContext": [ "postType" ],
|
||||
"usesContext": [ "postType", "isInSelectedTab" ],
|
||||
"supports": {
|
||||
"align": false,
|
||||
"html": false,
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 } ) =>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue