Skip to content

Commit 13d309f

Browse files
ntsekourast-hamanooandregaljasmussenjameskoster
authored
Experimental: Add revisions panel (WordPress#76735)
Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org> Co-authored-by: t-hamano <wildworks@git.wordpress.org> Co-authored-by: oandregal <oandregal@git.wordpress.org> Co-authored-by: jasmussen <joen@git.wordpress.org> Co-authored-by: jameskoster <jameskoster@git.wordpress.org> Co-authored-by: fcoveram <fcoveram@git.wordpress.org>
1 parent 84879c5 commit 13d309f

9 files changed

Lines changed: 285 additions & 110 deletions

File tree

packages/editor/src/components/post-card-panel/index.js

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
__experimentalText as Text,
1010
privateApis as componentsPrivateApis,
1111
} from '@wordpress/components';
12-
import { moreVertical, close } from '@wordpress/icons';
12+
import { close } from '@wordpress/icons';
1313
import { store as coreStore } from '@wordpress/core-data';
1414
import { useSelect } from '@wordpress/data';
1515
import { useMemo } from '@wordpress/element';
@@ -52,7 +52,7 @@ export default function PostCardPanel( {
5252
() => ( Array.isArray( postId ) ? postId : [ postId ] ),
5353
[ postId ]
5454
);
55-
const { postTitle, icon, labels, isRevision } = useSelect(
55+
const { postTitle, icon, labels } = useSelect(
5656
( select ) => {
5757
const { getEditedEntityRecord, getCurrentTheme, getPostType } =
5858
select( coreStore );
@@ -75,7 +75,6 @@ export default function PostCardPanel( {
7575
area: _record?.area,
7676
} ),
7777
labels: getPostType( parentPostType )?.labels,
78-
isRevision: true,
7978
};
8079
}
8180

@@ -146,24 +145,11 @@ export default function PostCardPanel( {
146145
) }
147146
</Text>
148147
{ ! hideActions && postIds.length === 1 && (
149-
<>
150-
{ isRevision ? (
151-
<Button
152-
size="small"
153-
icon={ moreVertical }
154-
label={ __( 'Actions' ) }
155-
disabled
156-
accessibleWhenDisabled
157-
className="editor-all-actions-button"
158-
/>
159-
) : (
160-
<PostActions
161-
postType={ postType }
162-
postId={ postIds[ 0 ] }
163-
onActionPerformed={ onActionPerformed }
164-
/>
165-
) }
166-
</>
148+
<PostActions
149+
postType={ postType }
150+
postId={ postIds[ 0 ] }
151+
onActionPerformed={ onActionPerformed }
152+
/>
167153
) }
168154
{ onClose && (
169155
<Button

packages/editor/src/components/post-content-information/index.js

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { store as coreStore } from '@wordpress/core-data';
1212
* Internal dependencies
1313
*/
1414
import { store as editorStore } from '../../store';
15-
import { unlock } from '../../lock-unlock';
1615
import {
1716
TEMPLATE_POST_TYPE,
1817
TEMPLATE_PART_POST_TYPE,
@@ -23,19 +22,9 @@ const AVERAGE_READING_RATE = 189;
2322

2423
// This component renders the wordcount and reading time for the post.
2524
export default function PostContentInformation() {
26-
const { postContent } = useSelect( ( select ) => {
25+
const postContent = useSelect( ( select ) => {
2726
const { getEditedPostAttribute, getCurrentPostType, getCurrentPostId } =
2827
select( editorStore );
29-
const { getCurrentRevision, isRevisionsMode } = unlock(
30-
select( editorStore )
31-
);
32-
33-
if ( isRevisionsMode() ) {
34-
return {
35-
postContent: getCurrentRevision()?.content?.raw,
36-
};
37-
}
38-
3928
const { canUser } = select( coreStore );
4029
const { getEntityRecord } = select( coreStore );
4130
const siteSettings = canUser( 'read', {
@@ -52,12 +41,12 @@ export default function PostContentInformation() {
5241
! [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE ].includes(
5342
postType
5443
);
55-
return {
56-
postContent:
57-
showPostContentInfo && getEditedPostAttribute( 'content' ),
58-
};
44+
return showPostContentInfo && getEditedPostAttribute( 'content' );
5945
}, [] );
46+
return <PostContentInformationUI postContent={ postContent } />;
47+
}
6048

49+
export function PostContentInformationUI( { postContent } ) {
6150
/*
6251
* translators: If your word count is based on single characters (e.g. East Asian characters),
6352
* enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import {
5+
PanelBody,
6+
Button,
7+
__experimentalHStack as HStack,
8+
__experimentalVStack as VStack,
9+
privateApis as componentsPrivateApis,
10+
} from '@wordpress/components';
11+
import { store as coreStore } from '@wordpress/core-data';
12+
import { DataViews } from '@wordpress/dataviews';
13+
import { dateI18n, getDate, humanTimeDiff, getSettings } from '@wordpress/date';
14+
import { useSelect, useDispatch } from '@wordpress/data';
15+
import { __ } from '@wordpress/i18n';
16+
import { authorField } from '@wordpress/fields';
17+
18+
/**
19+
* Internal dependencies
20+
*/
21+
import PostLastRevisionCheck from '../post-last-revision/check';
22+
import { store as editorStore } from '../../store';
23+
import { unlock } from '../../lock-unlock';
24+
25+
const { Badge } = unlock( componentsPrivateApis );
26+
const DAY_IN_MILLISECONDS = 86400000;
27+
const EMPTY_ARRAY = [];
28+
29+
const REVISIONS_QUERY = {
30+
per_page: 3,
31+
orderby: 'date',
32+
order: 'desc',
33+
context: 'embed',
34+
_fields: 'id,date,author',
35+
};
36+
const defaultLayouts = { activity: {} };
37+
const view = {
38+
type: 'activity',
39+
titleField: 'date',
40+
fields: [ 'author' ],
41+
layout: {
42+
density: 'compact',
43+
},
44+
};
45+
const fields = [
46+
{
47+
id: 'date',
48+
label: __( 'Date' ),
49+
render: ( { item } ) => {
50+
const dateNowInMs = getDate( null ).getTime();
51+
const date = getDate( item.date ?? null );
52+
const displayDate =
53+
dateNowInMs - date.getTime() > DAY_IN_MILLISECONDS
54+
? dateI18n(
55+
getSettings().formats.datetimeAbbreviated,
56+
date
57+
)
58+
: humanTimeDiff( date );
59+
return (
60+
<time
61+
className="editor-post-revisions-panel__revision-date"
62+
dateTime={ item.date }
63+
>
64+
{ displayDate }
65+
</time>
66+
);
67+
},
68+
enableSorting: false,
69+
enableHiding: false,
70+
},
71+
authorField,
72+
];
73+
const noop = () => {};
74+
const paginationInfo = {};
75+
76+
function PostRevisionsPanelContent() {
77+
const { setCurrentRevisionId } = unlock( useDispatch( editorStore ) );
78+
const { revisionsCount, revisions, isLoading, lastRevisionId } = useSelect(
79+
( select ) => {
80+
const { getCurrentPostId, getCurrentPostType } =
81+
select( editorStore );
82+
const {
83+
getCurrentPostRevisionsCount,
84+
getCurrentPostLastRevisionId,
85+
} = select( editorStore );
86+
const { getRevisions, isResolving } = select( coreStore );
87+
const query = [
88+
'postType',
89+
getCurrentPostType(),
90+
getCurrentPostId(),
91+
REVISIONS_QUERY,
92+
];
93+
const _revisions = getRevisions( ...query );
94+
return {
95+
revisionsCount: getCurrentPostRevisionsCount(),
96+
lastRevisionId: getCurrentPostLastRevisionId(),
97+
revisions: _revisions,
98+
isLoading: isResolving( 'getRevisions', query ),
99+
};
100+
},
101+
[]
102+
);
103+
return (
104+
<PanelBody
105+
title={
106+
<HStack justify="space-between" align="center" as="span">
107+
<span>{ __( 'Revisions' ) }</span>
108+
<Badge className="editor-post-revisions-panel__revisions-count">
109+
{ revisionsCount }
110+
</Badge>
111+
</HStack>
112+
}
113+
initialOpen={ false }
114+
>
115+
<VStack className="editor-post-revisions-panel">
116+
<DataViews
117+
view={ view }
118+
onChangeView={ noop }
119+
fields={ fields }
120+
data={ revisions || EMPTY_ARRAY }
121+
isLoading={ isLoading }
122+
paginationInfo={ paginationInfo }
123+
defaultLayouts={ defaultLayouts }
124+
getItemId={ ( item ) => item.id }
125+
isItemClickable={ () => true }
126+
onClickItem={ ( item ) => {
127+
setCurrentRevisionId( item.id );
128+
} }
129+
>
130+
<DataViews.Layout />
131+
</DataViews>
132+
<Button
133+
className="editor-post-revisions-panel__view-all"
134+
__next40pxDefaultSize
135+
variant="secondary"
136+
onClick={ () => setCurrentRevisionId( lastRevisionId ) }
137+
>
138+
{ __( 'View all revisions' ) }
139+
</Button>
140+
</VStack>
141+
</PanelBody>
142+
);
143+
}
144+
145+
export default function PostRevisionsPanel() {
146+
return (
147+
<PostLastRevisionCheck>
148+
<PostRevisionsPanelContent />
149+
</PostLastRevisionCheck>
150+
);
151+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.editor-post-revisions-panel {
2+
.editor-post-revisions-panel__view-all {
3+
justify-content: center;
4+
}
5+
6+
.editor-post-revisions-panel__revision-date {
7+
text-transform: uppercase;
8+
font-weight: 600;
9+
font-size: 12px;
10+
}
11+
}
12+
13+
.editor-post-revisions-panel__revisions-count {
14+
margin-top: -4.5px;
15+
margin-bottom: -4.5px;
16+
}

packages/editor/src/components/sidebar/dataform-post-summary.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import PostPanelSection from '../post-panel-section';
1616
import { store as editorStore } from '../../store';
1717
import PostTrash from '../post-trash';
1818
import usePostFields from '../post-fields';
19-
import { unlock } from '../../lock-unlock';
2019
import { usePostTemplatePanelMode } from '../post-template/hooks';
2120

2221
const form = {
@@ -72,15 +71,12 @@ const form = {
7271

7372
export default function DataFormPostSummary( { onActionPerformed } ) {
7473
const { postType, postId } = useSelect( ( select ) => {
75-
const { getCurrentPostType, getCurrentPostId } = unlock(
76-
select( editorStore )
77-
);
74+
const { getCurrentPostType, getCurrentPostId } = select( editorStore );
7875
return {
7976
postType: getCurrentPostType(),
8077
postId: getCurrentPostId(),
8178
};
8279
}, [] );
83-
8480
const record = useSelect(
8581
( select ) => {
8682
if ( ! postType || ! postId ) {
@@ -173,7 +169,6 @@ export default function DataFormPostSummary( { onActionPerformed } ) {
173169

174170
editEntityRecord( 'postType', postType, postId, edits );
175171
};
176-
177172
return (
178173
<PostPanelSection className="editor-post-summary">
179174
<VStack spacing={ 4 }>

packages/editor/src/components/sidebar/index.js

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ import PatternOverridesPanel from '../pattern-overrides-panel';
2626
import PluginDocumentSettingPanel from '../plugin-document-setting-panel';
2727
import PluginSidebar from '../plugin-sidebar';
2828
import PostSummary from './post-summary';
29+
import PostRevisionSummary from './post-revision-summary';
2930
import PostTaxonomiesPanel from '../post-taxonomies/panel';
30-
import RevisionFieldsDiffPanel from '../revision-fields-diff';
3131
import PostTransformPanel from '../post-transform-panel';
3232
import SidebarHeader from './header';
3333
import TemplateActionsPanel from '../template-actions-panel';
3434
import TemplateContentPanel from '../template-content-panel';
3535
import TemplatePartContentPanel from '../template-part-content-panel';
3636
import { MediaMetadataPanel } from '../media';
37+
import PostRevisionsPanel from '../post-revisions-panel';
3738
import RevisionBlockDiffPanel from '../revision-block-diff';
3839
import useAutoSwitchEditorSidebars from '../provider/use-auto-switch-editor-sidebars';
3940
import { sidebars } from './constants';
@@ -97,6 +98,35 @@ const SidebarContent = ( {
9798
}
9899
}, [ tabName ] );
99100

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+
100130
return (
101131
<PluginSidebar
102132
identifier={ tabName }
@@ -121,32 +151,7 @@ const SidebarContent = ( {
121151
>
122152
<Tabs.Context.Provider value={ tabsContextValue }>
123153
<Tabs.TabPanel tabId={ sidebars.document } focusable={ false }>
124-
{ isAttachment ? (
125-
<MediaMetadataPanel
126-
onActionPerformed={ onActionPerformed }
127-
/>
128-
) : (
129-
<>
130-
<PostSummary
131-
onActionPerformed={ onActionPerformed }
132-
/>
133-
{ isRevisionsMode && <RevisionFieldsDiffPanel /> }
134-
{ ! isRevisionsMode && (
135-
<>
136-
<PluginDocumentSettingPanel.Slot />
137-
<TemplateContentPanel />
138-
{ window?.__experimentalDataFormInspector && (
139-
<TemplateActionsPanel />
140-
) }
141-
<TemplatePartContentPanel />
142-
<PostTransformPanel />
143-
<PostTaxonomiesPanel />
144-
<PatternOverridesPanel />
145-
{ extraPanels }
146-
</>
147-
) }
148-
</>
149-
) }
154+
{ tabContent }
150155
</Tabs.TabPanel>
151156
{ ! isAttachment && (
152157
<Tabs.TabPanel tabId={ sidebars.block } focusable={ false }>

0 commit comments

Comments
 (0)