Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP modernize dependencies and implementation #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2017,
ecmaVersion: 2018,
sourceType: 'module'
},
plugins: [
Expand Down
30 changes: 15 additions & 15 deletions addon/adapters/ember-data-utils-json-api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import DS from 'ember-data';
import { JSONAPIAdapter } from '@ember/data';
import { camelize } from '@ember/string';
import { isEmpty } from '@ember/utils';
import { appendToQueryParam } from 'ember-data-utils/utils/url';
Expand Down Expand Up @@ -26,21 +26,21 @@ import { getOwner } from '@ember/application';
```
@class EmberDataUtilsJSONAPIAdapter
*/
export default DS.JSONAPIAdapter.extend({
export class EmberDataUtilsJSONAPIAdapter extends JSONAPIAdapter {
/**
List of query param keys that your resource supports filtering on.
Extend your base class for specific models to declare.
@field {Array} supportedFilters
*/
supportedFilters: [], // eslint-disable-line ember/avoid-leaking-state-in-ember-objects
supportedFilters = []; // eslint-disable-line ember/avoid-leaking-state-in-ember-objects

/**
Array of includes to always include when querying a particular model.
Extend your base class for specific models to declare.

@field {Array} include
*/
include: [], // eslint-disable-line ember/avoid-leaking-state-in-ember-objects
include = []; // eslint-disable-line ember/avoid-leaking-state-in-ember-objects

/**
* @public
Expand All @@ -56,8 +56,8 @@ export default DS.JSONAPIAdapter.extend({
jsonApiQuery = this._applySort(jsonApiQuery, query);
jsonApiQuery = this._applyIncludes(jsonApiQuery);

return this._super(store, type, jsonApiQuery);
},
return super.query(store, type, jsonApiQuery);
}

/**
* queryRecord and findRecord use buildQuery to add includes to
Expand All @@ -70,7 +70,7 @@ export default DS.JSONAPIAdapter.extend({
*/
buildQuery(snapshot) {
let { include } = this;
let query = this._super(snapshot);
let query = super.buildQuery(snapshot);

if (!include.length) {
return query;
Expand All @@ -82,17 +82,17 @@ export default DS.JSONAPIAdapter.extend({
query.include = combinedUniqueIncludes.join(',');

return query;
},
}

findHasMany(store, snapshot, url, relationship) {
let adapter = this._adapterForRelationship(relationship.type);
let updatedUrl = appendToQueryParam(url, 'include', adapter.include)
return this._super(store, snapshot, updatedUrl, relationship);
},
return super.findHasMany(store, snapshot, updatedUrl, relationship);
}

_adapterForRelationship(type) {
return getOwner(this).lookup(`adapter:${type}`);
},
}

/**
* Mutate the `jsonApiQueryParams` object with pagination related keys from `rawQueryParams` object
Expand All @@ -113,7 +113,7 @@ export default DS.JSONAPIAdapter.extend({
}
});
return jsonApiQueryParams;
},
}

_applySupportedFilters(jsonApiQueryParams, rawQueryParams) {
this.supportedFilters.forEach(key => {
Expand All @@ -124,19 +124,19 @@ export default DS.JSONAPIAdapter.extend({
});

return jsonApiQueryParams;
},
}

_applySort(jsonApiQueryParams, rawQueryParams) {
if (rawQueryParams.sort) {
jsonApiQueryParams.sort = rawQueryParams.sort;
}
return jsonApiQueryParams;
},
}

_applyIncludes(jsonApiQueryParams) {
if (!isEmpty(this.include)) {
jsonApiQueryParams.include = this.include.join(',');
}
return jsonApiQueryParams;
}
});
}
7 changes: 7 additions & 0 deletions addon/components/query-data/index.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{did-update this.didQueryUpdate @query @modelType}}
{{yield (hash
isLoading=this.loadDataTask.isRunning
sortedModels=this.sortedModels
isEmpty=(eq this.sortedModels.length 0)
refresh=this.refresh
)}}
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import Component from '@ember/component';
import layout from './template';
import Component from '@glimmer/component';
import { parseQueryToFunction } from 'ember-data-utils/utils';
import { computed } from '@ember/object';
import { sort } from '@ember/object/computed';
import { task } from 'ember-concurrency';
import { inject as service } from '@ember/service';

/**
A component to fetch data from your api

@argument {string} modelType
@description The name of the ember data model, eg; 'user'
@required
modelType;

@argument {object} query
@description The object of values to query against the server, eg: { admin: true, firstName: 'Bob' }
@required
query = null;

@description Callback fired every time server response finished
@argument {Function} onModelsLoaded
@optional
onModelsLoaded()

```handlebars
{{query-data
modelType='app-page-profile'
sortBy=(array 'createdAt:desc')
query=(hash [email protected])
as |data|}}
<QueryData
@modelType='app-page-profile'
@sortBy={{array 'createdAt:desc'}}
@query={{hash [email protected]}}
as |data|>
...
{{/query-data}}
</QueryData>
```
@class QueryData
@yield {object} data
Expand All @@ -25,77 +37,53 @@ import { inject as service } from '@ember/service';
@yield {array} data.sortedModels The models returned by the api, sorted
@yield {Action} data.refresh Action method to trigger the component to refresh the data
*/
export default Component.extend({
layout,

tagName: '',
store: service(),

/**
The name of the ember data model, eg; 'user'
@argument {string} modelType
@required
*/
modelType: null,

/**
The object of values to query against the server, eg: { admin: true, firstName: 'Bob' }
@argument {object} query
@required
*/
query: null,

/**
Callback fired every time server response finished
@argument {Function} onModelsLoaded
@optional
*/
onModelsLoaded() {},

didReceiveAttrs() {
this._super(...arguments);

let newQuery = this.query;
export default class extends Component {
@service store;

didQueryUpdate() {
let newQuery = this.args.query;
if (this._oldQuery === newQuery) {
return;
}
this.loadDataTask.perform();
this._oldQuery = newQuery;
},
}

sortedModels: sort('filteredModels', 'sortBy'),
get sortedModels() {
return this.filteredModels.sortBy('sortBy');
}

/**
A live record array of all of the models in the store of that
type. This array will be automatically filtered down by the
filter function created from the query hash

@computed liveRecordArray
@property liveRecordArray
@type Array<Object>
@private
@readOnly
*/
liveRecordArray: computed('modelType', function() {
return this.store.peekAll(this.modelType);
}),
get liveRecordArray() {
return this.store.peekAll(this.args.modelType);
}

loadDataTask: task(function*() {
yield this.store.query(this.modelType, this.query);
@task({ keepLatest: true })
*loadDataTask() {
yield this.store.query(this.args.modelType, this.args.query);
if (this.onModelsLoaded) { this.onModelsLoaded(); }
}).keepLatest(),
}

/**
@computed filteredModels
@property filteredModels
@type Array<Object>
@private
@readOnly
*/
filteredModels: computed('liveRecordArray.[]', 'query', 'isLoading', function() {
let filterFn = this.buildFilterFunction(this.query);
get filteredModels() {
let filterFn = this.buildFilterFunction(this.args.query);

return this.liveRecordArray.filter(filterFn);
}
),
return this.liveRecordArray.filter(filterFn);
}

/**
@method buildFilterFunction
Expand All @@ -108,9 +96,8 @@ export default Component.extend({
return function(record) {
return queryFunc(record);
};
},
}

actions: {
/**
@action refresh
@public
Expand All @@ -119,5 +106,4 @@ export default Component.extend({
refresh() {
this.loadDataTask.perform();
}
}
});
}
6 changes: 0 additions & 6 deletions addon/components/query-data/template.hbs

This file was deleted.

11 changes: 5 additions & 6 deletions addon/serializers/ember-data-utils-json-api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import DS from 'ember-data';
import { JSONAPISerializer } from '@ember/data';
import { cleanupLinksForSyncRelationships, hasLinks } from 'ember-data-utils/utils'

/**
Expand All @@ -13,19 +13,18 @@ import { cleanupLinksForSyncRelationships, hasLinks } from 'ember-data-utils/uti

@class EmberDataUtilsJSONAPISerializer
*/
export default DS.JSONAPISerializer.extend({
export class EmberDataUtilsJSONAPISerializer extends JSONAPISerializer {
/**
* @public
* @method extractRelationships
* @param {EmberDataModel} modelClass the ember-data model class
* @param {object} resourceHash
*/
extractRelationships(modelClass, resourceHash) {
let relationships = this._super(modelClass, resourceHash);
let relationships = super.extractRelationships(modelClass, resourceHash);
if (hasLinks(relationships)) {
relationships = cleanupLinksForSyncRelationships(modelClass, relationships);
}
return relationships;
},

});
}
}
1 change: 0 additions & 1 deletion app/components/query-data/component.js

This file was deleted.

1 change: 1 addition & 0 deletions app/components/query-data/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'ember-data-utils/components/query-data';
Loading