@wordpress/edit-site 6.4.0 → 6.5.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.
Files changed (198) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/add-new-pattern/index.js +6 -1
  3. package/build/components/add-new-pattern/index.js.map +1 -1
  4. package/build/components/add-new-post/index.js +2 -1
  5. package/build/components/add-new-post/index.js.map +1 -1
  6. package/build/components/add-new-template/utils.js +2 -2
  7. package/build/components/add-new-template/utils.js.map +1 -1
  8. package/build/components/editor/index.js +71 -20
  9. package/build/components/editor/index.js.map +1 -1
  10. package/build/components/global-styles/font-families.js +3 -4
  11. package/build/components/global-styles/font-families.js.map +1 -1
  12. package/build/components/global-styles/font-library-modal/context.js +0 -5
  13. package/build/components/global-styles/font-library-modal/context.js.map +1 -1
  14. package/build/components/global-styles/font-library-modal/font-collection.js +25 -5
  15. package/build/components/global-styles/font-library-modal/font-collection.js.map +1 -1
  16. package/build/components/global-styles/font-library-modal/index.js +1 -8
  17. package/build/components/global-styles/font-library-modal/index.js.map +1 -1
  18. package/build/components/global-styles/font-library-modal/installed-fonts.js +21 -6
  19. package/build/components/global-styles/font-library-modal/installed-fonts.js.map +1 -1
  20. package/build/components/global-styles/font-library-modal/upload-fonts.js +2 -3
  21. package/build/components/global-styles/font-library-modal/upload-fonts.js.map +1 -1
  22. package/build/components/global-styles/screen-typeset.js +40 -0
  23. package/build/components/global-styles/screen-typeset.js.map +1 -0
  24. package/build/components/global-styles/screen-typography-element.js +14 -0
  25. package/build/components/global-styles/screen-typography-element.js.map +1 -1
  26. package/build/components/global-styles/screen-typography.js +4 -6
  27. package/build/components/global-styles/screen-typography.js.map +1 -1
  28. package/build/components/global-styles/shadows-edit-panel.js +50 -59
  29. package/build/components/global-styles/shadows-edit-panel.js.map +1 -1
  30. package/build/components/global-styles/typeset-button.js +97 -0
  31. package/build/components/global-styles/typeset-button.js.map +1 -0
  32. package/build/components/global-styles/typeset.js +80 -0
  33. package/build/components/global-styles/typeset.js.map +1 -0
  34. package/build/components/global-styles/ui.js +4 -0
  35. package/build/components/global-styles/ui.js.map +1 -1
  36. package/build/components/global-styles/utils.js +10 -1
  37. package/build/components/global-styles/utils.js.map +1 -1
  38. package/build/components/page-patterns/fields.js +230 -0
  39. package/build/components/page-patterns/fields.js.map +1 -0
  40. package/build/components/page-patterns/index.js +8 -226
  41. package/build/components/page-patterns/index.js.map +1 -1
  42. package/build/components/page-patterns/use-patterns.js +26 -1
  43. package/build/components/page-patterns/use-patterns.js.map +1 -1
  44. package/build/components/page-templates/fields.js +169 -0
  45. package/build/components/page-templates/fields.js.map +1 -0
  46. package/build/components/page-templates/index.js +10 -177
  47. package/build/components/page-templates/index.js.map +1 -1
  48. package/build/components/post-edit/index.js +18 -6
  49. package/build/components/post-edit/index.js.map +1 -1
  50. package/build/components/post-fields/index.js +19 -15
  51. package/build/components/post-fields/index.js.map +1 -1
  52. package/build/components/post-list/index.js +125 -67
  53. package/build/components/post-list/index.js.map +1 -1
  54. package/build/components/sidebar-dataviews/add-new-view.js +2 -2
  55. package/build/components/sidebar-dataviews/add-new-view.js.map +1 -1
  56. package/build/components/sidebar-dataviews/dataview-item.js +2 -3
  57. package/build/components/sidebar-dataviews/dataview-item.js.map +1 -1
  58. package/build/components/sidebar-dataviews/default-views.js +81 -81
  59. package/build/components/sidebar-dataviews/default-views.js.map +1 -1
  60. package/build/components/sidebar-dataviews/index.js +3 -42
  61. package/build/components/sidebar-dataviews/index.js.map +1 -1
  62. package/build/components/site-hub/index.js +6 -3
  63. package/build/components/site-hub/index.js.map +1 -1
  64. package/build/components/style-book/index.js +22 -25
  65. package/build/components/style-book/index.js.map +1 -1
  66. package/build/components/sync-state-with-url/use-init-edited-entity-from-url.js +5 -0
  67. package/build/components/sync-state-with-url/use-init-edited-entity-from-url.js.map +1 -1
  68. package/build/hooks/push-changes-to-global-styles/index.js +2 -3
  69. package/build/hooks/push-changes-to-global-styles/index.js.map +1 -1
  70. package/build/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +2 -4
  71. package/build/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js.map +1 -1
  72. package/build/index.js +0 -2
  73. package/build/index.js.map +1 -1
  74. package/build-module/components/add-new-pattern/index.js +6 -1
  75. package/build-module/components/add-new-pattern/index.js.map +1 -1
  76. package/build-module/components/add-new-post/index.js +2 -1
  77. package/build-module/components/add-new-post/index.js.map +1 -1
  78. package/build-module/components/add-new-template/utils.js +2 -2
  79. package/build-module/components/add-new-template/utils.js.map +1 -1
  80. package/build-module/components/editor/index.js +73 -22
  81. package/build-module/components/editor/index.js.map +1 -1
  82. package/build-module/components/global-styles/font-families.js +3 -4
  83. package/build-module/components/global-styles/font-families.js.map +1 -1
  84. package/build-module/components/global-styles/font-library-modal/context.js +0 -5
  85. package/build-module/components/global-styles/font-library-modal/context.js.map +1 -1
  86. package/build-module/components/global-styles/font-library-modal/font-collection.js +26 -6
  87. package/build-module/components/global-styles/font-library-modal/font-collection.js.map +1 -1
  88. package/build-module/components/global-styles/font-library-modal/index.js +1 -8
  89. package/build-module/components/global-styles/font-library-modal/index.js.map +1 -1
  90. package/build-module/components/global-styles/font-library-modal/installed-fonts.js +21 -6
  91. package/build-module/components/global-styles/font-library-modal/installed-fonts.js.map +1 -1
  92. package/build-module/components/global-styles/font-library-modal/upload-fonts.js +2 -3
  93. package/build-module/components/global-styles/font-library-modal/upload-fonts.js.map +1 -1
  94. package/build-module/components/global-styles/screen-typeset.js +34 -0
  95. package/build-module/components/global-styles/screen-typeset.js.map +1 -0
  96. package/build-module/components/global-styles/screen-typography-element.js +14 -0
  97. package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
  98. package/build-module/components/global-styles/screen-typography.js +4 -6
  99. package/build-module/components/global-styles/screen-typography.js.map +1 -1
  100. package/build-module/components/global-styles/shadows-edit-panel.js +51 -60
  101. package/build-module/components/global-styles/shadows-edit-panel.js.map +1 -1
  102. package/build-module/components/global-styles/typeset-button.js +89 -0
  103. package/build-module/components/global-styles/typeset-button.js.map +1 -0
  104. package/build-module/components/global-styles/typeset.js +71 -0
  105. package/build-module/components/global-styles/typeset.js.map +1 -0
  106. package/build-module/components/global-styles/ui.js +4 -0
  107. package/build-module/components/global-styles/ui.js.map +1 -1
  108. package/build-module/components/global-styles/utils.js +10 -1
  109. package/build-module/components/global-styles/utils.js.map +1 -1
  110. package/build-module/components/page-patterns/fields.js +223 -0
  111. package/build-module/components/page-patterns/fields.js.map +1 -0
  112. package/build-module/components/page-patterns/index.js +11 -229
  113. package/build-module/components/page-patterns/index.js.map +1 -1
  114. package/build-module/components/page-patterns/use-patterns.js +26 -1
  115. package/build-module/components/page-patterns/use-patterns.js.map +1 -1
  116. package/build-module/components/page-templates/fields.js +160 -0
  117. package/build-module/components/page-templates/fields.js.map +1 -0
  118. package/build-module/components/page-templates/index.js +12 -178
  119. package/build-module/components/page-templates/index.js.map +1 -1
  120. package/build-module/components/post-edit/index.js +20 -8
  121. package/build-module/components/post-edit/index.js.map +1 -1
  122. package/build-module/components/post-fields/index.js +19 -15
  123. package/build-module/components/post-fields/index.js.map +1 -1
  124. package/build-module/components/post-list/index.js +127 -69
  125. package/build-module/components/post-list/index.js.map +1 -1
  126. package/build-module/components/sidebar-dataviews/add-new-view.js +2 -2
  127. package/build-module/components/sidebar-dataviews/add-new-view.js.map +1 -1
  128. package/build-module/components/sidebar-dataviews/dataview-item.js +2 -3
  129. package/build-module/components/sidebar-dataviews/dataview-item.js.map +1 -1
  130. package/build-module/components/sidebar-dataviews/default-views.js +81 -81
  131. package/build-module/components/sidebar-dataviews/default-views.js.map +1 -1
  132. package/build-module/components/sidebar-dataviews/index.js +3 -42
  133. package/build-module/components/sidebar-dataviews/index.js.map +1 -1
  134. package/build-module/components/site-hub/index.js +7 -4
  135. package/build-module/components/site-hub/index.js.map +1 -1
  136. package/build-module/components/style-book/index.js +23 -26
  137. package/build-module/components/style-book/index.js.map +1 -1
  138. package/build-module/components/sync-state-with-url/use-init-edited-entity-from-url.js +5 -0
  139. package/build-module/components/sync-state-with-url/use-init-edited-entity-from-url.js.map +1 -1
  140. package/build-module/hooks/push-changes-to-global-styles/index.js +2 -3
  141. package/build-module/hooks/push-changes-to-global-styles/index.js.map +1 -1
  142. package/build-module/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +2 -3
  143. package/build-module/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js.map +1 -1
  144. package/build-module/index.js +0 -2
  145. package/build-module/index.js.map +1 -1
  146. package/build-style/posts-rtl.css +190 -11
  147. package/build-style/posts.css +190 -11
  148. package/build-style/style-rtl.css +296 -55
  149. package/build-style/style.css +296 -55
  150. package/package.json +41 -41
  151. package/src/components/add-new-pattern/index.js +8 -3
  152. package/src/components/add-new-post/index.js +2 -1
  153. package/src/components/add-new-template/utils.js +10 -6
  154. package/src/components/editor/index.js +80 -22
  155. package/src/components/editor/style.scss +59 -1
  156. package/src/components/global-styles/font-families.js +3 -5
  157. package/src/components/global-styles/font-library-modal/context.js +0 -5
  158. package/src/components/global-styles/font-library-modal/font-collection.js +34 -10
  159. package/src/components/global-styles/font-library-modal/index.js +2 -7
  160. package/src/components/global-styles/font-library-modal/installed-fonts.js +23 -5
  161. package/src/components/global-styles/font-library-modal/style.scss +1 -1
  162. package/src/components/global-styles/font-library-modal/upload-fonts.js +2 -2
  163. package/src/components/global-styles/screen-typeset.js +42 -0
  164. package/src/components/global-styles/screen-typography-element.js +14 -0
  165. package/src/components/global-styles/screen-typography.js +4 -4
  166. package/src/components/global-styles/shadows-edit-panel.js +66 -73
  167. package/src/components/global-styles/style.scss +4 -7
  168. package/src/components/global-styles/typeset-button.js +93 -0
  169. package/src/components/global-styles/typeset.js +73 -0
  170. package/src/components/global-styles/ui.js +5 -0
  171. package/src/components/global-styles/utils.js +13 -1
  172. package/src/components/layout/style.scss +8 -0
  173. package/src/components/page-patterns/fields.js +251 -0
  174. package/src/components/page-patterns/index.js +15 -244
  175. package/src/components/page-patterns/style.scss +82 -85
  176. package/src/components/page-patterns/use-patterns.js +31 -1
  177. package/src/components/page-templates/fields.js +157 -0
  178. package/src/components/page-templates/index.js +19 -170
  179. package/src/components/page-templates/style.scss +14 -5
  180. package/src/components/post-edit/index.js +27 -8
  181. package/src/components/post-fields/index.js +29 -17
  182. package/src/components/post-list/index.js +134 -74
  183. package/src/components/sidebar-dataviews/add-new-view.js +2 -4
  184. package/src/components/sidebar-dataviews/dataview-item.js +2 -2
  185. package/src/components/sidebar-dataviews/default-views.js +95 -95
  186. package/src/components/sidebar-dataviews/index.js +3 -37
  187. package/src/components/site-hub/index.js +11 -2
  188. package/src/components/site-icon/style.scss +4 -1
  189. package/src/components/style-book/index.js +27 -32
  190. package/src/components/sync-state-with-url/use-init-edited-entity-from-url.js +5 -0
  191. package/src/hooks/push-changes-to-global-styles/index.js +2 -3
  192. package/src/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +2 -3
  193. package/src/index.js +0 -2
  194. package/build/utils/clone-deep.js +0 -15
  195. package/build/utils/clone-deep.js.map +0 -1
  196. package/build-module/utils/clone-deep.js +0 -9
  197. package/build-module/utils/clone-deep.js.map +0 -1
  198. package/src/utils/clone-deep.js +0 -8
