diff --git a/packages/dataviews/src/components/dataviews/style.scss b/packages/dataviews/src/components/dataviews/style.scss index bd75a1ff9e2a18..a357679bef1eb9 100644 --- a/packages/dataviews/src/components/dataviews/style.scss +++ b/packages/dataviews/src/components/dataviews/style.scss @@ -60,6 +60,16 @@ color: var(--wp-admin-theme-color); } } + + &.dataviews-view-grid__primary-field--clickable span, + > .dataviews-view-table__cell-content--clickable span { + color: $gray-900; + + &:hover { + color: var(--wp-admin-theme-color); + } + @include link-reset(); + } } .dataviews-view-list__primary-field--clickable, diff --git a/packages/edit-site/src/components/page-patterns/fields.js b/packages/edit-site/src/components/page-patterns/fields.js index 60e37844b2edb1..f202664389f0ff 100644 --- a/packages/edit-site/src/components/page-patterns/fields.js +++ b/packages/edit-site/src/components/page-patterns/fields.js @@ -6,21 +6,15 @@ import clsx from 'clsx'; /** * WordPress dependencies */ -import { - __experimentalHStack as HStack, - Button, - Tooltip, - FlexBlock, -} from '@wordpress/components'; +import { __experimentalHStack as HStack } from '@wordpress/components'; import { __, _x } from '@wordpress/i18n'; import { useState, useMemo, useId } from '@wordpress/element'; import { BlockPreview, privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; -import { Icon, lockSmall } from '@wordpress/icons'; +import { Icon } from '@wordpress/icons'; import { parse } from '@wordpress/blocks'; -import { decodeEntities } from '@wordpress/html-entities'; import { privateApis as routerPrivateApis } from '@wordpress/router'; /** @@ -112,57 +106,6 @@ export const previewField = { enableSorting: false, }; -function TitleField( { item } ) { - const isUserPattern = item.type === PATTERN_TYPES.user; - const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; - const { onClick } = useLink( - `/${ item.type }/${ - isUserPattern || isTemplatePart ? item.id : item.name - }?canvas=edit` - ); - const title = decodeEntities( defaultGetTitle( item ) ); - return ( - - - { item.type === PATTERN_TYPES.theme ? ( - title - ) : ( - - ) } - - { item.type === PATTERN_TYPES.theme && ( - - - - ) } - - ); -} - -export const titleField = { - label: __( 'Title' ), - id: 'title', - getValue: ( { item } ) => item.title?.raw || item.title, - render: TitleField, - enableHiding: false, -}; - const SYNC_FILTERS = [ { value: PATTERN_SYNC_TYPES.full, diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js index b6753334887573..9a4dedca098030 100644 --- a/packages/edit-site/src/components/page-patterns/index.js +++ b/packages/edit-site/src/components/page-patterns/index.js @@ -9,6 +9,7 @@ import { usePrevious } from '@wordpress/compose'; import { useEntityRecords } from '@wordpress/core-data'; import { privateApis as editorPrivateApis } from '@wordpress/editor'; import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { patternTitleField } from '@wordpress/fields'; /** * Internal dependencies @@ -29,13 +30,12 @@ import { useEditPostAction } from '../dataviews-actions'; import { patternStatusField, previewField, - titleField, templatePartAuthorField, } from './fields'; const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis ); const { usePostActions } = unlock( editorPrivateApis ); -const { useLocation } = unlock( routerPrivateApis ); +const { useLocation, useHistory } = unlock( routerPrivateApis ); const EMPTY_ARRAY = []; const defaultLayouts = { @@ -74,6 +74,7 @@ export default function DataviewsPatterns() { const { query: { postType = 'wp_block', categoryId: categoryIdFromURL }, } = useLocation(); + const history = useHistory(); const categoryId = categoryIdFromURL || PATTERN_DEFAULT_CATEGORY; const [ view, setView ] = useState( DEFAULT_VIEW ); const previousCategoryId = usePrevious( categoryId ); @@ -105,7 +106,7 @@ export default function DataviewsPatterns() { }, [ records ] ); const fields = useMemo( () => { - const _fields = [ previewField, titleField ]; + const _fields = [ previewField, patternTitleField ]; if ( postType === PATTERN_TYPES.user ) { _fields.push( patternStatusField ); @@ -183,6 +184,21 @@ export default function DataviewsPatterns() { data={ dataWithPermissions || EMPTY_ARRAY } getItemId={ ( item ) => item.name ?? item.id } isLoading={ isResolving } + isItemClickable={ ( item ) => + item.type !== PATTERN_TYPES.theme + } + onClickItem={ ( item ) => { + history.navigate( + `/${ item.type }/${ + [ + PATTERN_TYPES.user, + TEMPLATE_PART_POST_TYPE, + ].includes( item.type ) + ? item.id + : item.name + }?canvas=edit` + ); + } } view={ view } onChangeView={ setView } defaultLayouts={ defaultLayouts } diff --git a/packages/edit-site/src/components/page-patterns/style.scss b/packages/edit-site/src/components/page-patterns/style.scss index d59cce420202ee..72d53c2a721afc 100644 --- a/packages/edit-site/src/components/page-patterns/style.scss +++ b/packages/edit-site/src/components/page-patterns/style.scss @@ -71,34 +71,6 @@ } } -.edit-site-patterns__pattern-title { - display: block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - color: inherit; - - .is-link { - text-decoration: none; - color: $gray-200; - - &:hover, - &:focus { - color: $white; - } - } - - .edit-site-patterns__pattern-icon { - border-radius: $grid-unit-05; - background: var(--wp-block-synced-color); - fill: $white; - } - - .edit-site-patterns__pattern-lock-icon { - fill: currentcolor; - } -} - .edit-site-page-patterns-dataviews { .dataviews-view-grid__badge-fields { .dataviews-view-grid__field-value:has(.edit-site-patterns__field-sync-status-fully) { diff --git a/packages/edit-site/src/components/post-list/style.scss b/packages/edit-site/src/components/post-list/style.scss index 14bb11b41d4450..8ff7e31c79dd6f 100644 --- a/packages/edit-site/src/components/post-list/style.scss +++ b/packages/edit-site/src/components/post-list/style.scss @@ -65,42 +65,6 @@ } } -.edit-site-post-list__title span { - text-overflow: ellipsis; - overflow: hidden; -} - -.dataviews-view-grid__primary-field.dataviews-view-grid__primary-field--clickable -.edit-site-post-list__title -span, -.dataviews-view-table__primary-field > .dataviews-view-table__cell-content--clickable -.edit-site-post-list__title -span { - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - display: block; - flex-grow: 0; - color: $gray-900; - - &:hover { - color: var(--wp-admin-theme-color); - } - @include link-reset(); -} - -.edit-site-post-list__title-badge { - background: $gray-100; - color: $gray-800; - padding: 0 $grid-unit-05; - border-radius: $radius-small; - font-size: 12px; - font-weight: 400; - flex-shrink: 0; - line-height: $grid-unit-05 * 5; -} - .edit-site-post-list__status-icon { height: $grid-unit-30; width: $grid-unit-30; diff --git a/packages/editor/src/dataviews/store/private-actions.ts b/packages/editor/src/dataviews/store/private-actions.ts index 9e8d184e34d3a4..1316aaabe1bdd5 100644 --- a/packages/editor/src/dataviews/store/private-actions.ts +++ b/packages/editor/src/dataviews/store/private-actions.ts @@ -4,13 +4,6 @@ import { store as coreStore } from '@wordpress/core-data'; import type { Action, Field } from '@wordpress/dataviews'; import { doAction } from '@wordpress/hooks'; - -/** - * Internal dependencies - */ -import type { PostType } from '../types'; -import { store as editorStore } from '../../store'; -import { unlock } from '../../lock-unlock'; import { viewPost, viewPostRevisions, @@ -33,8 +26,30 @@ import { statusField, authorField, titleField, + templateTitleField, + pageTitleField, } from '@wordpress/fields'; + +/** + * Internal dependencies + */ +import type { PostType } from '../types'; +import { store as editorStore } from '../../store'; +import { unlock } from '../../lock-unlock'; import duplicateTemplatePart from '../actions/duplicate-template-part'; +import { + NAVIGATION_POST_TYPE, + PATTERN_POST_TYPE, + TEMPLATE_PART_POST_TYPE, + TEMPLATE_POST_TYPE, +} from '../../store/constants'; + +const DESIGN_POST_TYPES = [ + PATTERN_POST_TYPE, + TEMPLATE_POST_TYPE, + NAVIGATION_POST_TYPE, + TEMPLATE_PART_POST_TYPE, +]; export function registerEntityAction< Item >( kind: string, @@ -126,6 +141,7 @@ export const registerPostTypeSchema = .resolveSelect( coreStore ) .getCurrentTheme(); + const isDeisgnPostType = DESIGN_POST_TYPES.includes( postType ); const actions = [ postTypeConfig.viewable ? viewPost : undefined, !! postTypeConfig.supports?.revisions @@ -133,25 +149,19 @@ export const registerPostTypeSchema = : undefined, // @ts-ignore globalThis.IS_GUTENBERG_PLUGIN - ? ! [ 'wp_template', 'wp_block', 'wp_template_part' ].includes( - postTypeConfig.slug - ) && - canCreate && - duplicatePost + ? ! isDeisgnPostType && canCreate && duplicatePost : undefined, postTypeConfig.slug === 'wp_template_part' && canCreate && currentTheme?.is_block_theme ? duplicateTemplatePart : undefined, - canCreate && postTypeConfig.slug === 'wp_block' - ? duplicatePattern - : undefined, + canCreate && postType === 'wp_block' ? duplicatePattern : undefined, postTypeConfig.supports?.title ? renamePost : undefined, postTypeConfig.supports?.[ 'page-attributes' ] ? reorderPage : undefined, - postTypeConfig.slug === 'wp_block' ? exportPattern : undefined, + postType === 'wp_block' ? exportPattern : undefined, restorePost, resetPost, deletePost, @@ -163,14 +173,17 @@ export const registerPostTypeSchema = postTypeConfig.supports?.thumbnail && currentTheme?.[ 'theme-supports' ]?.[ 'post-thumbnails' ] && featuredImageField, - titleField, + ! isDeisgnPostType && + postTypeConfig.supports?.title && + ( postType === 'page' ? pageTitleField : titleField ), + postType === TEMPLATE_POST_TYPE && templateTitleField, postTypeConfig.supports?.author && authorField, statusField, dateField, slugField, postTypeConfig.supports?.[ 'page-attributes' ] && parentField, postTypeConfig.supports?.comments && commentStatusField, - passwordField, + ! isDeisgnPostType && passwordField, ].filter( Boolean ); registry.batch( () => { diff --git a/packages/fields/README.md b/packages/fields/README.md index 5993fae4e01175..a1785c4161d08d 100644 --- a/packages/fields/README.md +++ b/packages/fields/README.md @@ -58,6 +58,10 @@ Undocumented declaration. Undocumented declaration. +### pageTitleField + +Undocumented declaration. + ### parentField This field is used to display the post parent. @@ -66,6 +70,10 @@ This field is used to display the post parent. This field is used to display the post password. +### patternTitleField + +Undocumented declaration. + ### permanentlyDeletePost Undocumented declaration. diff --git a/packages/fields/src/fields/index.ts b/packages/fields/src/fields/index.ts index f6390a6075371a..600d161a9e259a 100644 --- a/packages/fields/src/fields/index.ts +++ b/packages/fields/src/fields/index.ts @@ -1,6 +1,8 @@ export { default as slugField } from './slug'; export { default as titleField } from './title'; +export { default as pageTitleField } from './page-title'; export { default as templateTitleField } from './template-title'; +export { default as patternTitleField } from './pattern-title'; export { default as orderField } from './order'; export { default as featuredImageField } from './featured-image'; export { default as parentField } from './parent'; diff --git a/packages/fields/src/fields/page-title/index.ts b/packages/fields/src/fields/page-title/index.ts new file mode 100644 index 00000000000000..533eb8f591dc07 --- /dev/null +++ b/packages/fields/src/fields/page-title/index.ts @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import type { Field } from '@wordpress/dataviews'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import type { BasePost } from '../../types'; +import { getItemTitle } from '../../actions/utils'; +import PageTitleView from './view'; + +const pageTitleField: Field< BasePost > = { + type: 'text', + id: 'title', + label: __( 'Title' ), + placeholder: __( 'No title' ), + getValue: ( { item } ) => getItemTitle( item ), + render: PageTitleView, + enableHiding: false, + enableGlobalSearch: true, +}; + +export default pageTitleField; diff --git a/packages/fields/src/fields/page-title/style.scss b/packages/fields/src/fields/page-title/style.scss new file mode 100644 index 00000000000000..5ccb2ccaf9bf35 --- /dev/null +++ b/packages/fields/src/fields/page-title/style.scss @@ -0,0 +1,10 @@ +.fields-title-field__badge { + background: $gray-100; + color: $gray-800; + padding: 0 $grid-unit-05; + border-radius: $radius-small; + font-size: 12px; + font-weight: 400; + flex-shrink: 0; + line-height: $grid-unit-05 * 5; +} diff --git a/packages/fields/src/fields/page-title/view.tsx b/packages/fields/src/fields/page-title/view.tsx new file mode 100644 index 00000000000000..ea517feaf00377 --- /dev/null +++ b/packages/fields/src/fields/page-title/view.tsx @@ -0,0 +1,38 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; +import type { Settings } from '@wordpress/core-data'; + +/** + * Internal dependencies + */ +import type { CommonPost } from '../../types'; +import { BaseTitleView } from '../title/view'; + +export default function PageTitleView( { item }: { item: CommonPost } ) { + const { frontPageId, postsPageId } = useSelect( ( select ) => { + const { getEntityRecord } = select( coreStore ); + const siteSettings = getEntityRecord( + 'root', + 'site' + ) as Partial< Settings >; + return { + frontPageId: siteSettings?.page_on_front, + postsPageId: siteSettings?.page_for_posts, + }; + }, [] ); + return ( + + { [ frontPageId, postsPageId ].includes( item.id as number ) && ( + + { item.id === frontPageId + ? __( 'Homepage' ) + : __( 'Posts Page' ) } + + ) } + + ); +} diff --git a/packages/fields/src/fields/pattern-title/index.ts b/packages/fields/src/fields/pattern-title/index.ts new file mode 100644 index 00000000000000..ba8e4e2cab590d --- /dev/null +++ b/packages/fields/src/fields/pattern-title/index.ts @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import type { Field } from '@wordpress/dataviews'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import type { Pattern } from '../../types'; +import { getItemTitle } from '../../actions/utils'; +import PatternTitleView from './view'; + +const patternTitleField: Field< Pattern > = { + type: 'text', + id: 'title', + label: __( 'Title' ), + placeholder: __( 'No title' ), + getValue: ( { item } ) => getItemTitle( item ), + render: PatternTitleView, + enableHiding: false, + enableGlobalSearch: true, +}; + +export default patternTitleField; diff --git a/packages/fields/src/fields/pattern-title/style.scss b/packages/fields/src/fields/pattern-title/style.scss new file mode 100644 index 00000000000000..cd7944f259294e --- /dev/null +++ b/packages/fields/src/fields/pattern-title/style.scss @@ -0,0 +1,3 @@ +.fields-title-field span:first-child { + flex: 1; +} diff --git a/packages/fields/src/fields/pattern-title/view.tsx b/packages/fields/src/fields/pattern-title/view.tsx new file mode 100644 index 00000000000000..26ee622d00ee5e --- /dev/null +++ b/packages/fields/src/fields/pattern-title/view.tsx @@ -0,0 +1,36 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Icon, lockSmall } from '@wordpress/icons'; +import { Tooltip } from '@wordpress/components'; +// @ts-ignore +import { privateApis as patternPrivateApis } from '@wordpress/patterns'; + +/** + * Internal dependencies + */ +import type { CommonPost } from '../../types'; +import { BaseTitleView } from '../title/view'; +import { unlock } from '../../lock-unlock'; + +export const { PATTERN_TYPES } = unlock( patternPrivateApis ); + +export default function PatternTitleView( { item }: { item: CommonPost } ) { + return ( + + { item.type === PATTERN_TYPES.theme && ( + + + + ) } + + ); +} diff --git a/packages/fields/src/fields/template-title/index.ts b/packages/fields/src/fields/template-title/index.ts index b45c5007151dc4..1854c64b49985f 100644 --- a/packages/fields/src/fields/template-title/index.ts +++ b/packages/fields/src/fields/template-title/index.ts @@ -12,6 +12,7 @@ import { getItemTitle } from '../../actions/utils'; import TitleView from '../title/view'; const templateTitleField: Field< Template > = { + type: 'text', label: __( 'Template' ), id: 'title', getValue: ( { item } ) => getItemTitle( item ), diff --git a/packages/fields/src/fields/title/index.ts b/packages/fields/src/fields/title/index.ts index bc6d7759ad5299..5295f507dce6a0 100644 --- a/packages/fields/src/fields/title/index.ts +++ b/packages/fields/src/fields/title/index.ts @@ -7,18 +7,19 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { BasePost } from '../../types'; +import type { CommonPost } from '../../types'; import { getItemTitle } from '../../actions/utils'; -import { PostTitleView } from './view'; +import TitleView from './view'; -const titleField: Field< BasePost > = { +const titleField: Field< CommonPost > = { type: 'text', id: 'title', label: __( 'Title' ), placeholder: __( 'No title' ), getValue: ( { item } ) => getItemTitle( item ), - render: PostTitleView, + render: TitleView, enableHiding: false, + enableGlobalSearch: true, }; export default titleField; diff --git a/packages/fields/src/fields/title/style.scss b/packages/fields/src/fields/title/style.scss new file mode 100644 index 00000000000000..764637b190ff65 --- /dev/null +++ b/packages/fields/src/fields/title/style.scss @@ -0,0 +1,8 @@ +.fields-title-field span:first-child { + text-overflow: ellipsis; + overflow: hidden; + text-decoration: none; + white-space: nowrap; + display: block; + flex-grow: 0; +} diff --git a/packages/fields/src/fields/title/view.tsx b/packages/fields/src/fields/title/view.tsx index 581d17b9a2abd9..7e73d36f5d2dbf 100644 --- a/packages/fields/src/fields/title/view.tsx +++ b/packages/fields/src/fields/title/view.tsx @@ -8,9 +8,6 @@ import type { ReactNode } from 'react'; */ import { __experimentalHStack as HStack } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useSelect } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; -import type { Settings } from '@wordpress/core-data'; /** * Internal dependencies @@ -18,35 +15,6 @@ import type { Settings } from '@wordpress/core-data'; import type { CommonPost } from '../../types'; import { getItemTitle } from '../../actions/utils'; -export function PostTitleView( { item }: { item: CommonPost } ) { - const { frontPageId, postsPageId } = useSelect( ( select ) => { - const { getEntityRecord } = select( coreStore ); - const siteSettings = getEntityRecord( - 'root', - 'site' - ) as Partial< Settings >; - return { - frontPageId: siteSettings?.page_on_front, - postsPageId: siteSettings?.page_for_posts, - }; - }, [] ); - let suffix; - if ( item.id === frontPageId ) { - suffix = ( - - { __( 'Homepage' ) } - - ); - } else if ( item.id === postsPageId ) { - suffix = ( - - { __( 'Posts Page' ) } - - ); - } - return { suffix }; -} - export function BaseTitleView( { item, children, @@ -57,7 +25,7 @@ export function BaseTitleView( { const renderedTitle = getItemTitle( item ); return ( diff --git a/packages/fields/src/style.scss b/packages/fields/src/style.scss index 1639f455ba093e..309733d9e8ed68 100644 --- a/packages/fields/src/style.scss +++ b/packages/fields/src/style.scss @@ -1,2 +1,5 @@ @import "./fields/slug/style.scss"; @import "./fields/featured-image/style.scss"; +@import "./fields/title/style.scss"; +@import "./fields/page-title/style.scss"; +@import "./fields/pattern-title/style.scss";