mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
Refactor MarketSubmitButton to pull the piece as necessary rather than always fetching it in MarketAdditionalDataForm
This commit is contained in:
parent
c6071d8ab4
commit
50129b9d0c
@ -5,15 +5,14 @@ import React from 'react';
|
||||
import Row from 'react-bootstrap/lib/Row';
|
||||
import Col from 'react-bootstrap/lib/Col';
|
||||
|
||||
import Form from './../ascribe_forms/form';
|
||||
|
||||
import PieceExtraDataForm from './../ascribe_forms/form_piece_extradata';
|
||||
|
||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||
|
||||
import FurtherDetailsFileuploader from './further_details_fileuploader';
|
||||
|
||||
import Form from './../ascribe_forms/form';
|
||||
import PieceExtraDataForm from './../ascribe_forms/form_piece_extradata';
|
||||
|
||||
import { formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils';
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ let MarketAclButtonList = React.createClass({
|
||||
|
||||
componentDidMount() {
|
||||
UserStore.listen(this.onChange);
|
||||
UserActions.fetchCurrentUser();
|
||||
UserActions.fetchCurrentUser.defer();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -3,6 +3,11 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import PieceActions from '../../../../../../actions/piece_actions';
|
||||
import PieceStore from '../../../../../../stores/piece_store';
|
||||
import WhitelabelActions from '../../../../../../actions/whitelabel_actions';
|
||||
import WhitelabelStore from '../../../../../../stores/whitelabel_store';
|
||||
|
||||
import MarketAdditionalDataForm from '../market_forms/market_additional_data_form';
|
||||
|
||||
import AclFormFactory from '../../../../../ascribe_forms/acl_form_factory';
|
||||
@ -11,15 +16,14 @@ import ConsignForm from '../../../../../ascribe_forms/form_consign';
|
||||
import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
|
||||
|
||||
import AclProxy from '../../../../../acl_proxy';
|
||||
|
||||
import PieceActions from '../../../../../../actions/piece_actions';
|
||||
import WhitelabelActions from '../../../../../../actions/whitelabel_actions';
|
||||
import WhitelabelStore from '../../../../../../stores/whitelabel_store';
|
||||
import AscribeSpinner from '../../../../../ascribe_spinner';
|
||||
|
||||
import ApiUrls from '../../../../../../constants/api_urls';
|
||||
|
||||
import { getAclFormMessage, getAclFormDataId } from '../../../../../../utils/form_utils';
|
||||
import { mergeOptions } from '../../../../../../utils/general_utils';
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
import { onChangeOnce } from '../../../../../../utils/store_utils';
|
||||
|
||||
let MarketSubmitButton = React.createClass({
|
||||
propTypes: {
|
||||
@ -27,11 +31,19 @@ let MarketSubmitButton = React.createClass({
|
||||
currentUser: React.PropTypes.object,
|
||||
editions: React.PropTypes.array.isRequired,
|
||||
handleSuccess: React.PropTypes.func.isRequired,
|
||||
className: React.PropTypes.string,
|
||||
|
||||
className: React.PropTypes.string
|
||||
},
|
||||
|
||||
// This component may eventually need to use the
|
||||
// PieceStore, but we don't need it initially
|
||||
getInitialState() {
|
||||
return WhitelabelStore.getState();
|
||||
return mergeOptions(
|
||||
WhitelabelStore.getState(),
|
||||
{
|
||||
piece: {}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
@ -41,6 +53,7 @@ let MarketSubmitButton = React.createClass({
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PieceStore.unlisten(this.onChange);
|
||||
WhitelabelStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
@ -62,8 +75,24 @@ let MarketSubmitButton = React.createClass({
|
||||
return false;
|
||||
},
|
||||
|
||||
getFormDataId() {
|
||||
return getAclFormDataId(false, this.props.editions);
|
||||
getAdditionalDataForm() {
|
||||
const { piece } = this.state;
|
||||
|
||||
if (piece.id) {
|
||||
return (
|
||||
<MarketAdditionalDataForm
|
||||
extraData={piece.extra_data}
|
||||
otherData={piece.other_data}
|
||||
pieceId={piece.id}
|
||||
submitLabel={getLangText('Continue to consignment')} />
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="fullpage-spinner">
|
||||
<AscribeSpinner color='dark-blue' size='lg'/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
getAggregateEditionDetails() {
|
||||
@ -82,6 +111,10 @@ let MarketSubmitButton = React.createClass({
|
||||
});
|
||||
},
|
||||
|
||||
getFormDataId() {
|
||||
return getAclFormDataId(false, this.props.editions);
|
||||
},
|
||||
|
||||
handleAdditionalDataSuccess(pieceId) {
|
||||
// Fetch newly updated piece to update the views
|
||||
PieceActions.fetchPiece(pieceId);
|
||||
@ -89,6 +122,19 @@ let MarketSubmitButton = React.createClass({
|
||||
this.refs.consignModal.show();
|
||||
},
|
||||
|
||||
loadPieceIfNeeded(neededPieceId) {
|
||||
if (neededPieceId) {
|
||||
const pieceStore = PieceStore.getState();
|
||||
|
||||
if (pieceStore.piece.id === neededPieceId) {
|
||||
this.setState(pieceStore);
|
||||
} else {
|
||||
onChangeOnce(this, PieceStore);
|
||||
PieceActions.fetchPiece(neededPieceId);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const { availableAcls, currentUser, className, editions, handleSuccess } = this.props;
|
||||
const { whitelabel: { name: whitelabelName = 'Market', user: whitelabelAdminEmail } } = this.state;
|
||||
@ -102,7 +148,9 @@ let MarketSubmitButton = React.createClass({
|
||||
});
|
||||
|
||||
const triggerButton = (
|
||||
<button className={classNames('btn', 'btn-default', 'btn-sm', className)}>
|
||||
<button
|
||||
className={classNames('btn', 'btn-default', 'btn-sm', className)}
|
||||
onClick={solePieceId && !canSubmit ? () => this.loadPieceIfNeeded(solePieceId) : () => {}}>
|
||||
{getLangText('CONSIGN TO %s', whitelabelName.toUpperCase())}
|
||||
</button>
|
||||
);
|
||||
@ -128,9 +176,7 @@ let MarketSubmitButton = React.createClass({
|
||||
trigger={triggerButton}
|
||||
handleSuccess={() => this.handleAdditionalDataSuccess(solePieceId)}
|
||||
title={getLangText('Add additional information')}>
|
||||
<MarketAdditionalDataForm
|
||||
pieceId={solePieceId}
|
||||
submitLabel={getLangText('Continue to consignment')} />
|
||||
{this.getAdditionalDataForm()}
|
||||
</ModalWrapper>
|
||||
|
||||
<ModalWrapper
|
||||
|
@ -6,8 +6,12 @@ import MarketAdditionalDataForm from '../market_forms/market_additional_data_for
|
||||
|
||||
let MarketFurtherDetails = React.createClass({
|
||||
propTypes: {
|
||||
pieceId: React.PropTypes.number,
|
||||
pieceId: React.PropTypes.number.isRequired,
|
||||
|
||||
editable: React.PropTypes.bool,
|
||||
extraData: React.PropTypes.object,
|
||||
handleSuccess: React.PropTypes.func,
|
||||
otherData: React.PropTypes.arrayOf(React.PropTypes.object)
|
||||
},
|
||||
|
||||
render() {
|
||||
|
@ -2,21 +2,18 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Form from '../../../../../ascribe_forms/form';
|
||||
import Property from '../../../../../ascribe_forms/property';
|
||||
|
||||
import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable';
|
||||
|
||||
import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader';
|
||||
import AscribeSpinner from '../../../../../ascribe_spinner';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
|
||||
|
||||
import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader';
|
||||
|
||||
import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable';
|
||||
import Form from '../../../../../ascribe_forms/form';
|
||||
import Property from '../../../../../ascribe_forms/property';
|
||||
|
||||
import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils';
|
||||
|
||||
import PieceActions from '../../../../../../actions/piece_actions';
|
||||
import PieceStore from '../../../../../../stores/piece_store';
|
||||
import AscribeSpinner from '../../../../../ascribe_spinner';
|
||||
|
||||
import ApiUrls from '../../../../../../constants/api_urls';
|
||||
import AppConstants from '../../../../../../constants/application_constants';
|
||||
@ -28,13 +25,16 @@ import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
|
||||
let MarketAdditionalDataForm = React.createClass({
|
||||
propTypes: {
|
||||
pieceId: React.PropTypes.number,
|
||||
pieceId: React.PropTypes.number.isRequired,
|
||||
|
||||
editable: React.PropTypes.bool,
|
||||
extraData: React.PropTypes.object,
|
||||
handleSuccess: React.PropTypes.func,
|
||||
isInline: React.PropTypes.bool,
|
||||
otherData: React.PropTypes.arrayOf(React.PropTypes.object),
|
||||
showHeading: React.PropTypes.bool,
|
||||
showNotification: React.PropTypes.bool,
|
||||
submitLabel: React.PropTypes.string,
|
||||
handleSuccess: React.PropTypes.func
|
||||
submitLabel: React.PropTypes.string
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
@ -45,33 +45,18 @@ let MarketAdditionalDataForm = React.createClass({
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
const pieceStore = PieceStore.getState();
|
||||
|
||||
return mergeOptions(
|
||||
pieceStore,
|
||||
{
|
||||
return {
|
||||
// Allow the form to be submitted if there's already an additional image uploaded
|
||||
isUploadReady: this.isUploadReadyOnChange(pieceStore.piece),
|
||||
isUploadReady: this.isUploadReadyOnChange(),
|
||||
forceUpdateKey: 0
|
||||
});
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PieceStore.listen(this.onChange);
|
||||
|
||||
if (this.props.pieceId) {
|
||||
PieceActions.fetchPiece(this.props.pieceId);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PieceStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
Object.assign({}, state, {
|
||||
// Allow the form to be submitted if the updated piece already has an additional image uploaded
|
||||
isUploadReady: this.isUploadReadyOnChange(state.piece),
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.extraData !== nextProps.extraData || this.props.otherData !== nextProps.otherData) {
|
||||
this.setState({
|
||||
// Allow the form to be submitted if the updated piece has an additional image uploaded
|
||||
isUploadReady: this.isUploadReadyOnChange(),
|
||||
|
||||
/**
|
||||
* Increment the forceUpdateKey to force the form to rerender on each change
|
||||
@ -82,13 +67,12 @@ let MarketAdditionalDataForm = React.createClass({
|
||||
*/
|
||||
forceUpdateKey: this.state.forceUpdateKey + 1
|
||||
});
|
||||
|
||||
this.setState(state);
|
||||
}
|
||||
},
|
||||
|
||||
getFormData() {
|
||||
let extradata = {};
|
||||
let formRefs = this.refs.form.refs;
|
||||
const extradata = {};
|
||||
const formRefs = this.refs.form.refs;
|
||||
|
||||
// Put additional fields in extra data object
|
||||
Object
|
||||
@ -99,12 +83,12 @@ let MarketAdditionalDataForm = React.createClass({
|
||||
|
||||
return {
|
||||
extradata: extradata,
|
||||
piece_id: this.state.piece.id
|
||||
piece_id: this.props.pieceId
|
||||
};
|
||||
},
|
||||
|
||||
isUploadReadyOnChange(piece) {
|
||||
return piece && piece.other_data && piece.other_data.length > 0;
|
||||
isUploadReadyOnChange() {
|
||||
return this.props.otherData && this.props.otherData.length;
|
||||
},
|
||||
|
||||
handleSuccessWithNotification() {
|
||||
@ -123,10 +107,18 @@ let MarketAdditionalDataForm = React.createClass({
|
||||
},
|
||||
|
||||
render() {
|
||||
const { editable, isInline, handleSuccess, showHeading, showNotification, submitLabel } = this.props;
|
||||
const { piece } = this.state;
|
||||
let buttons, heading;
|
||||
const {
|
||||
editable,
|
||||
extraData,
|
||||
isInline,
|
||||
handleSuccess,
|
||||
otherData,
|
||||
pieceId,
|
||||
showHeading,
|
||||
showNotification,
|
||||
submitLabel } = this.props;
|
||||
|
||||
let buttons, heading;
|
||||
let spinner = <AscribeSpinner color='dark-blue' size='lg' />;
|
||||
|
||||
if (!isInline) {
|
||||
@ -156,76 +148,68 @@ let MarketAdditionalDataForm = React.createClass({
|
||||
) : null;
|
||||
}
|
||||
|
||||
if (piece.id) {
|
||||
return (
|
||||
<Form
|
||||
className="ascribe-form-bordered"
|
||||
ref='form'
|
||||
key={this.state.forceUpdateKey}
|
||||
url={requests.prepareUrl(ApiUrls.piece_extradata, {piece_id: piece.id})}
|
||||
url={requests.prepareUrl(ApiUrls.piece_extradata, {piece_id: pieceId})}
|
||||
handleSuccess={showNotification ? this.handleSuccessWithNotification : handleSuccess}
|
||||
getFormData={this.getFormData}
|
||||
buttons={buttons}
|
||||
spinner={spinner}
|
||||
disabled={!this.props.editable || !piece.acl.acl_edit}>
|
||||
disabled={!this.props.editable}>
|
||||
{heading}
|
||||
<FurtherDetailsFileuploader
|
||||
label={getLangText('Marketplace Thumbnail Image')}
|
||||
submitFile={function () {}}
|
||||
setIsUploadReady={this.setIsUploadReady}
|
||||
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
|
||||
pieceId={piece.id}
|
||||
otherData={piece.other_data}
|
||||
pieceId={pieceId}
|
||||
otherData={otherData}
|
||||
editable={editable} />
|
||||
<Property
|
||||
name='artist_bio'
|
||||
label={getLangText('Artist Bio')}
|
||||
expanded={editable || !!piece.extra_data.artist_bio}>
|
||||
expanded={editable || !!extraData.artist_bio}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
defaultValue={piece.extra_data.artist_bio}
|
||||
defaultValue={extraData.artist_bio}
|
||||
placeholder={getLangText('Enter a biography of the artist...')}
|
||||
required />
|
||||
</Property>
|
||||
<Property
|
||||
name='work_description'
|
||||
label={getLangText('Work Description')}
|
||||
expanded={editable || !!piece.extra_data.work_description}>
|
||||
expanded={editable || !!extraData.work_description}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
defaultValue={piece.extra_data.work_description}
|
||||
defaultValue={extraData.work_description}
|
||||
placeholder={getLangText('Enter a description of the work...')}
|
||||
required />
|
||||
</Property>
|
||||
<Property
|
||||
name='technology_details'
|
||||
label={getLangText('Technology Details')}
|
||||
expanded={editable || !!piece.extra_data.technology_details}>
|
||||
expanded={editable || !!extraData.technology_details}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
defaultValue={piece.extra_data.technology_details}
|
||||
defaultValue={extraData.technology_details}
|
||||
placeholder={getLangText('Enter technological details about the work...')}
|
||||
required />
|
||||
</Property>
|
||||
<Property
|
||||
name='display_instructions'
|
||||
label={getLangText('Display Instructions')}
|
||||
expanded={editable || !!piece.extra_data.display_instructions}>
|
||||
expanded={editable || !!extraData.display_instructions}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
defaultValue={piece.extra_data.display_instructions}
|
||||
defaultValue={extraData.display_instructions}
|
||||
placeholder={getLangText('Enter instructions on how to best display the work...')}
|
||||
required />
|
||||
</Property>
|
||||
</Form>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="ascribe-loading-position">
|
||||
{spinner}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -6,11 +6,6 @@ import { History } from 'react-router';
|
||||
import Col from 'react-bootstrap/lib/Col';
|
||||
import Row from 'react-bootstrap/lib/Row';
|
||||
|
||||
import MarketAdditionalDataForm from './market_forms/market_additional_data_form';
|
||||
|
||||
import Property from '../../../../ascribe_forms/property';
|
||||
import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece';
|
||||
|
||||
import PieceActions from '../../../../../actions/piece_actions';
|
||||
import PieceListStore from '../../../../../stores/piece_list_store';
|
||||
import PieceListActions from '../../../../../actions/piece_list_actions';
|
||||
@ -19,6 +14,11 @@ import UserActions from '../../../../../actions/user_actions';
|
||||
import WhitelabelActions from '../../../../../actions/whitelabel_actions';
|
||||
import WhitelabelStore from '../../../../../stores/whitelabel_store';
|
||||
|
||||
import MarketAdditionalDataForm from './market_forms/market_additional_data_form';
|
||||
|
||||
import Property from '../../../../ascribe_forms/property';
|
||||
import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece';
|
||||
|
||||
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
|
@ -7,8 +7,8 @@ import PieceActions from '../actions/piece_actions';
|
||||
|
||||
const PieceSource = {
|
||||
lookupPiece: {
|
||||
remote(state) {
|
||||
return requests.get('piece', { piece_id: state.pieceMeta.idToFetch });
|
||||
remote(state, pieceId) {
|
||||
return requests.get('piece', { piece_id: pieceId });
|
||||
},
|
||||
|
||||
success: PieceActions.successFetchPiece,
|
||||
|
@ -21,8 +21,7 @@ class PieceStore {
|
||||
getInitialState() {
|
||||
this.piece = {};
|
||||
this.pieceMeta = {
|
||||
err: null,
|
||||
idToFetch: null
|
||||
err: null
|
||||
};
|
||||
|
||||
return {
|
||||
@ -31,10 +30,12 @@ class PieceStore {
|
||||
}
|
||||
}
|
||||
|
||||
onFetchPiece(idToFetch) {
|
||||
this.pieceMeta.idToFetch = idToFetch;
|
||||
onFetchPiece(pieceId) {
|
||||
this.getInstance().lookupPiece(pieceId);
|
||||
|
||||
this.getInstance().lookupPiece();
|
||||
// Prevent alt from sending an empty change event when a request is sent
|
||||
// off to the source
|
||||
this.preventDefault();
|
||||
}
|
||||
|
||||
onSuccessFetchPiece({ piece }) {
|
||||
@ -42,10 +43,12 @@ class PieceStore {
|
||||
this.onUpdatePiece(piece);
|
||||
} else {
|
||||
this.pieceMeta.err = new Error('Problem fetching the piece');
|
||||
console.logGlobal(this.pieceMeta.err);
|
||||
}
|
||||
}
|
||||
|
||||
onErrorPiece(err) {
|
||||
console.logGlobal(err);
|
||||
this.pieceMeta.err = err;
|
||||
}
|
||||
|
||||
@ -56,11 +59,10 @@ class PieceStore {
|
||||
onUpdatePiece(piece) {
|
||||
this.piece = piece;
|
||||
this.pieceMeta.err = null;
|
||||
this.pieceMeta.idToFetch = null;
|
||||
}
|
||||
|
||||
onUpdateProperty({ key, value }) {
|
||||
if(this.piece && key in this.piece) {
|
||||
if (this.piece && key in this.piece) {
|
||||
this.piece[key] = value;
|
||||
} else {
|
||||
throw new Error('There is no piece defined in PieceStore or the piece object does not have the property you\'re looking for.');
|
||||
|
@ -238,7 +238,7 @@ $vivi23--highlight-color: #de2600;
|
||||
&.active:hover{
|
||||
background-color: $vivi23--highlight-color;
|
||||
border-color: $vivi23--highlight-color;
|
||||
color: $vivi23--highlight-color;
|
||||
color: $vivi23--bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user