@@ -0,0 +1,157 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import clsx from 'clsx';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { Icon, __experimentalHStack as HStack } from '@wordpress/components';
10
+ import { __ } from '@wordpress/i18n';
11
+ import { useState, useMemo } from '@wordpress/element';
12
+ import { decodeEntities } from '@wordpress/html-entities';
13
+ import { parse } from '@wordpress/blocks';
14
+ import {
15
+ BlockPreview,
16
+ privateApis as blockEditorPrivateApis,
17
+ } from '@wordpress/block-editor';
18
+ import { EditorProvider } from '@wordpress/editor';
19
+
20
+ /**
21
+ * Internal dependencies
22
+ */
23
+ import { Async } from '../async';
24
+ import { default as Link, useLink } from '../routes/link';
25
+ import { useAddedBy } from './hooks';
26
+
27
+ import usePatternSettings from '../page-patterns/use-pattern-settings';
28
+ import { unlock } from '../../lock-unlock';
29
+
30
+ const { useGlobalStyle } = unlock( blockEditorPrivateApis );
31
+
32
+ function PreviewField( { item } ) {
33
+ const settings = usePatternSettings();
34
+ const [ backgroundColor = 'white' ] = useGlobalStyle( 'color.background' );
35
+ const blocks = useMemo( () => {
36
+ return parse( item.content.raw );
37
+ }, [ item.content.raw ] );
38
+ const { onClick } = useLink( {
39
+ postId: item.id,
40
+ postType: item.type,
41
+ canvas: 'edit',
42
+ } );
43
+
44
+ const isEmpty = ! blocks?.length;
45
+ // Wrap everything in a block editor provider to ensure 'styles' that are needed
46
+ // for the previews are synced between the site editor store and the block editor store.
47
+ // Additionally we need to have the `__experimentalBlockPatterns` setting in order to
48
+ // render patterns inside the previews.
49
+ // TODO: Same approach is used in the patterns list and it becomes obvious that some of
50
+ // the block editor settings are needed in context where we don't have the block editor.
51
+ // Explore how we can solve this in a better way.
52
+ return (
53
+ <EditorProvider post={ item } settings={ settings }>
54
+ <div
55
+ className="page-templates-preview-field"
56
+ style={ { backgroundColor } }
57
+ >
58
+ <button
59
+ className="page-templates-preview-field__button"
60
+ type="button"
61
+ onClick={ onClick }
62
+ aria-label={ item.title?.rendered || item.title }
63
+ >
64
+ { isEmpty && __( 'Empty template' ) }
65
+ { ! isEmpty && (
66
+ <Async>
67
+ <BlockPreview blocks={ blocks } />
68
+ </Async>
69
+ ) }
70
+ </button>
71
+ </div>
72
+ </EditorProvider>
73
+ );
74
+ }
75
+
76
+ export const previewField = {
77
+ label: __( 'Preview' ),
78
+ id: 'preview',
79
+ render: PreviewField,
80
+ enableSorting: false,
81
+ };
82
+
83
+ function TitleField( { item } ) {
84
+ const linkProps = {
85
+ params: {
86
+ postId: item.id,
87
+ postType: item.type,
88
+ canvas: 'edit',
89
+ },
90
+ };
91
+ return (
92
+ <Link { ...linkProps }>
93
+ { decodeEntities( item.title?.rendered ) || __( '(no title)' ) }
94
+ </Link>
95
+ );
96
+ }
97
+
98
+ export const titleField = {
99
+ label: __( 'Template' ),
100
+ id: 'title',
101
+ getValue: ( { item } ) => item.title?.rendered,
102
+ render: TitleField,
103
+ enableHiding: false,
104
+ enableGlobalSearch: true,
105
+ };
106
+
107
+ export const descriptionField = {
108
+ label: __( 'Description' ),
109
+ id: 'description',
110
+ render: ( { item } ) => {
111
+ return (
112
+ item.description && (
113
+ <span className="page-templates-description">
114
+ { decodeEntities( item.description ) }
115
+ </span>
116
+ )
117
+ );
118
+ },
119
+ enableSorting: false,
120
+ enableGlobalSearch: true,
121
+ };
122
+
123
+ function AuthorField( { item } ) {
124
+ const [ isImageLoaded, setIsImageLoaded ] = useState( false );
125
+ const { text, icon, imageUrl } = useAddedBy( item.type, item.id );
126
+
127
+ return (
128
+ <HStack alignment="left" spacing={ 0 }>
129
+ { imageUrl && (
130
+ <div
131
+ className={ clsx( 'page-templates-author-field__avatar', {
132
+ 'is-loaded': isImageLoaded,
133
+ } ) }
134
+ >
135
+ <img
136
+ onLoad={ () => setIsImageLoaded( true ) }
137
+ alt=""
138
+ src={ imageUrl }
139
+ />
140
+ </div>
141
+ ) }
142
+ { ! imageUrl && (
143
+ <div className="page-templates-author-field__icon">
144
+ <Icon icon={ icon } />
145
+ </div>
146
+ ) }
147
+ <span className="page-templates-author-field__name">{ text }</span>
148
+ </HStack>
149
+ );
150
+ }
151
+
152
+ export const authorField = {
153
+ label: __( 'Author' ),
154
+ id: 'author',
155
+ getValue: ( { item } ) => item.author_text,
156
+ render: AuthorField,
157
+ };
@@ -1,36 +1,18 @@
1
- /**
2
- * External dependencies
3
- */
4
- import clsx from 'clsx';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
- import { Icon, __experimentalHStack as HStack } from '@wordpress/components';
10
4
  import { __ } from '@wordpress/i18n';
