@wordpress/editor 14.5.0 → 14.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/build/bindings/post-meta.js +2 -2
- package/build/bindings/post-meta.js.map +1 -1
- package/build/components/create-template-part-modal/index.js +1 -0
- package/build/components/create-template-part-modal/index.js.map +1 -1
- package/build/components/global-styles-provider/index.js +17 -4
- package/build/components/global-styles-provider/index.js.map +1 -1
- package/build/components/inserter-sidebar/index.js +5 -2
- package/build/components/inserter-sidebar/index.js.map +1 -1
- package/build/components/page-attributes/parent.js +6 -5
- package/build/components/page-attributes/parent.js.map +1 -1
- package/build/components/post-actions/actions.js +4 -499
- package/build/components/post-actions/actions.js.map +1 -1
- package/build/components/post-actions/index.js +8 -17
- package/build/components/post-actions/index.js.map +1 -1
- package/build/components/post-card-panel/index.js +20 -20
- package/build/components/post-card-panel/index.js.map +1 -1
- package/build/components/post-featured-image/index.js +2 -0
- package/build/components/post-featured-image/index.js.map +1 -1
- package/build/components/post-publish-panel/postpublish.js +4 -0
- package/build/components/post-publish-panel/postpublish.js.map +1 -1
- package/build/components/post-slug/index.js +1 -0
- package/build/components/post-slug/index.js.map +1 -1
- package/build/components/post-taxonomies/hierarchical-term-selector.js +2 -1
- package/build/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
- package/build/components/post-url/index.js +6 -5
- package/build/components/post-url/index.js.map +1 -1
- package/build/components/sidebar/post-summary.js +10 -7
- package/build/components/sidebar/post-summary.js.map +1 -1
- package/build/components/template-content-panel/index.js +1 -1
- package/build/components/template-content-panel/index.js.map +1 -1
- package/build/dataviews/actions/duplicate-pattern.js +48 -0
- package/build/dataviews/actions/duplicate-pattern.js.map +1 -0
- package/build/dataviews/actions/duplicate-post.js +146 -0
- package/build/dataviews/actions/duplicate-post.js.map +1 -0
- package/build/dataviews/actions/duplicate-post.native.js +9 -0
- package/build/dataviews/actions/duplicate-post.native.js.map +1 -0
- package/build/dataviews/actions/duplicate-template-part.js +67 -0
- package/build/dataviews/actions/duplicate-template-part.js.map +1 -0
- package/build/dataviews/actions/rename-post.js +125 -0
- package/build/dataviews/actions/rename-post.js.map +1 -0
- package/build/dataviews/actions/reorder-page.js +116 -0
- package/build/dataviews/actions/reorder-page.js.map +1 -0
- package/build/dataviews/actions/reorder-page.native.js +9 -0
- package/build/dataviews/actions/reorder-page.native.js.map +1 -0
- package/build/dataviews/actions/reset-post.js +1 -1
- package/build/dataviews/actions/reset-post.js.map +1 -1
- package/build/dataviews/actions/utils.js +9 -1
- package/build/dataviews/actions/utils.js.map +1 -1
- package/build/dataviews/actions/view-post-revisions.js +49 -0
- package/build/dataviews/actions/view-post-revisions.js.map +1 -0
- package/build/dataviews/actions/view-post.js +36 -0
- package/build/dataviews/actions/view-post.js.map +1 -0
- package/build/dataviews/fields/index.js +32 -0
- package/build/dataviews/fields/index.js.map +1 -0
- package/build/dataviews/store/private-actions.js +16 -2
- package/build/dataviews/store/private-actions.js.map +1 -1
- package/build/dataviews/types.js.map +1 -1
- package/build/private-apis.js +2 -0
- package/build/private-apis.js.map +1 -1
- package/build/store/private-actions.js +1 -1
- package/build/store/private-actions.js.map +1 -1
- package/build/store/utils/is-template-revertable.js +1 -1
- package/build/store/utils/is-template-revertable.js.map +1 -1
- package/build-module/bindings/post-meta.js +2 -2
- package/build-module/bindings/post-meta.js.map +1 -1
- package/build-module/components/create-template-part-modal/index.js +1 -0
- package/build-module/components/create-template-part-modal/index.js.map +1 -1
- package/build-module/components/global-styles-provider/index.js +17 -4
- package/build-module/components/global-styles-provider/index.js.map +1 -1
- package/build-module/components/inserter-sidebar/index.js +5 -2
- package/build-module/components/inserter-sidebar/index.js.map +1 -1
- package/build-module/components/page-attributes/parent.js +6 -5
- package/build-module/components/page-attributes/parent.js.map +1 -1
- package/build-module/components/post-actions/actions.js +5 -501
- package/build-module/components/post-actions/actions.js.map +1 -1
- package/build-module/components/post-actions/index.js +8 -17
- package/build-module/components/post-actions/index.js.map +1 -1
- package/build-module/components/post-card-panel/index.js +20 -20
- package/build-module/components/post-card-panel/index.js.map +1 -1
- package/build-module/components/post-featured-image/index.js +2 -0
- package/build-module/components/post-featured-image/index.js.map +1 -1
- package/build-module/components/post-publish-panel/postpublish.js +4 -0
- package/build-module/components/post-publish-panel/postpublish.js.map +1 -1
- package/build-module/components/post-slug/index.js +1 -0
- package/build-module/components/post-slug/index.js.map +1 -1
- package/build-module/components/post-taxonomies/hierarchical-term-selector.js +3 -2
- package/build-module/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
- package/build-module/components/post-url/index.js +7 -6
- package/build-module/components/post-url/index.js.map +1 -1
- package/build-module/components/sidebar/post-summary.js +10 -7
- package/build-module/components/sidebar/post-summary.js.map +1 -1
- package/build-module/components/template-content-panel/index.js +1 -1
- package/build-module/components/template-content-panel/index.js.map +1 -1
- package/build-module/dataviews/actions/duplicate-pattern.js +39 -0
- package/build-module/dataviews/actions/duplicate-pattern.js.map +1 -0
- package/build-module/dataviews/actions/duplicate-post.js +139 -0
- package/build-module/dataviews/actions/duplicate-post.js.map +1 -0
- package/build-module/dataviews/actions/duplicate-post.native.js +3 -0
- package/build-module/dataviews/actions/duplicate-post.native.js.map +1 -0
- package/build-module/dataviews/actions/duplicate-template-part.js +58 -0
- package/build-module/dataviews/actions/duplicate-template-part.js.map +1 -0
- package/build-module/dataviews/actions/rename-post.js +118 -0
- package/build-module/dataviews/actions/rename-post.js.map +1 -0
- package/build-module/dataviews/actions/reorder-page.js +111 -0
- package/build-module/dataviews/actions/reorder-page.js.map +1 -0
- package/build-module/dataviews/actions/reorder-page.native.js +3 -0
- package/build-module/dataviews/actions/reorder-page.native.js.map +1 -0
- package/build-module/dataviews/actions/reset-post.js +1 -1
- package/build-module/dataviews/actions/reset-post.js.map +1 -1
- package/build-module/dataviews/actions/utils.js +7 -1
- package/build-module/dataviews/actions/utils.js.map +1 -1
- package/build-module/dataviews/actions/view-post-revisions.js +43 -0
- package/build-module/dataviews/actions/view-post-revisions.js.map +1 -0
- package/build-module/dataviews/actions/view-post.js +30 -0
- package/build-module/dataviews/actions/view-post.js.map +1 -0
- package/build-module/dataviews/fields/index.js +26 -0
- package/build-module/dataviews/fields/index.js.map +1 -0
- package/build-module/dataviews/store/private-actions.js +16 -2
- package/build-module/dataviews/store/private-actions.js.map +1 -1
- package/build-module/dataviews/types.js.map +1 -1
- package/build-module/private-apis.js +2 -0
- package/build-module/private-apis.js.map +1 -1
- package/build-module/store/private-actions.js +1 -1
- package/build-module/store/private-actions.js.map +1 -1
- package/build-module/store/utils/is-template-revertable.js +1 -1
- package/build-module/store/utils/is-template-revertable.js.map +1 -1
- package/build-style/style-rtl.css +2 -31
- package/build-style/style.css +2 -31
- package/build-types/components/create-template-part-modal/index.d.ts.map +1 -1
- package/build-types/components/global-styles-provider/index.d.ts.map +1 -1
- package/build-types/components/inserter-sidebar/index.d.ts.map +1 -1
- package/build-types/components/page-attributes/parent.d.ts.map +1 -1
- package/build-types/components/post-actions/actions.d.ts +1 -26
- package/build-types/components/post-actions/actions.d.ts.map +1 -1
- package/build-types/components/post-actions/index.d.ts +3 -2
- package/build-types/components/post-actions/index.d.ts.map +1 -1
- package/build-types/components/post-card-panel/index.d.ts +4 -2
- package/build-types/components/post-card-panel/index.d.ts.map +1 -1
- package/build-types/components/post-slug/index.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/hierarchical-term-selector.d.ts +1 -17
- package/build-types/components/post-taxonomies/hierarchical-term-selector.d.ts.map +1 -1
- package/build-types/components/post-url/index.d.ts.map +1 -1
- package/build-types/components/sidebar/post-summary.d.ts.map +1 -1
- package/build-types/components/template-content-panel/index.d.ts.map +1 -1
- package/build-types/dataviews/actions/duplicate-pattern.d.ts +5 -0
- package/build-types/dataviews/actions/duplicate-pattern.d.ts.map +1 -0
- package/build-types/dataviews/actions/duplicate-post.d.ts +5 -0
- package/build-types/dataviews/actions/duplicate-post.d.ts.map +1 -0
- package/build-types/dataviews/actions/duplicate-post.native.d.ts +3 -0
- package/build-types/dataviews/actions/duplicate-post.native.d.ts.map +1 -0
- package/build-types/dataviews/actions/duplicate-template-part.d.ts +5 -0
- package/build-types/dataviews/actions/duplicate-template-part.d.ts.map +1 -0
- package/build-types/dataviews/actions/rename-post.d.ts +5 -0
- package/build-types/dataviews/actions/rename-post.d.ts.map +1 -0
- package/build-types/dataviews/actions/reorder-page.d.ts +8 -0
- package/build-types/dataviews/actions/reorder-page.d.ts.map +1 -0
- package/build-types/dataviews/actions/reorder-page.native.d.ts +3 -0
- package/build-types/dataviews/actions/reorder-page.native.d.ts.map +1 -0
- package/build-types/dataviews/actions/reset-post.d.ts.map +1 -1
- package/build-types/dataviews/actions/utils.d.ts +5 -3
- package/build-types/dataviews/actions/utils.d.ts.map +1 -1
- package/build-types/dataviews/actions/view-post-revisions.d.ts +8 -0
- package/build-types/dataviews/actions/view-post-revisions.d.ts.map +1 -0
- package/build-types/dataviews/actions/view-post.d.ts +8 -0
- package/build-types/dataviews/actions/view-post.d.ts.map +1 -0
- package/build-types/dataviews/fields/index.d.ts +8 -0
- package/build-types/dataviews/fields/index.d.ts.map +1 -0
- package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
- package/build-types/dataviews/types.d.ts +57 -8
- package/build-types/dataviews/types.d.ts.map +1 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/store/utils/is-template-revertable.d.ts.map +1 -1
- package/package.json +36 -36
- package/src/bindings/post-meta.js +2 -2
- package/src/components/block-manager/style.scss +2 -2
- package/src/components/create-template-part-modal/index.js +1 -0
- package/src/components/error-boundary/style.native.scss +1 -1
- package/src/components/error-boundary/style.scss +1 -1
- package/src/components/global-styles-provider/index.js +16 -3
- package/src/components/inserter-sidebar/index.js +10 -4
- package/src/components/page-attributes/parent.js +13 -9
- package/src/components/post-actions/actions.js +5 -616
- package/src/components/post-actions/index.js +16 -20
- package/src/components/post-card-panel/index.js +28 -27
- package/src/components/post-discussion/style.scss +0 -9
- package/src/components/post-featured-image/index.js +2 -0
- package/src/components/post-format/style.scss +0 -6
- package/src/components/post-publish-panel/postpublish.js +8 -2
- package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +8 -8
- package/src/components/post-slug/index.js +1 -0
- package/src/components/post-status/style.scss +0 -19
- package/src/components/post-taxonomies/hierarchical-term-selector.js +3 -1
- package/src/components/post-url/index.js +15 -9
- package/src/components/save-publish-panels/style.scss +3 -3
- package/src/components/sidebar/post-summary.js +20 -16
- package/src/components/site-discussion/style.scss +0 -14
- package/src/components/template-content-panel/index.js +4 -1
- package/src/dataviews/actions/duplicate-pattern.tsx +40 -0
- package/src/dataviews/actions/duplicate-post.native.tsx +3 -0
- package/src/dataviews/actions/duplicate-post.tsx +174 -0
- package/src/dataviews/actions/duplicate-template-part.tsx +70 -0
- package/src/dataviews/actions/rename-post.tsx +146 -0
- package/src/dataviews/actions/reorder-page.native.tsx +3 -0
- package/src/dataviews/actions/reorder-page.tsx +125 -0
- package/src/dataviews/actions/reset-post.tsx +2 -1
- package/src/dataviews/actions/utils.ts +14 -4
- package/src/dataviews/actions/view-post-revisions.tsx +47 -0
- package/src/dataviews/actions/view-post.tsx +30 -0
- package/src/dataviews/fields/index.ts +26 -0
- package/src/dataviews/store/private-actions.ts +42 -1
- package/src/dataviews/types.ts +47 -6
- package/src/private-apis.js +2 -0
- package/src/store/private-actions.js +1 -1
- package/src/store/utils/is-template-revertable.js +2 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useDispatch } from '@wordpress/data';
|
|
5
|
+
import { __, sprintf, _x } from '@wordpress/i18n';
|
|
6
|
+
import { store as noticesStore } from '@wordpress/notices';
|
|
7
|
+
import { useMemo } from '@wordpress/element';
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
import { parse } from '@wordpress/blocks';
|
|
10
|
+
import type { Action } from '@wordpress/dataviews';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
import { TEMPLATE_PART_POST_TYPE } from '../../store/constants';
|
|
16
|
+
import { CreateTemplatePartModalContents } from '../../components/create-template-part-modal';
|
|
17
|
+
import { getItemTitle } from './utils';
|
|
18
|
+
import type { TemplatePart } from '../types';
|
|
19
|
+
|
|
20
|
+
const duplicateTemplatePart: Action< TemplatePart > = {
|
|
21
|
+
id: 'duplicate-template-part',
|
|
22
|
+
label: _x( 'Duplicate', 'action label' ),
|
|
23
|
+
isEligible: ( item ) => item.type === TEMPLATE_PART_POST_TYPE,
|
|
24
|
+
modalHeader: _x( 'Duplicate template part', 'action label' ),
|
|
25
|
+
RenderModal: ( { items, closeModal } ) => {
|
|
26
|
+
const [ item ] = items;
|
|
27
|
+
const blocks = useMemo( () => {
|
|
28
|
+
return (
|
|
29
|
+
item.blocks ??
|
|
30
|
+
parse(
|
|
31
|
+
typeof item.content === 'string'
|
|
32
|
+
? item.content
|
|
33
|
+
: item.content.raw,
|
|
34
|
+
{
|
|
35
|
+
__unstableSkipMigrationLogs: true,
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
}, [ item.content, item.blocks ] );
|
|
40
|
+
const { createSuccessNotice } = useDispatch( noticesStore );
|
|
41
|
+
function onTemplatePartSuccess() {
|
|
42
|
+
createSuccessNotice(
|
|
43
|
+
sprintf(
|
|
44
|
+
// translators: %s: The new template part's title e.g. 'Call to action (copy)'.
|
|
45
|
+
__( '"%s" duplicated.' ),
|
|
46
|
+
getItemTitle( item )
|
|
47
|
+
),
|
|
48
|
+
{ type: 'snackbar', id: 'edit-site-patterns-success' }
|
|
49
|
+
);
|
|
50
|
+
closeModal?.();
|
|
51
|
+
}
|
|
52
|
+
return (
|
|
53
|
+
<CreateTemplatePartModalContents
|
|
54
|
+
blocks={ blocks }
|
|
55
|
+
defaultArea={ item.area }
|
|
56
|
+
defaultTitle={ sprintf(
|
|
57
|
+
/* translators: %s: Existing template part title */
|
|
58
|
+
__( '%s (Copy)' ),
|
|
59
|
+
getItemTitle( item )
|
|
60
|
+
) }
|
|
61
|
+
onCreate={ onTemplatePartSuccess }
|
|
62
|
+
onError={ closeModal }
|
|
63
|
+
confirmLabel={ _x( 'Duplicate', 'action label' ) }
|
|
64
|
+
closeModal={ closeModal }
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default duplicateTemplatePart;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useDispatch } from '@wordpress/data';
|
|
5
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
import { useState } from '@wordpress/element';
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
|
|
10
|
+
import {
|
|
11
|
+
Button,
|
|
12
|
+
TextControl,
|
|
13
|
+
__experimentalHStack as HStack,
|
|
14
|
+
__experimentalVStack as VStack,
|
|
15
|
+
} from '@wordpress/components';
|
|
16
|
+
import type { Action } from '@wordpress/dataviews';
|
|
17
|
+
import { store as noticesStore } from '@wordpress/notices';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Internal dependencies
|
|
21
|
+
*/
|
|
22
|
+
import {
|
|
23
|
+
TEMPLATE_ORIGINS,
|
|
24
|
+
TEMPLATE_PART_POST_TYPE,
|
|
25
|
+
TEMPLATE_POST_TYPE,
|
|
26
|
+
} from '../../store/constants';
|
|
27
|
+
import { unlock } from '../../lock-unlock';
|
|
28
|
+
import {
|
|
29
|
+
getItemTitle,
|
|
30
|
+
isTemplateRemovable,
|
|
31
|
+
isTemplate,
|
|
32
|
+
isTemplatePart,
|
|
33
|
+
} from './utils';
|
|
34
|
+
import type { CoreDataError, PostWithPermissions } from '../types';
|
|
35
|
+
|
|
36
|
+
// Patterns.
|
|
37
|
+
const { PATTERN_TYPES } = unlock( patternsPrivateApis );
|
|
38
|
+
|
|
39
|
+
const renamePost: Action< PostWithPermissions > = {
|
|
40
|
+
id: 'rename-post',
|
|
41
|
+
label: __( 'Rename' ),
|
|
42
|
+
isEligible( post ) {
|
|
43
|
+
if ( post.status === 'trash' ) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
// Templates, template parts and patterns have special checks for renaming.
|
|
47
|
+
if (
|
|
48
|
+
! [
|
|
49
|
+
TEMPLATE_POST_TYPE,
|
|
50
|
+
TEMPLATE_PART_POST_TYPE,
|
|
51
|
+
...Object.values( PATTERN_TYPES ),
|
|
52
|
+
].includes( post.type )
|
|
53
|
+
) {
|
|
54
|
+
return post.permissions?.update;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// In the case of templates, we can only rename custom templates.
|
|
58
|
+
if ( isTemplate( post ) ) {
|
|
59
|
+
return (
|
|
60
|
+
isTemplateRemovable( post ) &&
|
|
61
|
+
post.is_custom &&
|
|
62
|
+
post.permissions?.update
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if ( isTemplatePart( post ) ) {
|
|
67
|
+
return (
|
|
68
|
+
post.source === TEMPLATE_ORIGINS.custom &&
|
|
69
|
+
! post?.has_theme_file &&
|
|
70
|
+
post.permissions?.update
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return post.type === PATTERN_TYPES.user && post.permissions?.update;
|
|
75
|
+
},
|
|
76
|
+
RenderModal: ( { items, closeModal, onActionPerformed } ) => {
|
|
77
|
+
const [ item ] = items;
|
|
78
|
+
const [ title, setTitle ] = useState( () => getItemTitle( item ) );
|
|
79
|
+
const { editEntityRecord, saveEditedEntityRecord } =
|
|
80
|
+
useDispatch( coreStore );
|
|
81
|
+
const { createSuccessNotice, createErrorNotice } =
|
|
82
|
+
useDispatch( noticesStore );
|
|
83
|
+
|
|
84
|
+
async function onRename( event: React.FormEvent ) {
|
|
85
|
+
event.preventDefault();
|
|
86
|
+
try {
|
|
87
|
+
await editEntityRecord( 'postType', item.type, item.id, {
|
|
88
|
+
title,
|
|
89
|
+
} );
|
|
90
|
+
// Update state before saving rerenders the list.
|
|
91
|
+
setTitle( '' );
|
|
92
|
+
closeModal?.();
|
|
93
|
+
// Persist edited entity.
|
|
94
|
+
await saveEditedEntityRecord( 'postType', item.type, item.id, {
|
|
95
|
+
throwOnError: true,
|
|
96
|
+
} );
|
|
97
|
+
createSuccessNotice( __( 'Name updated' ), {
|
|
98
|
+
type: 'snackbar',
|
|
99
|
+
} );
|
|
100
|
+
onActionPerformed?.( items );
|
|
101
|
+
} catch ( error ) {
|
|
102
|
+
const typedError = error as CoreDataError;
|
|
103
|
+
const errorMessage =
|
|
104
|
+
typedError.message && typedError.code !== 'unknown_error'
|
|
105
|
+
? typedError.message
|
|
106
|
+
: __( 'An error occurred while updating the name' );
|
|
107
|
+
createErrorNotice( errorMessage, { type: 'snackbar' } );
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<form onSubmit={ onRename }>
|
|
113
|
+
<VStack spacing="5">
|
|
114
|
+
<TextControl
|
|
115
|
+
__nextHasNoMarginBottom
|
|
116
|
+
__next40pxDefaultSize
|
|
117
|
+
label={ __( 'Name' ) }
|
|
118
|
+
value={ title }
|
|
119
|
+
onChange={ setTitle }
|
|
120
|
+
required
|
|
121
|
+
/>
|
|
122
|
+
<HStack justify="right">
|
|
123
|
+
<Button
|
|
124
|
+
__next40pxDefaultSize
|
|
125
|
+
variant="tertiary"
|
|
126
|
+
onClick={ () => {
|
|
127
|
+
closeModal?.();
|
|
128
|
+
} }
|
|
129
|
+
>
|
|
130
|
+
{ __( 'Cancel' ) }
|
|
131
|
+
</Button>
|
|
132
|
+
<Button
|
|
133
|
+
__next40pxDefaultSize
|
|
134
|
+
variant="primary"
|
|
135
|
+
type="submit"
|
|
136
|
+
>
|
|
137
|
+
{ __( 'Save' ) }
|
|
138
|
+
</Button>
|
|
139
|
+
</HStack>
|
|
140
|
+
</VStack>
|
|
141
|
+
</form>
|
|
142
|
+
);
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export default renamePost;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useDispatch } from '@wordpress/data';
|
|
5
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
import { store as noticesStore } from '@wordpress/notices';
|
|
8
|
+
import { useState } from '@wordpress/element';
|
|
9
|
+
import { DataForm, isItemValid } from '@wordpress/dataviews';
|
|
10
|
+
import {
|
|
11
|
+
Button,
|
|
12
|
+
__experimentalHStack as HStack,
|
|
13
|
+
__experimentalVStack as VStack,
|
|
14
|
+
} from '@wordpress/components';
|
|
15
|
+
import type { Action, RenderModalProps } from '@wordpress/dataviews';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Internal dependencies
|
|
19
|
+
*/
|
|
20
|
+
import type { CoreDataError, BasePost } from '../types';
|
|
21
|
+
import { orderField } from '../fields';
|
|
22
|
+
|
|
23
|
+
const fields = [ orderField ];
|
|
24
|
+
const formOrderAction = {
|
|
25
|
+
fields: [ 'menu_order' ],
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function ReorderModal( {
|
|
29
|
+
items,
|
|
30
|
+
closeModal,
|
|
31
|
+
onActionPerformed,
|
|
32
|
+
}: RenderModalProps< BasePost > ) {
|
|
33
|
+
const [ item, setItem ] = useState( items[ 0 ] );
|
|
34
|
+
const orderInput = item.menu_order;
|
|
35
|
+
const { editEntityRecord, saveEditedEntityRecord } =
|
|
36
|
+
useDispatch( coreStore );
|
|
37
|
+
const { createSuccessNotice, createErrorNotice } =
|
|
38
|
+
useDispatch( noticesStore );
|
|
39
|
+
|
|
40
|
+
async function onOrder( event: React.FormEvent ) {
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
|
|
43
|
+
if ( ! isItemValid( item, fields, formOrderAction ) ) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
await editEntityRecord( 'postType', item.type, item.id, {
|
|
49
|
+
menu_order: orderInput,
|
|
50
|
+
} );
|
|
51
|
+
closeModal?.();
|
|
52
|
+
// Persist edited entity.
|
|
53
|
+
await saveEditedEntityRecord( 'postType', item.type, item.id, {
|
|
54
|
+
throwOnError: true,
|
|
55
|
+
} );
|
|
56
|
+
createSuccessNotice( __( 'Order updated.' ), {
|
|
57
|
+
type: 'snackbar',
|
|
58
|
+
} );
|
|
59
|
+
onActionPerformed?.( items );
|
|
60
|
+
} catch ( error ) {
|
|
61
|
+
const typedError = error as CoreDataError;
|
|
62
|
+
const errorMessage =
|
|
63
|
+
typedError.message && typedError.code !== 'unknown_error'
|
|
64
|
+
? typedError.message
|
|
65
|
+
: __( 'An error occurred while updating the order' );
|
|
66
|
+
createErrorNotice( errorMessage, {
|
|
67
|
+
type: 'snackbar',
|
|
68
|
+
} );
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const isSaveDisabled = ! isItemValid( item, fields, formOrderAction );
|
|
72
|
+
return (
|
|
73
|
+
<form onSubmit={ onOrder }>
|
|
74
|
+
<VStack spacing="5">
|
|
75
|
+
<div>
|
|
76
|
+
{ __(
|
|
77
|
+
'Determines the order of pages. Pages with the same order value are sorted alphabetically. Negative order values are supported.'
|
|
78
|
+
) }
|
|
79
|
+
</div>
|
|
80
|
+
<DataForm
|
|
81
|
+
data={ item }
|
|
82
|
+
fields={ fields }
|
|
83
|
+
form={ formOrderAction }
|
|
84
|
+
onChange={ ( changes ) =>
|
|
85
|
+
setItem( {
|
|
86
|
+
...item,
|
|
87
|
+
...changes,
|
|
88
|
+
} )
|
|
89
|
+
}
|
|
90
|
+
/>
|
|
91
|
+
<HStack justify="right">
|
|
92
|
+
<Button
|
|
93
|
+
__next40pxDefaultSize
|
|
94
|
+
variant="tertiary"
|
|
95
|
+
onClick={ () => {
|
|
96
|
+
closeModal?.();
|
|
97
|
+
} }
|
|
98
|
+
>
|
|
99
|
+
{ __( 'Cancel' ) }
|
|
100
|
+
</Button>
|
|
101
|
+
<Button
|
|
102
|
+
__next40pxDefaultSize
|
|
103
|
+
variant="primary"
|
|
104
|
+
type="submit"
|
|
105
|
+
accessibleWhenDisabled
|
|
106
|
+
disabled={ isSaveDisabled }
|
|
107
|
+
>
|
|
108
|
+
{ __( 'Save' ) }
|
|
109
|
+
</Button>
|
|
110
|
+
</HStack>
|
|
111
|
+
</VStack>
|
|
112
|
+
</form>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const reorderPage: Action< BasePost > = {
|
|
117
|
+
id: 'order-pages',
|
|
118
|
+
label: __( 'Order' ),
|
|
119
|
+
isEligible( { status } ) {
|
|
120
|
+
return status !== 'trash';
|
|
121
|
+
},
|
|
122
|
+
RenderModal: ReorderModal,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export default reorderPage;
|
|
@@ -32,7 +32,8 @@ const resetPost: Action< Post > = {
|
|
|
32
32
|
return (
|
|
33
33
|
isTemplateOrTemplatePart( item ) &&
|
|
34
34
|
item?.source === TEMPLATE_ORIGINS.custom &&
|
|
35
|
-
item?.
|
|
35
|
+
( Boolean( item.type === 'wp_template' && item?.plugin ) ||
|
|
36
|
+
item?.has_theme_file )
|
|
36
37
|
);
|
|
37
38
|
},
|
|
38
39
|
icon: backup,
|
|
@@ -12,11 +12,19 @@ import {
|
|
|
12
12
|
TEMPLATE_POST_TYPE,
|
|
13
13
|
} from '../../store/constants';
|
|
14
14
|
|
|
15
|
-
import type { Post,
|
|
15
|
+
import type { Post, TemplatePart, Template } from '../types';
|
|
16
|
+
|
|
17
|
+
export function isTemplate( post: Post ): post is Template {
|
|
18
|
+
return post.type === TEMPLATE_POST_TYPE;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function isTemplatePart( post: Post ): post is TemplatePart {
|
|
22
|
+
return post.type === TEMPLATE_PART_POST_TYPE;
|
|
23
|
+
}
|
|
16
24
|
|
|
17
25
|
export function isTemplateOrTemplatePart(
|
|
18
26
|
p: Post
|
|
19
|
-
): p is
|
|
27
|
+
): p is Template | TemplatePart {
|
|
20
28
|
return p.type === TEMPLATE_POST_TYPE || p.type === TEMPLATE_PART_POST_TYPE;
|
|
21
29
|
}
|
|
22
30
|
|
|
@@ -39,7 +47,7 @@ export function getItemTitle( item: Post ) {
|
|
|
39
47
|
* @param template The template entity to check.
|
|
40
48
|
* @return Whether the template is removable.
|
|
41
49
|
*/
|
|
42
|
-
export function isTemplateRemovable( template:
|
|
50
|
+
export function isTemplateRemovable( template: Template | TemplatePart ) {
|
|
43
51
|
if ( ! template ) {
|
|
44
52
|
return false;
|
|
45
53
|
}
|
|
@@ -49,6 +57,8 @@ export function isTemplateRemovable( template: TemplateOrTemplatePart ) {
|
|
|
49
57
|
return (
|
|
50
58
|
[ template.source, template.source ].includes(
|
|
51
59
|
TEMPLATE_ORIGINS.custom
|
|
52
|
-
) &&
|
|
60
|
+
) &&
|
|
61
|
+
! Boolean( template.type === 'wp_template' && template?.plugin ) &&
|
|
62
|
+
! template.has_theme_file
|
|
53
63
|
);
|
|
54
64
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { addQueryArgs } from '@wordpress/url';
|
|
5
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
6
|
+
import type { Action } from '@wordpress/dataviews';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import type { Post } from '../types';
|
|
12
|
+
|
|
13
|
+
const viewPostRevisions: Action< Post > = {
|
|
14
|
+
id: 'view-post-revisions',
|
|
15
|
+
context: 'list',
|
|
16
|
+
label( items ) {
|
|
17
|
+
const revisionsCount =
|
|
18
|
+
items[ 0 ]._links?.[ 'version-history' ]?.[ 0 ]?.count ?? 0;
|
|
19
|
+
return sprintf(
|
|
20
|
+
/* translators: %s: number of revisions */
|
|
21
|
+
__( 'View revisions (%s)' ),
|
|
22
|
+
revisionsCount
|
|
23
|
+
);
|
|
24
|
+
},
|
|
25
|
+
isEligible( post ) {
|
|
26
|
+
if ( post.status === 'trash' ) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const lastRevisionId =
|
|
30
|
+
post?._links?.[ 'predecessor-version' ]?.[ 0 ]?.id ?? null;
|
|
31
|
+
const revisionsCount =
|
|
32
|
+
post?._links?.[ 'version-history' ]?.[ 0 ]?.count ?? 0;
|
|
33
|
+
return !! lastRevisionId && revisionsCount > 1;
|
|
34
|
+
},
|
|
35
|
+
callback( posts, { onActionPerformed } ) {
|
|
36
|
+
const post = posts[ 0 ];
|
|
37
|
+
const href = addQueryArgs( 'revision.php', {
|
|
38
|
+
revision: post?._links?.[ 'predecessor-version' ]?.[ 0 ]?.id,
|
|
39
|
+
} );
|
|
40
|
+
document.location.href = href;
|
|
41
|
+
if ( onActionPerformed ) {
|
|
42
|
+
onActionPerformed( posts );
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default viewPostRevisions;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { external } from '@wordpress/icons';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
import type { Action } from '@wordpress/dataviews';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import type { BasePost } from '../types';
|
|
12
|
+
|
|
13
|
+
const viewPost: Action< BasePost > = {
|
|
14
|
+
id: 'view-post',
|
|
15
|
+
label: __( 'View' ),
|
|
16
|
+
isPrimary: true,
|
|
17
|
+
icon: external,
|
|
18
|
+
isEligible( post ) {
|
|
19
|
+
return post.status !== 'trash';
|
|
20
|
+
},
|
|
21
|
+
callback( posts, { onActionPerformed } ) {
|
|
22
|
+
const post = posts[ 0 ];
|
|
23
|
+
window.open( post?.link, '_blank' );
|
|
24
|
+
if ( onActionPerformed ) {
|
|
25
|
+
onActionPerformed( posts );
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default viewPost;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import type { Field } from '@wordpress/dataviews';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import type { BasePost } from '../types';
|
|
11
|
+
import { getItemTitle } from '../actions/utils';
|
|
12
|
+
|
|
13
|
+
export const titleField: Field< BasePost > = {
|
|
14
|
+
type: 'text',
|
|
15
|
+
id: 'title',
|
|
16
|
+
label: __( 'Title' ),
|
|
17
|
+
placeholder: __( 'No title' ),
|
|
18
|
+
getValue: ( { item } ) => getItemTitle( item ),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const orderField: Field< BasePost > = {
|
|
22
|
+
type: 'integer',
|
|
23
|
+
id: 'menu_order',
|
|
24
|
+
label: __( 'Order' ),
|
|
25
|
+
description: __( 'Determines the order of pages.' ),
|
|
26
|
+
};
|
|
@@ -9,14 +9,21 @@ import { doAction } from '@wordpress/hooks';
|
|
|
9
9
|
* Internal dependencies
|
|
10
10
|
*/
|
|
11
11
|
import deletePost from '../actions/delete-post';
|
|
12
|
+
import duplicatePattern from '../actions/duplicate-pattern';
|
|
13
|
+
import duplicateTemplatePart from '../actions/duplicate-template-part';
|
|
12
14
|
import exportPattern from '../actions/export-pattern';
|
|
13
15
|
import resetPost from '../actions/reset-post';
|
|
14
16
|
import trashPost from '../actions/trash-post';
|
|
15
17
|
import permanentlyDeletePost from '../actions/permanently-delete-post';
|
|
18
|
+
import renamePost from '../actions/rename-post';
|
|
19
|
+
import reorderPage from '../actions/reorder-page';
|
|
16
20
|
import restorePost from '../actions/restore-post';
|
|
17
21
|
import type { PostType } from '../types';
|
|
18
22
|
import { store as editorStore } from '../../store';
|
|
19
23
|
import { unlock } from '../../lock-unlock';
|
|
24
|
+
import duplicatePost from '../actions/duplicate-post';
|
|
25
|
+
import viewPostRevisions from '../actions/view-post-revisions';
|
|
26
|
+
import viewPost from '../actions/view-post';
|
|
20
27
|
|
|
21
28
|
export function registerEntityAction< Item >(
|
|
22
29
|
kind: string,
|
|
@@ -72,7 +79,41 @@ export const registerPostTypeActions =
|
|
|
72
79
|
.resolveSelect( coreStore )
|
|
73
80
|
.getPostType( postType ) ) as PostType;
|
|
74
81
|
|
|
82
|
+
const canCreate = await registry
|
|
83
|
+
.resolveSelect( coreStore )
|
|
84
|
+
.canUser( 'create', {
|
|
85
|
+
kind: 'postType',
|
|
86
|
+
name: postType,
|
|
87
|
+
} );
|
|
88
|
+
const currentTheme = await registry
|
|
89
|
+
.resolveSelect( coreStore )
|
|
90
|
+
.getCurrentTheme();
|
|
91
|
+
|
|
75
92
|
const actions = [
|
|
93
|
+
postTypeConfig.viewable ? viewPost : undefined,
|
|
94
|
+
!! postTypeConfig?.supports?.revisions
|
|
95
|
+
? viewPostRevisions
|
|
96
|
+
: undefined,
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
globalThis.IS_GUTENBERG_PLUGIN
|
|
99
|
+
? ! [ 'wp_template', 'wp_block', 'wp_template_part' ].includes(
|
|
100
|
+
postTypeConfig.slug
|
|
101
|
+
) &&
|
|
102
|
+
canCreate &&
|
|
103
|
+
duplicatePost
|
|
104
|
+
: undefined,
|
|
105
|
+
postTypeConfig.slug === 'wp_template_part' &&
|
|
106
|
+
canCreate &&
|
|
107
|
+
currentTheme?.is_block_theme
|
|
108
|
+
? duplicateTemplatePart
|
|
109
|
+
: undefined,
|
|
110
|
+
canCreate && postTypeConfig.slug === 'wp_block'
|
|
111
|
+
? duplicatePattern
|
|
112
|
+
: undefined,
|
|
113
|
+
postTypeConfig.supports?.title ? renamePost : undefined,
|
|
114
|
+
postTypeConfig?.supports?.[ 'page-attributes' ]
|
|
115
|
+
? reorderPage
|
|
116
|
+
: undefined,
|
|
76
117
|
postTypeConfig.slug === 'wp_block' ? exportPattern : undefined,
|
|
77
118
|
resetPost,
|
|
78
119
|
restorePost,
|
|
@@ -83,7 +124,7 @@ export const registerPostTypeActions =
|
|
|
83
124
|
|
|
84
125
|
registry.batch( () => {
|
|
85
126
|
actions.forEach( ( action ) => {
|
|
86
|
-
if ( action
|
|
127
|
+
if ( ! action ) {
|
|
87
128
|
return;
|
|
88
129
|
}
|
|
89
130
|
unlock( registry.dispatch( editorStore ) ).registerEntityAction(
|
package/src/dataviews/types.ts
CHANGED
|
@@ -7,27 +7,62 @@ type PostStatus =
|
|
|
7
7
|
| 'auto-draft'
|
|
8
8
|
| 'trash';
|
|
9
9
|
|
|
10
|
-
export interface
|
|
10
|
+
export interface CommonPost {
|
|
11
11
|
status?: PostStatus;
|
|
12
12
|
title: string | { rendered: string } | { raw: string };
|
|
13
|
+
content: string | { raw: string; rendered: string };
|
|
13
14
|
type: string;
|
|
14
15
|
id: string | number;
|
|
16
|
+
blocks?: Object[];
|
|
17
|
+
_links?: Links;
|
|
15
18
|
}
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
|
|
20
|
+
interface Links {
|
|
21
|
+
'predecessor-version'?: { href: string; id: number }[];
|
|
22
|
+
'version-history'?: { href: string; count: number }[];
|
|
23
|
+
[ key: string ]: { href: string }[] | undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface BasePost extends CommonPost {
|
|
27
|
+
comment_status?: 'open' | 'closed';
|
|
28
|
+
excerpt?: string | { raw: string; rendered: string };
|
|
29
|
+
meta?: Record< string, any >;
|
|
30
|
+
parent?: number;
|
|
31
|
+
password?: string;
|
|
32
|
+
template?: string;
|
|
33
|
+
format?: string;
|
|
34
|
+
featured_media?: number;
|
|
35
|
+
menu_order?: number;
|
|
36
|
+
ping_status?: 'open' | 'closed';
|
|
37
|
+
link?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface Template extends CommonPost {
|
|
41
|
+
type: 'wp_template';
|
|
42
|
+
is_custom: boolean;
|
|
18
43
|
source: string;
|
|
44
|
+
origin: string;
|
|
45
|
+
plugin?: string;
|
|
19
46
|
has_theme_file: boolean;
|
|
20
47
|
id: string;
|
|
21
48
|
}
|
|
22
49
|
|
|
23
|
-
export interface
|
|
50
|
+
export interface TemplatePart extends CommonPost {
|
|
51
|
+
type: 'wp_template_part';
|
|
52
|
+
source: string;
|
|
53
|
+
origin: string;
|
|
54
|
+
has_theme_file: boolean;
|
|
55
|
+
id: string;
|
|
56
|
+
area: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface Pattern extends CommonPost {
|
|
24
60
|
slug: string;
|
|
25
61
|
title: { raw: string };
|
|
26
|
-
content: { raw: string } | string;
|
|
27
62
|
wp_pattern_sync_status: string;
|
|
28
63
|
}
|
|
29
64
|
|
|
30
|
-
export type Post =
|
|
65
|
+
export type Post = Template | TemplatePart | Pattern | BasePost;
|
|
31
66
|
|
|
32
67
|
export type PostWithPermissions = Post & {
|
|
33
68
|
permissions: {
|
|
@@ -38,6 +73,12 @@ export type PostWithPermissions = Post & {
|
|
|
38
73
|
|
|
39
74
|
export interface PostType {
|
|
40
75
|
slug: string;
|
|
76
|
+
viewable: boolean;
|
|
77
|
+
supports?: {
|
|
78
|
+
'page-attributes'?: boolean;
|
|
79
|
+
title?: boolean;
|
|
80
|
+
revisions?: boolean;
|
|
81
|
+
};
|
|
41
82
|
}
|
|
42
83
|
|
|
43
84
|
// Will be unnecessary after typescript 5.0 upgrade.
|
package/src/private-apis.js
CHANGED
|
@@ -14,6 +14,7 @@ import BackButton from './components/header/back-button';
|
|
|
14
14
|
import CreateTemplatePartModal from './components/create-template-part-modal';
|
|
15
15
|
import Editor from './components/editor';
|
|
16
16
|
import PluginPostExcerpt from './components/post-excerpt/plugin';
|
|
17
|
+
import PostCardPanel from './components/post-card-panel';
|
|
17
18
|
import PreferencesModal from './components/preferences-modal';
|
|
18
19
|
import { usePostActions } from './components/post-actions/actions';
|
|
19
20
|
import ToolsMoreMenuGroup from './components/more-menu/tools-more-menu-group';
|
|
@@ -40,6 +41,7 @@ lock( privateApis, {
|
|
|
40
41
|
GlobalStylesProvider,
|
|
41
42
|
mergeBaseAndUserConfigs,
|
|
42
43
|
PluginPostExcerpt,
|
|
44
|
+
PostCardPanel,
|
|
43
45
|
PreferencesModal,
|
|
44
46
|
usePostActions,
|
|
45
47
|
ToolsMoreMenuGroup,
|
|
@@ -269,7 +269,7 @@ export const revertTemplate =
|
|
|
269
269
|
|
|
270
270
|
const fileTemplatePath = addQueryArgs(
|
|
271
271
|
`${ templateEntityConfig.baseURL }/${ template.id }`,
|
|
272
|
-
{ context: 'edit', source:
|
|
272
|
+
{ context: 'edit', source: template.origin }
|
|
273
273
|
);
|
|
274
274
|
|
|
275
275
|
const fileTemplate = await apiFetch( { path: fileTemplatePath } );
|
|
@@ -18,6 +18,7 @@ export default function isTemplateRevertable( templateOrTemplatePart ) {
|
|
|
18
18
|
|
|
19
19
|
return (
|
|
20
20
|
templateOrTemplatePart.source === TEMPLATE_ORIGINS.custom &&
|
|
21
|
-
templateOrTemplatePart
|
|
21
|
+
( Boolean( templateOrTemplatePart?.plugin ) ||
|
|
22
|
+
templateOrTemplatePart?.has_theme_file )
|
|
22
23
|
);
|
|
23
24
|
}
|