Skip to content

Commit

Permalink
Adding author display name and avatar to rest response
Browse files Browse the repository at this point in the history
Redesigning the buttons view
Rationalizing rest API return properties
  • Loading branch information
ramonjd committed Apr 14, 2023
1 parent 461d7ad commit 408a755
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,79 +34,11 @@ public function register_routes() {
),
),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
parent::register_routes();
}

/**
* Retrieves the global styles type' schema, conforming to JSON Schema.
*
* @since 5.9.0
* @since 6.3 Adds `revisions` schema.
*
* @return array Item schema data.
*/
public function get_item_schema() {
if ( $this->schema ) {
return $this->add_additional_fields_schema( $this->schema );
}

$schema = array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => $this->post_type,
'type' => 'object',
'properties' => array(
'id' => array(
'description' => __( 'ID of global styles config.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'embed', 'view', 'edit' ),
'readonly' => true,
),
'styles' => array(
'description' => __( 'Global styles.', 'gutenberg' ),
'type' => array( 'object' ),
'context' => array( 'view', 'edit' ),
),
'settings' => array(
'description' => __( 'Global settings.', 'gutenberg' ),
'type' => array( 'object' ),
'context' => array( 'view', 'edit' ),
),
'title' => array(
'description' => __( 'Title of the global styles variation.', 'gutenberg' ),
'type' => array( 'object', 'string' ),
'default' => '',
'context' => array( 'embed', 'view', 'edit' ),
'properties' => array(
'raw' => array(
'description' => __( 'Title for the global styles variation, as it exists in the database.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit', 'embed' ),
),
'rendered' => array(
'description' => __( 'HTML title for the post, transformed for display.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit', 'embed' ),
'readonly' => true,
),
),
),
'revisions' => array(
'description' => __( 'Global styles revisions.', 'gutenberg' ),
'type' => array( 'object' ),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
),
);

$this->schema = $schema;

return $this->add_additional_fields_schema( $this->schema );
}

/**
* Returns revisions of the given global styles config custom post type.
*
Expand All @@ -129,7 +61,6 @@ public function get_item_revisions( $request ) {
$user_theme_revisions = wp_get_post_revisions(
$post->ID,
array(
'author' => $post->post_author,
'posts_per_page' => 100,
)
);
Expand All @@ -148,13 +79,22 @@ public function get_item_revisions( $request ) {
$revisions[] = array(
'styles' => ! empty( $config['styles'] ) ? $config['styles'] : new stdClass(),
'settings' => ! empty( $config['settings'] ) ? $config['settings'] : new stdClass(),
'title' => array(
'date' => array(
'raw' => $revision->post_modified,
/* translators: 1: Human-readable time difference, 2: short date combined to show rendered revision date. */
'rendered' => sprintf( __( '%1$s (%2$s)', 'gutenberg' ), $time_ago, $date_short ),
),
'id' => $id,
'is_latest' => array_key_first( $user_theme_revisions ) === $id,
'author' => array(
'display_name' => get_the_author_meta( 'display_name', $post->post_author ),
'avatar_url' => get_avatar_url(
$post->post_author,
array(
'size' => 24,
)
),
),
);
}
}
Expand Down
10 changes: 1 addition & 9 deletions packages/core-data/src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -508,17 +508,9 @@ export const __experimentalGetCurrentThemeGlobalStylesRevisions =
const revisionsURL =
currentGlobalStyles?._links?.[ 'version-history' ]?.[ 0 ]?.href;
if ( revisionsURL ) {
const restRevisions = await apiFetch( {
const revisions = await apiFetch( {
url: revisionsURL,
} );
const revisions = restRevisions?.map( ( revision ) =>
Object.fromEntries(
Object.entries( revision ).map( ( [ key, value ] ) => [
camelCase( key ),
value,
] )
)
);
dispatch.__experimentalReceiveThemeGlobalStyleRevisions(
currentGlobalStyles?.id,
revisions
Expand Down
98 changes: 73 additions & 25 deletions packages/edit-site/src/components/global-styles/screen-revisions.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
useMemo,
} from '@wordpress/element';
import {
check,
undo as undoIcon,
redo as redoIcon,
backup as backupIcon,
Expand All @@ -44,11 +43,27 @@ const { GlobalStylesContext } = unlock( blockEditorPrivateApis );
function RevisionsSelect( { userRevisions, currentRevisionId, onChange } ) {
const userRevisionsOptions = useMemo( () => {
return ( userRevisions ?? [] ).map( ( revision ) => {
const { id, date, author, is_latest: isLatest } = revision;
const revisionTitle = decodeEntities( date?.rendered );
return {
value: revision.id,
label: revision.isLatest
? __( 'Latest saved revision' )
: decodeEntities( revision.title.rendered ),
value: id,
label: isLatest
? sprintf(
/* translators: %(name)s author display name, %(date)s: human-friendly revision creation date */
__( 'Current revision by %(name)s from %(date)s)' ),
{
name: author?.display_name,
date: revisionTitle,
}
)
: sprintf(
/* translators: %(name)s author display name, %(date)s: human-friendly revision creation date */
__( 'Revision by %(name)s from %(date)s' ),
{
name: author?.display_name,
date: revisionTitle,
}
),
};
} );
}, [ userRevisions ] );
Expand All @@ -72,45 +87,78 @@ function RevisionsSelect( { userRevisions, currentRevisionId, onChange } ) {
function RevisionsButtons( { userRevisions, currentRevisionId, onChange } ) {
return (
<>
<ol className="edit-site-global-styles-screen-revisions__revisions-list">
<ol
className="edit-site-global-styles-screen-revisions__revisions-list"
aria-label={ __( 'Global styles revisions' ) }
role="group"
>
{ userRevisions.map( ( revision ) => {
revision.is_latest = undefined;
const isActive = revision?.id === currentRevisionId;
const revisionTitle = decodeEntities(
revision.title.rendered
);
const { id, date, author, is_latest: isLatest } = revision;
const isActive = id === currentRevisionId;
const revisionTitle = decodeEntities( date?.rendered );

return (
<li key={ `user-styles-revision-${ revision.id }` }>
<li key={ `user-styles-revision-${ id }` }>
<Button
className={ classnames(
'edit-site-global-styles-screen-revisions__revision-item',
{
'is-current': isActive,
}
) }
variant={ isActive ? 'tertiary' : 'secondary' }
disabled={ isActive }
icon={ revision.isLatest ? check : null }
onClick={ () => {
onChange( revision );
} }
aria-label={
revision.isLatest
? __( 'Restore latest saved revision' )
isLatest
? sprintf(
/* translators: %(name)s author display name, %(date)s: human-friendly revision creation date */
__(
'Revision by %(name)s from %(date)s (current)'
),
{
name: author?.display_name,
date: revisionTitle,
}
)
: sprintf(
/* translators: %s: human-friendly revision creation date */
/* translators: %(name)s author display name, %(date)s: human-friendly revision creation date */
__(
'Restore revision from %s'
'Revision by %(name)s from %(date)s'
),
revisionTitle
{
name: author?.display_name,
date: revisionTitle,
}
)
}
>
<span className="edit-site-global-styles-screen-revisions__title">
{ revision.isLatest
? __( 'Latest saved revision' )
: revisionTitle }
<span className="edit-site-global-styles-screen-revisions__description">
<span className="edit-site-global-styles-screen-revisions__avatar">
<img
alt={ author?.display_name }
src={ author?.avatar_url }
/>
</span>
<span>
{ isLatest
? sprintf(
/* translators: %s: author display name */
__(
'Current revision by %s'
),
author?.display_name
)
: sprintf(
/* translators: %s: author display name */
__( 'Revision by %s' ),
author?.display_name
) }
</span>
<span className="edit-site-global-styles-screen-revisions__date">
{ revisionTitle }
</span>
</span>
</Button>
</li>
Expand Down Expand Up @@ -174,7 +222,7 @@ function ScreenRevisions() {
canRestoreCachedConfig &&
! isGlobalStyleConfigEqual(
cachedUserConfig,
userRevisions.find( ( revision ) => revision.isLatest === true )
userRevisions.find( ( revision ) => revision.is_latest === true )
);

return (
Expand All @@ -187,7 +235,7 @@ function ScreenRevisions() {
/>
<div className="edit-site-global-styles-screen-revisions">
<VStack spacing={ 3 }>
<Subtitle>{ __( 'REVISIONS' ) }</Subtitle>
<Subtitle>{ __( 'Revisions' ) }</Subtitle>
<RevisionsComponent
onChange={ restoreRevision }
currentRevisionId={ currentRevisionId }
Expand Down
39 changes: 36 additions & 3 deletions packages/edit-site/src/components/global-styles/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,16 @@
.edit-site-global-styles-screen-revisions__revisions-list {
list-style: none;
margin: 0;
li {
margin-bottom: $grid-unit-20;
}
}

.edit-site-global-styles-screen-revisions__revision-item {
justify-content: center;
width: 100%;
height: auto;
&.is-current:disabled {
color: $white;
background: $gray-900;
background: $gray-400;
}
}

Expand All @@ -222,3 +224,34 @@
padding-top: 0;
height: auto;
}

.edit-site-global-styles-screen-revisions__description {
display: grid;
grid-template-columns: max-content 1fr;
grid-template-rows: 1fr 1fr;
gap: $grid-unit-05 $grid-unit-10;
grid-auto-flow: row;
align-items: start;
justify-items: start;
grid-template-areas:
"edit-site-global-styles-screen-revisions__avatar ."
"edit-site-global-styles-screen-revisions__avatar .";
.edit-site-global-styles-screen-revisions__avatar {
grid-area: edit-site-global-styles-screen-revisions__avatar;
width: 24px;
height: 24px;
position: relative;
overflow: hidden;
border-radius: 50%;
img {
display: inline;
margin: 0 auto;
height: 100%;
width: auto;
}
}
.edit-site-global-styles-screen-revisions__date {
font-size: 11px;
}
}

21 changes: 15 additions & 6 deletions packages/edit-site/src/components/global-styles/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
privateApis as blockEditorPrivateApis,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import { __, sprintf, _n } from '@wordpress/i18n';
import { store as preferencesStore } from '@wordpress/preferences';
import { moreVertical } from '@wordpress/icons';
import { store as coreStore } from '@wordpress/core-data';
Expand Down Expand Up @@ -50,27 +50,28 @@ const { Slot: GlobalStylesMenuSlot, Fill: GlobalStylesMenuFill } =

function GlobalStylesActionMenu() {
const { toggle } = useDispatch( preferencesStore );
const { canEditCSS, hasRevisions } = useSelect( ( select ) => {
const { canEditCSS, revisionsCount } = useSelect( ( select ) => {
const { getEntityRecord, __experimentalGetCurrentGlobalStyles } =
select( coreStore );
const currentGlobalStyles = __experimentalGetCurrentGlobalStyles();
const globalStyles = currentGlobalStyles?.id
? getEntityRecord( 'root', 'globalStyles', currentGlobalStyles?.id )
: undefined;
const revisionsCount =
globalStyles?._links?.[ 'version-history' ]?.[ 0 ]?.count;

return {
canEditCSS:
!! globalStyles?._links?.[ 'wp:action-edit-css' ] ?? false,
hasRevisions: revisionsCount && revisionsCount > 1,
revisionsCount:
( globalStyles?._links?.[ 'version-history' ]?.[ 0 ]?.count ??
0 ) + 1,
};
}, [] );
const { useGlobalStylesReset } = unlock( blockEditorPrivateApis );
const [ canReset, onReset ] = useGlobalStylesReset();
const { goTo } = useNavigator();
const loadCustomCSS = () => goTo( '/css' );
const loadRevisions = () => goTo( '/revisions' );
const hasRevisions = revisionsCount >= 2;
return (
<GlobalStylesMenuFill>
<DropdownMenu
Expand Down Expand Up @@ -98,7 +99,15 @@ function GlobalStylesActionMenu() {
...( hasRevisions
? [
{
title: __( 'Revisions' ),
title: sprintf(
/* translators: %d: number of revisions */
_n(
'%d Revision',
'%d Revisions',
revisionsCount
),
revisionsCount
),
onClick: loadRevisions,
},
]
Expand Down
Loading

0 comments on commit 408a755

Please sign in to comment.