@wordpress/edit-site 5.20.1 → 5.21.1-next.f8d8eceb.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 (260) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/actions/index.js +121 -0
  3. package/build/components/actions/index.js.map +1 -0
  4. package/build/components/add-new-template/add-custom-template-modal-content.js +17 -13
  5. package/build/components/add-new-template/add-custom-template-modal-content.js.map +1 -1
  6. package/build/components/block-editor/resize-handle.js +2 -1
  7. package/build/components/block-editor/resize-handle.js.map +1 -1
  8. package/build/components/block-editor/use-site-editor-settings.js +12 -4
  9. package/build/components/block-editor/use-site-editor-settings.js.map +1 -1
  10. package/build/components/create-template-part-modal/index.js +10 -6
  11. package/build/components/create-template-part-modal/index.js.map +1 -1
  12. package/build/components/dataviews/context.js +15 -0
  13. package/build/components/dataviews/context.js.map +1 -0
  14. package/build/components/dataviews/dataviews.js +50 -33
  15. package/build/components/dataviews/dataviews.js.map +1 -1
  16. package/build/components/dataviews/filters.js +74 -0
  17. package/build/components/dataviews/filters.js.map +1 -0
  18. package/build/components/dataviews/in-filter.js +49 -0
  19. package/build/components/dataviews/in-filter.js.map +1 -0
  20. package/build/components/dataviews/index.js +0 -7
  21. package/build/components/dataviews/index.js.map +1 -1
  22. package/build/components/dataviews/item-actions.js +62 -0
  23. package/build/components/dataviews/item-actions.js.map +1 -0
  24. package/build/components/dataviews/pagination.js +74 -45
  25. package/build/components/dataviews/pagination.js.map +1 -1
  26. package/build/components/dataviews/{text-filter.js → search.js} +21 -15
  27. package/build/components/dataviews/search.js.map +1 -0
  28. package/build/components/dataviews/view-actions.js +94 -56
  29. package/build/components/dataviews/view-actions.js.map +1 -1
  30. package/build/components/dataviews/view-grid.js +59 -0
  31. package/build/components/dataviews/view-grid.js.map +1 -0
  32. package/build/components/dataviews/view-list.js +283 -0
  33. package/build/components/dataviews/view-list.js.map +1 -0
  34. package/build/components/editor/index.js +2 -1
  35. package/build/components/editor/index.js.map +1 -1
  36. package/build/components/global-styles/font-library-modal/context.js +16 -10
  37. package/build/components/global-styles/font-library-modal/context.js.map +1 -1
  38. package/build/components/global-styles/font-library-modal/font-collection.js +20 -6
  39. package/build/components/global-styles/font-library-modal/font-collection.js.map +1 -1
  40. package/build/components/global-styles/screen-block.js +2 -10
  41. package/build/components/global-styles/screen-block.js.map +1 -1
  42. package/build/components/global-styles/screen-root.js +1 -2
  43. package/build/components/global-styles/screen-root.js.map +1 -1
  44. package/build/components/global-styles/ui.js +3 -4
  45. package/build/components/global-styles/ui.js.map +1 -1
  46. package/build/components/layout/index.js +10 -2
  47. package/build/components/layout/index.js.map +1 -1
  48. package/build/components/media/index.js +34 -0
  49. package/build/components/media/index.js.map +1 -0
  50. package/build/components/page-actions/index.js +0 -2
  51. package/build/components/page-actions/index.js.map +1 -1
  52. package/build/components/page-pages/default-views.js +60 -0
  53. package/build/components/page-pages/default-views.js.map +1 -0
  54. package/build/components/page-pages/index.js +174 -107
  55. package/build/components/page-pages/index.js.map +1 -1
  56. package/build/components/page-patterns/delete-category-menu-item.js +89 -0
  57. package/build/components/page-patterns/delete-category-menu-item.js.map +1 -0
  58. package/build/components/page-patterns/duplicate-menu-item.js +52 -131
  59. package/build/components/page-patterns/duplicate-menu-item.js.map +1 -1
  60. package/build/components/page-patterns/grid-item.js +1 -0
  61. package/build/components/page-patterns/grid-item.js.map +1 -1
  62. package/build/components/page-patterns/header.js +25 -3
  63. package/build/components/page-patterns/header.js.map +1 -1
  64. package/build/components/page-patterns/rename-category-menu-item.js +49 -0
  65. package/build/components/page-patterns/rename-category-menu-item.js.map +1 -0
  66. package/build/components/page-patterns/rename-menu-item.js +1 -1
  67. package/build/components/page-patterns/rename-menu-item.js.map +1 -1
  68. package/build/components/page-patterns/use-patterns.js +1 -0
  69. package/build/components/page-patterns/use-patterns.js.map +1 -1
  70. package/build/components/pattern-modal/duplicate.js +65 -0
  71. package/build/components/pattern-modal/duplicate.js.map +1 -0
  72. package/build/components/pattern-modal/index.js +24 -0
  73. package/build/components/pattern-modal/index.js.map +1 -0
  74. package/build/components/pattern-modal/rename.js +42 -0
  75. package/build/components/pattern-modal/rename.js.map +1 -0
  76. package/build/components/sidebar/index.js +3 -1
  77. package/build/components/sidebar/index.js.map +1 -1
  78. package/build/components/sidebar-dataviews/index.js +72 -0
  79. package/build/components/sidebar-dataviews/index.js.map +1 -0
  80. package/build/components/sidebar-edit-mode/template-panel/last-revision.js +3 -0
  81. package/build/components/sidebar-edit-mode/template-panel/last-revision.js.map +1 -1
  82. package/build/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js +2 -2
  83. package/build/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js.map +1 -1
  84. package/build/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js +2 -3
  85. package/build/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js.map +1 -1
  86. package/build/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js +29 -0
  87. package/build/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js.map +1 -0
  88. package/build/components/sidebar-navigation-screen-template/home-template-details.js +12 -1
  89. package/build/components/sidebar-navigation-screen-template/home-template-details.js.map +1 -1
  90. package/build/hooks/commands/use-common-commands.js +1 -2
  91. package/build/hooks/commands/use-common-commands.js.map +1 -1
  92. package/build/hooks/commands/use-edit-mode-commands.js +50 -0
  93. package/build/hooks/commands/use-edit-mode-commands.js.map +1 -1
  94. package/build/lock-unlock.js +1 -1
  95. package/build/lock-unlock.js.map +1 -1
  96. package/build/store/selectors.js +4 -5
  97. package/build/store/selectors.js.map +1 -1
  98. package/build-module/components/actions/index.js +108 -0
  99. package/build-module/components/actions/index.js.map +1 -0
  100. package/build-module/components/add-new-template/add-custom-template-modal-content.js +16 -12
  101. package/build-module/components/add-new-template/add-custom-template-modal-content.js.map +1 -1
  102. package/build-module/components/block-editor/resize-handle.js +2 -1
  103. package/build-module/components/block-editor/resize-handle.js.map +1 -1
  104. package/build-module/components/block-editor/use-site-editor-settings.js +12 -4
  105. package/build-module/components/block-editor/use-site-editor-settings.js.map +1 -1
  106. package/build-module/components/create-template-part-modal/index.js +10 -6
  107. package/build-module/components/create-template-part-modal/index.js.map +1 -1
  108. package/build-module/components/dataviews/context.js +7 -0
  109. package/build-module/components/dataviews/context.js.map +1 -0
  110. package/build-module/components/dataviews/dataviews.js +49 -32
  111. package/build-module/components/dataviews/dataviews.js.map +1 -1
  112. package/build-module/components/dataviews/filters.js +66 -0
  113. package/build-module/components/dataviews/filters.js.map +1 -0
  114. package/build-module/components/dataviews/in-filter.js +41 -0
  115. package/build-module/components/dataviews/in-filter.js.map +1 -0
  116. package/build-module/components/dataviews/index.js +0 -1
  117. package/build-module/components/dataviews/index.js.map +1 -1
  118. package/build-module/components/dataviews/item-actions.js +55 -0
  119. package/build-module/components/dataviews/item-actions.js.map +1 -0
  120. package/build-module/components/dataviews/pagination.js +73 -46
  121. package/build-module/components/dataviews/pagination.js.map +1 -1
  122. package/build-module/components/dataviews/search.js +42 -0
  123. package/build-module/components/dataviews/search.js.map +1 -0
  124. package/build-module/components/dataviews/view-actions.js +95 -54
  125. package/build-module/components/dataviews/view-actions.js.map +1 -1
  126. package/build-module/components/dataviews/view-grid.js +51 -0
  127. package/build-module/components/dataviews/view-grid.js.map +1 -0
  128. package/build-module/components/dataviews/view-list.js +274 -0
  129. package/build-module/components/dataviews/view-list.js.map +1 -0
  130. package/build-module/components/editor/index.js +2 -1
  131. package/build-module/components/editor/index.js.map +1 -1
  132. package/build-module/components/global-styles/font-library-modal/context.js +16 -10
  133. package/build-module/components/global-styles/font-library-modal/context.js.map +1 -1
  134. package/build-module/components/global-styles/font-library-modal/font-collection.js +20 -6
  135. package/build-module/components/global-styles/font-library-modal/font-collection.js.map +1 -1
  136. package/build-module/components/global-styles/screen-block.js +2 -10
  137. package/build-module/components/global-styles/screen-block.js.map +1 -1
  138. package/build-module/components/global-styles/screen-root.js +1 -2
  139. package/build-module/components/global-styles/screen-root.js.map +1 -1
  140. package/build-module/components/global-styles/ui.js +3 -4
  141. package/build-module/components/global-styles/ui.js.map +1 -1
  142. package/build-module/components/layout/index.js +11 -3
  143. package/build-module/components/layout/index.js.map +1 -1
  144. package/build-module/components/media/index.js +26 -0
  145. package/build-module/components/media/index.js.map +1 -0
  146. package/build-module/components/page-actions/index.js +0 -2
  147. package/build-module/components/page-actions/index.js.map +1 -1
  148. package/build-module/components/page-pages/default-views.js +53 -0
  149. package/build-module/components/page-pages/default-views.js.map +1 -0
  150. package/build-module/components/page-pages/index.js +175 -110
  151. package/build-module/components/page-pages/index.js.map +1 -1
  152. package/build-module/components/page-patterns/delete-category-menu-item.js +82 -0
  153. package/build-module/components/page-patterns/delete-category-menu-item.js.map +1 -0
  154. package/build-module/components/page-patterns/duplicate-menu-item.js +54 -133
  155. package/build-module/components/page-patterns/duplicate-menu-item.js.map +1 -1
  156. package/build-module/components/page-patterns/grid-item.js +1 -0
  157. package/build-module/components/page-patterns/grid-item.js.map +1 -1
  158. package/build-module/components/page-patterns/header.js +26 -4
  159. package/build-module/components/page-patterns/header.js.map +1 -1
  160. package/build-module/components/page-patterns/rename-category-menu-item.js +42 -0
  161. package/build-module/components/page-patterns/rename-category-menu-item.js.map +1 -0
  162. package/build-module/components/page-patterns/rename-menu-item.js +1 -1
  163. package/build-module/components/page-patterns/rename-menu-item.js.map +1 -1
  164. package/build-module/components/page-patterns/use-patterns.js +1 -0
  165. package/build-module/components/page-patterns/use-patterns.js.map +1 -1
  166. package/build-module/components/pattern-modal/duplicate.js +57 -0
  167. package/build-module/components/pattern-modal/duplicate.js.map +1 -0
  168. package/build-module/components/pattern-modal/index.js +14 -0
  169. package/build-module/components/pattern-modal/index.js.map +1 -0
  170. package/build-module/components/pattern-modal/rename.js +34 -0
  171. package/build-module/components/pattern-modal/rename.js.map +1 -0
  172. package/build-module/components/sidebar/index.js +3 -1
  173. package/build-module/components/sidebar/index.js.map +1 -1
  174. package/build-module/components/sidebar-dataviews/index.js +64 -0
  175. package/build-module/components/sidebar-dataviews/index.js.map +1 -0
  176. package/build-module/components/sidebar-edit-mode/template-panel/last-revision.js +3 -0
  177. package/build-module/components/sidebar-edit-mode/template-panel/last-revision.js.map +1 -1
  178. package/build-module/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js +2 -2
  179. package/build-module/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js.map +1 -1
  180. package/build-module/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js +2 -3
  181. package/build-module/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js.map +1 -1
  182. package/build-module/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js +22 -0
  183. package/build-module/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js.map +1 -0
  184. package/build-module/components/sidebar-navigation-screen-template/home-template-details.js +12 -1
  185. package/build-module/components/sidebar-navigation-screen-template/home-template-details.js.map +1 -1
  186. package/build-module/hooks/commands/use-common-commands.js +1 -2
  187. package/build-module/hooks/commands/use-common-commands.js.map +1 -1
  188. package/build-module/hooks/commands/use-edit-mode-commands.js +51 -1
  189. package/build-module/hooks/commands/use-edit-mode-commands.js.map +1 -1
  190. package/build-module/lock-unlock.js +1 -1
  191. package/build-module/lock-unlock.js.map +1 -1
  192. package/build-module/store/selectors.js +4 -5
  193. package/build-module/store/selectors.js.map +1 -1
  194. package/build-style/style-rtl.css +48 -11
  195. package/build-style/style.css +48 -11
  196. package/package.json +40 -40
  197. package/src/components/actions/index.js +123 -0
  198. package/src/components/add-new-template/add-custom-template-modal-content.js +22 -17
  199. package/src/components/block-editor/resize-handle.js +1 -0
  200. package/src/components/block-editor/use-site-editor-settings.js +21 -13
  201. package/src/components/create-template-part-modal/index.js +9 -5
  202. package/src/components/dataviews/README.md +194 -0
  203. package/src/components/dataviews/context.js +7 -0
  204. package/src/components/dataviews/dataviews.js +55 -34
  205. package/src/components/dataviews/filters.js +75 -0
  206. package/src/components/dataviews/in-filter.js +45 -0
  207. package/src/components/dataviews/index.js +0 -1
  208. package/src/components/dataviews/item-actions.js +69 -0
  209. package/src/components/dataviews/pagination.js +80 -59
  210. package/src/components/dataviews/search.js +41 -0
  211. package/src/components/dataviews/style.scss +18 -3
  212. package/src/components/dataviews/view-actions.js +108 -63
  213. package/src/components/dataviews/view-grid.js +65 -0
  214. package/src/components/dataviews/view-list.js +348 -0
  215. package/src/components/editor/index.js +2 -0
  216. package/src/components/global-styles/font-library-modal/context.js +17 -11
  217. package/src/components/global-styles/font-library-modal/font-collection.js +19 -11
  218. package/src/components/global-styles/screen-block.js +2 -9
  219. package/src/components/global-styles/screen-root.js +1 -2
  220. package/src/components/global-styles/style.scss +16 -4
  221. package/src/components/global-styles/ui.js +1 -2
  222. package/src/components/layout/index.js +12 -4
  223. package/src/components/media/index.js +25 -0
  224. package/src/components/page-actions/index.js +1 -7
  225. package/src/components/page-pages/default-views.js +58 -0
  226. package/src/components/page-pages/index.js +181 -108
  227. package/src/components/page-pages/style.scss +3 -0
  228. package/src/components/page-patterns/delete-category-menu-item.js +104 -0
  229. package/src/components/page-patterns/duplicate-menu-item.js +68 -181
  230. package/src/components/page-patterns/grid-item.js +1 -0
  231. package/src/components/page-patterns/header.js +42 -6
  232. package/src/components/page-patterns/rename-category-menu-item.js +45 -0
  233. package/src/components/page-patterns/rename-menu-item.js +2 -2
  234. package/src/components/page-patterns/style.scss +8 -0
  235. package/src/components/page-patterns/use-patterns.js +5 -0
  236. package/src/components/pattern-modal/duplicate.js +53 -0
  237. package/src/components/pattern-modal/index.js +19 -0
  238. package/src/components/pattern-modal/rename.js +29 -0
  239. package/src/components/sidebar/index.js +2 -0
  240. package/src/components/sidebar-dataviews/index.js +65 -0
  241. package/src/components/sidebar-edit-mode/template-panel/last-revision.js +4 -0
  242. package/src/components/sidebar-navigation-screen/style.scss +17 -5
  243. package/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu-list-item.js +2 -7
  244. package/src/components/sidebar-navigation-screen-pattern/template-part-navigation-menu.js +2 -8
  245. package/src/components/sidebar-navigation-screen-pattern/use-navigation-menu-title.js +32 -0
  246. package/src/components/sidebar-navigation-screen-template/home-template-details.js +21 -7
  247. package/src/hooks/commands/use-common-commands.js +1 -2
  248. package/src/hooks/commands/use-edit-mode-commands.js +43 -0
  249. package/src/lock-unlock.js +1 -1
  250. package/src/store/selectors.js +9 -10
  251. package/src/style.scss +1 -0
  252. package/build/components/dataviews/list-view.js +0 -89
  253. package/build/components/dataviews/list-view.js.map +0 -1
  254. package/build/components/dataviews/text-filter.js.map +0 -1
  255. package/build-module/components/dataviews/list-view.js +0 -80
  256. package/build-module/components/dataviews/list-view.js.map +0 -1
  257. package/build-module/components/dataviews/text-filter.js +0 -36
  258. package/build-module/components/dataviews/text-filter.js.map +0 -1
  259. package/src/components/dataviews/list-view.js +0 -106
  260. package/src/components/dataviews/text-filter.js +0 -37
@@ -2,217 +2,104 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { MenuItem } from '@wordpress/components';
5
- import { store as coreStore } from '@wordpress/core-data';
6
5
  import { useDispatch } from '@wordpress/data';
6
+ import { useState } from '@wordpress/element';
7
7
  import { __, sprintf } from '@wordpress/i18n';
8
8
  import { store as noticesStore } from '@wordpress/notices';
9
+ import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
9
10
  import { privateApis as routerPrivateApis } from '@wordpress/router';
10
11
 
11
12
  /**
12
13
  * Internal dependencies
13
14
  */
14
- import {
15
- TEMPLATE_PART_POST_TYPE,
16
- PATTERN_TYPES,
17
- PATTERN_SYNC_TYPES,
18
- } from '../../utils/constants';
19
- import {
20
- useExistingTemplateParts,
21
- getUniqueTemplatePartTitle,
22
- getCleanTemplatePartSlug,
23
- } from '../../utils/template-part-create';
15
+ import { TEMPLATE_PART_POST_TYPE, PATTERN_TYPES } from '../../utils/constants';
24
16
  import { unlock } from '../../lock-unlock';
25
- import usePatternCategories from '../sidebar-navigation-screen-patterns/use-pattern-categories';
17
+ import CreateTemplatePartModal from '../create-template-part-modal';
26
18
 
19
+ const { DuplicatePatternModal } = unlock( patternsPrivateApis );
27
20
  const { useHistory } = unlock( routerPrivateApis );
28
21
 
29
- function getPatternMeta( item ) {
30
- if ( item.type === PATTERN_TYPES.theme ) {
31
- return { wp_pattern_sync_status: PATTERN_SYNC_TYPES.unsynced };
32
- }
33
-
34
- const syncStatus = item.patternBlock.wp_pattern_sync_status;
35
- const isUnsynced = syncStatus === PATTERN_SYNC_TYPES.unsynced;
36
-
37
- return {
38
- ...item.patternBlock.meta,
39
- wp_pattern_sync_status: isUnsynced ? syncStatus : undefined,
40
- };
41
- }
42
-
43
22
  export default function DuplicateMenuItem( {
44
23
  categoryId,
45
24
  item,
46
25
  label = __( 'Duplicate' ),
47
26
  onClose,
48
27
  } ) {
49
- const { saveEntityRecord, invalidateResolution } = useDispatch( coreStore );
50
- const { createErrorNotice, createSuccessNotice } =
51
- useDispatch( noticesStore );
52
-
28
+ const { createSuccessNotice } = useDispatch( noticesStore );
29
+ const [ isModalOpen, setIsModalOpen ] = useState( false );
53
30
  const history = useHistory();
54
- const existingTemplateParts = useExistingTemplateParts();
55
- const { patternCategories } = usePatternCategories();
56
31
 
57
- async function createTemplatePart() {
58
- try {
59
- const copiedTitle = sprintf(
60
- /* translators: %s: Existing template part title */
61
- __( '%s (Copy)' ),
62
- item.title
63
- );
64
- const title = getUniqueTemplatePartTitle(
65
- copiedTitle,
66
- existingTemplateParts
67
- );
68
- const slug = getCleanTemplatePartSlug( title );
69
- const { area, content } = item.templatePart;
70
-
71
- const result = await saveEntityRecord(
72
- 'postType',
73
- TEMPLATE_PART_POST_TYPE,
74
- { slug, title, content, area },
75
- { throwOnError: true }
76
- );
77
-
78
- createSuccessNotice(
79
- sprintf(
80
- // translators: %s: The new template part's title e.g. 'Call to action (copy)'.
81
- __( '"%s" duplicated.' ),
82
- item.title
83
- ),
84
- {
85
- type: 'snackbar',
86
- id: 'edit-site-patterns-success',
87
- }
88
- );
32
+ const closeModal = () => setIsModalOpen( false );
89
33
 
90
- history.push( {
91
- postType: TEMPLATE_PART_POST_TYPE,
92
- postId: result?.id,
93
- categoryType: TEMPLATE_PART_POST_TYPE,
94
- categoryId,
95
- } );
34
+ const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE;
35
+ const isThemePattern = item.type === PATTERN_TYPES.theme;
96
36
 
97
- onClose();
98
- } catch ( error ) {
99
- const errorMessage =
100
- error.message && error.code !== 'unknown_error'
101
- ? error.message
102
- : __(
103
- 'An error occurred while creating the template part.'
104
- );
105
-
106
- createErrorNotice( errorMessage, {
37
+ async function onTemplatePartSuccess( templatePart ) {
38
+ createSuccessNotice(
39
+ sprintf(
40
+ // translators: %s: The new template part's title e.g. 'Call to action (copy)'.
41
+ __( '"%s" duplicated.' ),
42
+ item.title
43
+ ),
44
+ {
107
45
  type: 'snackbar',
108
- id: 'edit-site-patterns-error',
109
- } );
110
- onClose();
111
- }
112
- }
113
-
114
- async function findOrCreateTerm( term ) {
115
- try {
116
- const newTerm = await saveEntityRecord(
117
- 'taxonomy',
118
- 'wp_pattern_category',
119
- {
120
- name: term.label,
121
- slug: term.name,
122
- description: term.description,
123
- },
124
- {
125
- throwOnError: true,
126
- }
127
- );
128
- invalidateResolution( 'getUserPatternCategories' );
129
- return newTerm.id;
130
- } catch ( error ) {
131
- if ( error.code !== 'term_exists' ) {
132
- throw error;
46
+ id: 'edit-site-patterns-success',
133
47
  }
48
+ );
134
49
 
135
- return error.data.term_id;
136
- }
137
- }
138
-
139
- async function getCategories( categories ) {
140
- const terms = categories.map( ( category ) => {
141
- const fullCategory = patternCategories.find(
142
- ( cat ) => cat.name === category
143
- );
144
- if ( fullCategory.id ) {
145
- return fullCategory.id;
146
- }
147
- return findOrCreateTerm( fullCategory );
50
+ history.push( {
51
+ postType: TEMPLATE_PART_POST_TYPE,
52
+ postId: templatePart?.id,
53
+ categoryType: TEMPLATE_PART_POST_TYPE,
54
+ categoryId,
148
55
  } );
149
56
 
150
- return Promise.all( terms );
57
+ onClose();
151
58
  }
152
59
 
153
- async function createPattern() {
154
- try {
155
- const isThemePattern = item.type === PATTERN_TYPES.theme;
156
- const title = sprintf(
157
- /* translators: %s: Existing pattern title */
158
- __( '%s (Copy)' ),
159
- item.title || item.name
160
- );
161
- const categories = await getCategories( item.categories || [] );
162
-
163
- const result = await saveEntityRecord(
164
- 'postType',
165
- PATTERN_TYPES.user,
166
- {
167
- content: isThemePattern
168
- ? item.content
169
- : item.patternBlock.content,
170
- meta: getPatternMeta( item ),
171
- status: 'publish',
172
- title,
173
- wp_pattern_category: categories,
174
- },
175
- { throwOnError: true }
176
- );
177
-
178
- createSuccessNotice(
179
- sprintf(
180
- // translators: %s: The new pattern's title e.g. 'Call to action (copy)'.
181
- __( '"%s" duplicated.' ),
182
- item.title || item.name
183
- ),
184
- {
185
- type: 'snackbar',
186
- id: 'edit-site-patterns-success',
187
- }
188
- );
189
-
190
- history.push( {
191
- categoryType: PATTERN_TYPES.theme,
192
- categoryId,
193
- postType: PATTERN_TYPES.user,
194
- postId: result?.id,
195
- } );
196
-
197
- onClose();
198
- } catch ( error ) {
199
- const errorMessage =
200
- error.message && error.code !== 'unknown_error'
201
- ? error.message
202
- : __( 'An error occurred while creating the pattern.' );
60
+ function onPatternSuccess( { pattern } ) {
61
+ history.push( {
62
+ categoryType: PATTERN_TYPES.theme,
63
+ categoryId,
64
+ postType: PATTERN_TYPES.user,
65
+ postId: pattern.id,
66
+ } );
203
67
 
204
- createErrorNotice( errorMessage, {
205
- type: 'snackbar',
206
- id: 'edit-site-patterns-error',
207
- } );
208
- onClose();
209
- }
68
+ onClose();
210
69
  }
211
70
 
212
- const createItem =
213
- item.type === TEMPLATE_PART_POST_TYPE
214
- ? createTemplatePart
215
- : createPattern;
216
-
217
- return <MenuItem onClick={ createItem }>{ label }</MenuItem>;
71
+ return (
72
+ <>
73
+ <MenuItem
74
+ onClick={ () => setIsModalOpen( true ) }
75
+ aria-expanded={ isModalOpen }
76
+ aria-haspopup="dialog"
77
+ >
78
+ { label }
79
+ </MenuItem>
80
+ { isModalOpen && ! isTemplatePart && (
81
+ <DuplicatePatternModal
82
+ onClose={ closeModal }
83
+ onSuccess={ onPatternSuccess }
84
+ pattern={ isThemePattern ? item : item.patternBlock }
85
+ />
86
+ ) }
87
+ { isModalOpen && isTemplatePart && (
88
+ <CreateTemplatePartModal
89
+ blocks={ item.blocks }
90
+ closeModal={ closeModal }
91
+ confirmLabel={ __( 'Duplicate' ) }
92
+ defaultArea={ item.templatePart.area }
93
+ defaultTitle={ sprintf(
94
+ /* translators: %s: Existing template part title */
95
+ __( '%s (Copy)' ),
96
+ item.title
97
+ ) }
98
+ modalTitle={ __( 'Duplicate template part' ) }
99
+ onCreate={ onTemplatePartSuccess }
100
+ onError={ closeModal }
101
+ />
102
+ ) }
103
+ </>
104
+ );
218
105
  }
@@ -174,6 +174,7 @@ function GridItem( { categoryId, item, ...props } ) {
174
174
  // Even though still incomplete, passing ids helps performance.
175
175
  // @see https://reakit.io/docs/composite/#performance.
176
176
  id={ `edit-site-patterns-${ item.name }` }
177
+ type="button"
177
178
  { ...props }
178
179
  onClick={
179
180
  item.type !== PATTERN_TYPES.theme ? onClick : undefined
@@ -2,16 +2,23 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import {
5
- __experimentalVStack as VStack,
5
+ DropdownMenu,
6
+ MenuGroup,
7
+ __experimentalHStack as HStack,
6
8
  __experimentalHeading as Heading,
7
9
  __experimentalText as Text,
10
+ __experimentalVStack as VStack,
8
11
  } from '@wordpress/components';
9
12
  import { store as editorStore } from '@wordpress/editor';
10
13
  import { useSelect } from '@wordpress/data';
14
+ import { __, sprintf } from '@wordpress/i18n';
15
+ import { moreVertical } from '@wordpress/icons';
11
16
 
12
17
  /**
13
18
  * Internal dependencies
14
19
  */
20
+ import RenameCategoryMenuItem from './rename-category-menu-item';
21
+ import DeleteCategoryMenuItem from './delete-category-menu-item';
15
22
  import usePatternCategories from '../sidebar-navigation-screen-patterns/use-pattern-categories';
16
23
  import { TEMPLATE_PART_POST_TYPE, PATTERN_TYPES } from '../../utils/constants';
17
24
 
@@ -28,7 +35,7 @@ export default function PatternsHeader( {
28
35
  []
29
36
  );
30
37
 
31
- let title, description;
38
+ let title, description, patternCategory;
32
39
  if ( type === TEMPLATE_PART_POST_TYPE ) {
33
40
  const templatePartArea = templatePartAreas.find(
34
41
  ( area ) => area.area === categoryId
@@ -36,7 +43,7 @@ export default function PatternsHeader( {
36
43
  title = templatePartArea?.label;
37
44
  description = templatePartArea?.description;
38
45
  } else if ( type === PATTERN_TYPES.theme ) {
39
- const patternCategory = patternCategories.find(
46
+ patternCategory = patternCategories.find(
40
47
  ( category ) => category.name === categoryId
41
48
  );
42
49
  title = patternCategory?.label;
@@ -47,9 +54,38 @@ export default function PatternsHeader( {
47
54
 
48
55
  return (
49
56
  <VStack className="edit-site-patterns__section-header">
50
- <Heading as="h2" level={ 4 } id={ titleId }>
51
- { title }
52
- </Heading>
57
+ <HStack justify="space-between">
58
+ <Heading as="h2" level={ 4 } id={ titleId }>
59
+ { title }
60
+ </Heading>
61
+ { !! patternCategory?.id && (
62
+ <DropdownMenu
63
+ icon={ moreVertical }
64
+ label={ __( 'Actions' ) }
65
+ toggleProps={ {
66
+ className: 'edit-site-patterns__button',
67
+ describedBy: sprintf(
68
+ /* translators: %s: pattern category name */
69
+ __( 'Action menu for %s pattern category' ),
70
+ title
71
+ ),
72
+ } }
73
+ >
74
+ { ( { onClose } ) => (
75
+ <MenuGroup>
76
+ <RenameCategoryMenuItem
77
+ category={ patternCategory }
78
+ onClose={ onClose }
79
+ />
80
+ <DeleteCategoryMenuItem
81
+ category={ patternCategory }
82
+ onClose={ onClose }
83
+ />
84
+ </MenuGroup>
85
+ ) }
86
+ </DropdownMenu>
87
+ ) }
88
+ </HStack>
53
89
  { description ? (
54
90
  <Text variant="muted" as="p" id={ descriptionId }>
55
91
  { description }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { MenuItem } from '@wordpress/components';
5
+ import { useState } from '@wordpress/element';
6
+ import { __ } from '@wordpress/i18n';
7
+ import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { unlock } from '../../lock-unlock';
13
+
14
+ const { RenamePatternCategoryModal } = unlock( patternsPrivateApis );
15
+
16
+ export default function RenameCategoryMenuItem( { category, onClose } ) {
17
+ const [ isModalOpen, setIsModalOpen ] = useState( false );
18
+
19
+ // User created pattern categories have their properties updated when
20
+ // retrieved via `getUserPatternCategories`. The rename modal expects an
21
+ // object that will match the pattern category entity.
22
+ const normalizedCategory = {
23
+ id: category.id,
24
+ slug: category.slug,
25
+ name: category.label,
26
+ };
27
+
28
+ return (
29
+ <>
30
+ <MenuItem onClick={ () => setIsModalOpen( true ) }>
31
+ { __( 'Rename' ) }
32
+ </MenuItem>
33
+ { isModalOpen && (
34
+ <RenamePatternCategoryModal
35
+ category={ normalizedCategory }
36
+ onClose={ () => {
37
+ setIsModalOpen( false );
38
+ onClose();
39
+ } }
40
+ overlayClassName="edit-site-list__rename-modal"
41
+ />
42
+ ) }
43
+ </>
44
+ );
45
+ }
@@ -61,9 +61,9 @@ export default function RenameMenuItem( { item, onClose } ) {
61
61
  const fallbackErrorMessage =
62
62
  item.type === TEMPLATE_PART_POST_TYPE
63
63
  ? __(
64
- 'An error occurred while reverting the template part.'
64
+ 'An error occurred while renaming the template part.'
65
65
  )
66
- : __( 'An error occurred while reverting the pattern.' );
66
+ : __( 'An error occurred while renaming the pattern.' );
67
67
  const errorMessage =
68
68
  error.message && error.code !== 'unknown_error'
69
69
  ? error.message
@@ -101,6 +101,10 @@
101
101
  background: $gray-900;
102
102
  padding: $grid-unit-40 $grid-unit-40 $grid-unit-20;
103
103
  z-index: z-index(".edit-site-patterns__header");
104
+
105
+ .edit-site-patterns__button {
106
+ color: $gray-600;
107
+ }
104
108
  }
105
109
 
106
110
  .edit-site-patterns__section {
@@ -218,3 +222,7 @@
218
222
  .edit-site-patterns__no-results {
219
223
  color: $gray-600;
220
224
  }
225
+
226
+ .edit-site-patterns__delete-modal {
227
+ width: $modal-width-small;
228
+ }
@@ -195,6 +195,11 @@ const patternBlockToPattern = ( patternBlock, categories ) => ( {
195
195
  : patternCategoryId
196
196
  ),
197
197
  } ),
198
+ termLabels: patternBlock.wp_pattern_category.map( ( patternCategoryId ) =>
199
+ categories?.get( patternCategoryId )
200
+ ? categories.get( patternCategoryId ).label
201
+ : patternCategoryId
202
+ ),
198
203
  id: patternBlock.id,
199
204
  name: patternBlock.slug,
200
205
  syncStatus: patternBlock.wp_pattern_sync_status || PATTERN_SYNC_TYPES.full,
@@ -0,0 +1,53 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useDispatch, useSelect } from '@wordpress/data';
5
+ import { store as interfaceStore } from '@wordpress/interface';
6
+ import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
7
+ import { privateApis as routerPrivateApis } from '@wordpress/router';
8
+ import { getQueryArgs } from '@wordpress/url';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { PATTERN_MODALS } from './';
14
+ import { PATTERN_TYPES } from '../../utils/constants';
15
+ import { unlock } from '../../lock-unlock';
16
+ import useEditedEntityRecord from '../use-edited-entity-record';
17
+
18
+ const { DuplicatePatternModal } = unlock( patternsPrivateApis );
19
+ const { useHistory } = unlock( routerPrivateApis );
20
+
21
+ export default function PatternDuplicateModal() {
22
+ const { record } = useEditedEntityRecord();
23
+ const { categoryType, categoryId } = getQueryArgs( window.location.href );
24
+ const { closeModal } = useDispatch( interfaceStore );
25
+ const history = useHistory();
26
+
27
+ const isActive = useSelect( ( select ) =>
28
+ select( interfaceStore ).isModalActive( PATTERN_MODALS.duplicate )
29
+ );
30
+
31
+ if ( ! isActive ) {
32
+ return null;
33
+ }
34
+
35
+ function onSuccess( { pattern: newPattern } ) {
36
+ history.push( {
37
+ categoryType,
38
+ categoryId,
39
+ postType: PATTERN_TYPES.user,
40
+ postId: newPattern.id,
41
+ } );
42
+
43
+ closeModal();
44
+ }
45
+
46
+ return (
47
+ <DuplicatePatternModal
48
+ onClose={ closeModal }
49
+ onSuccess={ onSuccess }
50
+ pattern={ record }
51
+ />
52
+ );
53
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import PatternRenameModal from './rename';
5
+ import PatternDuplicateModal from './duplicate';
6
+
7
+ export const PATTERN_MODALS = {
8
+ rename: 'edit-site/pattern-rename',
9
+ duplicate: 'edit-site/pattern-duplicate',
10
+ };
11
+
12
+ export default function PatternModal() {
13
+ return (
14
+ <>
15
+ <PatternDuplicateModal />
16
+ <PatternRenameModal />
17
+ </>
18
+ );
19
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useDispatch, useSelect } from '@wordpress/data';
5
+ import { store as interfaceStore } from '@wordpress/interface';
6
+ import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { PATTERN_MODALS } from './';
12
+ import { unlock } from '../../lock-unlock';
13
+ import useEditedEntityRecord from '../use-edited-entity-record';
14
+
15
+ const { RenamePatternModal } = unlock( patternsPrivateApis );
16
+
17
+ export default function PatternRenameModal() {
18
+ const { record: pattern } = useEditedEntityRecord();
19
+ const { closeModal } = useDispatch( interfaceStore );
20
+ const isActive = useSelect( ( select ) =>
21
+ select( interfaceStore ).isModalActive( PATTERN_MODALS.rename )
22
+ );
23
+
24
+ if ( ! isActive ) {
25
+ return null;
26
+ }
27
+
28
+ return <RenamePatternModal onClose={ closeModal } pattern={ pattern } />;
29
+ }
@@ -29,6 +29,7 @@ import { unlock } from '../../lock-unlock';
29
29
  import SidebarNavigationScreenPages from '../sidebar-navigation-screen-pages';
30
30
  import SidebarNavigationScreenPage from '../sidebar-navigation-screen-page';
31
31
  import SidebarNavigationScreen from '../sidebar-navigation-screen';
32
+ import DataViewsSidebarContent from '../sidebar-dataviews';
32
33
 
33
34
  const { useLocation } = unlock( routerPrivateApis );
34
35
 
@@ -61,6 +62,7 @@ function SidebarScreens() {
61
62
  title={ __( 'All Pages' ) }
62
63
  description={ __( 'Manage your pages.' ) }
63
64
  backPath="/page"
65
+ content={ <DataViewsSidebarContent /> }
64
66
  />
65
67
  </NavigatorScreen>
66
68
  ) }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __experimentalItemGroup as ItemGroup } from '@wordpress/components';
5
+ import { page, columns } from '@wordpress/icons';
6
+ import { privateApis as routerPrivateApis } from '@wordpress/router';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { useLink } from '../routes/link';
12
+ import { default as DEFAULT_VIEWS } from '../page-pages/default-views';
13
+ import { unlock } from '../../lock-unlock';
14
+ const { useLocation } = unlock( routerPrivateApis );
15
+ import SidebarNavigationItem from '../sidebar-navigation-item';
16
+
17
+ function getDataViewIcon( dataview ) {
18
+ const icons = { list: page, grid: columns };
19
+ return icons[ dataview.view.type ];
20
+ }
21
+
22
+ function DataViewItem( { dataview, isActive } ) {
23
+ const {
24
+ params: { path },
25
+ } = useLocation();
26
+
27
+ const icon = getDataViewIcon( dataview );
28
+
29
+ const linkInfo = useLink( {
30
+ path,
31
+ activeView: dataview.slug,
32
+ } );
33
+ return (
34
+ <SidebarNavigationItem
35
+ icon={ icon }
36
+ { ...linkInfo }
37
+ aria-current={ isActive ? 'true' : undefined }
38
+ >
39
+ { dataview.title }
40
+ </SidebarNavigationItem>
41
+ );
42
+ }
43
+
44
+ export default function DataViewsSidebarContent() {
45
+ const {
46
+ params: { path, activeView = 'all' },
47
+ } = useLocation();
48
+ if ( ! path || path !== '/pages' ) {
49
+ return null;
50
+ }
51
+
52
+ return (
53
+ <ItemGroup>
54
+ { DEFAULT_VIEWS.map( ( dataview ) => {
55
+ return (
56
+ <DataViewItem
57
+ key={ dataview.slug }
58
+ dataview={ dataview }
59
+ isActive={ dataview.slug === activeView }
60
+ />
61
+ );
62
+ } ) }
63
+ </ItemGroup>
64
+ );
65
+ }
@@ -31,6 +31,10 @@ const useRevisionData = () => {
31
31
  function PostLastRevisionCheck( { children } ) {
32
32
  const { lastRevisionId, revisionsCount } = useRevisionData();
33
33
 
34
+ if ( ! process.env.IS_GUTENBERG_PLUGIN ) {
35
+ return null;
36
+ }
37
+
34
38
  if ( ! lastRevisionId || revisionsCount < 2 ) {
35
39
  return null;
36
40
  }