@wordpress/edit-site 6.4.0 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/add-new-pattern/index.js +6 -1
  3. package/build/components/add-new-pattern/index.js.map +1 -1
  4. package/build/components/add-new-post/index.js +2 -1
  5. package/build/components/add-new-post/index.js.map +1 -1
  6. package/build/components/add-new-template/utils.js +2 -2
  7. package/build/components/add-new-template/utils.js.map +1 -1
  8. package/build/components/editor/index.js +71 -20
  9. package/build/components/editor/index.js.map +1 -1
  10. package/build/components/global-styles/background-panel.js +1 -4
  11. package/build/components/global-styles/background-panel.js.map +1 -1
  12. package/build/components/global-styles/font-families.js +3 -4
  13. package/build/components/global-styles/font-families.js.map +1 -1
  14. package/build/components/global-styles/font-library-modal/context.js +0 -5
  15. package/build/components/global-styles/font-library-modal/context.js.map +1 -1
  16. package/build/components/global-styles/font-library-modal/font-collection.js +25 -5
  17. package/build/components/global-styles/font-library-modal/font-collection.js.map +1 -1
  18. package/build/components/global-styles/font-library-modal/index.js +1 -8
  19. package/build/components/global-styles/font-library-modal/index.js.map +1 -1
  20. package/build/components/global-styles/font-library-modal/installed-fonts.js +23 -7
  21. package/build/components/global-styles/font-library-modal/installed-fonts.js.map +1 -1
  22. package/build/components/global-styles/font-library-modal/upload-fonts.js +2 -3
  23. package/build/components/global-styles/font-library-modal/upload-fonts.js.map +1 -1
  24. package/build/components/global-styles/screen-block.js +5 -7
  25. package/build/components/global-styles/screen-block.js.map +1 -1
  26. package/build/components/global-styles/screen-css.js +1 -1
  27. package/build/components/global-styles/screen-css.js.map +1 -1
  28. package/build/components/global-styles/screen-typeset.js +40 -0
  29. package/build/components/global-styles/screen-typeset.js.map +1 -0
  30. package/build/components/global-styles/screen-typography-element.js +14 -0
  31. package/build/components/global-styles/screen-typography-element.js.map +1 -1
  32. package/build/components/global-styles/screen-typography.js +4 -6
  33. package/build/components/global-styles/screen-typography.js.map +1 -1
  34. package/build/components/global-styles/shadows-edit-panel.js +51 -59
  35. package/build/components/global-styles/shadows-edit-panel.js.map +1 -1
  36. package/build/components/global-styles/size-control/index.js +10 -5
  37. package/build/components/global-styles/size-control/index.js.map +1 -1
  38. package/build/components/global-styles/typeset-button.js +97 -0
  39. package/build/components/global-styles/typeset-button.js.map +1 -0
  40. package/build/components/global-styles/typeset.js +80 -0
  41. package/build/components/global-styles/typeset.js.map +1 -0
  42. package/build/components/global-styles/ui.js +4 -0
  43. package/build/components/global-styles/ui.js.map +1 -1
  44. package/build/components/global-styles/utils.js +10 -1
  45. package/build/components/global-styles/utils.js.map +1 -1
  46. package/build/components/page-patterns/fields.js +230 -0
  47. package/build/components/page-patterns/fields.js.map +1 -0
  48. package/build/components/page-patterns/index.js +13 -228
  49. package/build/components/page-patterns/index.js.map +1 -1
  50. package/build/components/page-patterns/use-patterns.js +29 -1
  51. package/build/components/page-patterns/use-patterns.js.map +1 -1
  52. package/build/components/page-templates/fields.js +169 -0
  53. package/build/components/page-templates/fields.js.map +1 -0
  54. package/build/components/page-templates/index.js +10 -177
  55. package/build/components/page-templates/index.js.map +1 -1
  56. package/build/components/post-edit/index.js +46 -34
  57. package/build/components/post-edit/index.js.map +1 -1
  58. package/build/components/post-fields/index.js +50 -28
  59. package/build/components/post-fields/index.js.map +1 -1
  60. package/build/components/post-list/index.js +126 -68
  61. package/build/components/post-list/index.js.map +1 -1
  62. package/build/components/sidebar-dataviews/add-new-view.js +3 -2
  63. package/build/components/sidebar-dataviews/add-new-view.js.map +1 -1
  64. package/build/components/sidebar-dataviews/custom-dataviews-list.js +1 -0
  65. package/build/components/sidebar-dataviews/custom-dataviews-list.js.map +1 -1
  66. package/build/components/sidebar-dataviews/dataview-item.js +2 -3
  67. package/build/components/sidebar-dataviews/dataview-item.js.map +1 -1
  68. package/build/components/sidebar-dataviews/default-views.js +81 -81
  69. package/build/components/sidebar-dataviews/default-views.js.map +1 -1
  70. package/build/components/sidebar-dataviews/index.js +3 -42
  71. package/build/components/sidebar-dataviews/index.js.map +1 -1
  72. package/build/components/site-hub/index.js +6 -3
  73. package/build/components/site-hub/index.js.map +1 -1
  74. package/build/components/style-book/index.js +22 -25
  75. package/build/components/style-book/index.js.map +1 -1
  76. package/build/components/sync-state-with-url/use-init-edited-entity-from-url.js +5 -0
  77. package/build/components/sync-state-with-url/use-init-edited-entity-from-url.js.map +1 -1
  78. package/build/hooks/push-changes-to-global-styles/index.js +3 -3
  79. package/build/hooks/push-changes-to-global-styles/index.js.map +1 -1
  80. package/build/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +2 -4
  81. package/build/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js.map +1 -1
  82. package/build/index.js +0 -2
  83. package/build/index.js.map +1 -1
  84. package/build/utils/is-template-removable.js +2 -2
  85. package/build/utils/is-template-removable.js.map +1 -1
  86. package/build/utils/is-template-revertable.js +1 -1
  87. package/build/utils/is-template-revertable.js.map +1 -1
  88. package/build-module/components/add-new-pattern/index.js +6 -1
  89. package/build-module/components/add-new-pattern/index.js.map +1 -1
  90. package/build-module/components/add-new-post/index.js +2 -1
  91. package/build-module/components/add-new-post/index.js.map +1 -1
  92. package/build-module/components/add-new-template/utils.js +2 -2
  93. package/build-module/components/add-new-template/utils.js.map +1 -1
  94. package/build-module/components/editor/index.js +73 -22
  95. package/build-module/components/editor/index.js.map +1 -1
  96. package/build-module/components/global-styles/background-panel.js +1 -4
  97. package/build-module/components/global-styles/background-panel.js.map +1 -1
  98. package/build-module/components/global-styles/font-families.js +3 -4
  99. package/build-module/components/global-styles/font-families.js.map +1 -1
  100. package/build-module/components/global-styles/font-library-modal/context.js +0 -5
  101. package/build-module/components/global-styles/font-library-modal/context.js.map +1 -1
  102. package/build-module/components/global-styles/font-library-modal/font-collection.js +26 -6
  103. package/build-module/components/global-styles/font-library-modal/font-collection.js.map +1 -1
  104. package/build-module/components/global-styles/font-library-modal/index.js +1 -8
  105. package/build-module/components/global-styles/font-library-modal/index.js.map +1 -1
  106. package/build-module/components/global-styles/font-library-modal/installed-fonts.js +23 -7
  107. package/build-module/components/global-styles/font-library-modal/installed-fonts.js.map +1 -1
  108. package/build-module/components/global-styles/font-library-modal/upload-fonts.js +2 -3
  109. package/build-module/components/global-styles/font-library-modal/upload-fonts.js.map +1 -1
  110. package/build-module/components/global-styles/screen-block.js +5 -7
  111. package/build-module/components/global-styles/screen-block.js.map +1 -1
  112. package/build-module/components/global-styles/screen-css.js +1 -1
  113. package/build-module/components/global-styles/screen-css.js.map +1 -1
  114. package/build-module/components/global-styles/screen-typeset.js +34 -0
  115. package/build-module/components/global-styles/screen-typeset.js.map +1 -0
  116. package/build-module/components/global-styles/screen-typography-element.js +14 -0
  117. package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
  118. package/build-module/components/global-styles/screen-typography.js +4 -6
  119. package/build-module/components/global-styles/screen-typography.js.map +1 -1
  120. package/build-module/components/global-styles/shadows-edit-panel.js +52 -60
  121. package/build-module/components/global-styles/shadows-edit-panel.js.map +1 -1
  122. package/build-module/components/global-styles/size-control/index.js +10 -5
  123. package/build-module/components/global-styles/size-control/index.js.map +1 -1
  124. package/build-module/components/global-styles/typeset-button.js +89 -0
  125. package/build-module/components/global-styles/typeset-button.js.map +1 -0
  126. package/build-module/components/global-styles/typeset.js +71 -0
  127. package/build-module/components/global-styles/typeset.js.map +1 -0
  128. package/build-module/components/global-styles/ui.js +4 -0
  129. package/build-module/components/global-styles/ui.js.map +1 -1
  130. package/build-module/components/global-styles/utils.js +10 -1
  131. package/build-module/components/global-styles/utils.js.map +1 -1
  132. package/build-module/components/page-patterns/fields.js +223 -0
  133. package/build-module/components/page-patterns/fields.js.map +1 -0
  134. package/build-module/components/page-patterns/index.js +14 -231
  135. package/build-module/components/page-patterns/index.js.map +1 -1
  136. package/build-module/components/page-patterns/use-patterns.js +26 -0
  137. package/build-module/components/page-patterns/use-patterns.js.map +1 -1
  138. package/build-module/components/page-templates/fields.js +160 -0
  139. package/build-module/components/page-templates/fields.js.map +1 -0
  140. package/build-module/components/page-templates/index.js +12 -178
  141. package/build-module/components/page-templates/index.js.map +1 -1
  142. package/build-module/components/post-edit/index.js +49 -37
  143. package/build-module/components/post-edit/index.js.map +1 -1
  144. package/build-module/components/post-fields/index.js +50 -28
  145. package/build-module/components/post-fields/index.js.map +1 -1
  146. package/build-module/components/post-list/index.js +128 -70
  147. package/build-module/components/post-list/index.js.map +1 -1
  148. package/build-module/components/sidebar-dataviews/add-new-view.js +3 -2
  149. package/build-module/components/sidebar-dataviews/add-new-view.js.map +1 -1
  150. package/build-module/components/sidebar-dataviews/custom-dataviews-list.js +1 -0
  151. package/build-module/components/sidebar-dataviews/custom-dataviews-list.js.map +1 -1
  152. package/build-module/components/sidebar-dataviews/dataview-item.js +2 -3
  153. package/build-module/components/sidebar-dataviews/dataview-item.js.map +1 -1
  154. package/build-module/components/sidebar-dataviews/default-views.js +81 -81
  155. package/build-module/components/sidebar-dataviews/default-views.js.map +1 -1
  156. package/build-module/components/sidebar-dataviews/index.js +3 -42
  157. package/build-module/components/sidebar-dataviews/index.js.map +1 -1
  158. package/build-module/components/site-hub/index.js +7 -4
  159. package/build-module/components/site-hub/index.js.map +1 -1
  160. package/build-module/components/style-book/index.js +23 -26
  161. package/build-module/components/style-book/index.js.map +1 -1
  162. package/build-module/components/sync-state-with-url/use-init-edited-entity-from-url.js +5 -0
  163. package/build-module/components/sync-state-with-url/use-init-edited-entity-from-url.js.map +1 -1
  164. package/build-module/hooks/push-changes-to-global-styles/index.js +3 -3
  165. package/build-module/hooks/push-changes-to-global-styles/index.js.map +1 -1
  166. package/build-module/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +2 -3
  167. package/build-module/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js.map +1 -1
  168. package/build-module/index.js +0 -2
  169. package/build-module/index.js.map +1 -1
  170. package/build-module/utils/is-template-removable.js +2 -2
  171. package/build-module/utils/is-template-removable.js.map +1 -1
  172. package/build-module/utils/is-template-revertable.js +1 -1
  173. package/build-module/utils/is-template-revertable.js.map +1 -1
  174. package/build-style/posts-rtl.css +201 -25
  175. package/build-style/posts.css +201 -25
  176. package/build-style/style-rtl.css +307 -69
  177. package/build-style/style.css +307 -69
  178. package/package.json +41 -41
  179. package/src/components/add-new-pattern/index.js +8 -3
  180. package/src/components/add-new-post/index.js +2 -1
  181. package/src/components/add-new-template/style.scss +1 -1
  182. package/src/components/add-new-template/utils.js +10 -6
  183. package/src/components/editor/index.js +80 -22
  184. package/src/components/editor/style.scss +60 -2
  185. package/src/components/global-styles/background-panel.js +0 -3
  186. package/src/components/global-styles/font-families.js +3 -5
  187. package/src/components/global-styles/font-library-modal/context.js +0 -5
  188. package/src/components/global-styles/font-library-modal/font-collection.js +34 -10
  189. package/src/components/global-styles/font-library-modal/index.js +2 -7
  190. package/src/components/global-styles/font-library-modal/installed-fonts.js +26 -6
  191. package/src/components/global-styles/font-library-modal/style.scss +2 -2
  192. package/src/components/global-styles/font-library-modal/upload-fonts.js +2 -2
  193. package/src/components/global-styles/screen-block.js +2 -4
  194. package/src/components/global-styles/screen-css.js +3 -1
  195. package/src/components/global-styles/screen-typeset.js +42 -0
  196. package/src/components/global-styles/screen-typography-element.js +14 -0
  197. package/src/components/global-styles/screen-typography.js +4 -4
  198. package/src/components/global-styles/shadows-edit-panel.js +67 -73
  199. package/src/components/global-styles/size-control/index.js +9 -6
  200. package/src/components/global-styles/style.scss +4 -7
  201. package/src/components/global-styles/typeset-button.js +93 -0
  202. package/src/components/global-styles/typeset.js +73 -0
  203. package/src/components/global-styles/ui.js +5 -0
  204. package/src/components/global-styles/utils.js +13 -1
  205. package/src/components/layout/style.scss +8 -0
  206. package/src/components/page-patterns/fields.js +251 -0
  207. package/src/components/page-patterns/index.js +19 -246
  208. package/src/components/page-patterns/style.scss +82 -85
  209. package/src/components/page-patterns/use-patterns.js +33 -0
  210. package/src/components/page-templates/fields.js +157 -0
  211. package/src/components/page-templates/index.js +19 -170
  212. package/src/components/page-templates/style.scss +14 -5
  213. package/src/components/post-edit/index.js +58 -35
  214. package/src/components/post-fields/index.js +88 -25
  215. package/src/components/post-list/index.js +135 -79
  216. package/src/components/sidebar-dataviews/add-new-view.js +3 -4
  217. package/src/components/sidebar-dataviews/custom-dataviews-list.js +1 -0
  218. package/src/components/sidebar-dataviews/dataview-item.js +2 -2
  219. package/src/components/sidebar-dataviews/default-views.js +95 -95
  220. package/src/components/sidebar-dataviews/index.js +3 -37
  221. package/src/components/site-hub/index.js +11 -2
  222. package/src/components/site-icon/style.scss +4 -1
  223. package/src/components/style-book/index.js +27 -32
  224. package/src/components/sync-state-with-url/use-init-edited-entity-from-url.js +5 -0
  225. package/src/hooks/push-changes-to-global-styles/index.js +3 -3
  226. package/src/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +2 -3
  227. package/src/index.js +0 -2
  228. package/src/utils/is-template-removable.js +4 -2
  229. package/src/utils/is-template-revertable.js +2 -1
  230. package/build/utils/clone-deep.js +0 -15
  231. package/build/utils/clone-deep.js.map +0 -1
  232. package/build-module/utils/clone-deep.js +0 -9
  233. package/build-module/utils/clone-deep.js.map +0 -1
  234. package/src/utils/clone-deep.js +0 -8
