-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exporter: WP.com API integration #1359
Changes from all commits
6355d2e
299011e
8e4bbba
2f7bb07
a0141f5
9c724bb
4c985d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,25 +34,41 @@ export default React.createClass( { | |
pages: this.translate( 'Pages' ), | ||
feedback: this.translate( 'Feedback' ) | ||
}; | ||
const defaultLabels = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should be translated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, I missed that in a past refactor. Fixed |
||
author: this.translate( 'All Authors' ), | ||
status: this.translate( 'All Statuses' ), | ||
startDate: this.translate( 'Start Date…' ), | ||
endDate: this.translate( 'End Date…' ), | ||
category: this.translate( 'All Categories' ) | ||
} | ||
let buildMenu = ( contentType, setting, optionList ) => { | ||
return { | ||
value: this.props[ contentType ][ setting ], | ||
options: this.props.options[ contentType ][ optionList ], | ||
defaultLabel: defaultLabels[ setting ], | ||
onChange: ( e ) => this.props.onChangeSetting( contentType, setting, e.target.value ) | ||
}; | ||
}; | ||
|
||
const menus = { | ||
posts: [ | ||
{ value: 0, options: [ this.translate( 'All Authors' ) ] }, | ||
{ value: 0, options: [ this.translate( 'All Statuses' ) ] }, | ||
{ value: 0, options: [ this.translate( 'Starting Date…' ) ] }, | ||
{ value: 0, options: [ this.translate( 'Ending Date…' ) ] }, | ||
{ value: 0, options: [ this.translate( 'All Categories' ) ] } | ||
buildMenu( 'posts', 'author', 'authors' ), | ||
buildMenu( 'posts', 'status', 'statuses' ), | ||
buildMenu( 'posts', 'startDate', 'startDates' ), | ||
buildMenu( 'posts', 'endDate', 'endDates' ), | ||
buildMenu( 'posts', 'category', 'categories' ) | ||
], | ||
pages: [ | ||
{ value: 0, options: [ this.translate( 'All Authors' ) ] }, | ||
{ value: 0, options: [ this.translate( 'All Statuses' ) ] }, | ||
{ value: 0, options: [ this.translate( 'Starting Date…' ) ] }, | ||
{ value: 0, options: [ this.translate( 'Ending Date…' ) ] } | ||
buildMenu( 'pages', 'author', 'authors' ), | ||
buildMenu( 'pages', 'status', 'statuses' ), | ||
buildMenu( 'pages', 'startDate', 'startDates' ), | ||
buildMenu( 'pages', 'endDate', 'endDates' ), | ||
], | ||
feedback: [] | ||
}; | ||
|
||
const buildOptionProps = key => ( { | ||
isLoadingOptions: this.props.isLoadingOptions, | ||
legend: legends[ key ], | ||
isEnabled: this.props.postType === key, | ||
menus: menus[ key ], | ||
|
@@ -76,15 +92,14 @@ export default React.createClass( { | |
<OptionFieldset { ...buildOptionProps( 'posts' ) } /> | ||
<OptionFieldset { ...buildOptionProps( 'pages' ) } /> | ||
<OptionFieldset { ...buildOptionProps( 'feedback' ) } | ||
description={ this.translate( 'Survey results etc.' ) } | ||
/> | ||
description={ this.translate( 'Survey results etc.' ) } /> | ||
</div> | ||
<SpinnerButton | ||
className="exporter__export-button" | ||
disabled={ !this.props.postType } | ||
loading={ this.props.shouldShowProgress } | ||
isPrimary={ true } | ||
onClick={ this.props.onClickExport } | ||
onClick={ () => this.props.onClickExport( this.props.postType ) } | ||
text={ this.translate( 'Export Selected Content' ) } | ||
loadingText={ this.translate( 'Exporting…' ) } /> | ||
</div> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,21 +16,29 @@ export default React.createClass( { | |
propTypes: { | ||
startExport: PropTypes.func.isRequired, | ||
setPostType: PropTypes.func.isRequired, | ||
setAdvancedSetting: PropTypes.func.isRequired, | ||
|
||
shouldShowProgress: PropTypes.bool.isRequired, | ||
advancedSettings: PropTypes.object.isRequired, | ||
postType: PropTypes.string | ||
}, | ||
|
||
render: function() { | ||
const { setPostType, startExport } = this.props; | ||
const { postType, shouldShowProgress } = this.props; | ||
const { setPostType, startExport, setAdvancedSetting } = this.props; | ||
const { | ||
postType, | ||
advancedSettings, | ||
shouldShowProgress, | ||
options, | ||
isLoadingOptions | ||
} = this.props; | ||
|
||
const exportButton = ( | ||
<SpinnerButton | ||
className="exporter__export-button" | ||
loading={ shouldShowProgress } | ||
isPrimary={ true } | ||
onClick={ startExport } | ||
onClick={ () => startExport() } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Okay - I see the error now that onClick={ partial( startExport, null ) } // ignore the event payload Of course, this only works if the function expects a single parameter. Maybe a better solution would be to stop overloading |
||
text={ this.translate( 'Export All' ) } | ||
loadingText={ this.translate( 'Exporting…' ) } /> | ||
); | ||
|
@@ -53,10 +61,14 @@ export default React.createClass( { | |
expandedSummary={ exportButton } | ||
> | ||
<AdvancedSettings | ||
{ ...advancedSettings } | ||
postType={ postType } | ||
shouldShowProgress={ shouldShowProgress } | ||
onSelectPostType={ setPostType } | ||
onClickExport={ startExport } | ||
onChangeSetting={ setAdvancedSetting } | ||
isLoadingOptions={ isLoadingOptions } | ||
options={ options } | ||
/> | ||
</FoldableCard> | ||
</div> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,87 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import React, { Component } from 'react'; | ||
import { connect } from 'react-redux'; | ||
import { compose } from 'lodash'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import Exporter from './exporter'; | ||
import { getUIState, shouldShowProgress } from 'state/site-settings/exporter/selectors'; | ||
import { setPostType, startExport } from 'state/site-settings/exporter/actions'; | ||
|
||
function mapStateToProps( state, ownProps ) { | ||
import { | ||
getUIState, | ||
getAuthorOptions, | ||
getStatusOptions, | ||
getDateOptions, | ||
getCategoryOptions, | ||
isLoadingOptions, | ||
shouldShowProgress, | ||
} from 'state/site-settings/exporter/selectors'; | ||
|
||
import { | ||
setPostType, | ||
setAdvancedSetting, | ||
startExport, | ||
ensureHasSettings | ||
} from 'state/site-settings/exporter/actions'; | ||
|
||
import { getSelectedSite } from 'state/ui/selectors'; | ||
|
||
class ExporterContainer extends Component { | ||
|
||
componentDidMount() { | ||
this.props.ensureHasSettings(); | ||
} | ||
|
||
componentWillReceiveProps() { | ||
this.props.ensureHasSettings(); | ||
} | ||
|
||
render() { | ||
return <Exporter { ...this.props } /> | ||
} | ||
} | ||
|
||
function mapStateToProps( state ) { | ||
const uiState = getUIState( state ); | ||
const selectedSite = getSelectedSite( state ); | ||
|
||
const START_OF_MONTH = false; | ||
const END_OF_MONTH = true; | ||
|
||
return { | ||
site: ownProps.site, | ||
siteId: selectedSite && selectedSite.ID, | ||
postType: uiState.postType, | ||
advancedSettings: uiState.advancedSettings, | ||
shouldShowProgress: shouldShowProgress( state ) | ||
isLoadingOptions: isLoadingOptions( state ), | ||
shouldShowProgress: shouldShowProgress( state ), | ||
options: { | ||
posts: { | ||
authors: getAuthorOptions( state, 'post' ), | ||
statuses: getStatusOptions( state, 'post' ), | ||
startDates: getDateOptions( state, 'post', START_OF_MONTH ), | ||
endDates: getDateOptions( state, 'post', END_OF_MONTH ), | ||
categories: getCategoryOptions( state, 'post' ) | ||
}, | ||
pages: { | ||
authors: getAuthorOptions( state, 'page' ), | ||
statuses: getStatusOptions( state, 'page' ), | ||
startDates: getDateOptions( state, 'page', START_OF_MONTH ), | ||
endDates: getDateOptions( state, 'page', END_OF_MONTH ) | ||
} | ||
} | ||
}; | ||
} | ||
|
||
function mapDispatchToProps( dispatch ) { | ||
return { | ||
setPostType: compose( dispatch, setPostType ), | ||
startExport: () => startExport()( dispatch ) | ||
setAdvancedSetting: compose( dispatch, setAdvancedSetting ), | ||
startExport: compose( dispatch, startExport ), | ||
ensureHasSettings: compose( dispatch, ensureHasSettings ) | ||
}; | ||
} | ||
|
||
export default connect( mapStateToProps, mapDispatchToProps )( Exporter ); | ||
export default connect( mapStateToProps, mapDispatchToProps )( ExporterContainer ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you return these calls, then your code can take advantage of that by inspecting the request object.
additionally, if you return them and don't use a callback, the
wpcom.js
library will return a Promise that resolves on the successful response from the API and rejects on error