Compare commits

...

30 Commits

Author SHA1 Message Date
basti c57d4162d7 1.16.0 2020-05-16 11:28:23 +02:00
basti 41cc37d3eb Merge pull request #186 from 67P/chore/upgrade_ember_and_deps
Upgrade Ember and deps to 3.18/Octane
2020-05-11 13:18:58 +02:00
basti 081584a508 Remove obsolete file 2020-05-11 13:15:47 +02:00
basti 3cc01cce4e Fix some minor template issues 2020-05-11 13:15:17 +02:00
basti cedbe3cb3d Formatting 2020-05-11 13:03:46 +02:00
basti b8da04c145 Re-add contribution status class 2020-05-11 13:03:46 +02:00
galfert 009caa53e5 Fix typo in contribution-status helper
The wrong property name caused an exception when trying to remove the observer.
2020-05-11 12:18:07 +02:00
basti 9a1f543921 Mark remaining template-lint issues as pending
These need more updates outside of the templates, like e.g. Glimmer
components and such.
2020-05-11 10:24:38 +02:00
basti 22300c2980 Fix actions, etc. 2020-05-11 10:21:23 +02:00
basti 018132034d Fix github icon filename 2020-05-11 10:21:23 +02:00
basti f5d7916556 Turn on warnings for observer usage 2020-05-11 10:21:23 +02:00
basti 12df28f7fd Fix ESLint errors 2020-05-11 10:21:22 +02:00
basti 2f4f350a93 WIP Octanify the templates 2020-05-11 10:21:18 +02:00
basti 4946b3311d Remove all proposal-related code
We're not using proposals at the moment, so it's just in the way.
2020-05-10 10:25:06 +02:00
basti cc2f91afce Do not lint icon templates 2020-05-09 17:39:54 +02:00
basti aa351cbe17 Move icon templates out of pod directory
Glimmer components don't have extra markup around them, so we don't need
the component JS files anymore. Also, we can easily ignore the icon
templates when linting now.
2020-05-09 17:37:58 +02:00
basti 065c635580 Upgrade to latest Ember, etc. 2020-05-09 17:07:35 +02:00
basti 67e3c9a7c3 Merge pull request #185 from 67P/dependabot/npm_and_yarn/jquery-3.5.0
Bump jquery from 3.4.1 to 3.5.0
2020-04-30 19:54:31 +02:00
dependabot[bot] 4f4b3c5c17 Bump jquery from 3.4.1 to 3.5.0
Bumps [jquery](https://github.com/jquery/jquery) from 3.4.1 to 3.5.0.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Commits](https://github.com/jquery/jquery/compare/3.4.1...3.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-04-30 16:18:08 +00:00
basti 4f6bafa31e Merge pull request #184 from 67P/dependabot/npm_and_yarn/acorn-5.7.4
Bump acorn from 5.7.3 to 5.7.4
2020-03-16 10:50:11 -05:00
dependabot[bot] 94846c6e00 Bump acorn from 5.7.3 to 5.7.4
Bumps [acorn](https://github.com/acornjs/acorn) from 5.7.3 to 5.7.4.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/5.7.3...5.7.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-03-16 12:37:30 +00:00
basti 45d553866e Remove obsolete file 2019-12-14 16:35:13 +01:00
basti 8ac6e3ad3c 1.15.0 2019-12-14 12:06:28 +01:00
basti 215ad1d640 Merge pull request #180 from 67P/feature/add_contribution_with_params
Add "give kredits" button to contributor profiles
2019-12-13 17:33:18 +01:00
basti 3f4cc39067 Refactor assignment
Co-authored-by: Garret Alfert <alfert@wevelop.de>
2019-12-13 17:04:52 +01:00
basti 0a6b6180b9 Add "give kredits" button to contributor profiles
closes #172
2019-12-12 17:33:08 +01:00
basti 536868002f Support query params for adding contribution
Just contributor ID, kind, and amount for now.
2019-12-10 18:16:54 +01:00
basti 04a7f9139d Allow partial override of contribution attributes 2019-12-10 13:40:08 +03:00
basti 863b542e3e Add failing test for partial attribute override
Currently the default attributes are only set correctly when either none
or all attributes are handed to the component
2019-12-10 13:18:21 +03:00
basti 23d86f1502 Add unit test for add-contribution component 2019-12-10 13:09:30 +03:00
85 changed files with 18053 additions and 12278 deletions
-1
View File
@@ -4,7 +4,6 @@
root = true root = true
[*] [*]
end_of_line = lf end_of_line = lf
charset = utf-8 charset = utf-8
+12 -4
View File
@@ -1,8 +1,14 @@
'use strict';
module.exports = { module.exports = {
root: true, root: true,
parser: 'babel-eslint',
parserOptions: { parserOptions: {
ecmaVersion: 2018, ecmaVersion: 2018,
sourceType: 'module' sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true
}
}, },
globals: { globals: {
console: true console: true
@@ -19,7 +25,10 @@ module.exports = {
}, },
rules: { rules: {
'ember/avoid-leaking-state-in-ember-objects': 'warn', 'ember/avoid-leaking-state-in-ember-objects': 'warn',
'no-console': 'off' 'no-console': 'off',
'ember/no-jquery': 'error',
'ember/require-computed-property-dependencies': 'warn',
'ember/no-observers': 'warn'
}, },
overrides: [ overrides: [
// node files // node files
@@ -35,8 +44,7 @@ module.exports = {
'server/**/*.js' 'server/**/*.js'
], ],
parserOptions: { parserOptions: {
sourceType: 'script', sourceType: 'script'
ecmaVersion: 2015
}, },
env: { env: {
browser: false, browser: false,
+85 -2
View File
@@ -1,10 +1,93 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
extends: 'recommended', extends: 'octane',
rules: { rules: {
'simple-unless': false, 'simple-unless': false,
'no-nested-interactive': false 'no-nested-interactive': false
} },
ignore: [
'kredits-web/templates/components/**',
'app/templates/components/**'
],
pending: [
{
"moduleId": "app/templates/dashboard",
"only": [
"no-action"
]
},
{
"moduleId": "app/components/add-contribution/template",
"only": [
"no-action",
"no-curly-component-invocation"
]
},
{
"moduleId": "app/components/add-contributor/template",
"only": [
"no-action",
"no-curly-component-invocation"
]
},
{
"moduleId": "app/components/contribution-list/template",
"only": [
"no-action",
"no-curly-component-invocation"
]
},
{
"moduleId": "app/components/contributor-list/template",
"only": [
"no-action"
]
},
{
"moduleId": "app/components/topbar-account-panel/template",
"only": [
"no-action"
]
},
{
"moduleId": "app/templates/contributions/new",
"only": [
"no-action"
]
},
{
"moduleId": "app/templates/contributions/resubmit",
"only": [
"no-action"
]
},
{
"moduleId": "app/templates/contributors/edit",
"only": [
"no-action"
]
},
{
"moduleId": "app/templates/contributors/new",
"only": [
"no-action"
]
},
{
"moduleId": "app/templates/signup/eth-account",
"only": [
"no-action"
]
},
{
"moduleId": "app/templates/signup/index",
"only": [
"no-action"
]
}
]
}; };
+4 -2
View File
@@ -23,7 +23,9 @@ env:
# See https://git.io/vdao3 for details. # See https://git.io/vdao3 for details.
- JOBS=1 - JOBS=1
branches:
only:
- master
script: script:
- npm run lint:hbs
- npm run lint:js
- npm test - npm test
+6 -8
View File
@@ -1,14 +1,12 @@
import Application from '@ember/application'; import Application from '@ember/application';
import Resolver from './resolver'; import Resolver from 'ember-resolver';
import loadInitializers from 'ember-load-initializers'; import loadInitializers from 'ember-load-initializers';
import config from './config/environment'; import config from './config/environment';
const App = Application.extend({ export default class App extends Application {
modulePrefix: config.modulePrefix, modulePrefix = config.modulePrefix;
podModulePrefix: config.podModulePrefix, podModulePrefix = config.podModulePrefix;
Resolver Resolver = Resolver;
}); }
loadInitializers(App, config.modulePrefix); loadInitializers(App, config.modulePrefix);
export default App;
+14 -14
View File
@@ -1,7 +1,7 @@
import Component from '@ember/component'; import Component from '@ember/component';
import { computed } from '@ember/object'; import { computed } from '@ember/object';
import { and, notEmpty } from '@ember/object/computed'; import { and, notEmpty } from '@ember/object/computed';
import { isEmpty } from '@ember/utils'; import { assign } from '@ember/polyfills';
import moment from 'moment'; import moment from 'moment';
export default Component.extend({ export default Component.extend({
@@ -24,19 +24,17 @@ export default Component.extend({
init () { init () {
this._super(...arguments); this._super(...arguments);
this.set('defaultDate', moment().startOf('hour').toDate()); this.set('defaultDate', moment().startOf('hour').toDate());
this.set('defaultAttr', {
contributorId: null,
kind: null,
date: this.defaultDate,
amount: null,
description: null,
url: null,
details: null
});
// Default attributes used by reset this.set('attributes', assign({}, this.defaultAttr, this.attributes));
if (isEmpty(this.attributes)) {
this.set('attributes', {
contributorId: null,
kind: null,
date: this.defaultDate,
amount: null,
description: null,
url: null,
details: null
});
}
this.reset(); this.reset();
}, },
@@ -47,7 +45,9 @@ export default Component.extend({
actions: { actions: {
submit () { submit (evt) {
evt.preventDefault();
if (!this.isValid) { if (!this.isValid) {
alert('Invalid data. Please review and try again.'); alert('Invalid data. Please review and try again.');
return; return;
+25 -25
View File
@@ -1,11 +1,11 @@
<form {{action "submit" on="submit"}}> <form onsubmit={{action "submit"}}>
<label> <label>
<p class="label">Contributor:</p> <p class="label">Contributor:</p>
<p> <p>
<select required onchange={{action (mut contributorId) value="target.value"}}> <select required onchange={{action (mut this.contributorId) value="target.value"}}>
<option value="" selected disabled hidden></option> <option value="" selected disabled hidden></option>
{{#each contributors as |contributor|}} {{#each @contributors as |contributor|}}
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.name}}</option> <option value={{contributor.id}} selected={{eq this.contributorId contributor.id}}>{{contributor.name}}</option>
{{/each}} {{/each}}
</select> </select>
</p> </p>
@@ -13,14 +13,14 @@
<label> <label>
<p class="label">Kind:</p> <p class="label">Kind:</p>
<p> <p>
<select required onchange={{action (mut kind) value="target.value"}}> <select required onchange={{action (mut this.kind) value="target.value"}}>
<option value="" selected disabled hidden></option> <option value="" selected disabled hidden></option>
<option value="community" selected={{eq kind "community"}}>Community</option> <option value="community" selected={{eq this.kind "community"}}>Community</option>
<option value="design" selected={{eq kind "design"}}>Design</option> <option value="design" selected={{eq this.kind "design"}}>Design</option>
<option value="dev" selected={{eq kind "dev"}}>Development</option> <option value="dev" selected={{eq this.kind "dev"}}>Development</option>
<option value="docs" selected={{eq kind "docs"}}>Documentation</option> <option value="docs" selected={{eq this.kind "docs"}}>Documentation</option>
<option value="ops" selected={{eq kind "ops"}}>IT Operations</option> <option value="ops" selected={{eq this.kind "ops"}}>IT Operations</option>
<option value="special" selected={{eq kind "special"}}>Special</option> <option value="special" selected={{eq this.kind "special"}}>Special</option>
</select> </select>
</p> </p>
</label> </label>
@@ -28,12 +28,12 @@
<p class="label">Date:</p> <p class="label">Date:</p>
<p> <p>
{{ember-flatpickr {{ember-flatpickr
date=date date=this.date
defaultDate=defaultDate defaultDate=this.defaultDate
maxDate=defaultDate maxDate=this.defaultDate
enableTime=true enableTime=true
time_24hr=true time_24hr=true
onChange=(action (mut date)) onChange=(action (mut this.date))
}} }}
</p> </p>
</label> </label>
@@ -42,33 +42,33 @@
<p> <p>
{{input type="text" {{input type="text"
placeholder="500" placeholder="500"
value=amount value=this.amount
class=(if isValidAmount "valid" "")}} class=(if this.isValidAmount "valid" "")}}
</p> </p>
</label> </label>
<label> <label>
<p class="label">Description:</p> <p class="label">Description:</p>
<p> <p>
{{input type="text" {{input type="text"
value=description value=this.description
class=(if isValidDescription "valid" "")}} class=(if this.isValidDescription "valid" "")}}
</p> </p>
</label> </label>
<label> <label>
<p class="label">URL (optional):</p> <p class="label">URL (optional):</p>
<p> <p>
{{input type="text" {{input type="text"
value=url value=this.url
class=(if isValidUrl "valid" "")}} class=(if this.isValidUrl "valid" "")}}
</p> </p>
</label> </label>
{{#if details}} {{#if this.details}}
<label> <label>
<p class="label">Details:</p> <p class="label">Details:</p>
<p> <p>
<pre> <pre>
{{details}} {{this.details}}
</pre> </pre>
</p> </p>
</label> </label>
@@ -76,8 +76,8 @@
<p class="actions"> <p class="actions">
{{input type="submit" {{input type="submit"
disabled=inProgress disabled=this.inProgress
value=(if inProgress "Processing" "Save")}} value=(if this.inProgress "Processing" "Save")}}
</p> </p>
</form> </form>
+9 -3
View File
@@ -7,8 +7,8 @@ import { isAddress } from 'web3-utils';
export default Component.extend({ export default Component.extend({
kredits: service(),
router: service(), router: service(),
kredits: service(),
attributes: null, attributes: null,
@@ -60,9 +60,15 @@ export default Component.extend({
actions: { actions: {
submit () { submit (evt) {
evt.preventDefault();
if (!this.kredits.currentUserIsCore) {
window.alert('Only core team members can edit profiles. Please ask someone to set you up.');
return;
}
if (!this.isValid) { if (!this.isValid) {
alert('Invalid data. Please review and try again.'); window.alert('Invalid data. Please review and try again.');
return; return;
} }
+25 -24
View File
@@ -1,55 +1,56 @@
<form {{action "submit" on="submit"}}> <form onsubmit={{action "submit"}}>
<p> <p>
<label for="c-account">Ethereum account</label> <label for="c-account">Ethereum account</label>
{{input name="account" id="c-account" <Input @type="text"
type="text" value=account @value={{this.account}}
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4" name="account" id="c-account"
class=(if isValidAccount "valid" "")}} placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
class={{if this.isValidAccount "valid" ""}} />
</p> </p>
<p> <p>
<label for="c-kind">Kind</label> <label for="c-kind">Kind</label>
<select required onchange={{action (mut kind) value="target.value"}} id="c-kind"> <select required onchange={{action (mut this.kind) value="target.value"}} id="c-kind">
<option value="person" selected={{eq kind "person"}}>Person</option> <option value="person" selected={{eq this.kind "person"}}>Person</option>
<option value="organization" selected={{eq kind "organization"}}>Organization</option> <option value="organization" selected={{eq this.kind "organization"}}>Organization</option>
</select> </select>
</p> </p>
<p> <p>
<label for="c-name">Name</label> <label for="c-name">Name</label>
{{input name="name" type="text" value=name placeholder="Zero Cool" {{input name="name" type="text" value=this.name placeholder="Zero Cool"
class=(if isValidName "valid" "") id="c-name"}} class=(if this.isValidName "valid" "") id="c-name"}}
</p> </p>
<p> <p>
<label for="c-url">URL</label> <label for="c-url">URL</label>
{{input name="url" type="text" value=url placeholder="http://zerocool.bit" {{input name="url" type="text" value=this.url placeholder="http://zerocool.bit"
class=(if isValidURL "valid" "") id="c-url"}} class=(if this.isValidURL "valid" "") id="c-url"}}
</p> </p>
<p> <p>
<label for="c-github-uid">GitHub UID</label> <label for="c-github-uid">GitHub UID</label>
{{input name="github_uid" type="text" value=github_uid placeholder="2342" {{input name="github_uid" type="text" value=this.github_uid placeholder="2342"
class=(if isValidGithubUID "valid" "") id="c-github-uid"}} class=(if this.isValidGithubUID "valid" "") id="c-github-uid"}}
</p> </p>
<p> <p>
<label for="c-github-username">GitHub username</label> <label for="c-github-username">GitHub username</label>
{{input name="github_username" type="text" value=github_username placeholder="zerocool" {{input name="github_username" type="text" value=this.github_username placeholder="zerocool"
class=(if isValidGithubUsername "valid" "") id="c-github-username"}} class=(if this.isValidGithubUsername "valid" "") id="c-github-username"}}
</p> </p>
<p> <p>
<label for="c-gitea-username">Gitea username</label> <label for="c-gitea-username">Gitea username</label>
{{input name="gitea_username" type="text" value=gitea_username placeholder="zerocool" {{input name="gitea_username" type="text" value=this.gitea_username placeholder="zerocool"
class=(if isValidGiteaUsername "valid" "") id="c-gitea-username"}} class=(if this.isValidGiteaUsername "valid" "") id="c-gitea-username"}}
</p> </p>
<p> <p>
<label for="c-wiki-username">Wiki username</label> <label for="c-wiki-username">Wiki username</label>
{{input name="wiki_username" type="text" value=wiki_username placeholder="ZeroCool" {{input name="wiki_username" type="text" value=this.wiki_username placeholder="ZeroCool"
class=(if isValidWikiUsername "valid" "") id="c-wiki-username"}} class=(if this.isValidWikiUsername "valid" "") id="c-wiki-username"}}
</p> </p>
<p> <p>
<label for="c-zoom-display-name">Zoom display name</label> <label for="c-zoom-display-name">Zoom display name</label>
{{input name="zoom_display_name" type="text" value=zoom_display_name placeholder="Zero Cool" {{input name="zoom_display_name" type="text" value=this.zoom_display_name placeholder="Zero Cool"
class=(if isValidZoomDisplayName "valid" "") id="c-zoom-display-name"}} class=(if this.isValidZoomDisplayName "valid" "") id="c-zoom-display-name"}}
</p> </p>
<p class="actions"> <p class="actions">
{{input type="submit" disabled=inProgress {{input type="submit" disabled=this.inProgress
value=(if inProgress "Processing" "Save")}} value=(if this.inProgress "Processing" "Save")}}
</p> </p>
</form> </form>
-64
View File
@@ -1,64 +0,0 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { and, notEmpty } from '@ember/object/computed';
export default Component.extend({
attributes: null,
contributors: Object.freeze([]),
isValidContributor: notEmpty('contributorId'),
isValidAmount: computed('amount', function() {
return parseInt(this.amount, 10) > 0;
}),
isValidDescription: notEmpty('description'),
isValidUrl: notEmpty('url'),
isValid: and('isValidContributor',
'isValidAmount',
'isValidDescription'),
init () {
this._super(...arguments);
// Default attributes used by reset
this.set('attributes', {
contributorId: null,
kind: 'community',
amount: null,
description: null,
url: null,
});
},
didInsertElement() {
this._super(...arguments);
this.reset();
},
reset: function() {
this.setProperties(this.attributes);
},
actions: {
submit() {
if (!this.isValid) {
alert('Invalid data. Please review and try again.');
return;
}
let attributes = Object.keys(this.attributes);
let proposal = this.getProperties(attributes);
let saved = this.save(proposal);
// The promise handles inProgress
this.set('inProgress', saved);
saved.then(() => {
this.reset();
window.scroll(0,0);
window.alert('Proposal added.');
});
}
}
});
-44
View File
@@ -1,44 +0,0 @@
<form {{action "submit" on="submit"}}>
<p>
<select required onchange={{action (mut contributorId) value="target.value"}}>
<option value="" selected disabled hidden>Contributor</option>
{{#each contributors as |contributor|}}
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.github_username}}</option>
{{/each}}
</select>
</p>
<p>
<select required onchange={{action (mut kind) value="target.value"}}>
<option value="community" selected={{eq kind "community"}}>Community</option>
<option value="design" selected={{eq kind "design"}}>Design</option>
<option value="dev" selected={{eq kind "dev"}}>Development</option>
<option value="docs" selected={{eq kind "docs"}}>Documentation</option>
<option value="ops" selected={{eq kind "ops"}}>IT Operations</option>
</select>
</p>
<p>
{{input type="text"
placeholder="100"
value=amount
class=(if isValidAmount "valid" "")}}
</p>
<p>
{{input type="text"
placeholder="Description"
value=description
class=(if isValidDescription "valid" "")}}
</p>
<p>
{{input type="text"
placeholder="URL (optional)"
value=url
class=(if isValidUrl "valid" "")}}
</p>
<p class="actions">
{{input type="submit"
disabled=(is-pending inProgress)
value=(if (is-pending inProgress) "Processing" "Save")}}
{{#link-to "index"}}Back{{/link-to}}
</p>
</form>
@@ -1,7 +1,6 @@
<div class="chart"> <div class="chart">
{{ember-chart type="doughnut" <EmberChart @type="doughnut"
data=chartData @data={{this.chartData}}
options=chartOptions @options={{this.chartOptions}}
width=200 @width="200" @height="200" />
height=200}}
</div> </div>
@@ -24,12 +24,10 @@ export default Component.extend({
contributors: sort('kredits.contributors', 'contributorsSorting'), contributors: sort('kredits.contributors', 'contributorsSorting'),
contributorsActive: computed('contributors.[]', 'contributions', function() { contributorsActive: computed('contributors.[]', 'contributions', function() {
let activeIds = this.contributions.mapBy('contributorId') const activeIds = new Set(this.contributions.mapBy('contributorId')
.map(id => id.toString()) .map(id => id.toString()));
.uniq();
return this.contributors.filter(c => { return this.contributors.filter(c => activeIds.has(c.id.toString()));
return activeIds.includes(c.id.toString());
});
}), }),
contributionKinds: computed('contributions.[]', function() { contributionKinds: computed('contributions.[]', function() {
+15 -16
View File
@@ -1,28 +1,28 @@
{{#if showQuickFilter}} {{#if @showQuickFilter}}
<div class="quick-filter"> <div class="quick-filter">
<p> <p>
<label class="filter-contributor"> <label class="filter-contributor">
Contributor: Contributor:
<select onchange={{action (mut contributorId) value="target.value"}}> <select onchange={{action (mut this.contributorId) value="target.value"}}>
<option value="" selected>all</option> <option value="" selected>all</option>
{{#each contributorsActive as |contributor|}} {{#each this.contributorsActive as |contributor|}}
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.name}}</option> <option value={{contributor.id}} selected={{eq this.contributorId contributor.id}}>{{contributor.name}}</option>
{{/each}} {{/each}}
</select> </select>
</label> </label>
<label class="filter-contribution-kind"> <label class="filter-contribution-kind">
Kind: Kind:
<select onchange={{action (mut contributionKind) value="target.value"}}> <select onchange={{action (mut this.contributionKind) value="target.value"}}>
<option value="" selected>all</option> <option value="" selected>all</option>
{{#each contributionKinds as |kind|}} {{#each this.contributionKinds as |kind|}}
<option value={{kind}} selected={{eq contributionKind kind}}>{{capitalize-string kind}}</option> <option value={{kind}} selected={{eq this.contributionKind kind}}>{{capitalize-string kind}}</option>
{{/each}} {{/each}}
</select> </select>
</label> </label>
<label class="filter-contribution-size"> <label class="filter-contribution-size">
{{input type="checkbox" checked=hideSmallContributions}} <Input @type="checkbox" @checked={{this.hideSmallContributions}} />
Hide small contributions Hide small contributions
</label> </label>
</p> </p>
@@ -30,12 +30,12 @@
{{/if}} {{/if}}
<ul class="contribution-list"> <ul class="contribution-list">
{{#each contributionsFiltered as |contribution|}} {{#each this.contributionsFiltered as |contribution|}}
<li role="button" {{action "openContributionDetails" contribution}} <li role="button" data-contribution-id={{contribution.id}}
data-contribution-id={{contribution.id}} {{action "openContributionDetails" contribution}}
class="{{contribution-status contribution}}{{if (eq contribution.id selectedContributionId) " selected"}}"> class="{{contribution-status contribution}}{{if (eq contribution.id @selectedContributionId) " selected"}}">
<p class="meta"> <p class="meta">
<span class="recipient">{{user-avatar contributor=contribution.contributor}}</span> <span class="recipient"><UserAvatar @contributor={{contribution.contributor}} /></span>
<span class="category {{contribution.kind}}">({{contribution.kind}})</span> <span class="category {{contribution.kind}}">({{contribution.kind}})</span>
<span class="title">{{contribution.description}}</span> <span class="title">{{contribution.description}}</span>
</p> </p>
@@ -45,10 +45,9 @@
{{#unless contribution.vetoed}} {{#unless contribution.vetoed}}
{{#unless (is-confirmed-contribution contribution)}} {{#unless (is-confirmed-contribution contribution)}}
<p class="voting"> <p class="voting">
{{input type="button" class="button small danger" {{input type="button" class="button small danger" value="veto"
click=(action "veto" contribution.id) click=(action "veto" contribution.id)
disabled=contribution.hasPendingChanges disabled=contribution.hasPendingChanges}}
value="veto"}}
</p> </p>
{{/unless}} {{/unless}}
{{/unless}} {{/unless}}
+6 -5
View File
@@ -1,13 +1,14 @@
<tbody> <tbody>
{{#each contributorList as |c|}} {{#each @contributorList as |c|}}
<tr role="button" {{action "openContributorDetails" c.contributor}} <tr role="button"
class="{{if (is-current-user c.contributor) "current-user"}} {{if (eq c.contributor.id selectedContributorId) "selected"}}"> onclick={{action "openContributorDetails" c.contributor}}
class="{{if (is-current-user c.contributor) "current-user"}} {{if (eq c.contributor.id @selectedContributorId) "selected"}}">
<td class="person"> <td class="person">
{{user-avatar contributor=c.contributor}} {{c.contributor.name}} <UserAvatar @contributor={{c.contributor}} /> {{c.contributor.name}}
</td> </td>
<td class="kredits"> <td class="kredits">
<span class="amount"> <span class="amount">
{{#if showUnconfirmedKredits}} {{#if @showUnconfirmedKredits}}
{{c.amountTotal}} {{c.amountTotal}}
{{else}} {{else}}
{{c.amountConfirmed}} {{c.amountConfirmed}}
@@ -1,4 +1,5 @@
<a href={{account.url}} target="_blank" rel="noopener" title="{{account.username}} on {{account.site}}"> <a href={{this.account.url}} target="_blank" rel="noopener noreferrer"
<span class="site">{{account.site}}</span> title="{{this.account.username}} on {{this.account.site}}">
{{component iconComponentName}} <span class="site">{{this.account.site}}</span>
{{component this.iconComponentName}}
</a> </a>
@@ -1,5 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: ""
});
@@ -1,5 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: ""
});
@@ -1,5 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: ""
});
@@ -1,5 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: ""
});
-5
View File
@@ -1,5 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: ""
});
@@ -1,5 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: ""
});
-20
View File
@@ -1,20 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: 'ul',
classNames: ['proposal-list'],
actions: {
confirm(proposalId) {
if (this.contractInteractionEnabled) {
this.confirmProposal(proposalId);
} else {
window.alert('Only members can vote on proposals. Please ask someone to set you up.');
}
}
}
});
-20
View File
@@ -1,20 +0,0 @@
{{#each proposals as |proposal|}}
<li data-proposal-id={{proposal.id}} class={{if proposal.isExecuted "confirmed" "unconfirmed"}}>
<p class="meta">
<span class="category {{proposal.kind}}">♥ ({{proposal.kind}})</span>
<span class="recipient">{{proposal.contributor.name}}:</span>
</p>
<p class="kredits-amount">
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
</p>
<p class="description">
<span class="description">{{proposal.description}}</span>
</p>
<p class="voting">
{{#unless proposal.isExecuted}}
<span class="votes">({{proposal.votesCount}}/{{proposal.votesNeeded}} votes)</span>
<button {{action "confirm" proposal.id}}>+1</button>
{{/unless}}
</p>
</li>
{{/each}}
@@ -1,17 +1,17 @@
<section id="user-account"> <section id="user-account">
{{#if setupInProgress}} {{#if this.setupInProgress}}
Connecting account... Connecting account...
{{else}} {{else}}
{{#if (and kredits.hasAccounts kredits.currentUser)}} {{#if (and this.kredits.hasAccounts this.kredits.currentUser)}}
{{kredits.currentUser.name}} {{this.kredits.currentUser.name}}
{{#if kredits.currentUserIsCore}} {{#if this.kredits.currentUserIsCore}}
<span class="core-flag">(core)</span> <span class="core-flag">(core)</span>
{{/if}} {{/if}}
{{else}} {{else}}
<span class="anonymous">Anonymous</span> <span class="anonymous">Anonymous</span>
<button {{action "signup"}} class="small">Sign up</button> <button onclick={{action "signup"}} class="small" type="button">Sign up</button>
{{#if showConnectButton}} {{#if this.showConnectButton}}
<button {{action "connectAccount"}} class="small green">Connect account</button> <button onclick={{action "connectAccount"}} class="small green" type="button">Connect account</button>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}
+3
View File
@@ -24,6 +24,9 @@ export default Component.extend({
if (github_uid) { if (github_uid) {
return `https://avatars2.githubusercontent.com/u/${github_uid}?v=3&s=${SIZES[this.size]}`; return `https://avatars2.githubusercontent.com/u/${github_uid}?v=3&s=${SIZES[this.size]}`;
} else {
// TODO use custom avatar
return '';
} }
}) })
+2
View File
@@ -6,6 +6,8 @@ export default Controller.extend({
kredits: service(), kredits: service(),
queryParams: ['contributorId', 'kind', 'amount'],
contributors: alias('kredits.contributors'), contributors: alias('kredits.contributors'),
minedContributors: filterBy('contributors', 'id'), minedContributors: filterBy('contributors', 'id'),
-6
View File
@@ -45,12 +45,6 @@ export default Controller.extend({
}); });
}, },
confirmProposal (proposalId) {
this.kredits.vote(proposalId).then(transaction => {
console.debug('[controllers:index] Vote submitted to Ethereum blockhain: '+transaction.hash);
});
},
toggleQuickFilterUnconfirmed () { toggleQuickFilterUnconfirmed () {
this.toggleProperty('showQuickFilterUnconfirmed'); this.toggleProperty('showQuickFilterUnconfirmed');
}, },
-24
View File
@@ -1,24 +0,0 @@
import Controller from '@ember/controller';
import { alias, filterBy } from '@ember/object/computed';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
contributors: alias('kredits.contributors'),
minedContributors: filterBy('contributors', 'id'),
actions: {
save(proposal) {
// contributorIpfsHash is needed for the proposal ipfs data. I'm not happy to do this here but I think to load all the contributors in addProposal again is a bit too much. I hope we can refactor it later.
let contributor = this.contributors.findBy('id', proposal.contributorId);
proposal.contributorIpfsHash = contributor.get('ipfsHash');
return this.kredits.addProposal(proposal)
.then((proposal) => {
this.transitionToRoute('index');
return proposal;
});
}
}
});
+2 -4
View File
@@ -45,14 +45,12 @@ export default Helper.extend({
contribution.removeObserver('vetoed', this, this.triggerRecompute); contribution.removeObserver('vetoed', this, this.triggerRecompute);
contribution.removeObserver('confirmedAt', this, this.triggerRecompute); contribution.removeObserver('confirmedAt', this, this.triggerRecompute);
contribution.removeObserver('currentBlock', this, this.triggerRecompute); contribution.removeObserver('currentBlock', this, this.triggerRecompute);
contribution.removeObserver('hadPendingChanges', this, this.triggerRecompute); contribution.removeObserver('hasPendingChanges', this, this.triggerRecompute);
}; };
}, },
triggerRecompute () { triggerRecompute () {
once(this, function () { once(this, this.recompute);
this.recompute();
});
} }
}); });
-32
View File
@@ -1,32 +0,0 @@
import EmberObject from '@ember/object';
import { alias } from '@ember/object/computed';
import bignumber from 'kredits-web/utils/cps/bignumber';
export default EmberObject.extend({
// Contract
id: bignumber('idRaw', 'toString'),
creatorAccount: null,
contributorId: bignumber('contributorIdRaw', 'toString'),
amount: bignumber('amountRaw', 'toNumber'),
votesCount: bignumber('votesCountRaw', 'toNumber'),
votesNeeded: bignumber('votesNeededRaw', 'toNumber'),
executed: null,
ipfsHash: null,
// Shortcuts
isExecuted: alias('executed'),
// IPFS
kind: null,
description: null,
details: null,
url: null,
ipfsData: '',
init () {
this._super(...arguments);
this.set('details', {});
}
});
-3
View File
@@ -1,3 +0,0 @@
import Resolver from 'ember-resolver';
export default Resolver;
+5 -10
View File
@@ -1,10 +1,10 @@
import EmberRouter from '@ember/routing/router'; import EmberRouter from '@ember/routing/router';
import config from './config/environment'; import config from './config/environment';
const Router = EmberRouter.extend({ export default class Router extends EmberRouter {
location: config.locationType, location = config.locationType;
rootURL: config.rootURL rootURL = config.rootURL;
}); }
Router.map(function() { Router.map(function() {
this.route('dashboard', function() { this.route('dashboard', function() {
@@ -16,11 +16,8 @@ Router.map(function() {
this.route('show', { path: ':id' }); this.route('show', { path: ':id' });
}); });
}); });
this.route('proposals', function() {
this.route('new');
});
this.route('contributions', function() { this.route('contributions', function() {
this.route('new'); this.route('new', { queryParams: ['contributorId', 'kind', 'amount'] });
this.route('resubmit', { path: ':id/resubmit' }); this.route('resubmit', { path: ':id/resubmit' });
}); });
this.route('contributors', function() { this.route('contributors', function() {
@@ -33,5 +30,3 @@ Router.map(function() {
this.route('complete'); this.route('complete');
}); });
}); });
export default Router;
+9
View File
@@ -0,0 +1,9 @@
import Route from '@ember/routing/route';
export default Route.extend({
model (params) {
return { params };
}
});
+2 -88
View File
@@ -13,7 +13,6 @@ import formatKredits from 'kredits-web/utils/format-kredits';
import config from 'kredits-web/config/environment'; import config from 'kredits-web/config/environment';
import Contributor from 'kredits-web/models/contributor' import Contributor from 'kredits-web/models/contributor'
import Proposal from 'kredits-web/models/proposal'
import Contribution from 'kredits-web/models/contribution' import Contribution from 'kredits-web/models/contribution'
export default Service.extend({ export default Service.extend({
@@ -23,7 +22,6 @@ export default Service.extend({
currentUser: null, currentUser: null,
contributors: null, contributors: null,
contributions: null, contributions: null,
proposals: null,
githubAccessToken: null, githubAccessToken: null,
currentUserIsContributor: notEmpty('currentUser'), currentUserIsContributor: notEmpty('currentUser'),
@@ -77,7 +75,6 @@ export default Service.extend({
init () { init () {
this._super(...arguments); this._super(...arguments);
this.set('contributors', []); this.set('contributors', []);
this.set('proposals', []);
this.set('contributions', []); this.set('contributions', []);
}, },
@@ -232,31 +229,6 @@ export default Service.extend({
}); });
}, },
//
// TODO Implement proposals with voting
//
// addProposal (attributes) {
// console.debug('[kredits] add proposal', attributes);
//
// return this.kredits.Proposal.addProposal(attributes)
// .then((data) => {
// console.debug('[kredits] add proposal response', data);
// attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
// return Proposal.create(attributes);
// });
// },
// getProposals () {
// return this.kredits.Proposal.all()
// .then(proposals => {
// return proposals.map(proposal => {
// proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
// return Proposal.create(proposal);
// });
// });
// },
getContributions () { getContributions () {
return this.kredits.Contribution.all({page: {size: 200}}) return this.kredits.Contribution.all({page: {size: 200}})
.then(contributions => { .then(contributions => {
@@ -267,16 +239,6 @@ export default Service.extend({
}); });
}, },
vote (proposalId) {
console.debug('[kredits] vote for', proposalId);
return this.kredits.Proposal.functions.vote(proposalId)
.then(data => {
console.debug('[kredits] vote response', data);
return data;
});
},
veto (contributionId) { veto (contributionId) {
console.debug('[kredits] veto against', contributionId); console.debug('[kredits] veto against', contributionId);
const contribution = this.contributions.findBy('id', contributionId); const contribution = this.contributions.findBy('id', contributionId);
@@ -289,12 +251,12 @@ export default Service.extend({
}); });
}, },
getCurrentUser: computed('kredits.provider', function() { getCurrentUser: computed('kredits.provider', 'currentUserAccounts.[]', function() {
if (isEmpty(this.currentUserAccounts)) { if (isEmpty(this.currentUserAccounts)) {
return RSVP.resolve(); return RSVP.resolve();
} }
return this.kredits.Contributor return this.kredits.Contributor
.functions.getContributorIdByAddress(this.get('currentUserAccounts.firstObject')) .functions.getContributorIdByAddress(this.currentUserAccounts.firstObject)
.then((id) => { .then((id) => {
// check if the user is a contributor or not // check if the user is a contributor or not
if (id === 0) { if (id === 0) {
@@ -305,10 +267,6 @@ export default Service.extend({
}); });
}), }),
findProposalById(proposalId) {
return this.proposals.findBy('id', proposalId.toString());
},
// Contract events // Contract events
addContractEventHandlers () { addContractEventHandlers () {
this.kredits.Contributor this.kredits.Contributor
@@ -320,11 +278,6 @@ export default Service.extend({
.on('ContributionAdded', this.handleContributionAdded.bind(this)) .on('ContributionAdded', this.handleContributionAdded.bind(this))
.on('ContributionVetoed', this.handleContributionVetoed.bind(this)) .on('ContributionVetoed', this.handleContributionVetoed.bind(this))
this.kredits.Proposal
.on('ProposalCreated', this.handleProposalCreated.bind(this))
.on('ProposalVoted', this.handleProposalVoted.bind(this))
.on('ProposalExecuted', this.handleProposalExecuted.bind(this));
this.kredits.Token this.kredits.Token
.on('Transfer', this.handleTransfer.bind(this)); .on('Transfer', this.handleTransfer.bind(this));
}, },
@@ -374,45 +327,6 @@ export default Service.extend({
} }
}, },
handleProposalCreated (proposalId) {
let proposal = this.findProposalById(proposalId);
if (proposal) {
console.debug('[events] proposal exists, not adding from event');
return;
}
this.kredits.Proposal.getById(proposalId)
.then((proposal) => {
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
this.proposals.pushObject(Proposal.create(proposal));
});
},
// TODO: We may want to reload that proposal to show the voter as voted
handleProposalVoted (proposalId, voterId, totalVotes) {
let proposal = this.findProposalById(proposalId);
if (proposal) {
proposal.set('votesCount', totalVotes);
}
},
handleProposalExecuted (proposalId, contributorId, amount) {
let proposal = this.findProposalById(proposalId);
if (proposal.get('isExecuted')) {
console.debug('[events] proposal already executed, not adding from event');
return;
}
proposal.set('executed', true);
this.contributors
.findBy('id', contributorId.toString())
.incrementProperty('balance', amount);
},
handleTransfer (from, to, value) { handleTransfer (from, to, value) {
value = value.toNumber(); value = value.toNumber();
-1
View File
@@ -1,6 +1,5 @@
section#add-contributor, section#add-contributor,
section#add-contribution, section#add-contribution,
section#add-proposal,
section#signup { section#signup {
form { form {
-17
View File
@@ -76,22 +76,6 @@ section {
} }
} }
} }
&#proposals-open, &#proposals-closed {
.actions {
padding-top: 3rem;
font-size: 1rem;
color: $primary-color;
text-align: center;
@include media-max(small) {
padding-top: 2rem;
}
a {
color: $primary-color;
}
}
}
} }
@media (min-width: 550px) { @media (min-width: 550px) {
@@ -111,7 +95,6 @@ section {
@import "components/contributor-profile"; @import "components/contributor-profile";
@import "components/external-account-link"; @import "components/external-account-link";
@import "components/loading-spinner"; @import "components/loading-spinner";
@import "components/proposal-list";
@import "components/topbar"; @import "components/topbar";
@import "components/topbar-account-panel"; @import "components/topbar-account-panel";
@import "components/user-avatar"; @import "components/user-avatar";
@@ -115,37 +115,3 @@ ul.contribution-list {
} }
} }
@media (min-width: 550px) {
ul.proposal-list {
li {
grid-template-columns: auto 10rem;
grid-row-gap: 0.5rem;
p {
&.kredits-amount, &.voting {
text-align: right;
}
}
&.unconfirmed {
p {
&.kredits-amount, &.voting {
text-align: right;
}
&.description {
grid-column-start: span 1;
}
&.voting {
grid-column-start: span 1;
}
}
}
.description {
}
}
}
}
@@ -42,6 +42,10 @@ section#contributor-profile {
} }
} }
} }
.actions {
margin-top: 2rem;
}
} }
.actions { .actions {
-111
View File
@@ -1,111 +0,0 @@
ul.proposal-list {
clear: both;
width: 100%;
list-style: none;
li {
display: grid;
grid-template-columns: auto 5rem;
grid-row-gap: 0.5rem;
padding: 1rem 1.2rem;
background-color: rgba(255,255,255,0.1);
font-size: 1.2rem;
border-bottom: 1px solid rgba(255,255,255,0.2);
&:first-of-type {
border-top: 1px solid rgba(255,255,255,0.2);
}
p {
align-self: center;
margin: 0;
line-height: 2rem;
&.kredits-amount, &.voting {
text-align: right;
}
&.description {
grid-column-start: span 2;
}
&.voting {
grid-column-start: span 2;
}
}
span {
}
.description {
line-height: 1.4em;
font-size: 1rem;
}
.category {
color: $blue;
padding-right: 0.2rem;
&.community { color: $red; }
&.dev { color: $pink; }
&.design { color: $yellow; }
&.docs { color: $green; }
&.ops { color: $purple; }
}
.amount {
font-weight: 500;
}
.symbol {
font-size: 1rem;
font-weight: 500;
padding-left: 0.2rem;
}
.recipient {
font-weight: 500;
}
.votes {
font-size: 1rem;
color: $primary-color;
margin-right: 0.5rem;
}
}
}
@media (min-width: 550px) {
ul.proposal-list {
li {
grid-template-columns: auto 10rem;
grid-row-gap: 0.5rem;
p {
&.kredits-amount, &.voting {
text-align: right;
}
}
&.unconfirmed {
p {
&.kredits-amount, &.voting {
text-align: right;
}
&.description {
grid-column-start: span 1;
}
&.voting {
grid-column-start: span 1;
}
}
}
.description {
}
}
}
}
+1 -1
View File
@@ -1 +1 @@
{{loading-spinner}} <LoadingSpinner />
+2 -2
View File
@@ -1,6 +1,6 @@
<header id="topbar"> <header id="topbar">
<h1>{{link-to "Kosmos Kredits" "dashboard"}}</h1> <h1><LinkTo @route="dashboard">Kosmos Kredits</LinkTo></h1>
{{topbar-account-panel}} <TopbarAccountPanel />
</header> </header>
{{outlet}} {{outlet}}
View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Before

Width:  |  Height:  |  Size: 703 B

After

Width:  |  Height:  |  Size: 703 B

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 750 B

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

+3 -1
View File
@@ -6,7 +6,9 @@
</header> </header>
<div class="content"> <div class="content">
{{add-contribution contributors=sortedContributors save=(action "save")}} <AddContribution @contributors={{this.sortedContributors}}
@attributes={{this.model.params}}
@save={{action "save"}} />
</div> </div>
</section> </section>
+4 -2
View File
@@ -2,11 +2,13 @@
<section id="add-contribution"> <section id="add-contribution">
<header> <header>
<h2>Re-submit contribution #{{model.id}}</h2> <h2>Re-submit contribution #{{this.model.id}}</h2>
</header> </header>
<div class="content"> <div class="content">
{{add-contribution attributes=attributes contributors=sortedContributors save=(action "save")}} <AddContribution @attributes={{this.attributes}}
@contributors={{this.sortedContributors}}
@save={{action "save"}} />
</div> </div>
</section> </section>
+1 -1
View File
@@ -6,7 +6,7 @@
</header> </header>
<div class="content"> <div class="content">
{{add-contributor attributes=attributes save=(action "save")}} <AddContributor @attributes={{this.attributes}} @save={{action "save"}} />
</div> </div>
</section> </section>
+1 -1
View File
@@ -6,7 +6,7 @@
</header> </header>
<div class="content"> <div class="content">
{{add-contributor save=(action "save")}} <AddContributor @save={{action "save"}} />
</div> </div>
</section> </section>
+41 -29
View File
@@ -1,42 +1,44 @@
{{#if showIntroText}} {{#if this.showIntroText}}
<div id="intro" class={{if showDetailsPane "with-details"}}> <div id="intro" class={{if this.showDetailsPane "with-details"}}>
<h2> <h2>
Welcome to the contribution dashboard of the Welcome to the contribution dashboard of the
<a href="https://kosmos.org" target="_blank" rel="noopener">Kosmos</a> project! <a href="https://kosmos.org" target="_blank" rel="noreferrer noopener">Kosmos</a> project!
</h2> </h2>
<p> <p>
If you want to learn more about what the numbers mean and how this works, If you want to learn more about what the numbers mean and how this works,
check out the check out the
<a href="https://wiki.kosmos.org/Kredits" target="_blank" rel="noopener">Kredits documentation</a>. <a href="https://wiki.kosmos.org/Kredits" target="_blank" rel="noreferrer noopener">Kredits documentation</a>.
If you want to start earning kredits for your contributions, If you want to start earning kredits for your contributions,
{{link-to "create a contributor profile" "signup"}}. <LinkTo @route="signup">create a contributor profile</LinkTo>.
</p> </p>
</div> </div>
{{/if}} {{/if}}
<main id="dashboard" class={{if showDetailsPane "with-details"}}> <main id="dashboard" class={{if this.showDetailsPane "with-details"}}>
<div id="stats"> <div id="stats">
<section id="people"> <section id="people">
<header class="with-nav"> <header class="with-nav">
<h2>Contributors</h2> <h2>Contributors</h2>
{{#if kredits.hasAccounts}} {{#if this.kredits.hasAccounts}}
<nav> <nav>
{{link-to "add" "contributors.new" title="Add contributor profile" class="button small green"}} <LinkTo @route="contributors.new" @title="Add contributor profile" class="button small green">add</LinkTo>
</nav> </nav>
{{/if}} {{/if}}
</header> </header>
<div class="content"> <div class="content">
{{contributor-list contributorList=kreditsToplist <ContributorList @contributorList={{this.kreditsToplist}}
showUnconfirmedKredits=showUnconfirmedKredits @showUnconfirmedKredits={{this.showUnconfirmedKredits}}
selectedContributorId=selectedContributorId}} @selectedContributorId={{this.selectedContributorId}} />
<p class="stats"> <p class="stats">
<span class="number">{{await kredits.totalKreditsEarned}}</span> kredits confirmed and issued to <span class="number">{{await this.kredits.totalKreditsEarned}}</span> kredits confirmed and issued to
<span class="number">{{contributorsWithKredits.length}}</span> contributors <span class="number">{{this.contributorsWithKredits.length}}</span> contributors
</p> </p>
<p class="stats"> <p class="stats">
{{input type="checkbox" id="hide-unnconfirmed-kredits" checked=showUnconfirmedKredits}} <Input id="hide-unnconfirmed-kredits"
@type="checkbox"
@checked={{this.showUnconfirmedKredits}} />
<label for="hide-unnconfirmed-kredits">Show unconfirmed kredits in toplist</label> <label for="hide-unnconfirmed-kredits">Show unconfirmed kredits in toplist</label>
</p> </p>
</div> </div>
@@ -47,30 +49,36 @@
<h2>Contributions by type</h2> <h2>Contributions by type</h2>
</header> </header>
<div class="content"> <div class="content">
{{chart-contributions-by-type contributions=contributions}} <ChartContributionsByType @contributions={{this.contributions}} />
</div> </div>
</section> </section>
</div> </div>
<div id="contributions"> <div id="contributions">
{{#if contributionsUnconfirmed}} {{#if this.contributionsUnconfirmed}}
<section id="contributions-unconfirmed"> <section id="contributions-unconfirmed">
<header class="with-nav"> <header class="with-nav">
<h2>Latest Contributions</h2> <h2>Latest Contributions</h2>
<nav> <nav>
<button {{action "toggleQuickFilterUnconfirmed"}} class="small {{if showQuickFilterUnconfirmed "active"}}">filter</button> <button type="button"
{{#if kredits.hasAccounts}} onclick={{action "toggleQuickFilterUnconfirmed"}}
{{link-to "add" "contributions.new" title="Submit a contribution" class="button small green"}} class="small {{if this.showQuickFilterUnconfirmed "active"}}">
filter
</button>
{{#if this.kredits.hasAccounts}}
<LinkTo @route="contributions.new"
@title="Submit a contribution"
class="button small green">add</LinkTo>
{{/if}} {{/if}}
</nav> </nav>
</header> </header>
<div class="content"> <div class="content">
{{!-- TODO: We need a better naming for kredits.hasAccounts --}} {{!-- TODO: We need a better naming for kredits.hasAccounts --}}
{{contribution-list contributions=contributionsUnconfirmedSorted <ContributionList @contributions={{this.contributionsUnconfirmedSorted}}
vetoContribution=(action "vetoContribution") @vetoContribution={{action "vetoContribution"}}
contractInteractionEnabled=kredits.hasAccounts @contractInteractionEnabled={{this.kredits.hasAccounts}}
selectedContributionId=selectedContributionId @selectedContributionId={{this.selectedContributionId}}
showQuickFilter=showQuickFilterUnconfirmed}} @showQuickFilter={{this.showQuickFilterUnconfirmed}} />
</div> </div>
</section> </section>
{{/if}} {{/if}}
@@ -79,14 +87,18 @@
<header class="with-nav"> <header class="with-nav">
<h2>Confirmed Contributions</h2> <h2>Confirmed Contributions</h2>
<nav> <nav>
<button {{action "toggleQuickFilterConfirmed"}} class="small {{if showQuickFilterConfirmed "active"}}">filter</button> <button type="button"
onclick={{action "toggleQuickFilterConfirmed"}}
class="small {{if this.showQuickFilterConfirmed "active"}}">
filter
</button>
</nav> </nav>
</header> </header>
<div class="content"> <div class="content">
{{contribution-list contributions=contributionsConfirmedSorted <ContributionList @contributions={{this.contributionsConfirmedSorted}}
vetoContribution=(action "vetoContribution") @vetoContribution={{action "vetoContribution"}}
selectedContributionId=selectedContributionId @selectedContributionId={{this.selectedContributionId}}
showQuickFilter=showQuickFilterConfirmed}} @showQuickFilter={{this.showQuickFilterConfirmed}} />
</div> </div>
</section> </section>
</div> </div>
+20 -20
View File
@@ -1,8 +1,8 @@
<section id="contribution-details" class={{if model.vetoed "vetoed"}}> <section id="contribution-details" class={{if this.model.vetoed "vetoed"}}>
<header class="with-nav"> <header class="with-nav">
<h2>Contribution #{{model.id}}</h2> <h2>Contribution #{{this.model.id}}</h2>
<nav> <nav>
<span class="amount">{{model.amount}}</span>&nbsp; <span class="amount">{{this.model.amount}}</span>&nbsp;
<span class="symbol">₭S</span> <span class="symbol">₭S</span>
</nav> </nav>
</header> </header>
@@ -10,39 +10,39 @@
<div class="content"> <div class="content">
<p class="who-what-when"> <p class="who-what-when">
<span class="contributor"> <span class="contributor">
{{user-avatar contributor=model.contributor}} <UserAvatar @contributor={{this.model.contributor}} />
{{link-to model.contributor.name "dashboard.contributors.show" model.contributor}} <LinkTo @route="dashboard.contributors.show" @model={{this.model.contributor}}>{{this.model.contributor.name}}</LinkTo>
</span> </span>
contributed contributed
<span class="date" title={{model.iso8601Date}}>{{moment-from model.iso8601Date}}</span>: <span class="date" title={{this.model.iso8601Date}}>{{moment-from this.model.iso8601Date}}</span>:
</p> </p>
<h3>{{model.description}}</h3> <h3>{{this.model.description}}</h3>
<p> <p>
Kind: {{model.kind}} Kind: {{this.model.kind}}
<br>Status: {{contribution-status model}} <br>Status: {{contribution-status this.model}}
</p> </p>
{{#if model.url}} {{#if this.model.url}}
<p> <p>
<a href={{model.url}} <a href={{this.model.url}}
title={{model.description}} title={{this.model.description}}
class="button" class="button"
target="_blank" target="_blank"
rel="noopener"> rel="noopener noreferrer">
Open URL Open URL
</a> </a>
</p> </p>
{{/if}} {{/if}}
{{#if model.vetoed}} {{#if this.model.vetoed}}
<div class="hint vetoed"> <div class="hint vetoed">
<div class="icon"> <div class="icon">
{{icon-warning}} <IconWarning />
</div> </div>
<p> <p>
This contribution has been vetoed, meaning no This contribution has been vetoed, meaning no
kredits will be issued. kredits will be issued.
</p> </p>
<p> <p>
{{link-to "Re-submit contribution …" "contributions.resubmit" model class="button small green"}} <LinkTo @route="contributions.resubmit" @model={{this.model}} class="button small green">Re-submit contribution …</LinkTo>
</p> </p>
</div> </div>
{{/if}} {{/if}}
@@ -50,10 +50,10 @@
<div class="actions"> <div class="actions">
<p> <p>
{{link-to "Copy & edit as new" "contributions.resubmit" model class="button small"}} <LinkTo @route="contributions.resubmit" @model={{this.model}} class="button small">Copy & edit as new</LinkTo>
{{#if model.ipfsHash}} {{#if this.model.ipfsHash}}
<a href="{{ipfsGatewayUrl}}/{{model.ipfsHash}}" <a href="{{this.ipfsGatewayUrl}}/{{this.model.ipfsHash}}"
class="button small" target="_blank" rel="noopener"> class="button small" target="_blank" rel="noopener noreferrer">
Inspect IPFS data Inspect IPFS data
</a> </a>
{{/if}} {{/if}}
+17 -12
View File
@@ -1,36 +1,41 @@
<section id="contributor-profile"> <section id="contributor-profile">
<header> <header>
{{user-avatar contributor=model size="medium"}} <UserAvatar @contributor={{this.model}} @size="medium" />
</header> </header>
<div class="content"> <div class="content">
<h2>{{model.name}}</h2> <h2>{{this.model.name}}</h2>
<p class="role">{{roleName}}</p> <p class="role">{{this.roleName}}</p>
<ul class="external-accounts"> <ul class="external-accounts">
{{#each model.accounts as |account|}} {{#each this.model.accounts as |account|}}
<li> <li>
{{external-account-link account=account}} <ExternalAccountLink @account={{account}} />
</li> </li>
{{/each}} {{/each}}
{{#if model.url}} {{#if this.model.url}}
<li> <li>
<a href={{model.url}} target="_blank" rel="noopener" title="Website"> <a href={{this.model.url}} target="_blank" rel="noopener noreferrer" title="Website">
<span class="site">Web</span> <span class="site">Web</span>
{{icon-web-globe}} <IconWebGlobe />
</a> </a>
</li> </li>
{{/if}} {{/if}}
</ul> </ul>
<div class="actions">
<p>
<LinkTo @route="contributions.new" @query={{hash contributorId=this.model.id}} class="button green">♥ Give kredits</LinkTo>
</p>
</div>
</div> </div>
<div class="actions"> <div class="actions">
<p> <p>
<a href="https://rinkeby.etherscan.io/address/{{model.account}}" class="button small" target="_blank" rel="noopener">Inspect Ethereum transactions</a> <a href="https://rinkeby.etherscan.io/address/{{this.model.account}}" class="button small" target="_blank" rel="noopener noreferrer">Inspect Ethereum transactions</a>
{{#if model.ipfsHash}} {{#if this.model.ipfsHash}}
<a href="{{ipfsGatewayUrl}}/{{model.ipfsHash}}" class="button small" target="_blank" rel="noopener">Inspect IPFS profile</a> <a href="{{this.ipfsGatewayUrl}}/{{this.model.ipfsHash}}" class="button small" target="_blank" rel="noopener noreferrer">Inspect IPFS profile</a>
{{/if}} {{/if}}
{{link-to "Edit profile" "contributors.edit" model class="button small"}} <LinkTo @route="contributors.edit" @model={{this.model}} class="button small">Edit profile</LinkTo>
</p> </p>
</div> </div>
</section> </section>
-10
View File
@@ -1,10 +0,0 @@
<section id="add-proposal">
<header>
<h2>Add Proposal</h2>
</header>
<div class="content">
{{add-proposal contributors=minedContributors save=(action "save")}}
</div>
</section>
+1 -1
View File
@@ -10,6 +10,6 @@
<a href="https://wiki.kosmos.org/Main_Page#Community_.2F_Getting_in_touch_.2F_Getting_involved">in one of our chat rooms</a>?. <a href="https://wiki.kosmos.org/Main_Page#Community_.2F_Getting_in_touch_.2F_Getting_involved">in one of our chat rooms</a>?.
</p> </p>
<p class="actions"> <p class="actions">
{{#link-to "dashboard" class="button small"}}Return to dashboard{{/link-to}} <LinkTo @route="dashboard" class="button small">Return to dashboard</LinkTo>
</p> </p>
</div> </div>
+5 -6
View File
@@ -6,19 +6,18 @@
Kredits allow you to take part in project governance, and to earn rewards for 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. your contributions. For both, you will need an Ethereum wallet/account.
</p> </p>
<form {{action "submit" on="submit"}}> <form>
<p> <p>
<label> <label>
Ethereum account:<br> Ethereum account:<br>
{{input type="text" value=ethAddress <Input @type="text" @value={{this.ethAddress}} placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4" class={{if this.isValidEthAccount "valid" ""}} />
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
class=(if isValidEthAccount "valid" "")}}
</label> </label>
</p> </p>
</form> </form>
<p class="actions"> <p class="actions">
<button disabled={{signupButtonDisabled}} <button disabled={{this.signupButtonDisabled}}
{{action "completeSignup"}}> onclick={{action "completeSignup"}}
type="button">
Complete my profile Complete my profile
</button> </button>
</p> </p>
+2 -2
View File
@@ -12,8 +12,8 @@
connecting one of the following accounts: connecting one of the following accounts:
</p> </p>
<p class="actions"> <p class="actions">
<button {{action "connectGithub"}} class="icon"> <button onclick={{action "connectGithub"}} class="icon" type="button">
{{icon-account-github-com}} <IconAccountGithubCom />
Connect GitHub Connect GitHub
</button> </button>
</p> </p>
+20
View File
@@ -0,0 +1,20 @@
{
"schemaVersion": "1.0.0",
"packages": [
{
"name": "ember-cli",
"version": "3.18.0",
"blueprints": [
{
"name": "app",
"outputRepo": "https://github.com/ember-cli/ember-new-output",
"codemodsSource": "ember-app-codemods-manifest@1",
"isBaseBlueprint": true,
"options": [
"--no-welcome"
]
}
]
}
]
}
+4 -1
View File
@@ -1,3 +1,6 @@
{ {
"jquery-integration": true "application-template-wrapper": false,
"default-async-observers": true,
"jquery-integration": false,
"template-only-glimmer-components": true
} }
+8627 -2577
View File
File diff suppressed because it is too large Load Diff
+39 -31
View File
@@ -1,6 +1,6 @@
{ {
"name": "kredits-web", "name": "kredits-web",
"version": "1.14.0", "version": "1.16.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",
@@ -11,12 +11,14 @@
"test": "tests" "test": "tests"
}, },
"scripts": { "scripts": {
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*",
"lint:hbs": "ember-template-lint .", "lint:hbs": "ember-template-lint .",
"lint:js": "eslint .", "lint:js": "eslint .",
"test": "ember test",
"start": "ember serve", "start": "ember serve",
"test": "npm-run-all lint:* test:*",
"test:ember": "ember test",
"start:local": "WEB3_PROVIDER_URL=http://localhost:7545 ember serve", "start:local": "WEB3_PROVIDER_URL=http://localhost:7545 ember serve",
"build": "ember build", "build": "ember build --environment=production",
"build-prod": "rm -rf release/* && ember build -prod --output-path release", "build-prod": "rm -rf release/* && ember build -prod --output-path release",
"preversion": "npm test", "preversion": "npm test",
"version": "npm run build-prod && git add release/", "version": "npm run build-prod && git add release/",
@@ -24,53 +26,59 @@
"deploy": "git push 5apps master" "deploy": "git push 5apps master"
}, },
"devDependencies": { "devDependencies": {
"@ember/jquery": "^0.6.0", "@ember/optional-features": "^1.3.0",
"@ember/optional-features": "^0.7.0", "@glimmer/component": "^1.0.0",
"@glimmer/tracking": "^1.0.0",
"babel-eslint": "^10.1.0",
"babel-preset-es2015": "^6.22.0", "babel-preset-es2015": "^6.22.0",
"babelify": "^7.3.0", "babelify": "^7.3.0",
"brfs": "^2.0.2", "brfs": "^2.0.2",
"broccoli-asset-rev": "^3.0.0", "broccoli-asset-rev": "^3.0.0",
"ember-ajax": "^5.0.0",
"ember-auto-import": "^1.5.3", "ember-auto-import": "^1.5.3",
"ember-awesome-macros": "0.41.0", "ember-awesome-macros": "0.41.0",
"ember-cli": "~3.10.1", "ember-cli": "~3.18.0",
"ember-cli-app-version": "^3.2.0", "ember-cli-app-version": "^3.2.0",
"ember-cli-babel": "^7.7.3", "ember-cli-babel": "^7.19.0",
"ember-cli-chart": "^3.4.0", "ember-cli-chart": "^3.6.0",
"ember-cli-dependency-checker": "^3.1.0", "ember-cli-dependency-checker": "^3.2.0",
"ember-cli-eslint": "^5.1.0", "ember-cli-htmlbars": "^4.3.1",
"ember-cli-htmlbars": "^3.0.1", "ember-cli-inject-live-reload": "^2.0.2",
"ember-cli-htmlbars-inline-precompile": "^2.1.0",
"ember-cli-inject-live-reload": "^1.8.2",
"ember-cli-moment-shim": "^3.7.1", "ember-cli-moment-shim": "^3.7.1",
"ember-cli-sass": "^7.2.0", "ember-cli-sass": "^10.0.1",
"ember-cli-sri": "^2.1.1", "ember-cli-sri": "^2.1.1",
"ember-cli-template-lint": "^1.0.0-beta.1", "ember-cli-uglify": "^3.0.0",
"ember-cli-uglify": "^2.1.0", "ember-export-application-global": "^2.0.1",
"ember-export-application-global": "^2.0.0", "ember-fetch": "^8.0.1",
"ember-flatpickr": "^2.14.0", "ember-flatpickr": "^2.16.2",
"ember-load-initializers": "^2.0.0", "ember-load-initializers": "^2.1.1",
"ember-macro-helpers": "0.17.0", "ember-macro-helpers": "0.17.0",
"ember-maybe-import-regenerator": "^0.1.6", "ember-maybe-import-regenerator": "^0.1.6",
"ember-moment": "^7.8.1", "ember-moment": "^7.8.1",
"ember-promise-helpers": "1.0.6", "ember-promise-helpers": "^1.0.9",
"ember-qunit": "^4.4.1", "ember-qunit": "^4.6.0",
"ember-resolver": "^5.0.1", "ember-resolver": "^8.0.0",
"ember-source": "~3.10.0", "ember-source": "~3.18.0",
"ember-template-lint": "^2.6.0",
"ember-truth-helpers": "github:jmurphyau/ember-truth-helpers#31a14373a31f1f82c77537720549b47a95c28e5f", "ember-truth-helpers": "github:jmurphyau/ember-truth-helpers#31a14373a31f1f82c77537720549b47a95c28e5f",
"eslint-plugin-ember": "^6.2.0", "eslint": "^7.0.0",
"eslint-plugin-node": "^9.0.1", "eslint-plugin-ember": "^8.4.0",
"ethers": "^4.0.27", "eslint-plugin-node": "^11.1.0",
"kosmos-schemas": "^2.0.0", "ethers": "^4.0.47",
"kosmos-schemas": "^2.1.0",
"kredits-contracts": "^5.5.0", "kredits-contracts": "^5.5.0",
"loader.js": "^4.7.0", "loader.js": "^4.7.0",
"ndjson": "github:hugomrdias/ndjson#feat/readable-stream3", "ndjson": "github:hugomrdias/ndjson#feat/readable-stream3",
"qunit-dom": "^0.8.4", "npm-run-all": "^4.1.5",
"qunit-dom": "^1.2.0",
"sass": "^1.26.5",
"transform-loader": "^0.2.4", "transform-loader": "^0.2.4",
"tv4": "^1.3.0", "tv4": "^1.3.0",
"web3-utils": "^1.0.0" "web3-utils": "^1.2.7"
}, },
"engines": { "engines": {
"node": "8.* || >= 10.*" "node": "10.* || >= 12"
},
"ember": {
"edition": "octane"
} }
} }
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
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
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
+5 -5
View File
@@ -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_JQUERY_INTEGRATION%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22kredits-web%22%2C%22version%22%3A%221.14.0%2B9c063b82%22%7D%2C%22browserify%22%3A%7B%22tests%22%3Atrue%2C%22transform%22%3A%5B%5B%22babelify%22%2C%7B%22presets%22%3A%5B%22es2015%22%5D%2C%22global%22%3Atrue%7D%5D%5D%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frinkeby.infura.io%2Fv3%2Fd4f788b7a6584f7db2fc3c268d4d09e9%22%2C%22web3RequiredNetwork%22%3A%22rinkeby%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%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%221.16.0%2B41cc37d3%22%7D%2C%22browserify%22%3A%7B%22tests%22%3Atrue%2C%22transform%22%3A%5B%5B%22babelify%22%2C%7B%22presets%22%3A%5B%22es2015%22%5D%2C%22global%22%3Atrue%7D%5D%5D%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frinkeby.infura.io%2Fv3%2Fd4f788b7a6584f7db2fc3c268d4d09e9%22%2C%22web3RequiredNetwork%22%3A%22rinkeby%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%22exportApplicationGlobal%22%3Afalse%7D" />
<link integrity="" rel="stylesheet" href="/assets/vendor-179cf27a97ea5bbb0ce72403a401cc8c.css"> <link integrity="" rel="stylesheet" href="/assets/vendor-ca96b2e19fc9f356e3dbad90c9f3f323.css">
<link integrity="" rel="stylesheet" href="/assets/kredits-web-29c0dd0eeecfecc400ab5919e55a8362.css"> <link integrity="" rel="stylesheet" href="/assets/kredits-web-8440190dda6de1748075524fe140b4ee.css">
@@ -24,8 +24,8 @@
<body> <body>
<script src="/assets/vendor-21c31ba5343c7b72f638899d335a0531.js" integrity="sha256-5QKR4/TvbS9UoThtAlcyvj54wU+Bcn0hnM0FzjUbvfA= sha512-tHxWM5t9FYFz6DBnXuzWiIMPPW/gNwPaFDOdUL32cWvWcMfjyrhIEPM5I1D6+HQE1kXCEd64a+7UiMdU2hH5JQ==" ></script> <script src="/assets/vendor-5ebca0a713676bf484d729ec58e9d74b.js" integrity="sha256-K9BPrQzg0Nv83HSPUwk2n1hU8IOaceDf03EaU5LgblQ= sha512-stOJYOdJfiuzleqChwK9pNLCVMQwg9sZXUSboTsvtIixnRoQ285yS080rRX/GfcRd/eI0TEpPI0XKqvN56kzLA==" ></script>
<script src="/assets/kredits-web-5a80f454037be98f10b521243c18f375.js" integrity="sha256-/u89bvyhfTs5ADerxtWsWB50nJaU5f2a+n+n1GlkeT8= sha512-PcHQovpgVHkaTZkWjgwdOy3RSG1wl3C7V4825v6g/ArPoOhFtYSU6O33ne0aNUqoNObovg1SGI9QEgmmYn5dbw==" ></script> <script src="/assets/kredits-web-d376614e43d3edec456b90f7efdfedf4.js" integrity="sha256-ZUj9gy+521ioE0n+gKl53UrRqVALwY7YTOonD2SjZfg= sha512-0G4MUqxkZ+yazboR03+jfA9BRKoyKh2/IgG9iAVttTfVZRyMTHqiFnGlG00KY72H0y2jVamQtgY6UpLgAohGLg==" ></script>
</body> </body>
+3 -1
View File
@@ -1,3 +1,5 @@
'use strict';
module.exports = { module.exports = {
test_page: 'tests/index.html?hidepassed', test_page: 'tests/index.html?hidepassed',
disable_watching: true, disable_watching: true,
@@ -7,13 +9,13 @@ module.exports = {
launch_in_dev: [ launch_in_dev: [
'Chrome' 'Chrome'
], ],
browser_start_timeout: 120,
browser_args: { browser_args: {
Chrome: { Chrome: {
ci: [ ci: [
// --no-sandbox is needed when running Chrome inside a container // --no-sandbox is needed when running Chrome inside a container
process.env.CI ? '--no-sandbox' : null, process.env.CI ? '--no-sandbox' : null,
'--headless', '--headless',
'--disable-gpu',
'--disable-dev-shm-usage', '--disable-dev-shm-usage',
'--disable-software-rasterizer', '--disable-software-rasterizer',
'--mute-audio', '--mute-audio',
@@ -1,18 +0,0 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | add proposal', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });
await render(hbs`{{add-proposal}}`);
assert.dom('.actions a').hasText('Back');
});
});
@@ -6,7 +6,7 @@ import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | chart-contributions-by-type', function(hooks) { module('Integration | Component | chart-contributions-by-type', function(hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
let proposals = [ let contributions = [
{ kind: 'dev', amount: 500 }, { kind: 'dev', amount: 500 },
{ kind: 'dev', amount: 1500 }, { kind: 'dev', amount: 1500 },
{ kind: 'ops', amount: 1500 }, { kind: 'ops', amount: 1500 },
@@ -20,9 +20,9 @@ module('Integration | Component | chart-contributions-by-type', function(hooks)
]; ];
test('it renders', async function(assert) { test('it renders', async function(assert) {
this.set('proposals', proposals); this.set('contributions', contributions);
await render(hbs`{{chart-contributions-by-type contributions=proposals}}`); await render(hbs`{{chart-contributions-by-type contributions=contributions}}`);
assert.dom(this.element).hasText(''); assert.dom(this.element).hasText('');
}); });
@@ -1,18 +0,0 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | proposal list', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });
await render(hbs`{{proposal-list}}`);
assert.dom('*').hasText('');
});
});
@@ -29,7 +29,7 @@ module('Integration | Component | topbar-account-panel', function(hooks) {
}); });
await render(hbs`<TopbarAccountPanel />`); await render(hbs`<TopbarAccountPanel />`);
assert.equal(this.element.textContent.trim(), 'Dorian Nakamoto'); assert.dom(this.element).hasText('Dorian Nakamoto');
service.set('currentUser.isCore', true); service.set('currentUser.isCore', true);
await render(hbs`<TopbarAccountPanel />`); await render(hbs`<TopbarAccountPanel />`);
@@ -0,0 +1,41 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import moment from 'moment';
module('Unit | Component | add-contribution', function(hooks) {
setupTest(hooks);
test('it exists', function(assert) {
let component = this.owner.factoryFor('component:add-contribution').create();
assert.ok(component);
});
test('default attributes', function(assert) {
let component = this.owner.factoryFor('component:add-contribution').create();
['contributorId', 'kind', 'amount', 'description', 'url', 'details'].forEach(a => {
assert.equal(component.attributes[a], null, `sets the default ${a} attribute`);
assert.equal(component.get(a), null, `sets the ${a} property`);
});
assert.ok(moment.isDate(component.attributes.date), 'sets the default date attribute');
assert.ok(moment.isDate(component.date), 'sets the default date');
});
test('override default attributes', function(assert) {
let component = this.owner.factoryFor('component:add-contribution').create({
attributes: { contributorId: '1' }
});
assert.equal(component.contributorId, '1', `overrides the default property`);
['kind', 'amount', 'description', 'url', 'details'].forEach(a => {
assert.equal(component.attributes[a], null, `sets the default ${a} attribute`);
assert.equal(component.get(a), null, `sets the ${a} property`);
});
assert.ok(moment.isDate(component.attributes.date), 'sets the default date attribute');
assert.ok(moment.isDate(component.date), 'sets the default date');
});
});
@@ -1,12 +0,0 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Controller | proposals/new', function(hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function(assert) {
let controller = this.owner.lookup('controller:proposals/new');
assert.ok(controller);
});
});
-8
View File
@@ -1,8 +0,0 @@
// import { moduleFor, test } from 'ember-qunit';
//
// moduleFor('model:proposal', 'Unit | Model | proposal');
//
// test('contributor relation', function(assert) {
// // TODO: Test contributor relation
// assert.ok(true);
// });
-71
View File
@@ -1,71 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg15"
version="1.1"
viewBox="0 0 60 60"
height="60px"
width="60px">
<metadata
id="metadata19">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Warning</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<!-- Generator: Sketch 3.2.2 (9983) - http://www.bohemiancoding.com/sketch -->
<title
id="title2">Warning</title>
<desc
id="desc4">Created with Sketch.</desc>
<defs
id="defs6" />
<g
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:1"
sketch:type="MSPage"
id="stroked">
<g
style="stroke:#535353;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"
transform="translate(-479,-238)"
sketch:type="MSLayerGroup"
id="Transport">
<g
sketch:type="MSShapeGroup"
transform="translate(482,244)"
id="Warning">
<a
transform="translate(0,2)"
id="a4529">
<polygon
id="Triangle-58"
points="0.15321248,44 27,0 53.846787,44 " />
</a>
<rect
height="21"
width="4"
y="13"
x="25"
id="Rectangle-1700" />
<a
transform="translate(0,2)"
id="a4532">
<circle
id="Oval-1484"
cx="27"
cy="38"
r="2" />
</a>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB