diff --git a/packages/edit-post/src/components/sidebar/post-taxonomies/index.js b/packages/edit-post/src/components/sidebar/post-taxonomies/index.js
deleted file mode 100644
index d44815ee98b71b..00000000000000
--- a/packages/edit-post/src/components/sidebar/post-taxonomies/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * WordPress dependencies
- */
-import {
- PostTaxonomies as PostTaxonomiesForm,
- PostTaxonomiesCheck,
-} from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import TaxonomyPanel from './taxonomy-panel';
-
-function PostTaxonomies() {
- return (
-
- {
- return (
-
- { content }
-
- );
- } }
- />
-
- );
-}
-
-export default PostTaxonomies;
diff --git a/packages/edit-post/src/components/sidebar/settings-sidebar/index.js b/packages/edit-post/src/components/sidebar/settings-sidebar/index.js
index 9b413d1858b589..3aac4d59df23b4 100644
--- a/packages/edit-post/src/components/sidebar/settings-sidebar/index.js
+++ b/packages/edit-post/src/components/sidebar/settings-sidebar/index.js
@@ -11,14 +11,17 @@ import { isRTL, __ } from '@wordpress/i18n';
import { drawerLeft, drawerRight } from '@wordpress/icons';
import { store as interfaceStore } from '@wordpress/interface';
import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts';
-import { store as editorStore, PostLastRevisionPanel } from '@wordpress/editor';
+import {
+ store as editorStore,
+ PostLastRevisionPanel,
+ PostTaxonomiesPanel,
+} from '@wordpress/editor';
/**
* Internal dependencies
*/
import SettingsHeader from '../settings-header';
import PostStatus from '../post-status';
-import PostTaxonomies from '../post-taxonomies';
import FeaturedImage from '../featured-image';
import PostExcerpt from '../post-excerpt';
import DiscussionPanel from '../discussion-panel';
@@ -79,7 +82,7 @@ const SidebarContent = ( {
-
+
diff --git a/packages/edit-site/src/components/sidebar-edit-mode/page-panels/index.js b/packages/edit-site/src/components/sidebar-edit-mode/page-panels/index.js
index d23dc87f42543c..28741f4ed6db7c 100644
--- a/packages/edit-site/src/components/sidebar-edit-mode/page-panels/index.js
+++ b/packages/edit-site/src/components/sidebar-edit-mode/page-panels/index.js
@@ -12,7 +12,11 @@ import { humanTimeDiff } from '@wordpress/date';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { decodeEntities } from '@wordpress/html-entities';
-import { PostLastRevisionPanel, store as editorStore } from '@wordpress/editor';
+import {
+ PostLastRevisionPanel,
+ PostTaxonomiesPanel,
+ store as editorStore,
+} from '@wordpress/editor';
/**
* Internal dependencies
@@ -95,6 +99,7 @@ export default function PagePanels() {
) }
+
>
);
}
diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/index.js b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/index.js
index 2364053c834d71..97a8ba4db448e8 100644
--- a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/index.js
+++ b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/index.js
@@ -3,7 +3,11 @@
*/
import { useSelect } from '@wordpress/data';
import { PanelBody } from '@wordpress/components';
-import { PostLastRevisionPanel, store as editorStore } from '@wordpress/editor';
+import {
+ PostTaxonomiesPanel,
+ PostLastRevisionPanel,
+ store as editorStore,
+} from '@wordpress/editor';
import { store as coreStore } from '@wordpress/core-data';
import { decodeEntities } from '@wordpress/html-entities';
import { navigation, symbol } from '@wordpress/icons';
@@ -15,8 +19,6 @@ import { store as editSiteStore } from '../../../store';
import TemplateActions from './template-actions';
import TemplateAreas from './template-areas';
import SidebarCard from '../sidebar-card';
-import PatternCategories from './pattern-categories';
-import { PATTERN_TYPES } from '../../../utils/constants';
const CARD_ICONS = {
wp_block: symbol,
@@ -24,29 +26,24 @@ const CARD_ICONS = {
};
export default function TemplatePanel() {
- const { title, description, icon, record, postType } = useSelect(
- ( select ) => {
- const { getEditedPostType, getEditedPostId } =
- select( editSiteStore );
- const { getEditedEntityRecord } = select( coreStore );
- const { __experimentalGetTemplateInfo: getTemplateInfo } =
- select( editorStore );
+ const { title, description, icon, record } = useSelect( ( select ) => {
+ const { getEditedPostType, getEditedPostId } = select( editSiteStore );
+ const { getEditedEntityRecord } = select( coreStore );
+ const { __experimentalGetTemplateInfo: getTemplateInfo } =
+ select( editorStore );
- const type = getEditedPostType();
- const postId = getEditedPostId();
- const _record = getEditedEntityRecord( 'postType', type, postId );
- const info = getTemplateInfo( _record );
+ const type = getEditedPostType();
+ const postId = getEditedPostId();
+ const _record = getEditedEntityRecord( 'postType', type, postId );
+ const info = getTemplateInfo( _record );
- return {
- title: info.title,
- description: info.description,
- icon: info.icon,
- record: _record,
- postType: type,
- };
- },
- []
- );
+ return {
+ title: info.title,
+ description: info.description,
+ icon: info.icon,
+ record: _record,
+ };
+ }, [] );
if ( ! title && ! description ) {
return null;
@@ -66,11 +63,7 @@ export default function TemplatePanel() {
-
- { postType === PATTERN_TYPES.user && (
-
- ) }
-
+
>
);
}
diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/pattern-categories.js b/packages/edit-site/src/components/sidebar-edit-mode/template-panel/pattern-categories.js
deleted file mode 100644
index 3740b622361ff5..00000000000000
--- a/packages/edit-site/src/components/sidebar-edit-mode/template-panel/pattern-categories.js
+++ /dev/null
@@ -1,279 +0,0 @@
-/**
- * WordPress dependencies
- */
-import { __, _x, sprintf } from '@wordpress/i18n';
-import { useEffect, useMemo, useState } from '@wordpress/element';
-import { FormTokenField, FlexBlock, PanelRow } from '@wordpress/components';
-import { useSelect, useDispatch } from '@wordpress/data';
-import { store as coreStore } from '@wordpress/core-data';
-import { useDebounce } from '@wordpress/compose';
-import { store as noticesStore } from '@wordpress/notices';
-import { decodeEntities } from '@wordpress/html-entities';
-
-/**
- * Internal dependencies
- */
-import { PATTERN_TYPES } from '../../../utils/constants';
-
-export const unescapeString = ( arg ) => {
- return decodeEntities( arg );
-};
-
-/**
- * Returns a term object with name unescaped.
- *
- * @param {Object} term The term object to unescape.
- *
- * @return {Object} Term object with name property unescaped.
- */
-export const unescapeTerm = ( term ) => {
- return {
- ...term,
- name: unescapeString( term.name ),
- };
-};
-
-/**
- * Shared reference to an empty array for cases where it is important to avoid
- * returning a new array reference on every invocation.
- *
- * @type {Array}
- */
-const EMPTY_ARRAY = [];
-
-/**
- * Module constants
- */
-const MAX_TERMS_SUGGESTIONS = 20;
-const DEFAULT_QUERY = {
- per_page: MAX_TERMS_SUGGESTIONS,
- _fields: 'id,name',
- context: 'view',
-};
-
-const isSameTermName = ( termA, termB ) =>
- unescapeString( termA ).toLowerCase() ===
- unescapeString( termB ).toLowerCase();
-
-const termNamesToIds = ( names, terms ) => {
- return names.map(
- ( termName ) =>
- terms.find( ( term ) => isSameTermName( term.name, termName ) ).id
- );
-};
-
-export default function PatternCategories( { post } ) {
- const slug = 'wp_pattern_category';
- const [ values, setValues ] = useState( [] );
- const [ search, setSearch ] = useState( '' );
- const debouncedSearch = useDebounce( setSearch, 500 );
-
- const {
- terms,
- taxonomy,
- hasAssignAction,
- hasCreateAction,
- hasResolvedTerms,
- } = useSelect(
- ( select ) => {
- const { getEntityRecords, getTaxonomy, hasFinishedResolution } =
- select( coreStore );
- const _taxonomy = getTaxonomy( slug );
- const _termIds =
- post?.wp_pattern_category?.length > 0
- ? post?.wp_pattern_category
- : EMPTY_ARRAY;
- const query = {
- ...DEFAULT_QUERY,
- include: _termIds?.join( ',' ),
- per_page: -1,
- };
-
- return {
- hasCreateAction: _taxonomy
- ? post._links?.[
- 'wp:action-create-' + _taxonomy.rest_base
- ] ?? false
- : false,
- hasAssignAction: _taxonomy
- ? post._links?.[
- 'wp:action-assign-' + _taxonomy.rest_base
- ] ?? false
- : false,
- taxonomy: _taxonomy,
- termIds: _termIds,
- terms: _termIds?.length
- ? getEntityRecords( 'taxonomy', slug, query )
- : EMPTY_ARRAY,
- hasResolvedTerms: hasFinishedResolution( 'getEntityRecords', [
- 'taxonomy',
- slug,
- query,
- ] ),
- };
- },
- [ slug, post ]
- );
-
- const { searchResults } = useSelect(
- ( select ) => {
- const { getEntityRecords } = select( coreStore );
-
- return {
- searchResults: !! search
- ? getEntityRecords( 'taxonomy', slug, {
- ...DEFAULT_QUERY,
- search,
- } )
- : EMPTY_ARRAY,
- };
- },
- [ search, slug ]
- );
-
- // Update terms state only after the selectors are resolved.
- // We're using this to avoid terms temporarily disappearing on slow networks
- // while core data makes REST API requests.
- useEffect( () => {
- if ( hasResolvedTerms ) {
- const newValues = ( terms ?? [] ).map( ( term ) =>
- unescapeString( term.name )
- );
-
- setValues( newValues );
- }
- }, [ terms, hasResolvedTerms ] );
-
- const suggestions = useMemo( () => {
- return ( searchResults ?? [] ).map( ( term ) =>
- unescapeString( term.name )
- );
- }, [ searchResults ] );
-
- const { saveEntityRecord, editEntityRecord, invalidateResolution } =
- useDispatch( coreStore );
- const { createErrorNotice } = useDispatch( noticesStore );
-
- if ( ! hasAssignAction ) {
- return null;
- }
-
- async function findOrCreateTerm( term ) {
- try {
- const newTerm = await saveEntityRecord( 'taxonomy', slug, term, {
- throwOnError: true,
- } );
- invalidateResolution( 'getUserPatternCategories' );
- return unescapeTerm( newTerm );
- } catch ( error ) {
- if ( error.code !== 'term_exists' ) {
- throw error;
- }
-
- return {
- id: error.data.term_id,
- name: term.name,
- };
- }
- }
-
- function onUpdateTerms( newTermIds ) {
- editEntityRecord( 'postType', PATTERN_TYPES.user, post.id, {
- wp_pattern_category: newTermIds,
- } );
- }
-
- function onChange( termNames ) {
- const availableTerms = [
- ...( terms ?? [] ),
- ...( searchResults ?? [] ),
- ];
- const uniqueTerms = termNames.reduce( ( acc, name ) => {
- if (
- ! acc.some( ( n ) => n.toLowerCase() === name.toLowerCase() )
- ) {
- acc.push( name );
- }
- return acc;
- }, [] );
-
- const newTermNames = uniqueTerms.filter(
- ( termName ) =>
- ! availableTerms.find( ( term ) =>
- isSameTermName( term.name, termName )
- )
- );
-
- // Optimistically update term values.
- // The selector will always re-fetch terms later.
- setValues( uniqueTerms );
-
- if ( newTermNames.length === 0 ) {
- return onUpdateTerms(
- termNamesToIds( uniqueTerms, availableTerms )
- );
- }
-
- if ( ! hasCreateAction ) {
- return;
- }
-
- Promise.all(
- newTermNames.map( ( termName ) =>
- findOrCreateTerm( { name: termName } )
- )
- )
- .then( ( newTerms ) => {
- const newAvailableTerms = availableTerms.concat( newTerms );
- return onUpdateTerms(
- termNamesToIds( uniqueTerms, newAvailableTerms )
- );
- } )
- .catch( ( error ) => {
- createErrorNotice( error.message, {
- type: 'snackbar',
- } );
- } );
- }
-
- const singularName =
- taxonomy?.labels?.singular_name ??
- ( slug === 'post_tag' ? __( 'Tag' ) : __( 'Term' ) );
- const termAddedLabel = sprintf(
- /* translators: %s: term name. */
- _x( '%s added', 'term' ),
- singularName
- );
- const termRemovedLabel = sprintf(
- /* translators: %s: term name. */
- _x( '%s removed', 'term' ),
- singularName
- );
- const removeTermLabel = sprintf(
- /* translators: %s: term name. */
- _x( 'Remove %s', 'term' ),
- singularName
- );
-
- return (
-
-
-
-
-
- );
-}
diff --git a/packages/editor/src/components/index.js b/packages/editor/src/components/index.js
index a16c01c8c166ad..4a0dfac03dd5ac 100644
--- a/packages/editor/src/components/index.js
+++ b/packages/editor/src/components/index.js
@@ -68,6 +68,7 @@ export { default as PostTaxonomies } from './post-taxonomies';
export { FlatTermSelector as PostTaxonomiesFlatTermSelector } from './post-taxonomies/flat-term-selector';
export { HierarchicalTermSelector as PostTaxonomiesHierarchicalTermSelector } from './post-taxonomies/hierarchical-term-selector';
export { default as PostTaxonomiesCheck } from './post-taxonomies/check';
+export { default as PostTaxonomiesPanel } from './post-taxonomies/panel';
export { default as PostTextEditor } from './post-text-editor';
export { default as PostTitle } from './post-title';
export { default as PostTitleRaw } from './post-title/post-title-raw';
diff --git a/packages/edit-post/src/components/sidebar/post-taxonomies/taxonomy-panel.js b/packages/editor/src/components/post-taxonomies/panel.js
similarity index 66%
rename from packages/edit-post/src/components/sidebar/post-taxonomies/taxonomy-panel.js
rename to packages/editor/src/components/post-taxonomies/panel.js
index 4b3bab1fcf3442..a2c2d175246403 100644
--- a/packages/edit-post/src/components/sidebar/post-taxonomies/taxonomy-panel.js
+++ b/packages/editor/src/components/post-taxonomies/panel.js
@@ -3,7 +3,13 @@
*/
import { PanelBody } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
-import { store as editorStore } from '@wordpress/editor';
+
+/**
+ * Internal dependencies
+ */
+import { store as editorStore } from '../../store';
+import PostTaxonomiesForm from './index';
+import PostTaxonomiesCheck from './check';
function TaxonomyPanel( { taxonomy, children } ) {
const slug = taxonomy?.slug;
@@ -41,4 +47,20 @@ function TaxonomyPanel( { taxonomy, children } ) {
);
}
-export default TaxonomyPanel;
+function PostTaxonomies() {
+ return (
+
+ {
+ return (
+
+ { content }
+
+ );
+ } }
+ />
+
+ );
+}
+
+export default PostTaxonomies;