11
5
  import { useState, useMemo, useCallback, useEffect } from '@wordpress/element';
12
- import { useEntityRecords } from '@wordpress/core-data';
13
- import { decodeEntities } from '@wordpress/html-entities';
14
- import { parse } from '@wordpress/blocks';
15
- import {
16
- BlockPreview,
17
- privateApis as blockEditorPrivateApis,
18
- } from '@wordpress/block-editor';
6
+ import { privateApis as corePrivateApis } from '@wordpress/core-data';
19
7
  import { DataViews, filterSortAndPaginate } from '@wordpress/dataviews';
20
8
  import { privateApis as routerPrivateApis } from '@wordpress/router';
21
- import {
22
- privateApis as editorPrivateApis,
23
- EditorProvider,
24
- } from '@wordpress/editor';
9
+ import { privateApis as editorPrivateApis } from '@wordpress/editor';
25
10
 
26
11
  /**
27
12
  * Internal dependencies
28
13
  */
29
- import { Async } from '../async';
30
14
  import Page from '../page';
31
- import { default as Link, useLink } from '../routes/link';
32
15
  import AddNewTemplate from '../add-new-template';
33
- import { useAddedBy } from './hooks';
34
16
  import {
35
17
  TEMPLATE_POST_TYPE,
36
18
  OPERATOR_IS_ANY,
@@ -38,15 +20,18 @@ import {
38
20
  LAYOUT_TABLE,
39
21
  LAYOUT_LIST,
40
22
  } from '../../utils/constants';
41
-
42
- import usePatternSettings from '../page-patterns/use-pattern-settings';
43
23
  import { unlock } from '../../lock-unlock';
44
24
  import { useEditPostAction } from '../dataviews-actions';
25
+ import {
26
+ authorField,
27
+ descriptionField,
28
+ previewField,
29
+ titleField,
30
+ } from './fields';
45
31
 
46
32
  const { usePostActions } = unlock( editorPrivateApis );
47
-
48
- const { useGlobalStyle } = unlock( blockEditorPrivateApis );
49
33
  const { useHistory, useLocation } = unlock( routerPrivateApis );
34
+ const { useEntityRecordsWithPermissions } = unlock( corePrivateApis );
50
35
 
51
36
  const EMPTY_ARRAY = [];
52
37
 
@@ -69,8 +54,7 @@ const defaultLayouts = {
69
54
  minWidth: 320,
70
55
  },
71
56
  preview: {
72
- minWidth: 120,
73
- maxWidth: 120,
57
+ width: '1%',
74
58
  },
75
59
  author: {
76
60
  width: '1%',
@@ -109,104 +93,6 @@ const DEFAULT_VIEW = {
109
93
  filters: [],
110
94
  };
111
95
 
112
- function Title( { item, viewType } ) {
113
- if ( viewType === LAYOUT_LIST ) {
114
- return decodeEntities( item.title?.rendered ) || __( '(no title)' );
115
- }
116
- const linkProps = {
117
- params: {
118
- postId: item.id,
119
- postType: item.type,
120
- canvas: 'edit',
121
- },
122
- };
123
- return (
124
- <Link { ...linkProps }>
125
- { decodeEntities( item.title?.rendered ) || __( '(no title)' ) }
126
- </Link>
127
- );
128
- }
129
-
130
- function AuthorField( { item } ) {
131
- const [ isImageLoaded, setIsImageLoaded ] = useState( false );
132
- const { text, icon, imageUrl } = useAddedBy( item.type, item.id );
133
-
134
- return (
135
- <HStack alignment="left" spacing={ 0 }>
136
- { imageUrl && (
137
- <div
138
- className={ clsx( 'page-templates-author-field__avatar', {
139
- 'is-loaded': isImageLoaded,
140
- } ) }
141
- >
142
- <img
143
- onLoad={ () => setIsImageLoaded( true ) }
144
- alt=""
145
- src={ imageUrl }
146
- />
147
- </div>
148
- ) }
149
- { ! imageUrl && (
150
- <div className="page-templates-author-field__icon">
151
- <Icon icon={ icon } />
152
- </div>
153
- ) }
154
- <span className="page-templates-author-field__name">{ text }</span>
155
- </HStack>
156
- );
157
- }
158
-
159
- function Preview( { item, viewType } ) {
160
- const settings = usePatternSettings();
161
- const [ backgroundColor = 'white' ] = useGlobalStyle( 'color.background' );
162
- const blocks = useMemo( () => {
163
- return parse( item.content.raw );
164
- }, [ item.content.raw ] );
165
- const { onClick } = useLink( {
166
- postId: item.id,
167
- postType: item.type,
168
- canvas: 'edit',
169
- } );
170
-
171
- const isEmpty = ! blocks?.length;
172
- // Wrap everything in a block editor provider to ensure 'styles' that are needed
173
- // for the previews are synced between the site editor store and the block editor store.
174
- // Additionally we need to have the `__experimentalBlockPatterns` setting in order to
175
- // render patterns inside the previews.
176
- // TODO: Same approach is used in the patterns list and it becomes obvious that some of
177
- // the block editor settings are needed in context where we don't have the block editor.
178
- // Explore how we can solve this in a better way.
179
- return (
180
- <EditorProvider post={ item } settings={ settings }>
181
- <div
182
- className={ `page-templates-preview-field is-viewtype-${ viewType }` }
183
- style={ { backgroundColor } }
184
- >
185
- { viewType === LAYOUT_LIST && ! isEmpty && (
186
- <Async>
187
- <BlockPreview blocks={ blocks } />
188
- </Async>
189
- ) }
190
- { viewType !== LAYOUT_LIST && (
191
- <button
192
- className="page-templates-preview-field__button"
193
- type="button"
194
- onClick={ onClick }
195
- aria-label={ item.title?.rendered || item.title }
196
- >
197
- { isEmpty && __( 'Empty template' ) }
198
- { ! isEmpty && (
199
- <Async>
200
- <BlockPreview blocks={ blocks } />
201
- </Async>
202
- ) }
203
- </button>
204
- ) }
205
- </div>
206
- </EditorProvider>
207
- );
208
- }
209
-
210
96
  export default function PageTemplates() {
211
97
  const { params } = useLocation();
212
98
  const { activeView = 'all', layout, postId } = params;
@@ -248,13 +134,10 @@ export default function PageTemplates() {
248
134
  } ) );
249
135
  }, [ activeView ] );
