Skip to content

Instantly share code, notes, and snippets.

@onechiporenko
Last active June 14, 2019 08:25
Show Gist options
  • Save onechiporenko/918153a68f768b7a17c97ddd849dcd61 to your computer and use it in GitHub Desktop.
Save onechiporenko/918153a68f768b7a17c97ddd849dcd61 to your computer and use it in GitHub Desktop.
Table settings from query params (v2.3.0)
import Ember from 'ember';
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
host: 'https://api.github.com',
namespace: 'search/repositories',
query(store, b, query) {
const url = `${this.get('host')}/${this.get('namespace')}`;
let q = 'language:javascript';
const _query = Object.assign({}, query);
if (_query.search) {
q = `${q} ${_query.search}`;
delete _query.search;
}
if (_query.order) {
_query.order = _query.order.toLowerCase();
}
['stars', 'forks', 'user'].forEach(propertyName => {
if (_query[propertyName]) {
q = `${q} ${propertyName}:${_query[propertyName]}`;
delete _query[propertyName];
}
});
_query.q = q;
store.serializerFor('repo').set('pageSize', query.per_page);
return this.ajax(url, 'GET', {data: _query});
}
});
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Table settings from query params'
});
import Ember from 'ember';
import Bs4Theme from 'app/themes/bootstrap4';
const {get, computed} = Ember;
export default Ember.Controller.extend({
queryParams: ['page', 'per_page', 'search', 'hidden', 'sort', 'order', 'sorted', 'filters'],
page: 1,
per_page: 10,
search: '',
hidden: '',
sort: '',
order: 'desc',
sorted: '',
filters: '',
themeInstance: Bs4Theme.create({
table: 'table table-striped table-sm',
buttonDefaultSmall: 'btn btn-secondary'
}),
columns: [
{propertyName: 'name', disableSorting: true, disableFiltering: true},
{propertyName: 'owner.login', title: 'Owner', disableSorting: true, filteredBy: 'user'},
{propertyName: 'stargazers_count', title: 'Stars', sortedBy: 'stars', filterWithSelect: true, predefinedFilterOptions: ['>0', '0..10', '11..50', '51..100', '100..500', '>500'], filteredBy: 'stars'},
{propertyName: 'forks_count', title: 'Forks', filteredBy: 'forks', filterWithSelect: true, predefinedFilterOptions: ['>0', '0..10', '11..50', '51..100', '100..500', '>500']},
{propertyName: 'open_issues_count', title: 'Open Issues', disableSorting: true}
],
filterQueryParameters: {
pageSize: 'per_page',
page: 'page',
sort: 'sort',
sortDirection: 'order',
globalFilter: 'search'
},
actions: {
displayAction(d) {
const sorted = d.columns.find(_ => _.sorting !== 'none');
if (sorted) {
this.setProperties({
sort: sorted.sortField,
order: sorted.sorting,
sorted: d.columns.indexOf(sorted)
});
}
else {
this.setProperties({
sorted: '',
order: 'desc',
sort: ''
});
}
const filters = [];
d.columns.forEach((c, i) => {
if (c.filterString) {
filters.pushObject(`${i}:${c.filterField}:${c.filterString}`);
}
});
this.setProperties({
page: get(d, 'currentPageNumber'),
per_page: get(d, 'pageSize'),
search: get(d, 'filterString'),
filters: filters.join(',')
});
},
visibilityAction(d) {
const hidden = [];
d.forEach((c, i) => {
if (c.isHidden) {
hidden.pushObject(i);
}
});
this.set('hidden', hidden);
}
}
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
export default Model.extend({
name: attr('string'),
full_name: attr('string'),
html_url: attr('string'),
description: attr('string'),
fork: attr('boolean'),
owner: belongsTo('user'),
stargazers_count: attr('number'),
language: attr('string'),
forks_count: attr('number'),
open_issues_count: attr('number')
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
export default Model.extend({
login: attr('string'),
avatar_url: attr('string'),
url: attr('string'),
html_url: attr('string'),
type: attr('string'),
site_admin: attr('boolean')
});
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: 'none',
rootURL: config.rootURL
});
Router.map(function() {
this.route('table');
});
export default Router;
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel() {
this.transitionTo('table', {queryParams: {search: 'ember', page: 2, per_page: 25, hidden: '4', sort: 'stars', sorted: '2', filters: '2:stars:>0'}});
}
});
import Ember from 'ember';
export default Ember.Route.extend({
queryParams: {
per_page: {refreshModel: true},
page: {refreshModel: true},
search: {refreshModel: true},
sort: {refreshModel: true},
order: {refreshModel: true},
filters: {refreshModel: true}
},
hidden: '',
order: '',
sorted: '',
filters: '',
model(qp) {
const {page, per_page, search, sort, order, sorted, filters} = qp;
const query = {page, per_page, search};
filters.split(',').map(f => {
const [id, prop, val] = f.split(':');
query[prop] = val;
});
if (sort && sorted) {
query.sort = sort;
query.order = order;
this.setProperties({sorted, order});
}
this.setProperties({
hidden: qp.hidden,
filters
});
return this.get('store').query('repo', query);
},
setupController(controller) {
this._super(...arguments);
const columns = controller.get('columns');
this.get('hidden').split(',').map(index => columns[index].isHidden = true);
const sorted = this.get('sorted');
const order = this.get('order');
if (sorted && order) {
columns[sorted].sortDirection = order;
columns[sorted].sortPrecedence = 1;
}
const filters = this.get('filters');
if (filters) {
filters.split(',').forEach(f => {
const [index, prop, val] = f.split(':');
columns[index].filterString = val;
});
}
controller.set('columns', columns);
}
});
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
pageSize: 10,
_mapIncluded(data, type) {
const clb = item => ({
id: item.id,
type,
attributes: item
});
return Ember.isArray(data) ? data.map(clb) : clb(data);
},
normalizeQueryResponse(a, b, payload) {
const included = [];
const newPayload = {
data: payload.items.map(item => {
const itemData = {
id: item.id,
type: 'repo',
attributes: item,
relationships: {
owner: {
data: {
id: item.owner.id,
type: 'user'
}
}
}
};
included.pushObject(this._mapIncluded(item.owner, 'user'));
return itemData;
})
};
newPayload.included = included;
// github api won't allow to search more 1000 items
const itemsCount = payload.total_count > 1000 ? 1000 : payload.total_count;
newPayload.meta = {
itemsCount,
pagesCount: Math.ceil(itemsCount / this.get('pageSize'))
};
return newPayload;
}
});
<div class="container-fluid">
<h1>{{appName}}</h1>
<p><small>GitHub-API to search JavaScript repositories is used.</small></p>
<p class="alert alert-info"><small>GitHub API won't allow to search more than 1000 items, so <code>total_count</code> is set 1000 if it's greater.</small></p>
{{outlet}}
</div>
{{models-table-server-paginated
data=model
columns=columns
themeInstance=themeInstance
filterQueryParameters=filterQueryParameters
currentPageNumber=page
pageSize=per_page
filterString=search
displayDataChangedAction=(action "displayAction")
columnsVisibilityChangedAction=(action "visibilityAction")
}}
{
"version": "0.12.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"bs4css": "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css",
"popover": "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js",
"bs4js": "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js",
"fa": "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css",
"ember": "2.12.0",
"ember-template-compiler": "2.12.0",
"ember-testing": "2.12.0"
},
"addons": {
"ember-data": "2.12.1",
"ember-models-table": "2.3.0",
"ember-cli-showdown": "4.1.0",
"ember-moment": "7.4.1",
"ember-pikaday": "2.2.3"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment