Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
6a72a5b418
|
|||
|
d90ddd464a
|
|||
|
2626543f3e
|
|||
| 088db24534 | |||
| f7b7daa024 | |||
| bb11e2267b | |||
| 7cd023a21b | |||
|
1095bf0218
|
|||
|
138cec0389
|
|||
|
a93be41e08
|
|||
|
89f6fa0b5c
|
|||
|
e2a80eafd1
|
|||
|
662e76979b
|
|||
|
6c7de97e38
|
|||
|
fe27b010da
|
|||
|
ff716c68ea
|
|||
|
84dded2f10
|
|||
|
f86190030f
|
@@ -48,6 +48,12 @@ module.exports = {
|
||||
"no-action"
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "app/components/expense-list/template",
|
||||
"only": [
|
||||
"no-invalid-role"
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "app/components/topbar-account-panel/template",
|
||||
"only": [
|
||||
|
||||
@@ -44,26 +44,10 @@
|
||||
|
||||
<h3>Expense items</h3>
|
||||
{{#if this.expenses}}
|
||||
<ul class="expense-list">
|
||||
{{#each this.expenses as |expense|}}
|
||||
<li>
|
||||
<div class="description" rowspan="2">
|
||||
<h4>
|
||||
<span class="date">{{expense.date}}:</span>
|
||||
<span class="title">{{expense.title}}</span>
|
||||
</h4>
|
||||
<p class="description">{{expense.description}}</p>
|
||||
</div>
|
||||
<div class="amount">
|
||||
{{fmt-fiat-currency expense.amount expense.currency}}
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button {{on "click" (fn this.removeExpenseItem expense)}}
|
||||
class="danger small" type="button">delete</button>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<ExpenseList @expenses={{this.expenses}}
|
||||
@removeExpenseItem={{this.removeExpenseItem}}
|
||||
@deletable={{true}} />
|
||||
|
||||
<p class="actions">
|
||||
<button {{on "click" this.showExpenseForm}}
|
||||
class="green small" type="button">+ Add another item</button>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { inject as service } from '@ember/service';
|
||||
import moment from 'moment';
|
||||
|
||||
export default class ConfirmedInComponent extends Component {
|
||||
@service kredits;
|
||||
|
||||
get confirmedInBlocks () {
|
||||
return this.args.confirmedAtBlock - this.kredits.currentBlock;
|
||||
}
|
||||
|
||||
get confirmedInSeconds () {
|
||||
// A new block is mined every 30 seconds on average
|
||||
return this.confirmedInBlocks * 30;
|
||||
}
|
||||
|
||||
get confirmedInHumanTime () {
|
||||
return moment.duration(this.confirmedInSeconds, "seconds").humanize();
|
||||
}
|
||||
|
||||
get isConfirmed () {
|
||||
return this.confirmedInBlocks <= 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{{#unless this.isConfirmed}}
|
||||
Confirming in <strong>{{this.confirmedInBlocks}}</strong> blocks (~ {{this.confirmedInHumanTime}})
|
||||
{{/unless}}
|
||||
@@ -0,0 +1,9 @@
|
||||
import Component from '@glimmer/component';
|
||||
|
||||
export default class ExpenseListComponent extends Component {
|
||||
|
||||
get showDeleteButton () {
|
||||
return !!this.args.deletable;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<ul class="expense-list">
|
||||
{{#each @expenses as |expense|}}
|
||||
<li class="expense-item">
|
||||
<h4>
|
||||
<span class="date">{{fmt-date-localized expense.date}}:</span>
|
||||
<span class="title">{{expense.title}}</span>
|
||||
</h4>
|
||||
<div class="amount">
|
||||
{{fmt-fiat-currency expense.amount expense.currency}}
|
||||
</div>
|
||||
<p class="description">
|
||||
{{expense.description}}
|
||||
</p>
|
||||
<p class="tags">
|
||||
{{#each expense.tags as |tag|}}
|
||||
<button type="button" class="small yellow" role="none">
|
||||
<IconTag />{{tag}}
|
||||
</button>
|
||||
{{/each}}
|
||||
</p>
|
||||
{{#if this.showDeleteButton}}
|
||||
<div class="actions">
|
||||
<button {{on "click" (fn @removeExpenseItem expense)}}
|
||||
class="danger small" type="button">delete</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
@@ -3,44 +3,36 @@
|
||||
<li data-reimbursement-id={{reimbursement.id}}
|
||||
class="{{item-status reimbursement}}">
|
||||
<p class="meta">
|
||||
<span class="title">
|
||||
Expenses covered by {{reimbursement.contributor.name}}
|
||||
</span>
|
||||
<span class="recipient">
|
||||
<UserAvatar @contributor={{reimbursement.contributor}} />
|
||||
</span>
|
||||
<span class="title">
|
||||
Expenses covered by {{reimbursement.contributor.name}}
|
||||
</span>
|
||||
</p>
|
||||
<p class="token-amount">
|
||||
<span class="amount">
|
||||
{{sats-to-btc reimbursement.amount}}</span> <span class="symbol">BTC</span>
|
||||
</p>
|
||||
<ul class="expense-list">
|
||||
{{#each reimbursement.expenses as |expense|}}
|
||||
<li>
|
||||
<div class="description" rowspan="2">
|
||||
<h4>
|
||||
<span class="date">{{expense.date}}:</span>
|
||||
<span class="title">{{expense.title}}</span>
|
||||
</h4>
|
||||
<p class="description">{{expense.description}}</p>
|
||||
</div>
|
||||
<div class="amount">
|
||||
{{fmt-fiat-currency expense.amount expense.currency}}
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{#if this.kredits.currentUserIsCore}}
|
||||
<p>
|
||||
|
||||
<ExpenseList @expenses={{reimbursement.expenses}} />
|
||||
|
||||
<div class="meta">
|
||||
<p class="confirmation-eta">
|
||||
<ConfirmedIn @confirmedAtBlock={{reimbursement.confirmedAt}} />
|
||||
</p>
|
||||
<p class="actions">
|
||||
<a href="{{this.ipfsGatewayUrl}}/{{reimbursement.ipfsHash}}"
|
||||
class="button small" target="_blank" rel="noopener noreferrer">
|
||||
Inspect IPFS data
|
||||
</a>
|
||||
<button {{on "click" (fn this.veto reimbursement.id)}}
|
||||
disabled={{reimbursement.vetoed}}
|
||||
class="button small danger" type="button">veto</button>
|
||||
{{#if this.kredits.currentUserIsCore}}
|
||||
<button {{on "click" (fn this.veto reimbursement.id)}}
|
||||
disabled={{reimbursement.vetoed}}
|
||||
class="button small danger" type="button">veto</button>
|
||||
{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
@@ -1,6 +1,6 @@
|
||||
import Controller from '@ember/controller';
|
||||
import { computed } from '@ember/object';
|
||||
import { alias, not, sort } from '@ember/object/computed';
|
||||
import { alias, gt, not, sort } from '@ember/object/computed';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default Controller.extend({
|
||||
@@ -33,6 +33,8 @@ export default Controller.extend({
|
||||
showQuickFilterUnconfirmed: false,
|
||||
showQuickFilterConfirmed: false,
|
||||
|
||||
showFullContributionSync: gt('kredits.missingHistoricContributionsCount', 0),
|
||||
|
||||
showIntroText: computed('kredits.{hasAccounts,currentUser}', function(){
|
||||
return (!this.kredits.hasAccounts || !this.kredits.currentUser);
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { helper } from '@ember/component/helper';
|
||||
import getLocale from 'kredits-web/utils/get-locale';
|
||||
|
||||
export default helper(function(dateStr) {
|
||||
const date = new Date(dateStr);
|
||||
const locale = getLocale();
|
||||
return new Intl.DateTimeFormat(locale).format(date);
|
||||
});
|
||||
@@ -11,8 +11,11 @@ export default class DashboardRoute extends Route {
|
||||
schedule('afterRender', this.kredits.syncContributions,
|
||||
this.kredits.syncContributions.perform);
|
||||
}
|
||||
schedule('afterRender', this.kredits.fetchMissingContributions,
|
||||
this.kredits.fetchMissingContributions.perform);
|
||||
// TODO fetch automatically under a certain threshold
|
||||
// The browser might delete cached data and we don't need manual re-syncs
|
||||
// depending on how little is missing
|
||||
// schedule('afterRender', this.kredits.fetchMissingContributions,
|
||||
// this.kredits.fetchMissingContributions.perform);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+20
-6
@@ -48,6 +48,8 @@ export default Service.extend({
|
||||
contributionsNeedSync: false,
|
||||
reimbursementsNeedSync: false,
|
||||
|
||||
missingHistoricContributionsCount: 0,
|
||||
|
||||
init () {
|
||||
this._super(...arguments);
|
||||
this.set('contributors', []);
|
||||
@@ -118,9 +120,12 @@ export default Service.extend({
|
||||
});
|
||||
|
||||
await kredits.init();
|
||||
|
||||
this.set('kredits', kredits);
|
||||
this.set('currentBlock', await kredits.provider.getBlockNumber());
|
||||
this.set('currentBlock', await this.kredits.provider.getBlockNumber());
|
||||
this.kredits.provider.on('block', blockNumber => {
|
||||
console.debug('[kredits] New block mined:', blockNumber);
|
||||
this.set('currentBlock', blockNumber)
|
||||
});
|
||||
|
||||
if (this.currentUserAccounts && this.currentUserAccounts.length > 0) {
|
||||
this.getCurrentUser.then(contributorData => {
|
||||
@@ -227,12 +232,20 @@ export default Service.extend({
|
||||
await this.loadObjectsFromCache('Contribution');
|
||||
this.set('contributionsNeedSync', true);
|
||||
} else {
|
||||
await this.fetchContributions({ page: { size: 30 } });
|
||||
await this.fetchContributions({ page: { size: 40 } });
|
||||
}
|
||||
|
||||
await this.updateMissingHistoricContributionsCount();
|
||||
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
async updateMissingHistoricContributionsCount () {
|
||||
const contributionsCount = await this.kredits.Contribution.count;
|
||||
this.set('missingHistoricContributionsCount', contributionsCount - this.contributions.length);
|
||||
console.debug(`Missing ${this.missingHistoricContributionsCount} historic contributions (out of ${contributionsCount} overall)`)
|
||||
},
|
||||
|
||||
addContributor (attributes) {
|
||||
if (attributes.github_uid) {
|
||||
const uidInt = parseInt(attributes.github_uid);
|
||||
@@ -368,11 +381,12 @@ export default Service.extend({
|
||||
syncContributions: task(function * () {
|
||||
yield this.fetchNewContributions.perform();
|
||||
yield this.syncUnconfirmedContributions.perform();
|
||||
yield this.updateMissingHistoricContributionsCount();
|
||||
this.set('contributionsNeedSync', false);
|
||||
}).group('contributionTasks'),
|
||||
|
||||
fetchNewContributions: task(function * () {
|
||||
const count = yield this.kredits.Contribution.functions.contributionsCount();
|
||||
const count = yield this.kredits.Contribution.count;
|
||||
const lastKnownContributionId = Math.max.apply(null, this.contributions.mapBy('id'));
|
||||
const toFetch = count - lastKnownContributionId;
|
||||
|
||||
@@ -389,7 +403,7 @@ export default Service.extend({
|
||||
}),
|
||||
|
||||
fetchMissingContributions: task(function * () {
|
||||
const count = yield this.kredits.Contribution.functions.contributionsCount();
|
||||
const count = yield this.kredits.Contribution.count;
|
||||
const allIds = [...Array(count+1).keys()];
|
||||
allIds.shift(); // remove first item, which is 0
|
||||
const loadedContributions = new Set(this.contributions.mapBy('id'));
|
||||
@@ -738,5 +752,5 @@ export default Service.extend({
|
||||
this.contributors
|
||||
.findBy('address', to)
|
||||
.incrementProperty('balance', value);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
+34
-13
@@ -31,32 +31,53 @@ button, input[type=submit], .button {
|
||||
&.small {
|
||||
font-size: 0.86rem;
|
||||
padding: 0.2rem 0.8rem;
|
||||
|
||||
svg {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.danger:not(:disabled) {
|
||||
color: $red;
|
||||
background-color: rgba(40, 21, 21, 0.6);
|
||||
border-color: rgba(40, 21, 21, 1);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(40, 21, 21, 0.8);
|
||||
}
|
||||
&:focus, &:active, &.active {
|
||||
border-color: $red;
|
||||
}
|
||||
&:hover { background-color: rgba(40, 21, 21, 0.8); }
|
||||
&:focus, &:active, &.active { border-color: $red; }
|
||||
}
|
||||
|
||||
&.green:not(:disabled) {
|
||||
color: $green;
|
||||
background-color: rgba(21, 40, 21, 0.6);
|
||||
border-color: rgba(21, 40, 21, 1);
|
||||
&:hover { background-color: rgba(21, 40, 21, 0.8); }
|
||||
&:focus, &:active, &.active { border-color: $green; }
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(21, 40, 21, 0.8);
|
||||
}
|
||||
&:focus, &:active, &.active {
|
||||
border-color: $green;
|
||||
}
|
||||
&.pink:not(:disabled) {
|
||||
color: $pink;
|
||||
background-color: rgba(40, 21, 40, 0.6);
|
||||
border-color: rgba(40, 21, 40, 1);
|
||||
&:hover { background-color: rgba(40, 21, 40, 0.8); }
|
||||
&:focus, &:active, &.active { border-color: $pink; }
|
||||
}
|
||||
|
||||
&.purple:not(:disabled) {
|
||||
color: $purple;
|
||||
background-color: rgba(24, 21, 40, 0.6);
|
||||
border-color: rgba(24, 21, 40, 1);
|
||||
&:hover { background-color: rgba(24, 21, 40, 0.8); }
|
||||
&:focus, &:active, &.active { border-color: $purple; }
|
||||
}
|
||||
|
||||
&.yellow:not(:disabled) {
|
||||
color: $yellow;
|
||||
background-color: rgba(40, 40, 21, 0.6);
|
||||
border-color: rgba(40, 40, 21, 1);
|
||||
&:hover { background-color: rgba(40, 40, 21, 0.8); }
|
||||
&:focus, &:active, &.active { border-color: $yellow; }
|
||||
}
|
||||
|
||||
&.icon {
|
||||
|
||||
@@ -14,10 +14,6 @@ section#signup {
|
||||
p {
|
||||
font-size: 1.2rem;
|
||||
|
||||
&.mg-bottom-md {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
&.label {
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1rem;
|
||||
|
||||
@@ -62,15 +62,12 @@ main {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Remove after switch to Tailwind CSS
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
&.mg-bottom-md {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
&.actions {
|
||||
text-align: center;
|
||||
padding-top: 2rem;
|
||||
@@ -177,4 +174,9 @@ main section {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Remove after switch to Tailwind CSS
|
||||
.mb-4 { margin-bottom: 1rem; }
|
||||
.mb-8 { margin-bottom: 2rem; }
|
||||
}
|
||||
|
||||
|
||||
@@ -17,32 +17,30 @@ ul.expense-list {
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 3;
|
||||
}
|
||||
|
||||
.amount {
|
||||
justify-self: end;
|
||||
// font-weight: normal;
|
||||
}
|
||||
|
||||
.actions {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.2rem;
|
||||
font-weight: normal;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 2rem;
|
||||
.amount {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
&.description {
|
||||
font-size: 1rem;
|
||||
opacity: 0.7;
|
||||
.description {
|
||||
font-size: 1rem;
|
||||
opacity: 0.7;
|
||||
grid-column-start: span 2;
|
||||
}
|
||||
|
||||
.tags {
|
||||
button {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,4 +31,24 @@ ul.reimbursement-list {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.meta {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 3;
|
||||
margin-top: 0.6rem;
|
||||
border-top: 1px solid $item-border-color;
|
||||
display: flex;
|
||||
|
||||
p {
|
||||
flex: 1;
|
||||
padding: 1.6rem 0 1rem 0;
|
||||
|
||||
&.confirmation-eta {
|
||||
}
|
||||
|
||||
&.actions {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-tag"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path><line x1="7" y1="7" x2="7.01" y2="7"></line></svg>
|
||||
|
After Width: | Height: | Size: 355 B |
@@ -105,6 +105,32 @@
|
||||
@showQuickFilter={{this.showQuickFilterConfirmed}} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{#if this.showFullContributionSync}}
|
||||
<section id="sync-all-contributions">
|
||||
{{#if this.kredits.fetchMissingContributions.isIdle}}
|
||||
<p class="mb-4">
|
||||
There are
|
||||
<strong>{{this.kredits.missingHistoricContributionsCount}}</strong>
|
||||
earlier contributions, which are not currently loaded/displayed.
|
||||
</p>
|
||||
<p>
|
||||
You can fetch all historic data in one go, and have it stored locally in
|
||||
your browser:
|
||||
<button type="button" {{on "click" (perform this.kredits.fetchMissingContributions)}} class="small">
|
||||
fetch all data
|
||||
</button>
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="mb-4">
|
||||
Syncing data. Please be patient...
|
||||
</p>
|
||||
<p>
|
||||
(You can leave this website anytime and sync missing data when you come back.)
|
||||
</p>
|
||||
{{/if}}
|
||||
</section>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div id="details">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<h2>Complete your contributor profile</h2>
|
||||
</header>
|
||||
<div class="content text-lg">
|
||||
<p class="mg-bottom-md">
|
||||
<p class="mb-8">
|
||||
Kredits allow you to take part in project governance, and to earn rewards for
|
||||
your contributions. For both, you will need an Ethereum wallet/account.
|
||||
</p>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export default function() {
|
||||
return (navigator.languages && navigator.languages.length) ?
|
||||
navigator.languages[0] :
|
||||
navigator.language;
|
||||
}
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "kredits-web",
|
||||
"version": "2.0.0-beta.2",
|
||||
"version": "2.0.0-beta.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "kredits-web",
|
||||
"version": "2.0.0-beta.2",
|
||||
"version": "2.0.0-beta.3",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.19.1",
|
||||
|
||||
+1
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "kredits-web",
|
||||
"version": "2.0.0-beta.2",
|
||||
"version": "2.0.0-beta.3",
|
||||
"private": true,
|
||||
"description": "Contribution dashboard of the Kosmos project",
|
||||
"repository": "https://github.com/67P/kredits-web",
|
||||
@@ -22,7 +22,6 @@
|
||||
"build-prod": "rm -rf release/* && ember build -prod --output-path release",
|
||||
"preversion": "npm test",
|
||||
"version": "npm run build-prod && git add release/",
|
||||
"postversion": "git push origin master",
|
||||
"deploy": "git push 5apps master"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+102
-51
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
+3
-3
@@ -8,10 +8,10 @@
|
||||
<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.0.0-beta.2%2B62b618b6%22%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frsk-testnet.kosmos.org%22%2C%22web3RequiredChainId%22%3A31%2C%22web3RequiredNetworkName%22%3A%22RSK%20Testnet%22%2C%22githubConnectUrl%22%3A%22https%3A%2F%2Fhal8000.chat.kosmos.org%2Fkredits%2Fsignup%2Fconnect%2Fgithub%22%2C%22githubSignupUrl%22%3A%22https%3A%2F%2Fhal8000.chat.kosmos.org%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%22btcBalanceAPI%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fkredits%2Fonchain_btc_balance%22%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.0.0-beta.3%2Bd90ddd46%22%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frsk-testnet.kosmos.org%22%2C%22web3RequiredChainId%22%3A31%2C%22web3RequiredNetworkName%22%3A%22RSK%20Testnet%22%2C%22githubConnectUrl%22%3A%22https%3A%2F%2Fhal8000.chat.kosmos.org%2Fkredits%2Fsignup%2Fconnect%2Fgithub%22%2C%22githubSignupUrl%22%3A%22https%3A%2F%2Fhal8000.chat.kosmos.org%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%22btcBalanceAPI%22%3A%22https%3A%2F%2Fapi.kosmos.org%2Fkredits%2Fonchain_btc_balance%22%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/kredits-web-429511daa3257050f23812f202a534ee.css">
|
||||
<link integrity="" rel="stylesheet" href="/assets/kredits-web-f21602587acec9a1744c244385a83592.css">
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
|
||||
<script src="/assets/vendor-4ee536ded971436a83d35253df25f2cb.js" integrity="sha256-yb+pC9iuZ8WcQwk9VuDNhSlWguL7BEABsEOEhBpwUC0= sha512-50LApx5XqeKHu/FMaljzqhAMPgkqSiy2rDhUcViYBcXWBBYmilFirup/iWvLiNCdfr5ct9wk7+tU9iShdSgDww==" ></script>
|
||||
<script src="/assets/kredits-web-0a433c90d05ea3903308867e0d178f7f.js" integrity="sha256-kU8qbqT24o1tZj4xdYJzarfPFSfEmZr3JLu0g8pAmqk= sha512-gD6YmV3xDnwHJ2WU6yXNkUEiPScjdfM2S5eYwCrsfcsI4iJUG81z7IjUbwzstuZocKkCS5zt8Y84Hh84SdhSuw==" ></script>
|
||||
<script src="/assets/kredits-web-89113e4d5c371829e3d1b05e86cbab9b.js" integrity="sha256-aabl6JZt69T2BZIv4yXcRFfmhWCyEhVA2V4g1ZzkZ6s= sha512-aD0s+kWNsXdHJFxIkgncvwNZVhtARosjjKnbLE0w1ihSrvRoptWXV1SgySdZIHKxFgbNmJGA2oQOzhBKIoqvVg==" ></script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import createComponent from 'kredits-web/tests/helpers/create-component';
|
||||
// import moment from 'moment';
|
||||
|
||||
module('Unit | Component | confirmed-in', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let component = createComponent('component:confirmed-in');
|
||||
assert.ok(component);
|
||||
});
|
||||
|
||||
test('#confirmedInBlocks', function(assert) {
|
||||
const kredits = this.owner.lookup('service:kredits');
|
||||
kredits.set('currentBlock', 419550);
|
||||
let component = createComponent('component:confirmed-in');
|
||||
component.args.confirmedAtBlock = 420000;
|
||||
|
||||
assert.equal(component.confirmedInBlocks, 450);
|
||||
})
|
||||
|
||||
test('#confirmedInSeconds', function(assert) {
|
||||
const kredits = this.owner.lookup('service:kredits');
|
||||
kredits.set('currentBlock', 419550);
|
||||
let component = createComponent('component:confirmed-in');
|
||||
component.args.confirmedAtBlock = 420000;
|
||||
|
||||
assert.equal(component.confirmedInSeconds, 13500);
|
||||
})
|
||||
|
||||
test('#confirmedInHumanTime', function(assert) {
|
||||
const kredits = this.owner.lookup('service:kredits');
|
||||
kredits.set('currentBlock', 419550);
|
||||
let component = createComponent('component:confirmed-in');
|
||||
component.args.confirmedAtBlock = 420000;
|
||||
|
||||
assert.equal(component.confirmedInHumanTime, '4 hours');
|
||||
})
|
||||
|
||||
test('#isConfirmed', function(assert) {
|
||||
const kredits = this.owner.lookup('service:kredits');
|
||||
kredits.set('currentBlock', 430000);
|
||||
let component = createComponent('component:confirmed-in');
|
||||
component.args.confirmedAtBlock = 420000;
|
||||
|
||||
assert.ok(component.isConfirmed);
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user