Merge pull request #134 from 67P/feature/quick_filter
Add quick filters
This commit was merged in pull request #134.
This commit is contained in:
@@ -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: {
|
||||
|
||||
|
||||
@@ -1,25 +1,58 @@
|
||||
{{#each contributions as |contribution|}}
|
||||
<li data-contribution-id={{contribution.id}} class="{{contribution-status contribution}} {{if contribution.vetoed "vetoed"}}">
|
||||
<p class="meta">
|
||||
<span class="recipient">{{user-avatar contributor=contribution.contributor}}</span>
|
||||
<span class="category {{contribution.kind}}">({{contribution.kind}})</span>
|
||||
<span class="title">
|
||||
{{#if contribution.url}}
|
||||
<a href={{contribution.url}} target="_blank" rel="noopener">{{contribution.description}}</a>
|
||||
{{else}}
|
||||
{{contribution.description}}
|
||||
{{/if}}
|
||||
</span>
|
||||
{{#if showQuickFilter}}
|
||||
<div class="quick-filter">
|
||||
<p>
|
||||
<label class="filter-contributor">
|
||||
Contributor:
|
||||
<select onchange={{action (mut contributorId) value="target.value"}}>
|
||||
<option value="" selected>all</option>
|
||||
{{#each contributorsActive as |contributor|}}
|
||||
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="filter-contribution-kind">
|
||||
Kind:
|
||||
<select onchange={{action (mut contributionKind) value="target.value"}}>
|
||||
<option value="" selected>all</option>
|
||||
{{#each contributionKinds as |kind|}}
|
||||
<option value={{kind}} selected={{eq contributionKind kind}}>{{capitalize-string kind}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="filter-contribution-size">
|
||||
{{input type="checkbox" checked=hideSmallContributions}}
|
||||
Hide small contributions
|
||||
</label>
|
||||
</p>
|
||||
<p class="kredits-amount">
|
||||
<span class="amount">{{contribution.amount}}</span><span class="symbol">₭S</span>
|
||||
</p>
|
||||
{{#unless contribution.vetoed}}
|
||||
{{#unless (is-confirmed-contribution contribution)}}
|
||||
<p class="voting">
|
||||
<button {{action "veto" contribution.id}} class="small danger">veto</button>
|
||||
</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<ul class="contribution-list">
|
||||
{{#each contributionsFiltered as |contribution|}}
|
||||
<li data-contribution-id={{contribution.id}} class="{{contribution-status contribution}} {{if contribution.vetoed "vetoed"}}">
|
||||
<p class="meta">
|
||||
<span class="recipient">{{user-avatar contributor=contribution.contributor}}</span>
|
||||
<span class="category {{contribution.kind}}">({{contribution.kind}})</span>
|
||||
<span class="title">
|
||||
{{#if contribution.url}}
|
||||
<a href={{contribution.url}} target="_blank" rel="noopener">{{contribution.description}}</a>
|
||||
{{else}}
|
||||
{{contribution.description}}
|
||||
{{/if}}
|
||||
</span>
|
||||
</p>
|
||||
<p class="kredits-amount">
|
||||
<span class="amount">{{contribution.amount}}</span><span class="symbol">₭S</span>
|
||||
</p>
|
||||
{{#unless contribution.vetoed}}
|
||||
{{#unless (is-confirmed-contribution contribution)}}
|
||||
<p class="voting">
|
||||
<button {{action "veto" contribution.id}} class="small danger">veto</button>
|
||||
</p>
|
||||
{{/unless}}
|
||||
{{/unless}}
|
||||
{{/unless}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import Helper from '@ember/component/helper';
|
||||
|
||||
export default Helper.extend({
|
||||
compute([string]) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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%;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<h2>Latest Contributions</h2>
|
||||
{{#if kredits.hasAccounts}}
|
||||
<nav>
|
||||
<button {{action "toggleQuickFilterUnconfirmed"}} class="small {{if showQuickFilterUnconfirmed "active"}}">filter</button>
|
||||
{{link-to "add" "contributions.new" title="Submit a contribution" class="button small green"}}
|
||||
</nav>
|
||||
{{/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}}
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
<section id="contributions-confirmed">
|
||||
<header>
|
||||
<header class="with-nav">
|
||||
<h2>Confirmed Contributions</h2>
|
||||
<nav>
|
||||
<button {{action "toggleQuickFilterConfirmed"}} class="small {{if showQuickFilterConfirmed "active"}}">filter</button>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="content">
|
||||
{{contribution-list contributions=contributionsConfirmedSorted
|
||||
vetoContribution=(action "vetoContribution")}}
|
||||
vetoContribution=(action "vetoContribution")
|
||||
showQuickFilter=showQuickFilterConfirmed}}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
Vendored
+9
-9
@@ -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)));
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user