@wordpress/editor 13.34.0 → 13.35.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 (263) hide show
  1. package/CHANGELOG.md +10 -4
  2. package/build/bindings/pattern-overrides.js +70 -1
  3. package/build/bindings/pattern-overrides.js.map +1 -1
  4. package/build/components/block-settings-menu/content-only-settings-menu.js +126 -0
  5. package/build/components/block-settings-menu/content-only-settings-menu.js.map +1 -0
  6. package/build/components/block-settings-menu/content-only-settings-menu.native.js +11 -0
  7. package/build/components/block-settings-menu/content-only-settings-menu.native.js.map +1 -0
  8. package/build/components/collapsible-block-toolbar/index.js +2 -2
  9. package/build/components/collapsible-block-toolbar/index.js.map +1 -1
  10. package/build/components/document-bar/index.js +2 -2
  11. package/build/components/document-bar/index.js.map +1 -1
  12. package/build/components/document-outline/item.js +2 -2
  13. package/build/components/document-outline/item.js.map +1 -1
  14. package/build/components/document-tools/index.js +15 -18
  15. package/build/components/document-tools/index.js.map +1 -1
  16. package/build/components/editor-canvas/index.js +19 -8
  17. package/build/components/editor-canvas/index.js.map +1 -1
  18. package/build/components/global-keyboard-shortcuts/register-shortcuts.js +1 -1
  19. package/build/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
  20. package/build/components/global-styles-provider/index.js +130 -0
  21. package/build/components/global-styles-provider/index.js.map +1 -0
  22. package/build/components/header/index.js +147 -0
  23. package/build/components/header/index.js.map +1 -0
  24. package/build/components/inserter-sidebar/index.js +56 -31
  25. package/build/components/inserter-sidebar/index.js.map +1 -1
  26. package/build/components/keyboard-shortcut-help-modal/index.js +2 -2
  27. package/build/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  28. package/build/components/post-actions/actions.js +122 -64
  29. package/build/components/post-actions/actions.js.map +1 -1
  30. package/build/components/post-actions/index.js +7 -14
  31. package/build/components/post-actions/index.js.map +1 -1
  32. package/build/components/post-card-panel/index.js +5 -29
  33. package/build/components/post-card-panel/index.js.map +1 -1
  34. package/build/components/post-comments/index.js +28 -8
  35. package/build/components/post-comments/index.js.map +1 -1
  36. package/build/components/post-discussion/panel.js +103 -21
  37. package/build/components/post-discussion/panel.js.map +1 -1
  38. package/build/components/post-excerpt/panel.js +2 -2
  39. package/build/components/post-excerpt/panel.js.map +1 -1
  40. package/build/components/post-format/panel.js +27 -0
  41. package/build/components/post-format/panel.js.map +1 -0
  42. package/build/components/post-panel-row/index.js +2 -2
  43. package/build/components/post-panel-row/index.js.map +1 -1
  44. package/build/components/post-panel-section/index.js +28 -0
  45. package/build/components/post-panel-section/index.js.map +1 -0
  46. package/build/components/post-pingbacks/index.js +5 -2
  47. package/build/components/post-pingbacks/index.js.map +1 -1
  48. package/build/components/post-saved-state/index.js +2 -2
  49. package/build/components/post-saved-state/index.js.map +1 -1
  50. package/build/components/post-slug/panel.js +27 -0
  51. package/build/components/post-slug/panel.js.map +1 -0
  52. package/build/components/post-status/index.js +4 -4
  53. package/build/components/post-status/index.js.map +1 -1
  54. package/build/components/post-sticky/panel.js +21 -0
  55. package/build/components/post-sticky/panel.js.map +1 -0
  56. package/build/components/post-title/index.js +2 -2
  57. package/build/components/post-title/index.js.map +1 -1
  58. package/build/components/post-title/post-title-raw.js +2 -2
  59. package/build/components/post-title/post-title-raw.js.map +1 -1
  60. package/build/components/post-transform-panel/hooks.js +90 -0
  61. package/build/components/post-transform-panel/hooks.js.map +1 -0
  62. package/build/components/post-transform-panel/index.js +101 -0
  63. package/build/components/post-transform-panel/index.js.map +1 -0
  64. package/build/components/post-trash/panel.js +18 -0
  65. package/build/components/post-trash/panel.js.map +1 -0
  66. package/build/components/post-type-support-check/index.js +1 -1
  67. package/build/components/post-type-support-check/index.js.map +1 -1
  68. package/build/components/preferences-modal/index.js +3 -3
  69. package/build/components/preferences-modal/index.js.map +1 -1
  70. package/build/components/provider/index.js +3 -1
  71. package/build/components/provider/index.js.map +1 -1
  72. package/build/components/provider/use-block-editor-settings.js +21 -3
  73. package/build/components/provider/use-block-editor-settings.js.map +1 -1
  74. package/build/components/sidebar/constants.js +11 -0
  75. package/build/components/sidebar/constants.js.map +1 -0
  76. package/build/components/sidebar/header.js +53 -0
  77. package/build/components/sidebar/header.js.map +1 -0
  78. package/build/components/sidebar/index.js +157 -0
  79. package/build/components/sidebar/index.js.map +1 -0
  80. package/build/components/sidebar/post-summary.js +84 -0
  81. package/build/components/sidebar/post-summary.js.map +1 -0
  82. package/build/components/start-page-options/index.js +5 -7
  83. package/build/components/start-page-options/index.js.map +1 -1
  84. package/build/components/start-template-options/index.js +192 -0
  85. package/build/components/start-template-options/index.js.map +1 -0
  86. package/build/components/template-content-panel/index.js +38 -0
  87. package/build/components/template-content-panel/index.js.map +1 -0
  88. package/build/hooks/pattern-overrides.js +10 -5
  89. package/build/hooks/pattern-overrides.js.map +1 -1
  90. package/build/private-apis.js +7 -12
  91. package/build/private-apis.js.map +1 -1
  92. package/build/private-apis.native.js +72 -0
  93. package/build/private-apis.native.js.map +1 -0
  94. package/build/store/private-selectors.js +6 -1
  95. package/build/store/private-selectors.js.map +1 -1
  96. package/build/store/reducer.js +15 -0
  97. package/build/store/reducer.js.map +1 -1
  98. package/build-module/bindings/pattern-overrides.js +69 -1
  99. package/build-module/bindings/pattern-overrides.js.map +1 -1
  100. package/build-module/components/block-settings-menu/content-only-settings-menu.js +119 -0
  101. package/build-module/components/block-settings-menu/content-only-settings-menu.js.map +1 -0
  102. package/build-module/components/block-settings-menu/content-only-settings-menu.native.js +5 -0
  103. package/build-module/components/block-settings-menu/content-only-settings-menu.native.js.map +1 -0
  104. package/build-module/components/collapsible-block-toolbar/index.js +2 -2
  105. package/build-module/components/collapsible-block-toolbar/index.js.map +1 -1
  106. package/build-module/components/document-bar/index.js +2 -2
  107. package/build-module/components/document-bar/index.js.map +1 -1
  108. package/build-module/components/document-outline/item.js +2 -2
  109. package/build-module/components/document-outline/item.js.map +1 -1
  110. package/build-module/components/document-tools/index.js +16 -19
  111. package/build-module/components/document-tools/index.js.map +1 -1
  112. package/build-module/components/editor-canvas/index.js +19 -8
  113. package/build-module/components/editor-canvas/index.js.map +1 -1
  114. package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js +1 -1
  115. package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
  116. package/build-module/components/global-styles-provider/index.js +120 -0
  117. package/build-module/components/global-styles-provider/index.js.map +1 -0
  118. package/build-module/components/header/index.js +139 -0
  119. package/build-module/components/header/index.js.map +1 -0
  120. package/build-module/components/inserter-sidebar/index.js +59 -34
  121. package/build-module/components/inserter-sidebar/index.js.map +1 -1
  122. package/build-module/components/keyboard-shortcut-help-modal/index.js +2 -2
  123. package/build-module/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  124. package/build-module/components/post-actions/actions.js +125 -66
  125. package/build-module/components/post-actions/actions.js.map +1 -1
  126. package/build-module/components/post-actions/index.js +7 -14
  127. package/build-module/components/post-actions/index.js.map +1 -1
  128. package/build-module/components/post-card-panel/index.js +7 -30
  129. package/build-module/components/post-card-panel/index.js.map +1 -1
  130. package/build-module/components/post-comments/index.js +30 -10
  131. package/build-module/components/post-comments/index.js.map +1 -1
  132. package/build-module/components/post-discussion/panel.js +105 -23
  133. package/build-module/components/post-discussion/panel.js.map +1 -1
  134. package/build-module/components/post-excerpt/panel.js +2 -2
  135. package/build-module/components/post-excerpt/panel.js.map +1 -1
  136. package/build-module/components/post-format/panel.js +18 -0
  137. package/build-module/components/post-format/panel.js.map +1 -0
  138. package/build-module/components/post-panel-row/index.js +2 -2
  139. package/build-module/components/post-panel-row/index.js.map +1 -1
  140. package/build-module/components/post-panel-section/index.js +20 -0
  141. package/build-module/components/post-panel-section/index.js.map +1 -0
  142. package/build-module/components/post-pingbacks/index.js +6 -3
  143. package/build-module/components/post-pingbacks/index.js.map +1 -1
  144. package/build-module/components/post-saved-state/index.js +2 -2
  145. package/build-module/components/post-saved-state/index.js.map +1 -1
  146. package/build-module/components/post-slug/panel.js +18 -0
  147. package/build-module/components/post-slug/panel.js.map +1 -0
  148. package/build-module/components/post-status/index.js +4 -4
  149. package/build-module/components/post-status/index.js.map +1 -1
  150. package/build-module/components/post-sticky/panel.js +12 -0
  151. package/build-module/components/post-sticky/panel.js.map +1 -0
  152. package/build-module/components/post-title/index.js +2 -2
  153. package/build-module/components/post-title/index.js.map +1 -1
  154. package/build-module/components/post-title/post-title-raw.js +2 -2
  155. package/build-module/components/post-title/post-title-raw.js.map +1 -1
  156. package/build-module/components/post-transform-panel/hooks.js +83 -0
  157. package/build-module/components/post-transform-panel/hooks.js.map +1 -0
  158. package/build-module/components/post-transform-panel/index.js +94 -0
  159. package/build-module/components/post-transform-panel/index.js.map +1 -0
  160. package/build-module/components/post-trash/panel.js +10 -0
  161. package/build-module/components/post-trash/panel.js.map +1 -0
  162. package/build-module/components/post-type-support-check/index.js +1 -1
  163. package/build-module/components/post-type-support-check/index.js.map +1 -1
  164. package/build-module/components/preferences-modal/index.js +3 -3
  165. package/build-module/components/preferences-modal/index.js.map +1 -1
  166. package/build-module/components/provider/index.js +3 -1
  167. package/build-module/components/provider/index.js.map +1 -1
  168. package/build-module/components/provider/use-block-editor-settings.js +21 -3
  169. package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
  170. package/build-module/components/sidebar/constants.js +5 -0
  171. package/build-module/components/sidebar/constants.js.map +1 -0
  172. package/build-module/components/sidebar/header.js +46 -0
  173. package/build-module/components/sidebar/header.js.map +1 -0
  174. package/build-module/components/sidebar/index.js +149 -0
  175. package/build-module/components/sidebar/index.js.map +1 -0
  176. package/build-module/components/sidebar/post-summary.js +77 -0
  177. package/build-module/components/sidebar/post-summary.js.map +1 -0
  178. package/build-module/components/start-page-options/index.js +5 -7
  179. package/build-module/components/start-page-options/index.js.map +1 -1
  180. package/build-module/components/start-template-options/index.js +185 -0
  181. package/build-module/components/start-template-options/index.js.map +1 -0
  182. package/build-module/components/template-content-panel/index.js +31 -0
  183. package/build-module/components/template-content-panel/index.js.map +1 -0
  184. package/build-module/hooks/pattern-overrides.js +10 -5
  185. package/build-module/hooks/pattern-overrides.js.map +1 -1
  186. package/build-module/private-apis.js +7 -12
  187. package/build-module/private-apis.js.map +1 -1
  188. package/build-module/private-apis.native.js +62 -0
  189. package/build-module/private-apis.native.js.map +1 -0
  190. package/build-module/store/private-selectors.js +3 -0
  191. package/build-module/store/private-selectors.js.map +1 -1
  192. package/build-module/store/reducer.js +14 -0
  193. package/build-module/store/reducer.js.map +1 -1
  194. package/build-style/style-rtl.css +328 -18
  195. package/build-style/style.css +328 -18
  196. package/package.json +38 -36
  197. package/src/bindings/pattern-overrides.js +83 -1
  198. package/src/components/autocompleters/style.scss +1 -2
  199. package/src/components/block-settings-menu/content-only-settings-menu.js +175 -0
  200. package/src/components/block-settings-menu/content-only-settings-menu.native.js +4 -0
  201. package/src/components/block-settings-menu/style.scss +4 -0
  202. package/src/components/collapsible-block-toolbar/index.js +2 -2
  203. package/src/components/document-bar/index.js +2 -2
  204. package/src/components/document-outline/item.js +2 -2
  205. package/src/components/document-tools/index.js +19 -21
  206. package/src/components/editor-canvas/index.js +18 -6
  207. package/src/components/global-keyboard-shortcuts/register-shortcuts.js +1 -1
  208. package/src/components/global-styles-provider/index.js +162 -0
  209. package/src/components/header/index.js +154 -0
  210. package/src/components/header/style.scss +231 -0
  211. package/src/components/inserter-sidebar/index.js +52 -29
  212. package/src/components/inserter-sidebar/style.scss +10 -3
  213. package/src/components/keyboard-shortcut-help-modal/index.js +2 -2
  214. package/src/components/list-view-sidebar/style.scss +1 -0
  215. package/src/components/page-attributes/test/order.js +5 -1
  216. package/src/components/post-actions/actions.js +256 -150
  217. package/src/components/post-actions/index.js +5 -38
  218. package/src/components/post-card-panel/index.js +39 -85
  219. package/src/components/post-comments/index.js +47 -9
  220. package/src/components/post-discussion/panel.js +108 -31
  221. package/src/components/post-discussion/style.scss +26 -0
  222. package/src/components/post-excerpt/panel.js +2 -2
  223. package/src/components/post-format/panel.js +22 -0
  224. package/src/components/post-format/style.scss +6 -0
  225. package/src/components/post-last-revision/test/check.js +5 -1
  226. package/src/components/post-panel-row/index.js +2 -2
  227. package/src/components/post-panel-section/index.js +19 -0
  228. package/src/components/post-panel-section/style.scss +3 -0
  229. package/src/components/post-pingbacks/index.js +11 -2
  230. package/src/components/post-publish-panel/style.scss +5 -0
  231. package/src/components/post-saved-state/index.js +2 -2
  232. package/src/components/post-slug/panel.js +22 -0
  233. package/src/components/post-slug/style.scss +5 -0
  234. package/src/components/post-slug/test/index.js +5 -1
  235. package/src/components/post-status/index.js +4 -4
  236. package/src/components/post-sticky/panel.js +18 -0
  237. package/src/components/post-title/index.js +2 -2
  238. package/src/components/post-title/post-title-raw.js +2 -2
  239. package/src/components/post-transform-panel/hooks.js +114 -0
  240. package/src/components/post-transform-panel/index.js +99 -0
  241. package/src/components/post-trash/panel.js +13 -0
  242. package/src/components/post-type-support-check/index.js +1 -1
  243. package/src/components/post-type-support-check/test/index.js +2 -2
  244. package/src/components/preferences-modal/index.js +3 -3
  245. package/src/components/provider/index.js +4 -0
  246. package/src/components/provider/use-block-editor-settings.js +19 -4
  247. package/src/components/sidebar/constants.js +4 -0
  248. package/src/components/sidebar/header.js +49 -0
  249. package/src/components/sidebar/index.js +200 -0
  250. package/src/components/sidebar/post-summary.js +104 -0
  251. package/src/components/sidebar/style.scss +18 -0
  252. package/src/components/start-page-options/index.js +6 -4
  253. package/src/components/start-template-options/index.js +219 -0
  254. package/src/components/start-template-options/style.scss +55 -0
  255. package/src/components/template-areas/style.scss +0 -1
  256. package/src/components/template-content-panel/index.js +36 -0
  257. package/src/hooks/pattern-overrides.js +12 -6
  258. package/src/private-apis.js +10 -12
  259. package/src/private-apis.native.js +61 -0
  260. package/src/store/private-selectors.js +3 -0
  261. package/src/store/reducer.js +12 -0
  262. package/src/style.scss +7 -0
  263. package/src/components/post-slug/test/check.js +0 -17
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { external, trash, edit, backup } from '@wordpress/icons';
4
+ import { external, trash, backup } from '@wordpress/icons';
5
5
  import { addQueryArgs } from '@wordpress/url';
