Skip to content

Instantly share code, notes, and snippets.

@eneuhauser
Last active April 26, 2016 18:57
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 eneuhauser/a45c1e62a20fba3d2e983d03ac56e2de to your computer and use it in GitHub Desktop.
Save eneuhauser/a45c1e62a20fba3d2e983d03ac56e2de to your computer and use it in GitHub Desktop.
Skill Manager
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
skillService: Ember.inject.service('skills'),
init: function() {
this._super.apply(this, arguments);
},
skills: function() {
return this.get('skillService').list();
}.property()
});
{{skill-manager model=skills}}
{{ outlet }}
import Ember from 'ember';
export default Ember.Component.extend({
store: Ember.inject.service('store'),
isFiltered: Ember.computed('filter', {
get() {
const filter = this.get('filter');
return filter && filter.length > 2;
}
}),
parents: Ember.computed('model', {
get() {
return this.get('store').peekAll('skill')
.filterBy('isRoot', true)
.map((skill) => toViewModel(skill, 0))
.sortBy('name');
}
}),
skills: Ember.computed('parents', {
get() {
return this.get('parents');
}
})
});
function toViewModel(skill, level) {
const childLevel = level + 1;
const children = skill.get('children').map((child) => toViewModel(child, childLevel)).sortBy('skill.name');
return new Ember.Object({
skill: skill,
level: level,
expanded: false,
children: children,
filter(query) {
const filtered = this.get('children').reduce(function(aggregator, child) {
return addAll(aggregator, child.filter(query));
}, Ember.A());
if(filtered.length || this.matches(query)) {
filtered.unshift(this);
}
return filtered;
},
matches(query) {
return matches(this.get('skill.name'), query);
},
matchesAny(query) {
if(this.matches(query)) { return true; }
return this.matchesChildren(query);
},
matchesChildren(query) {
return this.get('children').any(function(child) {
return child.matchesAny(query);
});
}
});
}
{{ input value=filter }}
<h1>Is Filtered = {{ isFiltered }}</h1>
<ul>
{{#each skills as |vm|}}
{{skill-manager.skill model=vm}}
{{/each}}
</ul>
import DS from 'ember-data';
const Skill = DS.Model.extend({
name: DS.attr('string'),
parent: DS.belongsTo('skill', { async: true, inverse: 'children' }),
children: DS.hasMany('skill', { async: true, inverse: 'parent' }),
orderedChildren: Ember.computed('children', {
get() {
return this.get('children').sortBy('name');
}
}),
isRoot: Ember.computed('parent', {
get() {
return !this.get('parent.id');
}
}),
hasChildren: Ember.computed('children', {
get() {
return this.get('children.length') > 0;
}
})
});
Skill.reopenClass({
FIXTURES: [
{ id: '1', name: 'Skill 1' }
]
});
export default Skill;
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'li',
expanded: Ember.computed('model', {
get() {
return this.get('model.skill.hasChildren');
}
}),
actions: {
toggle() {
const expanded = !this.get('model.expanded');
this.set('model.expanded', expanded);
if(!expanded) { return; }
},
// Collapse siblings
onExpand(skill) {
}
}
});
{{ model.skill.name }}
{{#if expanded}}
<ul>
{{#each model.children as |child|}}
{{ skill-manager.skill model=child }}
{{/each}}
</ul>
{{/if}}
import Ember from 'ember';
const FIXTURES = {
'Analytics': {},
'BI Tech': {},
'Content Management': {
'.NET': {
'Sitecore': {}
}
},
'Web Development': {
'JavaScript': {
'Angular': {}
}
}
};
export default Ember.Service.extend({
store: Ember.inject.service('store'),
init() {
const data = [];
iterate(FIXTURES);
this.get('store').pushPayload({ data: data });
function iterate(skills, parentId) {
var index = arguments.length > 1 ? parentId + 1 : 1;
for(var prop in skills) {
data.push(buildSkill(index, prop, parentId));
index = iterate(skills[prop], index);
}
return index;
}
},
list() {
return this.get('store').peekAll('skill');
}
});
function buildSkill(id, name, parentId) {
return addParent({
id: id,
type: 'skill',
attributes: {
name: name
}
}, parentId);
}
function addParent(skill, parentId) {
if(!parentId) { return skill; }
skill.relationships = {
parent: {
data: {
id: parentId,
type: 'skill'
}
}
};
return skill;
}
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
{
"version": "0.7.2",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": true,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.js",
"ember": "https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.5.0/ember.debug.js",
"ember-data": "https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/2.4.3/ember-data.js",
"ember-template-compiler": "https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.4.4/ember-template-compiler.js"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment