UNPKG

@wordpress/editor

Version:
242 lines (222 loc) 5.89 kB
/** * External dependencies */ import { noop, get, some } from 'lodash'; import classnames from 'classnames'; /** * WordPress dependencies */ import { Button } from '@wordpress/components'; import { Component, createRef } from '@wordpress/element'; import { withSelect, withDispatch } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import PublishButtonLabel from './label'; export class PostPublishButton extends Component { constructor( props ) { super( props ); this.buttonNode = createRef(); this.createOnClick = this.createOnClick.bind( this ); this.closeEntitiesSavedStates = this.closeEntitiesSavedStates.bind( this ); this.state = { entitiesSavedStatesCallback: false, }; } componentDidMount() { if ( this.props.focusOnMount ) { this.buttonNode.current.focus(); } } createOnClick( callback ) { return ( ...args ) => { const { hasNonPostEntityChanges } = this.props; if ( hasNonPostEntityChanges ) { // The modal for multiple entity saving will open, // hold the callback for saving/publishing the post // so that we can call it if the post entity is checked. this.setState( { entitiesSavedStatesCallback: () => callback( ...args ), } ); // Open the save panel by setting its callback. // To set a function on the useState hook, we must set it // with another function (() => myFunction). Passing the // function on its own will cause an error when called. this.props.setEntitiesSavedStatesCallback( () => this.closeEntitiesSavedStates ); return noop; } return callback( ...args ); }; } closeEntitiesSavedStates( savedEntities ) { const { postType, postId } = this.props; const { entitiesSavedStatesCallback } = this.state; this.setState( { entitiesSavedStatesCallback: false }, () => { if ( savedEntities && some( savedEntities, ( elt ) => elt.kind === 'postType' && elt.name === postType && elt.key === postId ) ) { // The post entity was checked, call the held callback from `createOnClick`. entitiesSavedStatesCallback(); } } ); } render() { const { forceIsDirty, forceIsSaving, hasPublishAction, isBeingScheduled, isOpen, isPostSavingLocked, isPublishable, isPublished, isSaveable, isSaving, isAutoSaving, isToggle, onSave, onStatusChange, onSubmit = noop, onToggle, visibility, hasNonPostEntityChanges, } = this.props; const isButtonDisabled = isSaving || forceIsSaving || ! isSaveable || isPostSavingLocked || ( ! isPublishable && ! forceIsDirty ); const isToggleDisabled = isPublished || isSaving || forceIsSaving || ! isSaveable || ( ! isPublishable && ! forceIsDirty ); let publishStatus; if ( ! hasPublishAction ) { publishStatus = 'pending'; } else if ( visibility === 'private' ) { publishStatus = 'private'; } else if ( isBeingScheduled ) { publishStatus = 'future'; } else { publishStatus = 'publish'; } const onClickButton = () => { if ( isButtonDisabled ) { return; } onSubmit(); onStatusChange( publishStatus ); onSave(); }; const onClickToggle = () => { if ( isToggleDisabled ) { return; } onToggle(); }; const buttonProps = { 'aria-disabled': isButtonDisabled && ! hasNonPostEntityChanges, className: 'editor-post-publish-button', isBusy: ! isAutoSaving && isSaving && isPublished, isPrimary: true, onClick: this.createOnClick( onClickButton ), }; const toggleProps = { 'aria-disabled': isToggleDisabled && ! hasNonPostEntityChanges, 'aria-expanded': isOpen, className: 'editor-post-publish-panel__toggle', isBusy: isSaving && isPublished, isPrimary: true, onClick: this.createOnClick( onClickToggle ), }; const toggleChildren = isBeingScheduled ? __( 'Schedule…' ) : __( 'Publish' ); const buttonChildren = ( <PublishButtonLabel forceIsSaving={ forceIsSaving } hasNonPostEntityChanges={ hasNonPostEntityChanges } /> ); const componentProps = isToggle ? toggleProps : buttonProps; const componentChildren = isToggle ? toggleChildren : buttonChildren; return ( <> <Button ref={ this.buttonNode } { ...componentProps } className={ classnames( componentProps.className, 'editor-post-publish-button__button', { 'has-changes-dot': hasNonPostEntityChanges, } ) } > { componentChildren } </Button> </> ); } } export default compose( [ withSelect( ( select ) => { const { isSavingPost, isAutosavingPost, isEditedPostBeingScheduled, getEditedPostVisibility, isCurrentPostPublished, isEditedPostSaveable, isEditedPostPublishable, isPostSavingLocked, getCurrentPost, getCurrentPostType, getCurrentPostId, hasNonPostEntityChanges, } = select( 'core/editor' ); const _isAutoSaving = isAutosavingPost(); return { isSaving: isSavingPost() || _isAutoSaving, isAutoSaving: _isAutoSaving, isBeingScheduled: isEditedPostBeingScheduled(), visibility: getEditedPostVisibility(), isSaveable: isEditedPostSaveable(), isPostSavingLocked: isPostSavingLocked(), isPublishable: isEditedPostPublishable(), isPublished: isCurrentPostPublished(), hasPublishAction: get( getCurrentPost(), [ '_links', 'wp:action-publish' ], false ), postType: getCurrentPostType(), postId: getCurrentPostId(), hasNonPostEntityChanges: hasNonPostEntityChanges(), }; } ), withDispatch( ( dispatch ) => { const { editPost, savePost } = dispatch( 'core/editor' ); return { onStatusChange: ( status ) => editPost( { status }, { undoIgnore: true } ), onSave: savePost, }; } ), ] )( PostPublishButton );