Skip to content

Instantly share code, notes, and snippets.

@lvegerano
Last active May 7, 2020 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lvegerano/90fe45edf53f0bc35af90a4103d523da to your computer and use it in GitHub Desktop.
Save lvegerano/90fe45edf53f0bc35af90a4103d523da to your computer and use it in GitHub Desktop.
class-tracked-array
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class DataLoaderComponent extends Component {
@tracked filteredData = [];
data = [
{ tag_id: 1, title: 'Awesome 1', color_id: 4, artist: 'luis' },
{ tag_id: 2, title: 'Awesome 2', color_id: 3, artist: 'jaden' },
{ tag_id: 3, title: 'Awesome 3', color_id: 2, artist: 'gustavo' },
{ tag_id: 4, title: 'Awesome 4', color_id: 1, artist: 'jason' },
{ tag_id: 1, title: 'Awesome 5', color_id: 1, artist: 'justin' },
];
@action
getData() {
this.filteredData = this.data
.reduce((accum, r) => {
if (this.args.colorIds.length && this.args.tagIds.length) {
if (this.args.colorIds.includes(r.color_id) && this.args.tagIds.includes(r.tag_id)) {
accum.push(r);
}
} else if (this.args.colorIds.length) {
if (this.args.colorIds.includes(r.color_id)) {
accum.push(r);
}
} else if (this.args.tagIds.length) {
if (this.args.tagIds.includes(r.tag_id)) {
accum.push(r);
}
}
return accum;
}, [])
}
}
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class FilterBarPickerComponent extends Component {
@tracked showDropdown = false;
@action
select(item, evt) {
evt.stopPropagation();
this.args.onItemSelected?.(item.id);
}
@action
toggleDD() {
this.showDropdown = !this.showDropdown;
}
}
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class FilterBarComponent extends Component {
@tracked selectedFilters = [];
@tracked showDropdown = false;
get unselectedFilters() {
return (this.args.filterOptions || [])
.reduce((accum, filter) => {
const selectedFilter = this.selectedFilters.includes(filter);
if (selectedFilter) return accum;
accum.push(filter);
return accum;
}, []);
}
@action
addFilter(filter, dd) {
this.selectedFilters = [
...this.selectedFilters,
filter
];
this.showDropdown = false;
// dd.actions.close();
}
@action
toggleDD() {
this.showDropdown = !this.showDropdown;
}
}
import Controller from '@ember/controller';
export default class ApplicationController extends Controller {
appName = 'Ember Twiddle';
}
import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { setOwner, getOwner } from '@ember/application';
import { action } from '@ember/object';
class Option {
@service colors;
@service tags;
id;
qpName;
title;
@tracked selectedIds = [];
constructor(id) {
this.id = id;
}
get items() {
if (this.id === 'color') return this.colors.allColors;
if (this.id === 'tag') return this.tags.allTags;
return [];
}
get selected() {
console.log('filter selected running');
// I expect this to run when selectedIds updates
return this.items.filter(r => this.selectedIds.includes(r.id));
}
}
export default class HomeController extends Controller {
queryParams = [
{ colorIds: { type: 'array' } },
{ tagIds: { type: 'array' } }
];
// @tracked colorIds = [];
// @tracked tagIds = [];
@tracked _colorIds = [];
@tracked _tagIds = [];
get colorIds() {
return this._colorIds;
}
set colorIds(value) {
this._colorIds = value;
}
get tagIds() {
return this._tagIds;
}
set tagIds(value) {
this._tagIds = value;
}
constructor(){
super(...arguments);
this.colorOption = new Option('color');
setOwner(this.colorOption, getOwner(this));
this.colorOption.title = 'Colors';
this.colorOption.qpName = 'colorIds';
this.tagOption = new Option('tag');
setOwner(this.tagOption, getOwner(this));
this.tagOption.title = 'Tags';
this.tagOption.qpName = 'tagIds';
}
get filterOptions() {
console.log('buildign options')
// I expect this to run when I update the query params. It is not
this.colorOption.selectedIds = [...this.colorIds];
this.tagOption.selectedIds = [...this.tagIds];
return [
this.colorOption,
this.tagOption,
];
}
@action
toggleItemSelected(filterOption, id) {
const index = this[filterOption.qpName].indexOf(id);
if (index === -1) {
this[filterOption.qpName] = [
...this[filterOption.qpName],
id,
];
} else {
this[filterOption.qpName].splice(index, 1);
this[filterOption.qpName] = [...this[filterOption.qpName]];
}
}
}
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: 'none',
rootURL: config.rootURL
});
Router.map(function() {
this.route('home')
});
export default Router;
import Route from '@ember/routing/route';
export default Route.extend({
redirect() {
this.transitionTo('home');
}
});
import Route from '@ember/routing/route';
export default Route.extend({
});
import Service from '@ember/service';
export default class ColorsService extends Service{
allColors = [
{
id: 1,
name: 'gold',
hex: 'f6d186'
}, {
id: 2,
name: 'yellow',
hex: 'fcf7bb'
}, {
id: 3,
name: 'green',
hex: 'cbe2b0'
}, {
id: 4,
name: 'red',
hex: 'f19292'
},
];
}
import Service from '@ember/service';
export default class TagsService extends Service {
allTags = [
{
id: 1,
name: 'foo',
}, {
id: 2,
name: 'bar',
}, {
id: 3,
name: 'baz',
}, {
id: 4,
name: 'cool',
},
];
}
<h1>Welcome to {{this.appName}}</h1>
<br>
<br>
{{outlet}}
<br>
<br>
<div class="filtered-data"
{{did-insert this.getData}}
{{did-update this.getData @colorIds @tagIds}}
>
{{yield this.filteredData}}
</div>
<div>
<button {{on "click" this.toggleDD}}>
{{!-- As options are picke this should render --}}
{{#each @selectedItems as |item|}}
<span>{{item.name}}</span>
{{else}}
Add {{@name}} Filter
{{/each}}
</button>
{{#if this.showDropdown}}
<ul>
{{#each @list as |item|}}
<li {{on "click" (fn this.select item)}}>{{item.name}}</li>
{{/each}}
</ul>
{{/if}}
</div>
<div>
<h3>Selected Filters</h3>
{{#each this.selectedFilters as |item|}}
<FilterBarPicker
@name={{item.title}}
@selectedItems={{item.selected}}
@list={{item.items}}
@onItemSelected={{fn @onToggleItemSelected item}}
/>
{{/each}}
</div>
<hr>
<div>
<button {{on "click" this.toggleDD}}>Add Filter</button>
{{#if this.showDropdown}}
<ul>
{{#each this.unselectedFilters as |item|}}
<li {{on "click" (fn this.addFilter item)}}>{{item.title}}</li>
{{/each}}
</ul>
{{/if}}
</div>
<FilterBar
@filterOptions={{this.filterOptions}}
@onToggleItemSelected={{this.toggleItemSelected}}
/>
{{!-- uncommenting this makes it sorta work like WTF --}}
{{!--
{{#each this.filterOptions as |option|}}
<input type="hidden" value={{option.selectedIds}} />
{{/each}}
--}}
{
"version": "0.17.0",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": true,
"_APPLICATION_TEMPLATE_WRAPPER": false,
"_JQUERY_INTEGRATION": false
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.14.3",
"ember-template-compiler": "3.14.3",
"ember-testing": "3.14.3"
},
"addons": {
"@glimmer/component": "1.0.0",
"ember-basic-dropdown": "2.0.15"
},
"ember": {
"edition": "octane"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment