@wordpress/edit-site 6.3.0 → 6.4.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 (221) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/add-new-pattern/index.js +8 -2
  3. package/build/components/add-new-pattern/index.js.map +1 -1
  4. package/build/components/add-new-template/index.js +3 -1
  5. package/build/components/add-new-template/index.js.map +1 -1
  6. package/build/components/block-editor/use-site-editor-settings.js +1 -82
  7. package/build/components/block-editor/use-site-editor-settings.js.map +1 -1
  8. package/build/components/global-styles/block-preview-panel.js +14 -5
  9. package/build/components/global-styles/block-preview-panel.js.map +1 -1
  10. package/build/components/global-styles/font-families.js +42 -23
  11. package/build/components/global-styles/font-families.js.map +1 -1
  12. package/build/components/global-styles/font-library-modal/index.js +4 -4
  13. package/build/components/global-styles/font-library-modal/index.js.map +1 -1
  14. package/build/components/global-styles/font-library-modal/installed-fonts.js +58 -10
  15. package/build/components/global-styles/font-library-modal/installed-fonts.js.map +1 -1
  16. package/build/components/global-styles/font-sizes/confirm-delete-font-size-dialog.js +39 -0
  17. package/build/components/global-styles/font-sizes/confirm-delete-font-size-dialog.js.map +1 -0
  18. package/build/components/global-styles/font-sizes/confirm-reset-font-sizes-dialog.js +39 -0
  19. package/build/components/global-styles/font-sizes/confirm-reset-font-sizes-dialog.js.map +1 -0
  20. package/build/components/global-styles/font-sizes/font-size-preview.js +44 -0
  21. package/build/components/global-styles/font-sizes/font-size-preview.js.map +1 -0
  22. package/build/components/global-styles/font-sizes/font-size.js +213 -0
  23. package/build/components/global-styles/font-sizes/font-size.js.map +1 -0
  24. package/build/components/global-styles/font-sizes/font-sizes-count.js +50 -0
  25. package/build/components/global-styles/font-sizes/font-sizes-count.js.map +1 -0
  26. package/build/components/global-styles/font-sizes/font-sizes.js +163 -0
  27. package/build/components/global-styles/font-sizes/font-sizes.js.map +1 -0
  28. package/build/components/global-styles/font-sizes/rename-font-size-dialog.js +67 -0
  29. package/build/components/global-styles/font-sizes/rename-font-size-dialog.js.map +1 -0
  30. package/build/components/global-styles/screen-block.js +10 -8
  31. package/build/components/global-styles/screen-block.js.map +1 -1
  32. package/build/components/global-styles/screen-style-variations.js +2 -2
  33. package/build/components/global-styles/screen-style-variations.js.map +1 -1
  34. package/build/components/global-styles/screen-typography.js +3 -2
  35. package/build/components/global-styles/screen-typography.js.map +1 -1
  36. package/build/components/global-styles/size-control/index.js +85 -0
  37. package/build/components/global-styles/size-control/index.js.map +1 -0
  38. package/build/components/global-styles/style-variations-container.js +3 -0
  39. package/build/components/global-styles/style-variations-container.js.map +1 -1
  40. package/build/components/global-styles/ui.js +8 -0
  41. package/build/components/global-styles/ui.js.map +1 -1
  42. package/build/components/global-styles/variations/variations-color.js.map +1 -1
  43. package/build/components/global-styles/variations/variations-typography.js +1 -1
  44. package/build/components/global-styles/variations/variations-typography.js.map +1 -1
  45. package/build/components/layout/index.js +6 -0
  46. package/build/components/layout/index.js.map +1 -1
  47. package/build/components/layout/router.js +14 -6
  48. package/build/components/layout/router.js.map +1 -1
  49. package/build/components/page-patterns/header.js +1 -1
  50. package/build/components/page-patterns/header.js.map +1 -1
  51. package/build/components/page-patterns/index.js +23 -11
  52. package/build/components/page-patterns/index.js.map +1 -1
  53. package/build/components/page-templates/index.js +41 -34
  54. package/build/components/page-templates/index.js.map +1 -1
  55. package/build/components/post-edit/index.js +105 -0
  56. package/build/components/post-edit/index.js.map +1 -0
  57. package/build/components/post-fields/index.js +314 -0
  58. package/build/components/post-fields/index.js.map +1 -0
  59. package/build/components/post-list/index.js +281 -0
  60. package/build/components/post-list/index.js.map +1 -0
  61. package/build/components/posts-app/router.js +3 -3
  62. package/build/components/posts-app/router.js.map +1 -1
  63. package/build/components/sidebar-dataviews/default-views.js +22 -10
  64. package/build/components/sidebar-dataviews/default-views.js.map +1 -1
  65. package/build/components/sidebar-dataviews/index.js +40 -1
  66. package/build/components/sidebar-dataviews/index.js.map +1 -1
  67. package/build/components/sidebar-navigation-screen-global-styles/content.js +64 -0
  68. package/build/components/sidebar-navigation-screen-global-styles/content.js.map +1 -0
  69. package/build/components/sidebar-navigation-screen-global-styles/index.js +2 -47
  70. package/build/components/sidebar-navigation-screen-global-styles/index.js.map +1 -1
  71. package/build/hooks/push-changes-to-global-styles/index.js +1 -1
  72. package/build/hooks/push-changes-to-global-styles/index.js.map +1 -1
  73. package/build/index.js +5 -1
  74. package/build/index.js.map +1 -1
  75. package/build/store/selectors.js +34 -6
  76. package/build/store/selectors.js.map +1 -1
  77. package/build/utils/get-filtered-template-parts.js +64 -0
  78. package/build/utils/get-filtered-template-parts.js.map +1 -0
  79. package/build-module/components/add-new-pattern/index.js +8 -2
  80. package/build-module/components/add-new-pattern/index.js.map +1 -1
  81. package/build-module/components/add-new-template/index.js +3 -1
  82. package/build-module/components/add-new-template/index.js.map +1 -1
  83. package/build-module/components/block-editor/use-site-editor-settings.js +1 -82
  84. package/build-module/components/block-editor/use-site-editor-settings.js.map +1 -1
  85. package/build-module/components/global-styles/block-preview-panel.js +14 -5
  86. package/build-module/components/global-styles/block-preview-panel.js.map +1 -1
  87. package/build-module/components/global-styles/font-families.js +44 -25
  88. package/build-module/components/global-styles/font-families.js.map +1 -1
  89. package/build-module/components/global-styles/font-library-modal/index.js +4 -4
  90. package/build-module/components/global-styles/font-library-modal/index.js.map +1 -1
  91. package/build-module/components/global-styles/font-library-modal/installed-fonts.js +61 -13
  92. package/build-module/components/global-styles/font-library-modal/installed-fonts.js.map +1 -1
  93. package/build-module/components/global-styles/font-sizes/confirm-delete-font-size-dialog.js +32 -0
  94. package/build-module/components/global-styles/font-sizes/confirm-delete-font-size-dialog.js.map +1 -0
  95. package/build-module/components/global-styles/font-sizes/confirm-reset-font-sizes-dialog.js +32 -0
  96. package/build-module/components/global-styles/font-sizes/confirm-reset-font-sizes-dialog.js.map +1 -0
  97. package/build-module/components/global-styles/font-sizes/font-size-preview.js +37 -0
  98. package/build-module/components/global-styles/font-sizes/font-size-preview.js.map +1 -0
  99. package/build-module/components/global-styles/font-sizes/font-size.js +207 -0
  100. package/build-module/components/global-styles/font-sizes/font-size.js.map +1 -0
  101. package/build-module/components/global-styles/font-sizes/font-sizes-count.js +43 -0
  102. package/build-module/components/global-styles/font-sizes/font-sizes-count.js.map +1 -0
  103. package/build-module/components/global-styles/font-sizes/font-sizes.js +157 -0
  104. package/build-module/components/global-styles/font-sizes/font-sizes.js.map +1 -0
  105. package/build-module/components/global-styles/font-sizes/rename-font-size-dialog.js +61 -0
  106. package/build-module/components/global-styles/font-sizes/rename-font-size-dialog.js.map +1 -0
  107. package/build-module/components/global-styles/screen-block.js +10 -8
  108. package/build-module/components/global-styles/screen-block.js.map +1 -1
  109. package/build-module/components/global-styles/screen-style-variations.js +2 -2
  110. package/build-module/components/global-styles/screen-style-variations.js.map +1 -1
  111. package/build-module/components/global-styles/screen-typography.js +3 -2
  112. package/build-module/components/global-styles/screen-typography.js.map +1 -1
  113. package/build-module/components/global-styles/size-control/index.js +79 -0
  114. package/build-module/components/global-styles/size-control/index.js.map +1 -0
  115. package/build-module/components/global-styles/style-variations-container.js +3 -0
  116. package/build-module/components/global-styles/style-variations-container.js.map +1 -1
  117. package/build-module/components/global-styles/ui.js +8 -0
  118. package/build-module/components/global-styles/ui.js.map +1 -1
  119. package/build-module/components/global-styles/variations/variations-color.js +1 -1
  120. package/build-module/components/global-styles/variations/variations-color.js.map +1 -1
  121. package/build-module/components/global-styles/variations/variations-typography.js +1 -2
  122. package/build-module/components/global-styles/variations/variations-typography.js.map +1 -1
  123. package/build-module/components/layout/index.js +6 -0
  124. package/build-module/components/layout/index.js.map +1 -1
  125. package/build-module/components/layout/router.js +14 -6
  126. package/build-module/components/layout/router.js.map +1 -1
  127. package/build-module/components/page-patterns/header.js +1 -1
  128. package/build-module/components/page-patterns/header.js.map +1 -1
  129. package/build-module/components/page-patterns/index.js +23 -11
  130. package/build-module/components/page-patterns/index.js.map +1 -1
  131. package/build-module/components/page-templates/index.js +43 -37
  132. package/build-module/components/page-templates/index.js.map +1 -1
  133. package/build-module/components/post-edit/index.js +98 -0
  134. package/build-module/components/post-edit/index.js.map +1 -0
  135. package/build-module/components/post-fields/index.js +306 -0
  136. package/build-module/components/post-fields/index.js.map +1 -0
  137. package/build-module/components/post-list/index.js +275 -0
  138. package/build-module/components/post-list/index.js.map +1 -0
  139. package/build-module/components/posts-app/router.js +3 -3
  140. package/build-module/components/posts-app/router.js.map +1 -1
  141. package/build-module/components/sidebar-dataviews/default-views.js +21 -9
  142. package/build-module/components/sidebar-dataviews/default-views.js.map +1 -1
  143. package/build-module/components/sidebar-dataviews/index.js +42 -3
  144. package/build-module/components/sidebar-dataviews/index.js.map +1 -1
  145. package/build-module/components/sidebar-navigation-screen-global-styles/content.js +57 -0
  146. package/build-module/components/sidebar-navigation-screen-global-styles/content.js.map +1 -0
  147. package/build-module/components/sidebar-navigation-screen-global-styles/index.js +2 -47
  148. package/build-module/components/sidebar-navigation-screen-global-styles/index.js.map +1 -1
  149. package/build-module/hooks/push-changes-to-global-styles/index.js +1 -1
  150. package/build-module/hooks/push-changes-to-global-styles/index.js.map +1 -1
  151. package/build-module/index.js +5 -1
  152. package/build-module/index.js.map +1 -1
  153. package/build-module/store/selectors.js +35 -7
  154. package/build-module/store/selectors.js.map +1 -1
  155. package/build-module/utils/get-filtered-template-parts.js +57 -0
  156. package/build-module/utils/get-filtered-template-parts.js.map +1 -0
  157. package/build-style/posts-rtl.css +581 -503
  158. package/build-style/posts.css +581 -503
  159. package/build-style/style-rtl.css +621 -519
  160. package/build-style/style.css +621 -519
  161. package/package.json +41 -41
  162. package/src/components/add-new-pattern/index.js +8 -2
  163. package/src/components/add-new-template/index.js +4 -1
  164. package/src/components/add-new-template/style.scss +4 -6
  165. package/src/components/block-editor/use-site-editor-settings.js +15 -111
  166. package/src/components/global-styles/block-preview-panel.js +22 -9
  167. package/src/components/global-styles/font-families.js +66 -31
  168. package/src/components/global-styles/font-library-modal/index.js +4 -2
  169. package/src/components/global-styles/font-library-modal/installed-fonts.js +92 -11
  170. package/src/components/global-styles/font-library-modal/style.scss +9 -0
  171. package/src/components/global-styles/font-sizes/confirm-delete-font-size-dialog.js +43 -0
  172. package/src/components/global-styles/font-sizes/confirm-reset-font-sizes-dialog.js +37 -0
  173. package/src/components/global-styles/font-sizes/font-size-preview.js +43 -0
  174. package/src/components/global-styles/font-sizes/font-size.js +250 -0
  175. package/src/components/global-styles/font-sizes/font-sizes-count.js +40 -0
  176. package/src/components/global-styles/font-sizes/font-sizes.js +263 -0
  177. package/src/components/global-styles/font-sizes/rename-font-size-dialog.js +70 -0
  178. package/src/components/global-styles/screen-block.js +12 -14
  179. package/src/components/global-styles/screen-style-variations.js +2 -2
  180. package/src/components/global-styles/screen-typography.js +3 -2
  181. package/src/components/global-styles/size-control/index.js +86 -0
  182. package/src/components/global-styles/style-variations-container.js +4 -0
  183. package/src/components/global-styles/style.scss +13 -3
  184. package/src/components/global-styles/ui.js +10 -0
  185. package/src/components/global-styles/variations/variations-color.js +1 -1
  186. package/src/components/global-styles/variations/variations-typography.js +1 -2
  187. package/src/components/layout/index.js +11 -0
  188. package/src/components/layout/router.js +13 -5
  189. package/src/components/layout/style.scss +26 -8
  190. package/src/components/page-patterns/header.js +1 -1
  191. package/src/components/page-patterns/index.js +15 -8
  192. package/src/components/page-templates/index.js +51 -46
  193. package/src/components/page-templates/style.scss +5 -3
  194. package/src/components/post-edit/index.js +96 -0
  195. package/src/components/post-edit/style.scss +9 -0
  196. package/src/components/post-fields/index.js +345 -0
  197. package/src/components/post-list/index.js +326 -0
  198. package/src/components/{posts-app → post-list}/style.scss +12 -9
  199. package/src/components/posts-app/router.js +3 -3
  200. package/src/components/sidebar-dataviews/default-views.js +21 -9
  201. package/src/components/sidebar-dataviews/index.js +36 -1
  202. package/src/components/sidebar-navigation-screen-global-styles/content.js +55 -0
  203. package/src/components/sidebar-navigation-screen-global-styles/index.js +1 -55
  204. package/src/hooks/push-changes-to-global-styles/index.js +1 -1
  205. package/src/index.js +7 -1
  206. package/src/posts.scss +1 -1
  207. package/src/store/selectors.js +53 -14
  208. package/src/store/test/selectors.js +1 -26
  209. package/src/style.scss +2 -1
  210. package/src/utils/get-filtered-template-parts.js +61 -0
  211. package/src/utils/test/get-filtered-template-parts.js +127 -0
  212. package/build/components/global-styles/screen-background.js +0 -36
  213. package/build/components/global-styles/screen-background.js.map +0 -1
  214. package/build/components/posts-app/posts-list.js +0 -568
  215. package/build/components/posts-app/posts-list.js.map +0 -1
  216. package/build-module/components/global-styles/screen-background.js +0 -30
  217. package/build-module/components/global-styles/screen-background.js.map +0 -1
  218. package/build-module/components/posts-app/posts-list.js +0 -560
  219. package/build-module/components/posts-app/posts-list.js.map +0 -1
  220. package/src/components/global-styles/screen-background.js +0 -29
  221. package/src/components/posts-app/posts-list.js +0 -651
