Merge pull request #84 from ascribe/AD-1531-contract-settings-buttons-look-weird

AD-1531 Contract settings buttons look weird
This commit is contained in:
Brett Sun 2016-01-19 17:09:26 +01:00
commit 405a46dca3
6 changed files with 116 additions and 118 deletions

View File

@ -28,12 +28,10 @@ class ContractListActions {
}
changeContract(contract){
changeContract(contract) {
return Q.Promise((resolve, reject) => {
OwnershipFetcher.changeContract(contract)
.then((res) => {
resolve(res);
})
.then(resolve)
.catch((err)=> {
console.logGlobal(err);
reject(err);
@ -41,13 +39,11 @@ class ContractListActions {
});
}
removeContract(contractId){
return Q.Promise( (resolve, reject) => {
removeContract(contractId) {
return Q.Promise((resolve, reject) => {
OwnershipFetcher.deleteContract(contractId)
.then((res) => {
resolve(res);
})
.catch( (err) => {
.then(resolve)
.catch((err) => {
console.logGlobal(err);
reject(err);
});

View File

@ -28,11 +28,7 @@ import { mergeOptions, truncateTextAtCharIndex } from '../../utils/general_utils
let ContractSettings = React.createClass({
propTypes: {
location: React.PropTypes.object
},
getInitialState(){
getInitialState() {
return mergeOptions(
ContractListStore.getState(),
UserStore.getState()
@ -64,40 +60,39 @@ let ContractSettings = React.createClass({
ContractListActions.removeContract(contract.id)
.then((response) => {
ContractListActions.fetchContractList(true);
let notification = new GlobalNotificationModel(response.notification, 'success', 4000);
const notification = new GlobalNotificationModel(response.notification, 'success', 4000);
GlobalNotificationActions.appendGlobalNotification(notification);
})
.catch((err) => {
let notification = new GlobalNotificationModel(err, 'danger', 10000);
const notification = new GlobalNotificationModel(err, 'danger', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
});
};
},
getPublicContracts(){
getPublicContracts() {
return this.state.contractList.filter((contract) => contract.is_public);
},
getPrivateContracts(){
getPrivateContracts() {
return this.state.contractList.filter((contract) => !contract.is_public);
},
render() {
let publicContracts = this.getPublicContracts();
let privateContracts = this.getPrivateContracts();
const publicContracts = this.getPublicContracts();
const privateContracts = this.getPrivateContracts();
let createPublicContractForm = null;
setDocumentTitle(getLangText('Contracts settings'));
if(publicContracts.length === 0) {
if (publicContracts.length === 0) {
createPublicContractForm = (
<CreateContractForm
isPublic={true}
fileClassToUpload={{
singular: 'new contract',
plural: 'new contracts'
}}
location={this.props.location}/>
}} />
);
}
@ -114,7 +109,7 @@ let ContractSettings = React.createClass({
{publicContracts.map((contract, i) => {
return (
<ActionPanel
key={i}
key={contract.id}
title={contract.name}
content={truncateTextAtCharIndex(contract.name, 120, '(...).pdf')}
buttons={
@ -123,8 +118,7 @@ let ContractSettings = React.createClass({
aclObject={this.state.whitelabel}
aclName="acl_update_public_contract">
<ContractSettingsUpdateButton
contract={contract}
location={this.props.location}/>
contract={contract} />
</AclProxy>
<a
className="btn btn-default btn-sm margin-left-2px"
@ -154,12 +148,11 @@ let ContractSettings = React.createClass({
fileClassToUpload={{
singular: getLangText('new contract'),
plural: getLangText('new contracts')
}}
location={this.props.location}/>
}} />
{privateContracts.map((contract, i) => {
return (
<ActionPanel
key={i}
key={contract.id}
title={contract.name}
content={truncateTextAtCharIndex(contract.name, 120, '(...).pdf')}
buttons={
@ -168,8 +161,7 @@ let ContractSettings = React.createClass({
aclObject={this.state.whitelabel}
aclName="acl_update_private_contract">
<ContractSettingsUpdateButton
contract={contract}
location={this.props.location}/>
contract={contract} />
</AclProxy>
<a
className="btn btn-default btn-sm margin-left-2px"

View File

@ -24,71 +24,75 @@ let ContractSettingsUpdateButton = React.createClass({
},
submitFile(file) {
let contract = this.props.contract;
// override the blob with the key's value
contract.blob = file.key;
const contract = Object.assign(this.props.contract, { blob: file.key });
// send it to the server
ContractListActions
.changeContract(contract)
.then((res) => {
// Display feedback to the user
let notification = new GlobalNotificationModel(getLangText('Contract %s successfully updated', res.name), 'success', 5000);
const notification = new GlobalNotificationModel(getLangText('Contract %s successfully updated', contract.name), 'success', 5000);
GlobalNotificationActions.appendGlobalNotification(notification);
// and refresh the contract list to get the updated contracs
return ContractListActions.fetchContractList(true);
})
.then(() => {
// Also, reset the fineuploader component so that the user can again 'update' his contract
this.refs.fineuploader.reset();
})
.catch((err) => {
console.logGlobal(err);
let notification = new GlobalNotificationModel(getLangText('Contract could not be updated'), 'success', 5000);
return ContractListActions
.fetchContractList(true)
// Also, reset the fineuploader component if fetch is successful so that the user can again 'update' his contract
.then(this.refs.fineuploader.reset)
.catch((err) => {
const notification = new GlobalNotificationModel(getLangText('Latest contract failed to load'), 'danger', 5000);
GlobalNotificationActions.appendGlobalNotification(notification);
return Promise.reject(err);
});
}, (err) => {
const notification = new GlobalNotificationModel(getLangText('Contract could not be updated'), 'danger', 5000);
GlobalNotificationActions.appendGlobalNotification(notification);
});
return Promise.reject(err);
})
.catch(console.logGlobal);
},
render() {
return (
<ReactS3FineUploader
fileInputElement={UploadButton()}
keyRoutine={{
url: AppConstants.serverUrl + 's3/key/',
fileClass: 'contract'
}}
createBlobRoutine={{
url: ApiUrls.blob_contracts
}}
validation={{
itemLimit: AppConstants.fineUploader.validation.registerWork.itemLimit,
sizeLimit: AppConstants.fineUploader.validation.additionalData.sizeLimit,
allowedExtensions: ['pdf']
}}
setIsUploadReady={() =>{/* So that ReactS3FineUploader is not complaining */}}
signature={{
endpoint: AppConstants.serverUrl + 's3/signature/',
customHeaders: {
'X-CSRFToken': getCookie(AppConstants.csrftoken)
}
}}
deleteFile={{
enabled: true,
method: 'DELETE',
endpoint: AppConstants.serverUrl + 's3/delete',
customHeaders: {
'X-CSRFToken': getCookie(AppConstants.csrftoken)
}
}}
fileClassToUpload={{
singular: getLangText('UPDATE'),
plural: getLangText('UPDATE')
}}
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
submitFile={this.submitFile} />
ref='fineuploader'
fileInputElement={UploadButton({ showLabel: false })}
keyRoutine={{
url: AppConstants.serverUrl + 's3/key/',
fileClass: 'contract'
}}
createBlobRoutine={{
url: ApiUrls.blob_contracts
}}
validation={{
itemLimit: AppConstants.fineUploader.validation.registerWork.itemLimit,
sizeLimit: AppConstants.fineUploader.validation.additionalData.sizeLimit,
allowedExtensions: ['pdf']
}}
setIsUploadReady={() =>{/* So that ReactS3FineUploader is not complaining */}}
signature={{
endpoint: AppConstants.serverUrl + 's3/signature/',
customHeaders: {
'X-CSRFToken': getCookie(AppConstants.csrftoken)
}
}}
deleteFile={{
enabled: true,
method: 'DELETE',
endpoint: AppConstants.serverUrl + 's3/delete',
customHeaders: {
'X-CSRFToken': getCookie(AppConstants.csrftoken)
}
}}
fileClassToUpload={{
singular: getLangText('UPDATE'),
plural: getLangText('UPDATE')
}}
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
submitFile={this.submitFile} />
);
}
});

View File

@ -1,6 +1,7 @@
'use strict';
import React from 'react';
import classNames from 'classnames';
import { displayValidProgressFilesFilter } from '../react_s3_fine_uploader_utils';
import { getLangText } from '../../../utils/lang_utils';
@ -9,7 +10,7 @@ import { truncateTextAtCharIndex } from '../../../utils/general_utils';
const { func, array, bool, shape, string } = React.PropTypes;
export default function UploadButton({ className = 'btn btn-default btn-sm' } = {}) {
export default function UploadButton({ className = 'btn btn-default btn-sm', showLabel = true } = {}) {
return React.createClass({
displayName: 'UploadButton',
@ -119,28 +120,28 @@ export default function UploadButton({ className = 'btn btn-default btn-sm' } =
},
getUploadedFileLabel() {
const uploadedFile = this.getUploadedFile();
const uploadingFiles = this.getUploadingFiles();
if (showLabel) {
const uploadedFile = this.getUploadedFile();
const uploadingFiles = this.getUploadingFiles();
if(uploadingFiles.length) {
return (
<span>
{' ' + truncateTextAtCharIndex(uploadingFiles[0].name, 40) + ' '}
[<a onClick={this.onClickRemove}>{getLangText('cancel upload')}</a>]
</span>
);
} else if(uploadedFile) {
return (
<span>
<span className='ascribe-icon icon-ascribe-ok'/>
{' ' + truncateTextAtCharIndex(uploadedFile.name, 40) + ' '}
[<a onClick={this.onClickRemove}>{getLangText('remove')}</a>]
</span>
);
} else {
return (
<span>{getLangText('No file chosen')}</span>
);
if (uploadingFiles.length) {
return (
<span>
{' ' + truncateTextAtCharIndex(uploadingFiles[0].name, 40) + ' '}
[<a onClick={this.onClickRemove}>{getLangText('cancel upload')}</a>]
</span>
);
} else if (uploadedFile) {
return (
<span>
<span className='ascribe-icon icon-ascribe-ok'/>
{' ' + truncateTextAtCharIndex(uploadedFile.name, 40) + ' '}
[<a onClick={this.onClickRemove}>{getLangText('remove')}</a>]
</span>
);
} else {
return <span>{getLangText('No file chosen')}</span>;
}
}
},
@ -158,7 +159,7 @@ export default function UploadButton({ className = 'btn btn-default btn-sm' } =
* Therefore the wrapping component needs to be an `anchor` tag instead of a `button`
*/
return (
<div className="upload-button-wrapper">
<div className={classNames('ascribe-upload-button', {'ascribe-upload-button-has-label': showLabel})}>
{/*
The button needs to be of `type="button"` as it would
otherwise submit the form its in.

View File

@ -15,7 +15,7 @@ let OwnershipFetcher = {
/**
* Fetch the contracts of the logged-in user from the API.
*/
fetchContractList(isActive, isPublic, issuer){
fetchContractList(isActive, isPublic, issuer) {
let queryParams = {
isActive,
isPublic,
@ -28,7 +28,7 @@ let OwnershipFetcher = {
/**
* Create a contractagreement between the logged-in user and the email from the API with contract.
*/
createContractAgreement(signee, contractObj){
createContractAgreement(signee, contractObj) {
return requests.post(ApiUrls.ownership_contract_agreements, { body: {signee: signee, contract: contractObj.id }});
},
@ -44,23 +44,23 @@ let OwnershipFetcher = {
return requests.get(ApiUrls.ownership_contract_agreements, queryParams);
},
confirmContractAgreement(contractAgreement){
confirmContractAgreement(contractAgreement) {
return requests.put(ApiUrls.ownership_contract_agreements_confirm, {contract_agreement_id: contractAgreement.id});
},
denyContractAgreement(contractAgreement){
denyContractAgreement(contractAgreement) {
return requests.put(ApiUrls.ownership_contract_agreements_deny, {contract_agreement_id: contractAgreement.id});
},
fetchLoanPieceRequestList(){
fetchLoanPieceRequestList() {
return requests.get(ApiUrls.ownership_loans_pieces_request);
},
changeContract(contractObj){
changeContract(contractObj) {
return requests.put(ApiUrls.ownership_contract, { body: contractObj, contract_id: contractObj.id });
},
deleteContract(contractObjId){
deleteContract(contractObjId) {
return requests.delete(ApiUrls.ownership_contract, {contract_id: contractObjId});
}
};

View File

@ -182,15 +182,20 @@
height: 12px;
}
.upload-button-wrapper {
.ascribe-upload-button {
display: inline-block;
text-align: left;
.btn {
font-size: 1em;
margin-right: 1em;
}
&.ascribe-upload-button-has-label {
display: block;
span + .btn {
margin-left: 1em;
.btn {
font-size: 1em;
margin-right: 1em;
}
span + .btn {
margin-left: 1em;
}
}
}