Skip to content

Commit

Permalink
rename rows => models, better query params obj typing, demo processQu…
Browse files Browse the repository at this point in the history
…eryParams
  • Loading branch information
billdami committed Aug 11, 2020
1 parent 31116f3 commit afead9e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 41 deletions.
48 changes: 24 additions & 24 deletions addon/hooks/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { A } from '@ember/array';
import DS from 'ember-data';
import RouterService from '@ember/routing/router-service';

import { buildQueryParams } from '@gavant/ember-pagination/utils/query-params';
import { buildQueryParams, QueryParamsObj } from '@gavant/ember-pagination/utils/query-params';

export type RecordArrayWithMeta<T> = DS.AdapterPopulatedRecordArray<T> & { meta: any };

Expand All @@ -30,14 +30,14 @@ export interface PaginationConfigs {
includeKey?: string;
sortKey?: string;
serverDateFormat?: string;
processQueryParams?: (params: any) => any;
processQueryParams?: (params: QueryParamsObj) => QueryParamsObj;
onChangeSorting?: (sorts: string[], newSorts?: Sorting[]) => Promise<string[] | undefined> | void;
}

export interface PaginationArgs<T extends DS.Model, M = ResponseMetadata> extends PaginationConfigs {
context: any;
modelName: string;
rows: NativeArray<T> | T[];
models: NativeArray<T> | T[];
metadata?: M;
sorts?: string[];
}
Expand All @@ -60,7 +60,7 @@ export class Pagination<T extends DS.Model, M = ResponseMetadata> {
context: any;
modelName: string;
sorts: string[] | undefined = [];
@tracked rows: NativeArray<T> | T[] = A();
@tracked models: NativeArray<T> | T[] = A();
@tracked metadata: M | undefined;
@tracked hasMore: boolean = true;
@tracked isLoading: boolean = false;
Expand All @@ -74,12 +74,12 @@ export class Pagination<T extends DS.Model, M = ResponseMetadata> {
}

get offset() {
return this.rows.length;
return this.models.length;
}

/**
* Sets the initial pagination data/configuration which at minimum, requires
* a context, modelName, and initial rows/metadata
* a context, modelName, and initial models/metadata
* @param {PaginationArgs<T, M>} args
*/
constructor(args: PaginationArgs<T, M>) {
Expand All @@ -88,12 +88,12 @@ export class Pagination<T extends DS.Model, M = ResponseMetadata> {
this.modelName = args.modelName;
this.metadata = args.metadata;
this.sorts = args.sorts;
this.rows = A(args.rows);
this.models = A(args.models);

//set configs from initial args
delete args.context;
delete args.modelName;
delete args.rows;
delete args.models;
delete args.metadata;
delete args.sorts;
this.setConfigs(args);
Expand All @@ -106,17 +106,17 @@ export class Pagination<T extends DS.Model, M = ResponseMetadata> {
@action
setConfigs(config: PaginationConfigs) {
this.config = { ...this.config, ...config };
this.hasMore = this.rows.length >= this.config.limit!;
this.hasMore = this.models.length >= this.config.limit!;
}

/**
* Utility method for completely replacing the current rows array/metadata
* @param {NativeArray<T> | T[]} rows
* Utility method for completely replacing the current models array/metadata
* @param {NativeArray<T> | T[]} models
* @param {M} metadata
*/
@action
setRows(rows: NativeArray<T> | T[], metadata?: M) {
this.rows = rows;
setModels(models: NativeArray<T> | T[], metadata?: M) {
this.models = models;
this.metadata = metadata;
}

Expand Down Expand Up @@ -150,11 +150,11 @@ export class Pagination<T extends DS.Model, M = ResponseMetadata> {
try {
this.isLoading = true;
const result = await this.queryModels(queryParams);
const rows = result.toArray();
this.hasMore = rows.length >= this.config.limit!;
const models = result.toArray();
this.hasMore = models.length >= this.config.limit!;
this.metadata = result.meta;
this.rows.pushObjects(rows);
return rows;
this.models.pushObjects(models);
return models;
} finally {
this.isLoading = false;
}
Expand All @@ -176,12 +176,12 @@ export class Pagination<T extends DS.Model, M = ResponseMetadata> {
* @returns {Promise<T[]> | null}
*/
@action
loadMoreModels(): Promise<T[]> | null {
loadMoreModels(): Promise<T[]> | undefined {
if (this.hasMore && !this.isLoadingModels) {
return this.loadModels();
}

return null;
return undefined;
}

/**
Expand All @@ -203,22 +203,22 @@ export class Pagination<T extends DS.Model, M = ResponseMetadata> {
}

/**
* Clears all current model rows array
* Clears all current model models array
*/
@action
clearModels() {
this.rows = A();
this.models = A();
}

/**
* Deletes the model and removes it from the rows array
* Deletes the model and removes it from the models array
* @param {T} model
* @returns {Promise<void>}
*/
@action
async removeModel(model: T) {
const result = await model.destroyRecord();
this.rows.removeObject(result);
this.models.removeObject(result);
return result;
}

Expand Down Expand Up @@ -253,7 +253,7 @@ export class Pagination<T extends DS.Model, M = ResponseMetadata> {
}

/**
* Clears all models from the rows array and resets the current state
* Clears all models from the models array and resets the current state
* Sometimes useful in resetController() when the pagination may not
* be recreated/overwritten on every transition, and you want to clear
* it when leaving the page.
Expand Down
22 changes: 13 additions & 9 deletions addon/utils/query-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { isArray } from '@ember/array';
import { isEmpty } from '@ember/utils';
import moment from 'moment';

export interface QueryParamsObj {
[x: string]: any;
}

interface buildQueryParamsArgs {
context: any;
offset?: number;
Expand All @@ -15,7 +19,7 @@ interface buildQueryParamsArgs {
includeKey?: string;
sortKey?: string;
serverDateFormat?: string;
processQueryParams?: (params: any) => any;
processQueryParams?: (params: QueryParamsObj) => QueryParamsObj;
}

interface getParamsObjectArgs {
Expand All @@ -31,7 +35,7 @@ interface getParamsObjectArgs {
* Builds a query params object to use for paginated api requests using the "context" (e.g. Controller/Component)
* to get filter values, along with additional passed in configuration. Optimized for JSON-API spec APIs by default.
* @param {buildQueryParamsArgs} Config
* @returns {Object} Object with query params to send to server
* @returns {QueryParamsObj} Object with query params to send to server
*/
export function buildQueryParams({
context,
Expand All @@ -45,8 +49,8 @@ export function buildQueryParams({
includeKey = 'include',
sortKey = 'sort',
serverDateFormat = 'YYYY-MM-DDTHH:mm:ss',
processQueryParams = (params: any) => params
}: buildQueryParamsArgs) {
processQueryParams = (params: QueryParamsObj) => params
}: buildQueryParamsArgs): QueryParamsObj {
let queryParams = getParamsObject({
context,
filterList,
Expand Down Expand Up @@ -78,7 +82,7 @@ export function buildQueryParams({
/**
* Gets the parameter values from the "context" (e.g. Controller/Component)
* @param {getParamsObjectArgs} Config
* @returns {Object} Object with query params to send to server
* @returns {QueryParamsObj} Object with query params to send to server
*/
export function getParamsObject({
context,
Expand All @@ -87,8 +91,8 @@ export function getParamsObject({
sorts = [],
sortKey = 'sort',
serverDateFormat = 'YYYY-MM-DDTHH:mm:ss'
}: getParamsObjectArgs) {
let params: any = {};
}: getParamsObjectArgs): QueryParamsObj {
let params: QueryParamsObj = {};
let filterRoot = params;

if(filterRootKey) {
Expand Down Expand Up @@ -129,9 +133,9 @@ export function getParamsObject({
/**
* Remove empty(using [isEmpty](https://api.emberjs.com/ember/release/functions/@ember%2Futils/isEmpty))query params from the query params object thats built from `buildQueryParams`
* @param {any} queryParams The query params object
* @returns {Object} object with empty query params removed
* @returns {QueryParamsObj} object with empty query params removed
*/
export function removeEmptyQueryParams(queryParams: any) {
export function removeEmptyQueryParams(queryParams: QueryParamsObj): QueryParamsObj {
for(let i in queryParams) {
if(isEmpty(queryParams[i])) {
delete queryParams[i];
Expand Down
23 changes: 21 additions & 2 deletions tests/dummy/app/controllers/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Controller from '@ember/controller';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { Pagination } from '@gavant/ember-pagination/hooks/pagination';
import { QueryParamsObj } from '@gavant/ember-pagination/utils/query-params';

import Customer from '../models/customer';

Expand All @@ -20,11 +21,11 @@ export default class List extends Controller {
@tracked sortsTwo = ['-sortC', 'sortD'];

get totalPages() {
return Math.ceil(this.paginator.rows.length / 9);
return Math.ceil(this.paginator.models.length / 9);
}

get totalPagesTwo() {
return Math.ceil(this.paginatorTwo.rows.length / 9);
return Math.ceil(this.paginatorTwo.models.length / 9);
}

@action
Expand All @@ -34,6 +35,24 @@ export default class List extends Controller {
console.log('do something after reloading');
}

@action
processQueryParams(params: QueryParamsObj) {
//allows you to do some custom logic to modify/format
//the query params anytime they are generated by the
//paginator instance, before they are used in the api request
if(!params.filter) {
params.filter = {};
}

params.filter.randomInt = Math.floor(Math.random() * 1000) + 1

if(params.filter?.baz) {
params.filter.baz = params.filter.baz.trim();
}

return params;
}

@action
onChangeSorting(sorts: string[]) {
this.sorts = sorts;
Expand Down
11 changes: 7 additions & 4 deletions tests/dummy/app/routes/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default class List extends Route {
sorts: controller.sorts,
filterList: filters,
includeList: includes,
processQueryParams: controller.processQueryParams
});

return this.store.query('customer', params);
Expand All @@ -29,24 +30,26 @@ export default class List extends Route {
controller.paginator = usePagination<Customer>({
context: controller,
modelName: 'customer',
rows: model.toArray(),
models: model.toArray(),
metadata: model.meta,
limit: 9,
sorts: controller.sorts,
filterList: filters,
includeList: includes,
onChangeSorting: controller.onChangeSorting
onChangeSorting: controller.onChangeSorting,
processQueryParams: controller.processQueryParams
});

controller.paginatorTwo = usePagination<Customer>({
context: controller,
modelName: 'customer',
rows: model.toArray(),
models: model.toArray(),
metadata: model.meta,
limit: 9,
sorts: controller.sortsTwo,
filterList: ['foo', 'bar', 'baz', 'customFilter:mappedFilter'],
includeList: ['yetAnotherRel', 'imSomethingElse']
includeList: ['yetAnotherRel', 'imSomethingElse'],
processQueryParams: controller.processQueryParams
});

super.setupController(controller, model);
Expand Down
4 changes: 2 additions & 2 deletions tests/dummy/app/templates/list.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
{{if this.paginator.isLoading "Loading..." "Custom reload action"}}
</button>
</p>
{{#each this.paginator.rows as |customer|}}
{{#each this.paginator.models as |customer|}}
<h5>
{{customer.firstName}} {{customer.lastName}}
</h5>
Expand Down Expand Up @@ -92,7 +92,7 @@
{{if this.paginatorTwo.isLoading "Loading..." "Reload"}}
</button>
</p>
{{#each this.paginatorTwo.rows as |customer|}}
{{#each this.paginatorTwo.models as |customer|}}
<h5>
{{customer.firstName}} {{customer.lastName}}
</h5>
Expand Down

0 comments on commit afead9e

Please sign in to comment.