@@ -1,651 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import clsx from 'clsx';
5
-
6
- /**
7
- * WordPress dependencies
8
- */
9
- import {
10
- Button,
11
- __experimentalHStack as HStack,
12
- Icon,
13
- } from '@wordpress/components';
14
- import { __, sprintf } from '@wordpress/i18n';
15
- import { useEntityRecords, store as coreStore } from '@wordpress/core-data';
16
- import { decodeEntities } from '@wordpress/html-entities';
17
- import {
18
- createInterpolateElement,
19
- useState,
20
- useMemo,
21
- useCallback,
22
- useEffect,
23
- } from '@wordpress/element';
24
- import { dateI18n, getDate, getSettings } from '@wordpress/date';
25
- import { privateApis as routerPrivateApis } from '@wordpress/router';
26
- import { useSelect, useDispatch } from '@wordpress/data';
27
- import { DataViews } from '@wordpress/dataviews';
28
- import { privateApis as editorPrivateApis } from '@wordpress/editor';
29
- import {
30
- trash,
31
- drafts,
32
- published,
33
- scheduled,
34
- pending,
35
- notAllowed,
36
- commentAuthorAvatar as authorIcon,
37
- } from '@wordpress/icons';
38
-
39
- /**
40
- * Internal dependencies
41
- */
42
- import Page from '../page';
43
- import { default as Link, useLink } from '../routes/link';
44
- import {
45
- useDefaultViews,
46
- DEFAULT_CONFIG_PER_VIEW_TYPE,
47
- } from '../sidebar-dataviews/default-views';
48
- import {
49
- LAYOUT_GRID,
50
- LAYOUT_TABLE,
51
- LAYOUT_LIST,
52
- OPERATOR_IS_ANY,
53
- OPERATOR_IS_NONE,
54
- } from '../../utils/constants';
55
-
56
- import AddNewPostModal from '../add-new-post';
57
- import Media from '../media';
58
- import { unlock } from '../../lock-unlock';
59
- import { useEditPostAction } from '../dataviews-actions';
60
- import { usePrevious } from '@wordpress/compose';
61
-
62
- const { usePostActions } = unlock( editorPrivateApis );
63
- const { useLocation, useHistory } = unlock( routerPrivateApis );
64
- const EMPTY_ARRAY = [];
65
-
66
- const getFormattedDate = ( dateToDisplay ) =>
67
- dateI18n(
68
- getSettings().formats.datetimeAbbreviated,
69
- getDate( dateToDisplay )
70
- );
71
-
72
- function useView( postType ) {
73
- const {
74
- params: { activeView = 'all', isCustom = 'false', layout },
75
- } = useLocation();
76
- const history = useHistory();
77
- const DEFAULT_VIEWS = useDefaultViews( { postType } );
78
- const selectedDefaultView = useMemo( () => {
79
- const defaultView =
80
- isCustom === 'false' &&
81
- DEFAULT_VIEWS[ postType ].find(
82
- ( { slug } ) => slug === activeView
83
- )?.view;
84
- if ( isCustom === 'false' && layout ) {
85
- return {
86
- ...defaultView,
87
- type: layout,
88
- layout: {
89
- ...( DEFAULT_CONFIG_PER_VIEW_TYPE[ layout ] || {} ),
90
- },
91
- };
92
- }
93
- return defaultView;
94
- }, [ isCustom, activeView, layout, postType, DEFAULT_VIEWS ] );
95
- const [ view, setView ] = useState( selectedDefaultView );
96
-
97
- useEffect( () => {
98
- if ( selectedDefaultView ) {
99
- setView( selectedDefaultView );
100
- }
101
- }, [ selectedDefaultView ] );
102
- const editedViewRecord = useSelect(
103
- ( select ) => {
104
- if ( isCustom !== 'true' ) {
105
- return;
106
- }
107
- const { getEditedEntityRecord } = select( coreStore );
108
- const dataviewRecord = getEditedEntityRecord(
109
- 'postType',
110
- 'wp_dataviews',
111
- Number( activeView )
112
- );
113
- return dataviewRecord;
114
- },
115
- [ activeView, isCustom ]
116
- );
117
- const { editEntityRecord } = useDispatch( coreStore );
118
-
119
- const customView = useMemo( () => {
120
- const storedView =
121
- editedViewRecord?.content &&
122
- JSON.parse( editedViewRecord?.content );
123
- if ( ! storedView ) {
124
- return storedView;
125
- }
126
-
127
- return {
128
- ...storedView,
129
- layout: {
130
- ...( DEFAULT_CONFIG_PER_VIEW_TYPE[ storedView?.type ] || {} ),
131
- },
132
- };
133
- }, [ editedViewRecord?.content ] );
134
-
135
- const setCustomView = useCallback(
136
- ( viewToSet ) => {
137
- editEntityRecord(
138
- 'postType',
139
- 'wp_dataviews',
140
- editedViewRecord?.id,
141
- {
142
- content: JSON.stringify( viewToSet ),
143
- }
144
- );
145
- },
146
- [ editEntityRecord, editedViewRecord?.id ]
147
- );
148
-
149
- const setDefaultViewAndUpdateUrl = useCallback(
150
- ( viewToSet ) => {
151
- if ( viewToSet.type !== view?.type ) {
152
- const { params } = history.getLocationWithParams();
153
- history.push( {
154
- ...params,
155
- layout: viewToSet.type,
156
- } );
157
- }
158
- setView( viewToSet );
159
- },
160
- [ history, view?.type ]
161
- );
162
-
163
- if ( isCustom === 'false' ) {
164
- return [ view, setDefaultViewAndUpdateUrl ];
165
- } else if ( isCustom === 'true' && customView ) {
166
- return [ customView, setCustomView ];
167
- }
168
- // Loading state where no the view was not found on custom views or default views.
169
- return [ DEFAULT_VIEWS[ postType ][ 0 ].view, setDefaultViewAndUpdateUrl ];
170
- }
171
-
172
- // See https://github.com/WordPress/gutenberg/issues/55886
173
- // We do not support custom statutes at the moment.
174
- const STATUSES = [
175
- { value: 'draft', label: __( 'Draft' ), icon: drafts },
176
- { value: 'future', label: __( 'Scheduled' ), icon: scheduled },
177
- { value: 'pending', label: __( 'Pending Review' ), icon: pending },
178
- { value: 'private', label: __( 'Private' ), icon: notAllowed },
179
- { value: 'publish', label: __( 'Published' ), icon: published },
180
- { value: 'trash', label: __( 'Trash' ), icon: trash },
181
- ];
182
- const DEFAULT_STATUSES = 'draft,future,pending,private,publish'; // All but 'trash'.
183
-
184
- function FeaturedImage( { item, viewType } ) {
185
- const isDisabled = item.status === 'trash';
186
- const { onClick } = useLink( {
187
- postId: item.id,
188
- postType: item.type,
189
- canvas: 'edit',
190
- } );
191
- const hasMedia = !! item.featured_media;
192
- const size =
193
- viewType === LAYOUT_GRID
194
- ? [ 'large', 'full', 'medium', 'thumbnail' ]
195
- : [ 'thumbnail', 'medium', 'large', 'full' ];
196
- const media = hasMedia ? (
197
- <Media
198
- className="posts-list-page__featured-image"
199
- id={ item.featured_media }
200
- size={ size }
201
- />
202
- ) : null;
203
- const renderButton = viewType !== LAYOUT_LIST && ! isDisabled;
204
- return (
205
- <div
206
- className={ `posts-list-page__featured-image-wrapper is-layout-${ viewType }` }
207
- >
208
- { renderButton ? (
209
- <button
210
- className="posts-list-page-preview-field__button"
211
- type="button"
212
- onClick={ onClick }
213
- aria-label={ item.title?.rendered || __( '(no title)' ) }
214
- >
215
- { media }
216
- </button>
217
- ) : (
218
- media
219
- ) }
220
- </div>
221
- );
222
- }
223
-
224
- function getItemId( item ) {
225
- return item.id.toString();
226
- }
227
-
228
- function PostStatusField( { item } ) {
229
- const status = STATUSES.find( ( { value } ) => value === item.status );
230
- const label = status?.label || item.status;
231
- const icon = status?.icon;
232
- return (
233
- <HStack alignment="left" spacing={ 1 }>
234
- { icon && (
235
- <div className="posts-list-page-post-author-field__icon-container">
236
- <Icon icon={ icon } />
237
- </div>
238
- ) }
239
- <span>{ label }</span>
240
- </HStack>
241
- );
242
- }
243
-
244
- function PostAuthorField( { item, viewType } ) {
245
- const { text, icon, imageUrl } = useSelect(
246
- ( select ) => {
247
- const { getUser } = select( coreStore );
248
- const user = getUser( item.author );
249
- return {
250
- icon: authorIcon,
251
- imageUrl: user?.avatar_urls?.[ 48 ],
252
- text: user?.name,
253
- };
254
- },
255
- [ item ]
256
- );
257
-
258
- const withAuthorImage = viewType !== LAYOUT_LIST && imageUrl;
259
- const withAuthorIcon = viewType !== LAYOUT_LIST && ! imageUrl;
260
- const [ isImageLoaded, setIsImageLoaded ] = useState( false );
261
- return (
262
- <HStack alignment="left" spacing={ 1 }>
263
- { withAuthorImage && (
264
- <div
265
- className={ clsx( 'page-templates-author-field__avatar', {
266
- 'is-loaded': isImageLoaded,
267
- } ) }
268
- >
269
- <img
270
- onLoad={ () => setIsImageLoaded( true ) }
271
- alt={ __( 'Author avatar' ) }
272
- src={ imageUrl }
273
- />
274
- </div>
275
- ) }
276
- { withAuthorIcon && (
277
- <div className="page-templates-author-field__icon">
278
- <Icon icon={ icon } />
279
- </div>
280
- ) }
281
- <span className="page-templates-author-field__name">{ text }</span>
282
- </HStack>
283
- );
284
- }
285
-
286
- export default function PostsList( { postType } ) {
287
- const [ view, setView ] = useView( postType );
288
- const history = useHistory();
289
- const {
290
- params: { postId },
291
- } = useLocation();
292
- const [ selection, setSelection ] = useState( [ postId ] );
293
- const onSelectionChange = useCallback(
294
- ( items ) => {
295
- const { params } = history.getLocationWithParams();
296
- if (
297
- ( params.isCustom ?? 'false' ) === 'false' &&
298
- view?.type === LAYOUT_LIST
299
- ) {
300
- history.push( {
301
- ...params,
302
- postId: items.length === 1 ? items[ 0 ].id : undefined,
303
- } );
304
- }
305
- },
306
- [ history, view?.type ]
307
- );
308
-
309
- const queryArgs = useMemo( () => {
310
- const filters = {};
311
- view.filters.forEach( ( filter ) => {
312
- if (
313
- filter.field === 'status' &&
314
- filter.operator === OPERATOR_IS_ANY
315
- ) {
316
- filters.status = filter.value;
317
- }
318
- if (
319
- filter.field === 'author' &&
320
- filter.operator === OPERATOR_IS_ANY
321
- ) {
322
- filters.author = filter.value;
323
- } else if (
324
- filter.field === 'author' &&
325
- filter.operator === OPERATOR_IS_NONE
326
- ) {
327
- filters.author_exclude = filter.value;
328
- }
329
- } );
330
- // We want to provide a different default item for the status filter
331
- // than the REST API provides.
332
- if ( ! filters.status || filters.status === '' ) {
333
- filters.status = DEFAULT_STATUSES;
334
- }
335
-
336
- return {
337
- per_page: view.perPage,
338
- page: view.page,
339
- _embed: 'author',
340
- order: view.sort?.direction,
341
- orderby: view.sort?.field,
342
- search: view.search,
343
- ...filters,
344
- };
345
- }, [ view ] );
346
- const {
347
- records,
348
- isResolving: isLoadingMainEntities,
349
- totalItems,
350
- totalPages,
351
- } = useEntityRecords( 'postType', postType, queryArgs );
352
-
353
- const ids = records?.map( ( record ) => getItemId( record ) ) ?? [];
354
- const prevIds = usePrevious( ids ) ?? [];
355
- const deletedIds = prevIds.filter( ( id ) => ! ids.includes( id ) );
356
- const postIdWasDeleted = deletedIds.includes( postId );
357
-
358
- useEffect( () => {
359
- if ( postIdWasDeleted ) {
360
- history.push( {
361
- ...history.getLocationWithParams().params,
362
- postId: undefined,
363
- } );
364
- }
365
- }, [ postIdWasDeleted, history ] );
366
-
367
- const { records: authors, isResolving: isLoadingAuthors } =
368
- useEntityRecords( 'root', 'user', { per_page: -1 } );
369
-
370
- const paginationInfo = useMemo(
371
- () => ( {
372
- totalItems,
373
- totalPages,
374
- } ),
375
- [ totalItems, totalPages ]
376
- );
377
-
378
- const { frontPageId, postsPageId, labels, canCreateRecord } = useSelect(
379
- ( select ) => {
380
- const { getEntityRecord, getPostType, canUser } =
381
- select( coreStore );
382
- const siteSettings = getEntityRecord( 'root', 'site' );
383
- const postTypeObject = getPostType( postType );
384
- return {
385
- frontPageId: siteSettings?.page_on_front,
386
- postsPageId: siteSettings?.page_for_posts,
387
- labels: getPostType( postType )?.labels,
388
- canCreateRecord: canUser(
389
- 'create',
390
- postTypeObject?.rest_base || 'posts'
391
- ),
392
- };
393
- },
394
- [ postType ]
395
- );
396
-
397
- // TODO: this should be abstracted into a hook similar to `usePostActions`.
398
- const fields = useMemo(
399
- () => [
400
- {
401
- id: 'featured-image',
402
- header: __( 'Featured Image' ),
403
- getValue: ( { item } ) => item.featured_media,
404
- render: ( { item } ) => (
405
- <FeaturedImage item={ item } viewType={ view.type } />
406
- ),
407
- enableSorting: false,
408
- width: '1%',
409
- },
410
- {
411
- header: __( 'Title' ),
412
- id: 'title',
413
- getValue: ( { item } ) => item.title?.rendered,
414
- render: ( { item } ) => {
415
- const addLink =
416
- [ LAYOUT_TABLE, LAYOUT_GRID ].includes( view.type ) &&
417
- item.status !== 'trash';
418
- const title = addLink ? (
419
- <Link
420
- params={ {
421
- postId: item.id,
422
- postType: item.type,
423
- canvas: 'edit',
424
- } }
425
- >
426
- { decodeEntities( item.title?.rendered ) ||
427
- __( '(no title)' ) }
428
- </Link>
429
- ) : (
430
- <span>
431
- { decodeEntities( item.title?.rendered ) ||
432
- __( '(no title)' ) }
433
- </span>
434
- );
435
-
436
- let suffix = '';
437
- if ( item.id === frontPageId ) {
438
- suffix = (
439
- <span className="posts-list-page-title-badge">
440
- { __( 'Front Page' ) }
441
- </span>
442
- );
443
- } else if ( item.id === postsPageId ) {
444
- suffix = (
445
- <span className="posts-list-page-title-badge">
446
- { __( 'Posts Page' ) }
447
- </span>
448
- );
449
- }
450
-
451
- return (
452
- <HStack
453
- className="posts-list-page-title"
454
- alignment="center"
455
- justify="flex-start"
456
- >
457
- { title }
458
- { suffix }
459
- </HStack>
460
- );
461
- },
462
- maxWidth: 300,
463
- enableHiding: false,
464
- },
465
- {
466
- header: __( 'Author' ),
467
- id: 'author',
468
- getValue: ( { item } ) => item._embedded?.author[ 0 ]?.name,
469
- elements:
470
- authors?.map( ( { id, name } ) => ( {
471
- value: id,
472
- label: name,
473
- } ) ) || [],
474
- render: ( { item } ) => {
475
- return (
476
- <PostAuthorField viewType={ view.type } item={ item } />
477
- );
478
- },
479
- },
480
- {
481
- header: __( 'Status' ),
482
- id: 'status',
483
- getValue: ( { item } ) =>
484
- STATUSES.find( ( { value } ) => value === item.status )
485
- ?.label ?? item.status,
486
- elements: STATUSES,
487
- render: PostStatusField,
488
- enableSorting: false,
489
- filterBy: {
490
- operators: [ OPERATOR_IS_ANY ],
491
- },
492
- },
493
- {
494
- header: __( 'Date' ),
495
- id: 'date',
496
- render: ( { item } ) => {
497
- const isDraftOrPrivate = [ 'draft', 'private' ].includes(
498
- item.status
499
- );
500
- if ( isDraftOrPrivate ) {
501
- return createInterpolateElement(
502
- sprintf(
503
- /* translators: %s: page creation date */
504
- __( '<span>Modified: <time>%s</time></span>' ),
505
- getFormattedDate( item.date )
506
- ),
507
- {
508
- span: <span />,
509
- time: <time />,
510
- }
511
- );
512
- }
513
-
514
- const isScheduled = item.status === 'future';
515
- if ( isScheduled ) {
516
- return createInterpolateElement(
517
- sprintf(
518
- /* translators: %s: page creation date */
519
- __( '<span>Scheduled: <time>%s</time></span>' ),
520
- getFormattedDate( item.date )
521
- ),
522
- {
523
- span: <span />,
524
- time: <time />,
525
- }
526
- );
527
- }
528
-
529
- // Pending & Published posts show the modified date if it's newer.
530
- const dateToDisplay =
531
- getDate( item.modified ) > getDate( item.date )
532
- ? item.modified
533
- : item.date;
534
-
535
- const isPending = item.status === 'pending';
536
- if ( isPending ) {
537
- return createInterpolateElement(
538
- sprintf(
539
- /* translators: %s: the newest of created or modified date for the page */
540
- __( '<span>Modified: <time>%s</time></span>' ),
541
- getFormattedDate( dateToDisplay )
542
- ),
543
- {
544
- span: <span />,
545
- time: <time />,
546
- }
547
- );
548
- }
549
-
550
- const isPublished = item.status === 'publish';
551
- if ( isPublished ) {
552
- return createInterpolateElement(
553
- sprintf(
554
- /* translators: %s: the newest of created or modified date for the page */
555
- __( '<span>Published: <time>%s</time></span>' ),
556
- getFormattedDate( dateToDisplay )
557
- ),
558
- {
559
- span: <span />,
560
- time: <time />,
561
- }
562
- );
563
- }
564
-
565
- // Unknow status.
566
- return <time>{ getFormattedDate( item.date ) }</time>;
567
- },
568
- },
569
- ],
570
- [ authors, view.type, frontPageId, postsPageId ]
571
- );
572
- const postTypeActions = usePostActions( {
573
- postType,
574
- context: 'list',
575
- } );
576
- const editAction = useEditPostAction();
577
- const actions = useMemo(
578
- () => [ editAction, ...postTypeActions ],
579
- [ postTypeActions, editAction ]
580
- );
581
-
582
- const onChangeView = useCallback(
583
- ( newView ) => {
584
- if ( newView.type !== view.type ) {
585
- newView = {
586
- ...newView,
587
- layout: {
588
- ...DEFAULT_CONFIG_PER_VIEW_TYPE[ newView.type ],
589
- },
590
- };
591
- }
592
-
593
- setView( newView );
594
- },
595
- [ view.type, setView ]
596
- );
597
-
598
- const [ showAddPostModal, setShowAddPostModal ] = useState( false );
599
-
600
- const openModal = () => setShowAddPostModal( true );
601
- const closeModal = () => setShowAddPostModal( false );
602
- const handleNewPage = ( { type, id } ) => {
603
- history.push( {
604
- postId: id,
605
- postType: type,
606
- canvas: 'edit',
607
- } );
608
- closeModal();
609
- };
610
-
611
- return (
612
- <Page
613
- title={ labels?.name }
614
- actions={
615
- labels?.add_new_item &&
616
- canCreateRecord && (
617
- <>
618
- <Button
619
- variant="primary"
620
- onClick={ openModal }
621
- __next40pxDefaultSize
622
- >
623
- { labels.add_new_item }
624
- </Button>
625
- { showAddPostModal && (
626
- <AddNewPostModal
627
- postType={ postType }
628
- onSave={ handleNewPage }
629
- onClose={ closeModal }
630
- />
631
- ) }
632
- </>
633
- )
634
- }
635
- >
636
- <DataViews
637
- paginationInfo={ paginationInfo }
638
- fields={ fields }
639
- actions={ actions }
640
- data={ records || EMPTY_ARRAY }
641
- isLoading={ isLoadingMainEntities || isLoadingAuthors }
642
- view={ view }
643
- onChangeView={ onChangeView }
644
- selection={ selection }
645
- setSelection={ setSelection }
646
- onSelectionChange={ onSelectionChange }
647
- getItemId={ getItemId }
648
- />
649
- </Page>
650
- );
651
- }