@@ -42,11 +42,36 @@ import Media from '../media';
42
42
  // See https://github.com/WordPress/gutenberg/issues/55886
43
43
  // We do not support custom statutes at the moment.
44
44
  const STATUSES = [
45
- { value: 'draft', label: __( 'Draft' ), icon: drafts },
46
- { value: 'future', label: __( 'Scheduled' ), icon: scheduled },
47
- { value: 'pending', label: __( 'Pending Review' ), icon: pending },
48
- { value: 'private', label: __( 'Private' ), icon: notAllowed },
49
- { value: 'publish', label: __( 'Published' ), icon: published },
45
+ {
46
+ value: 'draft',
47
+ label: __( 'Draft' ),
48
+ icon: drafts,
49
+ description: __( 'Not ready to publish.' ),
50
+ },
51
+ {
52
+ value: 'future',
53
+ label: __( 'Scheduled' ),
54
+ icon: scheduled,
55
+ description: __( 'Publish automatically on a chosen date.' ),
56
+ },
57
+ {
58
+ value: 'pending',
59
+ label: __( 'Pending Review' ),
60
+ icon: pending,
61
+ description: __( 'Waiting for review before publishing.' ),
62
+ },
63
+ {
64
+ value: 'private',
65
+ label: __( 'Private' ),
66
+ icon: notAllowed,
67
+ description: __( 'Only visible to site admins and editors.' ),
68
+ },
69
+ {
70
+ value: 'publish',
71
+ label: __( 'Published' ),
72
+ icon: published,
73
+ description: __( 'Visible to everyone.' ),
74
+ },
50
75
  { value: 'trash', label: __( 'Trash' ), icon: trash },
51
76
  ];
