diff --git a/app/components/contribution-list/component.js b/app/components/contribution-list/component.js index f85da1d..edb7efe 100644 --- a/app/components/contribution-list/component.js +++ b/app/components/contribution-list/component.js @@ -1,9 +1,53 @@ import Component from '@ember/component'; +import { computed } from '@ember/object'; +import { sort } from '@ember/object/computed'; +import { isPresent } from '@ember/utils'; +import { inject as service } from '@ember/service'; export default Component.extend({ - tagName: 'ul', - classNames: ['contribution-list'], + tagName: 'div', + classNames: ['contributions'], + + showQuickFilter: false, + hideSmallContributions: false, + contributorId: null, + contributionKind: null, + + kredits: service(), + + contributorsSorting: Object.freeze(['name:asc']), + contributors: sort('kredits.contributors', 'contributorsSorting'), + + contributorsActive: computed('contributors.[]', 'contributions', function() { + let activeIds = this.contributions.mapBy('contributorId') + .map(id => id.toString()) + .uniq(); + return this.contributors.filter(c => { + return activeIds.includes(c.id.toString()); + }); + }), + + contributionKinds: computed('contributions.[]', function() { + return this.contributions.mapBy('kind').uniq(); + }), + + contributionsFiltered: computed('contributions.[]', 'hideSmallContributions', 'contributorId', 'contributionKind', function() { + return this.contributions.filter(c => { + let included = true; + + if (this.hideSmallContributions && + c.amount <= 500) { included = false; } + + if (isPresent(this.contributorId) && + c.contributorId.toString() !== this.contributorId.toString()) { included = false; } + + if (isPresent(this.contributionKind) && + c.kind !== this.contributionKind) { included = false; } + + return included; + }); + }), actions: { diff --git a/app/components/contribution-list/template.hbs b/app/components/contribution-list/template.hbs index 29a5760..a654f7b 100644 --- a/app/components/contribution-list/template.hbs +++ b/app/components/contribution-list/template.hbs @@ -1,25 +1,58 @@ -{{#each contributions as |contribution|}} -
  • -

    - {{user-avatar contributor=contribution.contributor}} - ({{contribution.kind}}) - - {{#if contribution.url}} - {{contribution.description}} - {{else}} - {{contribution.description}} - {{/if}} - +{{#if showQuickFilter}} +

    +

    + + + + +

    -

    - {{contribution.amount}}₭S -

    - {{#unless contribution.vetoed}} - {{#unless (is-confirmed-contribution contribution)}} -

    - -

    +
    +{{/if}} + + \ No newline at end of file diff --git a/app/controllers/index.js b/app/controllers/index.js index 20fc370..5bf9a5a 100644 --- a/app/controllers/index.js +++ b/app/controllers/index.js @@ -25,6 +25,9 @@ export default Controller.extend({ showUnconfirmedKredits: true, hideUnconfirmedKredits: not('showUnconfirmedKredits'), + showQuickFilterUnconfirmed: false, + showQuickFilterConfirmed: false, + actions: { vetoContribution (contributionId) { @@ -37,6 +40,14 @@ export default Controller.extend({ this.kredits.vote(proposalId).then(transaction => { console.debug('[controllers:index] Vote submitted to Ethereum blockhain: '+transaction.hash); }); + }, + + toggleQuickFilterUnconfirmed () { + this.toggleProperty('showQuickFilterUnconfirmed'); + }, + + toggleQuickFilterConfirmed () { + this.toggleProperty('showQuickFilterConfirmed'); } } diff --git a/app/helpers/capitalize-string.js b/app/helpers/capitalize-string.js new file mode 100644 index 0000000..47599a5 --- /dev/null +++ b/app/helpers/capitalize-string.js @@ -0,0 +1,7 @@ +import Helper from '@ember/component/helper'; + +export default Helper.extend({ + compute([string]) { + return string.charAt(0).toUpperCase() + string.slice(1); + } +}); diff --git a/app/styles/_buttons.scss b/app/styles/_buttons.scss index 41780e2..0e80146 100644 --- a/app/styles/_buttons.scss +++ b/app/styles/_buttons.scss @@ -11,10 +11,18 @@ button, input[type=submit], .button { cursor: pointer; letter-spacing: 0.1em; + &+button, &+input[type=submit], &+.button { + margin-left: 0.5rem; + } + &:hover { background-color: rgba(22, 21, 40, 0.8); } + &:active, &.active { + border-color: $primary-color; + } + &.small { font-size: 0.8rem; padding: 0.2rem 0.8rem; @@ -28,6 +36,9 @@ button, input[type=submit], .button { &:hover { background-color: rgba(40, 21, 21, 0.8); } + &:active, &.active { + border-color: $red; + } } &.green { @@ -38,5 +49,8 @@ button, input[type=submit], .button { &:hover { background-color: rgba(21, 40, 21, 0.8); } + &:active, &.active { + border-color: $green; + } } } diff --git a/app/styles/components/_contribution-list.scss b/app/styles/components/_contribution-list.scss index 0e0a938..53bbc32 100644 --- a/app/styles/components/_contribution-list.scss +++ b/app/styles/components/_contribution-list.scss @@ -6,6 +6,24 @@ main section { } } +.quick-filter { + font-size: 1.2rem; + margin-bottom: 2rem; + + p { + font-size: inherit; + padding: 0.2rem 0 0; + } + + label { + font-size: inherit; + + &+ label { + margin-left: 3.6rem; + } + } +} + ul.contribution-list { clear: both; width: 100%; diff --git a/app/templates/index.hbs b/app/templates/index.hbs index 58fc3f0..1ecc5f0 100644 --- a/app/templates/index.hbs +++ b/app/templates/index.hbs @@ -42,6 +42,7 @@

    Latest Contributions

    {{#if kredits.hasAccounts}} {{/if}} @@ -50,18 +51,23 @@ {{!-- TODO: We need a better naming for kredits.hasAccounts --}} {{contribution-list contributions=contributionsUnconfirmedSorted vetoContribution=(action "vetoContribution") - contractInteractionEnabled=kredits.hasAccounts}} + contractInteractionEnabled=kredits.hasAccounts + showQuickFilter=showQuickFilterUnconfirmed}} {{/if}}
    -
    +

    Confirmed Contributions

    +
    {{contribution-list contributions=contributionsConfirmedSorted - vetoContribution=(action "vetoContribution")}} + vetoContribution=(action "vetoContribution") + showQuickFilter=showQuickFilterConfirmed}}
    diff --git a/tests/fixtures/contributions.js b/tests/fixtures/contributions.js index 2fc2f13..c3a856a 100644 --- a/tests/fixtures/contributions.js +++ b/tests/fixtures/contributions.js @@ -3,15 +3,15 @@ import Model from 'kredits-web/models/contribution'; const items = []; const data = [ - { id: 1, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500 }, - { id: 2, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 5000 }, - { id: 3, contributorId: 2, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500 }, - { id: 4, contributorId: 2, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500 }, - { id: 5, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 5000 }, - { id: 6, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: true, amount: 500 }, - { id: 7, contributorId: 3, confirmedAtBlock: 2000, claimed: false, vetoed: false, amount: 5000 }, - { id: 8, contributorId: 1, confirmedAtBlock: 2000, claimed: false, vetoed: false, amount: 1500 }, - { id: 9, contributorId: 3, confirmedAtBlock: 2000, claimed: false, vetoed: true, amount: 1500 }, + { id: 1, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'dev' }, + { id: 2, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 5000, kind: 'ops' }, + { id: 3, contributorId: 2, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'ops' }, + { id: 4, contributorId: 2, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'docs' }, + { id: 5, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 5000, kind: 'design' }, + { id: 6, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: true, amount: 500, kind: 'dev' }, + { id: 7, contributorId: 3, confirmedAtBlock: 2000, claimed: false, vetoed: false, amount: 5000, kind: 'dev' }, + { id: 8, contributorId: 1, confirmedAtBlock: 2000, claimed: false, vetoed: false, amount: 1500, kind: 'community' }, + { id: 9, contributorId: 3, confirmedAtBlock: 2000, claimed: false, vetoed: true, amount: 1500, kind: 'docs' }, ]; data.forEach(attrs => items.push(Model.create(attrs))); diff --git a/tests/integration/components/contribution-list/component-test.js b/tests/integration/components/contribution-list/component-test.js index be94ef3..995ad69 100644 --- a/tests/integration/components/contribution-list/component-test.js +++ b/tests/integration/components/contribution-list/component-test.js @@ -1,17 +1,34 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render } from '@ember/test-helpers'; +import { click, fillIn, render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; +import contributors from '../../../fixtures/contributors'; +import contributions from '../../../fixtures/contributions'; module('Integration | Component | contribution-list', function(hooks) { setupRenderingTest(hooks); - test('it renders', async function(assert) { - // Set any properties with this.set('myProperty', 'value'); - // Handle any actions with this.set('myAction', function(val) { ... }); + test('it renders all contributions', async function(assert) { + this.set('fixtures', contributions); + await render(hbs`{{contribution-list contributions=fixtures}}`); - await render(hbs`{{contribution-list}}`); + assert.equal(this.element.querySelectorAll('li').length, 9); + }); - assert.equal(this.element.textContent.trim(), ''); + test('it renders filtered contributions', async function(assert) { + let service = this.owner.lookup('service:kredits'); + service.set('contributors', contributors); + + this.set('fixtures', contributions); + await render(hbs`{{contribution-list contributions=fixtures showQuickFilter=true}}`); + + await fillIn('.filter-contributor select', '1'); + assert.equal(this.element.querySelectorAll('li').length, 5, 'select contributor'); + + await click('.filter-contribution-size input'); + assert.equal(this.element.querySelectorAll('li').length, 4, 'hide small contributions'); + + await fillIn('.filter-contribution-kind select', 'dev'); + assert.equal(this.element.querySelectorAll('li').length, 1, 'select kind'); }); });