refactor: 💡 improve project filter UX
This commit is contained in:
7 files changed
+103
-20
No files matched your search
@@ -47,6 +47,10 @@ export default class BaseModel extends Model {
|
||||
})
|
||||
authorized_collection_actions;
|
||||
|
||||
get scopeModel() {
|
||||
const id = this.scopeID;
|
||||
return this.store.peekRecord('scope', id);
|
||||
}
|
||||
set scopeModel(model) {
|
||||
if (model) {
|
||||
const json = model.serialize();
|
||||
|
||||
@@ -13,8 +13,8 @@ module('Unit | Model | base', function (hooks) {
|
||||
assert.ok(model);
|
||||
});
|
||||
|
||||
test('it may have a scope fragment', function (assert) {
|
||||
assert.expect(1);
|
||||
test('it may have a scope fragment (and thus a scopeModel)', function (assert) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
store.push({
|
||||
data: {
|
||||
@@ -37,6 +37,7 @@ module('Unit | Model | base', function (hooks) {
|
||||
const scope = store.peekRecord('scope', 'o_1');
|
||||
const model = store.peekRecord('user', '123abc');
|
||||
assert.equal(model.scope.scope_id, scope.id);
|
||||
assert.equal(model.scopeModel.id, scope.id);
|
||||
});
|
||||
|
||||
test('it may accept a `scopeModel` for convenience, instead of a fragment', function (assert) {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { helper } from '@ember/component/helper';
|
||||
|
||||
const groupByReducer = (items, key) => {
|
||||
const obj = items.reduce((result, item) => {
|
||||
if (!result[item[key]]) result[item[key]] = { key: item[key], items: [] };
|
||||
result[item[key]].items.push(item);
|
||||
return result;
|
||||
}, {});
|
||||
// Convert object group to an array for iteration
|
||||
const arr = Object.keys(obj).map((key) => obj[key]);
|
||||
return arr;
|
||||
};
|
||||
|
||||
export default helper(function groupBy([items, key]) {
|
||||
const result = groupByReducer(items, key);
|
||||
return result;
|
||||
});
|
||||
@@ -81,7 +81,7 @@ export default class ScopesScopeProjectsSessionsRoute extends Route {
|
||||
* When this route is activated (entered), begin polling for changes.
|
||||
*/
|
||||
activate() {
|
||||
this.poller.perform();
|
||||
// this.poller.perform();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -95,15 +95,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
.rose-icon {
|
||||
margin-right: sizing.rems(xxs);
|
||||
margin-left: sizing.rems(xxs);
|
||||
}
|
||||
|
||||
.indent-label-1 {
|
||||
.rose-form-radio-label {
|
||||
.rose-form-radio-label,
|
||||
.rose-form-checkbox-label {
|
||||
padding-left: $indent;
|
||||
}
|
||||
}
|
||||
|
||||
.indent-label-2 {
|
||||
.rose-form-radio-label {
|
||||
padding-left: $indent + $icon-width;
|
||||
.rose-form-radio-label,
|
||||
.rose-form-checkbox-label {
|
||||
padding-left: $indent * 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,20 +59,44 @@
|
||||
@ignoreClickInside={{true}}
|
||||
as |dropdown|
|
||||
>
|
||||
<form.checkboxGroup
|
||||
@name={{filter.name}}
|
||||
@items={{filter.allowedValues}}
|
||||
@selectedItems={{filter.selectedValue}}
|
||||
@onChange={{route-action 'filterBy' filter.name}}
|
||||
as |group|
|
||||
>
|
||||
<dropdown.item>
|
||||
<group.checkbox
|
||||
@label={{group.item.displayName}}
|
||||
value={{group.item}}
|
||||
/>
|
||||
</dropdown.item>
|
||||
</form.checkboxGroup>
|
||||
<ul>
|
||||
{{#with
|
||||
(group-by filter.allowedValues 'scopeModel')
|
||||
as |groups|
|
||||
}}
|
||||
{{#each groups as |groupedItems|}}
|
||||
<li>
|
||||
<dropdown.item>
|
||||
<Rose::Icon
|
||||
@name='flight-icons/svg/org-16'
|
||||
@size='medium'
|
||||
/>
|
||||
{{groupedItems.key.displayName}}
|
||||
</dropdown.item>
|
||||
<ul class='indent-label-2'>
|
||||
<form.checkboxGroup
|
||||
@name={{filter.name}}
|
||||
@items={{groupedItems.items}}
|
||||
@selectedItems={{filter.selectedValue}}
|
||||
@onChange={{route-action 'filterBy' filter.name}}
|
||||
as |group|
|
||||
>
|
||||
<li>
|
||||
<dropdown.item>
|
||||
<group.checkbox
|
||||
@label={{group.item.displayName}}
|
||||
value={{group.item}}
|
||||
/>
|
||||
</dropdown.item>
|
||||
</li>
|
||||
</form.checkboxGroup>
|
||||
</ul>
|
||||
</li>
|
||||
{{/each}}
|
||||
{{/with}}
|
||||
</ul>
|
||||
|
||||
{{! }}
|
||||
</Rose::Dropdown>
|
||||
{{/with}}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, findAll } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Helper | group-by', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it renders', async function (assert) {
|
||||
this.set('inputValue', [
|
||||
{ group: 'a', id: '1' },
|
||||
{ group: 'a', id: '2' },
|
||||
{ group: 'b', id: '3' },
|
||||
{ group: 'b', id: '4' },
|
||||
{ group: 'c', id: '5' },
|
||||
{ group: 'c', id: '6' },
|
||||
]);
|
||||
|
||||
await render(hbs`
|
||||
<ul>
|
||||
{{#each (group-by this.inputValue 'group') as |group|}}
|
||||
<li>{{group.key}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
`);
|
||||
|
||||
assert.equal(findAll('li').length, 3);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user