@wordpress/editor 14.42.0 → 14.43.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 (199) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/collaborators-overlay/cursor-registry.cjs +86 -0
  3. package/build/components/collaborators-overlay/cursor-registry.cjs.map +7 -0
  4. package/build/components/collaborators-overlay/index.cjs +7 -2
  5. package/build/components/collaborators-overlay/index.cjs.map +2 -2
  6. package/build/components/collaborators-overlay/overlay-iframe-styles.cjs +1 -1
  7. package/build/components/collaborators-overlay/overlay-iframe-styles.cjs.map +2 -2
  8. package/build/components/collaborators-overlay/overlay.cjs +31 -1
  9. package/build/components/collaborators-overlay/overlay.cjs.map +2 -2
  10. package/build/components/collaborators-presence/index.cjs +14 -4
  11. package/build/components/collaborators-presence/index.cjs.map +2 -2
  12. package/build/components/collaborators-presence/list.cjs +20 -4
  13. package/build/components/collaborators-presence/list.cjs.map +2 -2
  14. package/build/components/post-card-panel/index.cjs +4 -15
  15. package/build/components/post-card-panel/index.cjs.map +2 -2
  16. package/build/components/post-content-information/index.cjs +10 -13
  17. package/build/components/post-content-information/index.cjs.map +2 -2
  18. package/build/components/post-revisions-panel/index.cjs +164 -0
  19. package/build/components/post-revisions-panel/index.cjs.map +7 -0
  20. package/build/components/post-revisions-preview/revisions-slider.cjs +24 -5
  21. package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
  22. package/build/components/post-template/create-new-template-modal.cjs +39 -46
  23. package/build/components/post-template/create-new-template-modal.cjs.map +2 -2
  24. package/build/components/post-template/hooks.cjs +52 -6
  25. package/build/components/post-template/hooks.cjs.map +2 -2
  26. package/build/components/post-template/swap-template-button.cjs +31 -20
  27. package/build/components/post-template/swap-template-button.cjs.map +2 -2
  28. package/build/components/preferences-modal/index.cjs +35 -27
  29. package/build/components/preferences-modal/index.cjs.map +2 -2
  30. package/build/components/revision-block-diff/index.cjs +9 -32
  31. package/build/components/revision-block-diff/index.cjs.map +3 -3
  32. package/build/components/revision-diff-panel/index.cjs +68 -0
  33. package/build/components/revision-diff-panel/index.cjs.map +7 -0
  34. package/build/components/revision-fields-diff/index.cjs +96 -0
  35. package/build/components/revision-fields-diff/index.cjs.map +7 -0
  36. package/build/components/sidebar/dataform-post-summary.cjs +8 -53
  37. package/build/components/sidebar/dataform-post-summary.cjs.map +2 -2
  38. package/build/components/sidebar/index.cjs +25 -22
  39. package/build/components/sidebar/index.cjs.map +3 -3
  40. package/build/components/sidebar/post-revision-summary.cjs +74 -0
  41. package/build/components/sidebar/post-revision-summary.cjs.map +7 -0
  42. package/build/components/sidebar/post-summary.cjs +35 -42
  43. package/build/components/sidebar/post-summary.cjs.map +3 -3
  44. package/build/components/style-book/index.cjs +4 -3
  45. package/build/components/style-book/index.cjs.map +2 -2
  46. package/build/components/sync-connection-error-modal/index.cjs +2 -2
  47. package/build/components/sync-connection-error-modal/index.cjs.map +1 -1
  48. package/build/components/template-actions-panel/block-theme-content.cjs +188 -0
  49. package/build/components/template-actions-panel/block-theme-content.cjs.map +7 -0
  50. package/build/components/template-actions-panel/classic-theme-content.cjs +159 -0
  51. package/build/components/template-actions-panel/classic-theme-content.cjs.map +7 -0
  52. package/build/components/template-actions-panel/index.cjs +59 -0
  53. package/build/components/template-actions-panel/index.cjs.map +7 -0
  54. package/build/dataviews/store/private-actions.cjs +2 -0
  55. package/build/dataviews/store/private-actions.cjs.map +2 -2
  56. package/build/store/private-actions.cjs +21 -2
  57. package/build/store/private-actions.cjs.map +2 -2
  58. package/build/store/private-selectors.cjs +40 -15
  59. package/build/store/private-selectors.cjs.map +2 -2
  60. package/build-module/components/collaborators-overlay/cursor-registry.mjs +61 -0
  61. package/build-module/components/collaborators-overlay/cursor-registry.mjs.map +7 -0
  62. package/build-module/components/collaborators-overlay/index.mjs +7 -2
  63. package/build-module/components/collaborators-overlay/index.mjs.map +2 -2
  64. package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs +1 -1
  65. package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs.map +2 -2
  66. package/build-module/components/collaborators-overlay/overlay.mjs +32 -2
  67. package/build-module/components/collaborators-overlay/overlay.mjs.map +2 -2
  68. package/build-module/components/collaborators-presence/index.mjs +14 -4
  69. package/build-module/components/collaborators-presence/index.mjs.map +2 -2
  70. package/build-module/components/collaborators-presence/list.mjs +20 -4
  71. package/build-module/components/collaborators-presence/list.mjs.map +2 -2
  72. package/build-module/components/post-card-panel/index.mjs +6 -17
  73. package/build-module/components/post-card-panel/index.mjs.map +2 -2
  74. package/build-module/components/post-content-information/index.mjs +6 -13
  75. package/build-module/components/post-content-information/index.mjs.map +2 -2
  76. package/build-module/components/post-revisions-panel/index.mjs +139 -0
  77. package/build-module/components/post-revisions-panel/index.mjs.map +7 -0
  78. package/build-module/components/post-revisions-preview/revisions-slider.mjs +24 -5
  79. package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
  80. package/build-module/components/post-template/create-new-template-modal.mjs +39 -46
  81. package/build-module/components/post-template/create-new-template-modal.mjs.map +2 -2
  82. package/build-module/components/post-template/hooks.mjs +53 -7
  83. package/build-module/components/post-template/hooks.mjs.map +2 -2
  84. package/build-module/components/post-template/swap-template-button.mjs +27 -20
  85. package/build-module/components/post-template/swap-template-button.mjs.map +2 -2
  86. package/build-module/components/preferences-modal/index.mjs +35 -27
  87. package/build-module/components/preferences-modal/index.mjs.map +2 -2
  88. package/build-module/components/revision-block-diff/index.mjs +9 -32
  89. package/build-module/components/revision-block-diff/index.mjs.map +2 -2
  90. package/build-module/components/revision-diff-panel/index.mjs +37 -0
  91. package/build-module/components/revision-diff-panel/index.mjs.map +7 -0
  92. package/build-module/components/revision-fields-diff/index.mjs +65 -0
  93. package/build-module/components/revision-fields-diff/index.mjs.map +7 -0
  94. package/build-module/components/sidebar/dataform-post-summary.mjs +8 -53
  95. package/build-module/components/sidebar/dataform-post-summary.mjs.map +2 -2
  96. package/build-module/components/sidebar/index.mjs +25 -22
  97. package/build-module/components/sidebar/index.mjs.map +2 -2
  98. package/build-module/components/sidebar/post-revision-summary.mjs +43 -0
  99. package/build-module/components/sidebar/post-revision-summary.mjs.map +7 -0
  100. package/build-module/components/sidebar/post-summary.mjs +31 -42
  101. package/build-module/components/sidebar/post-summary.mjs.map +2 -2
  102. package/build-module/components/style-book/index.mjs +4 -3
  103. package/build-module/components/style-book/index.mjs.map +2 -2
  104. package/build-module/components/sync-connection-error-modal/index.mjs +2 -2
  105. package/build-module/components/sync-connection-error-modal/index.mjs.map +1 -1
  106. package/build-module/components/template-actions-panel/block-theme-content.mjs +167 -0
  107. package/build-module/components/template-actions-panel/block-theme-content.mjs.map +7 -0
  108. package/build-module/components/template-actions-panel/classic-theme-content.mjs +138 -0
  109. package/build-module/components/template-actions-panel/classic-theme-content.mjs.map +7 -0
  110. package/build-module/components/template-actions-panel/index.mjs +28 -0
  111. package/build-module/components/template-actions-panel/index.mjs.map +7 -0
  112. package/build-module/dataviews/store/private-actions.mjs +5 -1
  113. package/build-module/dataviews/store/private-actions.mjs.map +2 -2
  114. package/build-module/store/private-actions.mjs +21 -2
  115. package/build-module/store/private-actions.mjs.map +2 -2
  116. package/build-module/store/private-selectors.mjs +40 -15
  117. package/build-module/store/private-selectors.mjs.map +2 -2
  118. package/build-style/style-rtl.css +111 -42
  119. package/build-style/style.css +111 -42
  120. package/build-types/components/collaborators-overlay/cursor-registry.d.ts +36 -0
  121. package/build-types/components/collaborators-overlay/cursor-registry.d.ts.map +1 -0
  122. package/build-types/components/collaborators-overlay/index.d.ts +7 -4
  123. package/build-types/components/collaborators-overlay/index.d.ts.map +1 -1
  124. package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts +1 -1
  125. package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts.map +1 -1
  126. package/build-types/components/collaborators-overlay/overlay.d.ts +4 -1
  127. package/build-types/components/collaborators-overlay/overlay.d.ts.map +1 -1
  128. package/build-types/components/collaborators-presence/index.d.ts.map +1 -1
  129. package/build-types/components/collaborators-presence/list.d.ts +4 -1
  130. package/build-types/components/collaborators-presence/list.d.ts.map +1 -1
  131. package/build-types/components/post-card-panel/index.d.ts.map +1 -1
  132. package/build-types/components/post-content-information/index.d.ts +4 -1
  133. package/build-types/components/post-content-information/index.d.ts.map +1 -1
  134. package/build-types/components/post-revisions-panel/index.d.ts +2 -0
  135. package/build-types/components/post-revisions-panel/index.d.ts.map +1 -0
  136. package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
  137. package/build-types/components/post-template/create-new-template-modal.d.ts.map +1 -1
  138. package/build-types/components/post-template/hooks.d.ts +1 -1
  139. package/build-types/components/post-template/hooks.d.ts.map +1 -1
  140. package/build-types/components/post-template/swap-template-button.d.ts +4 -0
  141. package/build-types/components/post-template/swap-template-button.d.ts.map +1 -1
  142. package/build-types/components/revision-block-diff/index.d.ts.map +1 -1
  143. package/build-types/components/revision-diff-panel/index.d.ts +14 -0
  144. package/build-types/components/revision-diff-panel/index.d.ts.map +1 -0
  145. package/build-types/components/revision-fields-diff/index.d.ts +6 -0
  146. package/build-types/components/revision-fields-diff/index.d.ts.map +1 -0
  147. package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -1
  148. package/build-types/components/sidebar/index.d.ts.map +1 -1
  149. package/build-types/components/sidebar/post-revision-summary.d.ts +2 -0
  150. package/build-types/components/sidebar/post-revision-summary.d.ts.map +1 -0
  151. package/build-types/components/sidebar/post-summary.d.ts +3 -0
  152. package/build-types/components/sidebar/post-summary.d.ts.map +1 -1
  153. package/build-types/components/style-book/index.d.ts +2 -1
  154. package/build-types/components/style-book/index.d.ts.map +1 -1
  155. package/build-types/components/template-actions-panel/block-theme-content.d.ts +2 -0
  156. package/build-types/components/template-actions-panel/block-theme-content.d.ts.map +1 -0
  157. package/build-types/components/template-actions-panel/classic-theme-content.d.ts +2 -0
  158. package/build-types/components/template-actions-panel/classic-theme-content.d.ts.map +1 -0
  159. package/build-types/components/template-actions-panel/index.d.ts +2 -0
  160. package/build-types/components/template-actions-panel/index.d.ts.map +1 -0
  161. package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
  162. package/build-types/store/private-actions.d.ts.map +1 -1
  163. package/build-types/store/private-selectors.d.ts.map +1 -1
  164. package/package.json +45 -44
  165. package/src/components/collaborators-overlay/cursor-registry.ts +96 -0
  166. package/src/components/collaborators-overlay/index.tsx +12 -4
  167. package/src/components/collaborators-overlay/overlay-iframe-styles.ts +1 -1
  168. package/src/components/collaborators-overlay/overlay.tsx +45 -1
  169. package/src/components/collaborators-presence/index.tsx +9 -1
  170. package/src/components/collaborators-presence/list.tsx +25 -1
  171. package/src/components/post-card-panel/index.js +7 -21
  172. package/src/components/post-content-information/index.js +5 -16
  173. package/src/components/post-revisions-panel/index.js +151 -0
  174. package/src/components/post-revisions-panel/style.scss +16 -0
  175. package/src/components/post-revisions-preview/revisions-slider.js +29 -7
  176. package/src/components/post-template/create-new-template-modal.js +1 -4
  177. package/src/components/post-template/hooks.js +65 -9
  178. package/src/components/post-template/style.scss +0 -6
  179. package/src/components/post-template/swap-template-button.js +30 -21
  180. package/src/components/preferences-modal/index.js +37 -25
  181. package/src/components/revision-block-diff/index.js +8 -43
  182. package/src/components/revision-diff-panel/index.js +59 -0
  183. package/src/components/revision-fields-diff/index.js +91 -0
  184. package/src/components/sidebar/dataform-post-summary.js +8 -55
  185. package/src/components/sidebar/index.js +33 -22
  186. package/src/components/sidebar/post-revision-summary.js +50 -0
  187. package/src/components/sidebar/post-summary.js +22 -40
  188. package/src/components/sidebar/style.scss +7 -0
  189. package/src/components/style-book/index.js +4 -2
  190. package/src/components/sync-connection-error-modal/index.tsx +2 -2
  191. package/src/components/template-actions-panel/block-theme-content.js +196 -0
  192. package/src/components/template-actions-panel/classic-theme-content.js +170 -0
  193. package/src/components/template-actions-panel/index.js +32 -0
  194. package/src/components/template-actions-panel/style.scss +39 -0
  195. package/src/dataviews/store/private-actions.ts +6 -0
  196. package/src/store/private-actions.js +24 -3
  197. package/src/store/private-selectors.js +46 -16
  198. package/src/style.scss +3 -1
  199. /package/src/components/{revision-block-diff → revision-diff-panel}/style.scss +0 -0