250
136
 
251
- const { records, isResolving: isLoadingData } = useEntityRecords(
252
- 'postType',
253
- TEMPLATE_POST_TYPE,
254
- {
137
+ const { records, isResolving: isLoadingData } =
138
+ useEntityRecordsWithPermissions( 'postType', TEMPLATE_POST_TYPE, {
255
139
  per_page: -1,
256
- }
257
- );
140
+ } );
258
141
  const history = useHistory();
259
142
  const onChangeSelection = useCallback(
260
143
  ( items ) => {
@@ -285,50 +168,15 @@ export default function PageTemplates() {
285
168
 
286
169
  const fields = useMemo(
287
170
  () => [
171
+ previewField,
172
+ titleField,
173
+ descriptionField,
288
174
  {
289
- label: __( 'Preview' ),
290
- id: 'preview',
291
- render: ( { item } ) => {
292
- return <Preview item={ item } viewType={ view.type } />;
293
- },
294
- enableSorting: false,
295
- },
296
- {
297
- label: __( 'Template' ),
298
- id: 'title',
299
- getValue: ( { item } ) => item.title?.rendered,
300
- render: ( { item } ) => (
301
- <Title item={ item } viewType={ view.type } />
302
- ),
303
- enableHiding: false,
304
- enableGlobalSearch: true,
305
- },
306
- {
307
- label: __( 'Description' ),
308
- id: 'description',
309
- render: ( { item } ) => {
310
- return (
311
- item.description && (
312
- <span className="page-templates-description">
313
- { decodeEntities( item.description ) }
314
- </span>
315
- )
316
- );
317
- },
318
- enableSorting: false,
319
- enableGlobalSearch: true,
320
- },
321
- {
322
- label: __( 'Author' ),
323
- id: 'author',
324
- getValue: ( { item } ) => item.author_text,
325
- render: ( { item } ) => {
326
- return <AuthorField viewType={ view.type } item={ item } />;
327
- },
175
+ ...authorField,
328
176
  elements: authors,
329
177
  },
330
178
  ],
331
- [ authors, view.type ]
179
+ [ authors ]
332
180
  );
333
181
 
334
182
  const { data, paginationInfo } = useMemo( () => {
@@ -366,6 +214,7 @@ export default function PageTemplates() {
366
214
  actions={ <AddNewTemplate /> }
367
215
  >
368
216
  <DataViews
217
+ key={ activeView }
369
218
  paginationInfo={ paginationInfo }
370
219
  fields={ fields }
371
220
  actions={ actions }
@@ -3,6 +3,7 @@
3
3
  flex-direction: column;
4
4
  height: 100%;
5
5
  width: 100%;
6
+ border-radius: $radius-medium;
6
7
 
7
8
  .page-templates-preview-field__button {
8
9
  box-shadow: none;
@@ -13,7 +14,7 @@
13
14
  cursor: pointer;
14
15
  overflow: hidden;
15
16
  height: 100%;
16
- border-radius: $grid-unit-05;
17
+ border-radius: $radius-medium;
17
18
 
18
19
  &:focus-visible {
19
20
  box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
@@ -22,21 +23,23 @@
22
23
  }
23
24
  }
24
25
 
25
- &.is-viewtype-list {
26
+ .dataviews-view-list & {
26
27
  .block-editor-block-preview__container {
27
28
  height: 120px;
28
29
  }
29
30
  }
30
31
 
31
- &.is-viewtype-grid {
32
+ .dataviews-view-grid & {
32
33
  .block-editor-block-preview__container {
33
34
  height: 100%;
34
35
  }
35
36
  }
36
37
 
37
- &.is-viewtype-table {
38
+ .dataviews-view-table & {
38
39
  border-radius: $radius-block-ui;
39
40
  position: relative;
41
+ width: 120px;
42
+ max-height: 160px;
40
43
 
41
44
  &::after {
42
45
  content: "";
@@ -52,7 +55,13 @@
52
55
  }
53
56
 
54
57
  .page-templates-description {
55
- white-space: normal;
58
+ max-width: 50em;
59
+ text-wrap: balance; // Fallback for Safari
60
+ text-wrap: pretty;
61
+
62
+ .dataviews-view-table & {
63
+ margin-bottom: $grid-unit-10;
64
+ }
56
65
  }
57
66
 
58
67
  .edit-site-page-templates {
@@ -7,10 +7,14 @@ import clsx from 'clsx';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { __ } from '@wordpress/i18n';
10
- import { DataForm } from '@wordpress/dataviews';
10
+ import { DataForm, isItemValid } from '@wordpress/dataviews';
11
11
  import { useDispatch, useSelect, useRegistry } from '@wordpress/data';
12
12
  import { store as coreDataStore } from '@wordpress/core-data';
13
- import { Button } from '@wordpress/components';
13
+ import {
14
+ Button,
15
+ FlexItem,
16
+ __experimentalVStack as VStack,
17
+ } from '@wordpress/components';
14
18
  import { useState, useMemo } from '@wordpress/element';
15
19
 
16
20
  /**
@@ -42,7 +46,8 @@ function PostEditForm( { postType, postId } ) {
42
46
  const { saveEntityRecord } = useDispatch( coreDataStore );
43
47
  const { fields } = usePostFields();
44
48
  const form = {
45
- visibleFields: [ 'title' ],
49
+ type: 'panel',
50
+ fields: [ 'title', 'author' ],
46
51
  };
47
52
  const [ edits, setEdits ] = useState( {} );
48
53
  const itemWithEdits = useMemo( () => {
@@ -53,6 +58,11 @@ function PostEditForm( { postType, postId } ) {
53
58
  }, [ initialEdits, edits ] );
54
59
  const onSubmit = async ( event ) => {
55
60
  event.preventDefault();
61
+
62
+ if ( ! isItemValid( itemWithEdits, fields, form ) ) {
63
+ return;
64
+ }
65
+
56
66
  const { getEntityRecord } = registry.resolveSelect( coreDataStore );
57
67
  for ( const id of ids ) {
58
68
  const item = await getEntityRecord( 'postType', postType, id );
@@ -64,18 +74,27 @@ function PostEditForm( { postType, postId } ) {
64
74
  setEdits( {} );
65
75
  };
66
76
 
77
+ const isUpdateDisabled = ! isItemValid( itemWithEdits, fields, form );
67
78
  return (
68
- <form onSubmit={ onSubmit }>
79
+ <VStack as="form" onSubmit={ onSubmit } spacing={ 4 }>
69
80
  <DataForm
70
81
  data={ itemWithEdits }
71
82
  fields={ fields }
72
83
  form={ form }
73
84
  onChange={ setEdits }
74
85
  />
75
- <Button variant="primary" type="submit">
76
- { __( 'Update' ) }
77
- </Button>
78
- </form>
86
+ <FlexItem>
87
+ <Button
88
+ variant="primary"
89
+ type="submit"
90
+ accessibleWhenDisabled
91
+ disabled={ isUpdateDisabled }
92
+ __next40pxDefaultSize
93
+ >
94
+ { __( 'Update' ) }
95
+ </Button>
96
+ </FlexItem>
97
+ </VStack>
79
98
  );
80
99
  }
81
100
 
@@ -186,6 +186,10 @@ function usePostFields( viewType ) {
186
186
  const addLink =
187
187
  [ LAYOUT_TABLE, LAYOUT_GRID ].includes( viewType ) &&
188
188
  item.status !== 'trash';
189
+ const renderedTitle =
190
+ typeof item.title === 'string'
191
+ ? item.title
192
+ : item.title?.rendered;
189
193
  const title = addLink ? (
190
194
  <Link
191
195
  params={ {
@@ -194,12 +198,12 @@ function usePostFields( viewType ) {
194
198
  canvas: 'edit',
195
199
  } }
196
200
  >
197
- { decodeEntities( item.title?.rendered ) ||
201
+ { decodeEntities( renderedTitle ) ||
198
202
  __( '(no title)' ) }
199
203
  </Link>
200
204
  ) : (
201
205
  <span>
202
- { decodeEntities( item.title?.rendered ) ||
206
+ { decodeEntities( renderedTitle ) ||
203
207
  __( '(no title)' ) }
204
208
  </span>
205
209
  );
@@ -235,13 +239,21 @@ function usePostFields( viewType ) {
235
239
  {
236
240
  label: __( 'Author' ),
237
241
  id: 'author',
238
- getValue: ( { item } ) => item._embedded?.author[ 0 ]?.name,
242
+ type: 'integer',
239
243
  elements:
240
244
  authors?.map( ( { id, name } ) => ( {
241
245
  value: id,
242
246
  label: name,
243
247
  } ) ) || [],
244
248
  render: PostAuthorField,
249
+ sort: ( a, b, direction ) => {
250
+ const nameA = a._embedded?.author?.[ 0 ]?.name || '';
251
+ const nameB = b._embedded?.author?.[ 0 ]?.name || '';
252
+
253
+ return direction === 'asc'
254
+ ? nameA.localeCompare( nameB )
255
+ : nameB.localeCompare( nameA );
256
+ },
245
257
  },
246
258
  {
247
259
  label: __( 'Status' ),
@@ -292,19 +304,13 @@ function usePostFields( viewType ) {
292
304
  );
293
305
  }
294
306
 
295
- // Pending & Published posts show the modified date if it's newer.
296
- const dateToDisplay =
297
- getDate( item.modified ) > getDate( item.date )
298
- ? item.modified
299
- : item.date;
300
-
301
- const isPending = item.status === 'pending';
302
- if ( isPending ) {
307
+ const isPublished = item.status === 'publish';
308
+ if ( isPublished ) {
303
309
  return createInterpolateElement(
304
310
  sprintf(
305
- /* translators: %s: the newest of created or modified date for the page */
306
- __( '<span>Modified: <time>%s</time></span>' ),
307
- getFormattedDate( dateToDisplay )
311
+ /* translators: %s: page creation time */
312
+ __( '<span>Published: <time>%s</time></span>' ),
313
+ getFormattedDate( item.date )
308
314
  ),
309
315
  {
310
316
  span: <span />,
@@ -313,12 +319,18 @@ function usePostFields( viewType ) {
313
319
  );
314
320
  }
315
321
 
316
- const isPublished = item.status === 'publish';
317
- if ( isPublished ) {
322
+ // Pending posts show the modified date if it's newer.
323
+ const dateToDisplay =
324
+ getDate( item.modified ) > getDate( item.date )
325
+ ? item.modified
326
+ : item.date;
327
+
328
+ const isPending = item.status === 'pending';
329
+ if ( isPending ) {
318
330
  return createInterpolateElement(
319
331
  sprintf(
320
332
  /* translators: %s: the newest of created or modified date for the page */
321
- __( '<span>Published: <time>%s</time></span>' ),
333
+ __( '<span>Modified: <time>%s</time></span>' ),
322
334
  getFormattedDate( dateToDisplay )
323
335
  ),
324
336
  {