Skip to content

Commit

Permalink
add RegistrationStatusSelect component (#514)
Browse files Browse the repository at this point in the history
* add getRegistrationStatuses() and isRequestingRegistrationStatuses()

* add getRegistrationStatuses()

* add RegistrationStatusSelect component.

Generates a registration status select input.

* add registrationStatusSelectOptions function

* export RegistrationStatusSelect

* set model name to "status" not "statuses"

* tweak var names
  • Loading branch information
tn3rb authored Jun 8, 2018
1 parent b9bf30c commit e11d47d
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 1 deletion.
5 changes: 4 additions & 1 deletion assets/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ export { ContactAvatar } from './entities/contact';
// query components
export { QueryLimit } from './query/limit';
// selection components
export { default as EventSelect } from './selection/event-select';
export { default as DatetimeSelect } from './selection/datetime-select';
export { default as EventSelect } from './selection/event-select';
export {
default as RegistrationStatusSelect,
} from './selection/registration-status-select';
export { default as TicketSelect } from './selection/ticket-select';
152 changes: 152 additions & 0 deletions assets/src/components/selection/registration-status-select/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/**
* External dependencies
*/
import { stringify } from 'querystringify';
import { isUndefined, pickBy, isEmpty } from 'lodash';
import PropTypes from 'prop-types';
import { __ } from '@eventespresso/i18n';

/**
* WordPress dependencies
*/
import { Placeholder, SelectControl, Spinner } from '@wordpress/components';
import { withSelect } from '@wordpress/data';
import { Component, Fragment } from '@wordpress/element';

/**
* Internal dependencies
*/
import { registrationStatusSelectOptions } from './options';

/**
* RegistrationStatusSelect component.
* Generates a registration status select input.
*
* @param {Array} regStatuses An empty array or array of Status
* Entities. See prop-types for shape.
* @param {function} onRegStatusSelect The callback on selection of ticket.
* @param {string} selectLabel The label for the select input.
* @param {number} selectedRegStatusId The ID of the ticket to pre-select.
* @param {boolean} isLoading Whether or not the selector should
* start in a loading state
* @return {Function} A pure component function.
* @constructor
*/
class RegistrationStatusSelect extends Component {
static propTypes = {
regStatuses: PropTypes.arrayOf( PropTypes.shape( {
STS_ID: PropTypes.number.isRequired,
STS_code: PropTypes.string.isRequired,
} ) ),
onRegStatusSelect: PropTypes.func,
selectLabel: PropTypes.string,
selectedRegStatusId: PropTypes.number,
isLoading: PropTypes.bool,
addAllOption: PropTypes.bool,
addAllOptionLabel: PropTypes.string,
attributes: PropTypes.shape( {
limit: PropTypes.number,
orderBy: PropTypes.string,
order: PropTypes.oneOf( [ 'asc', 'desc' ] ),
} ),
};

static defaultProps = {
regStatuses: [],
selectLabel: __( 'Select Registration Status', 'event_espresso' ),
selectedRegStatusId: 0,
isLoading: true,
addAllOption: true,
addAllOptionLabel: __( 'All Registration Statuses', 'event_espresso' ),
attributes: {
limit: 25,
orderBy: 'STS_code',
order: 'desc',
},
};

placeHolder() {
const { isLoading, selectLabel } = this.props;
return (
<Fragment>
<Placeholder
icon="clipboard"
label={ selectLabel }
>
{ isLoading ?
<Spinner /> :
__(
'Error loading Registration Statuses!',
'event_espresso',
)
}
</Placeholder>
</Fragment>
);
}

render() {
const {
regStatuses,
selectLabel,
selectedRegStatusId,
onRegStatusSelect,
addAllOption,
addAllOptionLabel,
} = this.props;
if ( isEmpty( regStatuses ) ) {
return this.placeHolder();
}
return (
<Fragment>
<SelectControl
label={ selectLabel }
value={ selectedRegStatusId }
options={
registrationStatusSelectOptions(
regStatuses,
addAllOption,
addAllOptionLabel,
)
}
onChange={ onRegStatusSelect }
/>
</Fragment>
);
}
}

/**
* The RegistrationStatusSelect Component wrapped in the `withSelect` higher
* order component. This subscribes the RegistrationStatusSelect component to
* the state maintained via the eventespresso/lists store.
*/
export default withSelect( ( select, ownProps ) => {
const {
attributes = RegistrationStatusSelect.defaultProps.attributes,
} = ownProps;
const {
selectedRegStatusId,
addAllOption,
addAllOptionLabel,
} = ownProps;
const {
getRegistrationStatuss,
isRequestingRegistrationStatuss,
} = select( 'eventespresso/lists' );
const queryArgs = {
limit: attributes.limit,
order: attributes.order,
order_by: attributes.orderBy,
};
const queryString = stringify( pickBy( queryArgs,
value => ! isUndefined( value ),
) );
return {
regStatuses: getRegistrationStatuss( queryString ),
isLoading: isRequestingRegistrationStatuss( queryString ),
selectedRegStatusId: selectedRegStatusId,
addAllOption: addAllOption,
addAllOptionLabel: addAllOptionLabel,
};
} )( RegistrationStatusSelect );
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* External dependencies
*/
import { reduce } from 'lodash';

export const EE_OPTION_REG_STATUS_SELECT_ALL = 'ALL_REG_STATUSES';

/**
* Receives an array of registration status entities
* and returns an array of simple objects
* that can be passed along to the options array
* used for the WordPress SelectControl component.
*
* @param { Array } regStatuses An array of registration status entities
* @param { boolean } addAllOption If true, will prepend options array
* with an "ALL" option meaning that all
* statuses are essentially selected
* @param { string } addAllOptionLabel label displayed for "ALL" option
* @return { Array } Returns an array of simple objects
* formatted for the WordPress
* SelectControl component.
*/
export const registrationStatusSelectOptions = (
regStatuses,
addAllOption,
addAllOptionLabel,
) => {
const regStatusOptions = reduce(
regStatuses,
function( options, status ) {
options.push(
{
value: status.STS_ID,
label: status.STS_code,
},
);
return options;
},
[],
);
if ( addAllOption === true ) {
regStatusOptions.unshift( {
value: EE_OPTION_REG_STATUS_SELECT_ALL,
label: addAllOptionLabel,
} );
}
return regStatusOptions;
};
10 changes: 10 additions & 0 deletions assets/src/data/eventespresso/lists/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,13 @@ export function getDatetimes( state, queryString ) {
export function getTickets( state, queryString ) {
return getItems( state, 'ticket', queryString );
}

/**
* Resolver for registration status entities.
*
* @param {Object} state Data in state.
* @return {IterableIterator<*>} A async iterable.
*/
export function getRegistrationStatuses( state ) {
return getItems( state, 'status', 'where[STS_type]=registration' );
}
22 changes: 22 additions & 0 deletions assets/src/data/eventespresso/lists/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,25 @@ export function getTickets( state, queryString ) {
export function isRequestingTickets( state, queryString ) {
return isResolving( 'getTickets', queryString );
}

/**
* Selector specific to registration statuses.
*
* @param {Object} state Data state.
* @return {Array} An array of event entities for the given model and query.
*/
export function getRegistrationStatuses( state ) {
return getItems( state, 'status', 'where[STS_type]=registration' );
}

/**
* Selector specific checking if requesting registration statuses.
*
* @return {boolean} Whether items are being requested or not.
*/
export function isRequestingRegistrationStatuses() {
return isResolving(
'getRegistrationStatuses',
'where[STS_type]=registration'
);
}

0 comments on commit e11d47d

Please sign in to comment.