52
77
 
@@ -186,6 +211,10 @@ function usePostFields( viewType ) {
186
211
  const addLink =
187
212
  [ LAYOUT_TABLE, LAYOUT_GRID ].includes( viewType ) &&
188
213
  item.status !== 'trash';
214
+ const renderedTitle =
215
+ typeof item.title === 'string'
216
+ ? item.title
217
+ : item.title?.rendered;
189
218
  const title = addLink ? (
190
219
  <Link
191
220
  params={ {
@@ -194,12 +223,12 @@ function usePostFields( viewType ) {
194
223
  canvas: 'edit',
195
224
  } }
196
225
  >
197
- { decodeEntities( item.title?.rendered ) ||
226
+ { decodeEntities( renderedTitle ) ||
198
227
  __( '(no title)' ) }
199
228
  </Link>
200
229
  ) : (
201
230
  <span>
202
- { decodeEntities( item.title?.rendered ) ||
231
+ { decodeEntities( renderedTitle ) ||
203
232
  __( '(no title)' ) }
204
233
  </span>
205
234
  );
@@ -235,22 +264,29 @@ function usePostFields( viewType ) {
235
264
  {
236
265
  label: __( 'Author' ),
237
266
  id: 'author',
238
- getValue: ( { item } ) => item._embedded?.author[ 0 ]?.name,
267
+ type: 'integer',
239
268
  elements:
240
269
  authors?.map( ( { id, name } ) => ( {
241
270
  value: id,
242
271
  label: name,
243
272
  } ) ) || [],
244
273
  render: PostAuthorField,
274
+ sort: ( a, b, direction ) => {
275
+ const nameA = a._embedded?.author?.[ 0 ]?.name || '';
276
+ const nameB = b._embedded?.author?.[ 0 ]?.name || '';
277
+
278
+ return direction === 'asc'
279
+ ? nameA.localeCompare( nameB )
280
+ : nameB.localeCompare( nameA );
281
+ },
245
282
  },
246
283
  {
247
284
  label: __( 'Status' ),
248
285
  id: 'status',
249
- getValue: ( { item } ) =>
250
- STATUSES.find( ( { value } ) => value === item.status )
251
- ?.label ?? item.status,
286
+ type: 'text',
252
287
  elements: STATUSES,
253
288
  render: PostStatusField,
289
+ Edit: 'radio',
254
290
  enableSorting: false,
255
291
  filterBy: {
256
292
  operators: [ OPERATOR_IS_ANY ],
@@ -259,6 +295,7 @@ function usePostFields( viewType ) {
259
295
  {
260
296
  label: __( 'Date' ),
261
297
  id: 'date',
298
+ type: 'datetime',
262
299
  render: ( { item } ) => {
263
300
  const isDraftOrPrivate = [ 'draft', 'private' ].includes(
264
301
  item.status
@@ -292,19 +329,13 @@ function usePostFields( viewType ) {
292
329
  );
293
330
  }
294
331
 
295
- // Pending & Published posts show the modified date if it's newer.
296
- const dateToDisplay =
297
- getDate( item.modified ) > getDate( item.date )
298
- ? item.modified
299
- : item.date;
300
-
301
- const isPending = item.status === 'pending';
302
- if ( isPending ) {
332
+ const isPublished = item.status === 'publish';
333
+ if ( isPublished ) {
303
334
  return createInterpolateElement(
304
335
  sprintf(
305
- /* translators: %s: the newest of created or modified date for the page */
306
- __( '<span>Modified: <time>%s</time></span>' ),
307
- getFormattedDate( dateToDisplay )
336
+ /* translators: %s: page creation time */
337
+ __( '<span>Published: <time>%s</time></span>' ),
338
+ getFormattedDate( item.date )
308
339
  ),
309
340
  {
310
341
  span: <span />,
@@ -313,12 +344,18 @@ function usePostFields( viewType ) {
313
344
  );
314
345
  }
315
346
 
316
- const isPublished = item.status === 'publish';
317
- if ( isPublished ) {
347
+ // Pending posts show the modified date if it's newer.
348
+ const dateToDisplay =
349
+ getDate( item.modified ) > getDate( item.date )
350
+ ? item.modified
351
+ : item.date;
352
+
353
+ const isPending = item.status === 'pending';
354
+ if ( isPending ) {
318
355
  return createInterpolateElement(
319
356
  sprintf(
320
357
  /* translators: %s: the newest of created or modified date for the page */
321
- __( '<span>Published: <time>%s</time></span>' ),
358
+ __( '<span>Modified: <time>%s</time></span>' ),
322
359
  getFormattedDate( dateToDisplay )
323
360
  ),
324
361
  {
@@ -332,6 +369,32 @@ function usePostFields( viewType ) {
332
369
  return <time>{ getFormattedDate( item.date ) }</time>;
333
370
  },
334
371
  },
372
+ {
373
+ id: 'comment_status',
374
+ label: __( 'Discussion' ),
375
+ type: 'text',
376
+ Edit: 'radio',
377
+ enableSorting: false,
378
+ filterBy: {
379
+ operators: [],
380
+ },
381
+ elements: [
382
+ {
383
+ value: 'open',
384
+ label: __( 'Open' ),
385
+ description: __(
386
+ 'Visitors can add new comments and replies.'
387
+ ),
388
+ },
389
+ {
390
+ value: 'closed',
391
+ label: __( 'Closed' ),
392
+ description: __(
393
+ 'Visitors cannot add new comments or replies. Existing comments remain visible.'
394
+ ),
395
+ },
396
+ ],
397
+ },
335
398
  ],
336
399
  [ authors, viewType, frontPageId, postsPageId ]
337
400
  );
@@ -2,11 +2,14 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { Button } from '@wordpress/components';
5
- import { useEntityRecords, store as coreStore } from '@wordpress/core-data';
5
+ import {
6
+ store as coreStore,
7
+ privateApis as coreDataPrivateApis,
8
+ } from '@wordpress/core-data';
6
9
  import { useState, useMemo, useCallback, useEffect } from '@wordpress/element';
7
10
  import { privateApis as routerPrivateApis } from '@wordpress/router';
8
11
  import { useSelect, useDispatch } from '@wordpress/data';
9
- import { DataViews } from '@wordpress/dataviews';
12
+ import { DataViews, filterSortAndPaginate } from '@wordpress/dataviews';
10
13
  import { privateApis as editorPrivateApis } from '@wordpress/editor';
11
14
  import { __ } from '@wordpress/i18n';
12
15
  import { drawerRight } from '@wordpress/icons';
@@ -33,102 +36,139 @@ import usePostFields from '../post-fields';
33
36
 
34
37
  const { usePostActions } = unlock( editorPrivateApis );
35
38
  const { useLocation, useHistory } = unlock( routerPrivateApis );
39
+ const { useEntityRecordsWithPermissions } = unlock( coreDataPrivateApis );
36
40
  const EMPTY_ARRAY = [];
37
41
 
42
+ const getDefaultView = ( defaultViews, activeView ) => {
43
+ return defaultViews.find( ( { slug } ) => slug === activeView )?.view;
44
+ };
45
+
46
+ const getCustomView = ( editedEntityRecord ) => {
47
+ if ( ! editedEntityRecord?.content ) {
48
+ return undefined;
49
+ }
50
+
51
+ const content = JSON.parse( editedEntityRecord.content );
52
+ if ( ! content ) {
53
+ return undefined;
54
+ }
55
+
56
+ return {
57
+ ...content,
58
+ layout: defaultLayouts[ content.type ]?.layout,
59
+ };
60
+ };
61
+
62
+ /**
63
+ * This function abstracts working with default & custom views by
64
+ * providing a [ state, setState ] tuple based on the URL parameters.
65
+ *
66
+ * Consumers use the provided tuple to work with state
67
+ * and don't have to deal with the specifics of default & custom views.
68
+ *
69
+ * @param {string} postType Post type to retrieve default views for.
70
+ * @return {Array} The [ state, setState ] tuple.
71
+ */
38
72
  function useView( postType ) {
39
73
  const {
40
74
  params: { activeView = 'all', isCustom = 'false', layout },
41
75
  } = useLocation();
42
76
  const history = useHistory();
43
- const DEFAULT_VIEWS = useDefaultViews( { postType } );
44
- const selectedDefaultView = useMemo( () => {
45
- const defaultView =
46
- isCustom === 'false' &&
47
- DEFAULT_VIEWS[ postType ].find(
48
- ( { slug } ) => slug === activeView
49
- )?.view;
50
- if ( isCustom === 'false' && layout ) {
51
- return {
52
- ...defaultView,
53
- type: layout,
54
- layout: defaultLayouts[ layout ]?.layout,
55
- };
56
- }
57
- return defaultView;
58
- }, [ isCustom, activeView, layout, postType, DEFAULT_VIEWS ] );
59
- const [ view, setView ] = useState( selectedDefaultView );
60
77
 
61
- useEffect( () => {
62
- if ( selectedDefaultView ) {
63
- setView( selectedDefaultView );
64
- }
65
- }, [ selectedDefaultView ] );
66
- const editedViewRecord = useSelect(
78
+ const defaultViews = useDefaultViews( { postType } );
79
+ const { editEntityRecord } = useDispatch( coreStore );
80
+ const editedEntityRecord = useSelect(
67
81
  ( select ) => {
68
82
  if ( isCustom !== 'true' ) {
69
- return;
83
+ return undefined;
70
84
  }
85
+
71
86
  const { getEditedEntityRecord } = select( coreStore );
72
- const dataviewRecord = getEditedEntityRecord(
87
+ return getEditedEntityRecord(
73
88
  'postType',
74
89
  'wp_dataviews',
75
90
  Number( activeView )
76
91
  );
77
- return dataviewRecord;
78
92
  },
79
93
  [ activeView, isCustom ]
80
94
  );
81
- const { editEntityRecord } = useDispatch( coreStore );
82
-
83
- const customView = useMemo( () => {
84
- const storedView =
85
- editedViewRecord?.content &&
86
- JSON.parse( editedViewRecord?.content );
87
- if ( ! storedView ) {
88
- return storedView;
95
+ const [ view, setView ] = useState( () => {
96
+ let initialView;
97
+ if ( isCustom === 'true' ) {
98
+ initialView = getCustomView( editedEntityRecord ) ?? {
99
+ type: layout ?? LAYOUT_LIST,
100
+ };
101
+ } else {
102
+ initialView = getDefaultView( defaultViews, activeView ) ?? {
103
+ type: layout ?? LAYOUT_LIST,
104
+ };
89
105
  }
90
106
 
107
+ const type = layout ?? initialView.type;
91
108
  return {
92
- ...storedView,
93
- layout: defaultLayouts[ storedView?.type ]?.layout,
109
+ ...initialView,
110
+ type,
94
111
  };
95
- }, [ editedViewRecord?.content ] );
112
+ } );
96
113
 
97
- const setCustomView = useCallback(
98
- ( viewToSet ) => {
99
- editEntityRecord(
100
- 'postType',
101
- 'wp_dataviews',
102
- editedViewRecord?.id,
103
- {
104
- content: JSON.stringify( viewToSet ),
105
- }
106
- );
107
- },
108
- [ editEntityRecord, editedViewRecord?.id ]
109
- );
114
+ const setViewWithUrlUpdate = useCallback(
115
+ ( newView ) => {
116
+ const { params } = history.getLocationWithParams();
110
117
 
111
- const setDefaultViewAndUpdateUrl = useCallback(
112
- ( viewToSet ) => {
113
- if ( viewToSet.type !== view?.type ) {
114
- const { params } = history.getLocationWithParams();
118
+ if ( newView.type === LAYOUT_LIST && ! params?.layout ) {
119
+ // Skip updating the layout URL param if
120
+ // it is not present and the newView.type is LAYOUT_LIST.
121
+ } else if ( newView.type !== params?.layout ) {
115
122
  history.push( {
116
123
  ...params,
117
- layout: viewToSet.type,
124
+ layout: newView.type,
118
125
  } );
119
126
  }
120
- setView( viewToSet );
127
+
128
+ setView( newView );
129
+
130
+ if ( isCustom === 'true' && editedEntityRecord?.id ) {
131
+ editEntityRecord(
132
+ 'postType',
133
+ 'wp_dataviews',
134
+ editedEntityRecord?.id,
135
+ {
136
+ content: JSON.stringify( newView ),
137
+ }
138
+ );
139
+ }
121
140
  },
122
- [ history, view?.type ]
141
+ [ history, isCustom, editEntityRecord, editedEntityRecord?.id ]
123
142
  );
124
143
 
125
- if ( isCustom === 'false' ) {
126
- return [ view, setDefaultViewAndUpdateUrl ];
127
- } else if ( isCustom === 'true' && customView ) {
128
- return [ customView, setCustomView ];
129
- }
130
- // Loading state where no the view was not found on custom views or default views.
131
- return [ DEFAULT_VIEWS[ postType ][ 0 ].view, setDefaultViewAndUpdateUrl ];
144
+ // When layout URL param changes, update the view type
145
+ // without affecting any other config.
146
+ useEffect( () => {
147
+ setView( ( prevView ) => ( {
148
+ ...prevView,
149
+ type: layout ?? LAYOUT_LIST,
150
+ } ) );
151
+ }, [ layout ] );
152
+
153
+ // When activeView or isCustom URL parameters change, reset the view.
154
+ useEffect( () => {
155
+ let newView;
156
+ if ( isCustom === 'true' ) {
157
+ newView = getCustomView( editedEntityRecord );
158
+ } else {
159
+ newView = getDefaultView( defaultViews, activeView );
160
+ }
161
+
162
+ if ( newView ) {
163
+ const type = layout ?? newView.type;
164
+ setView( {
165
+ ...newView,
166
+ type,
167
+ } );
168
+ }
169
+ }, [ activeView, isCustom, layout, defaultViews, editedEntityRecord ] );
170
+
171
+ return [ view, setViewWithUrlUpdate, setViewWithUrlUpdate ];
132
172
  }
133
173
 
134
174
  const DEFAULT_STATUSES = 'draft,future,pending,private,publish'; // All but 'trash'.
@@ -141,7 +181,12 @@ export default function PostList( { postType } ) {
141
181
  const [ view, setView ] = useView( postType );
142
182
  const history = useHistory();
143
183
  const location = useLocation();
144
- const { postId, quickEdit = false } = location.params;
184
+ const {
185
+ postId,
186
+ quickEdit = false,
187
+ isCustom,
188
+ activeView = 'all',
189
+ } = location.params;
145
190
  const [ selection, setSelection ] = useState( postId?.split( ',' ) ?? [] );
146
191
  const onChangeSelection = useCallback(
147
192
  ( items ) => {
@@ -157,9 +202,11 @@ export default function PostList( { postType } ) {
157
202
  [ history ]
158
203
  );
159
204
 
205
+ const { isLoading: isLoadingFields, fields } = usePostFields( view.type );
206
+
160
207
  const queryArgs = useMemo( () => {
161
208
  const filters = {};
162
- view.filters.forEach( ( filter ) => {
209
+ view.filters?.forEach( ( filter ) => {
163
210
  if (
164
211
  filter.field === 'status' &&
165
212
  filter.operator === OPERATOR_IS_ANY
@@ -196,12 +243,25 @@ export default function PostList( { postType } ) {
196
243
  }, [ view ] );
197
244
  const {
198
245
  records,
199
- isResolving: isLoadingMainEntities,
246
+ isResolving: isLoadingData,
200
247
  totalItems,
201
248
  totalPages,
202
- } = useEntityRecords( 'postType', postType, queryArgs );
249
+ } = useEntityRecordsWithPermissions( 'postType', postType, queryArgs );
250
+
251
+ // The REST API sort the authors by ID, but we want to sort them by name.
252
+ const data = useMemo( () => {
253
+ if ( ! isLoadingFields && view?.sort?.field === 'author' ) {
254
+ return filterSortAndPaginate(
255
+ records,
256
+ { sort: { ...view.sort } },
257
+ fields
258
+ ).data;
259
+ }
260
+
261
+ return records;
262
+ }, [ records, fields, isLoadingFields, view?.sort ] );
203
263
 
204
- const ids = records?.map( ( record ) => getItemId( record ) ) ?? [];
264
+ const ids = data?.map( ( record ) => getItemId( record ) ) ?? [];
205
265
  const prevIds = usePrevious( ids ) ?? [];
206
266
  const deletedIds = prevIds.filter( ( id ) => ! ids.includes( id ) );
207
267
  const postIdWasDeleted = deletedIds.includes( postId );
@@ -259,7 +319,6 @@ export default function PostList( { postType } ) {
259
319
  } );
260
320
  closeModal();
261
321
  };
262
- const { isLoading: isLoadingFields, fields } = usePostFields( view.type );
263
322
 
264
323
  return (
265
324
  <Page
@@ -287,11 +346,12 @@ export default function PostList( { postType } ) {
287
346
  }
288
347
  >
289
348
  <DataViews
349
+ key={ activeView + isCustom }
290
350
  paginationInfo={ paginationInfo }
291
351
  fields={ fields }
292
352
  actions={ actions }
293
- data={ records || EMPTY_ARRAY }
294
- isLoading={ isLoadingMainEntities || isLoadingFields }
353
+ data={ data || EMPTY_ARRAY }
354
+ isLoading={ isLoadingData || isLoadingFields }
295
355
  view={ view }
296
356
  onChangeView={ setView }
297
357
  selection={ selection }
@@ -306,11 +366,7 @@ export default function PostList( { postType } ) {
306
366
  size="compact"
307
367
  isPressed={ quickEdit }
308
368
  icon={ drawerRight }
309
- label={
310
- ! quickEdit
311
- ? __( 'Show quick edit sidebar' )
312
- : __( 'Close quick edit sidebar' )
313
- }
369
+ label={ __( 'Toggle details panel' ) }
314
370
  onClick={ () => {
315
371
  history.push( {
316
372
  ...location.params,
@@ -29,7 +29,7 @@ function AddNewItemModalContent( { type, setIsAdding } ) {
29
29
  const { saveEntityRecord } = useDispatch( coreStore );
30
30
  const [ title, setTitle ] = useState( '' );
31
31
  const [ isSaving, setIsSaving ] = useState( false );
32
- const DEFAULT_VIEWS = useDefaultViews( { postType: type } );
32
+ const defaultViews = useDefaultViews( { postType: type } );
33
33
  return (
34
34
  <form
35
35
  onSubmit={ async ( event ) => {
@@ -61,9 +61,7 @@ function AddNewItemModalContent( { type, setIsAdding } ) {
61
61
  title,
62
62
  status: 'publish',
63
63
  wp_dataviews_type: dataViewTaxonomyId,
64
- content: JSON.stringify(
65
- DEFAULT_VIEWS[ type ][ 0 ].view
66
- ),
64
+ content: JSON.stringify( defaultViews[ 0 ].view ),
67
65
  }
68
66
  );
69
67
  const {
@@ -80,6 +78,7 @@ function AddNewItemModalContent( { type, setIsAdding } ) {
80
78
  >
81
79
  <VStack spacing="5">
82
80
  <TextControl
81
+ __next40pxDefaultSize
83
82
  __nextHasNoMarginBottom
84
83
  label={ __( 'Name' ) }
85
84
  value={ title }
@@ -51,6 +51,7 @@ function RenameItemModalContent( { dataviewId, currentTitle, setIsRenaming } ) {
51
51
  >
52
52
  <VStack spacing="5">
53
53
  <TextControl
54
+ __next40pxDefaultSize
54
55
  __nextHasNoMarginBottom
55
56
  label={ __( 'Name' ) }
56
57
  value={ title }
@@ -29,7 +29,7 @@ export default function DataViewItem( {
29
29
  suffix,
30
30
  } ) {
31
31
  const {
32
- params: { postType, layout },
32
+ params: { postType },
33
33
  } = useLocation();
34
34
 
35
35
  const iconToUse =
@@ -41,7 +41,7 @@ export default function DataViewItem( {
41
41
  }
42
42
  const linkInfo = useLink( {
43
43
  postType,
44
- layout,
44
+ layout: type,
45
45
  activeView,
46
46
  isCustom: isCustom ? 'true' : undefined,
47
47
  } );