Cleanup controller, templates and service #41

Merged
fsmanuel merged 3 commits from refactor/cleanup-models into master 2018-04-08 12:56:06 +00:00
6 changed files with 93 additions and 111 deletions
Showing only changes of commit 28f7466595 - Show all commits
+4 -2
View File
@@ -2,9 +2,11 @@
<li data-proposal-id={{proposal.id}} title="({{proposal.kind}}) {{proposal.description}}">
<span class="category {{proposal.kind}}">♥</span>
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
for <span class="recipient">{{proposal.recipientName}}</span>
for <span class="recipient">{{proposal.contributor.name}}</span>
<span class="votes">({{proposal.votesCount}}/{{proposal.votesNeeded}} votes)</span>
{{#unless proposal.executed}}<button {{action "confirm" proposal.id}}>+1</button>{{/unless}}
{{#unless proposal.isExecuted}}
<button {{action "confirm" proposal.id}}>+1</button>
{{/unless}}
</li>
{{/each}}
+57 -74
View File
@@ -1,51 +1,10 @@
import Ember from 'ember';
import Proposal from 'kredits-web/models/proposal';
import Controller from 'ember-controller';
import computed, { alias, filter, filterBy, sort } from 'ember-computed';
import injectService from 'ember-service/inject';
const {
computed,
inject: {
service
}
} = Ember;
export default Ember.Controller.extend({
kredits: service(),
contractInteractionEnabled: computed.alias('kredits.hasAccounts'),
proposalsOpen: function() {
let proposals = this.get('model.proposals')
.filterBy('executed', false)
.map(p => {
p.set('recipientName', this.get('model.contributors').findBy('id', p.get('recipientId')).name);
return p;
});
return proposals;
}.property('model.proposals.[]', 'model.proposals.@each.executed', 'model.contributors.[]'),
proposalsClosed: function() {
let proposals = this.get('model.proposals')
.filterBy('executed', true)
.map(p => {
p.set('recipientName', this.get('model.contributors').findBy('id', p.get('recipientId')).name);
return p;
});
return proposals;
}.property('model.proposals.[]', 'model.proposals.@each.executed', 'model.contributors.[]'),
proposalsSorting: ['id:desc'],
proposalsClosedSorted: Ember.computed.sort('proposalsClosed', 'proposalsSorting'),
proposalsOpenSorted: Ember.computed.sort('proposalsOpen', 'proposalsSorting'),
contributorsWithKredits: function() {
return this.get('model.contributors').filter(c => {
return c.get('balance') !== 0;
});
}.property('model.contributors.@each.balance'),
contributorsSorting: ['balance:desc'],
contributorsSorted: Ember.computed.sort('contributorsWithKredits', 'contributorsSorting'),
export default Controller.extend({
kredits: injectService(),
init() {
this._super(...arguments);
@@ -58,58 +17,82 @@ export default Ember.Controller.extend({
});
bumi commented 2018-04-08 12:22:09 +00:00 (Migrated from github.com)
Review

we should reuse the getProposalById function here to load all the proposal data.
adds another call but makes sure we have all the proposal data (and not only the data from the event)

we should reuse the `getProposalById` function here to load all the proposal data. adds another call but makes sure we have all the proposal data (and not only the data from the event)
},
_handleProposalCreated(proposalId, creatorAddress, recipientAddress, amount) {
if (Ember.isPresent(this.get('model.proposals')
.findBy('id', proposalId.toNumber()))) {
contributors: alias('model.contributors'),
contributorsWithKredits: filter('contributors', function(contributor) {
return contributor.get('balance') !== 0;
}),
contributorsSorting: ['balance:desc'],
contributorsSorted: sort('contributorsWithKredits', 'contributorsSorting'),
proposals: computed('model.proposals.[]', 'contributors.[]', function() {
return this.get('model.proposals')
.map((proposal) => {
let contributor = this.get('contributors')
.findBy('id', proposal.get('recipientId'));
if (contributor) {
proposal.set('contributor', contributor);
}
return proposal;
});
}),
proposalsOpen: filterBy('proposals', 'isExecuted', false),
proposalsClosed: filterBy('proposals', 'isExecuted', true),
proposalsSorting: ['id:desc'],
proposalsClosedSorted: sort('proposalsClosed', 'proposalsSorting'),
proposalsOpenSorted: sort('proposalsOpen', 'proposalsSorting'),
_handleProposalCreated(proposalId, creatorAddress, recipientId, amount) {
// TODO: check if proposalId is already a string
let proposal = this.get('proposals')
.findBy('id', proposalId.toString());
if (proposal) {
Ember.Logger.debug('[index] proposal exists, not adding from event');
return false;
return;
}
let proposal = Proposal.create({
id: proposalId.toNumber(),
// TODO: we should remove votesNeeded
proposal = this.get('kredits').buildModel('proposal', {
id: proposalId,
creatorAddress: creatorAddress,
recipientAddress: recipientAddress,
recipientName: null,
votesCount: 0,
recipientId: recipientId.toString(),
votesNeeded: 2,
amount: amount.toNumber(),
executed: false
});
this.get('model.proposals').pushObject(proposal);
this.get('proposals').pushObject(proposal);
},
_handleProposalExecuted(proposalId, recipientId, amount) {
if (this.get('model.proposals')
.findBy('id', recipientId.toNumber())
.get('executed')) {
// TODO: check if proposalId is already a string
let proposal = this.get('proposals')
.findBy('id', proposalId.toString());
if (proposal.get('isExecuted')) {
Ember.Logger.debug('[index] proposal already executed, not adding from event');
return false;
return;
}
this.get('model.proposals')
.findBy('id', recipientId.toNumber())
.setProperties({
'executed': true,
'votesCount': 2 // TODO use real count
});
proposal.setProperties({
'executed': true,
});
this.get('model.contributors')
.findBy('id', recipientId)
this.get('contributors')
.findBy('id', recipientId.toString())
.incrementProperty('balance', amount.toNumber());
},
_handleProposalVoted(proposalId, voter, totalVotes) {
this.get('model.proposals')
.findBy('id', proposalId.toNumber())
this.get('proposals')
.findBy('id', proposalId.toString())
.setProperties({ 'votesCount': totalVotes });
},
_handleTransfer(data) {
this.get('model.contributors')
this.get('contributors')
.findBy('address', data.args.from)
.incrementProperty('balance', - data.args.value.toNumber());
this.get('model.contributors')
this.get('contributors')
.findBy('address', data.args.to)
.incrementProperty('balance', data.args.value.toNumber());
},
@@ -125,7 +108,7 @@ export default Ember.Controller.extend({
save(contributor) {
return this.get('kredits').addContributor(contributor)
.then((contributor) => {
this.get('model.contributors').pushObject(contributor);
this.get('contributors').pushObject(contributor);
return contributor;
});
}
+6 -6
View File
@@ -1,4 +1,5 @@
import EmberObject from 'ember-object';
import { alias } from 'ember-computed';
export default EmberObject.extend({
// Contract
@@ -11,6 +12,9 @@ export default EmberObject.extend({
executed: null,
ipfsHash: null,
// Shortcuts
isExecuted: alias('executed'),
// IPFS
kind: null,
description: null,
@@ -18,10 +22,6 @@ export default EmberObject.extend({
url: null,
ipfsData: '',
// Deprecated
recipientAddress: null,
recipientName: null,
recipientProfile: null,
// TODO: add contributor relation
// Relationships
contributor: null,
});
+16 -20
View File
@@ -109,21 +109,17 @@ export default Service.extend({
});
},
// TODO: Should be part of the service
buildContributor(attributes) {
debug('[kredits] buildContributor', attributes);
buildModel(name, attributes) {
debug('[kredits] build', name, attributes);
let model = getOwner(this).lookup(`model:${name}`);
let contributor = getOwner(this).lookup('model:contributor');
contributor.setProperties(attributes);
return contributor;
},
// coerce id to string
if (attributes.id) {
attributes.id = attributes.id.toString();
}
buildProposal(attributes) {
debug('[kredits] buildProposal', attributes);
let proposal = getOwner(this).lookup('model:proposal');
proposal.setProperties(attributes);
return proposal;
model.setProperties(attributes);
return model;
},
getContributorById(id) {
@@ -135,7 +131,7 @@ export default Service.extend({
let isCurrentUser = this.get('currentUserAccounts').includes(address);
return {
id: id.toString(),
id: id,
address,
balance: balance.toNumber(),
ipfsHash,
@@ -148,7 +144,7 @@ export default Service.extend({
return this.fetchAndMergeIpfsData(data, ContributorSerializer);
})
.then((attributes) => {
return this.buildContributor(attributes);
return this.buildModel('contributor', attributes);
});
},
@@ -217,9 +213,9 @@ export default Service.extend({
ipfsHash,
}) => {
return {
id: id.toString(),
id: id,
creatorAddress,
recipientId: recipientId.toNumber(),
recipientId: recipientId.toString(),
votesCount: votesCount.toNumber(),
votesNeeded: votesNeeded.toNumber(),
amount: amount.toNumber(),
@@ -232,7 +228,7 @@ export default Service.extend({
return this.fetchAndMergeIpfsData(data, ContributionSerializer);
})
.then((attributes) => {
return this.buildProposal(attributes);
return this.buildModel('proposal', attributes);
});
},
@@ -296,7 +292,7 @@ export default Service.extend({
})
.then((data) => {
debug('[kredits] add contributor response', data);
return this.buildContributor(attributes);
return this.buildModel('contributor', attributes);
});
},
@@ -333,7 +329,7 @@ export default Service.extend({
})
.then((data) => {
debug('[kredits] add proposal response', data);
return this.buildProposal(attributes);
return this.buildModel('proposal', attributes);
});
},
+10 -8
View File
@@ -30,11 +30,13 @@
<h2>Open Proposals</h2>
</header>
<div class="content">
{{!-- TODO: We need a better naming for kredits.hasAccounts --}}
{{proposal-list proposals=proposalsOpenSorted
confirmAction="confirmProposal"
contractInteractionEnabled=contractInteractionEnabled}}
contractInteractionEnabled=kredits.hasAccounts}}
{{#if contractInteractionEnabled}}
{{!-- TODO: We need a better naming --}}
{{#if kredits.hasAccounts}}
<p class="actions">
{{#link-to 'proposals.new'}}Create new proposal{{/link-to}}
</p>
@@ -51,7 +53,8 @@
{{proposal-list proposals=proposalsClosedSorted
confirmAction="confirmProposal"}}
{{#if contractInteractionEnabled}}
{{!-- TODO: We need a better naming --}}
{{#if kredits.hasAccounts}}
<p class="actions">
{{#link-to 'proposals.new'}}Create new proposal{{/link-to}}
</p>
@@ -65,11 +68,10 @@
</header>
<div class="content">
{{!--
TODO:
only show the form if currentUser.isCore else show:
{{#if currentUser.isCore}}
{{add-contributor contributors=model.contributors save=(action 'save')}}
{{else}}
Only core team members can add new contributors. Please ask someone to set you up.
--}}
{{add-contributor contributors=model.contributors save=(action 'save')}}
{{/if}}
</div>
</section>
@@ -7,7 +7,6 @@ module('Serializers contribution');
test('#serialize returns a valid JSON-LD representation', function(assert) {
let serialized = ContributionSerializer.serialize({
recipientAddress: '0xd4a64570b12da659ee4bbd41c3509b7b1f9c51ac',
kind: 'design',
description: 'New logo design',
url: 'http://opensourcedesign.org',