Skip to content

Commit

Permalink
Export: Dummy UI flow for export process
Browse files Browse the repository at this point in the history
Squashed commits:
Exporter: Only allow one of Posts, Pages or Feedback to be selected
Exporter: Improve styling of the text under Feedback heading to match design
Exporter: Always show basic Export button, change text to clarify

The button displayed above the advanced settings is now 'Export All',
and is displayed even when the advanced settings are visible.

Exporter: Change wording to suit the switch to radios
  • Loading branch information
jordwest committed Jan 12, 2016
1 parent 39bf44f commit 780cb45
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 112 deletions.
43 changes: 20 additions & 23 deletions client/my-sites/exporter/advanced-settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import React, { PropTypes } from 'react';
/**
* Internal dependencies
*/
import CompactCard from 'components/card/compact';
import Button from 'components/forms/form-button';
import OptionFieldset from 'my-sites/exporter/option-fieldset';
import SpinnerButton from './spinner-button';

/**
* Displays additional options for customising an export
Expand All @@ -22,18 +21,11 @@ export default React.createClass( {

propTypes: {
// Event handlers
onToggleFieldset: PropTypes.func.isRequired,
onSelectPostType: PropTypes.func.isRequired,
onClickExport: PropTypes.func.isRequired,

// Data
posts: PropTypes.shape( {
isEnabled: PropTypes.bool.isRequired
} ),
pages: PropTypes.shape( {
isEnabled: PropTypes.bool.isRequired
} ),
feedback: PropTypes.shape( {
isEnabled: PropTypes.bool.isRequired
} )
postType: PropTypes.string
},

render() {
Expand Down Expand Up @@ -62,21 +54,21 @@ export default React.createClass( {

const buildOptionProps = key => ( {
legend: legends[ key ],
isEnabled: this.props[ key ].isEnabled,
isEnabled: this.props.postType === key,
menus: menus[ key ],
onToggleEnabled: () => this.props.onToggleFieldset( key )
onSelect: () => this.props.onSelectPostType( key )
} );

return (
<CompactCard className="exporter__more-info">
<div className="exporter__advanced-settings">
<h1 className="exporter__advanced-settings-title">
{ this.translate( 'Select Content to Export' ) }
{ this.translate( 'Select specific content to export' ) }
</h1>
<p>
{ this.translate(
'Use the options below to select specific content ' +
'types to download. You can deselect Posts, Pages, ' +
'and Feedback, or filter each by the listed parameters. ' +
'Use the options below to select a specific content ' +
'type to download. You can select Posts, Pages, ' +
'or Feedback, and filter by the listed parameters. ' +
'After making your selection you can download your ' +
'content in an .xml file.' ) }
</p>
Expand All @@ -87,10 +79,15 @@ export default React.createClass( {
description={ this.translate( 'Survey results etc.' ) }
/>
</div>
<Button isPrimary={ true }>
{ this.translate( 'Export Selected Content' ) }
</Button>
</CompactCard>
<SpinnerButton
className="exporter__export-button"
disabled={ !this.props.postType }
loading={ this.props.shouldShowProgress }
isPrimary={ true }
onClick={ this.props.onClickExport }
text={ this.translate( 'Export Selected Content' ) }
loadingText={ this.translate( 'Exporting…' ) } />
</div>
);
}
} );
74 changes: 39 additions & 35 deletions client/my-sites/exporter/exporter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,59 @@ import React, { PropTypes } from 'react';
/**
* Internal dependencies
*/
import CompactCard from 'components/card/compact';
import Gridicon from 'components/gridicon';
import Button from 'components/forms/form-button';
import FoldableCard from 'components/foldable-card';
import AdvancedSettings from 'my-sites/exporter/advanced-settings';
import SpinnerButton from './spinner-button';

