From 83ea11fa126dcad2467f5bdec1a191ee7ccb3b97 Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Fri, 30 Jun 2023 22:59:53 +0300 Subject: [PATCH 01/35] Footnotes: inscrease selector specificity for anchor (#52179) --- packages/block-library/src/footnotes/style.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/footnotes/style.scss b/packages/block-library/src/footnotes/style.scss index b5540b70e6f0fd..4debba0560f173 100644 --- a/packages/block-library/src/footnotes/style.scss +++ b/packages/block-library/src/footnotes/style.scss @@ -3,7 +3,7 @@ counter-reset: footnotes; } -.fn { +[data-fn].fn { vertical-align: super; font-size: smaller; counter-increment: footnotes; @@ -11,7 +11,7 @@ text-indent: -9999999px; } -.fn::after { +[data-fn].fn::after { content: "[" counter(footnotes) "]"; text-indent: 0; float: left; From 2e8830c15f5b710181c7b44c2c1645f888d910e0 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Mon, 3 Jul 2023 11:31:42 +1000 Subject: [PATCH 02/35] Patterns: Include template parts for custom areas in Uncategorized category (#52159) --- .../src/components/page-library/use-patterns.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/page-library/use-patterns.js b/packages/edit-site/src/components/page-library/use-patterns.js index 9034dc43421fc0..5b66f0efe82c99 100644 --- a/packages/edit-site/src/components/page-library/use-patterns.js +++ b/packages/edit-site/src/components/page-library/use-patterns.js @@ -38,6 +38,15 @@ const templatePartToPattern = ( templatePart ) => ( { templatePart, } ); +const templatePartCategories = [ 'header', 'footer', 'sidebar' ]; +const templatePartHasCategory = ( item, category ) => { + if ( category === 'uncategorized' ) { + return ! templatePartCategories.includes( item.templatePart.area ); + } + + return item.templatePart.area === category; +}; + const useTemplatePartsAsPatterns = ( categoryId, postType = TEMPLATE_PARTS, @@ -83,7 +92,7 @@ const useTemplatePartsAsPatterns = ( return searchItems( templateParts, filterValue, { categoryId, - hasCategory: ( item, area ) => item.templatePart.area === area, + hasCategory: templatePartHasCategory, } ); }, [ templateParts, filterValue, categoryId ] ); From db158846230eb4c40c0f29f82887dc2613670c03 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 28 Jun 2023 18:33:07 +1200 Subject: [PATCH 03/35] Fix custom patterns console error (#51947) * Fix error with react list key with new custom patterns list in inserter * Update placeholder key * Add comment to explain the different keys * Patterns: Fix missing custom patterns in patterns explorer (#51889) * Add custom patterns to pattern explorer * show custom patterns in the patterns explorer dialog * remove changes from 51877 * Fix up use of async lists * remove a bit of code duplication by adding a new hook * add 51877 fix back to make testing easier * Just assign the key value in one place * Refactor the custom patterns to use the usePatternsState hook * Fix use of async list * Translate strings and remove unneeded fields from pattern object * Try integrating unsynced patterns directly into pattern selectors (#51955) * Include reusable blocks with an undefined sync status in inserter items * Update docs * Remove change to hover dependencies --------- Co-authored-by: Daniel Richards --- .../data/data-core-block-editor.md | 1 - .../block-patterns-explorer/patterns-list.js | 10 ++- .../components/inserter/block-patterns-tab.js | 63 ++-------------- .../inserter/hooks/use-block-types-state.js | 7 +- .../inserter/hooks/use-patterns-state.js | 54 +++++++++----- packages/block-editor/src/store/selectors.js | 71 +++++++++++++------ 6 files changed, 104 insertions(+), 102 deletions(-) diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index 20d6ebfe5291aa..8b0f24e60fb7bf 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -538,7 +538,6 @@ _Parameters_ - _state_ `Object`: Editor state. - _rootClientId_ `?string`: Optional root client ID of block list. -- _syncStatus_ `?string`: Optional sync status to filter pattern blocks by. _Returns_ diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/patterns-list.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/patterns-list.js index a4e3c91cba4ba2..fda1a00c1a07dc 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/patterns-list.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/patterns-list.js @@ -52,6 +52,7 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { onInsertBlocks, destinationRootClientId ); + const registeredPatternCategories = useMemo( () => patternCategories.map( @@ -75,7 +76,12 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { ); } return searchItems( allPatterns, filterValue ); - }, [ filterValue, selectedCategory, allPatterns ] ); + }, [ + filterValue, + allPatterns, + selectedCategory, + registeredPatternCategories, + ] ); // Announce search results on change. useEffect( () => { @@ -89,7 +95,7 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { count ); debouncedSpeak( resultsFoundMessage ); - }, [ filterValue, debouncedSpeak ] ); + }, [ filterValue, debouncedSpeak, filteredBlockPatterns.length ] ); const currentShownPatterns = useAsyncList( filteredBlockPatterns, { step: INITIAL_INSERTER_RESULTS, diff --git a/packages/block-editor/src/components/inserter/block-patterns-tab.js b/packages/block-editor/src/components/inserter/block-patterns-tab.js index 578791e8802692..5c2720fd0502e3 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -18,7 +18,6 @@ import { Button, } from '@wordpress/components'; import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; -import { parse } from '@wordpress/blocks'; import { focus } from '@wordpress/dom'; /** @@ -28,7 +27,6 @@ import usePatternsState from './hooks/use-patterns-state'; import BlockPatternList from '../block-patterns-list'; import PatternsExplorerModal from './block-patterns-explorer/explorer'; import MobileTabNavigation from './mobile-tab-navigation'; -import useBlockTypesState from './hooks/use-block-types-state'; const noop = () => {}; @@ -51,18 +49,6 @@ function usePatternsCategories( rootClientId ) { rootClientId ); - const [ unsyncedPatterns ] = useBlockTypesState( - rootClientId, - undefined, - 'unsynced' - ); - - const filteredUnsyncedPatterns = useMemo( () => { - return unsyncedPatterns.filter( - ( { category: unsyncedPatternCategory } ) => - unsyncedPatternCategory === 'reusable' - ); - }, [ unsyncedPatterns ] ); const hasRegisteredCategory = useCallback( ( pattern ) => { if ( ! pattern.categories || ! pattern.categories.length ) { @@ -107,20 +93,9 @@ function usePatternsCategories( rootClientId ) { label: _x( 'Uncategorized' ), } ); } - if ( filteredUnsyncedPatterns.length > 0 ) { - categories.push( { - name: 'reusable', - label: _x( 'Custom patterns' ), - } ); - } return categories; - }, [ - allCategories, - allPatterns, - filteredUnsyncedPatterns.length, - hasRegisteredCategory, - ] ); + }, [ allCategories, allPatterns, hasRegisteredCategory ] ); return populatedCategories; } @@ -169,24 +144,6 @@ export function BlockPatternsCategoryPanel( { onInsert, rootClientId ); - const [ unsyncedPatterns ] = useBlockTypesState( - rootClientId, - onInsert, - 'unsynced' - ); - const filteredUnsyncedPatterns = useMemo( () => { - return unsyncedPatterns - .filter( - ( { category: unsyncedPatternCategory } ) => - unsyncedPatternCategory === 'reusable' - ) - .map( ( syncedPattern ) => ( { - ...syncedPattern, - blocks: parse( syncedPattern.content, { - __unstableSkipMigrationLogs: true, - } ), - } ) ); - }, [ unsyncedPatterns ] ); const availableCategories = usePatternsCategories( rootClientId ); const currentCategoryPatterns = useMemo( @@ -208,21 +165,15 @@ export function BlockPatternsCategoryPanel( { return availablePatternCategories.length === 0; } ), - [ allPatterns, category ] + [ allPatterns, availableCategories, category.name ] ); - const patterns = - category.name === 'reusable' - ? filteredUnsyncedPatterns - : currentCategoryPatterns; - const currentShownPatterns = useAsyncList( patterns ); + + const categoryPatternsList = useAsyncList( currentCategoryPatterns ); // Hide block pattern preview on unmount. useEffect( () => () => onHover( null ), [] ); - if ( - ! currentCategoryPatterns.length && - ! filteredUnsyncedPatterns.length - ) { + if ( ! currentCategoryPatterns.length ) { return null; } @@ -233,8 +184,8 @@ export function BlockPatternsCategoryPanel( {

{ category.description }

{ +const useBlockTypesState = ( rootClientId, onInsert ) => { const { categories, collections, items } = useSelect( ( select ) => { const { getInserterItems } = select( blockEditorStore ); @@ -31,10 +30,10 @@ const useBlockTypesState = ( rootClientId, onInsert, syncStatus ) => { return { categories: getCategories(), collections: getCollections(), - items: getInserterItems( rootClientId, syncStatus ), + items: getInserterItems( rootClientId ), }; }, - [ rootClientId, syncStatus ] + [ rootClientId ] ); const onSelectItem = useCallback( diff --git a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js index ca287b95c43b9b..2a99e637ed1237 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { useCallback } from '@wordpress/element'; +import { useCallback, useMemo } from '@wordpress/element'; import { cloneBlock } from '@wordpress/blocks'; import { useDispatch, useSelect } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; @@ -12,6 +12,12 @@ import { store as noticesStore } from '@wordpress/notices'; */ import { store as blockEditorStore } from '../../../store'; +const CUSTOM_CATEGORY = { + name: 'custom', + label: __( 'Custom patterns' ), + description: __( 'Custom patterns add by site users' ), +}; + /** * Retrieves the block patterns inserter state. * @@ -25,6 +31,7 @@ const usePatternsState = ( onInsert, rootClientId ) => { ( select ) => { const { __experimentalGetAllowedPatterns, getSettings } = select( blockEditorStore ); + return { patterns: __experimentalGetAllowedPatterns( rootClientId ), patternCategories: @@ -33,25 +40,34 @@ const usePatternsState = ( onInsert, rootClientId ) => { }, [ rootClientId ] ); + + const allCategories = useMemo( + () => [ ...patternCategories, CUSTOM_CATEGORY ], + [ patternCategories ] + ); + const { createSuccessNotice } = useDispatch( noticesStore ); - const onClickPattern = useCallback( ( pattern, blocks ) => { - onInsert( - ( blocks ?? [] ).map( ( block ) => cloneBlock( block ) ), - pattern.name - ); - createSuccessNotice( - sprintf( - /* translators: %s: block pattern title. */ - __( 'Block pattern "%s" inserted.' ), - pattern.title - ), - { - type: 'snackbar', - } - ); - }, [] ); - - return [ patterns, patternCategories, onClickPattern ]; + const onClickPattern = useCallback( + ( pattern, blocks ) => { + onInsert( + ( blocks ?? [] ).map( ( block ) => cloneBlock( block ) ), + pattern.name + ); + createSuccessNotice( + sprintf( + /* translators: %s: block pattern title. */ + __( 'Block pattern "%s" inserted.' ), + pattern.title + ), + { + type: 'snackbar', + } + ); + }, + [ createSuccessNotice, onInsert ] + ); + + return [ patterns, allCategories, onClickPattern ]; }; export default usePatternsState; diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 05d00f65b1fd34..fc314636d11951 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1945,7 +1945,6 @@ const buildBlockTypeItem = * * @param {Object} state Editor state. * @param {?string} rootClientId Optional root client ID of block list. - * @param {?string} syncStatus Optional sync status to filter pattern blocks by. * * @return {WPEditorInserterItem[]} Items that appear in inserter. * @@ -1962,11 +1961,7 @@ const buildBlockTypeItem = * @property {number} frecency Heuristic that combines frequency and recency. */ export const getInserterItems = createSelector( - ( state, rootClientId = null, syncStatus ) => { - const buildBlockTypeInserterItem = buildBlockTypeItem( state, { - buildScope: 'inserter', - } ); - + ( state, rootClientId = null ) => { /* * Matches block comment delimiters amid serialized content. * @@ -2031,13 +2026,7 @@ export const getInserterItems = createSelector( }; }; - const blockTypeInserterItems = getBlockTypes() - .filter( ( blockType ) => - canIncludeBlockTypeInInserter( state, blockType, rootClientId ) - ) - .map( buildBlockTypeInserterItem ); - - const reusableBlockInserterItems = canInsertBlockTypeUnmemoized( + const syncedPatternInserterItems = canInsertBlockTypeUnmemoized( state, 'core/block', rootClientId @@ -2045,13 +2034,25 @@ export const getInserterItems = createSelector( ? getReusableBlocks( state ) .filter( ( reusableBlock ) => - syncStatus === reusableBlock.meta?.sync_status || - ( ! syncStatus && - reusableBlock.meta?.sync_status === '' ) + // Filter to either fully synced patterns (sync_status === 'fully'), + // or old school reusable blocks (sync_status === ''). + reusableBlock.meta?.sync_status === 'fully' || + reusableBlock.meta?.sync_status === '' || + ! reusableBlock.meta?.sync_status ) .map( buildReusableBlockInserterItem ) : []; + const buildBlockTypeInserterItem = buildBlockTypeItem( state, { + buildScope: 'inserter', + } ); + + const blockTypeInserterItems = getBlockTypes() + .filter( ( blockType ) => + canIncludeBlockTypeInInserter( state, blockType, rootClientId ) + ) + .map( buildBlockTypeInserterItem ); + const items = blockTypeInserterItems.reduce( ( accumulator, item ) => { const { variations = [] } = item; // Exclude any block type item that is to be replaced by a default variation. @@ -2082,7 +2083,7 @@ export const getInserterItems = createSelector( { core: [], noncore: [] } ); const sortedBlockTypes = [ ...coreItems, ...nonCoreItems ]; - return [ ...sortedBlockTypes, ...reusableBlockInserterItems ]; + return [ ...sortedBlockTypes, ...syncedPatternInserterItems ]; }, ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ], @@ -2306,10 +2307,32 @@ const checkAllowListRecursive = ( blocks, allowedBlockTypes ) => { return true; }; +function getUnsyncedPatterns( state ) { + const reusableBlocks = + state?.settings?.__experimentalReusableBlocks ?? EMPTY_ARRAY; + + return reusableBlocks + .filter( + ( reusableBlock ) => reusableBlock.meta?.sync_status === 'unsynced' + ) + .map( ( reusableBlock ) => { + return { + name: `core/block/${ reusableBlock.id }`, + title: reusableBlock.title.raw, + categories: [ 'custom' ], + content: reusableBlock.content.raw, + }; + } ); +} + export const __experimentalGetParsedPattern = createSelector( ( state, patternName ) => { const patterns = state.settings.__experimentalBlockPatterns; - const pattern = patterns.find( ( { name } ) => name === patternName ); + const unsyncedPatterns = getUnsyncedPatterns( state ); + + const pattern = [ ...patterns, ...unsyncedPatterns ].find( + ( { name } ) => name === patternName + ); if ( ! pattern ) { return null; } @@ -2320,14 +2343,20 @@ export const __experimentalGetParsedPattern = createSelector( } ), }; }, - ( state ) => [ state.settings.__experimentalBlockPatterns ] + ( state ) => [ + state.settings.__experimentalBlockPatterns, + state.settings.__experimentalReusableBlocks, + ] ); const getAllAllowedPatterns = createSelector( ( state ) => { const patterns = state.settings.__experimentalBlockPatterns; + const unsyncedPatterns = getUnsyncedPatterns( state ); + const { allowedBlockTypes } = getSettings( state ); - const parsedPatterns = patterns + + const parsedPatterns = [ ...patterns, ...unsyncedPatterns ] .filter( ( { inserter = true } ) => !! inserter ) .map( ( { name } ) => __experimentalGetParsedPattern( state, name ) @@ -2339,6 +2368,7 @@ const getAllAllowedPatterns = createSelector( }, ( state ) => [ state.settings.__experimentalBlockPatterns, + state.settings.__experimentalReusableBlocks, state.settings.allowedBlockTypes, ] ); @@ -2365,6 +2395,7 @@ export const __experimentalGetAllowedPatterns = createSelector( }, ( state, rootClientId ) => [ state.settings.__experimentalBlockPatterns, + state.settings.__experimentalReusableBlocks, state.settings.allowedBlockTypes, state.settings.templateLock, state.blockListSettings[ rootClientId ], From 6aaf2697918543b301eccb2f0ed29ffc2dc3b9a7 Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Sat, 1 Jul 2023 22:48:04 +0900 Subject: [PATCH 04/35] i18n: Add context to the word "Filters" (#52198) --- .../src/components/global-styles/filters-panel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/global-styles/filters-panel.js b/packages/block-editor/src/components/global-styles/filters-panel.js index e2ee95696d5d49..ef972de3f13cdf 100644 --- a/packages/block-editor/src/components/global-styles/filters-panel.js +++ b/packages/block-editor/src/components/global-styles/filters-panel.js @@ -22,7 +22,7 @@ import { Flex, FlexItem, } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; +import { __, _x } from '@wordpress/i18n'; import { useCallback, useMemo } from '@wordpress/element'; /** @@ -77,7 +77,7 @@ function FiltersToolsPanel( { return ( From 5b1f58090ecd5fc437ccc758db15bb054aece116 Mon Sep 17 00:00:00 2001 From: James Koster Date: Wed, 28 Jun 2023 20:59:09 +0100 Subject: [PATCH 05/35] Update home template icon (#52075) --- .../edit-site/src/components/add-new-template/new-template.js | 4 ++-- .../src/components/sidebar-navigation-screen-pages/index.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/edit-site/src/components/add-new-template/new-template.js b/packages/edit-site/src/components/add-new-template/new-template.js index 0c6ab03899cc81..31ddd754562dbf 100644 --- a/packages/edit-site/src/components/add-new-template/new-template.js +++ b/packages/edit-site/src/components/add-new-template/new-template.js @@ -34,7 +34,7 @@ import { page, plus, pin, - postList, + verse, search, tag, } from '@wordpress/icons'; @@ -78,7 +78,7 @@ const DEFAULT_TEMPLATE_SLUGS = [ const TEMPLATE_ICONS = { 'front-page': home, - home: postList, + home: verse, single: pin, page, archive, diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pages/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-pages/index.js index 8cfd041f36d3cc..567bf91aca69fd 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pages/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-pages/index.js @@ -12,7 +12,7 @@ import { __ } from '@wordpress/i18n'; import { useEntityRecords, store as coreStore } from '@wordpress/core-data'; import { decodeEntities } from '@wordpress/html-entities'; import { privateApis as routerPrivateApis } from '@wordpress/router'; -import { layout, page, home, loop, plus } from '@wordpress/icons'; +import { layout, page, home, verse, plus } from '@wordpress/icons'; import { useSelect } from '@wordpress/data'; /** @@ -159,7 +159,7 @@ export default function SidebarNavigationScreenPages() { itemIcon = home; break; case postsPage: - itemIcon = loop; + itemIcon = verse; break; default: itemIcon = page; From 14c54c5ed83273f1453021ae8b023e5298ca4f1b Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 30 Jun 2023 12:45:22 +0100 Subject: [PATCH 06/35] Centralise all permissions lookup in Link UI and enable (#52166) --- .../block-library/src/navigation-link/edit.js | 16 +--------------- .../block-library/src/navigation-link/link-ui.js | 16 ++++++++++++++-- .../navigation/edit/menu-inspector-controls.js | 1 - 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 539e1c6d92a982..b91015313f4039 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -35,10 +35,7 @@ import { } from '@wordpress/dom'; import { decodeEntities } from '@wordpress/html-entities'; import { link as linkIcon, addSubmenu } from '@wordpress/icons'; -import { - store as coreStore, - useResourcePermissions, -} from '@wordpress/core-data'; +import { store as coreStore } from '@wordpress/core-data'; import { useMergeRefs } from '@wordpress/compose'; /** @@ -184,9 +181,6 @@ export default function NavigationLinkEdit( { const itemLabelPlaceholder = __( 'Add label…' ); const ref = useRef(); - const pagesPermissions = useResourcePermissions( 'pages' ); - const postsPermissions = useResourcePermissions( 'posts' ); - const { innerBlocks, isAtMaxNesting, @@ -322,13 +316,6 @@ export default function NavigationLinkEdit( { setIsLinkOpen( false ); } - let userCanCreate = false; - if ( ! type || type === 'page' ) { - userCanCreate = pagesPermissions.canCreate; - } else if ( type === 'post' ) { - userCanCreate = postsPermissions.canCreate; - } - const { textColor, customTextColor, @@ -589,7 +576,6 @@ export default function NavigationLinkEdit( { link={ attributes } onClose={ () => setIsLinkOpen( false ) } anchor={ popoverAnchor } - hasCreateSuggestion={ userCanCreate } onRemove={ removeLink } onChange={ ( updatedValue ) => { updateAttributes( diff --git a/packages/block-library/src/navigation-link/link-ui.js b/packages/block-library/src/navigation-link/link-ui.js index 782d1fff4a01bf..950cac9cfb87bb 100644 --- a/packages/block-library/src/navigation-link/link-ui.js +++ b/packages/block-library/src/navigation-link/link-ui.js @@ -10,7 +10,10 @@ import { store as blockEditorStore, } from '@wordpress/block-editor'; import { createInterpolateElement, useMemo } from '@wordpress/element'; -import { store as coreStore } from '@wordpress/core-data'; +import { + store as coreStore, + useResourcePermissions, +} from '@wordpress/core-data'; import { decodeEntities } from '@wordpress/html-entities'; import { switchToBlockType } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; @@ -125,6 +128,8 @@ function LinkControlTransforms( { clientId } ) { export function LinkUI( props ) { const { saveEntityRecord } = useDispatch( coreStore ); + const pagesPermissions = useResourcePermissions( 'pages' ); + const postsPermissions = useResourcePermissions( 'posts' ); async function handleCreate( pageTitle ) { const postType = props.link.type || 'page'; @@ -155,6 +160,13 @@ export function LinkUI( props ) { const { label, url, opensInNewTab, type, kind } = props.link; + let userCanCreate = false; + if ( ! type || type === 'page' ) { + userCanCreate = pagesPermissions.canCreate; + } else if ( type === 'post' ) { + userCanCreate = postsPermissions.canCreate; + } + // Memoize link value to avoid overriding the LinkControl's internal state. // This is a temporary fix. See https://github.com/WordPress/gutenberg/issues/50976#issuecomment-1568226407. const link = useMemo( @@ -179,7 +191,7 @@ export function LinkUI( props ) { className={ props.className } value={ link } showInitialSuggestions={ true } - withCreateSuggestion={ props.hasCreateSuggestion } + withCreateSuggestion={ userCanCreate } createSuggestion={ handleCreate } createSuggestionButtonText={ ( searchTerm ) => { let format; diff --git a/packages/block-library/src/navigation/edit/menu-inspector-controls.js b/packages/block-library/src/navigation/edit/menu-inspector-controls.js index 8743b51fc6720c..9fd4bc3e33d41e 100644 --- a/packages/block-library/src/navigation/edit/menu-inspector-controls.js +++ b/packages/block-library/src/navigation/edit/menu-inspector-controls.js @@ -60,7 +60,6 @@ function AdditionalBlockContent( { block, insertedBlock, setInsertedBlock } ) { onClose={ () => { setInsertedBlock( null ); } } - hasCreateSuggestion={ false } onChange={ ( updatedValue ) => { updateAttributes( updatedValue, From 05287662ea56e40a7aad0375205d28b60097d671 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Fri, 30 Jun 2023 11:45:26 +0200 Subject: [PATCH 07/35] BlockRemovalWarningModal: Fix incorrect '_n' usage (#52164) --- .../components/block-removal-warning-modal/index.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/block-removal-warning-modal/index.js b/packages/block-editor/src/components/block-removal-warning-modal/index.js index 2e16d2834d2ce3..2ed65481f68959 100644 --- a/packages/block-editor/src/components/block-removal-warning-modal/index.js +++ b/packages/block-editor/src/components/block-removal-warning-modal/index.js @@ -8,7 +8,7 @@ import { Button, __experimentalHStack as HStack, } from '@wordpress/components'; -import { __, _n } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -75,11 +75,9 @@ export function BlockRemovalWarningModal() { ) }

- { _n( - 'Removing this block is not advised.', - 'Removing these blocks is not advised.', - blockNamesForPrompt.length - ) } + { blockNamesForPrompt.length > 1 + ? __( 'Removing these blocks is not advised.' ) + : __( 'Removing this block is not advised.' ) }

From b0a594329c7978a19c11e4554e14e8c0dc61ce73 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 30 Jun 2023 10:46:24 +0800 Subject: [PATCH 10/35] Fix history back after entering edit mode from Patterns (#52112) --- packages/edit-site/src/components/page-library/grid-item.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/edit-site/src/components/page-library/grid-item.js b/packages/edit-site/src/components/page-library/grid-item.js index 586602d1ac05d3..3022dd1bddae9f 100644 --- a/packages/edit-site/src/components/page-library/grid-item.js +++ b/packages/edit-site/src/components/page-library/grid-item.js @@ -46,7 +46,6 @@ export default function GridItem( { categoryId, composite, icon, item } ) { postId: item.type === USER_PATTERNS ? item.id : item.name, categoryId, categoryType: item.type, - canvas: 'view', } ); const onKeyDown = ( event ) => { From b64bc8a33bcac7b221adf32e4319cc784625b423 Mon Sep 17 00:00:00 2001 From: Carolina Nymark Date: Wed, 28 Jun 2023 13:56:57 +0200 Subject: [PATCH 11/35] Add template part icons to the library grid items (#51963) --- .../src/components/page-library/grid-item.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/page-library/grid-item.js b/packages/edit-site/src/components/page-library/grid-item.js index 3022dd1bddae9f..726f7a9896adc2 100644 --- a/packages/edit-site/src/components/page-library/grid-item.js +++ b/packages/edit-site/src/components/page-library/grid-item.js @@ -20,7 +20,13 @@ import { useInstanceId } from '@wordpress/compose'; import { useDispatch } from '@wordpress/data'; import { useState } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; -import { Icon, moreHorizontal } from '@wordpress/icons'; +import { + Icon, + header, + footer, + symbolFilled, + moreHorizontal, +} from '@wordpress/icons'; import { store as noticesStore } from '@wordpress/notices'; import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; import { DELETE, BACKSPACE } from '@wordpress/keycodes'; @@ -88,6 +94,15 @@ export default function GridItem( { categoryId, composite, icon, item } ) { ariaDescription = item.description; } + let itemIcon = icon; + if ( categoryId === 'header' ) { + itemIcon = header; + } else if ( categoryId === 'footer' ) { + itemIcon = footer; + } else if ( categoryId === 'uncategorized' ) { + itemIcon = symbolFilled; + } + return ( <>
@@ -126,7 +141,7 @@ export default function GridItem( { categoryId, composite, icon, item } ) { spacing={ 3 } className="edit-site-library__pattern-title" > - { icon && } + { icon && } { item.title } { item.type === USER_PATTERNS && ( From 0702768d3bf634d5514ddfecca082dbe0c6f04f0 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Wed, 28 Jun 2023 18:01:42 +1000 Subject: [PATCH 12/35] Patterns: Fix sidebar tab label (#51953) --- .../sidebar-edit-mode/settings-header/index.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-edit-mode/settings-header/index.js b/packages/edit-site/src/components/sidebar-edit-mode/settings-header/index.js index 10ce08e8e7401b..7bc951524e7e5c 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/settings-header/index.js +++ b/packages/edit-site/src/components/sidebar-edit-mode/settings-header/index.js @@ -18,6 +18,12 @@ import { STORE_NAME } from '../../../store/constants'; import { SIDEBAR_BLOCK, SIDEBAR_TEMPLATE } from '../constants'; import { store as editSiteStore } from '../../../store'; +const entityLabels = { + wp_navigation: __( 'Navigation' ), + wp_block: __( 'Pattern' ), + wp_template: __( 'Template' ), +}; + const SettingsHeader = ( { sidebarName } ) => { const { hasPageContentFocus, entityType } = useSelect( ( select ) => { const { getEditedPostType, hasPageContentFocus: _hasPageContentFocus } = @@ -29,8 +35,7 @@ const SettingsHeader = ( { sidebarName } ) => { }; } ); - const entityLabel = - entityType === 'wp_navigation' ? __( 'Navigation' ) : __( 'Template' ); + const entityLabel = entityLabels[ entityType ] || entityLabels.wp_template; const { enableComplementaryArea } = useDispatch( interfaceStore ); const openTemplateSettings = () => From 70fda0642eef0acbda0e56effe625b1b0cbc2dee Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Wed, 28 Jun 2023 17:55:31 +1000 Subject: [PATCH 13/35] Patterns: Fix setting of sync status for fully synced patterns (#51952) --- .../edit-site/src/components/create-pattern-modal/index.js | 5 ++++- .../edit-site/src/components/page-library/use-patterns.js | 2 +- packages/editor/src/components/post-sync-status/index.js | 7 ++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/edit-site/src/components/create-pattern-modal/index.js b/packages/edit-site/src/components/create-pattern-modal/index.js index 2cef6b21ebbbad..5180ad5d870684 100644 --- a/packages/edit-site/src/components/create-pattern-modal/index.js +++ b/packages/edit-site/src/components/create-pattern-modal/index.js @@ -54,7 +54,10 @@ export default function CreatePatternModal( { title: name || __( 'Untitled Pattern' ), content: '', status: 'publish', - meta: { sync_status: syncType }, + meta: + syncType === SYNC_TYPES.unsynced + ? { sync_status: syncType } + : undefined, }, { throwOnError: true } ); diff --git a/packages/edit-site/src/components/page-library/use-patterns.js b/packages/edit-site/src/components/page-library/use-patterns.js index 5b66f0efe82c99..a8d76b58cb45d5 100644 --- a/packages/edit-site/src/components/page-library/use-patterns.js +++ b/packages/edit-site/src/components/page-library/use-patterns.js @@ -154,7 +154,7 @@ const reusableBlockToPattern = ( reusableBlock ) => ( { categories: reusableBlock.wp_pattern, id: reusableBlock.id, name: reusableBlock.slug, - syncStatus: reusableBlock.meta?.sync_status, + syncStatus: reusableBlock.meta?.sync_status || SYNC_TYPES.full, title: reusableBlock.title.raw, type: reusableBlock.type, reusableBlock, diff --git a/packages/editor/src/components/post-sync-status/index.js b/packages/editor/src/components/post-sync-status/index.js index 40476111a82c17..392d33563ef78f 100644 --- a/packages/editor/src/components/post-sync-status/index.js +++ b/packages/editor/src/components/post-sync-status/index.js @@ -26,13 +26,10 @@ export default function PostSyncStatus() { editPost( { meta: { ...meta, - wp_block: - syncStatus === 'unsynced' - ? { sync_status: syncStatus } - : null, + sync_status: syncStatus === 'unsynced' ? syncStatus : null, }, } ); - const syncStatus = meta?.wp_block?.sync_status; + const syncStatus = meta?.sync_status; const isFullySynced = ! syncStatus; return ( From b59ce7c9501a2efa8d2403157b5a60dc538602ea Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Wed, 28 Jun 2023 17:57:09 +1000 Subject: [PATCH 14/35] Library: Reinstate manage all template parts page (#51961) --- .../src/components/page-main/index.js | 5 +- .../components/page-template-parts/index.js | 105 ++++++++++++++++++ .../index.js | 31 +++--- .../index.js | 16 ++- .../index.js | 2 + .../edit-site/src/components/sidebar/index.js | 6 +- .../edit-site/src/utils/get-is-list-page.js | 1 + 7 files changed, 146 insertions(+), 20 deletions(-) create mode 100644 packages/edit-site/src/components/page-template-parts/index.js diff --git a/packages/edit-site/src/components/page-main/index.js b/packages/edit-site/src/components/page-main/index.js index ebcf35dfb0c1f5..a6c05886888c45 100644 --- a/packages/edit-site/src/components/page-main/index.js +++ b/packages/edit-site/src/components/page-main/index.js @@ -6,8 +6,9 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ -import PageTemplates from '../page-templates'; import PageLibrary from '../page-library'; +import PageTemplateParts from '../page-template-parts'; +import PageTemplates from '../page-templates'; import { unlock } from '../../lock-unlock'; const { useLocation } = unlock( routerPrivateApis ); @@ -19,6 +20,8 @@ export default function PageMain() { if ( path === '/wp_template/all' ) { return ; + } else if ( path === '/wp_template_part/all' ) { + return ; } else if ( path === '/library' ) { return ; } diff --git a/packages/edit-site/src/components/page-template-parts/index.js b/packages/edit-site/src/components/page-template-parts/index.js new file mode 100644 index 00000000000000..0a50f839279793 --- /dev/null +++ b/packages/edit-site/src/components/page-template-parts/index.js @@ -0,0 +1,105 @@ +/** + * WordPress dependencies + */ +import { + VisuallyHidden, + __experimentalHeading as Heading, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; +import { store as coreStore, useEntityRecords } from '@wordpress/core-data'; +import { decodeEntities } from '@wordpress/html-entities'; + +/** + * Internal dependencies + */ +import Page from '../page'; +import Table from '../table'; +import Link from '../routes/link'; +import AddedBy from '../list/added-by'; +import TemplateActions from '../template-actions'; +import AddNewTemplate from '../add-new-template'; +import { store as editSiteStore } from '../../store'; + +export default function PageTemplateParts() { + const { records: templateParts } = useEntityRecords( + 'postType', + 'wp_template_part', + { + per_page: -1, + } + ); + + const { canCreate } = useSelect( ( select ) => { + const { supportsTemplatePartsMode } = + select( editSiteStore ).getSettings(); + return { + postType: select( coreStore ).getPostType( 'wp_template_part' ), + canCreate: ! supportsTemplatePartsMode, + }; + } ); + + const columns = [ + { + header: __( 'Template Part' ), + cell: ( templatePart ) => ( + + + + { decodeEntities( + templatePart.title?.rendered || + templatePart.slug + ) } + + + + ), + maxWidth: 400, + }, + { + header: __( 'Added by' ), + cell: ( templatePart ) => ( + + ), + }, + { + header: { __( 'Actions' ) }, + cell: ( templatePart ) => ( + + ), + }, + ]; + + return ( + + ) + } + > + { templateParts && ( + + ) } + + ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-library/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-library/index.js index d3cfcbece6be0e..270e0ed59afed0 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-library/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-library/index.js @@ -21,6 +21,7 @@ import SidebarNavigationScreen from '../sidebar-navigation-screen'; import CategoryItem from './category-item'; import { DEFAULT_CATEGORY, DEFAULT_TYPE } from '../page-library/utils'; import { store as editSiteStore } from '../../store'; +import { useLink } from '../routes/link'; import usePatternCategories from './use-pattern-categories'; import useTemplatePartAreas from './use-template-part-areas'; @@ -46,6 +47,22 @@ export default function SidebarNavigationScreenLibrary() { return !! settings.supportsTemplatePartsMode; }, [] ); + const templatePartsLink = useLink( { path: '/wp_template_part/all' } ); + const footer = ! isMobileViewport ? ( + + + { __( 'Manage all template parts' ) } + + + { __( 'Manage all custom patterns' ) } + + + ) : undefined; + return ( } - footer={ - - { ! isMobileViewport && ( - - { __( 'Manage all custom patterns' ) } - - ) } - - } + footer={ footer } content={ <> { isLoading && __( 'Loading library' ) } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js index 279b5a0de298d8..182a570d8a95d9 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js @@ -1,10 +1,11 @@ /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __experimentalUseNavigator as useNavigator } from '@wordpress/components'; import { useDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; import { pencil } from '@wordpress/icons'; -import { __experimentalUseNavigator as useNavigator } from '@wordpress/components'; +import { getQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -19,6 +20,7 @@ import { unlock } from '../../lock-unlock'; export default function SidebarNavigationScreenPattern() { const { params } = useNavigator(); + const { categoryType } = getQueryArgs( window.location.href ); const { postType, postId } = params; const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); @@ -27,6 +29,14 @@ export default function SidebarNavigationScreenPattern() { const patternDetails = usePatternDetails( postType, postId ); const content = useNavigationMenuContent( postType, postId ); + // The absence of a category type in the query params for template parts + // indicates the user has arrived at the template part via the "manage all" + // page and the back button should return them to that list page. + const backPath = + ! categoryType && postType === 'wp_template_part' + ? '/wp_template_part/all' + : '/library'; + return ( } - backPath={ '/library' } + backPath={ backPath } content={ content } { ...patternDetails } /> diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-templates-browse/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-templates-browse/index.js index 67e979c26e2cea..b5a0e4d195885d 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-templates-browse/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-templates-browse/index.js @@ -21,6 +21,7 @@ const config = { description: __( 'Create new template parts, or reset any customizations made to the template parts supplied by your theme.' ), + backPath: '/library', }, }; @@ -32,6 +33,7 @@ export default function SidebarNavigationScreenTemplatesBrowse() { ); } diff --git a/packages/edit-site/src/components/sidebar/index.js b/packages/edit-site/src/components/sidebar/index.js index eef37a44339956..df6a5665031406 100644 --- a/packages/edit-site/src/components/sidebar/index.js +++ b/packages/edit-site/src/components/sidebar/index.js @@ -59,12 +59,12 @@ function SidebarScreens() { + + + - - - diff --git a/packages/edit-site/src/utils/get-is-list-page.js b/packages/edit-site/src/utils/get-is-list-page.js index 963287308ac9a3..11827432071bd3 100644 --- a/packages/edit-site/src/utils/get-is-list-page.js +++ b/packages/edit-site/src/utils/get-is-list-page.js @@ -15,6 +15,7 @@ export default function getIsListPage( ) { return ( path === '/wp_template/all' || + path === '/wp_template_part/all' || ( path === '/library' && // Don't treat "/library" without categoryType and categoryId as a list page // in mobile because the sidebar covers the whole page. From d739511b77bc2da18fdb1b8b1140cd1fd41c0715 Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Fri, 30 Jun 2023 12:45:38 +0900 Subject: [PATCH 15/35] Command Palette: fix incorrect path and snackbar message when template part is deleted (#52034) * Command Center: Fix incorrect navigation when deleting template part * removeTemplate: consider title type --- .../src/hooks/commands/use-edit-mode-commands.js | 6 +++++- packages/edit-site/src/store/actions.js | 9 ++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js index 92ccee08592cde..e9e00b9723a125 100644 --- a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js +++ b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js @@ -111,6 +111,10 @@ function useManipulateDocumentCommands() { template.type === 'wp_template' ? __( 'Delete template' ) : __( 'Delete template part' ); + const path = + template.type === 'wp_template' + ? '/wp_template' + : '/wp_template_part/all'; commands.push( { name: 'core/remove-template', label, @@ -119,7 +123,7 @@ function useManipulateDocumentCommands() { removeTemplate( template ); // Navigate to the template list history.push( { - path: '/' + template.type, + path, } ); close(); }, diff --git a/packages/edit-site/src/store/actions.js b/packages/edit-site/src/store/actions.js index 8da362ca01f17d..ac07ac5beaa2af 100644 --- a/packages/edit-site/src/store/actions.js +++ b/packages/edit-site/src/store/actions.js @@ -141,11 +141,18 @@ export const removeTemplate = throw lastError; } + // Depending on how the entity was retrieved it's title might be + // an object or simple string. + const templateTitle = + typeof template.title === 'string' + ? template.title + : template.title?.rendered; + registry.dispatch( noticesStore ).createSuccessNotice( sprintf( /* translators: The template/part's name. */ __( '"%s" deleted.' ), - decodeEntities( template.title.rendered ) + decodeEntities( templateTitle ) ), { type: 'snackbar', id: 'site-editor-template-deleted-success' } ); From d4d010618dd6c815c12d5fdff9760f9ab854d9f1 Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Thu, 29 Jun 2023 15:50:12 +0200 Subject: [PATCH 16/35] Drop-indicator: remove white border. (#52122) --- packages/block-editor/src/components/list-view/style.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/list-view/style.scss b/packages/block-editor/src/components/list-view/style.scss index 0924e98b3f5d45..ab041af51aa1e9 100644 --- a/packages/block-editor/src/components/list-view/style.scss +++ b/packages/block-editor/src/components/list-view/style.scss @@ -408,8 +408,7 @@ $block-navigation-max-indent: 8; .block-editor-list-view-drop-indicator__line { background: var(--wp-admin-theme-color); - height: 6px; - border: 1px solid $white; + height: 4px; border-radius: 4px; } } From 7b8db97db1271aa8cc234fd09ac27f2185cfbdb3 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 29 Jun 2023 15:23:20 +0100 Subject: [PATCH 17/35] Make Navigation fallback selector private (#51413) * Move selector to become private * adds basic lock functionality * remove useless lock-unlock file * map private selectors to resolvers * Unlock the other usage * only create one fallback per session * Fix core-data duplicate private opt-in * Data: bind resolvers to selectors individually, support private selectors --------- Co-authored-by: Andrei Draganescu Co-authored-by: scruffian Co-authored-by: Jarda Snajdr --- docs/reference-guides/data/data-core.md | 12 --- .../src/navigation/edit/index.js | 3 +- packages/core-data/README.md | 12 --- packages/core-data/src/index.js | 7 +- packages/core-data/src/private-selectors.ts | 13 +++ packages/core-data/src/selectors.ts | 12 --- packages/data/src/redux-store/index.js | 84 ++++++++++--------- .../index.js | 16 +++- 8 files changed, 75 insertions(+), 84 deletions(-) diff --git a/docs/reference-guides/data/data-core.md b/docs/reference-guides/data/data-core.md index 8db3a26dd09772..a66c0991e3d274 100644 --- a/docs/reference-guides/data/data-core.md +++ b/docs/reference-guides/data/data-core.md @@ -329,18 +329,6 @@ _Returns_ - `any`: The entity record's save error. -### getNavigationFallbackId - -Retrieve the fallback Navigation. - -_Parameters_ - -- _state_ `State`: Data state. - -_Returns_ - -- `EntityRecordKey | undefined`: The ID for the fallback Navigation post. - ### getRawEntityRecord Returns the entity's record object by key, with its attributes mapped to their raw values. diff --git a/packages/block-library/src/navigation/edit/index.js b/packages/block-library/src/navigation/edit/index.js index 2fe86825bb6b11..7ec990d5b7389c 100644 --- a/packages/block-library/src/navigation/edit/index.js +++ b/packages/block-library/src/navigation/edit/index.js @@ -69,7 +69,6 @@ import ManageMenusButton from './manage-menus-button'; import MenuInspectorControls from './menu-inspector-controls'; import DeletedNavigationWarning from './deleted-navigation-warning'; import { unlock } from '../../lock-unlock'; - const { useBlockEditingMode } = unlock( blockEditorPrivateApis ); function Navigation( { @@ -224,7 +223,7 @@ function Navigation( { // that automatically saves the menu as an entity when changes are made to the inner blocks. const hasUnsavedBlocks = hasUncontrolledInnerBlocks && ! isEntityAvailable; - const { getNavigationFallbackId } = useSelect( coreStore ); + const { getNavigationFallbackId } = unlock( useSelect( coreStore ) ); const navigationFallbackId = ! ( ref || hasUnsavedBlocks ) ? getNavigationFallbackId() diff --git a/packages/core-data/README.md b/packages/core-data/README.md index ade2293efe167a..63e6e28db08d53 100644 --- a/packages/core-data/README.md +++ b/packages/core-data/README.md @@ -506,18 +506,6 @@ _Returns_ - `any`: The entity record's save error. -### getNavigationFallbackId - -Retrieve the fallback Navigation. - -_Parameters_ - -- _state_ `State`: Data state. - -_Returns_ - -- `EntityRecordKey | undefined`: The ID for the fallback Navigation post. - ### getRawEntityRecord Returns the entity's record object by key, with its attributes mapped to their raw values. diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index c2b491fa8c1ea1..98509d9f0383ba 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -13,6 +13,8 @@ import * as resolvers from './resolvers'; import createLocksActions from './locks/actions'; import { rootEntitiesConfig, getMethodName } from './entities'; import { STORE_NAME } from './name'; +import { unlock } from './private-apis'; +import { getNavigationFallbackId } from './private-selectors'; // The entity selectors/resolvers and actions are shortcuts to their generic equivalents // (getEntityRecord, getEntityRecords, updateEntityRecord, updateEntityRecords) @@ -62,7 +64,10 @@ const storeConfig = () => ( { * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore */ export const store = createReduxStore( STORE_NAME, storeConfig() ); -register( store ); +unlock( store ).registerPrivateSelectors( { + getNavigationFallbackId, +} ); +register( store ); // Register store after unlocking private selectors to allow resolvers to use them. export { default as EntityProvider } from './entity-provider'; export * from './entity-provider'; diff --git a/packages/core-data/src/private-selectors.ts b/packages/core-data/src/private-selectors.ts index 0ac2c750239692..1e253b900e1cbb 100644 --- a/packages/core-data/src/private-selectors.ts +++ b/packages/core-data/src/private-selectors.ts @@ -4,6 +4,7 @@ import type { State, UndoEdit } from './selectors'; type Optional< T > = T | undefined; +type EntityRecordKey = string | number; /** * Returns the previous edit from the current undo offset @@ -28,3 +29,15 @@ export function getUndoEdits( state: State ): Optional< UndoEdit[] > { export function getRedoEdits( state: State ): Optional< UndoEdit[] > { return state.undo.list[ state.undo.list.length + state.undo.offset ]; } + +/** + * Retrieve the fallback Navigation. + * + * @param state Data state. + * @return The ID for the fallback Navigation post. + */ +export function getNavigationFallbackId( + state: State +): EntityRecordKey | undefined { + return state.navigationFallbackId; +} diff --git a/packages/core-data/src/selectors.ts b/packages/core-data/src/selectors.ts index a6b7774d37094c..142d24a9d2b8dc 100644 --- a/packages/core-data/src/selectors.ts +++ b/packages/core-data/src/selectors.ts @@ -1257,18 +1257,6 @@ export function getBlockPatternCategories( state: State ): Array< any > { return state.blockPatternCategories; } -/** - * Retrieve the fallback Navigation. - * - * @param state Data state. - * @return The ID for the fallback Navigation post. - */ -export function getNavigationFallbackId( - state: State -): EntityRecordKey | undefined { - return state.navigationFallbackId; -} - /** * Returns the revisions of the current global styles theme. * diff --git a/packages/data/src/redux-store/index.js b/packages/data/src/redux-store/index.js index 7b1c0d2991e69d..518dd821640261 100644 --- a/packages/data/src/redux-store/index.js +++ b/packages/data/src/redux-store/index.js @@ -105,10 +105,10 @@ function createBindingCache( bind ) { const cache = new WeakMap(); return { - get( item ) { + get( item, itemName ) { let boundItem = cache.get( item ); if ( ! boundItem ) { - boundItem = bind( item ); + boundItem = bind( item, itemName ); cache.set( item, boundItem ); } return boundItem; @@ -198,7 +198,7 @@ export default function createReduxStore( key, options ) { get: ( target, prop ) => { const privateAction = privateActions[ prop ]; return privateAction - ? boundPrivateActions.get( privateAction ) + ? boundPrivateActions.get( privateAction, prop ) : actions[ prop ]; }, } ); @@ -210,7 +210,11 @@ export default function createReduxStore( key, options ) { lock( actions, allActions ); - function bindSelector( selector ) { + const resolvers = options.resolvers + ? mapResolvers( options.resolvers ) + : {}; + + function bindSelector( selector, selectorName ) { if ( selector.isRegistrySelector ) { selector.registry = registry; } @@ -218,8 +222,20 @@ export default function createReduxStore( key, options ) { const state = store.__unstableOriginalGetState(); return selector( state.root, ...args ); }; - boundSelector.hasResolver = false; - return boundSelector; + + const resolver = resolvers[ selectorName ]; + if ( ! resolver ) { + boundSelector.hasResolver = false; + return boundSelector; + } + + return mapSelectorWithResolver( + boundSelector, + selectorName, + resolver, + store, + resolversCache + ); } function bindMetadataSelector( selector ) { @@ -231,35 +247,26 @@ export default function createReduxStore( key, options ) { return boundSelector; } - let selectors = { + const selectors = { ...mapValues( metadataSelectors, bindMetadataSelector ), ...mapValues( options.selectors, bindSelector ), }; - let resolvers; - if ( options.resolvers ) { - resolvers = mapResolvers( options.resolvers ); - selectors = mapSelectorsWithResolvers( - selectors, - resolvers, - store, - resolversCache - ); - } - const boundPrivateSelectors = createBindingCache( bindSelector ); // Pre-bind the private selectors that have been registered by the time of // instantiation, so that registry selectors are bound to the registry. - for ( const privateSelector of Object.values( privateSelectors ) ) { - boundPrivateSelectors.get( privateSelector ); + for ( const [ selectorName, selector ] of Object.entries( + privateSelectors + ) ) { + boundPrivateSelectors.get( selector, selectorName ); } const allSelectors = new Proxy( () => {}, { get: ( target, prop ) => { const privateSelector = privateSelectors[ prop ]; return privateSelector - ? boundPrivateSelectors.get( privateSelector ) + ? boundPrivateSelectors.get( privateSelector, prop ) : selectors[ prop ]; }, } ); @@ -509,22 +516,24 @@ function mapResolvers( resolvers ) { } /** - * Returns resolvers with matched selectors for a given namespace. + * Returns a selector with a matched resolver. * Resolvers are side effects invoked once per argument set of a given selector call, * used in ensuring that the data needs for the selector are satisfied. * - * @param {Object} selectors The current selectors to be modified. - * @param {Object} resolvers Resolvers to register. + * @param {Object} selector The selector function to be bound. + * @param {string} selectorName The selector name. + * @param {Object} resolver Resolver to call. * @param {Object} store The redux store to which the resolvers should be mapped. * @param {Object} resolversCache Resolvers Cache. */ -function mapSelectorsWithResolvers( - selectors, - resolvers, +function mapSelectorWithResolver( + selector, + selectorName, + resolver, store, resolversCache ) { - function fulfillSelector( resolver, selectorName, args ) { + function fulfillSelector( args ) { const state = store.getState(); if ( @@ -570,17 +579,10 @@ function mapSelectorsWithResolvers( }, 0 ); } - return mapValues( selectors, ( selector, selectorName ) => { - const resolver = resolvers[ selectorName ]; - if ( ! resolver ) { - return selector; - } - - const selectorResolver = ( ...args ) => { - fulfillSelector( resolver, selectorName, args ); - return selector( ...args ); - }; - selectorResolver.hasResolver = true; - return selectorResolver; - } ); + const selectorResolver = ( ...args ) => { + fulfillSelector( args ); + return selector( ...args ); + }; + selectorResolver.hasResolver = true; + return selectorResolver; } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js index 57ebfd5a2e9533..9d36e956cdca47 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js @@ -21,6 +21,7 @@ import { PRELOADED_NAVIGATION_MENUS_QUERY } from './constants'; import { useLink } from '../routes/link'; import SingleNavigationMenu from '../sidebar-navigation-screen-navigation-menu/single-navigation-menu'; import useNavigationMenuHandlers from '../sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers'; +import { unlock } from '../../lock-unlock'; // Copied from packages/block-library/src/navigation/edit/navigation-menu-selector.js. function buildMenuLabel( title, id, status ) { @@ -41,6 +42,9 @@ function buildMenuLabel( title, id, status ) { ); } +// Save a boolean to prevent us creating a fallback more than once per session. +let hasCreatedFallback = false; + export default function SidebarNavigationScreenNavigationMenus() { const { records: navigationMenus, @@ -55,18 +59,22 @@ export default function SidebarNavigationScreenNavigationMenus() { const isLoading = isResolvingNavigationMenus && ! hasResolvedNavigationMenus; - const getNavigationFallbackId = useSelect( - ( select ) => select( coreStore ).getNavigationFallbackId - ); + const { getNavigationFallbackId } = unlock( useSelect( coreStore ) ); const firstNavigationMenu = navigationMenus?.[ 0 ]; + // Save a boolean to prevent us creating a fallback more than once per session. + if ( firstNavigationMenu ) { + hasCreatedFallback = true; + } + // If there is no navigation menu found // then trigger fallback algorithm to create one. if ( ! firstNavigationMenu && ! isResolvingNavigationMenus && - hasResolvedNavigationMenus + hasResolvedNavigationMenus && + ! hasCreatedFallback ) { getNavigationFallbackId(); } From ea6e8c5dabfac12fba14d63fdec482127d830acb Mon Sep 17 00:00:00 2001 From: Carolina Nymark Date: Thu, 29 Jun 2023 05:45:20 +0200 Subject: [PATCH 18/35] Focus Mode: Use the symbol icon if a pattern is being edited (#52031) --- .../header-edit-mode/document-actions/index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/header-edit-mode/document-actions/index.js b/packages/edit-site/src/components/header-edit-mode/document-actions/index.js index f31c789043e72e..3a048e753631f0 100644 --- a/packages/edit-site/src/components/header-edit-mode/document-actions/index.js +++ b/packages/edit-site/src/components/header-edit-mode/document-actions/index.js @@ -20,6 +20,7 @@ import { chevronLeftSmall as chevronLeftSmallIcon, page as pageIcon, navigation as navigationIcon, + symbol, } from '@wordpress/icons'; import { displayShortcut } from '@wordpress/keycodes'; import { useState, useEffect, useRef } from '@wordpress/element'; @@ -118,10 +119,17 @@ function TemplateDocumentActions( { className, onBack } ) { const entityLabel = getEntityLabel( record.type ); + let typeIcon = icon; + if ( record.type === 'wp_navigation' ) { + typeIcon = navigationIcon; + } else if ( record.type === 'wp_block' ) { + typeIcon = symbol; + } + return ( From 8064587075cd1ff294430e7e498e01c0a6b9a037 Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Thu, 29 Jun 2023 10:05:33 +0300 Subject: [PATCH 19/35] Footnotes: register meta field for pages (#52024) --- .../block-library/src/footnotes/index.php | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/footnotes/index.php b/packages/block-library/src/footnotes/index.php index b7be0542d7a0f3..e4bd8dcdeaac2e 100644 --- a/packages/block-library/src/footnotes/index.php +++ b/packages/block-library/src/footnotes/index.php @@ -59,15 +59,17 @@ function render_block_core_footnotes( $attributes, $content, $block ) { * Registers the `core/footnotes` block on the server. */ function register_block_core_footnotes() { - register_post_meta( - 'post', - 'footnotes', - array( - 'show_in_rest' => true, - 'single' => true, - 'type' => 'string', - ) - ); + foreach ( array( 'post', 'page' ) as $post_type ) { + register_post_meta( + $post_type, + 'footnotes', + array( + 'show_in_rest' => true, + 'single' => true, + 'type' => 'string', + ) + ); + } register_block_type_from_metadata( __DIR__ . '/footnotes', array( From 7dbdc1736e6b53e73a1448f0b4dac2ffd7a9a9fd Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Thu, 29 Jun 2023 11:34:08 +0300 Subject: [PATCH 20/35] Fix unintentional toggling on of distraction free (#52090) * replace toggle with set preference - because I don't read code properly it seems * remove notification --- .../index.js | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js index c10de840e8d478..06278590696cbc 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js @@ -16,6 +16,7 @@ import { BlockEditorProvider } from '@wordpress/block-editor'; import { humanTimeDiff } from '@wordpress/date'; import { useCallback } from '@wordpress/element'; import { store as noticesStore } from '@wordpress/notices'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -32,14 +33,21 @@ import useGlobalStylesRevisions from '../global-styles/screen-revisions/use-glob const noop = () => {}; export function SidebarNavigationItemGlobalStyles( props ) { - const { openGeneralSidebar, toggleFeature } = useDispatch( editSiteStore ); + const { openGeneralSidebar } = useDispatch( editSiteStore ); const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); const { createNotice } = useDispatch( noticesStore ); - const hasGlobalStyleVariations = useSelect( - ( select ) => - !! select( - coreStore - ).__experimentalGetCurrentThemeGlobalStylesVariations()?.length, + const { set: setPreference } = useDispatch( preferencesStore ); + const { hasGlobalStyleVariations, isDistractionFree } = useSelect( + ( select ) => ( { + hasGlobalStyleVariations: + !! select( + coreStore + ).__experimentalGetCurrentThemeGlobalStylesVariations()?.length, + isDistractionFree: select( preferencesStore ).get( + editSiteStore.name, + 'distractionFree' + ), + } ), [] ); if ( hasGlobalStyleVariations ) { @@ -56,15 +64,21 @@ export function SidebarNavigationItemGlobalStyles( props ) { { ...props } onClick={ () => { // Disable distraction free mode. - toggleFeature( 'distractionFree', false ); - createNotice( - 'info', - __( 'Distraction free mode turned off' ), - { - isDismissible: true, - type: 'snackbar', - } - ); + if ( isDistractionFree ) { + setPreference( + editSiteStore.name, + 'distractionFree', + false + ); + createNotice( + 'info', + __( 'Distraction free mode turned off' ), + { + isDismissible: true, + type: 'snackbar', + } + ); + } // Switch to edit mode. setCanvasMode( 'edit' ); // Open global styles sidebar. From 97e3acf765aba652614a51bc32897ca566872600 Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 29 Jun 2023 10:28:40 +1000 Subject: [PATCH 21/35] Revert "Updating social link attributes (#51997)" (#52019) This reverts commit c711e2aa613aceb93836635e854badd8ac15310d. --- packages/block-library/src/social-link/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/social-link/index.php b/packages/block-library/src/social-link/index.php index 1e5c4cf5de6fbd..51ed9374c9bcdf 100644 --- a/packages/block-library/src/social-link/index.php +++ b/packages/block-library/src/social-link/index.php @@ -47,8 +47,8 @@ function render_block_core_social_link( $attributes, $content, $block ) { $icon = block_core_social_link_get_icon( $service ); $wrapper_attributes = get_block_wrapper_attributes( array( - 'class' => esc_attr( 'wp-social-link wp-social-link-' . $service . block_core_social_link_get_color_classes( $block->context ) ), - 'style' => esc_attr( block_core_social_link_get_color_styles( $block->context ) ), + 'class' => 'wp-social-link wp-social-link-' . $service . block_core_social_link_get_color_classes( $block->context ), + 'style' => block_core_social_link_get_color_styles( $block->context ), ) ); From 53c86fcb535a650e25cfae8f3dd0471aed5550dc Mon Sep 17 00:00:00 2001 From: James Koster Date: Wed, 28 Jun 2023 16:36:54 +0100 Subject: [PATCH 22/35] Update home template name (#52048) --- lib/compat/wordpress-6.3/block-template-utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.3/block-template-utils.php b/lib/compat/wordpress-6.3/block-template-utils.php index cdd870db2d0813..cc367f66dd42d9 100644 --- a/lib/compat/wordpress-6.3/block-template-utils.php +++ b/lib/compat/wordpress-6.3/block-template-utils.php @@ -29,7 +29,7 @@ function gutenberg_get_default_block_template_types( $default_template_types ) { } if ( isset( $default_template_types['home'] ) ) { $default_template_types['home'] = array( - 'title' => _x( 'Home', 'Template name', 'gutenberg' ), + 'title' => _x( 'Blog Home', 'Template name', 'gutenberg' ), 'description' => __( 'Displays the latest posts as either the site homepage or as the "Posts page" as defined under reading settings. If it exists, the Front Page template overrides this template when posts are shown on the homepage.', 'gutenberg' From aba35cbdb52d74a9b9cbb0ada161d167225df74d Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 28 Jun 2023 12:53:16 +0100 Subject: [PATCH 23/35] Removes unused call (#51988) --- .../sidebar-navigation-screen-navigation-menu/index.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js index 6bce0f356f7400..92810d1411fc39 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js @@ -33,11 +33,8 @@ export default function SidebarNavigationScreenNavigationMenu() { const { isSaving, isDeleting } = useSelect( ( select ) => { - const { - isSavingEntityRecord, - isDeletingEntityRecord, - getEditedEntityRecord: getEditedEntityRecordSelector, - } = select( coreStore ); + const { isSavingEntityRecord, isDeletingEntityRecord } = + select( coreStore ); return { isSaving: isSavingEntityRecord( 'postType', postType, postId ), @@ -46,7 +43,6 @@ export default function SidebarNavigationScreenNavigationMenu() { postType, postId ), - getEditedEntityRecord: getEditedEntityRecordSelector, }; }, [ postId ] From 0ea227a8de82f49bad9d1e3b1d989e919bcff03c Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 29 Jun 2023 14:35:56 +1200 Subject: [PATCH 24/35] Remove ability for user to toggle sync status after pattern creation (#51998) --- .../src/components/post-sync-status/index.js | 29 ++++--------------- .../components/post-sync-status/style.scss | 4 +-- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/packages/editor/src/components/post-sync-status/index.js b/packages/editor/src/components/post-sync-status/index.js index 392d33563ef78f..c384fd234c7a34 100644 --- a/packages/editor/src/components/post-sync-status/index.js +++ b/packages/editor/src/components/post-sync-status/index.js @@ -1,9 +1,9 @@ /** * WordPress dependencies */ -import { useSelect, useDispatch } from '@wordpress/data'; +import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; -import { ToggleControl, PanelRow } from '@wordpress/components'; +import { PanelRow } from '@wordpress/components'; /** * Internal dependencies @@ -11,7 +11,6 @@ import { ToggleControl, PanelRow } from '@wordpress/components'; import { store as editorStore } from '../../store'; export default function PostSyncStatus() { - const { editPost } = useDispatch( editorStore ); const { meta, postType } = useSelect( ( select ) => { const { getEditedPostAttribute } = select( editorStore ); return { @@ -22,31 +21,15 @@ export default function PostSyncStatus() { if ( postType !== 'wp_block' ) { return null; } - const onUpdateSync = ( syncStatus ) => - editPost( { - meta: { - ...meta, - sync_status: syncStatus === 'unsynced' ? syncStatus : null, - }, - } ); const syncStatus = meta?.sync_status; const isFullySynced = ! syncStatus; return ( - { __( 'Syncing' ) } - { - onUpdateSync( - syncStatus === 'unsynced' ? 'fully' : 'unsynced' - ); - } } - /> + { __( 'Sync status' ) } +
+ { isFullySynced ? __( 'Fully synced' ) : __( 'Not synced' ) } +
); } diff --git a/packages/editor/src/components/post-sync-status/style.scss b/packages/editor/src/components/post-sync-status/style.scss index 385577b3334d86..7f81a327443ee1 100644 --- a/packages/editor/src/components/post-sync-status/style.scss +++ b/packages/editor/src/components/post-sync-status/style.scss @@ -9,8 +9,8 @@ flex-shrink: 0; } - .components-base-control { + > div { // Match padding on tertiary buttons for alignment. - padding-left: $grid-unit-15 * 0.5; + padding-left: $grid-unit-15; } } From 9d456e4dbf66783662af05a9dce52378dc908380 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Fri, 30 Jun 2023 13:46:54 +0300 Subject: [PATCH 25/35] Fix disable DFM when opening styles command (#52165) --- .../index.js | 7 ++----- .../src/hooks/commands/use-common-commands.js | 14 +++++++++++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js index 06278590696cbc..1e2e7aac159ef7 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js @@ -72,11 +72,8 @@ export function SidebarNavigationItemGlobalStyles( props ) { ); createNotice( 'info', - __( 'Distraction free mode turned off' ), - { - isDismissible: true, - type: 'snackbar', - } + __( 'Distraction free mode turned off.' ), + { type: 'snackbar' } ); } // Switch to edit mode. diff --git a/packages/edit-site/src/hooks/commands/use-common-commands.js b/packages/edit-site/src/hooks/commands/use-common-commands.js index 96a48980c021aa..dac547dc4d95c2 100644 --- a/packages/edit-site/src/hooks/commands/use-common-commands.js +++ b/packages/edit-site/src/hooks/commands/use-common-commands.js @@ -10,6 +10,7 @@ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; import { privateApis as routerPrivateApis } from '@wordpress/router'; import { store as preferencesStore } from '@wordpress/preferences'; import { store as coreStore } from '@wordpress/core-data'; +import { store as noticesStore } from '@wordpress/notices'; /** * Internal dependencies @@ -104,14 +105,19 @@ export function useCommonCommands() { useDispatch( editSiteStore ) ); const { set } = useDispatch( preferencesStore ); + const { createInfoNotice } = useDispatch( noticesStore ); const history = useHistory(); - const { homeUrl } = useSelect( ( select ) => { + const { homeUrl, isDistractionFree } = useSelect( ( select ) => { const { getUnstableBase, // Site index. } = select( coreStore ); return { homeUrl: getUnstableBase()?.home, + isDistractionFree: select( preferencesStore ).get( + editSiteStore.name, + 'distractionFree' + ), }; }, [] ); @@ -139,6 +145,12 @@ export function useCommonCommands() { path: '/wp_global_styles', canvas: 'edit', } ); + if ( isDistractionFree ) { + set( editSiteStore.name, 'distractionFree', false ); + createInfoNotice( __( 'Distraction free mode turned off.' ), { + type: 'snackbar', + } ); + } openGeneralSidebar( 'edit-site/global-styles' ); }, icon: styles, From d45c58c7f360c5c76bebef466e25d777cf188c37 Mon Sep 17 00:00:00 2001 From: Saxon Fletcher Date: Wed, 28 Jun 2023 20:58:34 +1000 Subject: [PATCH 26/35] Update custom patterns label to 'My patterns' (#51949) * rename custom patterns to my patterns * Add my patterns label to inserter and show at the top --------- Co-authored-by: Daniel Richards --- .../components/inserter/block-patterns-tab.js | 1 + .../inserter/hooks/use-patterns-state.js | 2 +- .../inserter/reusable-blocks-tab.js | 2 +- .../src/admin-navigation-commands.js | 2 +- .../src/components/page-library/utils.js | 6 ++--- .../index.js | 23 +++++++++++++++++-- .../use-my-patterns.js | 23 +++++++++++++++++++ .../use-pattern-categories.js | 19 +-------------- 8 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-library/use-my-patterns.js diff --git a/packages/block-editor/src/components/inserter/block-patterns-tab.js b/packages/block-editor/src/components/inserter/block-patterns-tab.js index 5c2720fd0502e3..f66d27ac06170d 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -33,6 +33,7 @@ const noop = () => {}; // Preferred order of pattern categories. Any other categories should // be at the bottom without any re-ordering. const patternCategoriesOrder = [ + 'custom', 'featured', 'posts', 'text', diff --git a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js index 2a99e637ed1237..805a89ca8ff0c4 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js @@ -14,7 +14,7 @@ import { store as blockEditorStore } from '../../../store'; const CUSTOM_CATEGORY = { name: 'custom', - label: __( 'Custom patterns' ), + label: __( 'My patterns' ), description: __( 'Custom patterns add by site users' ), }; diff --git a/packages/block-editor/src/components/inserter/reusable-blocks-tab.js b/packages/block-editor/src/components/inserter/reusable-blocks-tab.js index 65930fa9fcd4a6..c16d5f1a78e543 100644 --- a/packages/block-editor/src/components/inserter/reusable-blocks-tab.js +++ b/packages/block-editor/src/components/inserter/reusable-blocks-tab.js @@ -67,7 +67,7 @@ export function ReusableBlocksTab( { rootClientId, onInsert, onHover } ) { post_type: 'wp_block', } ) } > - { __( 'Manage custom patterns' ) } + { __( 'Manage my patterns' ) } diff --git a/packages/core-commands/src/admin-navigation-commands.js b/packages/core-commands/src/admin-navigation-commands.js index 577e7258df0b63..a72b0c7dd5ab9b 100644 --- a/packages/core-commands/src/admin-navigation-commands.js +++ b/packages/core-commands/src/admin-navigation-commands.js @@ -24,7 +24,7 @@ export function useAdminNavigationCommands() { } ); useCommand( { name: 'core/manage-reusable-blocks', - label: __( 'Manage all custom patterns' ), + label: __( 'Manage all of my patterns' ), callback: () => { document.location.href = 'edit.php?post_type=wp_block'; }, diff --git a/packages/edit-site/src/components/page-library/utils.js b/packages/edit-site/src/components/page-library/utils.js index a9f1d7a658483e..bbdff872fe355a 100644 --- a/packages/edit-site/src/components/page-library/utils.js +++ b/packages/edit-site/src/components/page-library/utils.js @@ -1,9 +1,9 @@ -export const DEFAULT_CATEGORY = 'header'; -export const DEFAULT_TYPE = 'wp_template_part'; +export const DEFAULT_CATEGORY = 'my-patterns'; +export const DEFAULT_TYPE = 'wp_block'; export const PATTERNS = 'pattern'; export const TEMPLATE_PARTS = 'wp_template_part'; export const USER_PATTERNS = 'wp_block'; -export const USER_PATTERN_CATEGORY = 'custom-patterns'; +export const USER_PATTERN_CATEGORY = 'my-patterns'; export const CORE_PATTERN_SOURCES = [ 'core', diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-library/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-library/index.js index 270e0ed59afed0..5aa32e7587ebd2 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-library/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-library/index.js @@ -10,7 +10,7 @@ import { useSelect } from '@wordpress/data'; import { getTemplatePartIcon } from '@wordpress/editor'; import { __ } from '@wordpress/i18n'; import { getQueryArgs } from '@wordpress/url'; -import { file } from '@wordpress/icons'; +import { file, starFilled } from '@wordpress/icons'; /** * Internal dependencies @@ -23,6 +23,7 @@ import { DEFAULT_CATEGORY, DEFAULT_TYPE } from '../page-library/utils'; import { store as editSiteStore } from '../../store'; import { useLink } from '../routes/link'; import usePatternCategories from './use-pattern-categories'; +import useMyPatterns from './use-my-patterns'; import useTemplatePartAreas from './use-template-part-areas'; const templatePartAreaLabels = { @@ -41,6 +42,7 @@ export default function SidebarNavigationScreenLibrary() { const { templatePartAreas, hasTemplateParts, isLoading } = useTemplatePartAreas(); const { patternCategories, hasPatterns } = usePatternCategories(); + const { myPatterns, hasPatterns: hasMyPatterns } = useMyPatterns(); const isTemplatePartsMode = useSelect( ( select ) => { const settings = select( editSiteStore ).getSettings(); @@ -58,7 +60,7 @@ export default function SidebarNavigationScreenLibrary() { href="edit.php?post_type=wp_block" withChevron > - { __( 'Manage all custom patterns' ) } + { __( 'Manage all of my patterns' ) } ) : undefined; @@ -86,6 +88,23 @@ export default function SidebarNavigationScreenLibrary() { ) } + { hasMyPatterns && ( + + + + ) } { hasTemplateParts && ( { Object.entries( templatePartAreas ).map( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-library/use-my-patterns.js b/packages/edit-site/src/components/sidebar-navigation-screen-library/use-my-patterns.js new file mode 100644 index 00000000000000..e3d5cc297164a2 --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-library/use-my-patterns.js @@ -0,0 +1,23 @@ +/** + * WordPress dependencies + */ +import { store as coreStore } from '@wordpress/core-data'; +import { useSelect } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; + +export default function useMyPatterns() { + const myPatterns = useSelect( ( select ) => + select( coreStore ).getEntityRecords( 'postType', 'wp_block', { + per_page: -1, + } ) + ); + + return { + myPatterns: { + count: myPatterns?.length || 0, + name: 'my-patterns', + label: __( 'My patterns' ), + }, + hasPatterns: !! myPatterns?.length, + }; +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-library/use-pattern-categories.js b/packages/edit-site/src/components/sidebar-navigation-screen-library/use-pattern-categories.js index a787f8c04c6390..96491018d07722 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-library/use-pattern-categories.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-library/use-pattern-categories.js @@ -1,10 +1,7 @@ /** * WordPress dependencies */ -import { store as coreStore } from '@wordpress/core-data'; -import { useSelect } from '@wordpress/data'; import { useMemo } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -15,11 +12,6 @@ import useThemePatterns from './use-theme-patterns'; export default function usePatternCategories() { const defaultCategories = useDefaultPatternCategories(); const themePatterns = useThemePatterns(); - const userPatterns = useSelect( ( select ) => - select( coreStore ).getEntityRecords( 'postType', 'wp_block', { - per_page: -1, - } ) - ); const patternCategories = useMemo( () => { const categoryMap = {}; @@ -48,17 +40,8 @@ export default function usePatternCategories() { } } ); - // Add "Your Patterns" category for user patterns if there are any. - if ( userPatterns?.length ) { - categoriesWithCounts.push( { - count: userPatterns.length || 0, - name: 'custom-patterns', - label: __( 'Custom patterns' ), - } ); - } - return categoriesWithCounts; - }, [ defaultCategories, themePatterns, userPatterns ] ); + }, [ defaultCategories, themePatterns ] ); return { patternCategories, hasPatterns: !! patternCategories.length }; } From 28789fc92acbac1fbff16db11ca086db05c572a0 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Wed, 28 Jun 2023 18:37:27 +1000 Subject: [PATCH 27/35] Library: Add sync status to pattern details screen (#51954) --- .../index.js | 3 -- .../use-pattern-details.js | 44 ++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js index 182a570d8a95d9..349cc5d43b431d 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js @@ -14,7 +14,6 @@ import SidebarButton from '../sidebar-button'; import SidebarNavigationScreen from '../sidebar-navigation-screen'; import useInitEditedEntityFromURL from '../sync-state-with-url/use-init-edited-entity-from-url'; import usePatternDetails from './use-pattern-details'; -import useNavigationMenuContent from './use-navigation-menu-content'; import { store as editSiteStore } from '../../store'; import { unlock } from '../../lock-unlock'; @@ -27,7 +26,6 @@ export default function SidebarNavigationScreenPattern() { useInitEditedEntityFromURL(); const patternDetails = usePatternDetails( postType, postId ); - const content = useNavigationMenuContent( postType, postId ); // The absence of a category type in the query params for template parts // indicates the user has arrived at the template part via the "manage all" @@ -47,7 +45,6 @@ export default function SidebarNavigationScreenPattern() { /> } backPath={ backPath } - content={ content } { ...patternDetails } /> ); diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js index 028b1c781f8f2c..dfc367ea0b97dc 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js @@ -11,7 +11,14 @@ import { Icon } from '@wordpress/components'; */ import { useAddedBy } from '../list/added-by'; import useEditedEntityRecord from '../use-edited-entity-record'; +import useNavigationMenuContent from './use-navigation-menu-content'; import SidebarNavigationScreenDetailsFooter from '../sidebar-navigation-screen-details-footer'; +import { + SidebarNavigationScreenDetailsPanel, + SidebarNavigationScreenDetailsPanelRow, + SidebarNavigationScreenDetailsPanelLabel, + SidebarNavigationScreenDetailsPanelValue, +} from '../sidebar-navigation-screen-details-panel'; export default function usePatternDetails( postType, postId ) { const { getDescription, getTitle, record } = useEditedEntityRecord( @@ -82,5 +89,40 @@ export default function usePatternDetails( postType, postId ) { /> ) : null; - return { title, description, footer }; + const details = []; + + if ( postType === 'wp_block' ) { + details.push( { + label: __( 'Syncing' ), + value: + record.meta?.sync_status === 'unsynced' + ? __( 'Not synced' ) + : __( 'Fully synced' ), + } ); + } + + const content = ( + <> + { !! details.length && ( + + { details.map( ( { label, value } ) => ( + + + { label } + + + { value } + + + ) ) } + + ) } + { useNavigationMenuContent( postType, postId ) } + + ); + + return { title, description, content, footer }; } From b40ea4a06950c94a46f410d734cb6fd3b9938c4d Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Fri, 30 Jun 2023 16:17:33 +1000 Subject: [PATCH 28/35] Patterns: Rename Library to Patterns (#52102) --- .../src/site-editor-navigation-commands.js | 2 +- .../components/create-pattern-modal/index.js | 2 +- .../src/components/page-main/index.js | 6 +- .../grid-item.js | 14 +-- .../{page-library => page-patterns}/grid.js | 2 +- .../{page-library => page-patterns}/index.js | 10 +- .../no-patterns.js | 2 +- .../patterns-list.js | 12 +-- .../search-items.js | 0 .../style.scss | 22 ++--- .../use-pattern-settings.js} | 2 +- .../use-patterns.js | 0 .../{page-library => page-patterns}/utils.js | 0 .../style.scss | 3 - .../sidebar-navigation-screen-main/index.js | 4 +- .../index.js | 2 +- .../category-item.js | 6 +- .../index.js | 16 +-- .../style.scss | 3 + .../use-default-pattern-categories.js | 0 .../use-my-patterns.js | 0 .../use-pattern-categories.js | 0 .../use-template-part-areas.js | 0 .../use-theme-patterns.js | 2 +- .../index.js | 2 +- .../index.js | 97 +++---------------- .../edit-site/src/components/sidebar/index.js | 6 +- .../use-sync-path-with-url.js | 2 +- packages/edit-site/src/style.scss | 4 +- .../edit-site/src/utils/get-is-list-page.js | 6 +- .../site-editor-url-navigation.spec.js | 2 +- 31 files changed, 81 insertions(+), 148 deletions(-) rename packages/edit-site/src/components/{page-library => page-patterns}/grid-item.js (92%) rename packages/edit-site/src/components/{page-library => page-patterns}/grid.js (94%) rename packages/edit-site/src/components/{page-library => page-patterns}/index.js (83%) rename packages/edit-site/src/components/{page-library => page-patterns}/no-patterns.js (77%) rename packages/edit-site/src/components/{page-library => page-patterns}/patterns-list.js (89%) rename packages/edit-site/src/components/{page-library => page-patterns}/search-items.js (100%) rename packages/edit-site/src/components/{page-library => page-patterns}/style.scss (82%) rename packages/edit-site/src/components/{page-library/use-library-settings.js => page-patterns/use-pattern-settings.js} (96%) rename packages/edit-site/src/components/{page-library => page-patterns}/use-patterns.js (100%) rename packages/edit-site/src/components/{page-library => page-patterns}/utils.js (100%) delete mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-library/style.scss rename packages/edit-site/src/components/{sidebar-navigation-screen-library => sidebar-navigation-screen-patterns}/category-item.js (86%) rename packages/edit-site/src/components/{sidebar-navigation-screen-library => sidebar-navigation-screen-patterns}/index.js (94%) create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-patterns/style.scss rename packages/edit-site/src/components/{sidebar-navigation-screen-library => sidebar-navigation-screen-patterns}/use-default-pattern-categories.js (100%) rename packages/edit-site/src/components/{sidebar-navigation-screen-library => sidebar-navigation-screen-patterns}/use-my-patterns.js (100%) rename packages/edit-site/src/components/{sidebar-navigation-screen-library => sidebar-navigation-screen-patterns}/use-pattern-categories.js (100%) rename packages/edit-site/src/components/{sidebar-navigation-screen-library => sidebar-navigation-screen-patterns}/use-template-part-areas.js (100%) rename packages/edit-site/src/components/{sidebar-navigation-screen-library => sidebar-navigation-screen-patterns}/use-theme-patterns.js (96%) diff --git a/packages/core-commands/src/site-editor-navigation-commands.js b/packages/core-commands/src/site-editor-navigation-commands.js index 6331afd058de34..8f2003d0e08a27 100644 --- a/packages/core-commands/src/site-editor-navigation-commands.js +++ b/packages/core-commands/src/site-editor-navigation-commands.js @@ -203,7 +203,7 @@ function useSiteEditorBasicNavigationCommands() { icon: symbolFilled, callback: ( { close } ) => { const args = { - path: '/library', + path: '/patterns', }; const targetUrl = addQueryArgs( 'site-editor.php', args ); if ( isSiteEditor ) { diff --git a/packages/edit-site/src/components/create-pattern-modal/index.js b/packages/edit-site/src/components/create-pattern-modal/index.js index 5180ad5d870684..bd83b369c3abb3 100644 --- a/packages/edit-site/src/components/create-pattern-modal/index.js +++ b/packages/edit-site/src/components/create-pattern-modal/index.js @@ -18,7 +18,7 @@ import { useDispatch } from '@wordpress/data'; /** * Internal dependencies */ -import { SYNC_TYPES, USER_PATTERN_CATEGORY } from '../page-library/utils'; +import { SYNC_TYPES, USER_PATTERN_CATEGORY } from '../page-patterns/utils'; export default function CreatePatternModal( { closeModal, diff --git a/packages/edit-site/src/components/page-main/index.js b/packages/edit-site/src/components/page-main/index.js index a6c05886888c45..af017a8db9700a 100644 --- a/packages/edit-site/src/components/page-main/index.js +++ b/packages/edit-site/src/components/page-main/index.js @@ -6,7 +6,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ -import PageLibrary from '../page-library'; +import PagePatterns from '../page-patterns'; import PageTemplateParts from '../page-template-parts'; import PageTemplates from '../page-templates'; import { unlock } from '../../lock-unlock'; @@ -22,8 +22,8 @@ export default function PageMain() { return ; } else if ( path === '/wp_template_part/all' ) { return ; - } else if ( path === '/library' ) { - return ; + } else if ( path === '/patterns' ) { + return ; } return null; diff --git a/packages/edit-site/src/components/page-library/grid-item.js b/packages/edit-site/src/components/page-patterns/grid-item.js similarity index 92% rename from packages/edit-site/src/components/page-library/grid-item.js rename to packages/edit-site/src/components/page-patterns/grid-item.js index 726f7a9896adc2..cc9d99fd900136 100644 --- a/packages/edit-site/src/components/page-library/grid-item.js +++ b/packages/edit-site/src/components/page-patterns/grid-item.js @@ -39,7 +39,7 @@ import { useLink } from '../routes/link'; export default function GridItem( { categoryId, composite, icon, item } ) { const instanceId = useInstanceId( GridItem ); - const descriptionId = `edit-site-library__pattern-description-${ instanceId }`; + const descriptionId = `edit-site-patterns__pattern-description-${ instanceId }`; const [ isDeleteDialogOpen, setIsDeleteDialogOpen ] = useState( false ); const { __experimentalDeleteReusableBlock } = @@ -61,10 +61,10 @@ export default function GridItem( { categoryId, composite, icon, item } ) { }; const isEmpty = ! item.blocks?.length; - const patternClassNames = classnames( 'edit-site-library__pattern', { + const patternClassNames = classnames( 'edit-site-patterns__pattern', { 'is-placeholder': isEmpty, } ); - const previewClassNames = classnames( 'edit-site-library__preview', { + const previewClassNames = classnames( 'edit-site-patterns__preview', { 'is-inactive': item.type === PATTERNS, } ); @@ -132,14 +132,14 @@ export default function GridItem( { categoryId, composite, icon, item } ) { ) }