const apiFetch = require( '@wordpress/api-fetch' ); const { Button, Modal, TextControl } = require( '@wordpress/components' ); const { compose } = require( '@wordpress/compose' ); const { withSelect, withDispatch } = require( '@wordpress/data' ); const { PluginDocumentSettingPanel } = require( '@wordpress/edit-post' ); const { useState } = require( '@wordpress/element' ); const { __, _n, sprintf } = require( '@wordpress/i18n' ); const { registerPlugin } = require( '@wordpress/plugins' ); const metaKey = window.wpRevisionsControlBlockEditorSettings.metaKey; const slug = 'wp-revisions-control'; /** * The settings panel for the plugin. * * @param {Object} props Component props. * @param {number} props.limit Number of revisions to keep. * @param {Function} props.manualPurge Callback to manually purge revisions. * @param {boolean} props.showPurgeButton Whether there are enough revisions to * show the purge button. * @param {Function} props.updateMeta Callback to update the revisions-limit for * this post. * @return {JSX.Element} Sidebar panel. */ const Render = ( { limit, manualPurge, showPurgeButton, updateMeta } ) => ( <PluginDocumentSettingPanel name={ slug } title={ __( 'WP Revisions Control', 'wp_revisions_control' ) } className={ slug } > <TextControl label={ __( 'Number of revisions to retain:', 'wp_revisions_control' ) } help={ __( 'Leave blank to keep all revisions.', 'wp_revisions_control' ) } value={ limit } onChange={ updateMeta } /> { showPurgeButton && PurgeModal( limit, manualPurge ) } </PluginDocumentSettingPanel> ); /** * Modal to confirm and trigger manual purge of excess revisions. * * @param {number} limit Number of revisions to keep. * @param {Function} manualPurge Callback to manually purge revisions. * @return {JSX.Element} Modal to confirm and trigger manual purge of excess * revisions. */ const PurgeModal = ( limit, manualPurge ) => { const [ isOpen, setOpen ] = useState( false ); const openModal = () => setOpen( true ); const closeModal = () => setOpen( false ); const closeModalAndPurge = () => { closeModal(); manualPurge(); }; const parsedLimit = parseInt( limit, 10 ); const modalText = 0 === parsedLimit ? __( 'This will remove all revisions.', 'wp_revisions_control' ) : // eslint-disable-next-line @wordpress/valid-sprintf sprintf( /* translators: 1. Number of revisions to keep. */ _n( 'This will remove all but the most-recent revision.', 'This will remove all but the %1$d most-recent revisions.', parsedLimit, 'wp_revisions_control' ), limit ); return ( <> <Button isSecondary onClick={ openModal }> { __( 'Purge excess revisions', 'wp_revisions_control' ) } </Button> { isOpen && ( <Modal title={ __( 'Purge excess revisions', 'wp_revisions_control' ) } contentLabel={ modalText } onRequestClose={ closeModal } > <p>{ modalText }</p> <Button isPrimary onClick={ closeModalAndPurge }> { __( 'Purge', 'wp_revisions_control' ) } </Button> <Button isSecondary onClick={ closeModal }> { __( 'Cancel', 'wp_revisions_control' ) } </Button> </Modal> ) } </> ); }; /** * Higher order component to render plugin's sidebar panel. */ const RevisionsControl = compose( [ withSelect( ( select ) => { const { getCurrentPostRevisionsCount, getEditedPostAttribute } = select( 'core/editor' ); const count = getCurrentPostRevisionsCount(); const limit = getEditedPostAttribute( 'meta' )[ metaKey ]; const showPurgeButton = Boolean( limit ) && count > parseInt( limit ); return { limit, showPurgeButton, }; } ), withDispatch( ( dispatch, { limit }, { select } ) => { const manualPurge = () => { const postId = select( 'core/editor' ).getCurrentPostId(); apiFetch( { path: `/wp-revisions-control/v1/schedule/${ postId }/${ parseInt( limit, 10 ) }`, method: 'PUT', } ).then( ( result ) => { let noticeType; let noticeText; if ( result ) { noticeType = 'success'; noticeText = __( 'Excess revisions scheduled for removal.', 'wp_revisions_control' ); } else { noticeType = 'error'; noticeText = __( 'Failed to schedule excess revisions for removal.', 'wp_revisions_control' ); } dispatch( 'core/notices' ).createNotice( noticeType, noticeText, { id: 'wp-revisions-control-scheduled-purge', isDismissible: true, type: 'snackbar', } ); } ); }; const updateMeta = ( value ) => { dispatch( 'core/editor' ).editPost( { meta: { [ metaKey ]: value, }, } ); }; return { manualPurge, updateMeta, }; } ), ] )( Render ); registerPlugin( slug, { render: RevisionsControl, icon: 'backup', } );