export default React.createClass( {
displayName: 'Exporter',

propTypes: {
toggleAdvancedSettings: PropTypes.func.isRequired,
toggleSection: PropTypes.func.isRequired,
advancedSettings: PropTypes.shape( {
isVisible: PropTypes.bool.isRequired
} ).isRequired
startExport: PropTypes.func.isRequired,
setPostType: PropTypes.func.isRequired,

shouldShowProgress: PropTypes.bool.isRequired,
postType: PropTypes.string
},

render: function() {
const { toggleAdvancedSettings, toggleSection, advancedSettings } = this.props;
const { setPostType, startExport } = this.props;
const { postType, shouldShowProgress } = this.props;

const exportButton = (
<SpinnerButton
className="exporter__export-button"
loading={ shouldShowProgress }
isPrimary={ true }
onClick={ startExport }
text={ this.translate( 'Export All' ) }
loadingText={ this.translate( 'Exporting…' ) } />
);

return (
<div className="exporter">
<CompactCard>
<header>
<Button
className="exporter__export-button"
disabled={ false }
isPrimary={ true }
>
{ this.translate( 'Export' ) }
</Button>
<h1 className="exporter__title">
{ this.translate( 'Download an Export File' ) }
</h1>
</header>
<a href="#" onClick={ toggleAdvancedSettings }>
<Gridicon
icon={ advancedSettings.isVisible ? 'chevron-up' : 'chevron-down' }
size={ 16 } />
{ this.translate( 'Advanced Export Settings' ) }
</a>
</CompactCard>

{
advancedSettings.isVisible &&
<FoldableCard
actionButtonIcon="cog"
header={
<div>
<h1 className="exporter__title">
{ this.translate( 'Export your content' ) }
</h1>
<h2 className="exporter__subtitle">
{ this.translate( 'Or select specific content items to export' ) }
</h2>
</div>
}
summary={ exportButton }
expandedSummary={ exportButton }
>
<AdvancedSettings
{ ...advancedSettings }
onToggleFieldset={ toggleSection }
postType={ postType }
shouldShowProgress={ shouldShowProgress }
onSelectPostType={ setPostType }
onClickExport={ startExport }
/>
}
</FoldableCard>
</div>
);
}
Expand Down
20 changes: 13 additions & 7 deletions client/my-sites/exporter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,25 @@ import { compose } from 'lodash';
* Internal dependencies
*/
import Exporter from './exporter';
import { toggleAdvancedSettings, toggleSection } from 'state/site-settings/exporter/actions';
import { getUIState, shouldShowProgress } from 'state/site-settings/exporter/selectors';
import { setPostType, startExport } from 'state/site-settings/exporter/actions';

function mapStateToProps( state, ownProps ) {
const uiState = getUIState( state );

function mapStateToProps( state ) {
return {
advancedSettings: state.siteSettings.exporter.ui.toJS().advancedSettings,
}
site: ownProps.site,
postType: uiState.postType,
advancedSettings: uiState.advancedSettings,
shouldShowProgress: shouldShowProgress( state )
};
}

function mapDispatchToProps( dispatch ) {
return {
toggleAdvancedSettings: compose( dispatch, toggleAdvancedSettings ),
toggleSection: compose( dispatch, toggleSection )
}
setPostType: compose( dispatch, setPostType ),
startExport: () => startExport()( dispatch )
};
}

export default connect( mapStateToProps, mapDispatchToProps )( Exporter );
8 changes: 4 additions & 4 deletions client/my-sites/exporter/option-fieldset.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import PureRenderMixin from 'react-pure-render/mixin';
/**
* Internal dependencies
*/
import Checkbox from 'components/forms/form-checkbox';
import FormRadio from 'components/forms/form-radio';
import Select from 'components/forms/form-select';
import Label from 'components/forms/form-label';

Expand All @@ -24,7 +24,7 @@ module.exports = React.createClass( {
mixins: [ PureRenderMixin ],

propTypes: {
onToggleEnabled: PropTypes.func,
onSelect: PropTypes.func,

legend: PropTypes.string.isRequired,
isEnabled: PropTypes.bool.isRequired
Expand All @@ -41,9 +41,9 @@ module.exports = React.createClass( {
<div className="exporter__option-fieldset">

<Label className="exporter__option-fieldset-legend">
<Checkbox
<FormRadio
checked={ this.props.isEnabled }
onChange={ this.props.onToggleEnabled }/>
onChange={ this.props.onSelect }/>
<span className="exporter__option-fieldset-legend-text">{ this.props.legend }</span>
</Label>

Expand Down
59 changes: 59 additions & 0 deletions client/my-sites/exporter/spinner-button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* External dependencies
*/
import React, { PropTypes } from 'react';
import { omit } from 'lodash';

/**
* Internal dependencies
*/
import Button from 'components/forms/form-button';
import Spinner from 'components/spinner';

export default React.createClass( {
displayName: 'SpinnerButton',

propTypes: {
disabled: PropTypes.bool,
loading: PropTypes.bool,

text: PropTypes.string,
loadingText: PropTypes.string,
size: PropTypes.number
},

getDefaultProps() {
return {
size: 24,
loading: false
}
},

render() {
const { loading, text, loadingText, size, disabled } = this.props;

// Pass any extra props down to the Button component, leaving out
// any SpinnerButton specific props
const buttonProps = omit( this.props, [
'loading',
'loadingText',
'text',
'size',
'disabled'
] );

return (
<div>
<Button disabled={ loading || disabled } { ...buttonProps }>
{ loading ? loadingText : text }
</Button>

{ loading &&
<Spinner
size={ size }
className="exporter__spinner-button" />
}
</div>
);
}
} );
30 changes: 23 additions & 7 deletions client/my-sites/exporter/style.scss
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
.section-export {
padding-bottom: 100px;
}

.exporter__title {
margin-bottom: 1em;
margin-bottom: 0.5em;

font-size: 26px;
font-weight: 200;
font-size: 24px;
font-weight: 300;
color: $gray-dark;

clear: left;
}

.exporter__subtitle {
font-size: 11px;
color: $gray-dark;
}

.exporter__spinner-button {
float: right;
padding: 8px;
}

.exporter__export-button {
float: right;
}

.exporter__more-info.card {
background-color: $gray-light;
.exporter__advanced-settings {
padding-bottom: 50px;
}

.exporter__advanced-settings-title {
margin-bottom: 1em;
margin-bottom: 0.5em;

font-size: 22px;
font-weight: 200;
Expand Down Expand Up @@ -48,7 +62,9 @@

.exporter__option-fieldset-description {
font-size: smaller;
color: $gray-dark;
color: $gray;
padding-left: 24px;
padding-right: 24px;
}

.exporter__option-fieldset-fields {
Expand Down
2 changes: 1 addition & 1 deletion client/my-sites/site-settings/section-export.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class SiteSettingsExport extends Component {
render() {
return (
<Provider store={ this.props.store }>
<ExporterContainer />
<ExporterContainer site={ this.props.site } />
</Provider>
);
}
Expand Down
7 changes: 5 additions & 2 deletions client/state/action-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* Please keep this list alphabetized!
*/

export const COMPLETE_EXPORT = 'COMPLETE_EXPORT';
export const FAIL_EXPORT = 'FAIL_EXPORT';
export const FAIL_PUBLICIZE_CONNECTIONS_REQUEST = 'FAIL_PUBLICIZE_CONNECTIONS_REQUEST';
export const FETCH_SITE_PLANS = 'FETCH_SITE_PLANS';
export const FETCH_SITE_PLANS_COMPLETED = 'FETCH_SITE_PLANS_COMPLETED';
Expand All @@ -14,8 +16,9 @@ export const RECEIVE_PUBLICIZE_CONNECTIONS = 'RECEIVE_PUBLICIZE_CONNECTIONS';
export const RECEIVE_SITE = 'RECEIVE_SITE';
export const REMOVE_NOTICE = 'REMOVE_NOTICE';
export const REMOVE_SITE_PLANS = 'REMOVE_SITE_PLANS';
export const REPLY_START_EXPORT = 'REPLY_START_EXPORT';
export const REQUEST_START_EXPORT = 'REQUEST_START_EXPORT';
export const SET_EXPORT_POST_TYPE = 'SET_EXPORT_POST_TYPE';
export const SET_ROUTE = 'SET_ROUTE';
export const SET_SECTION = 'SET_SECTION';
export const SET_SELECTED_SITE = 'SET_SELECTED_SITE';
export const TOGGLE_EXPORTER_ADVANCED_SETTINGS = 'TOGGLE_EXPORTER_ADVANCED_SETTINGS';
export const TOGGLE_EXPORTER_SECTION = 'TOGGLE_EXPORTER_SECTION';
Loading

0 comments on commit 780cb45

Please sign in to comment.