6
- import { useDispatch } from '@wordpress/data';
6
+ import { useDispatch, useSelect } from '@wordpress/data';
7
7
  import { decodeEntities } from '@wordpress/html-entities';
8
8
  import { store as coreStore } from '@wordpress/core-data';
9
9
  import { __, _n, sprintf, _x } from '@wordpress/i18n';
@@ -21,7 +21,12 @@ import {
21
21
  /**
22
22
  * Internal dependencies
23
23
  */
24
- import { TEMPLATE_ORIGINS, TEMPLATE_POST_TYPE } from '../../store/constants';
24
+ import {
25
+ TEMPLATE_ORIGINS,
26
+ TEMPLATE_PART_POST_TYPE,
27
+ TEMPLATE_POST_TYPE,
28
+ PATTERN_POST_TYPE,
29
+ } from '../../store/constants';
25
30
  import { store as editorStore } from '../../store';
26
31
  import { unlock } from '../../lock-unlock';
27
32
  import isTemplateRevertable from '../../store/utils/is-template-revertable';
@@ -43,7 +48,13 @@ const trashPostAction = {
43
48
  },
44
49
  supportsBulk: true,
45
50
  hideModalHeader: true,
46
- RenderModal: ( { items: posts, closeModal, onActionPerformed } ) => {
51
+ RenderModal: ( {
52
+ items: posts,
53
+ closeModal,
54
+ onActionStart,
55
+ onActionPerformed,
56
+ } ) => {
57
+ const [ isBusy, setIsBusy ] = useState( false );
47
58
  const { createSuccessNotice, createErrorNotice } =
48
59
  useDispatch( noticesStore );
49
60
  const { deleteEntityRecord } = useDispatch( coreStore );
@@ -67,12 +78,21 @@ const trashPostAction = {
67
78
  ) }
68
79
  </Text>
69
80
  <HStack justify="right">
70
- <Button variant="tertiary" onClick={ closeModal }>
81
+ <Button
82
+ variant="tertiary"
83
+ onClick={ closeModal }
84
+ disabled={ isBusy }
85
+ __experimentalIsFocusable
86
+ >
71
87
  { __( 'Cancel' ) }
72
88
  </Button>
73
89
  <Button
74
90
  variant="primary"
75
91
  onClick={ async () => {
92
+ setIsBusy( true );
93
+ if ( onActionStart ) {
94
+ onActionStart( posts );
95
+ }
76
96
  const promiseResult = await Promise.allSettled(
77
97
  posts.map( ( post ) => {
78
98
  return deleteEntityRecord(
@@ -97,9 +117,17 @@ const trashPostAction = {
97
117
  __( '"%s" moved to the Trash.' ),
98
118
  getItemTitle( posts[ 0 ] )
99
119
  );
120
+ } else if ( posts[ 0 ].type === 'page' ) {
121
+ successMessage = sprintf(
122
+ /* translators: The number of pages. */
123
+ __( '%s pages moved to the Trash.' ),
124
+ posts.length
125
+ );
100
126
  } else {
101
- successMessage = __(
102
- 'Pages moved to the Trash.'
127
+ successMessage = sprintf(
128
+ /* translators: The number of posts. */
129
+ __( '%s posts moved to the Trash.' ),
130
+ posts.length
103
131
  );
104
132
  }
105
133
  createSuccessNotice( successMessage, {
@@ -161,8 +189,12 @@ const trashPostAction = {
161
189
  if ( onActionPerformed ) {
162
190
  onActionPerformed( posts );
163
191
  }
192
+ setIsBusy( false );
164
193
  closeModal();
165
194
  } }
195
+ isBusy={ isBusy }
196
+ disabled={ isBusy }
197
+ __experimentalIsFocusable
166
198
  >
167
199
  { __( 'Delete' ) }
168
200
  </Button>
@@ -296,9 +328,9 @@ function useRestorePostAction() {
296
328
  return status === 'trash';
297
329
  },
298
330
  async callback( posts, onActionPerformed ) {
299
- try {
300
- for ( const post of posts ) {
301
- await editEntityRecord(
331
+ await Promise.allSettled(
332
+ posts.map( ( post ) => {
333
+ return editEntityRecord(
302
334
  'postType',
303
335
  post.type,
304
336
  post.id,
@@ -306,53 +338,101 @@ function useRestorePostAction() {
306
338
  status: 'draft',
307
339
  }
308
340
  );
309
- await saveEditedEntityRecord(
341
+ } )
342
+ );
343
+ const promiseResult = await Promise.allSettled(
344
+ posts.map( ( post ) => {
345
+ return saveEditedEntityRecord(
310
346
  'postType',
311
347
  post.type,
312
348
  post.id,
313
349
  { throwOnError: true }
314
350
  );
315
- }
351
+ } )
352
+ );
316
353
 
317
- createSuccessNotice(
318
- posts.length > 1
319
- ? sprintf(
320
- /* translators: The number of posts. */
321
- __( '%d posts have been restored.' ),
322
- posts.length
323
- )
324
- : sprintf(
325
- /* translators: The number of posts. */
326
- __( '"%s" has been restored.' ),
327
- getItemTitle( posts[ 0 ] )
328
- ),
329
- {
330
- type: 'snackbar',
331
- id: 'restore-post-action',
332
- }
333
- );
354
+ if (
355
+ promiseResult.every(
356
+ ( { status } ) => status === 'fulfilled'
357
+ )
358
+ ) {
359
+ let successMessage;
360
+ if ( posts.length === 1 ) {
361
+ successMessage = sprintf(
362
+ /* translators: The number of posts. */
363
+ __( '"%s" has been restored.' ),
364
+ getItemTitle( posts[ 0 ] )
365
+ );
366
+ } else if ( posts[ 0 ].type === 'page' ) {
367
+ successMessage = sprintf(
368
+ /* translators: The number of posts. */
369
+ __( '%d pages have been restored.' ),
370
+ posts.length
371
+ );
372
+ } else {
373
+ successMessage = sprintf(
374
+ /* translators: The number of posts. */
375
+ __( '%d posts have been restored.' ),
376
+ posts.length
377
+ );
378
+ }
379
+ createSuccessNotice( successMessage, {
380
+ type: 'snackbar',
381
+ id: 'restore-post-action',
382
+ } );
334
383
  if ( onActionPerformed ) {
335
384
  onActionPerformed( posts );
336
385
  }
337
- } catch ( error ) {
386
+ } else {
387
+ // If there was at lease one failure.
338
388
  let errorMessage;
339
- if (
340
- error.message &&
341
- error.code !== 'unknown_error' &&
342
- error.message
343
- ) {
344
- errorMessage = error.message;
345
- } else if ( posts.length > 1 ) {
346
- errorMessage = __(
347
- 'An error occurred while restoring the posts.'
348
- );
389
+ // If we were trying to move a single post to the trash.
390
+ if ( promiseResult.length === 1 ) {
391
+ if ( promiseResult[ 0 ].reason?.message ) {
392
+ errorMessage = promiseResult[ 0 ].reason.message;
393
+ } else {
394
+ errorMessage = __(
395
+ 'An error occurred while restoring the post.'
396
+ );
397
+ }
398
+ // If we were trying to move multiple posts to the trash
349
399
  } else {
350
- errorMessage = __(
351
- 'An error occurred while restoring the post.'
400
+ const errorMessages = new Set();
401
+ const failedPromises = promiseResult.filter(
402
+ ( { status } ) => status === 'rejected'
352
403
  );
404
+ for ( const failedPromise of failedPromises ) {
405
+ if ( failedPromise.reason?.message ) {
406
+ errorMessages.add(
407
+ failedPromise.reason.message
408
+ );
409
+ }
410
+ }
411
+ if ( errorMessages.size === 0 ) {
412
+ errorMessage = __(
413
+ 'An error occurred while restoring the posts.'
414
+ );
415
+ } else if ( errorMessages.size === 1 ) {
416
+ errorMessage = sprintf(
417
+ /* translators: %s: an error message */
418
+ __(
419
+ 'An error occurred while restoring the posts: %s'
420
+ ),
421
+ [ ...errorMessages ][ 0 ]
422
+ );
423
+ } else {
424
+ errorMessage = sprintf(
425
+ /* translators: %s: a list of comma separated error messages */
426
+ __(
427
+ 'Some errors occurred while restoring the posts: %s'
428
+ ),
429
+ [ ...errorMessages ].join( ',' )
430
+ );
431
+ }
353
432
  }
354
-
355
- createErrorNotice( errorMessage, { type: 'snackbar' } );
433
+ createErrorNotice( errorMessage, {
434
+ type: 'snackbar',
435
+ } );
356
436
  }
357
437
  },
358
438
  } ),
@@ -382,20 +462,6 @@ const viewPostAction = {
382
462
  },
383
463
  };
384
464
 
385
- const editPostAction = {
386
- id: 'edit-post',
387
- label: __( 'Edit' ),
388
- isPrimary: true,
389
- icon: edit,
390
- isEligible( { status } ) {
391
- return status !== 'trash';
392
- },
393
- callback( posts, onActionPerformed ) {
394
- if ( onActionPerformed ) {
395
- onActionPerformed( posts );
396
- }
397
- },
398
- };
399
465
  const postRevisionsAction = {
400
466
  id: 'view-post-revisions',
401
467
  label: __( 'View revisions' ),
@@ -500,7 +566,7 @@ const renamePostAction = {
500
566
  },
501
567
  };
502
568
 
503
- export const duplicatePostAction = {
569
+ const duplicatePostAction = {
504
570
  id: 'duplicate-post',
505
571
  label: _x( 'Duplicate', 'action label' ),
506
572
  isEligible( { status } ) {
@@ -618,9 +684,16 @@ const resetTemplateAction = {
618
684
  id: 'reset-template',
619
685
  label: __( 'Reset' ),
620
686
  isEligible: isTemplateRevertable,
687
+ icon: backup,
621
688
  supportsBulk: true,
622
689
  hideModalHeader: true,
623
- RenderModal: ( { items, closeModal, onActionPerformed } ) => {
690
+ RenderModal: ( {
691
+ items,
692
+ closeModal,
693
+ onActionStart,
694
+ onActionPerformed,
695
+ } ) => {
696
+ const [ isBusy, setIsBusy ] = useState( false );
624
697
  const { revertTemplate } = unlock( useDispatch( editorStore ) );
625
698
  const { saveEditedEntityRecord } = useDispatch( coreStore );
626
699
  const { createSuccessNotice, createErrorNotice } =
@@ -690,16 +763,29 @@ const resetTemplateAction = {
690
763
  { __( 'Reset to default and clear all customizations?' ) }
691
764
  </Text>
692
765
  <HStack justify="right">
693
- <Button variant="tertiary" onClick={ closeModal }>
766
+ <Button
767
+ variant="tertiary"
768
+ onClick={ closeModal }
769
+ disabled={ isBusy }
770
+ __experimentalIsFocusable
771
+ >
694
772
  { __( 'Cancel' ) }
695
773
  </Button>
696
774
  <Button
697
775
  variant="primary"
698
776
  onClick={ async () => {
777
+ setIsBusy( true );
778
+ if ( onActionStart ) {
779
+ onActionStart( items );
780
+ }
699
781
  await onConfirm( items );
700
782
  onActionPerformed?.( items );
701
783
  closeModal();
784
+ isBusy( false );
702
785
  } }
786
+ isBusy={ isBusy }
787
+ disabled={ isBusy }
788
+ __experimentalIsFocusable
703
789
  >
704
790
  { __( 'Reset' ) }
705
791
  </Button>
@@ -730,9 +816,16 @@ const deleteTemplateAction = {
730
816
  id: 'delete-template',
731
817
  label: __( 'Delete' ),
732
818
  isEligible: isTemplateRemovable,
819
+ icon: trash,
733
820
  supportsBulk: true,
734
821
  hideModalHeader: true,
735
- RenderModal: ( { items: templates, closeModal, onActionPerformed } ) => {
822
+ RenderModal: ( {
823
+ items: templates,
824
+ closeModal,
825
+ onActionStart,
826
+ onActionPerformed,
827
+ } ) => {
828
+ const [ isBusy, setIsBusy ] = useState( false );
736
829
  const { removeTemplates } = unlock( useDispatch( editorStore ) );
737
830
  return (
738
831
  <VStack spacing="5">
@@ -756,18 +849,31 @@ const deleteTemplateAction = {
756
849
  ) }
757
850
  </Text>
758
851
  <HStack justify="right">
759
- <Button variant="tertiary" onClick={ closeModal }>
852
+ <Button
853
+ variant="tertiary"
854
+ onClick={ closeModal }
855
+ disabled={ isBusy }
856
+ __experimentalIsFocusable
857
+ >
760
858
  { __( 'Cancel' ) }
761
859
  </Button>
762
860
  <Button
763
861
  variant="primary"
764
862
  onClick={ async () => {
863
+ setIsBusy( true );
864
+ if ( onActionStart ) {
865
+ onActionStart( templates );
866
+ }
765
867
  await removeTemplates( templates, {
766
868
  allowUndo: false,
767
869
  } );
768
870
  onActionPerformed?.( templates );
871
+ setIsBusy( false );
769
872
  closeModal();
770
873
  } }
874
+ isBusy={ isBusy }
875
+ disabled={ isBusy }
876
+ __experimentalIsFocusable
771
877
  >
772
878
  { __( 'Delete' ) }
773
879
  </Button>
@@ -882,96 +988,96 @@ const renameTemplateAction = {
882
988
  },
883
989
  };
884
990
 
885
- export function usePostActions( onActionPerformed, actionIds = null ) {
991
+ export function usePostActions( postType, onActionPerformed ) {
992
+ const { postTypeObject } = useSelect(
993
+ ( select ) => {
994
+ const { getPostType } = select( coreStore );
995
+ return {
996
+ postTypeObject: getPostType( postType ),
997
+ };
998
+ },
999
+ [ postType ]
1000
+ );
1001
+
886
1002
  const permanentlyDeletePostAction = usePermanentlyDeletePostAction();
887
1003
  const restorePostAction = useRestorePostAction();
888
- return useMemo(
889
- () => {
890
- // By default, return all actions...
891
- const defaultActions = [
892
- editPostAction,
893
- resetTemplateAction,
894
- viewPostAction,
895
- restorePostAction,
896
- deleteTemplateAction,
897
- permanentlyDeletePostAction,
898
- postRevisionsAction,
899
- duplicatePostAction,
900
- renamePostAction,
901
- renameTemplateAction,
902
- trashPostAction,
903
- ];
904
-
905
- // ... unless `actionIds` was specified, in which case we find the
906
- // actions matching the given IDs.
907
- const actions = actionIds
908
- ? actionIds.map( ( actionId ) =>
909
- defaultActions.find( ( { id } ) => actionId === id )
910
- )
911
- : defaultActions;
912
-
913
- if ( onActionPerformed ) {
914
- for ( let i = 0; i < actions.length; ++i ) {
915
- if ( actions[ i ].callback ) {
916
- const existingCallback = actions[ i ].callback;
917
- actions[ i ] = {
918
- ...actions[ i ],
919
- callback: ( items, _onActionPerformed ) => {
920
- existingCallback( items, ( _items ) => {
921
- if ( _onActionPerformed ) {
922
- _onActionPerformed( _items );
923
- }
924
- onActionPerformed(
925
- actions[ i ].id,
926
- _items
927
- );
928
- } );
929
- },
930
- };
931
- }
932
- if ( actions[ i ].RenderModal ) {
933
- const ExistingRenderModal = actions[ i ].RenderModal;
934
- actions[ i ] = {
935
- ...actions[ i ],
936
- RenderModal: ( props ) => {
937
- return (
938
- <ExistingRenderModal
939
- items={ props.items }
940
- closeModal={ props.closeModal }
941
- onActionPerformed={ ( _items ) => {
942
- if ( props.onActionPerformed ) {
943
- props.onActionPerformed(
944
- _items
945
- );
946
- }
947
- onActionPerformed(
948
- actions[ i ].id,
949
- _items
950
- );
951
- } }
952
- />
953
- );
954
- },
955
- };
956
- }
1004
+ const isTemplateOrTemplatePart = [
1005
+ TEMPLATE_POST_TYPE,
1006
+ TEMPLATE_PART_POST_TYPE,
1007
+ ].includes( postType );
1008
+ const isPattern = postType === PATTERN_POST_TYPE;
1009
+ const isLoaded = !! postTypeObject;
1010
+ return useMemo( () => {
1011
+ if ( ! isLoaded ) {
1012
+ return [];
1013
+ }
1014
+
1015
+ const actions = [
1016
+ isTemplateOrTemplatePart && resetTemplateAction,
1017
+ postTypeObject?.viewable && viewPostAction,
1018
+ ! isTemplateOrTemplatePart && restorePostAction,
1019
+ isTemplateOrTemplatePart && deleteTemplateAction,
1020
+ ! isTemplateOrTemplatePart && permanentlyDeletePostAction,
1021
+ postRevisionsAction,
1022
+ process.env.IS_GUTENBERG_PLUGIN
1023
+ ? ! isTemplateOrTemplatePart &&
1024
+ ! isPattern &&
1025
+ duplicatePostAction
1026
+ : false,
1027
+ ! isTemplateOrTemplatePart && renamePostAction,
1028
+ isTemplateOrTemplatePart && renameTemplateAction,
1029
+ ! isTemplateOrTemplatePart && trashPostAction,
1030
+ ].filter( Boolean );
1031
+
1032
+ if ( onActionPerformed ) {
1033
+ for ( let i = 0; i < actions.length; ++i ) {
1034
+ if ( actions[ i ].callback ) {
1035
+ const existingCallback = actions[ i ].callback;
1036
+ actions[ i ] = {
1037
+ ...actions[ i ],
1038
+ callback: ( items, _onActionPerformed ) => {
1039
+ existingCallback( items, ( _items ) => {
1040
+ if ( _onActionPerformed ) {
1041
+ _onActionPerformed( _items );
1042
+ }
1043
+ onActionPerformed( actions[ i ].id, _items );
1044
+ } );
1045
+ },
1046
+ };
1047
+ }
1048
+ if ( actions[ i ].RenderModal ) {
1049
+ const ExistingRenderModal = actions[ i ].RenderModal;
1050
+ actions[ i ] = {
1051
+ ...actions[ i ],
1052
+ RenderModal: ( props ) => {
1053
+ return (
1054
+ <ExistingRenderModal
1055
+ { ...props }
1056
+ onActionPerformed={ ( _items ) => {
1057
+ if ( props.onActionPerformed ) {
1058
+ props.onActionPerformed( _items );
1059
+ }
1060
+ onActionPerformed(
1061
+ actions[ i ].id,
1062
+ _items
1063
+ );
1064
+ } }
1065
+ />
1066
+ );
1067
+ },
1068
+ };
957
1069
  }
958
1070
  }
959
- return actions;
960
- },
1071
+ }
961
1072
 
962
- // Disable reason: if provided, `actionIds` is a shallow array of
963
- // strings, and the strings themselves should be part of the useMemo
964
- // dependencies. Two different disable statements are needed, as the
965
- // first flags what it thinks are missing dependencies, and the second
966
- // flags the array spread operation.
967
- //
968
- // eslint-disable-next-line react-hooks/exhaustive-deps
969
- [
970
- // eslint-disable-next-line react-hooks/exhaustive-deps
971
- ...( actionIds || [] ),
972
- permanentlyDeletePostAction,
973
- restorePostAction,
974
- onActionPerformed,
975
- ]
976
- );
1073
+ return actions;
1074
+ }, [
1075
+ isTemplateOrTemplatePart,
1076
+ isPattern,
1077
+ postTypeObject?.viewable,
1078
+ permanentlyDeletePostAction,
1079
+ restorePostAction,
1080
+ onActionPerformed,
1081
+ isLoaded,
1082
+ ] );
977
1083
  }
@@ -17,11 +17,6 @@ import { moreVertical } from '@wordpress/icons';
17
17
  import { unlock } from '../../lock-unlock';
18
18
  import { usePostActions } from './actions';
19
19
  import { store as editorStore } from '../../store';
20
- import {
21
- TEMPLATE_POST_TYPE,
22
- TEMPLATE_PART_POST_TYPE,
23
- PATTERN_POST_TYPE,
24
- } from '../../store/constants';
25
20
 
26
21
  const {
27
22
  DropdownMenuV2: DropdownMenu,
@@ -31,36 +26,16 @@ const {
31
26
  kebabCase,
32
27
  } = unlock( componentsPrivateApis );
33
28
 
34
- let POST_ACTIONS_WHILE_EDITING = [
35
- 'view-post',
36
- 'view-post-revisions',
37
- 'rename-post',
38
- 'move-to-trash',
39
- ];
40
-
41
- if ( process.env.IS_GUTENBERG_PLUGIN ) {
42
- POST_ACTIONS_WHILE_EDITING = [
43
- 'view-post',
44
- 'view-post-revisions',
45
- 'duplicate-post',
46
- 'rename-post',
47
- 'move-to-trash',
48
- ];
49
- }
50
-
51
29
  export default function PostActions( { onActionPerformed, buttonProps } ) {
52
30
  const [ isActionsMenuOpen, setIsActionsMenuOpen ] = useState( false );
53
- const { postType, item } = useSelect( ( select ) => {
31
+ const { item, postType } = useSelect( ( select ) => {
54
32
  const { getCurrentPostType, getCurrentPost } = select( editorStore );
55
33
  return {
56
- postType: getCurrentPostType(),
57
34
  item: getCurrentPost(),
35
+ postType: getCurrentPostType(),
58
36
  };
59
- } );
60
- const allActions = usePostActions(
61
- onActionPerformed,
62
- POST_ACTIONS_WHILE_EDITING
63
- );
37
+ }, [] );
38
+ const allActions = usePostActions( postType, onActionPerformed );
64
39
 
65
40
  const actions = useMemo( () => {
66
41
  return allActions.filter( ( action ) => {
@@ -68,15 +43,6 @@ export default function PostActions( { onActionPerformed, buttonProps } ) {
68
43
  } );
69
44
  }, [ allActions, item ] );
70
45
 
71
- if (
72
- [
73
- TEMPLATE_POST_TYPE,
74
- TEMPLATE_PART_POST_TYPE,
75
- PATTERN_POST_TYPE,
76
- ].includes( postType )
77
- ) {
78
- return null;
79
- }
80
46
  return (
81
47
  <DropdownMenu
82
48
  open={ isActionsMenuOpen }
@@ -86,6 +52,7 @@ export default function PostActions( { onActionPerformed, buttonProps } ) {
86
52
  icon={ moreVertical }
87
53
  label={ __( 'Actions' ) }
88
54
  disabled={ ! actions.length }
55
+ __experimentalIsFocusable
89
56
  className="editor-all-actions-button"
90
57
  onClick={ () =>
91
58
  setIsActionsMenuOpen( ! isActionsMenuOpen )