@@ -16,23 +16,40 @@ import { parse } from '@wordpress/blocks';
16
16
  import { useAvailableTemplates, useEditedPostContext } from './hooks';
17
17
  import { searchTemplates } from '../../utils/search-templates';
18
18
 
19
- export default function SwapTemplateButton( { onClick } ) {
20
- const [ showModal, setShowModal ] = useState( false );
19
+ export function SwapTemplateModal( { onRequestClose, onSelect } ) {
21
20
  const { postType, postId } = useEditedPostContext();
22
- const availableTemplates = useAvailableTemplates( postType );
23
21
  const { editEntityRecord } = useDispatch( coreStore );
24
-
25
22
  const onTemplateSelect = async ( template ) => {
26
23
  editEntityRecord(
27
24
  'postType',
28
25
  postType,
29
26
  postId,
30
- { template: template.name },
27
+ // Since we append the default template we need to properly
28
+ // update to an empty string.
29
+ { template: template.isDefault ? '' : template.name },
31
30
  { undoIgnore: true }
32
31
  );
33
- setShowModal( false ); // Close the template suggestions modal first.
34
- onClick();
32
+ onRequestClose();
33
+ onSelect?.();
35
34
  };
35
+ return (
36
+ <Modal
37
+ title={ __( 'Choose a template' ) }
38
+ onRequestClose={ onRequestClose }
39
+ overlayClassName="editor-post-template__swap-template-modal"
40
+ isFullScreen
41
+ >
42
+ <div className="editor-post-template__swap-template-modal-content">
43
+ <TemplatesList onSelect={ onTemplateSelect } />
44
+ </div>
45
+ </Modal>
46
+ );
47
+ }
48
+
49
+ export default function SwapTemplateButton( { onClick } ) {
50
+ const [ showModal, setShowModal ] = useState( false );
51
+ const availableTemplates = useAvailableTemplates();
52
+
36
53
  return (
37
54
  <>
38
55
  <MenuItem
@@ -43,27 +60,18 @@ export default function SwapTemplateButton( { onClick } ) {
43
60
  { __( 'Change template' ) }
44
61
  </MenuItem>
45
62
  { showModal && (
46
- <Modal
47
- title={ __( 'Choose a template' ) }
63
+ <SwapTemplateModal
48
64
  onRequestClose={ () => setShowModal( false ) }
49
- overlayClassName="editor-post-template__swap-template-modal"
50
- isFullScreen
51
- >
52
- <div className="editor-post-template__swap-template-modal-content">
53
- <TemplatesList
54
- postType={ postType }
55
- onSelect={ onTemplateSelect }
56
- />
57
- </div>
58
- </Modal>
65
+ onSelect={ onClick }
66
+ />
59
67
  ) }
60
68
  </>
61
69
  );
62
70
  }
63
71
 
64
- function TemplatesList( { postType, onSelect } ) {
72
+ function TemplatesList( { onSelect } ) {
65
73
  const [ searchValue, setSearchValue ] = useState( '' );
66
- const availableTemplates = useAvailableTemplates( postType );
74
+ const availableTemplates = useAvailableTemplates();
67
75
  const templatesAsPatterns = useMemo(
68
76
  () =>
69
77
  availableTemplates.map( ( template ) => ( {
@@ -71,6 +79,7 @@ function TemplatesList( { postType, onSelect } ) {
71
79
  blocks: parse( template.content.raw ),
72
80
  title: decodeEntities( template.title.rendered ),
73
81
  id: template.id,
82
+ isDefault: template.isDefault,
74
83
  } ) ),
75
84
  [ availableTemplates ]
76
85
  );
@@ -55,20 +55,25 @@ export default function EditorPreferencesModal( { extraSections = {} } ) {
55
55
 
56
56
  function PreferencesModalContents( { extraSections = {} } ) {
57
57
  const isLargeViewport = useViewportMatch( 'medium' );
58
- const showBlockBreadcrumbsOption = useSelect(
58
+ const { showBlockBreadcrumbsOption, showCollaborationOptions } = useSelect(
59
59
  ( select ) => {
60
- const { getEditorSettings } = select( editorStore );
60
+ const { getEditorSettings, isCollaborationEnabledForCurrentPost } =
61
+ select( editorStore );
61
62
  const { get } = select( preferencesStore );
62
63
  const isRichEditingEnabled = getEditorSettings().richEditingEnabled;
63
64
  const isDistractionFreeEnabled = get( 'core', 'distractionFree' );
64
- return (
65
- ! isDistractionFreeEnabled &&
66
- isLargeViewport &&
67
- isRichEditingEnabled
68
- );
65
+ return {
66
+ showBlockBreadcrumbsOption:
67
+ ! isDistractionFreeEnabled &&
68
+ isLargeViewport &&
69
+ isRichEditingEnabled,
70
+ showCollaborationOptions:
71
+ isCollaborationEnabledForCurrentPost(),
72
+ };
69
73
  },
70
74
  [ isLargeViewport ]
71
75
  );
76
+
72
77
  const { setIsListViewOpened, setIsInserterOpened } =
73
78
  useDispatch( editorStore );
74
79
  const { set: setPreference } = useDispatch( preferencesStore );
@@ -120,24 +125,30 @@ function PreferencesModalContents( { extraSections = {} } ) {
120
125
  ) }
121
126
  label={ __( 'Show starter patterns' ) }
122
127
  />
123
- <PreferenceToggleControl
124
- scope="core"
125
- featureName="showCollaborationCursor"
126
- help={ __(
127
- 'Show your own avatar inside blocks during collaborative editing sessions.'
128
- ) }
129
- label={ __( 'Show avatar in blocks' ) }
130
- />
131
- <PreferenceToggleControl
132
- scope="core"
133
- featureName="showCollaborationNotifications"
134
- help={ __(
135
- 'Show notifications when collaborators join, leave, or save the post.'
136
- ) }
137
- label={ __(
138
- 'Show collaboration notifications'
139
- ) }
140
- />
128
+ { showCollaborationOptions && (
129
+ <>
130
+ <PreferenceToggleControl
131
+ scope="core"
132
+ featureName="showCollaborationCursor"
133
+ help={ __(
134
+ 'Show your own avatar inside blocks during collaborative editing sessions.'
135
+ ) }
136
+ label={ __(
137
+ 'Show avatar in blocks'
138
+ ) }
139
+ />
140
+ <PreferenceToggleControl
141
+ scope="core"
142
+ featureName="showCollaborationNotifications"
143
+ help={ __(
144
+ 'Show notifications when collaborators join, leave, or save the post.'
145
+ ) }
146
+ label={ __(
147
+ 'Show collaboration notifications'
148
+ ) }
149
+ />
150
+ </>
151
+ ) }
141
152
  </PreferencesModalSection>
142
153
  <PreferencesModalSection
143
154
  title={ __( 'Document settings' ) }
@@ -350,6 +361,7 @@ function PreferencesModalContents( { extraSections = {} } ) {
350
361
  ].filter( Boolean ),
351
362
  [
352
363
  showBlockBreadcrumbsOption,
364
+ showCollaborationOptions,
353
365
  extraSections,
354
366
  setIsInserterOpened,
355
367
  setIsListViewOpened,
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { PanelBody } from '@wordpress/components';
5
4
  import { store as blockEditorStore } from '@wordpress/block-editor';
6
5
  import { useSelect } from '@wordpress/data';
7
6
  import { __ } from '@wordpress/i18n';
@@ -9,7 +8,7 @@ import { __ } from '@wordpress/i18n';
9
8
  /**
10
9
  * Internal dependencies
11
10
  */
12
- import PostPanelRow from '../post-panel-row';
11
+ import RevisionDiffPanel from '../revision-diff-panel';
13
12
 
14
13
  /**
15
14
  * Panel that shows changed block attributes for the selected block
@@ -27,48 +26,14 @@ export default function RevisionBlockDiffPanel() {
27
26
  return null;
28
27
  }
29
28
 
30
- const diffInfo = block.attributes?.__revisionDiffStatus;
31
- const changedAttributes = diffInfo?.changedAttributes;
32
-
33
- if ( ! changedAttributes ) {
34
- return null;
35
- }
36
-
37
- const fields = Object.entries( changedAttributes ).map(
38
- ( [ key, parts ] ) => (
39
- <PostPanelRow key={ key } label={ key }>
40
- <span className="editor-revision-fields-diff__value">
41
- { parts.map( ( part, index ) => {
42
- if ( part.added ) {
43
- return (
44
- <ins
45
- key={ index }
46
- className="editor-revision-fields-diff__added"
47
- >
48
- { part.value }
49
- </ins>
50
- );
51
- }
52
- if ( part.removed ) {
53
- return (
54
- <del
55
- key={ index }
56
- className="editor-revision-fields-diff__removed"
57
- >
58
- { part.value }
59
- </del>
60
- );
61
- }
62
- return <span key={ index }>{ part.value }</span>;
63
- } ) }
64
- </span>
65
- </PostPanelRow>
66
- )
67
- );
29
+ const changedAttributes =
30
+ block.attributes?.__revisionDiffStatus?.changedAttributes;
68
31
 
69
32
  return (
70
- <PanelBody title={ __( 'Changed attributes' ) } initialOpen>
71
- { fields }
72
- </PanelBody>
33
+ <RevisionDiffPanel
34
+ title={ __( 'Changed attributes' ) }
35
+ entries={ changedAttributes }
36
+ initialOpen
37
+ />
73
38
  );
74
39
  }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { PanelBody } from '@wordpress/components';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import PostPanelRow from '../post-panel-row';
10
+
11
+ /**
12
+ * Renders a panel of word-level diffs.
13
+ *
14
+ * @param {Object} props
15
+ * @param {string} props.title Panel title.
16
+ * @param {Object} props.entries Map of key → diffWords parts arrays.
17
+ * @param {boolean} props.initialOpen Whether the panel starts open.
18
+ */
19
+ export default function RevisionDiffPanel( { title, entries, initialOpen } ) {
20
+ if ( ! entries ) {
21
+ return null;
22
+ }
23
+
24
+ const fields = Object.entries( entries ).map( ( [ key, parts ] ) => (
25
+ <PostPanelRow key={ key } label={ key }>
26
+ <span className="editor-revision-fields-diff__value">
27
+ { parts.map( ( part, index ) => {
28
+ if ( part.added ) {
29
+ return (
30
+ <ins
31
+ key={ index }
32
+ className="editor-revision-fields-diff__added"
33
+ >
34
+ { part.value }
35
+ </ins>
36
+ );
37
+ }
38
+ if ( part.removed ) {
39
+ return (
40
+ <del
41
+ key={ index }
42
+ className="editor-revision-fields-diff__removed"
43
+ >
44
+ { part.value }
45
+ </del>
46
+ );
47
+ }
48
+ return <span key={ index }>{ part.value }</span>;
49
+ } ) }
50
+ </span>
51
+ </PostPanelRow>
52
+ ) );
53
+
54
+ return (
55
+ <PanelBody title={ title } initialOpen={ initialOpen }>
56
+ { fields }
57
+ </PanelBody>
58
+ );
59
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { diffWords } from 'diff/lib/diff/word';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { useSelect } from '@wordpress/data';
10
+ import { useMemo } from '@wordpress/element';
11
+ import { __ } from '@wordpress/i18n';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import RevisionDiffPanel from '../revision-diff-panel';
17
+ import { store as editorStore } from '../../store';
18
+ import { unlock } from '../../lock-unlock';
19
+
20
+ /**
21
+ * Safely stringifies a value for display and comparison.
22
+ *
23
+ * @param {*} value The value to stringify.
24
+ * @return {string} The stringified value.
25
+ */
26
+ function stringifyValue( value ) {
27
+ if ( value === null || value === undefined ) {
28
+ return '';
29
+ }
30
+ if ( typeof value === 'object' ) {
31
+ return JSON.stringify( value, null, 2 );
32
+ }
33
+ return String( value );
34
+ }
35
+
36
+ /**
37
+ * Panel that shows meta field diffs between the current revision and
38
+ * the previous revision in the document sidebar during revision mode.
39
+ */
40
+ export default function RevisionFieldsDiffPanel() {
41
+ const { revision, previousRevision } = useSelect( ( select ) => {
42
+ const { getCurrentRevision, getPreviousRevision } = unlock(
43
+ select( editorStore )
44
+ );
45
+
46
+ return {
47
+ revision: getCurrentRevision(),
48
+ previousRevision: getPreviousRevision(),
49
+ };
50
+ }, [] );
51
+
52
+ const entries = useMemo( () => {
53
+ if ( ! revision ) {
54
+ return null;
55
+ }
56
+
57
+ const revisionMeta = revision.meta ?? {};
58
+ const previousMeta = previousRevision?.meta ?? {};
59
+ const allMetaKeys = new Set( [
60
+ ...Object.keys( revisionMeta ),
61
+ ...Object.keys( previousMeta ),
62
+ ] );
63
+
64
+ const result = {};
65
+
66
+ for ( const key of allMetaKeys ) {
67
+ const revStr = stringifyValue( revisionMeta[ key ] );
68
+ const prevStr = stringifyValue( previousMeta[ key ] );
69
+
70
+ if ( ! revStr && ! prevStr ) {
71
+ continue;
72
+ }
73
+
74
+ result[ key ] = diffWords( prevStr, revStr );
75
+ }
76
+
77
+ if ( Object.keys( result ).length === 0 ) {
78
+ return null;
79
+ }
80
+
81
+ return result;
82
+ }, [ revision, previousRevision ] );
83
+
84
+ return (
85
+ <RevisionDiffPanel
86
+ title={ __( 'Meta' ) }
87
+ entries={ entries }
88
+ initialOpen={ false }
89
+ />
90
+ );
91
+ }
@@ -7,6 +7,7 @@ import { store as coreDataStore } from '@wordpress/core-data';
7
7
  import { DataForm } from '@wordpress/dataviews';
8
8
  import { __experimentalVStack as VStack } from '@wordpress/components';
9
9
  import { useMemo } from '@wordpress/element';
10
+ import { useViewConfig } from '@wordpress/views';
10
11
 
11
12
  /**
12
13
  * Internal dependencies
@@ -16,70 +17,23 @@ import PostPanelSection from '../post-panel-section';
16
17
  import { store as editorStore } from '../../store';
17
18
  import PostTrash from '../post-trash';
18
19
  import usePostFields from '../post-fields';
19
- import { unlock } from '../../lock-unlock';
20
20
  import { usePostTemplatePanelMode } from '../post-template/hooks';
21
21
 
22
- const form = {
23
- layout: {
24
- type: 'panel',
25
- },
26
- fields: [
27
- {
28
- id: 'featured_media',
29
- layout: {
30
- type: 'regular',
31
- labelPosition: 'none',
32
- },
33
- },
34
- {
35
- id: 'post-content-info',
36
- layout: {
37
- type: 'regular',
38
- labelPosition: 'none',
39
- },
40
- },
41
- {
42
- id: 'status',
43
- label: __( 'Status' ),
44
- children: [
45
- {
46
- id: 'status',
47
- layout: { type: 'regular', labelPosition: 'none' },
48
- },
49
- 'password',
50
- ],
51
- },
52
- 'date',
53
- 'slug',
54
- 'author',
55
- 'template',
56
- {
57
- id: 'discussion',
58
- label: __( 'Discussion' ),
59
- children: [
60
- {
61
- id: 'comment_status',
62
- layout: { type: 'regular', labelPosition: 'none' },
63
- },
64
- 'ping_status',
65
- ],
66
- },
67
- 'parent',
68
- 'format',
69
- ],
70
- };
22
+ const EMPTY_FORM = { layout: { type: 'panel' }, fields: [] };
71
23
 
72
24
  export default function DataFormPostSummary( { onActionPerformed } ) {
73
25
  const { postType, postId } = useSelect( ( select ) => {
74
- const { getCurrentPostType, getCurrentPostId } = unlock(
75
- select( editorStore )
76
- );
26
+ const { getCurrentPostType, getCurrentPostId } = select( editorStore );
77
27
  return {
78
28
  postType: getCurrentPostType(),
79
29
  postId: getCurrentPostId(),
80
30
  };
81
31
  }, [] );
82
-
32
+ const { form: formConfig } = useViewConfig( {
33
+ kind: 'postType',
34
+ name: postType,
35
+ } );
36
+ const form = formConfig ?? EMPTY_FORM;
83
37
  const record = useSelect(
84
38
  ( select ) => {
85
39
  if ( ! postType || ! postId ) {
@@ -172,7 +126,6 @@ export default function DataFormPostSummary( { onActionPerformed } ) {
172
126
 
173
127
  editEntityRecord( 'postType', postType, postId, edits );
174
128
  };
175
-
176
129
  return (
177
130
  <PostPanelSection className="editor-post-summary">
178
131
  <VStack spacing={ 4 }>
@@ -26,12 +26,15 @@ import PatternOverridesPanel from '../pattern-overrides-panel';
26
26
  import PluginDocumentSettingPanel from '../plugin-document-setting-panel';
27
27
  import PluginSidebar from '../plugin-sidebar';
28
28
  import PostSummary from './post-summary';
29
+ import PostRevisionSummary from './post-revision-summary';
29
30
  import PostTaxonomiesPanel from '../post-taxonomies/panel';
30
31
  import PostTransformPanel from '../post-transform-panel';
31
32
  import SidebarHeader from './header';
33
+ import TemplateActionsPanel from '../template-actions-panel';
32
34
  import TemplateContentPanel from '../template-content-panel';
33
35
  import TemplatePartContentPanel from '../template-part-content-panel';
34
36
  import { MediaMetadataPanel } from '../media';
37
+ import PostRevisionsPanel from '../post-revisions-panel';
35
38
  import RevisionBlockDiffPanel from '../revision-block-diff';
36
39
  import useAutoSwitchEditorSidebars from '../provider/use-auto-switch-editor-sidebars';
37
40
  import { sidebars } from './constants';
@@ -95,6 +98,35 @@ const SidebarContent = ( {
95
98
  }
96
99
  }, [ tabName ] );
97
100
 
101
+ let tabContent;
102
+ if ( isAttachment ) {
103
+ tabContent = (
104
+ <MediaMetadataPanel onActionPerformed={ onActionPerformed } />
105
+ );
106
+ } else if ( isRevisionsMode ) {
107
+ tabContent = <PostRevisionSummary />;
108
+ } else {
109
+ tabContent = (
110
+ <>
111
+ <PostSummary onActionPerformed={ onActionPerformed } />
112
+ <PluginDocumentSettingPanel.Slot />
113
+ <TemplateContentPanel />
114
+ { window?.__experimentalDataFormInspector &&
115
+ [ 'post', 'page' ].includes( postType ) && (
116
+ <>
117
+ <TemplateActionsPanel />
118
+ <PostRevisionsPanel />
119
+ </>
120
+ ) }
121
+ <TemplatePartContentPanel />
122
+ <PostTransformPanel />
123
+ <PostTaxonomiesPanel />
124
+ <PatternOverridesPanel />
125
+ { extraPanels }
126
+ </>
127
+ );
128
+ }
129
+
98
130
  return (
99
131
  <PluginSidebar
100
132
  identifier={ tabName }
@@ -119,28 +151,7 @@ const SidebarContent = ( {
119
151
  >
120
152
  <Tabs.Context.Provider value={ tabsContextValue }>
121
153
  <Tabs.TabPanel tabId={ sidebars.document } focusable={ false }>
122
- { isAttachment ? (
123
- <MediaMetadataPanel
124
- onActionPerformed={ onActionPerformed }
125
- />
126
- ) : (
127
- <>
128
- <PostSummary
129
- onActionPerformed={ onActionPerformed }
130
- />
131
- { ! isRevisionsMode && (
132
- <>
133
- <PluginDocumentSettingPanel.Slot />
134
- <TemplateContentPanel />
135
- <TemplatePartContentPanel />
136
- <PostTransformPanel />
137
- <PostTaxonomiesPanel />
138
- <PatternOverridesPanel />
139
- { extraPanels }
140
- </>
141
- ) }
142
- </>
143
- ) }
154
+ { tabContent }
144
155
  </Tabs.TabPanel>
145
156
  { ! isAttachment && (
146
157
  <Tabs.TabPanel tabId={ sidebars.block } focusable={ false }>
@@ -0,0 +1,50 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { __experimentalVStack as VStack } from '@wordpress/components';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { store as editorStore } from '../../store';
11
+ import { unlock } from '../../lock-unlock';
12
+ import RevisionAuthorPanel from '../revision-author-panel';
13
+ import RevisionCreatedPanel from '../revision-created-panel';
14
+ import { PostContentInformationUI } from '../post-content-information';
15
+ import RevisionFieldsDiffPanel from '../revision-fields-diff';
16
+ import PostPanelSection from '../post-panel-section';
17
+ import PostCardPanel from '../post-card-panel';
18
+ import { OpenRevisionsClassicScreen } from './post-summary';
19
+
20
+ export default function PostRevisionSummary() {
21
+ const { revisionId, postId, postContent } = useSelect( ( select ) => {
22
+ const { getCurrentRevisionId, getCurrentRevision, getCurrentPostId } =
23
+ unlock( select( editorStore ) );
24
+ const _revisionId = getCurrentRevisionId();
25
+ return {
26
+ revisionId: _revisionId,
27
+ postId: getCurrentPostId(),
28
+ postContent: _revisionId && getCurrentRevision()?.content?.raw,
29
+ };
30
+ }, [] );
31
+ if ( ! revisionId ) {
32
+ return null;
33
+ }
34
+ return (
35
+ <>
36
+ <PostPanelSection className="editor-post-summary">
37
+ <VStack spacing={ 4 }>
38
+ <PostCardPanel postId={ postId } hideActions />
39
+ <VStack spacing={ 1 }>
40
+ <PostContentInformationUI postContent={ postContent } />
41
+ <RevisionCreatedPanel />
42
+ </VStack>
43
+ <OpenRevisionsClassicScreen revisionId={ revisionId } />
44
+ <RevisionAuthorPanel />
45
+ </VStack>
46
+ </PostPanelSection>
47
+ <RevisionFieldsDiffPanel />
48
+ </>
49
+ );
50
+ }