Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
251e61891f
|
|||
| 66e1adc719 | |||
|
62388a0488
|
|||
| d7fe860353 | |||
|
14da36b806
|
|||
|
636c79ecc7
|
|||
|
d67bfd59da
|
|||
|
67538a9437
|
|||
|
473522986d
|
|||
|
0dd5f6c5ad
|
|||
|
731e01f2c5
|
|||
|
f02e5572ba
|
|||
|
aad2aaecd1
|
|||
|
7a61d1c569
|
|||
|
697ace35b5
|
|||
|
89ddde28b8
|
|||
|
50b0f2cd7a
|
|||
|
1b78cb4cb4
|
|||
| b32f805cbd | |||
|
3110fd347e
|
|||
|
5612ac4e95
|
|||
|
69ab4913aa
|
|||
|
39e01e4558
|
|||
|
7afc75dbff
|
|||
|
f5f74ae27f
|
|||
|
55f7baecf6
|
@@ -18,7 +18,8 @@ export default class AddExpenseItemComponent extends Component {
|
|||||||
|
|
||||||
currencies = [
|
currencies = [
|
||||||
{ code: 'EUR' },
|
{ code: 'EUR' },
|
||||||
{ code: 'USD' }
|
{ code: 'USD' },
|
||||||
|
{ code: 'BTC' }
|
||||||
];
|
];
|
||||||
|
|
||||||
get isValidAmount () {
|
get isValidAmount () {
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import { inject as service } from '@ember/service';
|
|||||||
import { action } from '@ember/object';
|
import { action } from '@ember/object';
|
||||||
import { A } from '@ember/array';
|
import { A } from '@ember/array';
|
||||||
import { scheduleOnce } from '@ember/runloop';
|
import { scheduleOnce } from '@ember/runloop';
|
||||||
|
import { btcToSats, satsToBtc } from 'kredits-web/utils/btc-conversions';
|
||||||
import isValidAmount from 'kredits-web/utils/is-valid-amount';
|
import isValidAmount from 'kredits-web/utils/is-valid-amount';
|
||||||
|
import isoDateIsToday from 'kredits-web/utils/iso-date-is-today';
|
||||||
import readFileContent from 'kredits-web/utils/read-file-content';
|
import readFileContent from 'kredits-web/utils/read-file-content';
|
||||||
import config from 'kredits-web/config/environment';
|
import config from 'kredits-web/config/environment';
|
||||||
|
|
||||||
@@ -27,6 +29,10 @@ export default class AddReimbursementComponent extends Component {
|
|||||||
this.exchangeRates.fetchRates();
|
this.exchangeRates.fetchRates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get contributorId () {
|
||||||
|
return this.recipientId || this.kredits.currentUser?.id;
|
||||||
|
}
|
||||||
|
|
||||||
get isValidTotal () {
|
get isValidTotal () {
|
||||||
return isValidAmount(this.total);
|
return isValidAmount(this.total);
|
||||||
}
|
}
|
||||||
@@ -69,22 +75,6 @@ export default class AddReimbursementComponent extends Component {
|
|||||||
anchor.scrollIntoView();
|
anchor.scrollIntoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTotalAmountFromFiat() {
|
|
||||||
let btcAmount = parseFloat(this.total);
|
|
||||||
|
|
||||||
if (this.exchangeRates.btceur > 0 && this.totalEUR > 0) {
|
|
||||||
btcAmount += (this.totalEUR / this.exchangeRates.btceur);
|
|
||||||
}
|
|
||||||
if (this.exchangeRates.btcusd > 0 && this.totalUSD > 0) {
|
|
||||||
btcAmount += (this.totalUSD / this.exchangeRates.btcusd);
|
|
||||||
}
|
|
||||||
if (this.totalUSD === 0 && this.totalEUR === 0) {
|
|
||||||
btcAmount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.total = btcAmount.toFixed(8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO use ember-concurrency here
|
// TODO use ember-concurrency here
|
||||||
// https://github.com/67P/kredits-web/pull/209#discussion_r1064234421
|
// https://github.com/67P/kredits-web/pull/209#discussion_r1064234421
|
||||||
@action
|
@action
|
||||||
@@ -104,7 +94,7 @@ export default class AddReimbursementComponent extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
updateContributor (event) {
|
updateContributor (event) {
|
||||||
this.recipientId = event.target.value;
|
this.recipientId = parseInt(event.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@@ -114,16 +104,38 @@ export default class AddReimbursementComponent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
addExpenseItem (expenseItem) {
|
async addExpenseItem (expense) {
|
||||||
this.expenses.pushObject(expenseItem);
|
let totalBTC = parseFloat(this.total);
|
||||||
this.updateTotalAmountFromFiat();
|
|
||||||
|
if (expense.currency === "BTC") {
|
||||||
|
expense.amountSats = btcToSats(expense.amount);
|
||||||
|
totalBTC += expense.amount;
|
||||||
|
} else {
|
||||||
|
let amountSats;
|
||||||
|
if (isoDateIsToday(expense.date)) {
|
||||||
|
amountSats = btcToSats(expense.amount / this.exchangeRates[expense.currency]);
|
||||||
|
} else {
|
||||||
|
const rates = await this.exchangeRates.fetchHistoricRates(expense.date);
|
||||||
|
amountSats = btcToSats(expense.amount / rates[expense.currency]);
|
||||||
|
}
|
||||||
|
expense.amountSats = amountSats;
|
||||||
|
totalBTC += satsToBtc(amountSats);
|
||||||
|
}
|
||||||
|
console.debug("Adding expense:", expense);
|
||||||
|
|
||||||
|
this.total = totalBTC.toFixed(8);
|
||||||
|
this.expenses.pushObject(expense);
|
||||||
this.expenseFormVisible = false;
|
this.expenseFormVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
removeExpenseItem (expenseItem) {
|
async removeExpenseItem (expense) {
|
||||||
this.expenses.removeObject(expenseItem);
|
let totalBTC = parseFloat(this.total);
|
||||||
this.updateTotalAmountFromFiat();
|
let amountBTC = satsToBtc(expense.amountSats);
|
||||||
|
totalBTC = totalBTC - amountBTC;
|
||||||
|
this.total = totalBTC.toFixed(8);
|
||||||
|
|
||||||
|
this.expenses.removeObject(expense);
|
||||||
|
|
||||||
if (this.expenses.length === 0) {
|
if (this.expenses.length === 0) {
|
||||||
this.expenseFormVisible = true;
|
this.expenseFormVisible = true;
|
||||||
@@ -136,12 +148,12 @@ export default class AddReimbursementComponent extends Component {
|
|||||||
if (!this.kredits.currentUser) { window.alert('You need to connect your RSK account first.'); return false }
|
if (!this.kredits.currentUser) { window.alert('You need to connect your RSK account first.'); return false }
|
||||||
if (!this.kredits.currentUserIsCore) { window.alert('Only core contributors can submit reimbursements.'); return false }
|
if (!this.kredits.currentUserIsCore) { window.alert('Only core contributors can submit reimbursements.'); return false }
|
||||||
|
|
||||||
const contributor = this.contributors.findBy('id', parseInt(this.recipientId));
|
const contributor = this.contributors.findBy('id', this.contributorId);
|
||||||
|
|
||||||
const attributes = {
|
const attributes = {
|
||||||
amount: parseInt(parseFloat(this.total) * 100000000), // convert to sats
|
amount: btcToSats(this.total),
|
||||||
token: config.tokens['BTC'],
|
token: config.tokens['BTC'],
|
||||||
recipientId: parseInt(this.recipientId),
|
recipientId: this.contributorId,
|
||||||
title: `Expenses covered by ${contributor.name}`,
|
title: `Expenses covered by ${contributor.name}`,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
url: this.url,
|
url: this.url,
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
<label>
|
<label>
|
||||||
<p class="label">Contributor:</p>
|
<p class="label">Contributor:</p>
|
||||||
<p>
|
<p>
|
||||||
<select required {{on "change" this.updateContributor}}>
|
<select id="contributor" required {{on "change" this.updateContributor}}>
|
||||||
<option value="" selected disabled hidden></option>
|
|
||||||
{{#each this.contributors as |contributor|}}
|
{{#each this.contributors as |contributor|}}
|
||||||
<option value={{contributor.id}} selected={{eq this.contributorId contributor.id}}>{{contributor.name}}</option>
|
<option value={{contributor.id}} selected={{eq this.contributorId contributor.id}}>{{contributor.name}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
@@ -15,6 +14,7 @@
|
|||||||
<p class="label">Total amount (BTC):</p>
|
<p class="label">Total amount (BTC):</p>
|
||||||
<p>
|
<p>
|
||||||
<Input @type="text"
|
<Input @type="text"
|
||||||
|
@name="total-btc"
|
||||||
@placeholder="0.0015"
|
@placeholder="0.0015"
|
||||||
@value={{this.total}}
|
@value={{this.total}}
|
||||||
@required={{true}}
|
@required={{true}}
|
||||||
@@ -50,7 +50,9 @@
|
|||||||
|
|
||||||
<p class="actions">
|
<p class="actions">
|
||||||
<button {{on "click" this.showExpenseForm}}
|
<button {{on "click" this.showExpenseForm}}
|
||||||
class="green small" type="button">+ Add another item</button>
|
id="add-another-item" class="green small" type="button">
|
||||||
|
+ Add another item
|
||||||
|
</button>
|
||||||
</p>
|
</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p>No line items yet.</p>
|
<p>No line items yet.</p>
|
||||||
|
|||||||
@@ -1,18 +1,43 @@
|
|||||||
import Component from '@ember/component';
|
import Component from '@glimmer/component';
|
||||||
|
import { action } from '@ember/object';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
|
import { tracked } from '@glimmer/tracking';
|
||||||
|
|
||||||
export default Component.extend({
|
export default class ContributorComponent extends Component {
|
||||||
tagName: '',
|
@service router;
|
||||||
|
|
||||||
router: service(),
|
@tracked selectedContributorId = null;
|
||||||
|
@tracked showToplistOnly = true;
|
||||||
|
|
||||||
selectedContributorId: null,
|
get contributorList () {
|
||||||
|
return this.args.contributorList;
|
||||||
|
}
|
||||||
|
|
||||||
actions: {
|
get contributorTop10 () {
|
||||||
|
return this.contributorList ?
|
||||||
|
this.contributorList.slice(0, 10) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get contributors () {
|
||||||
|
return this.showToplistOnly ?
|
||||||
|
this.contributorTop10 : this.contributorList;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hiddenContributorsAmount () {
|
||||||
|
return this.contributorList.length - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
get showAllButtonText () {
|
||||||
|
return `Show ${this.hiddenContributorsAmount} more contributors`;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
openContributorDetails (contributor) {
|
openContributorDetails (contributor) {
|
||||||
this.router.transitionTo('dashboard.contributors.show', contributor);
|
this.router.transitionTo('dashboard.contributors.show', contributor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
showAllContributors () {
|
||||||
|
this.showToplistOnly = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#each @contributorList as |c|}}
|
{{#each this.contributors as |c|}}
|
||||||
<tr role="button"
|
<tr role="button"
|
||||||
onclick={{action "openContributorDetails" c.contributor}}
|
onclick={{action "openContributorDetails" c.contributor}}
|
||||||
class="{{if (is-current-user c.contributor) "current-user"}} {{if (eq c.contributor.id @selectedContributorId) "selected"}}">
|
class="{{if (is-current-user c.contributor) "current-user"}} {{if (eq c.contributor.id @selectedContributorId) "selected"}}">
|
||||||
@@ -21,5 +21,12 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
{{#if this.showToplistOnly}}
|
||||||
|
<tr role="button" onclick={{action "showAllContributors"}}>
|
||||||
|
<td colspan="2">
|
||||||
|
{{this.showAllButtonText}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/if}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<span class="date">{{fmt-date-localized expense.date}}:</span>
|
<span class="date">{{fmt-date-localized expense.date}}:</span>
|
||||||
<span class="title">{{expense.title}}</span>
|
<span class="title">{{expense.title}}</span>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="amount">
|
<div class="amount" title="{{fmt-amount-sats-title expense.amountSats}}">
|
||||||
{{fmt-fiat-currency expense.amount expense.currency}}
|
{{fmt-fiat-currency expense.amount expense.currency}}
|
||||||
</div>
|
</div>
|
||||||
<p class="description">
|
<p class="description">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<li data-reimbursement-id={{@reimbursement.id}}
|
<li data-reimbursement-id={{@reimbursement.id}}
|
||||||
class="{{item-status @reimbursement}}"
|
class="{{item-status @reimbursement}}">
|
||||||
role="button" {{on "click" this.toggleExpenseDetails}}>
|
<p class="meta cursor-pointer" role="button"
|
||||||
<p class="meta">
|
{{on "click" this.toggleExpenseDetails}}>
|
||||||
<span class="recipient">
|
<span class="recipient">
|
||||||
<UserAvatar @contributor={{@reimbursement.contributor}} />
|
<UserAvatar @contributor={{@reimbursement.contributor}} />
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,10 +1,26 @@
|
|||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import { alias } from '@ember/object/computed';
|
import { alias } from '@ember/object/computed';
|
||||||
|
import { action } from '@ember/object';
|
||||||
|
|
||||||
export default class BudgetController extends Controller {
|
export default class BudgetController extends Controller {
|
||||||
@service kredits;
|
@service kredits;
|
||||||
|
@service router;
|
||||||
|
|
||||||
@alias('kredits.reimbursementsUnconfirmed') reimbursementsUnconfirmed;
|
@alias('kredits.reimbursementsUnconfirmed') reimbursementsUnconfirmed;
|
||||||
@alias('kredits.reimbursementsConfirmed') reimbursementsConfirmed;
|
@alias('kredits.reimbursementsConfirmed') reimbursementsConfirmed;
|
||||||
|
@alias('kredits.currentUserIsCore') currentUserIsCore;
|
||||||
|
|
||||||
|
@action
|
||||||
|
addReimbursement () {
|
||||||
|
if (!this.kredits.currentUser) {
|
||||||
|
window.alert('You need to connect your RSK account first.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!this.kredits.currentUserIsCore) {
|
||||||
|
window.alert('Only core contributors can submit reimbursements.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.router.transitionTo('reimbursements.new');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ export default Controller.extend({
|
|||||||
kreditsToplistSorting: computed('showUnconfirmedKredits', function(){
|
kreditsToplistSorting: computed('showUnconfirmedKredits', function(){
|
||||||
return this.showUnconfirmedKredits ? ['amountTotal:desc'] : ['amountConfirmed:desc'];
|
return this.showUnconfirmedKredits ? ['amountTotal:desc'] : ['amountConfirmed:desc'];
|
||||||
}),
|
}),
|
||||||
kreditsToplist: sort('kreditsByContributor', 'kreditsToplistSorting'),
|
kreditsToplist: computed('kreditsByContributor', function(){
|
||||||
|
return this.kreditsByContributor.filter(c => c.amountTotal > 0);
|
||||||
|
}),
|
||||||
|
kreditsToplistSorted: sort('kreditsToplist', 'kreditsToplistSorting'),
|
||||||
|
|
||||||
showUnconfirmedKredits: true,
|
showUnconfirmedKredits: true,
|
||||||
hideUnconfirmedKredits: not('showUnconfirmedKredits'),
|
hideUnconfirmedKredits: not('showUnconfirmedKredits'),
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { helper } from '@ember/component/helper';
|
||||||
|
|
||||||
|
export default helper(function fmtAmountSatsTitle(params) {
|
||||||
|
const amountSats = params[0];
|
||||||
|
|
||||||
|
if (typeof amountSats === 'number' && amountSats > 0) {
|
||||||
|
return `${amountSats} sats`;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -2,10 +2,14 @@ import { helper } from '@ember/component/helper';
|
|||||||
|
|
||||||
export default helper(function fmtFiatCurrency(params) {
|
export default helper(function fmtFiatCurrency(params) {
|
||||||
const lang = navigator.language || navigator.userLanguage;
|
const lang = navigator.language || navigator.userLanguage;
|
||||||
|
const value = params[0];
|
||||||
|
const currency = params[1] || 'EUR';
|
||||||
|
|
||||||
|
if (currency === 'BTC') return `BTC ${value}`;
|
||||||
|
|
||||||
const formatter = new Intl.NumberFormat(lang, {
|
const formatter = new Intl.NumberFormat(lang, {
|
||||||
style: 'currency',
|
style: 'currency', currency, currencyDisplay: 'code'
|
||||||
currency: params[1] || 'EUR',
|
|
||||||
currencyDisplay: 'code'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return formatter.format(params[0]);
|
return formatter.format(params[0]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export default class CommunityFundsService extends Service {
|
|||||||
|
|
||||||
// Format and round the approximate USD value
|
// Format and round the approximate USD value
|
||||||
const lang = navigator.language || navigator.userLanguage;
|
const lang = navigator.language || navigator.userLanguage;
|
||||||
const balanceUSD = (res.confirmed_balance / 100000000) * this.exchangeRates.btcusd;
|
const balanceUSD = (res.confirmed_balance / 100000000) * this.exchangeRates.USD;
|
||||||
res.balanceUSD = Math.round(balanceUSD).toLocaleString(lang);
|
res.balanceUSD = Math.round(balanceUSD).toLocaleString(lang);
|
||||||
|
|
||||||
this.balances.pushObject({
|
this.balances.pushObject({
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import config from 'kredits-web/config/environment';
|
|||||||
|
|
||||||
// Need to go through proxy for CORS headers
|
// Need to go through proxy for CORS headers
|
||||||
const bitstampBaseUrl = `${config.corsProxy}https://www.bitstamp.net/api/v2`;
|
const bitstampBaseUrl = `${config.corsProxy}https://www.bitstamp.net/api/v2`;
|
||||||
|
const kosmosBtcPriceBaseUrl = "https://storage.kosmos.org/kosmos/public/btc-price";
|
||||||
|
|
||||||
async function fetchFromBitstamp(currencyPair) {
|
async function fetchFromBitstamp(currencyPair) {
|
||||||
try {
|
try {
|
||||||
@@ -16,11 +17,12 @@ async function fetchFromBitstamp(currencyPair) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class ExchangeRatesService extends Service {
|
export default class ExchangeRatesService extends Service {
|
||||||
@tracked btceur = 0;
|
@tracked EUR = 0;
|
||||||
@tracked btcusd = 0;
|
@tracked USD = 0;
|
||||||
|
@tracked historic = {};
|
||||||
|
|
||||||
get exchangeRatesLoaded () {
|
get exchangeRatesLoaded () {
|
||||||
return (this.btceur !== 0) && (this.btcusd !== 0);
|
return (this.EUR !== 0) && (this.USD !== 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchRates (source='bitstamp') {
|
async fetchRates (source='bitstamp') {
|
||||||
@@ -28,8 +30,24 @@ export default class ExchangeRatesService extends Service {
|
|||||||
|
|
||||||
switch(source) {
|
switch(source) {
|
||||||
case 'bitstamp':
|
case 'bitstamp':
|
||||||
this.btceur = await fetchFromBitstamp('btceur');
|
this.EUR = await fetchFromBitstamp('btceur');
|
||||||
this.btcusd = await fetchFromBitstamp('btcusd');
|
this.USD = await fetchFromBitstamp('btcusd');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchHistoricRates (isoDate) {
|
||||||
|
if (typeof this.historic[isoDate] === "object") {
|
||||||
|
return this.historic[isoDate];
|
||||||
|
} else {
|
||||||
|
const url = `${kosmosBtcPriceBaseUrl}/${isoDate}`;
|
||||||
|
try {
|
||||||
|
const rates = await fetch(url).then(res => res.json());
|
||||||
|
this.historic[isoDate] = rates;
|
||||||
|
return rates;
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
Promise.reject(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ a {
|
|||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
|
|||||||
+10
-18
@@ -1,22 +1,6 @@
|
|||||||
<main id="budget">
|
<main id="budget">
|
||||||
|
|
||||||
<div id="aside">
|
<div id="aside">
|
||||||
<!-- <section id="main-nav"> -->
|
|
||||||
<!-- <header> -->
|
|
||||||
<!-- <h2>Budget</h2> -->
|
|
||||||
<!-- </header> -->
|
|
||||||
<!-- <div class="content"> -->
|
|
||||||
<!-- <ul> -->
|
|
||||||
<!-- <li> -->
|
|
||||||
<!-- <LinkTo @route="budget.expenses">Expenses</LinkTo> -->
|
|
||||||
<!-- </li> -->
|
|
||||||
<!-- <li> -->
|
|
||||||
<!-- <a href="#">Rewards</a> -->
|
|
||||||
<!-- </li> -->
|
|
||||||
<!-- </ul> -->
|
|
||||||
<!-- </div> -->
|
|
||||||
<!-- </section> -->
|
|
||||||
|
|
||||||
<section id="funds">
|
<section id="funds">
|
||||||
<header>
|
<header>
|
||||||
<h2>Community funds</h2>
|
<h2>Community funds</h2>
|
||||||
@@ -33,7 +17,11 @@
|
|||||||
<header class="with-nav">
|
<header class="with-nav">
|
||||||
<h2>Proposed Reimbursements</h2>
|
<h2>Proposed Reimbursements</h2>
|
||||||
<nav>
|
<nav>
|
||||||
<LinkTo @route="reimbursements.new" @title="Submit a reimbursement" class="button small green">add</LinkTo>
|
<button type="button" class="button small green"
|
||||||
|
title="Submit a reimbursement"
|
||||||
|
{{on "click" this.addReimbursement}}>
|
||||||
|
add
|
||||||
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@@ -47,7 +35,11 @@
|
|||||||
<header class="with-nav">
|
<header class="with-nav">
|
||||||
<h2>Confirmed Reimbursements</h2>
|
<h2>Confirmed Reimbursements</h2>
|
||||||
<nav>
|
<nav>
|
||||||
<LinkTo @route="reimbursements.new" @title="Submit a reimbursement" class="button small green">add</LinkTo>
|
<button type="button" class="button small green"
|
||||||
|
title="Submit a reimbursement"
|
||||||
|
{{on "click" this.addReimbursement}}>
|
||||||
|
add
|
||||||
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
</header>
|
</header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<ContributorList @contributorList={{this.kreditsToplist}}
|
<ContributorList @contributorList={{this.kreditsToplistSorted}}
|
||||||
@showUnconfirmedKredits={{this.showUnconfirmedKredits}}
|
@showUnconfirmedKredits={{this.showUnconfirmedKredits}}
|
||||||
@selectedContributorId={{this.selectedContributorId}}
|
@selectedContributorId={{this.selectedContributorId}}
|
||||||
@loading={{this.kredits.syncContributors.isRunning}} />
|
@loading={{this.kredits.syncContributors.isRunning}} />
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export function floatToBtc(number) {
|
||||||
|
return Number(number.toFixed(8))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function btcToSats(btc) {
|
||||||
|
return Math.round(btc * 100_000_000);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function satsToBtc(sats) {
|
||||||
|
return Math.round((sats / 100_000_000) * 100_000_000) / 100_000_000;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export default function(value) {
|
||||||
|
const today = new Date().toISOString().split('T')[0];
|
||||||
|
return value === today;
|
||||||
|
}
|
||||||
@@ -76,10 +76,10 @@ module.exports = function(environment) {
|
|||||||
ENV.githubSignupUrl = 'http://localhost:8888/kredits/signup/github';
|
ENV.githubSignupUrl = 'http://localhost:8888/kredits/signup/github';
|
||||||
|
|
||||||
ENV.ipfs = {
|
ENV.ipfs = {
|
||||||
host: 'localhost',
|
host: '10.1.1.198',
|
||||||
port: '5001',
|
port: '5001',
|
||||||
protocol: 'http',
|
protocol: 'http',
|
||||||
gatewayUrl: 'http://localhost:8080/ipfs'
|
gatewayUrl: 'http://10.1.1.198:9090/ipfs'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Uncomment if you want to use local akkounts
|
// Uncomment if you want to use local akkounts
|
||||||
|
|||||||
Generated
+29
-19
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "kredits-web",
|
"name": "kredits-web",
|
||||||
"version": "2.2.0",
|
"version": "2.3.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "kredits-web",
|
"name": "kredits-web",
|
||||||
"version": "2.2.0",
|
"version": "2.3.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/eslint-parser": "^7.19.1",
|
"@babel/eslint-parser": "^7.19.1",
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"@ember/optional-features": "^1.3.0",
|
"@ember/optional-features": "^1.3.0",
|
||||||
"@glimmer/component": "^1.0.0",
|
"@glimmer/component": "^1.0.0",
|
||||||
"@glimmer/tracking": "^1.0.0",
|
"@glimmer/tracking": "^1.0.0",
|
||||||
"@kredits/contracts": "^7.3.0",
|
"@kredits/contracts": "^7.5.0",
|
||||||
"babel-preset-es2015": "^6.22.0",
|
"babel-preset-es2015": "^6.22.0",
|
||||||
"broccoli-asset-rev": "^3.0.0",
|
"broccoli-asset-rev": "^3.0.0",
|
||||||
"ember-auto-import": "^1.12.1",
|
"ember-auto-import": "^1.12.1",
|
||||||
@@ -3062,17 +3062,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@kosmos/schemas": {
|
"node_modules/@kosmos/schemas": {
|
||||||
"version": "3.1.0",
|
"version": "3.2.0",
|
||||||
"dev": true,
|
"resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.2.0.tgz",
|
||||||
"license": "MIT"
|
"integrity": "sha512-GyWXmWcATcakmEdPOpafdckBgWFqcpSh+tB8nm11VGgtgA94pfoFhKZ3t88WELItKfuP/GFHgMiZmdMB3bSkdQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@kredits/contracts": {
|
"node_modules/@kredits/contracts": {
|
||||||
"version": "7.3.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@kredits/contracts/-/contracts-7.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@kredits/contracts/-/contracts-7.5.0.tgz",
|
||||||
"integrity": "sha512-7Bo2LFEqGIK39G54AStas1RWouBOp+r7Vcv2vP1uLbY01Usea8SHvd2OjLP6nFgsQa0n/rto9oremHv5IAylrQ==",
|
"integrity": "sha512-4Jw6lXn9DfZiTnMtWHwGLS5zhxEJZ2ANfAgcr7tZxqRl7Y0ijpoWvPCA+LkSGqRgKspyiw9+7vSVTtyvAyQbPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kosmos/schemas": "^3.1.0",
|
"@kosmos/schemas": "^3.2.0",
|
||||||
"ethers": "^5.4.7",
|
"ethers": "^5.4.7",
|
||||||
"ipfs-http-client": "^56.0.3",
|
"ipfs-http-client": "^56.0.3",
|
||||||
"multihashes": "^4.0.3",
|
"multihashes": "^4.0.3",
|
||||||
@@ -6816,7 +6817,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001332",
|
"version": "1.0.30001599",
|
||||||
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz",
|
||||||
|
"integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -6826,9 +6829,12 @@
|
|||||||
{
|
{
|
||||||
"type": "tidelift",
|
"type": "tidelift",
|
||||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"license": "CC-BY-4.0"
|
|
||||||
},
|
},
|
||||||
"node_modules/capture-exit": {
|
"node_modules/capture-exit": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@@ -26062,16 +26068,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@kosmos/schemas": {
|
"@kosmos/schemas": {
|
||||||
"version": "3.1.0",
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-GyWXmWcATcakmEdPOpafdckBgWFqcpSh+tB8nm11VGgtgA94pfoFhKZ3t88WELItKfuP/GFHgMiZmdMB3bSkdQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@kredits/contracts": {
|
"@kredits/contracts": {
|
||||||
"version": "7.3.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@kredits/contracts/-/contracts-7.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@kredits/contracts/-/contracts-7.5.0.tgz",
|
||||||
"integrity": "sha512-7Bo2LFEqGIK39G54AStas1RWouBOp+r7Vcv2vP1uLbY01Usea8SHvd2OjLP6nFgsQa0n/rto9oremHv5IAylrQ==",
|
"integrity": "sha512-4Jw6lXn9DfZiTnMtWHwGLS5zhxEJZ2ANfAgcr7tZxqRl7Y0ijpoWvPCA+LkSGqRgKspyiw9+7vSVTtyvAyQbPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@kosmos/schemas": "^3.1.0",
|
"@kosmos/schemas": "^3.2.0",
|
||||||
"ethers": "^5.4.7",
|
"ethers": "^5.4.7",
|
||||||
"ipfs-http-client": "^56.0.3",
|
"ipfs-http-client": "^56.0.3",
|
||||||
"multihashes": "^4.0.3",
|
"multihashes": "^4.0.3",
|
||||||
@@ -29050,7 +29058,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001332",
|
"version": "1.0.30001599",
|
||||||
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz",
|
||||||
|
"integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"capture-exit": {
|
"capture-exit": {
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "kredits-web",
|
"name": "kredits-web",
|
||||||
"version": "2.2.0",
|
"version": "2.3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Contribution dashboard of the Kosmos project",
|
"description": "Contribution dashboard of the Kosmos project",
|
||||||
"repository": "https://github.com/67P/kredits-web",
|
"repository": "https://github.com/67P/kredits-web",
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"@ember/optional-features": "^1.3.0",
|
"@ember/optional-features": "^1.3.0",
|
||||||
"@glimmer/component": "^1.0.0",
|
"@glimmer/component": "^1.0.0",
|
||||||
"@glimmer/tracking": "^1.0.0",
|
"@glimmer/tracking": "^1.0.0",
|
||||||
"@kredits/contracts": "^7.3.0",
|
"@kredits/contracts": "^7.5.0",
|
||||||
"babel-preset-es2015": "^6.22.0",
|
"babel-preset-es2015": "^6.22.0",
|
||||||
"broccoli-asset-rev": "^3.0.0",
|
"broccoli-asset-rev": "^3.0.0",
|
||||||
"ember-auto-import": "^1.12.1",
|
"ember-auto-import": "^1.12.1",
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+145
-103
File diff suppressed because one or more lines are too long
+9767
-5870
File diff suppressed because one or more lines are too long
+4
-4
@@ -8,10 +8,10 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
|
|
||||||
|
|
||||||
<meta name="kredits-web/config/environment" content="%7B%22modulePrefix%22%3A%22kredits-web%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22kredits-web%22%2C%22version%22%3A%222.2.0%2B0777c213%22%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frsk-testnet.kosmos.org%22%2C%22web3ChainId%22%3A31%2C%22web3NetworkName%22%3A%22RSK%20Testnet%22%2C%22githubConnectUrl%22%3A%22https%3A%2F%2Fhal8000.kosmos.chat%2Fkredits%2Fsignup%2Fconnect%2Fgithub%22%2C%22githubSignupUrl%22%3A%22https%3A%2F%2Fhal8000.kosmos.chat%2Fkredits%2Fsignup%2Fgithub%22%2C%22ipfs%22%3A%7B%22host%22%3A%22ipfs.kosmos.org%22%2C%22port%22%3A%225444%22%2C%22protocol%22%3A%22https%22%2C%22gatewayUrl%22%3A%22https%3A%2F%2Fipfs.kosmos.org%2Fipfs%22%7D%2C%22tokens%22%3A%7B%22BTC%22%3A%220x2260fac5e5542a773aa44fbcfedf7c193bc2c599%22%7D%2C%22communityFundsAPI%22%3A%7B%22balances%22%3A%7B%22onchain%22%3A%7B%22icon%22%3A%22icon-btc.png%22%2C%22symbol%22%3A%22BTC%22%2C%22description%22%3A%22BTC%20on%20chain%22%2C%22url%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fbtcpay%2Fonchain_btc_balance%22%7D%2C%22lightning%22%3A%7B%22icon%22%3A%22icon-btc-lightning.png%22%2C%22symbol%22%3A%22BTC%22%2C%22description%22%3A%22BTC%20on%20Lightning%20Network%22%2C%22url%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fbtcpay%2Flightning_btc_balance%22%7D%7D%7D%2C%22corsProxy%22%3A%22https%3A%2F%2Fcors.5apps.com%2F%3Furi%3D%22%2C%22exportApplicationGlobal%22%3Afalse%7D" />
|
<meta name="kredits-web/config/environment" content="%7B%22modulePrefix%22%3A%22kredits-web%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22kredits-web%22%2C%22version%22%3A%222.3.0%2B66e1adc7%22%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frsk-testnet.kosmos.org%22%2C%22web3ChainId%22%3A31%2C%22web3NetworkName%22%3A%22RSK%20Testnet%22%2C%22githubConnectUrl%22%3A%22https%3A%2F%2Fhal8000.kosmos.chat%2Fkredits%2Fsignup%2Fconnect%2Fgithub%22%2C%22githubSignupUrl%22%3A%22https%3A%2F%2Fhal8000.kosmos.chat%2Fkredits%2Fsignup%2Fgithub%22%2C%22ipfs%22%3A%7B%22host%22%3A%22ipfs.kosmos.org%22%2C%22port%22%3A%225444%22%2C%22protocol%22%3A%22https%22%2C%22gatewayUrl%22%3A%22https%3A%2F%2Fipfs.kosmos.org%2Fipfs%22%7D%2C%22tokens%22%3A%7B%22BTC%22%3A%220x2260fac5e5542a773aa44fbcfedf7c193bc2c599%22%7D%2C%22communityFundsAPI%22%3A%7B%22balances%22%3A%7B%22onchain%22%3A%7B%22icon%22%3A%22icon-btc.png%22%2C%22symbol%22%3A%22BTC%22%2C%22description%22%3A%22BTC%20on%20chain%22%2C%22url%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fbtcpay%2Fonchain_btc_balance%22%7D%2C%22lightning%22%3A%7B%22icon%22%3A%22icon-btc-lightning.png%22%2C%22symbol%22%3A%22BTC%22%2C%22description%22%3A%22BTC%20on%20Lightning%20Network%22%2C%22url%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fbtcpay%2Flightning_btc_balance%22%7D%7D%7D%2C%22corsProxy%22%3A%22https%3A%2F%2Fcors.5apps.com%2F%3Furi%3D%22%2C%22exportApplicationGlobal%22%3Afalse%7D" />
|
||||||
|
|
||||||
<link integrity="" rel="stylesheet" href="/assets/vendor-ca96b2e19fc9f356e3dbad90c9f3f323.css">
|
<link integrity="" rel="stylesheet" href="/assets/vendor-ca96b2e19fc9f356e3dbad90c9f3f323.css">
|
||||||
<link integrity="" rel="stylesheet" href="/assets/kredits-web-1ce689f6aada92a7d79a1947300931cf.css">
|
<link integrity="" rel="stylesheet" href="/assets/kredits-web-273a3e2096140c611fc6c314653c5122.css">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
||||||
<script src="/assets/vendor-4d87b3e0995c5bb18e46836a089900a4.js" integrity="sha256-5WmWY05Kd+n98Sw0GwuaWodmDVBZ2yVGGtC/2owVfQE= sha512-tiGPA5zvfhnSC9LPTmpvXJmOu30yhsdPqSiZJMPGmE/ez/xJLMaM29vjs4Cs74cDf6fX4uYSGRIu1KfOyGpJYA==" ></script>
|
<script src="/assets/vendor-fe68375ecc84328a68fb6e2dc6c2ffd0.js" integrity="sha256-R9zoGCHpj2nktDrCaA5bsKl5UIzBz3pi8OxcjZUcUXg= sha512-KgK1Q5VBzvVFUa5DEMaexc2VLg337DOyWnvp/3HvNzcjSFwCRG/dCn3x6EMuxULl1lY/rCVJ2ZgZN0K5NwZDkA==" ></script>
|
||||||
<script src="/assets/kredits-web-dab5f8c2df81891a0eb6d4d2bbf24a27.js" integrity="sha256-5XKNFa8JPKQWJztf69+Qhuszl/RV5uIYlg8/aPYp0ZY= sha512-0NYDa2a5cJBY6LxPDrEtaqD9YpuDEH7oR17jLvoMzWHBx4WIwerNRc9uadXwg+7UMnua3ysxt8M6i9uaJKRhTA==" ></script>
|
<script src="/assets/kredits-web-ff25bacd2246c053f7629aa0ac30852d.js" integrity="sha256-ZMtyPPTI2FdCZOW2AhZKoSc3V1F8p7eb5paSnXfUUVE= sha512-lbKnfjHisBjgh4AVaSvDb+7zrtfrMd9PhVj3kUW+UREmA9kl3qLaWECHtIfWz4VNPfzQV9xg5P9hQFmcrPe+ig==" ></script>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -1,13 +1,58 @@
|
|||||||
import { module, test } from 'qunit';
|
import { module, test } from 'qunit';
|
||||||
import { setupRenderingTest } from 'ember-qunit';
|
import { setupRenderingTest } from 'ember-qunit';
|
||||||
import { render } from '@ember/test-helpers';
|
import { click, fillIn, render } from '@ember/test-helpers';
|
||||||
import { hbs } from 'ember-cli-htmlbars';
|
import { hbs } from 'ember-cli-htmlbars';
|
||||||
|
import contributors from '../../../fixtures/contributors';
|
||||||
|
|
||||||
module('Integration | Component | add-reimbursement', function(hooks) {
|
module('Integration | Component | add-reimbursement', function(hooks) {
|
||||||
setupRenderingTest(hooks);
|
setupRenderingTest(hooks);
|
||||||
|
|
||||||
test('it works', async function(assert) {
|
hooks.beforeEach(function() {
|
||||||
|
let kredits = this.owner.lookup('service:kredits');
|
||||||
|
kredits.set('contributors', contributors);
|
||||||
|
kredits.set('currentUser', contributors.findBy('id', 3));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Contributor select menu', async function(assert) {
|
||||||
await render(hbs`<AddReimbursement />`);
|
await render(hbs`<AddReimbursement />`);
|
||||||
assert.ok(true);
|
|
||||||
|
assert.equal(this.element.querySelectorAll('select#contributor option').length, contributors.length,
|
||||||
|
'contains correct amount of items');
|
||||||
|
|
||||||
|
assert.equal(this.element.querySelector('select#contributor option:checked').value, "3",
|
||||||
|
'preselects the connected contributor account');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Adding expense items', async function(assert) {
|
||||||
|
await render(hbs`<AddReimbursement />`);
|
||||||
|
|
||||||
|
assert.dom(this.element).includesText('New expense item');
|
||||||
|
|
||||||
|
await fillIn('form input[name="expense-amount"]', '49');
|
||||||
|
await fillIn('form input[name="expense-title"]', 'Domain kosmos.org (yearly fee)');
|
||||||
|
await click('form#add-expense-item input[type="submit"]');
|
||||||
|
|
||||||
|
assert.equal(this.element.querySelector('input[name="total-eur"]').value, '49',
|
||||||
|
'updates the total EUR amount');
|
||||||
|
assert.equal(this.element.querySelector('input[name="total-usd"]').value, '0',
|
||||||
|
'does not update the total USD amount');
|
||||||
|
assert.equal(this.element.querySelector('input[name="total-btc"]').value, '0.00534493',
|
||||||
|
'updates the total BTC amount');
|
||||||
|
|
||||||
|
assert.dom(this.element).doesNotIncludeText('New expense item');
|
||||||
|
|
||||||
|
await click('button#add-another-item');
|
||||||
|
|
||||||
|
await fillIn('form input[name="expense-amount"]', '29');
|
||||||
|
await fillIn('select[name="expense-currency"]', 'USD');
|
||||||
|
await fillIn('form input[name="expense-title"]', 'Domain kosmos.social (yearly fee)');
|
||||||
|
await click('form#add-expense-item input[type="submit"]');
|
||||||
|
|
||||||
|
assert.equal(this.element.querySelector('input[name="total-usd"]').value, '29',
|
||||||
|
'updates the total USD amount');
|
||||||
|
assert.equal(this.element.querySelector('input[name="total-eur"]').value, '49',
|
||||||
|
'does not update the total EUR amount');
|
||||||
|
assert.equal(this.element.querySelector('input[name="total-btc"]').value, '0.00804268',
|
||||||
|
'updates the total BTC amount');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,5 +18,12 @@ module('Integration | Helper | fmt-fiat-currency', function(hooks) {
|
|||||||
await render(hbs`{{fmt-fiat-currency this.amount 'USD'}}`);
|
await render(hbs`{{fmt-fiat-currency this.amount 'USD'}}`);
|
||||||
assert.ok(this.element.textContent.trim().match(/USD/),
|
assert.ok(this.element.textContent.trim().match(/USD/),
|
||||||
'using defined currency when given');
|
'using defined currency when given');
|
||||||
|
|
||||||
|
await render(hbs`{{fmt-fiat-currency 0.00123 'BTC'}}`);
|
||||||
|
assert.ok(this.element.textContent.trim().match(/0.00123/),
|
||||||
|
'allows more decimals');
|
||||||
|
assert.ok(this.element.textContent.trim().match(/BTC/),
|
||||||
|
'using defined currency when given');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -39,12 +39,4 @@ module('Unit | Component | add-reimbursement', function(hooks) {
|
|||||||
assert.equal(component.totalEUR, '71');
|
assert.equal(component.totalEUR, '71');
|
||||||
assert.equal(component.totalUSD, '59');
|
assert.equal(component.totalUSD, '59');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('#updateTotalAmountFromFiat', async function(assert) {
|
|
||||||
let component = createComponent('component:add-reimbursement');
|
|
||||||
component.expenses = expenses;
|
|
||||||
await component.exchangeRates.fetchRates();
|
|
||||||
component.updateTotalAmountFromFiat();
|
|
||||||
assert.equal(component.total, '0.01323322', 'converts EUR and USD totals to BTC and rounds to 8 decimals');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,29 +1,31 @@
|
|||||||
// import { isEmpty, isPresent } from '@ember/utils';
|
import { isEmpty } from '@ember/utils';
|
||||||
// import { module, test } from 'qunit';
|
import { module, test } from 'qunit';
|
||||||
// import { setupTest } from 'ember-qunit';
|
import { setupTest } from 'ember-qunit';
|
||||||
// import Contributor from 'kredits-web/models/contributor';
|
import Contributor from 'kredits-web/models/contributor';
|
||||||
//
|
|
||||||
// module('Unit | Controller | index', function(hooks) {
|
module('Unit | Controller | Dashboard', function(hooks) {
|
||||||
// setupTest(hooks);
|
setupTest(hooks);
|
||||||
//
|
|
||||||
// let addFixtures = function(controller) {
|
let addFixtures = function(controller) {
|
||||||
// [
|
[
|
||||||
// { github_username: "neo", github_uid: "318", totalKreditsEarned: 10000 },
|
{ github_username: "neo", github_uid: "318", totalKreditsEarned: 10000 },
|
||||||
// { github_username: "morpheus", github_uid: "843", totalKreditsEarned: 15000 },
|
{ github_username: "morpheus", github_uid: "843", totalKreditsEarned: 15000 },
|
||||||
// { github_username: "trinity", github_uid: "123", totalKreditsEarned: 5000 },
|
{ github_username: "trinity", github_uid: "123", totalKreditsEarned: 5000 },
|
||||||
// { github_username: "mouse", github_uid: "696", totalKreditsEarned: 0 }
|
{ github_username: "mouse", github_uid: "696", totalKreditsEarned: 0 }
|
||||||
// ].forEach(fixture => {
|
].forEach(fixture => {
|
||||||
// controller.get('kredits.contributors').push(Contributor.create(fixture));
|
controller.get('kredits.contributors').push(Contributor.create(fixture));
|
||||||
// });
|
});
|
||||||
// };
|
};
|
||||||
//
|
|
||||||
// test('doesn\'t contain people with 0 balance', function(assert) {
|
test('kreditsToplistSorted()', function(assert) {
|
||||||
// let controller = this.owner.lookup('controller:index');
|
const controller = this.owner.lookup('controller:dashboard');
|
||||||
// addFixtures(controller);
|
addFixtures(controller);
|
||||||
//
|
|
||||||
// let contributorsSorted = controller.get('contributorsSorted');
|
const kreditsToplistSorted = controller.get('kreditsToplistSorted');
|
||||||
//
|
|
||||||
// assert.ok(isPresent(contributorsSorted.findBy('github_username', 'neo')));
|
assert.equal(kreditsToplistSorted.length, 3,
|
||||||
// assert.ok(isEmpty(contributorsSorted.findBy('github_username', 'mouse')));
|
'contains all contributors with kredits');
|
||||||
// });
|
assert.ok(isEmpty(kreditsToplistSorted.findBy('github_username', 'mouse')),
|
||||||
// });
|
'does not contain contributors with 0 kredits');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ module('Unit | Service | exchange-rates', function(hooks) {
|
|||||||
test('#fetchRates', async function(assert) {
|
test('#fetchRates', async function(assert) {
|
||||||
let service = this.owner.lookup('service:exchange-rates');
|
let service = this.owner.lookup('service:exchange-rates');
|
||||||
await service.fetchRates();
|
await service.fetchRates();
|
||||||
assert.equal(service.btceur, 9167.57, 'fetches BTCEUR from Bitstamp');
|
assert.equal(service.EUR, 9167.57, 'fetches BTCEUR from Bitstamp');
|
||||||
assert.equal(service.btcusd, 10749.70, 'fetches BTCUSD from Bitstamp');
|
assert.equal(service.USD, 10749.70, 'fetches BTCUSD from Bitstamp');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { floatToBtc, btcToSats, satsToBtc } from 'kredits-web/utils/btc-conversions';
|
||||||
|
import { module, test } from 'qunit';
|
||||||
|
|
||||||
|
module('Unit | Utility | btc-conversions', function() {
|
||||||
|
test('floatToBtc', function(assert) {
|
||||||
|
assert.equal(floatToBtc(0.001429007), 0.00142901);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('btcToSats', function(assert) {
|
||||||
|
assert.equal(btcToSats(0.001429007), 142901);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('satsToBtc', function(assert) {
|
||||||
|
assert.equal(satsToBtc(142901), 0.00142901);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user