diff --git a/editor/components/post-permalink/index.js b/editor/components/post-permalink/index.js index 830de1932ac3f..c89f8ac97019e 100644 --- a/editor/components/post-permalink/index.js +++ b/editor/components/post-permalink/index.js @@ -9,60 +9,197 @@ import { connect } from 'react-redux'; import { Component } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Dashicon, ClipboardButton, Button } from '@wordpress/components'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal Dependencies */ import './style.scss'; -import { isEditedPostNew, getEditedPostAttribute } from '../../store/selectors'; +import { + isEditedPostNew, + isCurrentPostPublished, + getEditedPostAttribute, +} from '../../store/selectors'; +import { editPost } from '../../store/actions'; + +/** + * Constants + */ +const REGEXP_NEWLINES = /[\r\n]+/g; class PostPermalink extends Component { constructor() { super( ...arguments ); this.state = { - showCopyConfirmation: false, + editingSlug: false, + permalink: '', }; + this.getSlug = this.getSlug.bind( this ); + this.onChangePermalink = this.onChangePermalink.bind( this ); + this.onEditPermalink = this.onEditPermalink.bind( this ); + this.onSavePermalink = this.onSavePermalink.bind( this ); this.onCopy = this.onCopy.bind( this ); - this.onFinishCopy = this.onFinishCopy.bind( this ); + } + + /** + * Returns a permalink for a given post slug. + * + * @param {string} slug The post slug to insert in into the permalink. + * + * @returns {string} The full permalink. + */ + getPermalink( slug ) { + let permalink = this.props.link; + const samplePermalink = this.props.samplePermalink; + if ( samplePermalink ) { + permalink = samplePermalink[ 0 ].replace( '%postname%', slug || samplePermalink[ 1 ] ); + } + + return permalink; + } + + /** + * Returns the slug for the current post. + * + * @returns {string} The slug. + */ + getSlug() { + const { actualSlug, isPublished, samplePermalink } = this.props; + + if ( isPublished ) { + return actualSlug; + } + + if ( samplePermalink ) { + return samplePermalink[ 1 ]; + } + + return ''; + } + + componentDidMount() { + this.setState( { + permalink: this.getPermalink(), + slug: this.getSlug(), + } ); } componentWillUnmount() { clearTimeout( this.dismissCopyConfirmation ); } - onCopy() { + componentWillReceiveProps() { + const slug = this.getSlug(); this.setState( { - showCopyConfirmation: true, + permalink: this.getPermalink( slug ), + slug: slug, + } ); + } + + /** + * Event handler for the slug input field being changed. + * + * @param {Object} event Change event + */ + onChangePermalink( event ) { + this.setState( { slug: event.target.value } ); + } + + /** + * Event handler for the Edit button being clicked. + */ + onEditPermalink() { + this.setState( { editingSlug: true } ); + } + + /** + * Event handler for the slug being saved. + */ + onSavePermalink() { + this.setState( { + editingSlug: false, + permalink: this.getPermalink( this.state.slug ), } ); + const newSlug = this.state.slug.replace( REGEXP_NEWLINES, ' ' ); + this.props.onUpdate( newSlug ); } - onFinishCopy() { + /** + * Event handler for the copy button to show feedback. + */ + onCopy() { this.setState( { - showCopyConfirmation: false, + showCopyConfirmation: true, } ); + + clearTimeout( this.dismissCopyConfirmation ); + this.dismissCopyConfirmation = setTimeout( () => { + this.setState( { + showCopyConfirmation: false, + } ); + }, 4000 ); } render() { const { isNew, link } = this.props; + const { editingSlug, permalink, slug } = this.state; if ( isNew || ! link ) { return null; } + const prefix = permalink.replace( /[^/]+\/?$/, '' ); return (