1
0
mirror of https://github.com/ascribe/onion.git synced 2024-06-28 08:37:59 +02:00

Autofocus message field in consignment form and use custom labels

For now, we’ll let the artist specify their suggested price in the
consignment form’s message field.
This commit is contained in:
Brett Sun 2015-11-10 18:24:46 +01:00
parent b100fdd80a
commit 84e8e4612f
9 changed files with 84 additions and 43 deletions

View File

@ -31,7 +31,7 @@ export default function ({ action, displayName, title, tooltip }) {
availableAcls: React.PropTypes.object.isRequired, availableAcls: React.PropTypes.object.isRequired,
buttonAcceptName: React.PropTypes.string, buttonAcceptName: React.PropTypes.string,
buttonAcceptClassName: React.PropTypes.string, buttonAcceptClassName: React.PropTypes.string,
currentUser: React.PropTypes.object.isRequired, currentUser: React.PropTypes.object,
email: React.PropTypes.string, email: React.PropTypes.string,
pieceOrEditions: React.PropTypes.oneOfType([ pieceOrEditions: React.PropTypes.oneOfType([
React.PropTypes.object, React.PropTypes.object,

View File

@ -20,9 +20,11 @@ import { getAclFormMessage, getAclFormDataId } from '../../utils/form_utils';
let AclFormFactory = React.createClass({ let AclFormFactory = React.createClass({
propTypes: { propTypes: {
action: React.PropTypes.oneOf(AppConstants.aclList).isRequired, action: React.PropTypes.oneOf(AppConstants.aclList).isRequired,
currentUser: React.PropTypes.object.isRequired, autoFocusProperty: React.PropTypes.string,
currentUser: React.PropTypes.object,
email: React.PropTypes.string, email: React.PropTypes.string,
message: React.PropTypes.string, message: React.PropTypes.string,
labels: React.PropTypes.object,
pieceOrEditions: React.PropTypes.oneOfType([ pieceOrEditions: React.PropTypes.oneOfType([
React.PropTypes.object, React.PropTypes.object,
React.PropTypes.array React.PropTypes.array
@ -53,10 +55,12 @@ let AclFormFactory = React.createClass({
render() { render() {
const { const {
action, action,
autoFocusProperty,
pieceOrEditions, pieceOrEditions,
currentUser, currentUser,
email, email,
message, message,
labels,
handleSuccess, handleSuccess,
showNotification } = this.props; showNotification } = this.props;
@ -64,14 +68,16 @@ let AclFormFactory = React.createClass({
aclName: action, aclName: action,
entities: pieceOrEditions, entities: pieceOrEditions,
isPiece: this.isPiece(), isPiece: this.isPiece(),
senderName: currentUser.username senderName: currentUser && currentUser.username
}); });
if (action === 'acl_consign') { if (action === 'acl_consign') {
return ( return (
<ConsignForm <ConsignForm
autoFocusProperty={autoFocusProperty}
email={email} email={email}
message={formMessage} message={formMessage}
labels={labels}
id={this.getFormDataId()} id={this.getFormDataId()}
url={ApiUrls.ownership_consigns} url={ApiUrls.ownership_consigns}
handleSuccess={showNotification ? this.showSuccessNotification : handleSuccess} /> handleSuccess={showNotification ? this.showSuccessNotification : handleSuccess} />

View File

@ -17,8 +17,10 @@ let ConsignForm = React.createClass({
propTypes: { propTypes: {
url: React.PropTypes.string, url: React.PropTypes.string,
id: React.PropTypes.object, id: React.PropTypes.object,
autoFocusProperty: React.PropTypes.string,
email: React.PropTypes.string, email: React.PropTypes.string,
message: React.PropTypes.string, message: React.PropTypes.string,
labels: React.PropTypes.object,
handleSuccess: React.PropTypes.func handleSuccess: React.PropTypes.func
}, },
@ -27,10 +29,12 @@ let ConsignForm = React.createClass({
}, },
render() { render() {
const { autoFocusProperty, email, id, handleSuccess, message, labels, url } = this.props;
return ( return (
<Form <Form
ref='form' ref='form'
url={this.props.url} url={url}
getFormData={this.getFormData} getFormData={this.getFormData}
handleSuccess={this.props.handleSuccess} handleSuccess={this.props.handleSuccess}
buttons={ buttons={
@ -51,24 +55,26 @@ let ConsignForm = React.createClass({
</div>}> </div>}>
<AclInformation aim={'form'} verbs={['acl_consign']}/> <AclInformation aim={'form'} verbs={['acl_consign']}/>
<Property <Property
autoFocus={autoFocusProperty === 'email'}
name='consignee' name='consignee'
label={getLangText('Email')} label={labels.email || getLangText('Email')}
editable={!this.props.email} editable={!email}
overrideForm={!!this.props.email}> overrideForm={!!email}>
<input <input
type="email" type="email"
placeholder={getLangText('Email of the consignee')} placeholder={getLangText('Email of the consignee')}
defaultValue={this.props.email} defaultValue={email}
required/> required/>
</Property> </Property>
<Property <Property
autoFocus={autoFocusProperty === 'message'}
name='consign_message' name='consign_message'
label={getLangText('Personal Message')} label={labels.message || getLangText('Personal Message')}
editable={true} editable
overrideForm={true}> overrideForm>
<InputTextAreaToggable <InputTextAreaToggable
rows={1} rows={1}
defaultValue={this.props.message} defaultValue={message}
placeholder={getLangText('Enter a message...')} placeholder={getLangText('Enter a message...')}
required /> required />
</Property> </Property>

View File

@ -7,6 +7,7 @@ import TextareaAutosize from 'react-textarea-autosize';
let InputTextAreaToggable = React.createClass({ let InputTextAreaToggable = React.createClass({
propTypes: { propTypes: {
autoFocus: React.PropTypes.bool,
disabled: React.PropTypes.bool, disabled: React.PropTypes.bool,
rows: React.PropTypes.number.isRequired, rows: React.PropTypes.number.isRequired,
required: React.PropTypes.bool, required: React.PropTypes.bool,
@ -23,6 +24,10 @@ let InputTextAreaToggable = React.createClass({
}, },
componentDidMount() { componentDidMount() {
if (this.props.autoFocus) {
this.refs.textarea.focus();
}
this.setState({ this.setState({
value: this.props.defaultValue value: this.props.defaultValue
}); });
@ -51,6 +56,7 @@ let InputTextAreaToggable = React.createClass({
className = className + ' ascribe-textarea-editable'; className = className + ' ascribe-textarea-editable';
textarea = ( textarea = (
<TextareaAutosize <TextareaAutosize
ref='textarea'
className={className} className={className}
value={this.state.value} value={this.state.value}
rows={this.props.rows} rows={this.props.rows}

View File

@ -10,7 +10,7 @@ let ListRequestActions = React.createClass({
React.PropTypes.object, React.PropTypes.object,
React.PropTypes.array React.PropTypes.array
]).isRequired, ]).isRequired,
currentUser: React.PropTypes.object.isRequired, currentUser: React.PropTypes.object,
handleSuccess: React.PropTypes.func.isRequired, handleSuccess: React.PropTypes.func.isRequired,
notifications: React.PropTypes.array.isRequired notifications: React.PropTypes.array.isRequired
}, },
@ -33,4 +33,4 @@ let ListRequestActions = React.createClass({
} }
}); });
export default ListRequestActions; export default ListRequestActions;

View File

@ -15,6 +15,7 @@ let Property = React.createClass({
propTypes: { propTypes: {
hidden: React.PropTypes.bool, hidden: React.PropTypes.bool,
autoFocus: React.PropTypes.bool,
editable: React.PropTypes.bool, editable: React.PropTypes.bool,
// If we want Form to have a different value for disabled as Property has one for // If we want Form to have a different value for disabled as Property has one for
@ -68,6 +69,12 @@ let Property = React.createClass({
}; };
}, },
componentDidMount() {
if (this.props.autoFocus) {
this.handleFocus();
}
},
componentWillReceiveProps() { componentWillReceiveProps() {
let childInput = this.refs.input; let childInput = this.refs.input;

View File

@ -5,8 +5,6 @@ import classNames from 'classnames';
import LumenusAdditionalDataForm from '../lumenus_forms/lumenus_additional_data_form'; import LumenusAdditionalDataForm from '../lumenus_forms/lumenus_additional_data_form';
import ConsignButton from '../../../../../ascribe_buttons/acls/consign_button';
import AclFormFactory from '../../../../../ascribe_forms/acl_form_factory'; import AclFormFactory from '../../../../../ascribe_forms/acl_form_factory';
import ConsignForm from '../../../../../ascribe_forms/form_consign'; import ConsignForm from '../../../../../ascribe_forms/form_consign';
@ -20,13 +18,13 @@ import WhitelabelStore from '../../../../../../stores/whitelabel_store';
import ApiUrls from '../../../../../../constants/api_urls'; import ApiUrls from '../../../../../../constants/api_urls';
import { getAclFormDataId } from '../../../../../../utils/form_utils'; import { getAclFormMessage, getAclFormDataId } from '../../../../../../utils/form_utils';
import { getLangText } from '../../../../../../utils/lang_utils'; import { getLangText } from '../../../../../../utils/lang_utils';
let LumenusSubmitButton = React.createClass({ let LumenusSubmitButton = React.createClass({
propTypes: { propTypes: {
availableAcls: React.PropTypes.object.isRequired, availableAcls: React.PropTypes.object.isRequired,
currentUser: React.PropTypes.object.isRequired, currentUser: React.PropTypes.object,
editions: React.PropTypes.array.isRequired, editions: React.PropTypes.array.isRequired,
handleSuccess: React.PropTypes.func.isRequired, handleSuccess: React.PropTypes.func.isRequired,
className: React.PropTypes.string, className: React.PropTypes.string,
@ -93,9 +91,32 @@ let LumenusSubmitButton = React.createClass({
render() { render() {
const { availableAcls, currentUser, className, editions, handleSuccess } = this.props; const { availableAcls, currentUser, className, editions, handleSuccess } = this.props;
const buttonTitle = getLangText('CONSIGN TO LUMENUS');
const { solePieceId, canSubmit } = this.getAggregateEditionDetails(); const { solePieceId, canSubmit } = this.getAggregateEditionDetails();
const message = getAclFormMessage({
aclName: 'acl_consign',
entities: editions,
isPiece: false,
additionalMessage: getLangText('Suggested price:'),
senderName: currentUser.username
});
const triggerButton = (
<button className={classNames('btn', 'btn-default', 'btn-sm', className)}>
{getLangText('CONSIGN TO LUMENUS')}
</button>
);
const consignForm = (
<AclFormFactory
action='acl_consign'
autoFocusProperty='message'
email={this.state.whitelabel.user}
message={message}
labels={{
'message': getLangText('Message (also suggest a sales price if necessary)')
}}
pieceOrEditions={editions}
showNotification />
);
if (solePieceId && !canSubmit) { if (solePieceId && !canSubmit) {
return ( return (
@ -103,11 +124,7 @@ let LumenusSubmitButton = React.createClass({
aclObject={availableAcls} aclObject={availableAcls}
aclName='acl_consign'> aclName='acl_consign'>
<ModalWrapper <ModalWrapper
trigger={ trigger={triggerButton}
<button className={classNames('btn', 'btn-default', 'btn-sm', className)}>
{buttonTitle}
</button>
}
handleSuccess={this.handleAdditionalDataSuccess.bind(this, solePieceId)} handleSuccess={this.handleAdditionalDataSuccess.bind(this, solePieceId)}
title={getLangText('Add additional information')}> title={getLangText('Add additional information')}>
<LumenusAdditionalDataForm <LumenusAdditionalDataForm
@ -118,25 +135,22 @@ let LumenusSubmitButton = React.createClass({
ref="consignModal" ref="consignModal"
handleSuccess={handleSuccess} handleSuccess={handleSuccess}
title={getLangText('Consign artwork')}> title={getLangText('Consign artwork')}>
<AclFormFactory {consignForm}
action='acl_consign'
currentUser={currentUser}
email={this.state.whitelabel.user}
pieceOrEditions={editions}
showNotification />
</ModalWrapper> </ModalWrapper>
</AclProxy> </AclProxy>
); );
} else { } else {
return ( return (
<ConsignButton <AclProxy
availableAcls={{'acl_consign': availableAcls.acl_consign && canSubmit}} aclObject={{'acl_consign': availableAcls.acl_consign && canSubmit}}
buttonAcceptName={buttonTitle} aclName='acl_consign'>
email={this.state.whitelabel.user} <ModalWrapper
currentUser={currentUser} trigger={triggerButton}
handleSuccess={handleSuccess} handleSuccess={handleSuccess}
pieceOrEditions={editions} title={getLangText('Consign artwork to Lumenus')}>
className={className} /> {consignForm}
</ModalWrapper>
</AclProxy>
); );
} }
} }

View File

@ -51,10 +51,8 @@ let LumenusAdditionalDataForm = React.createClass({
componentDidMount() { componentDidMount() {
PieceStore.listen(this.onChange); PieceStore.listen(this.onChange);
// If the Piece store doesn't already have the piece we want loaded, load it if (this.props.pieceId) {
const { pieceId } = this.props; PieceActions.fetchOne(this.props.pieceId);
if (pieceId && this.state.piece.id !== pieceId) {
PieceActions.fetchOne(pieceId);
} }
}, },

View File

@ -72,6 +72,10 @@ export function getAclFormMessage(options) {
throw new Error('Your specified aclName did not match a an acl class.'); throw new Error('Your specified aclName did not match a an acl class.');
} }
if (options.additionalMessage) {
message += '\n\n' + options.additionalMessage;
}
if (options.senderName) { if (options.senderName) {
message += '\n\n'; message += '\n\n';
message += getLangText('Truly yours,'); message += getLangText('Truly yours,');