-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated mixins to native classes; updated handlebars version to lates…
…t; swapped ember decorators with built in ember objects
- Loading branch information
Showing
9 changed files
with
26,480 additions
and
1,142 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,215 +1,183 @@ | ||
import Mixin from '@ember/object/mixin'; | ||
import { inject as service } from '@ember/service'; | ||
import { get, set, setProperties, computed } from '@ember/object'; | ||
import { action, computed, setProperties } from '@ember/object'; | ||
import { readOnly, or } from '@ember/object/computed'; | ||
import { tryInvoke } from '@ember/utils'; | ||
import NativeArray from '@ember/array/-private/native-array'; | ||
import { reject } from 'rsvp'; | ||
import { A } from '@ember/array'; | ||
import { buildQueryParams, PaginationController, sortDirection } from '@gavant/ember-pagination/utils/query-params'; | ||
import DS from 'ember-data'; | ||
import RouterService from '@ember/routing/router-service'; | ||
|
||
export default function ControllerPaginationClass<T extends ConcreteSubclass<any>>(ControllerSubclass: T) { | ||
class PaginationControllerClass extends ControllerSubclass { | ||
@service router!: RouterService; | ||
sort: NativeArray<any> = A(); | ||
hasMore: boolean = true; | ||
limit: number = 10; | ||
isLoadingPage = false; | ||
|
||
@or('isLoadingPage', 'isLoadingRoute') isLoadingModels!: boolean; | ||
@readOnly('model.length') offset: number | undefined; | ||
|
||
@computed('router.currentRouteName') | ||
get isLoadingRoute() { | ||
return this.router.currentRouteName.match(/loading$/); | ||
} | ||
|
||
export default Mixin.create({ | ||
router: service(), | ||
loadingBar: service(), | ||
sort: A(), | ||
hasMore: true, | ||
limit: 10, | ||
isLoadingPage: false, | ||
|
||
isLoadingRoute: computed('router.currentRouteName', function() { | ||
return get(this, 'router.currentRouteName').match(/loading$/); | ||
}), | ||
isLoadingModels: or('isLoadingPage', 'isLoadingRoute'), | ||
offset: readOnly('model.length'), | ||
pagesLoaded: computed('model.length', 'limit', function() { | ||
return Math.ceil(get(this, 'model.length') / get(this, 'limit')); | ||
}), | ||
|
||
async _loadModels(this: PaginationController, reset: boolean) { | ||
set(this, 'isLoadingPage', true); | ||
if(reset) { | ||
this.clearModels(); | ||
@computed('model.length', 'limit') | ||
get pagesLoaded() { | ||
return Math.ceil(this.model.length / this.limit); | ||
} | ||
|
||
const offset = get(this, 'offset'); | ||
const limit = get(this, 'limit'); | ||
const queryParams = buildQueryParams(this, offset, limit); | ||
let models = []; | ||
try { | ||
const result = await this.fetchModels(queryParams); | ||
models = result.toArray(); | ||
|
||
setProperties(this, { | ||
metadata: get(result, 'meta'), | ||
hasMore: get(models, 'length') >= limit | ||
}); | ||
|
||
tryInvoke(get(this, 'model'), 'pushObjects', [models]); | ||
} catch(errors) { | ||
reject(errors); | ||
async _loadModels(this: PaginationController, reset: boolean) { | ||
this.set('isLoadingPage', true); | ||
if(reset) { | ||
this.clearModels(); | ||
} | ||
|
||
const offset = this.offset; | ||
const limit = this.limit; | ||
const queryParams = buildQueryParams(this, offset, limit); | ||
let models = []; | ||
try { | ||
const result = await this.fetchModels(queryParams); | ||
models = result.toArray(); | ||
setProperties(this, { | ||
metadata: result.meta, | ||
hasMore: models.length >= limit | ||
}); | ||
|
||
tryInvoke(this.model, 'pushObjects', [models]); | ||
} catch(errors) { | ||
reject(errors); | ||
} | ||
|
||
this.set('isLoadingPage', false); | ||
return models; | ||
} | ||
set(this, 'isLoadingPage', false); | ||
return models; | ||
}, | ||
|
||
// loadModelsTask: task(function * (reset, params) { | ||
// get(this, 'loadingBar').start(); | ||
// if(reset) { | ||
// this.clearModels(); | ||
// } | ||
// | ||
// const offset = get(this, 'offset'); | ||
// const limit = get(this, 'limit'); | ||
// const queryParams = this.buildQueryParams(this, params, offset, limit); | ||
// const result = yield this.fetchModels(queryParams); | ||
// const models = result.toArray(); | ||
// | ||
// setProperties(this, { | ||
// metadata: get(result, 'meta'), | ||
// hasMore: get(models, 'length') >= limit | ||
// }); | ||
// | ||
// tryInvoke(get(this, 'model'), 'pushObjects', [models]); | ||
// get(this, 'loadingBar').stop(); | ||
// return models; | ||
// }).restartable(), | ||
|
||
/** | ||
* Override this method if more complex logic is necessary to retrieve the records | ||
* It should return a promise, which resolves to an array-like object (such as a DS.RecordArray) | ||
* @returns - the result of `store.query` | ||
*/ | ||
fetchModels(this: PaginationController, queryParams: any) { | ||
const modelName = get(this, 'modelName'); | ||
return get(this, 'store').query(modelName, queryParams); | ||
}, | ||
|
||
/** | ||
* Change the sorting and call `filterModels`. Will only load models if not currently making an API call | ||
* @param reset - Clear models | ||
* @returns - an array of models | ||
*/ | ||
loadModels(this: PaginationController, reset: boolean) { | ||
if (!get(this, 'isLoadingPage')) { | ||
return this._loadModels(reset); | ||
} else { | ||
return []; | ||
|
||
/** | ||
* Override this method if more complex logic is necessary to retrieve the records | ||
* It should return a promise, which resolves to an array-like object (such as a DS.RecordArray) | ||
* @returns - the result of `store.query` | ||
*/ | ||
fetchModels(this: PaginationController, queryParams: any) { | ||
const modelName = this.modelName as never; | ||
return this.store.query(modelName, queryParams); | ||
} | ||
}, | ||
|
||
/** | ||
* Clear models | ||
*/ | ||
clearModels(this: PaginationController) { | ||
set(this, 'model', A()); | ||
}, | ||
|
||
/** | ||
* Clear and Reload models | ||
* @returns - an array of models | ||
*/ | ||
reloadModels(this: PaginationController) { | ||
return this.loadModels(true); | ||
}, | ||
|
||
/** | ||
* Load another page of models | ||
* @returns - an array of models | ||
*/ | ||
loadMoreModels(this: PaginationController) { | ||
return this.loadModels(); | ||
}, | ||
|
||
/** | ||
* Change the sorting and call `filterModels` | ||
* @param model - A `DS.Model` record | ||
* @returns - result of api call | ||
*/ | ||
async removeModel(this: PaginationController, model: DS.Model) { | ||
try { | ||
let result = await tryInvoke(model, 'destroyRecord'); | ||
get(this, 'model').removeObject(model); | ||
return result; | ||
} catch(error) { | ||
return reject(error); | ||
|
||
/** | ||
* Change the sorting and call `filterModels`. Will only load models if not currently making an API call | ||
* @param reset - Clear models | ||
* @returns - an array of models | ||
*/ | ||
loadModels(this: PaginationController, reset: boolean = false) { | ||
if (!this.isLoadingPage) { | ||
return this._loadModels(reset); | ||
} else { | ||
return; | ||
} | ||
} | ||
}, | ||
|
||
/** | ||
* Change the sorting and call `filterModels` | ||
* @param sort - Array of strings | ||
* @param dir - The direction of the sort i.e `asc` or `desc` | ||
* @param isSorted - Is sorted | ||
* @returns - an array of models | ||
*/ | ||
changeSorting(this: PaginationController, sort: string[], dir: sortDirection, isSorted: boolean) { | ||
const sorting = get(this, 'sort'); | ||
const sortedValue = `${dir === "desc" ? '-' : ''}${sort}`; | ||
const oppositeSortedValue = `${dir === "asc" ? '-' : ''}${sort}`; | ||
if(!isSorted) { | ||
sorting.removeObject(sortedValue); | ||
sorting.removeObject(oppositeSortedValue); | ||
} else if (!sorting.includes(oppositeSortedValue) && !sorting.includes(sortedValue)) { | ||
sorting.unshift(sortedValue); | ||
} else { | ||
//make the new sort column the first one in the list | ||
//so that its sent to the server as the primary sort | ||
sorting.removeObject(oppositeSortedValue); | ||
sorting.unshift(sortedValue); | ||
|
||
/** | ||
* Filter models | ||
* @returns - an array of models | ||
*/ | ||
filterModels(this: PaginationController) { | ||
return this.loadModels(true); | ||
} | ||
return this.filterModels(); | ||
}, | ||
|
||
/** | ||
* Filter models | ||
* @returns - an array of models | ||
*/ | ||
filterModels(this: PaginationController) { | ||
return this.loadModels(true); | ||
}, | ||
|
||
/** | ||
* Clears the filters and returns the updated model array | ||
* @returns - an array of models | ||
*/ | ||
clearFilters(this: PaginationController) { | ||
get(this, 'serverQueryParams').forEach((param: any) => set(this, param, null)); | ||
return this.filterModels(); | ||
}, | ||
|
||
/** | ||
* Clears the sort array | ||
*/ | ||
clearSorting() { | ||
set(this, 'sort', A()); | ||
}, | ||
|
||
actions: { | ||
|
||
/** | ||
* Clears the sort array | ||
*/ | ||
clearSorting() { | ||
this.set('sort', A()); | ||
} | ||
|
||
/** | ||
* Load another page of models | ||
* @returns - an array of models | ||
*/ | ||
@action | ||
loadMoreModels(this: PaginationController) { | ||
return this.loadMoreModels(); | ||
}, | ||
return this.loadModels(); | ||
} | ||
|
||
/** | ||
* Clear and Reload models | ||
* @returns - an array of models | ||
*/ | ||
@action | ||
reloadModels(this: PaginationController) { | ||
return this.reloadModels(); | ||
}, | ||
return this.loadModels(true); | ||
} | ||
|
||
removeModel(this: PaginationController, row: any) { | ||
return this.removeModel(row); | ||
}, | ||
/** | ||
* Change the sorting and call `filterModels` | ||
* @param model - A `DS.Model` record | ||
* @returns - result of api call | ||
*/ | ||
@action | ||
async removeModel(this: PaginationController, model: DS.Model) { | ||
try { | ||
let result = await tryInvoke(model, 'destroyRecord'); | ||
this.model.removeObject(model); | ||
return result; | ||
} catch(error) { | ||
return reject(error); | ||
} | ||
} | ||
|
||
/** | ||
* Clear models | ||
*/ | ||
@action | ||
clearModels(this: PaginationController) { | ||
this.clearModels(); | ||
}, | ||
this.set('model', A()); | ||
} | ||
|
||
@action | ||
filter(this: PaginationController) { | ||
return this.filterModels(); | ||
}, | ||
} | ||
|
||
/** | ||
* Change the sorting and call `filterModels` | ||
* @param sort - Array of strings | ||
* @param dir - The direction of the sort i.e `asc` or `desc` | ||
* @param isSorted - Is sorted | ||
* @returns - an array of models | ||
*/ | ||
@action | ||
changeSorting(this: PaginationController, sort: string[], dir: sortDirection, isSorted: boolean) { | ||
return this.changeSorting(sort, dir, isSorted); | ||
}, | ||
const sorting = this.sort; | ||
const sortedValue = `${dir === "desc" ? '-' : ''}${sort}`; | ||
const oppositeSortedValue = `${dir === "asc" ? '-' : ''}${sort}`; | ||
if(!isSorted) { | ||
sorting.removeObject(sortedValue); | ||
sorting.removeObject(oppositeSortedValue); | ||
} else if (!sorting.includes(oppositeSortedValue) && !sorting.includes(sortedValue)) { | ||
sorting.unshift(sortedValue); | ||
} else { | ||
//make the new sort column the first one in the list | ||
//so that its sent to the server as the primary sort | ||
sorting.removeObject(oppositeSortedValue); | ||
sorting.unshift(sortedValue); | ||
} | ||
return this.filterModels(); | ||
} | ||
|
||
/** | ||
* Clears the filters and returns the updated model array | ||
* @returns - an array of models | ||
*/ | ||
@action | ||
clearFilters(this: PaginationController) { | ||
return this.clearFilters(); | ||
this.serverQueryParams.forEach((param: any) => this.set(param, null)); | ||
return this.filterModels(); | ||
} | ||
} | ||
}); | ||
|
||
return PaginationControllerClass; | ||
} |
Oops, something went wrong.