This commit is contained in:
2017-05-12 20:04:28 +02:00
14 changed files with 235 additions and 4 deletions
+60
View File
@@ -0,0 +1,60 @@
import Ember from 'ember';
const {
Component,
inject: {
service
},
computed
} = Ember;
export default Component.extend({
kredits: service(),
proposal: null,
inProgress: false,
isValidRecipient: computed('proposal.recipientAddress', function() {
return this.get('kredits.web3Instance').isAddress(this.get('proposal.recipientAddress'));
}),
isValidAmount: computed('proposal.amount', function() {
// TODO
return true;
}),
isValidUrl: computed('proposal.url', function() {
// TODO
return true;
}),
isValidIpfsHash: computed('proposal.ipfsHash', function() {
// TODO
return true;
}),
isValid: computed.and('isValidRecipient', 'isValidAmount', 'isValidUrl',
'isValidIpfsHash'),
actions: {
save() {
if (this.get('isValid')) {
this.set('inProgress', true);
this.get('kredits').addProposal(this.get('proposal'))
.then(() => {
this.attrs.onSave();
}).catch((error) => {
Ember.Logger.error('Error creating the proposal', error);
alert('Something went wrong.');
}).finally(() => {
this.set('inProgress', false);
});
} else {
alert('Invalid data. Please review and try again.');
}
}
}
});
+31
View File
@@ -0,0 +1,31 @@
<form {{action "save" on="submit"}}>
<p>
{{input type="text"
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
value=proposal.recipientAddress
class=(if isValidRecipient 'valid' '')}}
</p>
<p>
{{input type="text"
placeholder="100"
value=proposal.amount
class=(if isValidAmount 'valid' '')}}
</p>
<p>
{{input type="text"
placeholder="URL"
value=proposal.url
class=(if isValidUrl 'valid' '')}}
</p>
<p>
{{input type="text"
placeholder="IPFS Hash"
value=proposal.ipfsHash
class=(if isValidIpfsHash 'valid' '')}}
</p>
<p class="actions">
{{input type="submit" value=(if inProgress 'Processing' 'Save') disabled=inProgress}}
{{#link-to 'index'}}Back{{/link-to}}
</p>
</form>
+27
View File
@@ -0,0 +1,27 @@
import Ember from 'ember';
import QueryParams from 'ember-parachute';
export const queryParams = new QueryParams({
recipient: {
defaultValue: ''
},
amount: {
defaultValue: ''
},
url: {
defaultValue: ''
},
ipfsHash: {
defaultValue: ''
}
});
export default Ember.Controller.extend(queryParams.Mixin, {
actions: {
onSave() {
this.transitionToRoute('index');
}
}
});
+3
View File
@@ -8,6 +8,9 @@ const Router = Ember.Router.extend({
Router.map(function() { Router.map(function() {
this.route('spinner'); this.route('spinner');
this.route('proposals', function() {
this.route('new');
});
}); });
export default Router; export default Router;
+15
View File
@@ -0,0 +1,15 @@
import Ember from 'ember';
import Proposal from 'kredits-web/models/proposal';
export default Ember.Route.extend({
model(params) {
return Proposal.create({
recipientAddress: params.recipient,
amount: params.amount,
url: params.url,
ipfsHash: params.ipfsHash
});
}
});
+20 -3
View File
@@ -66,7 +66,7 @@ export default Ember.Service.extend({
Ember.Logger.debug('[kredits] read from contract', contract); Ember.Logger.debug('[kredits] read from contract', contract);
return new Ember.RSVP.Promise((resolve, reject) => { return new Ember.RSVP.Promise((resolve, reject) => {
this.get(contract)[contractMethod](...args, (err, data) => { this.get(contract)[contractMethod](...args, (err, data) => {
if (err) { reject(err); } if (err) { reject(err); return; }
resolve(data); resolve(data);
}); });
}); });
@@ -144,7 +144,7 @@ export default Ember.Service.extend({
Ember.Logger.debug('[kredits] vote for', proposalId); Ember.Logger.debug('[kredits] vote for', proposalId);
return new Ember.RSVP.Promise((resolve, reject) => { return new Ember.RSVP.Promise((resolve, reject) => {
this.get('kreditsContract').vote(proposalId, (err, data) => { this.get('kreditsContract').vote(proposalId, (err, data) => {
if (err) { reject(err); } if (err) { reject(err); return; }
Ember.Logger.debug('[kredits] vote response', data); Ember.Logger.debug('[kredits] vote response', data);
resolve(data); resolve(data);
}); });
@@ -168,7 +168,7 @@ export default Ember.Service.extend({
contributor.set('ipfsHash', ipfsHash); contributor.set('ipfsHash', ipfsHash);
console.debug('ADD', address, name, ipfsHash, isCore, id); console.debug('ADD', address, name, ipfsHash, isCore, id);
this.get('kreditsContract').addContributor(address, name, ipfsHash, isCore, id, (err, data) => { this.get('kreditsContract').addContributor(address, name, ipfsHash, isCore, id, (err, data) => {
if (err) { reject(err); } if (err) { reject(err); return; }
Ember.Logger.debug('[kredits] add contributor response', data); Ember.Logger.debug('[kredits] add contributor response', data);
resolve(contributor); resolve(contributor);
}); });
@@ -176,6 +176,23 @@ export default Ember.Service.extend({
}); });
}, },
addProposal(proposal) {
return new Ember.RSVP.Promise((resolve, reject) => {
const {
recipientAddress,
amount,
url,
ipfsHash
} = proposal.getProperties('recipientAddress', 'amount', 'url', 'ipfsHash');
this.get('kreditsContract').addProposal(recipientAddress, amount, url, ipfsHash, (err, data) => {
if (err) { reject(err); return; }
Ember.Logger.debug('[kredits] add proposal response', data);
resolve();
});
});
},
logKreditsContract: function() { logKreditsContract: function() {
Ember.Logger.debug('[kredits] kreditsContract', this.get('kreditsContract')); Ember.Logger.debug('[kredits] kreditsContract', this.get('kreditsContract'));
}.on('init') }.on('init')
+16
View File
@@ -65,6 +65,22 @@ section {
} }
} }
} }
&#proposals-open, &#proposals-closed {
.actions {
padding-top: 3rem;
font-size: 1rem;
color: lightblue;
text-align: center;
@include media($mobile) {
padding-top: 2rem;
}
a {
color: lightblue;
}
}
}
} }
button, input[type=submit] { button, input[type=submit] {
+5 -1
View File
@@ -1,4 +1,4 @@
section#add-contributor { section#add-contributor, section#add-proposal {
form { form {
@@ -8,6 +8,10 @@ section#add-contributor {
&.actions { &.actions {
padding-top: 1rem; padding-top: 1rem;
text-align: center; text-align: center;
a {
color: lightblue;
margin-left: 1rem;
}
} }
} }
+8
View File
@@ -22,6 +22,10 @@
{{proposal-list proposals=proposalsOpenSorted {{proposal-list proposals=proposalsOpenSorted
confirmAction="confirmProposal" confirmAction="confirmProposal"
contractInteractionEnabled=contractInteractionEnabled}} contractInteractionEnabled=contractInteractionEnabled}}
<p class="actions">
{{#link-to 'proposals.new'}}Create new proposal{{/link-to}}
</p>
</div> </div>
</section> </section>
{{/if}} {{/if}}
@@ -33,6 +37,10 @@
<div class="content"> <div class="content">
{{proposal-list proposals=proposalsClosedSorted {{proposal-list proposals=proposalsClosedSorted
confirmAction="confirmProposal"}} confirmAction="confirmProposal"}}
<p class="actions">
{{#link-to 'proposals.new'}}Create new proposal{{/link-to}}
</p>
</div> </div>
</section> </section>
+10
View File
@@ -0,0 +1,10 @@
<section id="add-proposal">
<header>
<h2>Add Proposal</h2>
</header>
<div class="content">
{{add-proposal proposal=model onSave=(action 'onSave')}}
</div>
</section>
+1
View File
@@ -51,6 +51,7 @@
"ember-cli-uglify": "^1.2.0", "ember-cli-uglify": "^1.2.0",
"ember-export-application-global": "^1.0.5", "ember-export-application-global": "^1.0.5",
"ember-load-initializers": "^0.5.1", "ember-load-initializers": "^0.5.1",
"ember-parachute": "0.1.0",
"ember-resolver": "^2.0.3", "ember-resolver": "^2.0.3",
"ipfs-api": "^12.1.7", "ipfs-api": "^12.1.7",
"kredits-contracts": "^2.0.4", "kredits-contracts": "^2.0.4",
@@ -0,0 +1,16 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
moduleForComponent('add-proposal', 'Integration | Component | add proposal', {
integration: true
});
test('it renders', function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });
this.render(hbs`{{add-proposal}}`);
assert.equal(this.$('.actions a').text().trim(), 'Back');
});
@@ -0,0 +1,12 @@
import { moduleFor, test } from 'ember-qunit';
moduleFor('controller:proposals/new', 'Unit | Controller | proposals/new', {
// Specify the other units that are required for this test.
// needs: ['controller:foo']
});
// Replace this with your real tests.
test('it exists', function(assert) {
let controller = this.subject();
assert.ok(controller);
});
+11
View File
@@ -0,0 +1,11 @@
import { moduleFor, test } from 'ember-qunit';
moduleFor('route:proposals/new', 'Unit | Route | proposals/new', {
// Specify the other units that are required for this test.
// needs: ['controller:foo']
});
test('it exists', function(assert) {
let route = this.subject();
assert.ok(route);
});