diff --git a/.github/workflows/check-backport-changelog.yml b/.github/workflows/check-backport-changelog.yml index 0d7025474d715d..dd3fe28fbfd59f 100644 --- a/.github/workflows/check-backport-changelog.yml +++ b/.github/workflows/check-backport-changelog.yml @@ -2,7 +2,7 @@ name: Verify Core Backport Changlog on: pull_request: - types: [opened, synchronize] + types: [opened, synchronize, labeled, unlabeled] paths: - 'lib/**' - '!lib/load.php' @@ -31,6 +31,7 @@ jobs: - name: 'Fetch relevant history from origin' run: git fetch origin ${{ github.event.pull_request.base.ref }} - name: Check CHANGELOG status + if: ${{ !contains(github.event.pull_request.labels.*.name, 'No Core Sync Required') && !contains(github.event.pull_request.labels.*.name, 'Backport from WordPress Core') }} env: PR_NUMBER: ${{ github.event.number }} run: | diff --git a/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md b/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md index d3628d991f872f..bf48c5db4e9bb9 100644 --- a/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md +++ b/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md @@ -178,7 +178,7 @@ As of Gutenberg version 14.2, the following controls are available: - `sticky` - Shows a dropdown to select how to handle sticky posts. - `taxQuery` - Shows available taxonomies filters for the currently selected post type. - `author` - Shows an input field to filter the query by author. -- `search` - Shows an input filed to filter the query by keywords. +- `search` - Shows an input field to filter the query by keywords. In our case, the property would look like this: diff --git a/lib/class-wp-rest-global-styles-controller-gutenberg.php b/lib/class-wp-rest-global-styles-controller-gutenberg.php index 3c960564a8fe0a..9bbca1ffcab404 100644 --- a/lib/class-wp-rest-global-styles-controller-gutenberg.php +++ b/lib/class-wp-rest-global-styles-controller-gutenberg.php @@ -1,6 +1,6 @@ =0.6.19" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -83177,9 +83187,9 @@ } }, "lint-staged": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.0.1.tgz", - "integrity": "sha512-Qk48GmcMX8zFzhuJsf0ZquILxnnDkY56Y+/y1TGxEe4S5P+RetnisiF0Z15t+Gwa5PMNAG4dPxqGHabW7L4zwg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.0.2.tgz", + "integrity": "sha512-ZldhtIfT7bynVa7nmU/1jbK05r9hYQXbIQqZSotqdBCAcGJDEUqaUB7kG3ZCdoe9Qkj6HUM3x2yjCGJRxPUQLA==", "dev": true, "requires": { "chalk": "^3.0.0", @@ -83193,6 +83203,7 @@ "micromatch": "^4.0.2", "normalize-path": "^3.0.0", "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", "stringify-object": "^3.3.0" }, "dependencies": { @@ -92808,6 +92819,12 @@ "safe-buffer": "~5.1.0" } }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", diff --git a/package.json b/package.json index 7995d6a9755a7e..77dce7cb5a5e72 100644 --- a/package.json +++ b/package.json @@ -218,7 +218,7 @@ "jest-message-util": "29.6.2", "jest-watch-typeahead": "2.2.2", "lerna": "7.1.4", - "lint-staged": "10.0.1", + "lint-staged": "10.0.2", "make-dir": "3.0.0", "mkdirp": "3.0.1", "mock-match-media": "0.4.2", diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index 6da035a883ffb1..e01cd095752696 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -111,10 +111,8 @@ const BlockInspector = ( { showNoBlockSelectedMessage = true } ) => { // displays based on the relationship between the selected block // and its parent, and only enable it if the parent is controlling // its children blocks. - const blockInspectorAnimationSettings = useBlockInspectorAnimationSettings( - blockType, - selectedBlockClientId - ); + const blockInspectorAnimationSettings = + useBlockInspectorAnimationSettings( blockType ); const borderPanelLabel = useBorderPanelLabel( { blockName: selectedBlockName, diff --git a/packages/block-editor/src/components/block-inspector/useBlockInspectorAnimationSettings.js b/packages/block-editor/src/components/block-inspector/useBlockInspectorAnimationSettings.js index 6be7d3fe18667e..d89639c4b9ac8c 100644 --- a/packages/block-editor/src/components/block-inspector/useBlockInspectorAnimationSettings.js +++ b/packages/block-editor/src/components/block-inspector/useBlockInspectorAnimationSettings.js @@ -8,10 +8,7 @@ import { useSelect } from '@wordpress/data'; */ import { store as blockEditorStore } from '../../store'; -export default function useBlockInspectorAnimationSettings( - blockType, - selectedBlockClientId -) { +export default function useBlockInspectorAnimationSettings( blockType ) { return useSelect( ( select ) => { if ( blockType ) { @@ -48,6 +45,6 @@ export default function useBlockInspectorAnimationSettings( } return null; }, - [ selectedBlockClientId, blockType ] + [ blockType ] ); } diff --git a/packages/core-commands/src/site-editor-navigation-commands.js b/packages/core-commands/src/site-editor-navigation-commands.js index 6ef9be58b4d007..ba34fffd98824c 100644 --- a/packages/core-commands/src/site-editor-navigation-commands.js +++ b/packages/core-commands/src/site-editor-navigation-commands.js @@ -16,7 +16,7 @@ import { navigation, } from '@wordpress/icons'; import { privateApis as routerPrivateApis } from '@wordpress/router'; -import { getQueryArg, addQueryArgs, getPath } from '@wordpress/url'; +import { addQueryArgs, getPath } from '@wordpress/url'; import { useDebounce } from '@wordpress/compose'; /** @@ -119,14 +119,6 @@ const getNavigationCommandLoaderPerPostType = ( postType ) => const isSiteEditor = getPath( window.location.href )?.includes( 'site-editor.php' ); - const extraArgs = isSiteEditor - ? { - canvas: getQueryArg( - window.location.href, - 'canvas' - ), - } - : {}; return { ...command, @@ -134,7 +126,7 @@ const getNavigationCommandLoaderPerPostType = ( postType ) => const args = { postType, postId: record.id, - ...extraArgs, + canvas: 'edit', }; const targetUrl = addQueryArgs( 'site-editor.php', @@ -195,15 +187,6 @@ const getNavigationCommandLoaderPerTemplate = ( templateType ) => const result = []; result.push( ...orderedRecords.map( ( record ) => { - const extraArgs = isSiteEditor - ? { - canvas: getQueryArg( - window.location.href, - 'canvas' - ), - } - : {}; - return { name: templateType + '-' + record.id, searchLabel: record.title?.rendered + ' ' + record.id, @@ -215,7 +198,7 @@ const getNavigationCommandLoaderPerTemplate = ( templateType ) => const args = { postType: templateType, postId: record.id, - ...extraArgs, + canvas: 'edit', }; const targetUrl = addQueryArgs( 'site-editor.php', @@ -242,8 +225,7 @@ const getNavigationCommandLoaderPerTemplate = ( templateType ) => icon: symbolFilled, callback: ( { close } ) => { const args = { - path: '/patterns', - categoryType: 'wp_template_part', + postType: 'wp_template_part', categoryId: 'all-parts', }; const targetUrl = addQueryArgs( @@ -296,7 +278,7 @@ function useSiteEditorBasicNavigationCommands() { icon: navigation, callback: ( { close } ) => { const args = { - path: '/navigation', + postType: 'wp_navigation', }; const targetUrl = addQueryArgs( 'site-editor.php', args ); if ( isSiteEditor ) { @@ -332,7 +314,7 @@ function useSiteEditorBasicNavigationCommands() { icon: page, callback: ( { close } ) => { const args = { - path: '/page', + post_type: 'page', }; const targetUrl = addQueryArgs( 'site-editor.php', args ); if ( isSiteEditor ) { @@ -350,7 +332,7 @@ function useSiteEditorBasicNavigationCommands() { icon: layout, callback: ( { close } ) => { const args = { - path: '/wp_template', + postType: 'wp_template', }; const targetUrl = addQueryArgs( 'site-editor.php', args ); if ( isSiteEditor ) { @@ -370,7 +352,7 @@ function useSiteEditorBasicNavigationCommands() { callback: ( { close } ) => { if ( canCreateTemplate ) { const args = { - path: '/patterns', + postType: 'wp_block', }; const targetUrl = addQueryArgs( 'site-editor.php', args ); if ( isSiteEditor ) { diff --git a/packages/dataviews/src/add-filter.js b/packages/dataviews/src/add-filter.tsx similarity index 79% rename from packages/dataviews/src/add-filter.js rename to packages/dataviews/src/add-filter.tsx index 37c057201a6164..b9fc6e9c504c87 100644 --- a/packages/dataviews/src/add-filter.js +++ b/packages/dataviews/src/add-filter.tsx @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import type { Ref } from 'react'; + /** * WordPress dependencies */ @@ -12,6 +17,7 @@ import { forwardRef } from '@wordpress/element'; * Internal dependencies */ import { unlock } from './lock-unlock'; +import type { NormalizedFilter, View } from './types'; const { DropdownMenuV2: DropdownMenu, @@ -19,7 +25,17 @@ const { DropdownMenuItemLabelV2: DropdownMenuItemLabel, } = unlock( componentsPrivateApis ); -function AddFilter( { filters, view, onChangeView, setOpenedFilter }, ref ) { +interface AddFilterProps { + filters: NormalizedFilter[]; + view: View; + onChangeView: ( view: View ) => void; + setOpenedFilter: ( filter: string | null ) => void; +} + +function AddFilter( + { filters, view, onChangeView, setOpenedFilter }: AddFilterProps, + ref: Ref< HTMLButtonElement > +) { if ( ! filters.length || filters.every( ( { isPrimary } ) => isPrimary ) ) { return null; } diff --git a/packages/dataviews/src/constants.ts b/packages/dataviews/src/constants.ts index b9ed8caff9e940..48753470280d0c 100644 --- a/packages/dataviews/src/constants.ts +++ b/packages/dataviews/src/constants.ts @@ -3,6 +3,11 @@ */ import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import type { Operator } from './types'; + // Filter operators. export const OPERATOR_IS = 'is'; export const OPERATOR_IS_NOT = 'isNot'; @@ -19,7 +24,7 @@ export const ALL_OPERATORS = [ OPERATOR_IS_ALL, OPERATOR_IS_NOT_ALL, ]; -export const OPERATORS = { +export const OPERATORS: Record< Operator, { key: string; label: string } > = { [ OPERATOR_IS ]: { key: 'is-filter', label: __( 'Is' ), diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.tsx similarity index 89% rename from packages/dataviews/src/filter-summary.js rename to packages/dataviews/src/filter-summary.tsx index f8251c7d1e15ec..da4b2e840a297f 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.tsx @@ -2,6 +2,7 @@ * External dependencies */ import clsx from 'clsx'; +import type { RefObject } from 'react'; /** * WordPress dependencies @@ -35,8 +36,30 @@ import { OPERATOR_IS_ALL, OPERATOR_IS_NOT_ALL, } from './constants'; +import type { Filter, NormalizedFilter, Operator, Option, View } from './types'; -const FilterText = ( { activeElements, filterInView, filter } ) => { +interface FilterTextProps { + activeElements: Option[]; + filterInView?: Filter; + filter: NormalizedFilter; +} + +interface OperatorSelectorProps { + filter: NormalizedFilter; + view: View; + onChangeView: ( view: View ) => void; +} + +interface FilterSummaryProps extends OperatorSelectorProps { + addFilterRef: RefObject< HTMLButtonElement >; + openedFilter: string | null; +} + +const FilterText = ( { + activeElements, + filterInView, + filter, +}: FilterTextProps ) => { if ( activeElements === undefined || activeElements.length === 0 ) { return filter.name; } @@ -125,7 +148,11 @@ const FilterText = ( { activeElements, filterInView, filter } ) => { ); }; -function OperatorSelector( { filter, view, onChangeView } ) { +function OperatorSelector( { + filter, + view, + onChangeView, +}: OperatorSelectorProps ) { const operatorOptions = filter.operators?.map( ( operator ) => ( { value: operator, label: OPERATORS[ operator ]?.label, @@ -150,13 +177,14 @@ function OperatorSelector( { filter, view, onChangeView } ) { value={ value } options={ operatorOptions } onChange={ ( newValue ) => { + const operator = newValue as Operator; const newFilters = currentFilter ? [ ...view.filters.map( ( _filter ) => { if ( _filter.field === filter.field ) { return { ..._filter, - operator: newValue, + operator, }; } return _filter; @@ -166,7 +194,8 @@ function OperatorSelector( { filter, view, onChangeView } ) { ...view.filters, { field: filter.field, - operator: newValue, + operator, + value: undefined, }, ]; onChangeView( { @@ -188,8 +217,8 @@ export default function FilterSummary( { addFilterRef, openedFilter, ...commonProps -} ) { - const toggleRef = useRef(); +}: FilterSummaryProps ) { + const toggleRef = useRef< HTMLDivElement >( null ); const { filter, view, onChangeView } = commonProps; const filterInView = view.filters.find( ( f ) => f.field === filter.field ); const activeElements = filter.elements.filter( ( element ) => { diff --git a/packages/dataviews/src/filters.js b/packages/dataviews/src/filters.tsx similarity index 82% rename from packages/dataviews/src/filters.js rename to packages/dataviews/src/filters.tsx index aae4d3871ab1ee..df7a13b2953f16 100644 --- a/packages/dataviews/src/filters.js +++ b/packages/dataviews/src/filters.tsx @@ -2,6 +2,7 @@ * WordPress dependencies */ import { memo, useRef } from '@wordpress/element'; +import { __experimentalHStack as HStack } from '@wordpress/components'; /** * Internal dependencies @@ -11,17 +12,25 @@ import AddFilter from './add-filter'; import ResetFilters from './reset-filters'; import { sanitizeOperators } from './utils'; import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from './constants'; -import { __experimentalHStack as HStack } from '@wordpress/components'; +import type { AnyItem, NormalizedField, NormalizedFilter, View } from './types'; + +interface FiltersProps< Item extends AnyItem > { + fields: NormalizedField< Item >[]; + view: View; + onChangeView: ( view: View ) => void; + openedFilter: string | null; + setOpenedFilter: ( openedFilter: string | null ) => void; +} -const Filters = memo( function Filters( { +const Filters = memo( function Filters< Item extends AnyItem >( { fields, view, onChangeView, openedFilter, setOpenedFilter, -} ) { - const addFilterRef = useRef(); - const filters = []; +}: FiltersProps< Item > ) { + const addFilterRef = useRef< HTMLButtonElement >( null ); + const filters: NormalizedFilter[] = []; fields.forEach( ( field ) => { if ( ! field.elements?.length ) { return; diff --git a/packages/dataviews/src/reset-filters.js b/packages/dataviews/src/reset-filters.tsx similarity index 66% rename from packages/dataviews/src/reset-filters.js rename to packages/dataviews/src/reset-filters.tsx index d7143599c443bf..74570b49d9548c 100644 --- a/packages/dataviews/src/reset-filters.js +++ b/packages/dataviews/src/reset-filters.tsx @@ -4,8 +4,23 @@ import { Button } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -export default function ResetFilter( { filters, view, onChangeView } ) { - const isPrimary = ( field ) => +/** + * Internal dependencies + */ +import type { NormalizedFilter, View } from './types'; + +interface ResetFilterProps { + filters: NormalizedFilter[]; + view: View; + onChangeView: ( view: View ) => void; +} + +export default function ResetFilter( { + filters, + view, + onChangeView, +}: ResetFilterProps ) { + const isPrimary = ( field: string ) => filters.some( ( _filter ) => _filter.field === field && _filter.isPrimary ); diff --git a/packages/dataviews/src/search-widget.js b/packages/dataviews/src/search-widget.tsx similarity index 91% rename from packages/dataviews/src/search-widget.js rename to packages/dataviews/src/search-widget.tsx index 080859b15ff8e5..6a5f4b6644f677 100644 --- a/packages/dataviews/src/search-widget.js +++ b/packages/dataviews/src/search-widget.tsx @@ -22,6 +22,7 @@ import { SVG, Circle } from '@wordpress/primitives'; * Internal dependencies */ import { unlock } from './lock-unlock'; +import type { Filter, NormalizedFilter, View } from './types'; const { CompositeV2: Composite, @@ -29,6 +30,12 @@ const { useCompositeStoreV2: useCompositeStore, } = unlock( componentsPrivateApis ); +interface SearchWidgetProps { + view: View; + filter: NormalizedFilter; + onChangeView: ( view: View ) => void; +} + const radioCheck = ( @@ -39,8 +46,11 @@ function normalizeSearchInput( input = '' ) { return removeAccents( input.trim().toLowerCase() ); } -const EMPTY_ARRAY = []; -const getCurrentValue = ( filterDefinition, currentFilter ) => { +const EMPTY_ARRAY: [] = []; +const getCurrentValue = ( + filterDefinition: NormalizedFilter, + currentFilter?: Filter +) => { if ( filterDefinition.singleSelection ) { return currentFilter?.value; } @@ -56,7 +66,11 @@ const getCurrentValue = ( filterDefinition, currentFilter ) => { return EMPTY_ARRAY; }; -const getNewValue = ( filterDefinition, currentFilter, value ) => { +const getNewValue = ( + filterDefinition: NormalizedFilter, + currentFilter: Filter | undefined, + value: any +) => { if ( filterDefinition.singleSelection ) { return value; } @@ -70,7 +84,7 @@ const getNewValue = ( filterDefinition, currentFilter, value ) => { return [ value ]; }; -function ListBox( { view, filter, onChangeView } ) { +function ListBox( { view, filter, onChangeView }: SearchWidgetProps ) { const compositeStore = useCompositeStore( { virtualFocus: true, focusLoop: true, @@ -184,7 +198,7 @@ function ListBox( { view, filter, onChangeView } ) { ); } -function ComboboxList( { view, filter, onChangeView } ) { +function ComboboxList( { view, filter, onChangeView }: SearchWidgetProps ) { const [ searchValue, setSearchValue ] = useState( '' ); const deferredSearchValue = useDeferredValue( searchValue ); const currentFilter = view.filters.find( @@ -234,7 +248,13 @@ function ComboboxList( { view, filter, onChangeView } ) { setValue={ setSearchValue } >
- }> + + { __( 'Search items' ) } + + } + > { __( 'Search items' ) } 10 ? ComboboxList : ListBox; return ; } diff --git a/packages/dataviews/src/style.scss b/packages/dataviews/src/style.scss index ae886842b2e9fd..07ba9174b51200 100644 --- a/packages/dataviews/src/style.scss +++ b/packages/dataviews/src/style.scss @@ -277,10 +277,14 @@ .dataviews-view-grid { margin-bottom: auto; - grid-template-columns: repeat(2, minmax(0, 1fr)) !important; + grid-template-columns: repeat(1, minmax(0, 1fr)) !important; grid-template-rows: max-content; padding: 0 $grid-unit-40 $grid-unit-30; + @include break-mobile() { + grid-template-columns: repeat(2, minmax(0, 1fr)) !important; // Todo: eliminate !important dependency + } + @include break-xlarge() { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; // Todo: eliminate !important dependency } @@ -557,6 +561,11 @@ } line-height: 0; + flex-shrink: 0; + + .components-checkbox-control__input-container { + margin: 0; + } } .dataviews-filters__custom-menu-radio-item-prefix { diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index e4bcb3440f5854..58b0bffc922966 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -8,9 +8,10 @@ export type SortDirection = 'asc' | 'desc'; /** * Generic option type. */ -interface Option< Value extends any = any > { +export interface Option< Value extends any = any > { value: Value; label: string; + description?: string; } interface FilterByConfig { @@ -28,15 +29,13 @@ interface FilterByConfig { isPrimary?: boolean; } -type DeprecatedOperator = 'in' | 'notIn'; -type Operator = +export type Operator = | 'is' | 'isNot' | 'isAny' | 'isNone' | 'isAll' - | 'isNotAll' - | DeprecatedOperator; + | 'isNotAll'; export type AnyItem = Record< string, any >; @@ -136,6 +135,43 @@ export interface Filter { value: any; } +export interface NormalizedFilter { + /** + * The field to filter by. + */ + field: string; + + /** + * The field name. + */ + name: string; + + /** + * The list of options to pick from when using the field as a filter. + */ + elements: Option[]; + + /** + * Is a single selection filter. + */ + singleSelection: boolean; + + /** + * The list of operators supported by the field. + */ + operators: Operator[]; + + /** + * Whether the filter is visible. + */ + isVisible: boolean; + + /** + * Whether it is a primary filter. + */ + isPrimary: boolean; +} + interface ViewBase { /** * The layout of the view. diff --git a/packages/dataviews/src/utils.ts b/packages/dataviews/src/utils.ts index 8321b96b9d07b1..d895289318da03 100644 --- a/packages/dataviews/src/utils.ts +++ b/packages/dataviews/src/utils.ts @@ -20,17 +20,6 @@ export function sanitizeOperators< Item extends AnyItem >( operators = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; } - // Transform legacy in, notIn operators to is, isNot. - // To be removed in the future. - if ( operators.includes( 'in' ) ) { - operators = operators.filter( ( operator ) => operator !== 'is' ); - operators.push( 'is' ); - } - if ( operators.includes( 'notIn' ) ) { - operators = operators.filter( ( operator ) => operator !== 'notIn' ); - operators.push( 'isNot' ); - } - // Make sure only valid operators are used. operators = operators.filter( ( operator ) => ALL_OPERATORS.includes( operator ) diff --git a/packages/e2e-test-utils-playwright/src/admin/visit-site-editor.ts b/packages/e2e-test-utils-playwright/src/admin/visit-site-editor.ts index 0c9da7b695be07..f0a7db5ad966ff 100644 --- a/packages/e2e-test-utils-playwright/src/admin/visit-site-editor.ts +++ b/packages/e2e-test-utils-playwright/src/admin/visit-site-editor.ts @@ -37,31 +37,32 @@ export async function visitSiteEditor( query.set( 'canvas', canvas ); } - const canvasLoader = this.page.locator( - // Spinner was used instead of the progress bar in an earlier version of - // the site editor. - '.edit-site-canvas-loader, .edit-site-canvas-spinner' - ); - await this.visitAdminPage( 'site-editor.php', query.toString() ); - // Try waiting for the canvas loader to appear first, so that the locator - // that waits for it to disappear doesn't resolve prematurely. - await canvasLoader.waitFor().catch( () => {} ); - /** * @todo This is a workaround for the fact that the editor canvas is seen as * ready and visible before the loading spinner is hidden. Ideally, the * content underneath the loading overlay should be marked inert until the * loading is done. */ - await canvasLoader.waitFor( { - state: 'hidden', - // Bigger timeout is needed for larger entities, like the Large Post - // HTML fixture that we load for performance tests, which often doesn't - // make it under the default timeout value. - timeout: 60_000, - } ); + if ( ! query.size || postId || canvas === 'edit' ) { + const canvasLoader = this.page.locator( + // Spinner was used instead of the progress bar in an earlier + // version of the site editor. + '.edit-site-canvas-loader, .edit-site-canvas-spinner' + ); + + // Wait for the canvas loader to appear first, so that the locator that + // waits for the hidden state doesn't resolve prematurely. + await canvasLoader.waitFor( { state: 'visible' } ); + await canvasLoader.waitFor( { + state: 'hidden', + // Bigger timeout is needed for larger entities, like the Large Post + // HTML fixture that we load for performance tests, which often + // doesn't make it under the default timeout value. + timeout: 60_000, + } ); + } if ( ! options.showWelcomeGuide ) { await this.editor.setPreferences( 'core/edit-site', { diff --git a/packages/edit-site/src/components/add-new-pattern/index.js b/packages/edit-site/src/components/add-new-pattern/index.js index ce0ad6bbbccf48..bca37df9715004 100644 --- a/packages/edit-site/src/components/add-new-pattern/index.js +++ b/packages/edit-site/src/components/add-new-pattern/index.js @@ -4,7 +4,7 @@ import { DropdownMenu } from '@wordpress/components'; import { useState, useRef } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; -import { plus, symbol, symbolFilled, upload } from '@wordpress/icons'; +import { symbol, symbolFilled, upload } from '@wordpress/icons'; import { useSelect, useDispatch } from '@wordpress/data'; import { privateApis as routerPrivateApis } from '@wordpress/router'; import { @@ -18,7 +18,6 @@ import { store as coreStore } from '@wordpress/core-data'; * Internal dependencies */ import CreateTemplatePartModal from '../create-template-part-modal'; -import SidebarButton from '../sidebar-button'; import { unlock } from '../../lock-unlock'; import { PATTERN_TYPES, @@ -26,14 +25,13 @@ import { TEMPLATE_PART_POST_TYPE, } from '../../utils/constants'; -const { useHistory, useLocation } = unlock( routerPrivateApis ); +const { useHistory } = unlock( routerPrivateApis ); const { CreatePatternModal, useAddPatternCategory } = unlock( editPatternsPrivateApis ); export default function AddNewPattern() { const history = useHistory(); - const { params } = useLocation(); const [ showPatternModal, setShowPatternModal ] = useState( false ); const [ showTemplatePartModal, setShowTemplatePartModal ] = useState( false ); @@ -41,19 +39,24 @@ export default function AddNewPattern() { const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); const patternUploadInputRef = useRef(); - const isBlockBasedTheme = useSelect( - ( select ) => select( coreStore ).getCurrentTheme()?.is_block_theme, - [] - ); - - function handleCreatePattern( { pattern, categoryId } ) { + const { isBlockBasedTheme, addNewPatternLabel, addNewTemplatePartLabel } = + useSelect( ( select ) => { + const { getCurrentTheme, getPostType } = select( coreStore ); + return { + isBlockBasedTheme: getCurrentTheme()?.is_block_theme, + addNewPatternLabel: getPostType( PATTERN_TYPES.user )?.labels + ?.add_new_item, + addNewTemplatePartLabel: getPostType( TEMPLATE_PART_POST_TYPE ) + ?.labels?.add_new_item, + }; + }, [] ); + + function handleCreatePattern( { pattern } ) { setShowPatternModal( false ); history.push( { postId: pattern.id, postType: PATTERN_TYPES.user, - categoryType: PATTERN_TYPES.theme, - categoryId, canvas: 'edit', } ); } @@ -74,19 +77,19 @@ export default function AddNewPattern() { setShowTemplatePartModal( false ); } - const controls = []; - - controls.push( { - icon: symbol, - onClick: () => setShowPatternModal( true ), - title: __( 'Create pattern' ), - } ); + const controls = [ + { + icon: symbol, + onClick: () => setShowPatternModal( true ), + title: addNewPatternLabel, + }, + ]; if ( isBlockBasedTheme ) { controls.push( { icon: symbolFilled, onClick: () => setShowTemplatePartModal( true ), - title: __( 'Create template part' ), + title: addNewTemplatePartLabel, } ); } @@ -101,14 +104,15 @@ export default function AddNewPattern() { const { categoryMap, findOrCreateTerm } = useAddPatternCategory(); return ( <> - + { addNewPatternLabel && ( + + ) } { showPatternModal && ( setShowPatternModal( false ) } @@ -136,16 +140,17 @@ export default function AddNewPattern() { return; } try { + const { + params: { postType, categoryId }, + } = history.getLocationWithParams(); let currentCategoryId; // When we're not handling template parts, we should // add or create the proper pattern category. - if ( params.categoryType !== TEMPLATE_PART_POST_TYPE ) { + if ( postType !== TEMPLATE_PART_POST_TYPE ) { const currentCategory = categoryMap .values() - .find( - ( term ) => term.name === params.categoryId - ); - if ( !! currentCategory ) { + .find( ( term ) => term.name === categoryId ); + if ( currentCategory ) { currentCategoryId = currentCategory.id || ( await findOrCreateTerm( @@ -165,11 +170,10 @@ export default function AddNewPattern() { // category. if ( ! currentCategoryId && - params.categoryId !== 'my-patterns' + categoryId !== 'my-patterns' ) { history.push( { - path: `/patterns`, - categoryType: PATTERN_TYPES.theme, + postType: PATTERN_TYPES.user, categoryId: PATTERN_DEFAULT_CATEGORY, } ); } diff --git a/packages/edit-site/src/components/create-template-part-modal/index.js b/packages/edit-site/src/components/create-template-part-modal/index.js index 376deae9d7321f..a74225dd81404f 100644 --- a/packages/edit-site/src/components/create-template-part-modal/index.js +++ b/packages/edit-site/src/components/create-template-part-modal/index.js @@ -39,12 +39,18 @@ import { } from '../../utils/template-part-create'; export default function CreateTemplatePartModal( { - modalTitle = __( 'Create template part' ), + modalTitle, ...restProps } ) { + const defaultModalTitle = useSelect( + ( select ) => + select( coreStore ).getPostType( TEMPLATE_PART_POST_TYPE )?.labels + ?.add_new_item, + [] + ); return ( @@ -56,7 +62,7 @@ export default function CreateTemplatePartModal( { export function CreateTemplatePartModalContents( { defaultArea = TEMPLATE_PART_AREA_DEFAULT_CATEGORY, blocks = [], - confirmLabel = __( 'Create' ), + confirmLabel = __( 'Add' ), closeModal, onCreate, onError, diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 7a215fdd9421ee..c521ea3d8e5c35 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -217,10 +217,7 @@ export default function Editor( { isLoading, onClick } ) { case 'move-to-trash': { history.push( { - path: '/' + items[ 0 ].type, - postId: undefined, - postType: undefined, - canvas: 'view', + postType: items[ 0 ].type, } ); } break; @@ -245,7 +242,6 @@ export default function Editor( { isLoading, onClick } ) { label: __( 'Edit' ), onClick: () => { history.push( { - path: undefined, postId: newItem.id, postType: newItem.type, canvas: 'edit', diff --git a/packages/edit-site/src/components/layout/router.js b/packages/edit-site/src/components/layout/router.js index 8d9e14db92a9fa..50d8c84319e5e2 100644 --- a/packages/edit-site/src/components/layout/router.js +++ b/packages/edit-site/src/components/layout/router.js @@ -17,38 +17,74 @@ import SidebarNavigationScreen from '../sidebar-navigation-screen'; import SidebarNavigationScreenGlobalStyles from '../sidebar-navigation-screen-global-styles'; import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main'; import SidebarNavigationScreenNavigationMenus from '../sidebar-navigation-screen-navigation-menus'; -import SidebarNavigationScreenPage from '../sidebar-navigation-screen-page'; import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse'; -import SidebarNavigationScreenTemplate from '../sidebar-navigation-screen-template'; -import SidebarNavigationScreenPattern from '../sidebar-navigation-screen-pattern'; import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns'; import SidebarNavigationScreenNavigationMenu from '../sidebar-navigation-screen-navigation-menu'; import DataViewsSidebarContent from '../sidebar-dataviews'; +import { + NAVIGATION_POST_TYPE, + PATTERN_TYPES, + TEMPLATE_PART_POST_TYPE, + TEMPLATE_POST_TYPE, +} from '../../utils/constants'; const { useLocation, useHistory } = unlock( routerPrivateApis ); -export default function useLayoutAreas() { - const isSiteEditorLoading = useIsSiteEditorLoading(); +function useRedirectOldPaths() { const history = useHistory(); const { params } = useLocation(); - const { postType, postId, path, layout, isCustom, canvas } = params; - useEffect( () => { - // `/wp_template_part/all` path is no longer used and redirects to - // Patterns page for backward compatibility. + const { postType, path, categoryType, ...rest } = params; + if ( path === '/wp_template_part/all' ) { - history.replace( { path: '/patterns' } ); + history.replace( { postType: TEMPLATE_PART_POST_TYPE } ); + } + + if ( path === '/page' ) { + history.replace( { + postType: 'page', + ...rest, + } ); + } + + if ( path === '/wp_template' ) { + history.replace( { + postType: TEMPLATE_POST_TYPE, + ...rest, + } ); + } + + if ( path === '/patterns' ) { + history.replace( { + postType: + categoryType === TEMPLATE_PART_POST_TYPE + ? TEMPLATE_PART_POST_TYPE + : PATTERN_TYPES.user, + ...rest, + } ); + } + + if ( path === '/navigation' ) { + history.replace( { + postType: NAVIGATION_POST_TYPE, + ...rest, + } ); } - }, [ history, path ] ); + }, [ history, params ] ); +} - // Note: Since "sidebar" is not yet supported here, - // returning undefined from "mobile" means show the sidebar. +export default function useLayoutAreas() { + const isSiteEditorLoading = useIsSiteEditorLoading(); + const history = useHistory(); + const { params } = useLocation(); + const { postType, postId, path, layout, isCustom, canvas } = params; + useRedirectOldPaths(); // Page list - if ( path === '/page' ) { + if ( postType === 'page' ) { const isListLayout = layout === 'list' || ! layout; return { - key: 'pages-list', + key: 'pages', areas: { sidebar: ( ), content: , - preview: isListLayout && ( + preview: ( isListLayout || canvas === 'edit' ) && ( @@ -83,61 +119,17 @@ export default function useLayoutAreas() { }; } - // Regular other post types - if ( postType && postId ) { - let sidebar; - if ( postType === 'wp_template_part' || postType === 'wp_block' ) { - sidebar = ( - - ); - } else if ( postType === 'wp_template' ) { - sidebar = ( - - ); - } else if ( postType === 'page' ) { - sidebar = ( - - ); - } else { - sidebar = ( - - ); - } - return { - key: 'page', - areas: { - sidebar, - preview: , - mobile: canvas === 'edit' && ( - - ), - }, - }; - } - // Templates - if ( path === '/wp_template' ) { + if ( postType === TEMPLATE_POST_TYPE ) { const isListLayout = isCustom !== 'true' && layout === 'list'; return { - key: 'templates-list', + key: 'templates', areas: { sidebar: ( ), content: , - preview: isListLayout && ( + preview: ( isListLayout || canvas === 'edit' ) && ( ), mobile: , @@ -149,15 +141,18 @@ export default function useLayoutAreas() { } // Patterns - // `/wp_template_part/all` path is no longer used and redirects to - // Patterns page for backward compatibility. - if ( path === '/patterns' || path === '/wp_template_part/all' ) { + if ( + [ TEMPLATE_PART_POST_TYPE, PATTERN_TYPES.user ].includes( postType ) + ) { return { key: 'patterns', areas: { sidebar: , content: , mobile: , + preview: canvas === 'edit' && ( + + ), }, }; } @@ -179,14 +174,14 @@ export default function useLayoutAreas() { } // Navigation - if ( path === '/navigation' ) { + if ( postType === NAVIGATION_POST_TYPE ) { if ( postId ) { return { key: 'navigation', areas: { sidebar: ( ), preview: , diff --git a/packages/edit-site/src/components/page-pages/index.js b/packages/edit-site/src/components/page-pages/index.js index 00d86ea942a37a..391db38fbc51b6 100644 --- a/packages/edit-site/src/components/page-pages/index.js +++ b/packages/edit-site/src/components/page-pages/index.js @@ -51,8 +51,9 @@ const getFormattedDate = ( dateToDisplay ) => ); function useView( postType ) { - const { params } = useLocation(); - const { activeView = 'all', isCustom = 'false', layout } = params; + const { + params: { activeView = 'all', isCustom = 'false', layout }, + } = useLocation(); const history = useHistory(); const selectedDefaultView = useMemo( () => { const defaultView = @@ -128,6 +129,7 @@ function useView( postType ) { const setDefaultViewAndUpdateUrl = useCallback( ( viewToSet ) => { if ( viewToSet.type !== view?.type ) { + const { params } = history.getLocationWithParams(); history.push( { ...params, layout: viewToSet.type, @@ -135,7 +137,7 @@ function useView( postType ) { } setView( viewToSet ); }, - [ params, view?.type, history ] + [ history, view?.type ] ); if ( isCustom === 'false' ) { @@ -203,19 +205,21 @@ export default function PagePages() { const postType = 'page'; const [ view, setView ] = useView( postType ); const history = useHistory(); - const { params } = useLocation(); - const { isCustom = 'false' } = params; const onSelectionChange = useCallback( ( items ) => { - if ( isCustom === 'false' && view?.type === LAYOUT_LIST ) { + const { params } = history.getLocationWithParams(); + if ( + ( params.isCustom ?? 'false' ) === 'false' && + view?.type === LAYOUT_LIST + ) { history.push( { ...params, postId: items.length === 1 ? items[ 0 ].id : undefined, } ); } }, - [ history, params, view?.type, isCustom ] + [ history, view?.type ] ); const queryArgs = useMemo( () => { @@ -273,13 +277,13 @@ export default function PagePages() { [ totalItems, totalPages ] ); - const { frontPageId, postsPageId } = useSelect( ( select ) => { - const { getEntityRecord } = select( coreStore ); + const { frontPageId, postsPageId, addNewLabel } = useSelect( ( select ) => { + const { getEntityRecord, getPostType } = select( coreStore ); const siteSettings = getEntityRecord( 'root', 'site' ); - return { frontPageId: siteSettings?.page_on_front, postsPageId: siteSettings?.page_for_posts, + addNewLabel: getPostType( 'page' )?.labels?.add_new_item, }; } ); @@ -488,22 +492,23 @@ export default function PagePages() { closeModal(); }; - // TODO: we need to handle properly `data={ data || EMPTY_ARRAY }` for when `isLoading`. return ( - - { showAddPageModal && ( - - ) } - + addNewLabel && ( + <> + + { showAddPageModal && ( + + ) } + + ) } > { const [ item ] = items; - const { - params: { categoryId = PATTERN_DEFAULT_CATEGORY }, - } = useLocation(); const isThemePattern = item.type === PATTERN_TYPES.theme; - const history = useHistory(); - function onPatternSuccess( { pattern } ) { - history.push( { - categoryType: PATTERN_TYPES.theme, - categoryId, - postType: PATTERN_TYPES.user, - postId: pattern.id, - } ); - closeModal(); - } const duplicatedProps = useDuplicatePatternProps( { pattern: isThemePattern ? item : item.patternPost, - onSuccess: onPatternSuccess, + onSuccess: () => closeModal(), } ); return ( { const [ item ] = items; const { createSuccessNotice } = useDispatch( noticesStore ); - const { - params: { categoryId = PATTERN_DEFAULT_CATEGORY }, - } = useLocation(); - const history = useHistory(); - function onTemplatePartSuccess( templatePart ) { + function onTemplatePartSuccess() { createSuccessNotice( sprintf( // translators: %s: The new template part's title e.g. 'Call to action (copy)'. @@ -79,12 +56,6 @@ export const duplicateTemplatePartAction = { ), { type: 'snackbar', id: 'edit-site-patterns-success' } ); - history.push( { - postType: TEMPLATE_PART_POST_TYPE, - postId: templatePart?.id, - categoryType: TEMPLATE_PART_POST_TYPE, - categoryId, - } ); closeModal(); } return ( diff --git a/packages/edit-site/src/components/page-patterns/delete-category-menu-item.js b/packages/edit-site/src/components/page-patterns/delete-category-menu-item.js index adb33e71816e56..d366ed6fb3a0e5 100644 --- a/packages/edit-site/src/components/page-patterns/delete-category-menu-item.js +++ b/packages/edit-site/src/components/page-patterns/delete-category-menu-item.js @@ -60,8 +60,7 @@ export default function DeleteCategoryMenuItem( { category, onClose } ) { onClose?.(); history.push( { - path: `/patterns`, - categoryType: PATTERN_TYPES.theme, + postType: PATTERN_TYPES.user, categoryId: PATTERN_DEFAULT_CATEGORY, } ); } catch ( error ) { diff --git a/packages/edit-site/src/components/page-patterns/header.js b/packages/edit-site/src/components/page-patterns/header.js index 85ca443cff3b5f..ebb4a647f28ad9 100644 --- a/packages/edit-site/src/components/page-patterns/header.js +++ b/packages/edit-site/src/components/page-patterns/header.js @@ -17,6 +17,7 @@ import { moreVertical } from '@wordpress/icons'; /** * Internal dependencies */ +import AddNewPattern from '../add-new-pattern'; import RenameCategoryMenuItem from './rename-category-menu-item'; import DeleteCategoryMenuItem from './delete-category-menu-item'; import usePatternCategories from '../sidebar-navigation-screen-patterns/use-pattern-categories'; @@ -44,7 +45,7 @@ export default function PatternsHeader( { description = templatePartArea?.description || __( 'Includes every template part defined for any area.' ); - } else if ( type === PATTERN_TYPES.theme ) { + } else if ( type === PATTERN_TYPES.user && !! categoryId ) { patternCategory = patternCategories.find( ( category ) => category.name === categoryId ); @@ -57,39 +58,42 @@ export default function PatternsHeader( { } return ( - + { title } - { !! patternCategory?.id && ( - - { ( { onClose } ) => ( - - - - - ) } - - ) } + + + { !! patternCategory?.id && ( + + { ( { onClose } ) => ( + + + + + ) } + + ) } + { description ? ( diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js index f8314d65f34ff5..e47ee70dc8e3e9 100644 --- a/packages/edit-site/src/components/page-patterns/index.js +++ b/packages/edit-site/src/components/page-patterns/index.js @@ -120,7 +120,7 @@ function PreviewWrapper( { item, onClick, ariaDescribedBy, children } ) { ); } -function Preview( { item, categoryId, viewType } ) { +function Preview( { item, viewType } ) { const descriptionId = useId(); const isUserPattern = item.type === PATTERN_TYPES.user; const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; @@ -130,8 +130,6 @@ function Preview( { item, categoryId, viewType } ) { const { onClick } = useLink( { postType: item.type, postId: isUserPattern ? item.id : item.name, - categoryId, - categoryType: isTemplatePart ? item.type : PATTERN_TYPES.theme, canvas: 'edit', } ); @@ -195,14 +193,11 @@ function Author( { item, viewType } ) { ); } -function Title( { item, categoryId } ) { +function Title( { item } ) { const isUserPattern = item.type === PATTERN_TYPES.user; - const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; const { onClick } = useLink( { postType: item.type, postId: isUserPattern ? item.id : item.name, - categoryId, - categoryType: isTemplatePart ? item.type : PATTERN_TYPES.theme, canvas: 'edit', } ); return ( @@ -245,25 +240,19 @@ function Title( { item, categoryId } ) { export default function DataviewsPatterns() { const { - params: { categoryType, categoryId: categoryIdFromURL }, + params: { postType, categoryId: categoryIdFromURL }, } = useLocation(); - const type = categoryType || PATTERN_TYPES.theme; + const type = postType || PATTERN_TYPES.user; const categoryId = categoryIdFromURL || PATTERN_DEFAULT_CATEGORY; const [ view, setView ] = useState( DEFAULT_VIEW ); - const isUncategorizedThemePatterns = - type === PATTERN_TYPES.theme && categoryId === 'uncategorized'; const previousCategoryId = usePrevious( categoryId ); const viewSyncStatus = view.filters?.find( ( { field } ) => field === 'sync-status' )?.value; - const { patterns, isResolving } = usePatterns( - type, - isUncategorizedThemePatterns ? '' : categoryId, - { - search: view.search, - syncStatus: viewSyncStatus, - } - ); + const { patterns, isResolving } = usePatterns( type, categoryId, { + search: view.search, + syncStatus: viewSyncStatus, + } ); const { records } = useEntityRecords( 'postType', TEMPLATE_PART_POST_TYPE, { per_page: -1, @@ -288,11 +277,7 @@ export default function DataviewsPatterns() { header: __( 'Preview' ), id: 'preview', render: ( { item } ) => ( - + ), enableSorting: false, enableHiding: false, @@ -301,14 +286,12 @@ export default function DataviewsPatterns() { { header: __( 'Title' ), id: 'title', - render: ( { item } ) => ( - - ), + render: ( { item } ) => <Title item={ item } />, enableHiding: false, }, ]; - if ( type === PATTERN_TYPES.theme ) { + if ( type === PATTERN_TYPES.user ) { _fields.push( { header: __( 'Sync status' ), id: 'sync-status', diff --git a/packages/edit-site/src/components/page-patterns/use-patterns.js b/packages/edit-site/src/components/page-patterns/use-patterns.js index 68c70d9447be89..32377edcd96842 100644 --- a/packages/edit-site/src/components/page-patterns/use-patterns.js +++ b/packages/edit-site/src/components/page-patterns/use-patterns.js @@ -291,21 +291,28 @@ const selectUserPatterns = createSelector( ); export const usePatterns = ( - categoryType, + postType, categoryId, { search = '', syncStatus } = {} ) => { return useSelect( ( select ) => { - if ( categoryType === TEMPLATE_PART_POST_TYPE ) { + if ( postType === TEMPLATE_PART_POST_TYPE ) { return selectTemplatePartsAsPatterns( select, categoryId, search ); - } else if ( categoryType === PATTERN_TYPES.theme ) { - return selectPatterns( select, categoryId, syncStatus, search ); - } else if ( categoryType === PATTERN_TYPES.user ) { + } else if ( postType === PATTERN_TYPES.user && !! categoryId ) { + const appliedCategory = + categoryId === 'uncategorized' ? '' : categoryId; + return selectPatterns( + select, + appliedCategory, + syncStatus, + search + ); + } else if ( postType === PATTERN_TYPES.user ) { return selectUserPatterns( select, syncStatus, search ); } return { @@ -313,7 +320,7 @@ export const usePatterns = ( isResolving: false, }; }, - [ categoryId, categoryType, search, syncStatus ] + [ categoryId, postType, search, syncStatus ] ); }; diff --git a/packages/edit-site/src/components/pattern-modal/duplicate.js b/packages/edit-site/src/components/pattern-modal/duplicate.js index 18cef4a6133809..cf79dacef8d426 100644 --- a/packages/edit-site/src/components/pattern-modal/duplicate.js +++ b/packages/edit-site/src/components/pattern-modal/duplicate.js @@ -3,28 +3,21 @@ */ import { useDispatch, useSelect } from '@wordpress/data'; import { privateApis as patternsPrivateApis } from '@wordpress/patterns'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; import { privateApis as editorPrivateApis } from '@wordpress/editor'; /** * Internal dependencies */ import { PATTERN_MODALS } from './'; -import { PATTERN_TYPES } from '../../utils/constants'; import { unlock } from '../../lock-unlock'; import useEditedEntityRecord from '../use-edited-entity-record'; const { DuplicatePatternModal } = unlock( patternsPrivateApis ); -const { useHistory, useLocation } = unlock( routerPrivateApis ); const { interfaceStore } = unlock( editorPrivateApis ); export default function PatternDuplicateModal() { const { record } = useEditedEntityRecord(); - const { - params: { categoryType, categoryId }, - } = useLocation(); const { closeModal } = useDispatch( interfaceStore ); - const history = useHistory(); const isActive = useSelect( ( select ) => select( interfaceStore ).isModalActive( PATTERN_MODALS.duplicate ) @@ -34,21 +27,10 @@ export default function PatternDuplicateModal() { return null; } - function onSuccess( { pattern: newPattern } ) { - history.push( { - categoryType, - categoryId, - postType: PATTERN_TYPES.user, - postId: newPattern.id, - } ); - - closeModal(); - } - return ( <DuplicatePatternModal onClose={ closeModal } - onSuccess={ onSuccess } + onSuccess={ () => closeModal() } pattern={ record } /> ); diff --git a/packages/edit-site/src/components/sidebar-dataviews/add-new-view.js b/packages/edit-site/src/components/sidebar-dataviews/add-new-view.js index 4bf7a173525c90..ffddddb9cad292 100644 --- a/packages/edit-site/src/components/sidebar-dataviews/add-new-view.js +++ b/packages/edit-site/src/components/sidebar-dataviews/add-new-view.js @@ -22,12 +22,9 @@ import SidebarNavigationItem from '../sidebar-navigation-item'; import { DEFAULT_VIEWS } from './default-views'; import { unlock } from '../../lock-unlock'; -const { useHistory, useLocation } = unlock( routerPrivateApis ); +const { useHistory } = unlock( routerPrivateApis ); function AddNewItemModalContent( { type, setIsAdding } ) { - const { - params: { path }, - } = useLocation(); const history = useHistory(); const { saveEntityRecord } = useDispatch( coreStore ); const [ title, setTitle ] = useState( '' ); @@ -68,8 +65,11 @@ function AddNewItemModalContent( { type, setIsAdding } ) { ), } ); + const { + params: { postType }, + } = history.getLocationWithParams(); history.push( { - path, + postType, activeView: savedRecord.id, isCustom: 'true', } ); diff --git a/packages/edit-site/src/components/sidebar-dataviews/custom-dataviews-list.js b/packages/edit-site/src/components/sidebar-dataviews/custom-dataviews-list.js index ebc2f43d2e4a14..5b8ccb4b69e6da 100644 --- a/packages/edit-site/src/components/sidebar-dataviews/custom-dataviews-list.js +++ b/packages/edit-site/src/components/sidebar-dataviews/custom-dataviews-list.js @@ -27,7 +27,7 @@ import DataViewItem from './dataview-item'; import AddNewItem from './add-new-view'; import { unlock } from '../../lock-unlock'; -const { useHistory, useLocation } = unlock( routerPrivateApis ); +const { useHistory } = unlock( routerPrivateApis ); const EMPTY_ARRAY = []; @@ -81,9 +81,6 @@ function RenameItemModalContent( { dataviewId, currentTitle, setIsRenaming } ) { } function CustomDataViewItem( { dataviewId, isActive } ) { - const { - params: { path }, - } = useLocation(); const history = useHistory(); const { dataview } = useSelect( ( select ) => { @@ -145,9 +142,10 @@ function CustomDataViewItem( { dataviewId, isActive } ) { } ); if ( isActive ) { - history.replace( { - path, - } ); + const { + params: { postType }, + } = history.getLocationWithParams(); + history.replace( { postType } ); } onClose(); } } diff --git a/packages/edit-site/src/components/sidebar-dataviews/dataview-item.js b/packages/edit-site/src/components/sidebar-dataviews/dataview-item.js index 53d0f2984cb939..e6ebd5b1f8ee8b 100644 --- a/packages/edit-site/src/components/sidebar-dataviews/dataview-item.js +++ b/packages/edit-site/src/components/sidebar-dataviews/dataview-item.js @@ -29,14 +29,14 @@ export default function DataViewItem( { suffix, } ) { const { - params: { path, layout }, + params: { postType, layout }, } = useLocation(); const iconToUse = icon || VIEW_LAYOUTS.find( ( v ) => v.type === type ).icon; const linkInfo = useLink( { - path, + postType, layout, activeView: isCustom ? customViewId : slug, isCustom: isCustom ? 'true' : 'false', diff --git a/packages/edit-site/src/components/sidebar-dataviews/index.js b/packages/edit-site/src/components/sidebar-dataviews/index.js index 73d7b56b80d00d..9362308172f89a 100644 --- a/packages/edit-site/src/components/sidebar-dataviews/index.js +++ b/packages/edit-site/src/components/sidebar-dataviews/index.js @@ -14,24 +14,19 @@ const { useLocation } = unlock( routerPrivateApis ); import DataViewItem from './dataview-item'; import CustomDataViewsList from './custom-dataviews-list'; -const PATH_TO_TYPE = { - '/page': 'page', -}; - export default function DataViewsSidebarContent() { const { - params: { path, activeView = 'all', isCustom = 'false' }, + params: { postType, activeView = 'all', isCustom = 'false' }, } = useLocation(); - if ( ! path || ! PATH_TO_TYPE[ path ] ) { + if ( ! postType ) { return null; } const isCustomBoolean = isCustom === 'true'; - const type = PATH_TO_TYPE[ path ]; return ( <> <ItemGroup> - { DEFAULT_VIEWS[ type ].map( ( dataview ) => { + { DEFAULT_VIEWS[ postType ].map( ( dataview ) => { return ( <DataViewItem key={ dataview.slug } @@ -51,7 +46,7 @@ export default function DataViewsSidebarContent() { { window?.__experimentalCustomViews && ( <CustomDataViewsList activeView={ activeView } - type={ type } + type={ postType } isCustom /> ) } diff --git a/packages/edit-site/src/components/sidebar-navigation-item/index.js b/packages/edit-site/src/components/sidebar-navigation-item/index.js index 8e979e7ab8bde7..80f06d7e93133b 100644 --- a/packages/edit-site/src/components/sidebar-navigation-item/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-item/index.js @@ -29,23 +29,23 @@ export default function SidebarNavigationItem( { icon, withChevron = false, suffix, - path, + uid, + params, onClick, children, ...props } ) { const history = useHistory(); const { navigate } = useContext( SidebarNavigationContext ); - - // If there is no custom click handler, create one that navigates to `path`. + // If there is no custom click handler, create one that navigates to `params`. function handleClick( e ) { if ( onClick ) { onClick( e ); navigate( 'forward' ); - } else if ( path ) { + } else if ( params ) { e.preventDefault(); - history.push( { path } ); - navigate( 'forward', `[id="${ path }"]` ); + history.push( params ); + navigate( 'forward', `[id="${ uid }"]` ); } } @@ -57,7 +57,7 @@ export default function SidebarNavigationItem( { className ) } onClick={ handleClick } - id={ path } + id={ uid } { ...props } > <HStack justify="flex-start"> 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 87a7b6d9d15f27..31e359acb4027d 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 @@ -45,7 +45,13 @@ export function SidebarNavigationItemGlobalStyles( props ) { [] ); if ( hasGlobalStyleVariations ) { - return <SidebarNavigationItem { ...props } path="/wp_global_styles" />; + return ( + <SidebarNavigationItem + { ...props } + params={ { path: '/wp_global_styles' } } + uid="global-styles-navigation-item" + /> + ); } return ( <SidebarNavigationItem diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js index 0859d64aa1a1c6..bdfb6ac93b51c4 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js @@ -15,6 +15,11 @@ import SidebarNavigationItem from '../sidebar-navigation-item'; import { SidebarNavigationItemGlobalStyles } from '../sidebar-navigation-screen-global-styles'; import { unlock } from '../../lock-unlock'; import { store as editSiteStore } from '../../store'; +import { + NAVIGATION_POST_TYPE, + TEMPLATE_POST_TYPE, + PATTERN_TYPES, +} from '../../utils/constants'; export default function SidebarNavigationScreenMain() { const { setEditorCanvasContainerView } = unlock( @@ -37,34 +42,39 @@ export default function SidebarNavigationScreenMain() { <> <ItemGroup> <SidebarNavigationItem - path="/navigation" + uid="navigation-navigation-item" + params={ { postType: NAVIGATION_POST_TYPE } } withChevron icon={ navigation } > { __( 'Navigation' ) } </SidebarNavigationItem> <SidebarNavigationItemGlobalStyles + uid="styles-navigation-item" withChevron icon={ styles } > { __( 'Styles' ) } </SidebarNavigationItemGlobalStyles> <SidebarNavigationItem - path="/page" + uid="page-navigation-item" + params={ { postType: 'page' } } withChevron icon={ page } > { __( 'Pages' ) } </SidebarNavigationItem> <SidebarNavigationItem - path="/wp_template" + uid="template-navigation-item" + params={ { postType: TEMPLATE_POST_TYPE } } withChevron icon={ layout } > { __( 'Templates' ) } </SidebarNavigationItem> <SidebarNavigationItem - path="/patterns" + uid="patterns-navigation-item" + params={ { postType: PATTERN_TYPES.user } } withChevron icon={ symbol } > diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js index ce75f3155f33e7..7009ddc6fc9278 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js @@ -42,7 +42,7 @@ function useDeleteNavigationMenu() { type: 'snackbar', } ); - history.push( { path: '/navigation' } ); + history.push( { postType: 'wp_navigation' } ); } catch ( error ) { createErrorNotice( sprintf( 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 d5c3fa92c902f9..bc32b0a9061c1e 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 @@ -156,7 +156,7 @@ export function SidebarNavigationScreenWrapper( { const NavMenuItem = ( { postId, ...props } ) => { const linkInfo = useLink( { postId, - path: '/navigation', + postType: 'wp_navigation', } ); return <SidebarNavigationItem { ...linkInfo } { ...props } />; }; diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js index bb34802ebbbc36..568ec291f9ed11 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js @@ -20,10 +20,9 @@ const POPOVER_PROPS = { */ import { unlock } from '../../lock-unlock'; -const { useLocation, useHistory } = unlock( routerPrivateApis ); +const { useHistory } = unlock( routerPrivateApis ); export default function LeafMoreMenu( props ) { - const { params } = useLocation(); const history = useHistory(); const { block } = props; const { clientId } = block; @@ -60,10 +59,12 @@ export default function LeafMoreMenu( props ) { attributes.type && history ) { + const { params } = history.getLocationWithParams(); history.push( { postType: attributes.type, postId: attributes.id, + canvas: 'edit', }, { backPath: params, @@ -71,10 +72,12 @@ export default function LeafMoreMenu( props ) { ); } if ( name === 'core/page-list-item' && attributes.id && history ) { + const { params } = history.getLocationWithParams(); history.push( { postType: 'page', postId: attributes.id, + canvas: 'edit', }, { backPath: params, @@ -82,7 +85,7 @@ export default function LeafMoreMenu( props ) { ); } }, - [ history, params ] + [ history ] ); return ( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js deleted file mode 100644 index 51251dcf846e66..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js +++ /dev/null @@ -1,204 +0,0 @@ -/** - * WordPress dependencies - */ -import { __, sprintf } from '@wordpress/i18n'; -import { useDispatch, useSelect } from '@wordpress/data'; -import { - __experimentalVStack as VStack, - ExternalLink, - __experimentalTruncate as Truncate, -} from '@wordpress/components'; -import { store as coreStore, useEntityRecord } from '@wordpress/core-data'; -import { decodeEntities } from '@wordpress/html-entities'; -import { pencil } from '@wordpress/icons'; -import { __unstableStripHTML as stripHTML } from '@wordpress/dom'; -import { escapeAttribute } from '@wordpress/escape-html'; -import { safeDecodeURIComponent, filterURLForDisplay } from '@wordpress/url'; -import { useEffect, useCallback } from '@wordpress/element'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; -import { privateApis as editorPrivateApis } from '@wordpress/editor'; -import { store as noticesStore } from '@wordpress/notices'; - -/** - * Internal dependencies - */ -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import { unlock } from '../../lock-unlock'; -import { store as editSiteStore } from '../../store'; -import SidebarButton from '../sidebar-button'; -import PageDetails from './page-details'; -import SidebarNavigationScreenDetailsFooter from '../sidebar-navigation-screen-details-footer'; - -const { useLocation, useHistory } = unlock( routerPrivateApis ); -const { PostActions } = unlock( editorPrivateApis ); - -export default function SidebarNavigationScreenPage( { backPath } ) { - const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); - const history = useHistory(); - const { createSuccessNotice } = useDispatch( noticesStore ); - const { - params: { postId }, - } = useLocation(); - const { record, hasResolved } = useEntityRecord( - 'postType', - 'page', - postId - ); - - const { featuredMediaAltText, featuredMediaSourceUrl } = useSelect( - ( select ) => { - const { getEntityRecord } = select( coreStore ); - // Featured image. - const attachedMedia = record?.featured_media - ? getEntityRecord( - 'postType', - 'attachment', - record?.featured_media - ) - : null; - - return { - featuredMediaSourceUrl: - attachedMedia?.media_details.sizes?.medium?.source_url || - attachedMedia?.source_url, - featuredMediaAltText: escapeAttribute( - attachedMedia?.alt_text || - attachedMedia?.description?.raw || - '' - ), - }; - }, - [ record ] - ); - - // Redirect to the main pages navigation screen if the page is not found or has been deleted. - useEffect( () => { - if ( hasResolved && ! record ) { - history.push( { - path: '/page', - postId: undefined, - postType: undefined, - canvas: 'view', - } ); - } - }, [ hasResolved, record, history ] ); - - const onActionPerformed = useCallback( - ( actionId, items ) => { - switch ( actionId ) { - case 'move-to-trash': - { - history.push( { - path: '/' + items[ 0 ].type, - postId: undefined, - postType: undefined, - canvas: 'view', - } ); - } - break; - case 'duplicate-post': - { - const newItem = items[ 0 ]; - const title = - typeof newItem.title === 'string' - ? newItem.title - : newItem.title?.rendered; - createSuccessNotice( - sprintf( - // translators: %s: Title of the created post e.g: "Post 1". - __( '"%s" successfully created.' ), - title - ), - { - type: 'snackbar', - id: 'duplicate-post-action', - actions: [ - { - label: __( 'Edit' ), - onClick: () => { - history.push( { - path: undefined, - postId: newItem.id, - postType: newItem.type, - canvas: 'edit', - } ); - }, - }, - ], - } - ); - } - break; - } - }, - [ history, createSuccessNotice ] - ); - - const featureImageAltText = featuredMediaAltText - ? decodeEntities( featuredMediaAltText ) - : decodeEntities( record?.title?.rendered || __( 'Featured image' ) ); - - return record ? ( - <SidebarNavigationScreen - backPath={ backPath } - title={ decodeEntities( - record?.title?.rendered || __( '(no title)' ) - ) } - actions={ - <> - <PostActions - onActionPerformed={ onActionPerformed } - buttonProps={ { size: 'default' } } - /> - <SidebarButton - onClick={ () => setCanvasMode( 'edit' ) } - label={ __( 'Edit' ) } - icon={ pencil } - /> - </> - } - meta={ - <ExternalLink - className="edit-site-sidebar-navigation-screen__page-link" - href={ record.link } - > - { filterURLForDisplay( - safeDecodeURIComponent( record.link ) - ) } - </ExternalLink> - } - content={ - <> - { !! featuredMediaSourceUrl && ( - <VStack - className="edit-site-sidebar-navigation-screen-page__featured-image-wrapper" - alignment="left" - spacing={ 2 } - > - <div className="edit-site-sidebar-navigation-screen-page__featured-image has-image"> - <img - alt={ featureImageAltText } - src={ featuredMediaSourceUrl } - /> - </div> - </VStack> - ) } - { !! record?.excerpt?.rendered && ( - <Truncate - className="edit-site-sidebar-navigation-screen-page__excerpt" - numberOfLines={ 3 } - > - { stripHTML( record.excerpt.rendered ) } - </Truncate> - ) } - <PageDetails id={ postId } /> - </> - } - footer={ - record?.modified ? ( - <SidebarNavigationScreenDetailsFooter record={ record } /> - ) : null - } - /> - ) : null; -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-page/page-details.js b/packages/edit-site/src/components/sidebar-navigation-screen-page/page-details.js deleted file mode 100644 index 7fcedcf40ce134..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-page/page-details.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * WordPress dependencies - */ -import { __, _x, sprintf } from '@wordpress/i18n'; -import { __experimentalTruncate as Truncate } from '@wordpress/components'; -import { count as wordCount } from '@wordpress/wordcount'; -import { useSelect } from '@wordpress/data'; -import { decodeEntities } from '@wordpress/html-entities'; -import { store as coreStore, useEntityRecord } from '@wordpress/core-data'; -import { safeDecodeURIComponent } from '@wordpress/url'; - -/** - * Internal dependencies - */ -import StatusLabel from './status-label'; -import { unlock } from '../../lock-unlock'; -import { store as editSiteStore } from '../../store'; -import { - SidebarNavigationScreenDetailsPanel, - SidebarNavigationScreenDetailsPanelRow, - SidebarNavigationScreenDetailsPanelLabel, - SidebarNavigationScreenDetailsPanelValue, -} from '../sidebar-navigation-screen-details-panel'; -import { TEMPLATE_POST_TYPE } from '../../utils/constants'; - -// Taken from packages/editor/src/components/time-to-read/index.js. -const AVERAGE_READING_RATE = 189; - -function getPageDetails( page ) { - if ( ! page ) { - return []; - } - - const details = [ - { - label: __( 'Status' ), - value: ( - <StatusLabel - status={ page?.password ? 'protected' : page.status } - date={ page?.date } - short - /> - ), - }, - { - label: __( 'Slug' ), - value: ( - <Truncate numberOfLines={ 1 }> - { safeDecodeURIComponent( - page.slug || page.generated_slug - ) } - </Truncate> - ), - }, - ]; - - if ( page?.templateTitle ) { - details.push( { - label: __( 'Template' ), - value: decodeEntities( page.templateTitle ), - } ); - } - - if ( page?.parentTitle ) { - details.push( { - label: __( 'Parent' ), - value: decodeEntities( page.parentTitle || __( '(no title)' ) ), - } ); - } - - /* - * translators: If your word count is based on single characters (e.g. East Asian characters), - * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'. - * Do not translate into your own language. - */ - const wordCountType = _x( 'words', 'Word count type. Do not translate!' ); - const wordsCounted = page?.content?.rendered - ? wordCount( page.content.rendered, wordCountType ) - : 0; - const readingTime = Math.round( wordsCounted / AVERAGE_READING_RATE ); - - if ( wordsCounted && ! page?.isPostsPage ) { - details.push( - { - label: __( 'Words' ), - value: wordsCounted.toLocaleString() || __( 'Unknown' ), - }, - { - label: __( 'Time to read' ), - value: - readingTime > 1 - ? sprintf( - /* translators: %s: is the number of minutes. */ - __( '%s mins' ), - readingTime.toLocaleString() - ) - : __( '< 1 min' ), - } - ); - } - return details; -} - -export default function PageDetails( { id } ) { - const { record } = useEntityRecord( 'postType', 'page', id ); - const { parentTitle, templateTitle, isPostsPage } = useSelect( - ( select ) => { - const { getEditedPostId } = unlock( select( editSiteStore ) ); - const template = select( coreStore ).getEntityRecord( - 'postType', - TEMPLATE_POST_TYPE, - getEditedPostId() - ); - const _templateTitle = template?.title?.rendered; - - // Parent page title. - const _parentTitle = record?.parent - ? select( coreStore ).getEntityRecord( - 'postType', - 'page', - record.parent, - { - _fields: [ 'title' ], - } - )?.title?.rendered - : null; - - const { getEntityRecord } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); - - return { - parentTitle: _parentTitle, - templateTitle: _templateTitle, - isPostsPage: record?.id === siteSettings?.page_for_posts, - }; - }, - [ record?.parent, record?.id ] - ); - return ( - <SidebarNavigationScreenDetailsPanel - spacing={ 5 } - title={ __( 'Details' ) } - > - { getPageDetails( { - parentTitle, - templateTitle, - isPostsPage, - ...record, - } ).map( ( { label, value } ) => ( - <SidebarNavigationScreenDetailsPanelRow key={ label }> - <SidebarNavigationScreenDetailsPanelLabel> - { label } - </SidebarNavigationScreenDetailsPanelLabel> - <SidebarNavigationScreenDetailsPanelValue> - { value } - </SidebarNavigationScreenDetailsPanelValue> - </SidebarNavigationScreenDetailsPanelRow> - ) ) } - </SidebarNavigationScreenDetailsPanel> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-page/status-label.js b/packages/edit-site/src/components/sidebar-navigation-screen-page/status-label.js deleted file mode 100644 index 934289311b4851..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-page/status-label.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * External dependencies - */ -import clsx from 'clsx'; - -/** - * WordPress dependencies - */ -import { __, sprintf } from '@wordpress/i18n'; -import { dateI18n, getDate, humanTimeDiff } from '@wordpress/date'; -import { createInterpolateElement } from '@wordpress/element'; - -export default function StatusLabel( { status, date, short } ) { - const relateToNow = humanTimeDiff( date ); - let statusLabel = status; - switch ( status ) { - case 'publish': - statusLabel = date - ? createInterpolateElement( - sprintf( - /* translators: %s: is the relative time when the post was published. */ - __( 'Published <time>%s</time>' ), - relateToNow - ), - { time: <time dateTime={ date } /> } - ) - : __( 'Published' ); - break; - case 'future': - const formattedDate = dateI18n( - short ? 'M j' : 'F j', - getDate( date ) - ); - statusLabel = date - ? createInterpolateElement( - sprintf( - /* translators: %s: is the formatted date and time on which the post is scheduled to be published. */ - __( 'Scheduled: <time>%s</time>' ), - formattedDate - ), - { time: <time dateTime={ date } /> } - ) - : __( 'Scheduled' ); - break; - case 'draft': - statusLabel = __( 'Draft' ); - break; - case 'pending': - statusLabel = __( 'Pending' ); - break; - case 'private': - statusLabel = __( 'Private' ); - break; - case 'protected': - statusLabel = __( 'Password protected' ); - break; - } - - return ( - <div - className={ clsx( - 'edit-site-sidebar-navigation-screen-page__status', - { - [ `has-status has-${ status }-status` ]: !! status, - } - ) } - > - { statusLabel } - </div> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-page/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-page/style.scss deleted file mode 100644 index 0daf52740c649b..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-page/style.scss +++ /dev/null @@ -1,69 +0,0 @@ -.edit-site-sidebar-navigation-screen-page__featured-image-wrapper { - background-color: $gray-800; - margin-bottom: $grid-unit-20; - min-height: 128px; - border-radius: $grid-unit-05; -} - -.edit-site-sidebar-navigation-screen-page__featured-image { - border-radius: 2px; - height: 128px; - overflow: hidden; - width: 100%; - background-size: cover; - background-position: 50% 50%; - display: flex; - align-items: center; - justify-content: center; - color: $gray-600; - img { - object-fit: cover; - height: 100%; - width: 100%; - object-position: 50% 50%; - } -} - -.edit-site-sidebar-navigation-screen-page__featured-image-description { - font-size: $helptext-font-size; -} - -.edit-site-sidebar-navigation-screen-page__excerpt { - font-size: $helptext-font-size; - margin-bottom: $grid-unit-30; -} - -.edit-site-sidebar-navigation-screen-page__modified { - margin: 0 0 $grid-unit-20 $grid-unit-20; - color: $gray-600; - .components-text { - color: $gray-600; - } -} - -.edit-site-sidebar-navigation-screen-page__status { - display: inline-flex; - - time { - display: contents; - } - - svg { - height: 16px; - width: 16px; - margin-right: $grid-unit-10; - fill: $alert-yellow; - } - - &.has-publish-status svg, - &.has-future-status svg { - fill: $alert-green; - } -} - -.edit-site-sidebar-navigation-screen__actions .editor-all-actions-button { - color: inherit; - &:active { - color: inherit; - } -} 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 deleted file mode 100644 index 1b21466576f8ef..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * WordPress dependencies - */ -import { useDispatch } from '@wordpress/data'; -import { __ } from '@wordpress/i18n'; -import { pencil } from '@wordpress/icons'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -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 { store as editSiteStore } from '../../store'; -import { unlock } from '../../lock-unlock'; -import TemplateActions from '../template-actions'; - -const { useLocation, useHistory } = unlock( routerPrivateApis ); - -export default function SidebarNavigationScreenPattern( { backPath } ) { - const history = useHistory(); - const location = useLocation(); - const { - params: { postType, postId }, - } = location; - const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); - - useInitEditedEntityFromURL(); - - const patternDetails = usePatternDetails( postType, postId ); - - return ( - <SidebarNavigationScreen - actions={ - <> - <TemplateActions - postType={ postType } - postId={ postId } - toggleProps={ { as: SidebarButton } } - onRemove={ () => { - history.push( backPath ); - } } - /> - <SidebarButton - onClick={ () => setCanvasMode( 'edit' ) } - label={ __( 'Edit' ) } - icon={ pencil } - /> - </> - } - backPath={ backPath } - { ...patternDetails } - /> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/style.scss deleted file mode 100644 index 95a27ba5aa5fa5..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/style.scss +++ /dev/null @@ -1,26 +0,0 @@ -.edit-site-sidebar-navigation-screen-pattern__added-by-description { - display: flex; - align-items: center; - justify-content: space-between; - margin-top: $grid-unit-30; -} - -.edit-site-sidebar-navigation-screen-pattern__added-by-description-author { - display: inline-flex; - align-items: center; - - img { - border-radius: $grid-unit-15; - } - - svg { - fill: $gray-600; - } -} - -.edit-site-sidebar-navigation-screen-pattern__added-by-description-author-icon { - width: 24px; - height: 24px; - margin-right: $grid-unit-10; -} - diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js deleted file mode 100644 index 22d9d841dc6fd5..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import SidebarNavigationItem from '../sidebar-navigation-item'; -import useNavigationMenuTitle from './use-navigation-menu-title'; -import { useLink } from '../routes/link'; -import { NAVIGATION_POST_TYPE } from '../../utils/constants'; - -export default function TemplatePartNavigationMenuListItem( { id } ) { - const title = useNavigationMenuTitle( id ); - - const linkInfo = useLink( { - postId: id, - postType: NAVIGATION_POST_TYPE, - } ); - - if ( ! id || title === undefined ) { - return null; - } - - return ( - <SidebarNavigationItem withChevron { ...linkInfo }> - { title || __( '(no title)' ) } - </SidebarNavigationItem> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list.js deleted file mode 100644 index 4171b1e782575e..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * WordPress dependencies - */ -import { __experimentalItemGroup as ItemGroup } from '@wordpress/components'; -/** - * Internal dependencies - */ -import TemplatePartNavigationMenuListItem from './template-part-navigation-menu-list-item'; - -export default function TemplatePartNavigationMenuList( { menus } ) { - return ( - <ItemGroup className="edit-site-sidebar-navigation-screen-template-part-navigation-menu-list"> - { menus.map( ( menuId ) => ( - <TemplatePartNavigationMenuListItem - key={ menuId } - id={ menuId } - /> - ) ) } - </ItemGroup> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js deleted file mode 100644 index 3d770cc4f7c26f..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { __experimentalHeading as Heading } from '@wordpress/components'; - -/** - * Internal dependencies - */ -import NavigationMenuEditor from '../sidebar-navigation-screen-navigation-menu/navigation-menu-editor'; -import useNavigationMenuTitle from './use-navigation-menu-title'; - -export default function TemplatePartNavigationMenu( { id } ) { - const title = useNavigationMenuTitle( id ); - - if ( ! id || title === undefined ) { - return null; - } - - return ( - <> - <Heading - className="edit-site-sidebar-navigation-screen-template-part-navigation-menu__title" - size="11" - upperCase - weight={ 500 } - > - { title || __( 'Navigation' ) } - </Heading> - <NavigationMenuEditor navigationMenuId={ id } /> - </> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menus.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menus.js deleted file mode 100644 index d766d04b132ca1..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menus.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { __experimentalHeading as Heading } from '@wordpress/components'; -/** - * Internal dependencies - */ -import TemplatePartNavigationMenu from './template-part-navigation-menu'; -import TemplatePartNavigationMenuList from './template-part-navigation-menu-list'; - -export default function TemplatePartNavigationMenus( { menus } ) { - if ( ! menus.length ) { - return null; - } - - // if there is a single menu then render TemplatePartNavigationMenu - if ( menus.length === 1 ) { - return <TemplatePartNavigationMenu id={ menus[ 0 ] } />; - } - - // if there are multiple menus then render TemplatePartNavigationMenuList - return ( - <> - <Heading - className="edit-site-sidebar-navigation-screen-template-part-navigation-menu__title" - size="11" - upperCase - weight={ 500 } - > - { __( 'Navigation' ) } - </Heading> - <TemplatePartNavigationMenuList menus={ menus } /> - </> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-content.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-content.js deleted file mode 100644 index 249124b1054cec..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-content.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * WordPress dependencies - */ -import { parse } from '@wordpress/blocks'; - -/** - * Internal dependencies - */ -import TemplatePartNavigationMenus from './template-part-navigation-menus'; -import useEditedEntityRecord from '../use-edited-entity-record'; -import { TEMPLATE_PART_POST_TYPE } from '../../utils/constants'; - -function getBlocksFromRecord( record ) { - if ( record?.blocks ) { - return record?.blocks; - } - - return record?.content && typeof record.content !== 'function' - ? parse( record.content ) - : []; -} - -/** - * Retrieves a list of specific blocks from a given tree of blocks. - * - * @param {string} targetBlockType The name of the block type to find. - * @param {Array} blocks A list of blocks from a template part entity. - * - * @return {Array} A list of any navigation blocks found in the blocks. - */ -function getBlocksOfTypeFromBlocks( targetBlockType, blocks ) { - if ( ! targetBlockType || ! blocks?.length ) { - return []; - } - - const findInBlocks = ( _blocks ) => { - if ( ! _blocks ) { - return []; - } - - const navigationBlocks = []; - - for ( const block of _blocks ) { - if ( block.name === targetBlockType ) { - navigationBlocks.push( block ); - } - - if ( block?.innerBlocks ) { - const innerNavigationBlocks = findInBlocks( block.innerBlocks ); - - if ( innerNavigationBlocks.length ) { - navigationBlocks.push( ...innerNavigationBlocks ); - } - } - } - - return navigationBlocks; - }; - - return findInBlocks( blocks ); -} - -export default function useNavigationMenuContent( postType, postId ) { - const { record } = useEditedEntityRecord( postType, postId ); - - // Only managing navigation menus in template parts is supported - // to match previous behaviour. This could potentially be expanded - // to patterns as well. - if ( postType !== TEMPLATE_PART_POST_TYPE ) { - return; - } - - const blocks = getBlocksFromRecord( record ); - const navigationBlocks = getBlocksOfTypeFromBlocks( - 'core/navigation', - blocks - ); - - if ( ! navigationBlocks.length ) { - return; - } - - const navigationMenuIds = navigationBlocks?.map( - ( block ) => block.attributes.ref - ); - - // Dedupe the Navigation blocks, as you can have multiple navigation blocks in the template. - // Also, filter out undefined values, as blocks don't have an id when initially added. - const uniqueNavigationMenuIds = [ ...new Set( navigationMenuIds ) ].filter( - ( menuId ) => menuId - ); - - if ( ! uniqueNavigationMenuIds?.length ) { - return; - } - - return <TemplatePartNavigationMenus menus={ uniqueNavigationMenuIds } />; -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js deleted file mode 100644 index 4585c98ce3e1f5..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * WordPress dependencies - */ -import { useSelect } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; - -/** - * Internal dependencies - */ -import { NAVIGATION_POST_TYPE } from '../../utils/constants'; - -export default function useNavigationMenuTitle( id ) { - return useSelect( - ( select ) => { - if ( ! id ) { - return undefined; - } - - const editedRecord = select( coreStore ).getEditedEntityRecord( - 'postType', - NAVIGATION_POST_TYPE, - id - ); - - // Do not display a 'trashed' navigation menu. - return editedRecord.status === 'trash' - ? undefined - : editedRecord.title; - }, - [ id ] - ); -} 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 deleted file mode 100644 index dfdfbd87d22008..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/use-pattern-details.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - * External dependencies - */ -import { sentenceCase } from 'change-case'; - -/** - * WordPress dependencies - */ -import { __, _x, sprintf } from '@wordpress/i18n'; -import { store as coreStore } from '@wordpress/core-data'; -import { store as editorStore } from '@wordpress/editor'; -import { useSelect } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { useAddedBy } from '../page-templates/hooks'; -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'; -import { - PATTERN_TYPES, - TEMPLATE_PART_POST_TYPE, - PATTERN_SYNC_TYPES, - TEMPLATE_ORIGINS, -} from '../../utils/constants'; - -export default function usePatternDetails( postType, postId ) { - const { getDescription, getTitle, record } = useEditedEntityRecord( - postType, - postId - ); - const templatePartAreas = useSelect( - ( select ) => - select( editorStore ).__experimentalGetDefaultTemplatePartAreas(), - [] - ); - const { currentTheme, userPatternCategories } = useSelect( ( select ) => { - const { getCurrentTheme, getUserPatternCategories } = - select( coreStore ); - - return { - currentTheme: getCurrentTheme(), - userPatternCategories: getUserPatternCategories(), - }; - }, [] ); - - const addedBy = useAddedBy( postType, postId ); - const isAddedByActiveTheme = - addedBy.type === 'theme' && record.theme === currentTheme?.stylesheet; - const title = getTitle(); - let description = getDescription(); - - if ( ! description && addedBy.text ) { - description = - postType === PATTERN_TYPES.user - ? sprintf( - // translators: %s: pattern title e.g: "Header". - __( 'This is the %s pattern.' ), - getTitle() - ) - : sprintf( - // translators: %s: template part title e.g: "Header". - __( 'This is the %s template part.' ), - getTitle() - ); - } - - if ( ! description && postType === PATTERN_TYPES.user && record?.title ) { - description = sprintf( - // translators: %s: user created pattern title e.g. "Footer". - __( 'This is the %s pattern.' ), - record.title - ); - } - - const footer = record?.modified ? ( - <SidebarNavigationScreenDetailsFooter record={ record } /> - ) : null; - - const details = []; - - if ( - postType === PATTERN_TYPES.user || - postType === TEMPLATE_PART_POST_TYPE - ) { - details.push( { - label: __( 'Syncing' ), - value: - record.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced - ? _x( - 'Not synced', - 'Text that indicates that the pattern is not synchronized' - ) - : _x( - 'Synced', - 'Text that indicates that the pattern is synchronized' - ), - } ); - - if ( record.wp_pattern_category?.length === 0 ) { - details.push( { - label: __( 'Categories' ), - value: __( 'Uncategorized' ), - } ); - } - if ( record.wp_pattern_category?.length > 0 ) { - const patternCategories = new Map(); - userPatternCategories.forEach( ( userCategory ) => - patternCategories.set( userCategory.id, userCategory ) - ); - - const categories = record.wp_pattern_category - .filter( ( category ) => patternCategories.get( category ) ) - .map( ( category ) => patternCategories.get( category ).label ); - - details.push( { - label: __( 'Categories' ), - value: categories.length > 0 ? categories.join( ', ' ) : '', - } ); - } - } - - if ( postType === TEMPLATE_PART_POST_TYPE ) { - const templatePartArea = templatePartAreas.find( - ( area ) => area.area === record.area - ); - - let areaDetailValue = templatePartArea?.label; - - if ( ! areaDetailValue ) { - areaDetailValue = record.area - ? sprintf( - // translators: %s: Sentenced cased template part area e.g: "My custom area". - __( '%s (removed)' ), - sentenceCase( record.area ) - ) - : __( 'None' ); - } - - details.push( { label: __( 'Area' ), value: areaDetailValue } ); - } - - if ( - postType === TEMPLATE_PART_POST_TYPE && - addedBy.text && - ! isAddedByActiveTheme - ) { - details.push( { - label: __( 'Added by' ), - value: ( - <span className="edit-site-sidebar-navigation-screen-pattern__added-by-description-author"> - { addedBy.text } - </span> - ), - } ); - } - - if ( - postType === TEMPLATE_PART_POST_TYPE && - addedBy.text && - ( record.origin === TEMPLATE_ORIGINS.plugin || - record.has_theme_file === true ) - ) { - details.push( { - label: __( 'Customized' ), - value: ( - <span className="edit-site-sidebar-navigation-screen-pattern__added-by-description-customized"> - { addedBy.isCustomized ? __( 'Yes' ) : __( 'No' ) } - </span> - ), - } ); - } - - const content = ( - <> - { useNavigationMenuContent( postType, postId ) } - { !! details.length && ( - <SidebarNavigationScreenDetailsPanel - spacing={ 5 } - title={ __( 'Details' ) } - > - { details.map( ( { label, value } ) => ( - <SidebarNavigationScreenDetailsPanelRow key={ label }> - <SidebarNavigationScreenDetailsPanelLabel> - { label } - </SidebarNavigationScreenDetailsPanelLabel> - <SidebarNavigationScreenDetailsPanelValue> - { value } - </SidebarNavigationScreenDetailsPanelValue> - </SidebarNavigationScreenDetailsPanelRow> - ) ) } - </SidebarNavigationScreenDetailsPanel> - ) } - </> - ); - - return { title, description, content, footer }; -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/category-item.js b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/category-item.js index 49274a0435bafa..092f090e3c152e 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/category-item.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/category-item.js @@ -3,6 +3,7 @@ */ import SidebarNavigationItem from '../sidebar-navigation-item'; import { useLink } from '../routes/link'; +import { TEMPLATE_PART_POST_TYPE, PATTERN_TYPES } from '../../utils/constants'; export default function CategoryItem( { count, @@ -11,12 +12,13 @@ export default function CategoryItem( { isActive, label, type, - path = '/patterns', } ) { const linkInfo = useLink( { - path, - categoryType: type, categoryId: id, + postType: + type === TEMPLATE_PART_POST_TYPE + ? TEMPLATE_PART_POST_TYPE + : PATTERN_TYPES.user, } ); if ( ! count ) { diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js index 9c8681b86dbf37..e0d085812ba53c 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-patterns/index.js @@ -15,7 +15,6 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ -import AddNewPattern from '../add-new-pattern'; import SidebarNavigationScreen from '../sidebar-navigation-screen'; import CategoryItem from './category-item'; import { @@ -31,7 +30,6 @@ import { unlock } from '../../lock-unlock'; const { useLocation } = unlock( routerPrivateApis ); function CategoriesGroup( { - path, templatePartAreas, patternCategories, currentCategory, @@ -43,7 +41,6 @@ function CategoriesGroup( { <ItemGroup className="edit-site-sidebar-navigation-screen-patterns__group"> <CategoryItem key="all" - path={ path } count={ Object.values( templatePartAreas ) .map( ( { templateParts } ) => templateParts?.length || 0 ) .reduce( ( acc, val ) => acc + val, 0 ) } @@ -60,7 +57,6 @@ function CategoriesGroup( { ( [ area, { label, templateParts } ] ) => ( <CategoryItem key={ area } - path={ path } count={ templateParts?.length } icon={ getTemplatePartIcon( area ) } label={ label } @@ -77,32 +73,28 @@ function CategoriesGroup( { { allPatterns && ( <CategoryItem key={ allPatterns.name } - path={ path } count={ allPatterns.count } label={ allPatterns.label } icon={ file } id={ allPatterns.name } - type="pattern" + type={ PATTERN_TYPES.user } isActive={ currentCategory === `${ allPatterns.name }` && - ( currentType === PATTERN_TYPES.theme || - currentType === PATTERN_TYPES.user ) + currentType === PATTERN_TYPES.user } /> ) } { otherPatterns.map( ( category ) => ( <CategoryItem key={ category.name } - path={ path } count={ category.count } label={ category.label } icon={ file } id={ category.name } - type="pattern" + type={ PATTERN_TYPES.user } isActive={ currentCategory === `${ category.name }` && - ( currentType === PATTERN_TYPES.theme || - currentType === PATTERN_TYPES.user ) + currentType === PATTERN_TYPES.user } /> ) ) } @@ -112,10 +104,10 @@ function CategoriesGroup( { export default function SidebarNavigationScreenPatterns( { backPath } ) { const { - params: { categoryType, categoryId, path }, + params: { postType, categoryId }, } = useLocation(); const currentCategory = categoryId || PATTERN_DEFAULT_CATEGORY; - const currentType = categoryType || PATTERN_TYPES.theme; + const currentType = postType || PATTERN_TYPES.user; const { templatePartAreas, hasTemplateParts, isLoading } = useTemplatePartAreas(); @@ -133,7 +125,6 @@ export default function SidebarNavigationScreenPatterns( { backPath } ) { 'Manage what patterns are available when editing the site.' ) } backPath={ backPath } - actions={ <AddNewPattern /> } content={ <> { isLoading && __( 'Loading items…' ) } @@ -145,7 +136,6 @@ export default function SidebarNavigationScreenPatterns( { backPath } ) { </ItemGroup> ) } <CategoriesGroup - path={ path } templatePartAreas={ templatePartAreas } patternCategories={ patternCategories } currentCategory={ currentCategory } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template/home-template-details.js b/packages/edit-site/src/components/sidebar-navigation-screen-template/home-template-details.js deleted file mode 100644 index 57a13377617533..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-template/home-template-details.js +++ /dev/null @@ -1,144 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { debounce } from '@wordpress/compose'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; -import { - CheckboxControl, - __experimentalInputControl as InputControl, - __experimentalNumberControl as NumberControl, -} from '@wordpress/components'; -import { useState, useEffect } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import { - SidebarNavigationScreenDetailsPanel, - SidebarNavigationScreenDetailsPanelRow, -} from '../sidebar-navigation-screen-details-panel'; - -const EMPTY_OBJECT = {}; - -export default function HomeTemplateDetails() { - const { editEntityRecord } = useDispatch( coreStore ); - - const { - allowCommentsOnNewPosts, - postsPerPage, - postsPageTitle, - postsPageId, - } = useSelect( ( select ) => { - const { getEntityRecord } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); - const _postsPageRecord = siteSettings?.page_for_posts - ? getEntityRecord( - 'postType', - 'page', - siteSettings?.page_for_posts - ) - : EMPTY_OBJECT; - - return { - allowCommentsOnNewPosts: - siteSettings?.default_comment_status === 'open', - postsPageTitle: _postsPageRecord?.title?.rendered, - postsPageId: _postsPageRecord?.id, - postsPerPage: siteSettings?.posts_per_page, - }; - }, [] ); - - const [ commentsOnNewPostsValue, setCommentsOnNewPostsValue ] = - useState( '' ); - const [ postsCountValue, setPostsCountValue ] = useState( 1 ); - const [ postsPageTitleValue, setPostsPageTitleValue ] = useState( '' ); - - /* - * This hook serves to set the server-retrieved values, - * postsPageTitle, allowCommentsOnNewPosts, postsPerPage, - * to local state. - */ - useEffect( () => { - setCommentsOnNewPostsValue( allowCommentsOnNewPosts ); - setPostsPageTitleValue( postsPageTitle ); - setPostsCountValue( postsPerPage ); - }, [ postsPageTitle, allowCommentsOnNewPosts, postsPerPage ] ); - - const setAllowCommentsOnNewPosts = ( newValue ) => { - setCommentsOnNewPostsValue( newValue ); - editEntityRecord( 'root', 'site', undefined, { - default_comment_status: newValue ? 'open' : null, - } ); - }; - - const setPostsPageTitle = ( newValue ) => { - setPostsPageTitleValue( newValue ); - editEntityRecord( 'postType', 'page', postsPageId, { - title: newValue, - } ); - }; - - const setPostsPerPage = ( newValue ) => { - setPostsCountValue( newValue ); - editEntityRecord( 'root', 'site', undefined, { - posts_per_page: newValue, - } ); - }; - - return ( - <> - <SidebarNavigationScreenDetailsPanel spacing={ 6 }> - { postsPageId && ( - <SidebarNavigationScreenDetailsPanelRow> - <InputControl - className="edit-site-sidebar-navigation-screen__input-control" - placeholder={ __( 'No Title' ) } - size={ '__unstable-large' } - value={ postsPageTitleValue } - onChange={ debounce( setPostsPageTitle, 300 ) } - label={ __( 'Blog title' ) } - help={ __( - 'Set the Posts Page title. Appears in search results, and when the page is shared on social media.' - ) } - /> - </SidebarNavigationScreenDetailsPanelRow> - ) } - <SidebarNavigationScreenDetailsPanelRow> - <NumberControl - className="edit-site-sidebar-navigation-screen__input-control" - placeholder={ 0 } - value={ postsCountValue } - size={ '__unstable-large' } - spinControls="custom" - step="1" - min="1" - onChange={ setPostsPerPage } - label={ __( 'Posts per page' ) } - help={ __( - 'Set the default number of posts to display on blog pages, including categories and tags. Some templates may override this setting.' - ) } - /> - </SidebarNavigationScreenDetailsPanelRow> - </SidebarNavigationScreenDetailsPanel> - - <SidebarNavigationScreenDetailsPanel - title={ __( 'Discussion' ) } - spacing={ 3 } - > - <SidebarNavigationScreenDetailsPanelRow> - <CheckboxControl - className="edit-site-sidebar-navigation-screen__input-control" - label={ __( 'Allow comments on new posts' ) } - help={ __( - 'Changes will apply to new posts only. Individual posts may override these settings.' - ) } - checked={ commentsOnNewPostsValue } - onChange={ setAllowCommentsOnNewPosts } - /> - </SidebarNavigationScreenDetailsPanelRow> - </SidebarNavigationScreenDetailsPanel> - </> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-template/index.js deleted file mode 100644 index 76641f969fca79..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-template/index.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * WordPress dependencies - */ -import { __, _x } from '@wordpress/i18n'; -import { useDispatch, useSelect } from '@wordpress/data'; -import { pencil } from '@wordpress/icons'; -import { Icon } from '@wordpress/components'; -import { store as coreStore } from '@wordpress/core-data'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import TemplateAreas from './template-areas'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import useEditedEntityRecord from '../use-edited-entity-record'; -import { unlock } from '../../lock-unlock'; -import { store as editSiteStore } from '../../store'; -import SidebarButton from '../sidebar-button'; -import { useAddedBy } from '../page-templates/hooks'; -import TemplateActions from '../template-actions'; -import HomeTemplateDetails from './home-template-details'; -import SidebarNavigationScreenDetailsFooter from '../sidebar-navigation-screen-details-footer'; - -const { useHistory, useLocation } = unlock( routerPrivateApis ); - -function useTemplateDetails( postType, postId ) { - const { getDescription, getTitle, record } = useEditedEntityRecord( - postType, - postId - ); - const currentTheme = useSelect( - ( select ) => select( coreStore ).getCurrentTheme(), - [] - ); - const addedBy = useAddedBy( postType, postId ); - const isAddedByActiveTheme = - addedBy.type === 'theme' && record.theme === currentTheme?.stylesheet; - const title = getTitle(); - let descriptionText = getDescription(); - - if ( ! descriptionText && addedBy.text ) { - descriptionText = __( - 'This is a custom template that can be applied manually to any Post or Page.' - ); - } - - const content = - record?.slug === 'home' || record?.slug === 'index' ? ( - <> - <HomeTemplateDetails /> - <TemplateAreas /> - </> - ) : ( - <TemplateAreas /> - ); - - const footer = record?.modified ? ( - <SidebarNavigationScreenDetailsFooter record={ record } /> - ) : null; - - const description = ( - <> - { descriptionText } - - { addedBy.text && ! isAddedByActiveTheme && ( - <span className="edit-site-sidebar-navigation-screen-template__added-by-description"> - <span className="edit-site-sidebar-navigation-screen-template__added-by-description-author"> - <span className="edit-site-sidebar-navigation-screen-template__added-by-description-author-icon"> - { addedBy.imageUrl ? ( - <img - src={ addedBy.imageUrl } - alt="" - width="24" - height="24" - /> - ) : ( - <Icon icon={ addedBy.icon } /> - ) } - </span> - { addedBy.text } - </span> - - { addedBy.isCustomized && ( - <span className="edit-site-sidebar-navigation-screen-template__added-by-description-customized"> - { _x( '(Customized)', 'template' ) } - </span> - ) } - </span> - ) } - </> - ); - - return { title, description, content, footer }; -} - -export default function SidebarNavigationScreenTemplate( { backPath } ) { - const history = useHistory(); - const { - params: { postType, postId }, - } = useLocation(); - const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); - const { title, content, description, footer } = useTemplateDetails( - postType, - postId - ); - - return ( - <SidebarNavigationScreen - title={ title } - backPath={ backPath } - actions={ - <> - <TemplateActions - postType={ postType } - postId={ postId } - toggleProps={ { as: SidebarButton } } - onRemove={ () => { - history.push( { path: '/' + postType } ); - } } - /> - <SidebarButton - onClick={ () => setCanvasMode( 'edit' ) } - label={ __( 'Edit' ) } - icon={ pencil } - /> - </> - } - description={ description } - content={ content } - footer={ footer } - /> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-template/style.scss deleted file mode 100644 index 4e6fcc3700fc4d..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-template/style.scss +++ /dev/null @@ -1,53 +0,0 @@ -.edit-site-sidebar-navigation-screen-template__added-by-description { - display: flex; - align-items: center; - justify-content: space-between; - margin-top: $grid-unit-30; -} - -.edit-site-sidebar-navigation-screen-template__added-by-description-author { - display: inline-flex; - align-items: center; - - img { - border-radius: $grid-unit-15; - width: 20px; - height: 20px; - } - - svg { - fill: $gray-600; - } -} - -.edit-site-sidebar-navigation-screen-template__added-by-description-author-icon { - width: 24px; - height: 24px; - margin-right: $grid-unit-05; - display: inline-flex; - align-items: center; - justify-content: center; -} - -.edit-site-sidebar-navigation-screen-template__template-area-button { - color: $white; - display: flex; - align-items: center; - width: 100%; - flex-wrap: nowrap; - border-radius: 4px; - &:hover, - &:focus { - background: $gray-800; - color: $white; - } -} - -.edit-site-sidebar-navigation-screen-template__template-area-label-text { - margin: 0 $grid-unit-20 0 $grid-unit-05; - flex-grow: 1; -} - -.edit-site-sidebar-navigation-screen-template__template-icon { - display: flex; -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template/template-areas.js b/packages/edit-site/src/components/sidebar-navigation-screen-template/template-areas.js deleted file mode 100644 index db59f6886124be..00000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-template/template-areas.js +++ /dev/null @@ -1,135 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { useSelect } from '@wordpress/data'; -import { - __experimentalTruncate as Truncate, - __experimentalItemGroup as ItemGroup, -} from '@wordpress/components'; -import { store as editorStore } from '@wordpress/editor'; -import { useMemo } from '@wordpress/element'; -import { decodeEntities } from '@wordpress/html-entities'; - -/** - * Internal dependencies - */ -import { - SidebarNavigationScreenDetailsPanel, - SidebarNavigationScreenDetailsPanelRow, -} from '../sidebar-navigation-screen-details-panel'; -import { unlock } from '../../lock-unlock'; -import { store as editSiteStore } from '../../store'; -import { useLink } from '../routes/link'; -import SidebarNavigationItem from '../sidebar-navigation-item'; -import { TEMPLATE_PART_POST_TYPE } from '../../utils/constants'; - -function TemplateAreaButton( { postId, area, title } ) { - const templatePartArea = useSelect( - ( select ) => { - const defaultAreas = - select( - editorStore - ).__experimentalGetDefaultTemplatePartAreas(); - - return defaultAreas.find( - ( defaultArea ) => defaultArea.area === area - ); - }, - [ area ] - ); - const linkInfo = useLink( { - postType: TEMPLATE_PART_POST_TYPE, - postId, - } ); - - return ( - <SidebarNavigationItem - className="edit-site-sidebar-navigation-screen-template__template-area-button" - { ...linkInfo } - icon={ templatePartArea?.icon } - withChevron - > - <Truncate - limit={ 20 } - ellipsizeMode="tail" - numberOfLines={ 1 } - className="edit-site-sidebar-navigation-screen-template__template-area-label-text" - > - { decodeEntities( title ) } - </Truncate> - </SidebarNavigationItem> - ); -} - -export default function TemplateAreas() { - const { templatePartAreas, currentTemplateParts } = useSelect( - ( select ) => { - const { getSettings, getCurrentTemplateTemplateParts } = unlock( - select( editSiteStore ) - ); - return { - templatePartAreas: getSettings()?.defaultTemplatePartAreas, - currentTemplateParts: getCurrentTemplateTemplateParts(), - }; - }, - [] - ); - - /* - * Merge data in currentTemplateParts with templatePartAreas, - * which contains the template icon and fallback labels - */ - const templateAreas = useMemo( () => { - // Keep track of template part IDs that have already been added to the array. - const templatePartIds = new Set(); - const filterOutDuplicateTemplateParts = ( currentTemplatePart ) => { - // If the template part has already been added to the array, skip it. - if ( templatePartIds.has( currentTemplatePart.templatePart.id ) ) { - return; - } - // Add to the array of template part IDs. - templatePartIds.add( currentTemplatePart.templatePart.id ); - return currentTemplatePart; - }; - - return currentTemplateParts.length && templatePartAreas - ? currentTemplateParts - .filter( filterOutDuplicateTemplateParts ) - .map( ( { templatePart, block } ) => ( { - ...templatePartAreas?.find( - ( { area } ) => area === templatePart?.area - ), - ...templatePart, - clientId: block.clientId, - } ) ) - : []; - }, [ currentTemplateParts, templatePartAreas ] ); - - if ( ! templateAreas.length ) { - return null; - } - - return ( - <SidebarNavigationScreenDetailsPanel - title={ __( 'Areas' ) } - spacing={ 3 } - > - <ItemGroup> - { templateAreas.map( - ( { clientId, label, area, theme, slug, title } ) => ( - <SidebarNavigationScreenDetailsPanelRow - key={ clientId } - > - <TemplateAreaButton - postId={ `${ theme }//${ slug }` } - title={ title?.rendered || label } - area={ area } - /> - </SidebarNavigationScreenDetailsPanelRow> - ) - ) } - </ItemGroup> - </SidebarNavigationScreenDetailsPanel> - ); -} diff --git a/packages/edit-site/src/components/sync-state-with-url/use-init-edited-entity-from-url.js b/packages/edit-site/src/components/sync-state-with-url/use-init-edited-entity-from-url.js index 1f9d71945f76cf..0b3eb147527877 100644 --- a/packages/edit-site/src/components/sync-state-with-url/use-init-edited-entity-from-url.js +++ b/packages/edit-site/src/components/sync-state-with-url/use-init-edited-entity-from-url.js @@ -27,7 +27,9 @@ const postTypesWithoutParentTemplate = [ PATTERN_TYPES.user, ]; -function useResolveEditedEntityAndContext( { path, postId, postType } ) { +const authorizedPostTypes = [ 'page' ]; + +function useResolveEditedEntityAndContext( { postId, postType } ) { const { hasLoadedAllDependencies, homepageId, @@ -81,7 +83,10 @@ function useResolveEditedEntityAndContext( { path, postId, postType } ) { ( select ) => { // If we're rendering a post type that doesn't have a template // no need to resolve its template. - if ( postTypesWithoutParentTemplate.includes( postType ) ) { + if ( + postTypesWithoutParentTemplate.includes( postType ) && + postId + ) { return undefined; } @@ -168,16 +173,16 @@ function useResolveEditedEntityAndContext( { path, postId, postType } ) { return undefined; } - // If we're rendering a specific page, post... we need to resolve its template. - if ( postType && postId ) { + // If we're rendering a specific page, we need to resolve its template. + // The site editor only supports pages for now, not other CPTs. + if ( + postType && + postId && + authorizedPostTypes.includes( postType ) + ) { return resolveTemplateForPostTypeAndId( postType, postId ); } - // Some URLs in list views are different - if ( path === '/page' && postId ) { - return resolveTemplateForPostTypeAndId( 'page', postId ); - } - // If we're rendering the home page, and we have a static home page, resolve its template. if ( homepageId ) { return resolveTemplateForPostTypeAndId( 'page', homepageId ); @@ -196,37 +201,27 @@ function useResolveEditedEntityAndContext( { path, postId, postType } ) { url, postId, postType, - path, frontPageTemplateId, ] ); const context = useMemo( () => { - if ( postTypesWithoutParentTemplate.includes( postType ) ) { + if ( postTypesWithoutParentTemplate.includes( postType ) && postId ) { return {}; } - if ( postType && postId ) { + if ( postType && postId && authorizedPostTypes.includes( postType ) ) { return { postType, postId }; } - // Some URLs in list views are different - if ( path === '/page' && postId ) { - return { postType: 'page', postId }; - } - if ( homepageId ) { return { postType: 'page', postId: homepageId }; } return {}; - }, [ homepageId, postType, postId, path ] ); - - if ( path === '/wp_template' && postId ) { - return { isReady: true, postType: 'wp_template', postId, context }; - } + }, [ homepageId, postType, postId ] ); - if ( postTypesWithoutParentTemplate.includes( postType ) ) { + if ( postTypesWithoutParentTemplate.includes( postType ) && postId ) { return { isReady: true, postType, postId, context }; } 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 fdea50d8afbddb..2b5d0d8614c954 100644 --- a/packages/edit-site/src/hooks/commands/use-common-commands.js +++ b/packages/edit-site/src/hooks/commands/use-common-commands.js @@ -18,14 +18,12 @@ 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 { useViewportMatch } from '@wordpress/compose'; /** * Internal dependencies */ import { unlock } from '../../lock-unlock'; import { store as editSiteStore } from '../../store'; -import getIsListPage from '../../utils/get-is-list-page'; const { useGlobalStylesReset } = unlock( blockEditorPrivateApis ); const { useHistory, useLocation } = unlock( routerPrivateApis ); @@ -35,8 +33,6 @@ function useGlobalStylesOpenStylesCommands() { useDispatch( editSiteStore ) ); const { params } = useLocation(); - const isMobileViewport = useViewportMatch( 'medium', '<' ); - const isEditorPage = ! getIsListPage( params, isMobileViewport ); const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); const history = useHistory(); @@ -55,13 +51,13 @@ function useGlobalStylesOpenStylesCommands() { label: __( 'Open styles' ), callback: ( { close } ) => { close(); - if ( ! isEditorPage ) { + if ( ! params.postId ) { history.push( { path: '/wp_global_styles', canvas: 'edit', } ); } - if ( isEditorPage && getCanvasMode() !== 'edit' ) { + if ( params.postId && getCanvasMode() !== 'edit' ) { setCanvasMode( 'edit' ); } openGeneralSidebar( 'edit-site/global-styles' ); @@ -73,9 +69,9 @@ function useGlobalStylesOpenStylesCommands() { history, openGeneralSidebar, setCanvasMode, - isEditorPage, getCanvasMode, isBlockBasedTheme, + params.postId, ] ); return { @@ -89,8 +85,6 @@ function useGlobalStylesToggleWelcomeGuideCommands() { useDispatch( editSiteStore ) ); const { params } = useLocation(); - const isMobileViewport = useViewportMatch( 'medium', '<' ); - const isEditorPage = ! getIsListPage( params, isMobileViewport ); const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); const { set } = useDispatch( preferencesStore ); @@ -110,13 +104,13 @@ function useGlobalStylesToggleWelcomeGuideCommands() { label: __( 'Learn about styles' ), callback: ( { close } ) => { close(); - if ( ! isEditorPage ) { + if ( ! params.postId ) { history.push( { path: '/wp_global_styles', canvas: 'edit', } ); } - if ( isEditorPage && getCanvasMode() !== 'edit' ) { + if ( params.postId && getCanvasMode() !== 'edit' ) { setCanvasMode( 'edit' ); } openGeneralSidebar( 'edit-site/global-styles' ); @@ -134,10 +128,10 @@ function useGlobalStylesToggleWelcomeGuideCommands() { history, openGeneralSidebar, setCanvasMode, - isEditorPage, getCanvasMode, isBlockBasedTheme, set, + params.postId, ] ); return { @@ -176,9 +170,6 @@ function useGlobalStylesOpenCssCommands() { const { openGeneralSidebar, setEditorCanvasContainerView, setCanvasMode } = unlock( useDispatch( editSiteStore ) ); const { params } = useLocation(); - const isMobileViewport = useViewportMatch( 'medium', '<' ); - const isListPage = getIsListPage( params, isMobileViewport ); - const isEditorPage = ! isListPage; const history = useHistory(); const { canEditCSS } = useSelect( ( select ) => { const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = @@ -207,13 +198,13 @@ function useGlobalStylesOpenCssCommands() { icon: brush, callback: ( { close } ) => { close(); - if ( ! isEditorPage ) { + if ( ! params.postId ) { history.push( { path: '/wp_global_styles', canvas: 'edit', } ); } - if ( isEditorPage && getCanvasMode() !== 'edit' ) { + if ( params.postId && getCanvasMode() !== 'edit' ) { setCanvasMode( 'edit' ); } openGeneralSidebar( 'edit-site/global-styles' ); @@ -226,9 +217,9 @@ function useGlobalStylesOpenCssCommands() { openGeneralSidebar, setEditorCanvasContainerView, canEditCSS, - isEditorPage, getCanvasMode, setCanvasMode, + params.postId, ] ); return { isLoading: false, @@ -241,8 +232,6 @@ function useGlobalStylesOpenRevisionsCommands() { unlock( useDispatch( editSiteStore ) ); const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); const { params } = useLocation(); - const isMobileViewport = useViewportMatch( 'medium', '<' ); - const isEditorPage = ! getIsListPage( params, isMobileViewport ); const history = useHistory(); const hasRevisions = useSelect( ( select ) => { const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = @@ -266,13 +255,13 @@ function useGlobalStylesOpenRevisionsCommands() { icon: backup, callback: ( { close } ) => { close(); - if ( ! isEditorPage ) { + if ( ! params.postId ) { history.push( { path: '/wp_global_styles', canvas: 'edit', } ); } - if ( isEditorPage && getCanvasMode() !== 'edit' ) { + if ( params.postId && getCanvasMode() !== 'edit' ) { setCanvasMode( 'edit' ); } openGeneralSidebar( 'edit-site/global-styles' ); @@ -285,9 +274,9 @@ function useGlobalStylesOpenRevisionsCommands() { history, openGeneralSidebar, setEditorCanvasContainerView, - isEditorPage, getCanvasMode, setCanvasMode, + params.postId, ] ); return { 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 6afe4dcaa7ea97..1ca24b318a4448 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 @@ -32,7 +32,7 @@ import isTemplateRemovable from '../../utils/is-template-removable'; import isTemplateRevertable from '../../utils/is-template-revertable'; import { PATTERN_MODALS } from '../../components/pattern-modal'; import { unlock } from '../../lock-unlock'; -import { TEMPLATE_POST_TYPE } from '../../utils/constants'; +import { PATTERN_TYPES, TEMPLATE_POST_TYPE } from '../../utils/constants'; import { useLink } from '../../components/routes/link'; const { interfaceStore } = unlock( editorPrivateApis ); @@ -153,8 +153,6 @@ function useManipulateDocumentCommands() { __( 'Delete template part: %s' ), decodeEntities( template.title ) ); - const path = - template.type === TEMPLATE_POST_TYPE ? '/wp_template' : '/patterns'; commands.push( { name: 'core/remove-template', label, @@ -163,7 +161,7 @@ function useManipulateDocumentCommands() { removeTemplate( template ); // Navigate to the template list history.push( { - path, + postType: template.type, } ); close(); }, @@ -237,7 +235,7 @@ function usePatternCommands() { const commands = []; - if ( pattern?.type === 'wp_block' ) { + if ( pattern?.type === PATTERN_TYPES.user ) { commands.push( { name: 'core/rename-pattern', label: __( 'Rename pattern' ), diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index d8ee1c1d16dfa6..5b5acffd2596e4 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -25,11 +25,8 @@ @import "./components/sidebar-navigation-screen/style.scss"; @import "./components/sidebar-navigation-screen-details-footer/style.scss"; @import "./components/sidebar-navigation-screen-navigation-menu/style.scss"; -@import "./components/sidebar-navigation-screen-page/style.scss"; @import "components/sidebar-navigation-screen-details-panel/style.scss"; -@import "./components/sidebar-navigation-screen-pattern/style.scss"; @import "./components/sidebar-navigation-screen-patterns/style.scss"; -@import "./components/sidebar-navigation-screen-template/style.scss"; @import "./components/sidebar-dataviews/style.scss"; @import "./components/site-hub/style.scss"; @import "./components/sidebar-navigation-screen-navigation-menus/style.scss"; diff --git a/packages/edit-site/src/utils/get-is-list-page.js b/packages/edit-site/src/utils/get-is-list-page.js deleted file mode 100644 index f7312ec3c1c292..00000000000000 --- a/packages/edit-site/src/utils/get-is-list-page.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Returns if the params match the list page route. - * - * @param {Object} params The url params. - * @param {string} params.path The current path. - * @param {string} [params.categoryType] The current category type. - * @param {string} [params.categoryId] The current category id. - * @param {boolean} isMobileViewport Is mobile viewport. - * - * @return {boolean} Is list page or not. - */ -export default function getIsListPage( - { path, categoryType, categoryId }, - isMobileViewport -) { - return ( - [ '/wp_template', '/pages' ].includes( path ) || - ( path === '/patterns' && - // Don't treat "/patterns" without categoryType and categoryId as a - // list page in mobile because the sidebar covers the whole page. - ( ! isMobileViewport || ( !! categoryType && !! categoryId ) ) ) - ); -} diff --git a/packages/edit-site/src/utils/use-activate-theme.js b/packages/edit-site/src/utils/use-activate-theme.js index e5f9488a3edd8b..0dafd88340ba75 100644 --- a/packages/edit-site/src/utils/use-activate-theme.js +++ b/packages/edit-site/src/utils/use-activate-theme.js @@ -14,7 +14,7 @@ import { currentlyPreviewingTheme, } from './is-previewing-theme'; -const { useHistory, useLocation } = unlock( routerPrivateApis ); +const { useHistory } = unlock( routerPrivateApis ); /** * This should be refactored to use the REST API, once the REST API can activate themes. @@ -23,7 +23,6 @@ const { useHistory, useLocation } = unlock( routerPrivateApis ); */ export function useActivateTheme() { const history = useHistory(); - const { params } = useLocation(); const { startResolution, finishResolution } = useDispatch( coreStore ); return async () => { @@ -38,6 +37,7 @@ export function useActivateTheme() { finishResolution( 'activateTheme' ); // Remove the wp_theme_preview query param: we've finished activating // the queue and are switching to normal Site Editor. + const { params } = history.getLocationWithParams(); history.replace( { ...params, wp_theme_preview: undefined } ); } }; diff --git a/packages/editor/README.md b/packages/editor/README.md index 1fdb1d0918f5a6..64e28992ee2c3a 100644 --- a/packages/editor/README.md +++ b/packages/editor/README.md @@ -974,15 +974,49 @@ Undocumented declaration. ### PostFeaturedImage -Undocumented declaration. +Renders the component for managing the featured image of a post. + +_Parameters_ + +- _props_ `Object`: Props. +- _props.currentPostId_ `number`: ID of the current post. +- _props.featuredImageId_ `number`: ID of the featured image. +- _props.onUpdateImage_ `Function`: Function to call when the image is updated. +- _props.onRemoveImage_ `Function`: Function to call when the image is removed. +- _props.media_ `Object`: The media object representing the featured image. +- _props.postType_ `string`: Post type. +- _props.noticeUI_ `Element`: UI for displaying notices. +- _props.noticeOperations_ `Object`: Operations for managing notices. + +_Returns_ + +- `Element`: Component to be rendered . ### PostFeaturedImageCheck -Undocumented declaration. +Wrapper component that renders its children only if the post type supports a featured image and the theme supports post thumbnails. + +_Parameters_ + +- _props_ `Object`: Props. +- _props.children_ `Element`: Children to be rendered. + +_Returns_ + +- `Component`: The component to be rendered. ### PostFeaturedImagePanel -Undocumented declaration. +Renders the panel for the post featured image. + +_Parameters_ + +- _props_ `Object`: Props. +- _props.withPanelBody_ `boolean`: Whether to include the panel body. Default true. + +_Returns_ + +- `Component|null`: The component to be rendered. Return Null if the editor panel is disabled for featured image. ### PostFormat @@ -1013,15 +1047,32 @@ _Returns_ ### PostLastRevision -Undocumented declaration. +Renders the component for displaying the last revision of a post. + +_Returns_ + +- `Component`: The component to be rendered. ### PostLastRevisionCheck -Undocumented declaration. +Wrapper component that renders its children if the post has more than one revision. + +_Parameters_ + +- _props_ `Object`: Props. +- _props.children_ `Element`: Children to be rendered. + +_Returns_ + +- `Component|null`: Rendered child components if post has more than one revision, otherwise null. ### PostLastRevisionPanel -Undocumented declaration. +Renders the panel for displaying the last revision of a post. + +_Returns_ + +- `Component`: The component to be rendered. ### PostLockedModal @@ -1177,7 +1228,16 @@ Undocumented declaration. ### PostTitle -Undocumented declaration. +Renders the `PostTitle` component. + +_Parameters_ + +- \_\_\_ `Object`: Unused parameter. +- _forwardedRef_ `Element`: Forwarded ref for the component. + +_Returns_ + +- `Component`: The rendered PostTitle component. ### PostTitleRaw @@ -1207,19 +1267,50 @@ _Returns_ ### PostURL -Undocumented declaration. +Renders the `PostURL` component. + +_Usage_ + +```jsx +<PostURL /> +``` + +_Parameters_ + +- _onClose_ `Function`: Callback function to be executed when the popover is closed. + +_Returns_ + +- `Component`: The rendered PostURL component. ### PostURLCheck -Undocumented declaration. +Check if the post URL is valid and visible. + +_Parameters_ + +- _props_ `Object`: The component props. +- _props.children_ `Element`: The child components. + +_Returns_ + +- `Component|null`: The child components if the post URL is valid and visible, otherwise null. ### PostURLLabel -Undocumented declaration. +Represents a label component for a post URL. + +_Returns_ + +- `Component`: The PostURLLabel component. ### PostURLPanel -Undocumented declaration. +Renders the `PostURLPanel` component. + +_Returns_ + +- `JSX.Element`: The rendered PostURLPanel component. ### PostVisibility @@ -1362,7 +1453,11 @@ _Returns_ ### usePostURLLabel -Undocumented declaration. +Custom hook to get the label for the post URL. + +_Returns_ + +- `string`: The filtered and decoded post URL label. ### usePostVisibilityLabel diff --git a/packages/editor/src/components/post-featured-image/check.js b/packages/editor/src/components/post-featured-image/check.js index 24a9f80058ddcc..823559f766bc35 100644 --- a/packages/editor/src/components/post-featured-image/check.js +++ b/packages/editor/src/components/post-featured-image/check.js @@ -4,6 +4,15 @@ import PostTypeSupportCheck from '../post-type-support-check'; import ThemeSupportCheck from '../theme-support-check'; +/** + * Wrapper component that renders its children only if the post type supports a featured image + * and the theme supports post thumbnails. + * + * @param {Object} props Props. + * @param {Element} props.children Children to be rendered. + * + * @return {Component} The component to be rendered. + */ function PostFeaturedImageCheck( { children } ) { return ( <ThemeSupportCheck supportKeys="post-thumbnails"> diff --git a/packages/editor/src/components/post-featured-image/index.js b/packages/editor/src/components/post-featured-image/index.js index 5407cac15b5422..63c89669435d5e 100644 --- a/packages/editor/src/components/post-featured-image/index.js +++ b/packages/editor/src/components/post-featured-image/index.js @@ -266,6 +266,21 @@ const applyWithDispatch = withDispatch( } ); +/** + * Renders the component for managing the featured image of a post. + * + * @param {Object} props Props. + * @param {number} props.currentPostId ID of the current post. + * @param {number} props.featuredImageId ID of the featured image. + * @param {Function} props.onUpdateImage Function to call when the image is updated. + * @param {Function} props.onRemoveImage Function to call when the image is removed. + * @param {Object} props.media The media object representing the featured image. + * @param {string} props.postType Post type. + * @param {Element} props.noticeUI UI for displaying notices. + * @param {Object} props.noticeOperations Operations for managing notices. + * + * @return {Element} Component to be rendered . + */ export default compose( withNotices, applyWithSelect, diff --git a/packages/editor/src/components/post-featured-image/panel.js b/packages/editor/src/components/post-featured-image/panel.js index 87d80dda4a7c1f..dd2a1527152ddf 100644 --- a/packages/editor/src/components/post-featured-image/panel.js +++ b/packages/editor/src/components/post-featured-image/panel.js @@ -15,6 +15,15 @@ import PostFeaturedImageCheck from './check'; const PANEL_NAME = 'featured-image'; +/** + * Renders the panel for the post featured image. + * + * @param {Object} props Props. + * @param {boolean} props.withPanelBody Whether to include the panel body. Default true. + * + * @return {Component|null} The component to be rendered. + * Return Null if the editor panel is disabled for featured image. + */ export default function PostFeaturedImagePanel( { withPanelBody = true } ) { const { postType, isEnabled, isOpened } = useSelect( ( select ) => { const { diff --git a/packages/editor/src/components/post-last-revision/check.js b/packages/editor/src/components/post-last-revision/check.js index 44f96b9cf7acb0..c570f5e42cdc32 100644 --- a/packages/editor/src/components/post-last-revision/check.js +++ b/packages/editor/src/components/post-last-revision/check.js @@ -9,6 +9,14 @@ import { useSelect } from '@wordpress/data'; import PostTypeSupportCheck from '../post-type-support-check'; import { store as editorStore } from '../../store'; +/** + * Wrapper component that renders its children if the post has more than one revision. + * + * @param {Object} props Props. + * @param {Element} props.children Children to be rendered. + * + * @return {Component|null} Rendered child components if post has more than one revision, otherwise null. + */ function PostLastRevisionCheck( { children } ) { const { lastRevisionId, revisionsCount } = useSelect( ( select ) => { const { getCurrentPostLastRevisionId, getCurrentPostRevisionsCount } = diff --git a/packages/editor/src/components/post-last-revision/index.js b/packages/editor/src/components/post-last-revision/index.js index e747befefe44e0..97031106772ada 100644 --- a/packages/editor/src/components/post-last-revision/index.js +++ b/packages/editor/src/components/post-last-revision/index.js @@ -13,7 +13,12 @@ import { addQueryArgs } from '@wordpress/url'; import PostLastRevisionCheck from './check'; import { store as editorStore } from '../../store'; -function LastRevision() { +/** + * Renders the component for displaying the last revision of a post. + * + * @return {Component} The component to be rendered. + */ +function PostLastRevision() { const { lastRevisionId, revisionsCount } = useSelect( ( select ) => { const { getCurrentPostLastRevisionId, getCurrentPostRevisionsCount } = select( editorStore ); @@ -42,4 +47,4 @@ function LastRevision() { ); } -export default LastRevision; +export default PostLastRevision; diff --git a/packages/editor/src/components/post-last-revision/panel.js b/packages/editor/src/components/post-last-revision/panel.js index de0aee0ab77503..e87475cc2b34e9 100644 --- a/packages/editor/src/components/post-last-revision/panel.js +++ b/packages/editor/src/components/post-last-revision/panel.js @@ -9,6 +9,11 @@ import { PanelBody } from '@wordpress/components'; import PostLastRevision from './'; import PostLastRevisionCheck from './check'; +/** + * Renders the panel for displaying the last revision of a post. + * + * @return {Component} The component to be rendered. + */ function PostLastRevisionPanel() { return ( <PostLastRevisionCheck> diff --git a/packages/editor/src/components/post-title/index.js b/packages/editor/src/components/post-title/index.js index b307b2467b869b..57ab39f0061615 100644 --- a/packages/editor/src/components/post-title/index.js +++ b/packages/editor/src/components/post-title/index.js @@ -2,7 +2,6 @@ * External dependencies */ import clsx from 'clsx'; - /** * WordPress dependencies */ @@ -211,4 +210,12 @@ function PostTitle( _, forwardedRef ) { ); } +/** + * Renders the `PostTitle` component. + * + * @param {Object} _ Unused parameter. + * @param {Element} forwardedRef Forwarded ref for the component. + * + * @return {Component} The rendered PostTitle component. + */ export default forwardRef( PostTitle ); diff --git a/packages/editor/src/components/post-title/post-title-raw.js b/packages/editor/src/components/post-title/post-title-raw.js index a9510bc136c231..a4c9713a094925 100644 --- a/packages/editor/src/components/post-title/post-title-raw.js +++ b/packages/editor/src/components/post-title/post-title-raw.js @@ -20,6 +20,14 @@ import { DEFAULT_CLASSNAMES, REGEXP_NEWLINES } from './constants'; import usePostTitleFocus from './use-post-title-focus'; import usePostTitle from './use-post-title'; +/** + * Renders a raw post title input field. + * + * @param {Object} _ Unused parameter. + * @param {Element} forwardedRef Reference to the component's DOM node. + * + * @return {Component} The rendered component. + */ function PostTitleRaw( _, forwardedRef ) { const { placeholder, hasFixedToolbar } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); diff --git a/packages/editor/src/components/post-title/use-post-title-focus.js b/packages/editor/src/components/post-title/use-post-title-focus.js index effac53f2670a2..127b7661462ba9 100644 --- a/packages/editor/src/components/post-title/use-post-title-focus.js +++ b/packages/editor/src/components/post-title/use-post-title-focus.js @@ -9,6 +9,13 @@ import { useSelect } from '@wordpress/data'; */ import { store as editorStore } from '../../store'; +/** + * Custom hook that manages the focus behavior of the post title input field. + * + * @param {Element} forwardedRef - The forwarded ref for the input field. + * + * @return {Object} - The ref object. + */ export default function usePostTitleFocus( forwardedRef ) { const ref = useRef(); diff --git a/packages/editor/src/components/post-title/use-post-title.js b/packages/editor/src/components/post-title/use-post-title.js index 65bd67af6fb4c8..d335064a523549 100644 --- a/packages/editor/src/components/post-title/use-post-title.js +++ b/packages/editor/src/components/post-title/use-post-title.js @@ -7,6 +7,11 @@ import { useSelect, useDispatch } from '@wordpress/data'; */ import { store as editorStore } from '../../store'; +/** + * Custom hook for managing the post title in the editor. + * + * @return {Object} An object containing the current title and a function to update the title. + */ export default function usePostTitle() { const { editPost } = useDispatch( editorStore ); const { title } = useSelect( ( select ) => { diff --git a/packages/editor/src/components/post-url/check.js b/packages/editor/src/components/post-url/check.js index 65c54846a702b1..7eb390472bdd7d 100644 --- a/packages/editor/src/components/post-url/check.js +++ b/packages/editor/src/components/post-url/check.js @@ -9,6 +9,14 @@ import { store as coreStore } from '@wordpress/core-data'; */ import { store as editorStore } from '../../store'; +/** + * Check if the post URL is valid and visible. + * + * @param {Object} props The component props. + * @param {Element} props.children The child components. + * + * @return {Component|null} The child components if the post URL is valid and visible, otherwise null. + */ export default function PostURLCheck( { children } ) { const isVisible = useSelect( ( select ) => { const postTypeSlug = select( editorStore ).getCurrentPostType(); diff --git a/packages/editor/src/components/post-url/index.js b/packages/editor/src/components/post-url/index.js index cf55e30473329d..9453977a23bf05 100644 --- a/packages/editor/src/components/post-url/index.js +++ b/packages/editor/src/components/post-url/index.js @@ -24,6 +24,18 @@ import { useCopyToClipboard } from '@wordpress/compose'; import { usePostURLLabel } from './label'; import { store as editorStore } from '../../store'; +/** + * Renders the `PostURL` component. + * + * @example + * ```jsx + * <PostURL /> + * ``` + * + * @param {Function} onClose Callback function to be executed when the popover is closed. + * + * @return {Component} The rendered PostURL component. + */ export default function PostURL( { onClose } ) { const { isEditable, postSlug, postLink, permalinkPrefix, permalinkSuffix } = useSelect( ( select ) => { diff --git a/packages/editor/src/components/post-url/label.js b/packages/editor/src/components/post-url/label.js index 5c233dfd549467..4f03e2bce0d05f 100644 --- a/packages/editor/src/components/post-url/label.js +++ b/packages/editor/src/components/post-url/label.js @@ -9,10 +9,20 @@ import { filterURLForDisplay, safeDecodeURIComponent } from '@wordpress/url'; */ import { store as editorStore } from '../../store'; +/** + * Represents a label component for a post URL. + * + * @return {Component} The PostURLLabel component. + */ export default function PostURLLabel() { return usePostURLLabel(); } +/** + * Custom hook to get the label for the post URL. + * + * @return {string} The filtered and decoded post URL label. + */ export function usePostURLLabel() { const postLink = useSelect( ( select ) => select( editorStore ).getPermalink(), diff --git a/packages/editor/src/components/post-url/panel.js b/packages/editor/src/components/post-url/panel.js index c4a1cbba935c7d..fbf174cc28bf36 100644 --- a/packages/editor/src/components/post-url/panel.js +++ b/packages/editor/src/components/post-url/panel.js @@ -15,6 +15,11 @@ import PostURL from './index'; import PostPanelRow from '../post-panel-row'; import { store as editorStore } from '../../store'; +/** + * Renders the `PostURLPanel` component. + * + * @return {JSX.Element} The rendered PostURLPanel component. + */ export default function PostURLPanel() { // Use internal state instead of a ref to make sure that the component // re-renders when the popover's anchor updates. diff --git a/packages/patterns/src/components/create-pattern-modal.js b/packages/patterns/src/components/create-pattern-modal.js index 9576e50309e237..16ae706bf18f1d 100644 --- a/packages/patterns/src/components/create-pattern-modal.js +++ b/packages/patterns/src/components/create-pattern-modal.js @@ -11,13 +11,18 @@ import { } from '@wordpress/components'; import { __, _x } from '@wordpress/i18n'; import { useState } from '@wordpress/element'; -import { useDispatch } from '@wordpress/data'; +import { useDispatch, useSelect } from '@wordpress/data'; import { store as noticesStore } from '@wordpress/notices'; +import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies */ -import { PATTERN_DEFAULT_CATEGORY, PATTERN_SYNC_TYPES } from '../constants'; +import { + PATTERN_DEFAULT_CATEGORY, + PATTERN_SYNC_TYPES, + PATTERN_TYPES, +} from '../constants'; import { store as patternsStore } from '../store'; import CategorySelector from './category-selector'; import { useAddPatternCategory } from '../private-hooks'; @@ -25,12 +30,18 @@ import { unlock } from '../lock-unlock'; export default function CreatePatternModal( { className = 'patterns-menu-items__convert-modal', - modalTitle = __( 'Create pattern' ), + modalTitle, ...restProps } ) { + const defaultModalTitle = useSelect( + ( select ) => + select( coreStore ).getPostType( PATTERN_TYPES.user )?.labels + ?.add_new_item, + [] + ); return ( <Modal - title={ modalTitle } + title={ modalTitle || defaultModalTitle } onRequestClose={ restProps.onClose } overlayClassName={ className } > @@ -40,7 +51,7 @@ export default function CreatePatternModal( { } export function CreatePatternModalContents( { - confirmLabel = __( 'Create' ), + confirmLabel = __( 'Add' ), defaultCategories = [], content, onClose, diff --git a/packages/router/src/history.js b/packages/router/src/history.js index 56c85914a5453f..3a04745923a817 100644 --- a/packages/router/src/history.js +++ b/packages/router/src/history.js @@ -38,7 +38,24 @@ function replace( params, state ) { return originalHistoryReplace.call( history, { search }, state ); } +const locationMemo = new WeakMap(); +function getLocationWithParams() { + const location = history.location; + let locationWithParams = locationMemo.get( location ); + if ( ! locationWithParams ) { + locationWithParams = { + ...location, + params: Object.fromEntries( + new URLSearchParams( location.search ) + ), + }; + locationMemo.set( location, locationWithParams ); + } + return locationWithParams; +} + history.push = push; history.replace = replace; +history.getLocationWithParams = getLocationWithParams; export default history; diff --git a/packages/router/src/router.js b/packages/router/src/router.js index e5449cef54c6a0..55807175a5bdd9 100644 --- a/packages/router/src/router.js +++ b/packages/router/src/router.js @@ -3,9 +3,8 @@ */ import { createContext, - useState, - useEffect, useContext, + useSyncExternalStore, } from '@wordpress/element'; /** @@ -24,25 +23,13 @@ export function useHistory() { return useContext( HistoryContext ); } -function getLocationWithParams( location ) { - const searchParams = new URLSearchParams( location.search ); - return { - ...location, - params: Object.fromEntries( searchParams.entries() ), - }; -} - export function RouterProvider( { children } ) { - const [ location, setLocation ] = useState( () => - getLocationWithParams( history.location ) + const location = useSyncExternalStore( + history.listen, + history.getLocationWithParams, + history.getLocationWithParams ); - useEffect( () => { - return history.listen( ( { location: updatedLocation } ) => { - setLocation( getLocationWithParams( updatedLocation ) ); - } ); - }, [] ); - return ( <HistoryContext.Provider value={ history }> <RoutesContext.Provider value={ location }> diff --git a/test/e2e/specs/editor/blocks/image.spec.js b/test/e2e/specs/editor/blocks/image.spec.js index f556cb973642e4..3cb1565c8d4160 100644 --- a/test/e2e/specs/editor/blocks/image.spec.js +++ b/test/e2e/specs/editor/blocks/image.spec.js @@ -946,12 +946,12 @@ test.describe( 'Image - Site editor', () => { await requestUtils.activateTheme( 'emptytheme' ); } ); - test.beforeEach( async ( { admin, editor } ) => { + test.beforeEach( async ( { admin } ) => { await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); } ); test.afterEach( async ( { requestUtils } ) => { diff --git a/test/e2e/specs/editor/blocks/navigation-frontend-interactivity.spec.js b/test/e2e/specs/editor/blocks/navigation-frontend-interactivity.spec.js index 23a59faf498d35..b31533d0d17c24 100644 --- a/test/e2e/specs/editor/blocks/navigation-frontend-interactivity.spec.js +++ b/test/e2e/specs/editor/blocks/navigation-frontend-interactivity.spec.js @@ -26,8 +26,8 @@ test.describe( 'Navigation block - Frontend interactivity', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await requestUtils.createNavigationMenu( { title: 'Hidden menu', content: ` @@ -138,8 +138,8 @@ test.describe( 'Navigation block - Frontend interactivity', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await requestUtils.createNavigationMenu( { title: 'Hidden menu', content: ` @@ -353,8 +353,8 @@ test.describe( 'Navigation block - Frontend interactivity', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await requestUtils.createNavigationMenu( { title: 'Hidden menu', content: ` @@ -449,8 +449,8 @@ test.describe( 'Navigation block - Frontend interactivity', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await requestUtils.createNavigationMenu( { title: 'Page list menu', content: ` diff --git a/test/e2e/specs/editor/various/block-bindings.spec.js b/test/e2e/specs/editor/various/block-bindings.spec.js index 586ce9252149a3..97b8579bb07ba6 100644 --- a/test/e2e/specs/editor/various/block-bindings.spec.js +++ b/test/e2e/specs/editor/various/block-bindings.spec.js @@ -41,8 +41,8 @@ test.describe( 'Block bindings', () => { await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await editor.openDocumentSettingsSidebar(); } ); diff --git a/test/e2e/specs/editor/various/block-editor-keyboard-shortcuts.spec.js b/test/e2e/specs/editor/various/block-editor-keyboard-shortcuts.spec.js index 1962e2bc4202ae..967baccfcbe4ef 100644 --- a/test/e2e/specs/editor/various/block-editor-keyboard-shortcuts.spec.js +++ b/test/e2e/specs/editor/various/block-editor-keyboard-shortcuts.spec.js @@ -192,7 +192,7 @@ test.describe( 'Block editor keyboard shortcuts', () => { .getByRole( 'menuitem', { name: 'Create pattern' } ) .click(); await page - .getByRole( 'dialog', { name: 'Create pattern' } ) + .getByRole( 'dialog', { name: 'add new pattern' } ) .getByRole( 'textbox', { name: 'Name' } ) .fill( 'hi' ); diff --git a/test/e2e/specs/editor/various/inserting-blocks.spec.js b/test/e2e/specs/editor/various/inserting-blocks.spec.js index b3ff3ae1b72e5d..1a443152800dec 100644 --- a/test/e2e/specs/editor/various/inserting-blocks.spec.js +++ b/test/e2e/specs/editor/various/inserting-blocks.spec.js @@ -265,7 +265,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { .click(); await page.getByRole( 'menuitem', { name: 'Create pattern' } ).click(); const createPatternDialog = page.getByRole( 'dialog', { - name: 'Create pattern', + name: 'add new pattern', } ); await createPatternDialog .getByRole( 'textbox', { name: 'Name' } ) @@ -274,7 +274,7 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { .getByRole( 'checkbox', { name: 'Synced' } ) .setChecked( true ); await createPatternDialog - .getByRole( 'button', { name: 'Create' } ) + .getByRole( 'button', { name: 'Add' } ) .click(); const patternBlock = page.getByRole( 'document', { name: 'Block: Pattern', diff --git a/test/e2e/specs/editor/various/pattern-overrides.spec.js b/test/e2e/specs/editor/various/pattern-overrides.spec.js index 8aa0c9c530609d..706ddabd5a35dc 100644 --- a/test/e2e/specs/editor/various/pattern-overrides.spec.js +++ b/test/e2e/specs/editor/various/pattern-overrides.spec.js @@ -35,20 +35,20 @@ test.describe( 'Pattern Overrides', () => { const editableParagraphName = 'Editable Paragraph'; await test.step( 'Create a synced pattern and assign blocks to allow overrides', async () => { - await admin.visitSiteEditor( { path: '/patterns' } ); + await admin.visitSiteEditor( { postType: 'wp_block' } ); await page - .getByRole( 'region', { name: 'Navigation' } ) - .getByRole( 'button', { name: 'Create pattern' } ) + .getByRole( 'region', { name: 'Patterns content' } ) + .getByRole( 'button', { name: 'add new pattern' } ) .click(); await page - .getByRole( 'menu', { name: 'Create pattern' } ) - .getByRole( 'menuitem', { name: 'Create pattern' } ) + .getByRole( 'menu', { name: 'add new pattern' } ) + .getByRole( 'menuitem', { name: 'add new pattern' } ) .click(); const createPatternDialog = page.getByRole( 'dialog', { - name: 'Create pattern', + name: 'add new pattern', } ); await createPatternDialog .getByRole( 'textbox', { name: 'Name' } ) @@ -57,7 +57,7 @@ test.describe( 'Pattern Overrides', () => { .getByRole( 'checkbox', { name: 'Synced' } ) .setChecked( true ); await createPatternDialog - .getByRole( 'button', { name: 'Create' } ) + .getByRole( 'button', { name: 'Add' } ) .click(); await editor.canvas @@ -727,7 +727,6 @@ test.describe( 'Pattern Overrides', () => { await admin.visitSiteEditor( { postId: id, postType: 'wp_block', - categoryType: 'pattern', canvas: 'edit', } ); diff --git a/test/e2e/specs/editor/various/patterns.spec.js b/test/e2e/specs/editor/various/patterns.spec.js index 48eaf9e08c9b94..77f97ee3004a9e 100644 --- a/test/e2e/specs/editor/various/patterns.spec.js +++ b/test/e2e/specs/editor/various/patterns.spec.js @@ -37,7 +37,7 @@ test.describe( 'Unsynced pattern', () => { await page.getByRole( 'menuitem', { name: 'Create pattern' } ).click(); const createPatternDialog = page.getByRole( 'dialog', { - name: 'Create pattern', + name: 'add new pattern', } ); await createPatternDialog .getByRole( 'textbox', { name: 'Name' } ) @@ -136,7 +136,7 @@ test.describe( 'Synced pattern', () => { await page.getByRole( 'menuitem', { name: 'Create pattern' } ).click(); const createPatternDialog = page.getByRole( 'dialog', { - name: 'Create pattern', + name: 'add new pattern', } ); await createPatternDialog .getByRole( 'textbox', { name: 'Name' } ) @@ -150,7 +150,7 @@ test.describe( 'Synced pattern', () => { .setChecked( true ); await createPatternDialog - .getByRole( 'button', { name: 'Create' } ) + .getByRole( 'button', { name: 'Add' } ) .click(); // Check the pattern is focused. @@ -376,7 +376,7 @@ test.describe( 'Synced pattern', () => { await editor.clickBlockOptionsMenuItem( 'Create pattern' ); const createPatternDialog = page.getByRole( 'dialog', { - name: 'Create pattern', + name: 'add new pattern', } ); await createPatternDialog .getByRole( 'textbox', { name: 'Name' } ) @@ -385,7 +385,7 @@ test.describe( 'Synced pattern', () => { .getByRole( 'checkbox', { name: 'Synced' } ) .setChecked( true ); await createPatternDialog - .getByRole( 'button', { name: 'Create' } ) + .getByRole( 'button', { name: 'Add' } ) .click(); await admin.createNewPost(); @@ -419,7 +419,7 @@ test.describe( 'Synced pattern', () => { await editor.clickBlockOptionsMenuItem( 'Create pattern' ); const createPatternDialog = editor.page.getByRole( 'dialog', { - name: 'Create pattern', + name: 'add new pattern', } ); await createPatternDialog .getByRole( 'textbox', { name: 'Name' } ) @@ -428,7 +428,7 @@ test.describe( 'Synced pattern', () => { .getByRole( 'checkbox', { name: 'Synced' } ) .setChecked( true ); await createPatternDialog - .getByRole( 'button', { name: 'Create' } ) + .getByRole( 'button', { name: 'Add' } ) .click(); // Wait until the pattern is created. @@ -603,7 +603,7 @@ test.describe( 'Synced pattern', () => { await editor.clickBlockOptionsMenuItem( 'Create pattern' ); const createPatternDialog = editor.page.getByRole( 'dialog', { - name: 'Create pattern', + name: 'add new pattern', } ); await createPatternDialog .getByRole( 'textbox', { name: 'Name' } ) @@ -612,7 +612,7 @@ test.describe( 'Synced pattern', () => { .getByRole( 'checkbox', { name: 'Synced' } ) .setChecked( true ); await createPatternDialog - .getByRole( 'button', { name: 'Create' } ) + .getByRole( 'button', { name: 'Add' } ) .click(); await expect( diff --git a/test/e2e/specs/site-editor/block-removal.spec.js b/test/e2e/specs/site-editor/block-removal.spec.js index 7d656fbd2774ff..14f0ae422cc988 100644 --- a/test/e2e/specs/site-editor/block-removal.spec.js +++ b/test/e2e/specs/site-editor/block-removal.spec.js @@ -12,12 +12,12 @@ test.describe( 'Site editor block removal prompt', () => { await requestUtils.activateTheme( 'twentytwentyone' ); } ); - test.beforeEach( async ( { admin, editor } ) => { + test.beforeEach( async ( { admin } ) => { await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); } ); test( 'should appear when attempting to remove Query Block', async ( { diff --git a/test/e2e/specs/site-editor/browser-history.spec.js b/test/e2e/specs/site-editor/browser-history.spec.js index 4476ce0aa7c0ac..eaafb3aad1b3fd 100644 --- a/test/e2e/specs/site-editor/browser-history.spec.js +++ b/test/e2e/specs/site-editor/browser-history.spec.js @@ -27,7 +27,7 @@ test.describe( 'Site editor browser history', () => { // Navigate back to the template list await page.goBack(); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?path=%2Fwp_template' + '/wp-admin/site-editor.php?postType=wp_template' ); // Navigate back to the dashboard diff --git a/test/e2e/specs/site-editor/global-styles-sidebar.spec.js b/test/e2e/specs/site-editor/global-styles-sidebar.spec.js index f255640cb2f12f..257ebc38f3b4dd 100644 --- a/test/e2e/specs/site-editor/global-styles-sidebar.spec.js +++ b/test/e2e/specs/site-editor/global-styles-sidebar.spec.js @@ -12,12 +12,12 @@ test.describe( 'Global styles sidebar', () => { await requestUtils.activateTheme( 'twentytwentyone' ); } ); - test.beforeEach( async ( { admin, editor } ) => { + test.beforeEach( async ( { admin } ) => { await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); } ); test( 'should filter blocks list results', async ( { page } ) => { diff --git a/test/e2e/specs/site-editor/hybrid-theme.spec.js b/test/e2e/specs/site-editor/hybrid-theme.spec.js index 1f73b6de6f486a..b568aaf4445b5c 100644 --- a/test/e2e/specs/site-editor/hybrid-theme.spec.js +++ b/test/e2e/specs/site-editor/hybrid-theme.spec.js @@ -33,7 +33,7 @@ test.describe( 'Hybrid theme', () => { ); await expect( page ).toHaveURL( - '/wp-admin/site-editor.php?path=%2Fpatterns' + '/wp-admin/site-editor.php?postType=wp_template_part' ); await expect( diff --git a/test/e2e/specs/site-editor/iframe-rendering.spec.js b/test/e2e/specs/site-editor/iframe-rendering.spec.js index 4391f134a9f80b..9c25ef504637e4 100644 --- a/test/e2e/specs/site-editor/iframe-rendering.spec.js +++ b/test/e2e/specs/site-editor/iframe-rendering.spec.js @@ -19,6 +19,7 @@ test.describe( 'Site editor iframe rendering mode', () => { await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); const compatMode = await editor.canvas .locator( ':root' ) diff --git a/test/e2e/specs/site-editor/list-view.spec.js b/test/e2e/specs/site-editor/list-view.spec.js index 9bccc7c56446a6..ba8a316ee10c4d 100644 --- a/test/e2e/specs/site-editor/list-view.spec.js +++ b/test/e2e/specs/site-editor/list-view.spec.js @@ -12,13 +12,13 @@ test.describe( 'Site Editor List View', () => { await requestUtils.activateTheme( 'twentytwentyone' ); } ); - test.beforeEach( async ( { admin, editor } ) => { + test.beforeEach( async ( { admin } ) => { // Select a template part with a few blocks. await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); } ); test( 'should open by default when preference is enabled', async ( { diff --git a/test/e2e/specs/site-editor/multi-entity-saving.spec.js b/test/e2e/specs/site-editor/multi-entity-saving.spec.js index 0e79d96a2ad9e1..88a277b8c88f2c 100644 --- a/test/e2e/specs/site-editor/multi-entity-saving.spec.js +++ b/test/e2e/specs/site-editor/multi-entity-saving.spec.js @@ -18,12 +18,12 @@ test.describe( 'Site Editor - Multi-entity save flow', () => { ] ); } ); - test.beforeEach( async ( { admin, editor } ) => { + test.beforeEach( async ( { admin } ) => { await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); } ); test( 'save flow should work as expected', async ( { editor, page } ) => { diff --git a/test/e2e/specs/site-editor/new-templates-list.spec.js b/test/e2e/specs/site-editor/new-templates-list.spec.js index fc321a87e43650..ab37244df107c7 100644 --- a/test/e2e/specs/site-editor/new-templates-list.spec.js +++ b/test/e2e/specs/site-editor/new-templates-list.spec.js @@ -20,7 +20,7 @@ test.describe( 'Templates', () => { } ); test( 'Sorting', async ( { admin, page } ) => { - await admin.visitSiteEditor( { path: '/wp_template' } ); + await admin.visitSiteEditor( { postType: 'wp_template' } ); // Descending by title. await page.getByRole( 'button', { name: 'View options' } ).click(); @@ -47,7 +47,7 @@ test.describe( 'Templates', () => { title: 'Date Archives', content: 'hi', } ); - await admin.visitSiteEditor( { path: '/wp_template' } ); + await admin.visitSiteEditor( { postType: 'wp_template' } ); // Global search. await page.getByRole( 'searchbox', { name: 'Search' } ).fill( 'tag' ); const titles = page @@ -84,7 +84,7 @@ test.describe( 'Templates', () => { } ); test( 'Field visibility', async ( { admin, page } ) => { - await admin.visitSiteEditor( { path: '/wp_template' } ); + await admin.visitSiteEditor( { postType: 'wp_template' } ); await page.getByRole( 'button', { name: 'View options' } ).click(); await page.getByRole( 'menuitem', { name: 'Layout' } ).click(); diff --git a/test/e2e/specs/site-editor/patterns.spec.js b/test/e2e/specs/site-editor/patterns.spec.js index b556be5621f3d5..0b0fada39c2622 100644 --- a/test/e2e/specs/site-editor/patterns.spec.js +++ b/test/e2e/specs/site-editor/patterns.spec.js @@ -33,7 +33,7 @@ test.describe( 'Patterns', () => { admin, patterns, } ) => { - await admin.visitSiteEditor( { path: '/patterns' } ); + await admin.visitSiteEditor( { postType: 'wp_block' } ); await expect( patterns.navigation.getByRole( 'heading', { name: 'Patterns', @@ -42,24 +42,22 @@ test.describe( 'Patterns', () => { ).toBeVisible(); await expect( patterns.content ).toContainText( 'No results' ); - await patterns.navigation - .getByRole( 'button', { name: 'Create pattern' } ) + await patterns.content + .getByRole( 'button', { name: 'add new pattern' } ) .click(); - const createPatternMenu = page.getByRole( 'menu', { - name: 'Create pattern', - } ); - await expect( - createPatternMenu.getByRole( 'menuitem', { - name: 'Create pattern', + const addNewMenuItem = page + .getByRole( 'menu', { + name: 'add new pattern', } ) - ).toBeFocused(); - await createPatternMenu - .getByRole( 'menuitem', { name: 'Create pattern' } ) - .click(); + .getByRole( 'menuitem', { + name: 'add new pattern', + } ); + await expect( addNewMenuItem ).toBeFocused(); + await addNewMenuItem.click(); const createPatternDialog = page.getByRole( 'dialog', { - name: 'Create pattern', + name: 'add new pattern', } ); await createPatternDialog .getByRole( 'textbox', { name: 'Name' } ) @@ -87,9 +85,6 @@ test.describe( 'Patterns', () => { ).toContainText( 'Pattern updated' ); await page.getByRole( 'button', { name: 'Open navigation' } ).click(); - await patterns.navigation - .getByRole( 'button', { name: 'Back' } ) - .click(); await expect( patterns.navigation.getByRole( 'button', { @@ -150,7 +145,7 @@ test.describe( 'Patterns', () => { } ), ] ); - await admin.visitSiteEditor( { path: '/patterns' } ); + await admin.visitSiteEditor( { postType: 'wp_block' } ); await expect( patterns.item ).toHaveCount( 3 ); const searchBox = patterns.content.getByRole( 'searchbox', { @@ -168,7 +163,7 @@ test.describe( 'Patterns', () => { await expect( patterns.content ).toContainText( 'No results' ); await patterns.content - .getByRole( 'button', { name: 'Reset', exact: true } ) + .getByRole( 'button', { name: 'Reset search', exact: true } ) .click(); await expect( searchBox ).toHaveValue( '' ); await expect( patterns.item ).toHaveCount( 3 ); diff --git a/test/e2e/specs/site-editor/push-to-global-styles.spec.js b/test/e2e/specs/site-editor/push-to-global-styles.spec.js index 71a57fd04e515a..26224a83e27ebd 100644 --- a/test/e2e/specs/site-editor/push-to-global-styles.spec.js +++ b/test/e2e/specs/site-editor/push-to-global-styles.spec.js @@ -12,12 +12,12 @@ test.describe( 'Push to Global Styles button', () => { await requestUtils.activateTheme( 'twentytwentyone' ); } ); - test.beforeEach( async ( { admin, editor } ) => { + test.beforeEach( async ( { admin } ) => { await admin.visitSiteEditor( { postId: 'emptytheme//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); } ); test( 'should apply Heading block styles to all Heading blocks', async ( { diff --git a/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js b/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js index 9a6fd11a56e3b8..337c26315c8a3f 100644 --- a/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js +++ b/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js @@ -54,10 +54,10 @@ test.describe( 'Site editor url navigation', () => { } ) => { await admin.visitSiteEditor(); await page.click( 'role=button[name="Patterns"i]' ); - await page.click( 'role=button[name="Create pattern"i]' ); + await page.click( 'role=button[name="add new pattern"i]' ); await page - .getByRole( 'menu', { name: 'Create pattern' } ) - .getByRole( 'menuitem', { name: 'Create template part' } ) + .getByRole( 'menu', { name: 'add new pattern' } ) + .getByRole( 'menuitem', { name: 'add new template part' } ) .click(); // Fill in a name in the dialog that pops up. await page.type( 'role=dialog >> role=textbox[name="Name"i]', 'Demo' ); @@ -87,9 +87,8 @@ test.describe( 'Site editor url navigation', () => { page.getByRole( 'region', { name: 'Editor content' } ) ).toBeVisible(); await page.getByRole( 'button', { name: 'Open navigation' } ).click(); - await navigation.getByRole( 'button', { name: 'Back' } ).click(); await expect( - navigation.getByRole( 'button', { name: 'General' } ) - ).toHaveAttribute( 'aria-current', 'true' ); + navigation.getByRole( 'button', { name: 'All template parts' } ) + ).toBeVisible(); } ); } ); diff --git a/test/e2e/specs/site-editor/style-variations.spec.js b/test/e2e/specs/site-editor/style-variations.spec.js index 9b12f37c0baa6b..f991b512e840df 100644 --- a/test/e2e/specs/site-editor/style-variations.spec.js +++ b/test/e2e/specs/site-editor/style-variations.spec.js @@ -33,13 +33,12 @@ test.describe( 'Global styles variations', () => { admin, page, siteEditorStyleVariations, - editor, } ) => { await admin.visitSiteEditor( { postId: 'gutenberg-test-themes/style-variations//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await siteEditorStyleVariations.browseStyles(); @@ -70,13 +69,12 @@ test.describe( 'Global styles variations', () => { admin, page, siteEditorStyleVariations, - editor, } ) => { await admin.visitSiteEditor( { postId: 'gutenberg-test-themes/style-variations//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await siteEditorStyleVariations.browseStyles(); await page.click( 'role=button[name="pink"i]' ); await page.click( 'role=button[name="Back"i]' ); @@ -107,13 +105,12 @@ test.describe( 'Global styles variations', () => { admin, page, siteEditorStyleVariations, - editor, } ) => { await admin.visitSiteEditor( { postId: 'gutenberg-test-themes/style-variations//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await siteEditorStyleVariations.browseStyles(); await page.click( 'role=button[name="yellow"i]' ); await page.click( 'role=button[name="Back"i]' ); @@ -150,13 +147,12 @@ test.describe( 'Global styles variations', () => { admin, page, siteEditorStyleVariations, - editor, } ) => { await admin.visitSiteEditor( { postId: 'gutenberg-test-themes/style-variations//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await siteEditorStyleVariations.browseStyles(); await page.click( 'role=button[name="pink"i]' ); await page.click( 'role=button[name="Back"i]' ); @@ -185,8 +181,8 @@ test.describe( 'Global styles variations', () => { await admin.visitSiteEditor( { postId: 'gutenberg-test-themes/style-variations//index', postType: 'wp_template', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await siteEditorStyleVariations.browseStyles(); await page.click( 'role=button[name="yellow"i]' ); diff --git a/test/e2e/specs/site-editor/template-part.spec.js b/test/e2e/specs/site-editor/template-part.spec.js index e74cd0bec4ed16..f1e317e171736c 100644 --- a/test/e2e/specs/site-editor/template-part.spec.js +++ b/test/e2e/specs/site-editor/template-part.spec.js @@ -27,8 +27,8 @@ test.describe( 'Template Part', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); // Insert a new template block and 'start blank'. await editor.insertBlock( { name: 'core/template-part' } ); @@ -186,8 +186,8 @@ test.describe( 'Template Part', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await editor.insertBlock( { name: 'core/paragraph', attributes: { @@ -229,8 +229,8 @@ test.describe( 'Template Part', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); // Edit the header. await editor.insertBlock( { name: 'core/paragraph', @@ -264,8 +264,8 @@ test.describe( 'Template Part', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); await editor.insertBlock( { name: 'core/paragraph', attributes: { @@ -371,8 +371,8 @@ test.describe( 'Template Part', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); // Select the site title block. const siteTitle = editor.canvas.getByRole( 'document', { diff --git a/test/e2e/specs/site-editor/writing-flow.spec.js b/test/e2e/specs/site-editor/writing-flow.spec.js index 75f8766891156b..ad661175b6bdfe 100644 --- a/test/e2e/specs/site-editor/writing-flow.spec.js +++ b/test/e2e/specs/site-editor/writing-flow.spec.js @@ -23,8 +23,8 @@ test.describe( 'Site editor writing flow', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); // Select the first site title block. const siteTitleBlock = editor.canvas.locator( 'role=document[name="Block: Site Title"i]' @@ -51,8 +51,8 @@ test.describe( 'Site editor writing flow', () => { await admin.visitSiteEditor( { postId: 'emptytheme//header', postType: 'wp_template_part', + canvas: 'edit', } ); - await editor.canvas.locator( 'body' ).click(); // Make sure the sidebar is open. await editor.openDocumentSettingsSidebar(); diff --git a/test/performance/specs/site-editor.spec.js b/test/performance/specs/site-editor.spec.js index e8a4e3529334dd..dd052db5035dbe 100644 --- a/test/performance/specs/site-editor.spec.js +++ b/test/performance/specs/site-editor.spec.js @@ -81,6 +81,7 @@ test.describe( 'Site Editor Performance', () => { await admin.visitSiteEditor( { postId: draftId, postType: 'page', + canvas: 'edit', } ); // Wait for the first block. @@ -131,11 +132,11 @@ test.describe( 'Site Editor Performance', () => { await admin.visitSiteEditor( { postId: draftId, postType: 'page', + canvas: 'edit', } ); // Enter edit mode (second click is needed for the legacy edit mode). const canvas = await perfUtils.getCanvas(); - await canvas.locator( 'body' ).click(); // Run the test with the sidebar closed const toggleSidebarButton = page @@ -211,6 +212,7 @@ test.describe( 'Site Editor Performance', () => { metrics, } ) => { await admin.visitSiteEditor( { + // The old URL is supported in both previous versions and new versions. path: '/wp_template', } );