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

Merge remote-tracking branch 'origin/AD-943-add-custom-additional-fields' into AD-943-add-custom-additional-fields

This commit is contained in:
diminator 2015-09-22 17:23:37 +02:00
commit 24b7031c72
9 changed files with 142 additions and 95 deletions

View File

@ -35,27 +35,47 @@ class ContractAgreementListActions {
);
}
fetchAvailableContractAgreementList(issuer){
fetchAvailableContractAgreementList(issuer, createContractAgreement) {
return Q.Promise((resolve, reject) => {
this.actions.fetchContractAgreementList(issuer, true, null)
.then((contractAgreementListAccepted) => {
if (!contractAgreementListAccepted) {
// fetch pending agreements if no accepted ones
return this.actions.fetchContractAgreementList(issuer, null, true);
OwnershipFetcher.fetchContractAgreementList(issuer, true, null)
.then((acceptedContractAgreementList) => {
// if there is at least an accepted contract agreement, we're going to
// use it
if(acceptedContractAgreementList.count > 0) {
this.actions.updateContractAgreementList(acceptedContractAgreementList.results);
} else {
// otherwise, we're looking for contract agreements that are still pending
//
// Normally nesting promises, but for this conditional one, it makes sense to not
// overcomplicate the method
OwnershipFetcher.fetchContractAgreementList(issuer, null, true)
.then((pendingContractAgreementList) => {
if(pendingContractAgreementList.count > 0) {
this.actions.updateContractAgreementList(pendingContractAgreementList.results);
} else {
// if there was neither a pending nor an active contractAgreement
// found and createContractAgreement is set to true, we create a
// new contract agreement
if(createContractAgreement) {
this.actions.createContractAgreementFromPublicContract(issuer);
}
}
})
.catch((err) => {
console.logGlobal(err);
reject(err);
});
}
else {
resolve(contractAgreementListAccepted);
}
}).then((contractAgreementListPending) => {
resolve(contractAgreementListPending);
}).catch((err) => {
})
.catch((err) => {
console.logGlobal(err);
reject(err);
});
});
}
);
}
createContractAgreementFromPublicContract(issuer){
createContractAgreementFromPublicContract(issuer) {
ContractListActions.fetchContractList(null, null, issuer)
.then((publicContract) => {
// create an agreement with the public contract if there is one

View File

@ -59,10 +59,13 @@ let LoanForm = React.createClass({
this.getContractAgreementsOrCreatePublic(this.props.email);
},
/**
* This method needs to be in form_loan as some whitelabel pages (Cyland) load
* the loanee's email async!
*
* SO LEAVE IT IN!
*/
componentWillReceiveProps(nextProps) {
// however, it can also be that at the time the component is mounting,
// the email is not defined (because it's asynchronously fetched from the server).
// Then we need to update it as soon as it is included into LoanForm's props.
if(nextProps && nextProps.email && this.props.email !== nextProps.email) {
this.getContractAgreementsOrCreatePublic(nextProps.email);
}
@ -80,14 +83,7 @@ let LoanForm = React.createClass({
ContractAgreementListActions.flushContractAgreementList.defer();
if (email) {
// fetch the available contractagreements (pending/accepted)
ContractAgreementListActions.fetchAvailableContractAgreementList(email).then(
(contractAgreementList) => {
if (!contractAgreementList && this.props.createPublicContractAgreement) {
// for public contracts: fetch the public contract and create a contractagreement if available
ContractAgreementListActions.createContractAgreementFromPublicContract(email);
}
}
);
ContractAgreementListActions.fetchAvailableContractAgreementList(email, true);
}
},
@ -119,25 +115,46 @@ let LoanForm = React.createClass({
// we need to define a key on the InputCheckboxes as otherwise
// react is not rerendering them on a store switch and is keeping
// the default value of the component (which is in that case true)
let contract = this.state.contractAgreementList[0].contract;
let contractAgreement = this.state.contractAgreementList[0];
let contract = contractAgreement.contract;
return (
<Property
name="terms"
className="ascribe-settings-property-collapsible-toggle"
style={{paddingBottom: 0}}>
<InputCheckbox
key="terms_explicitly"
defaultChecked={false}>
<span>
{getLangText('I agree to the')}&nbsp;
<a href={contract.blob.url_safe} target="_blank">
{getLangText('terms of ')} {contract.issuer}
</a>
</span>
</InputCheckbox>
</Property>
);
if(contractAgreement.datetime_accepted) {
return (
<Property
name="terms"
hidden={false}
className="notification-contract-pdf">
<embed
className="loan-form"
src={contract.blob.url_safe}
alt="pdf"
pluginspage="http://www.adobe.com/products/acrobat/readstep2.html"/>
{/* We still need to send the server information that we're accepting */}
<InputCheckbox
style={{'display': 'none'}}
key="terms_implicitly"
defaultChecked={true} />
</Property>
);
} else {
return (
<Property
name="terms"
className="ascribe-settings-property-collapsible-toggle"
style={{paddingBottom: 0}}>
<InputCheckbox
key="terms_explicitly"
defaultChecked={false}>
<span>
{getLangText('I agree to the')}&nbsp;
<a href={contract.blob.url_safe} target="_blank">
{getLangText('terms of ')} {contract.issuer}
</a>
</span>
</InputCheckbox>
</Property>
);
}
} else {
return (
<Property
@ -157,12 +174,11 @@ let LoanForm = React.createClass({
let appendix = this.state.contractAgreementList[0].appendix;
if (appendix && appendix.default) {
return (
<div className='notification-contract-footer'>
<h2>{getLangText('Appendix')}</h2>
<pre>
{appendix.default}
</pre>
</div>
<Property
name='appendix'
label={getLangText('Appendix')}>
<pre className="ascribe-pre">{appendix.default}</pre>
</Property>
);
}
}
@ -214,7 +230,7 @@ let LoanForm = React.createClass({
name='loanee'
label={getLangText('Loanee Email')}
editable={!this.props.email}
onBlur={this.handleOnChange}
onChange={this.handleOnChange}
overrideForm={!!this.props.email}>
<input
value={this.props.email}
@ -264,6 +280,8 @@ let LoanForm = React.createClass({
placeholder={getLangText('Enter a message...')}
required={this.props.showPersonalMessage ? 'required' : ''}/>
</Property>
{this.getContractCheckbox()}
{this.getAppendix()}
<Property
name='password'
label={getLangText('Password')}
@ -273,8 +291,6 @@ let LoanForm = React.createClass({
placeholder={getLangText('Enter your password')}
required={this.props.showPassword ? 'required' : ''}/>
</Property>
{this.getContractCheckbox()}
{this.getAppendix()}
{this.props.children}
</Form>
);

View File

@ -25,7 +25,10 @@ let InputCheckbox = React.createClass({
// provided by Property
disabled: React.PropTypes.bool,
onChange: React.PropTypes.func
onChange: React.PropTypes.func,
// can be used to style the component from the outside
style: React.PropTypes.object
},
// As HTML inputs, we're setting the default value for an input to checked === false
@ -98,6 +101,7 @@ let InputCheckbox = React.createClass({
return (
<span
style={this.props.style}
onClick={this.onChange}>
<input
type="checkbox"

View File

@ -19,20 +19,10 @@ let InputTextAreaToggable = React.createClass({
};
},
componentDidUpdate(prevProps, prevState) {
// if the components state value was changed during an update, we want to refresh it
// in this component as well as in the parent Property
if(!this.state.value && this.state.value !== prevState.value) {
this.handleChange({
target: {
value: this.state.value
}
});
}
// Otherwise, if state wasn't defined beforehand and defaultValue is defined from the outside
// we set it as the component's state and update Property by calling handleChange
if(!this.state.value && this.props.defaultValue) {
componentDidUpdate() {
// If the initial value of state.value is null, we want to set props.defaultValue
// as a value. In all other cases TextareaAutosize.onChange is updating.handleChange already
if(this.state.value === null && this.props.defaultValue) {
this.setState({
value: this.props.defaultValue
});

View File

@ -68,7 +68,7 @@ let IkonotvArtistDetailsForm = React.createClass({
type="submit"
className="btn ascribe-btn ascribe-btn-login"
disabled={this.props.disabled}>
{getLangText('Proceed to artwork details')}
{getLangText('Proceed to loan')}
</button>
);

View File

@ -67,7 +67,7 @@ let IkonotvArtworkDetailsForm = React.createClass({
type="submit"
className="btn ascribe-btn ascribe-btn-login"
disabled={this.props.disabled}>
{getLangText('Proceed to loan')}
{getLangText('Proceed to artist details')}
</button>
);

View File

@ -22,6 +22,8 @@ import GlobalNotificationActions from '../../../../../actions/global_notificatio
import CopyrightAssociationForm from '../../../../ascribe_forms/form_copyright_association';
import Property from '../../../../ascribe_forms/property';
import AppConstants from '../../../../../constants/application_constants';
import { getLangText } from '../../../../../utils/lang_utils';
@ -67,16 +69,11 @@ let IkonotvContractNotifications = React.createClass({
if (blob.mime === 'pdf') {
return (
<div className='notification-contract-pdf'>
<embed src={blob.url_safe} alt="pdf"
pluginspage="http://www.adobe.com/products/acrobat/readstep2.html"/>
<div className='notification-contract-pdf-download'>
<a href={blob.url_safe} target="_blank">
<Glyphicon glyph='download-alt'/>
<span style={{padding: '0.3em'}}>
Download PDF version
</span>
</a>
</div>
<embed
height
src={blob.url_safe}
alt="pdf"
pluginspage="http://www.adobe.com/products/acrobat/readstep2.html"/>
</div>
);
}
@ -97,12 +94,11 @@ let IkonotvContractNotifications = React.createClass({
let appendix = notifications.contract_agreement.appendix;
if (appendix && appendix.default) {
return (
<div className='notification-contract-footer'>
<h1>{getLangText('Appendix')}</h1>
<pre>
{appendix.default}
</pre>
</div>
<Property
name='appendix'
label={getLangText('Appendix')}>
<pre className="ascribe-pre">{appendix.default}</pre>
</Property>
);
}
return null;
@ -153,9 +149,12 @@ let IkonotvContractNotifications = React.createClass({
},
render() {
if (this.state.contractAgreementListNotifications &&
this.state.contractAgreementListNotifications.length > 0) {
let notifications = this.state.contractAgreementListNotifications[0];
let blob = notifications.contract_agreement.contract.blob;
return (
<div className='container'>
<div className='notification-contract-wrapper'>
@ -168,6 +167,14 @@ let IkonotvContractNotifications = React.createClass({
{this.getContract()}
<div className='notification-contract-footer'>
{this.getAppendix()}
<div className='notification-contract-pdf-download'>
<a href={blob.url_safe} target="_blank">
<Glyphicon glyph='download-alt'/>
<span style={{padding: '0.3em'}}>
Download PDF version
</span>
</a>
</div>
{this.getCopyrightAssociationForm()}
<p style={{marginTop: '1em'}}>
<Button type="submit" onClick={this.handleConfirm}>

View File

@ -209,10 +209,9 @@ let IkonotvRegisterPiece = React.createClass({
getSlideLoan() {
if (this.canSubmit()) {
let today = new Moment();
let enddate = new Moment();
enddate.add(1, 'years');
enddate.add(2, 'years');
return (
<div data-slide-title={getLangText('Loan')}>
<Row className="no-margin">
@ -224,6 +223,8 @@ let IkonotvRegisterPiece = React.createClass({
email="submissions@ikono.org"
startdate={today}
enddate={enddate}
showStartDate={false}
showEndDate={false}
gallery="IkonoTV archive"
showPersonalMessage={false}
createPublicContractAgreement={false}

View File

@ -1,10 +1,10 @@
.notification-contract-download {
.notification-contract-wrapper {
text-align: center;
}
.notification-contract-wrapper{
text-align: center;
.notification-contract-pdf-download {
text-align: right;
margin: 1em 0 1em 0;
}
.notification-contract-logo {
@ -29,8 +29,17 @@
border: 1px solid #cccccc;
width: 100%;
height: 60vh;
margin-bottom: 0.4em;
margin-bottom: 0;
.loan-form {
height: 45vh;
}
}
.loan-form {
height: 40vh;
}
.notification-contract-pdf-download {
text-align: left;
margin-left: 1em;
@ -39,7 +48,7 @@
.notification-contract-footer {
text-align: left;
padding: 1em;
padding: 0 0 1em 0;
> h1 {
margin-top: 0.4em;
font-size: 1.4em;