Finish Reimbursement UI (MVP) #209
@@ -1,7 +1,18 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { sort } from '@ember/object/computed';
|
||||
import { action } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ReimbursementListComponent extends Component {
|
||||
@service kredits;
|
||||
|
||||
itemSorting = Object.freeze(['pendingStatus:asc', 'id:desc']);
|
||||
@sort('args.items', 'itemSorting') itemsSorted;
|
||||
|
||||
@action
|
||||
veto (id) {
|
||||
this.kredits.vetoReimbursement(id).then(transaction => {
|
||||
console.debug('[controllers:budget] Veto submitted to chain: '+transaction.hash);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
<li data-reimbursement-id={{reimbursement.id}}
|
||||
class="{{item-status reimbursement}}">
|
||||
<p class="meta">
|
||||
<span class="recipient"><UserAvatar @contributor={{reimbursement.contributor}} /></span>
|
||||
<span class="title">Expenses covered by {{reimbursement.contributor.name}}</span>
|
||||
<span class="title">
|
||||
Expenses covered by {{reimbursement.contributor.name}}
|
||||
</span>
|
||||
<span class="recipient">
|
||||
<UserAvatar @contributor={{reimbursement.contributor}} />
|
||||
</span>
|
||||
</p>
|
||||
<p class="token-amount">
|
||||
<span class="amount">
|
||||
@@ -26,6 +30,13 @@
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{#if this.kredits.currentUserIsCore}}
|
||||
<p>
|
||||
<button {{on "click" (fn this.veto reimbursement.id)}}
|
||||
disabled={{reimbursement.vetoed}}
|
||||
class="button small danger">veto</button>
|
||||
</p>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
+21
-8
@@ -617,6 +617,18 @@ export default Service.extend({
|
||||
yield this.fetchMissingObjects.perform('Reimbursement');
|
||||
}).group('syncTaskGroup'),
|
||||
|
||||
vetoReimbursement (id) {
|
||||
console.debug('[kredits] veto against reimbursement', id);
|
||||
const reimbursement = this.reimbursements.findBy('id', id);
|
||||
|
||||
return this.kredits.Reimbursement.functions.veto(id, { gasLimit: 300000 })
|
||||
.then(data => {
|
||||
console.debug('[kredits] veto response', data);
|
||||
reimbursement.set('pendingTx', data);
|
||||
return data;
|
||||
});
|
||||
},
|
||||
|
||||
//
|
||||
// Contract events
|
||||
//
|
||||
@@ -676,7 +688,7 @@ export default Service.extend({
|
||||
},
|
||||
|
||||
async handleContributionVetoed (contributionId) {
|
||||
console.debug('[kredits] ContributionVetoed event received for ', contributionId);
|
||||
console.debug('[kredits] ContributionVetoed event received for #', contributionId);
|
||||
const c = this.contributions.findBy('id', contributionId);
|
||||
|
||||
if (c) {
|
||||
@@ -709,14 +721,15 @@ export default Service.extend({
|
||||
//
|
||||
// TODO test when reimbursement txs are successful and veto is implemented
|
||||
//
|
||||
handleReimbursementVetoed (id) {
|
||||
console.debug('[kredits] ReimbursementVetoed received for ', id);
|
||||
const reimbursement = this.reimbursements.findBy('id', id);
|
||||
console.debug('[kredits] reimbursement', this.reimbursement);
|
||||
async handleReimbursementVetoed (id) {
|
||||
console.debug(`[kredits] ReimbursementVetoed received for #${id}`);
|
||||
const r = this.reimbursements.findBy('id', id);
|
||||
console.debug('[kredits] reimbursement', r);
|
||||
|
||||
if (reimbursement) {
|
||||
reimbursement.set('vetoed', true);
|
||||
reimbursement.set('pendingTx', null);
|
||||
if (r) {
|
||||
r.set('vetoed', true);
|
||||
r.set('pendingTx', null);
|
||||
await this.browserCache.reimbursements.setItem(r.id.toString(), r.serialize());
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@ ul.reimbursement-list {
|
||||
grid-row-gap: 0.5rem;
|
||||
padding-top: 1.6rem;
|
||||
|
||||
&.vetoed {
|
||||
text-decoration: line-through;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.token-amount {
|
||||
text-align: right;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user