Skip to content

Commit

Permalink
fix(akita-filter-plugins): fix withServer sort
Browse files Browse the repository at this point in the history
- when using withServer sort (need to add withSort options in withServer function), previously it run sorting locally and then call withServer callback. Now it will just call the withServer callback.
  • Loading branch information
manudss committed Jan 6, 2021
1 parent d2b7727 commit 0e15be6
Show file tree
Hide file tree
Showing 8 changed files with 1,292 additions and 859 deletions.
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"ngx-markdown": "^8.1.0",
"ngx-take-until-destroy": "^5.4.0",
"rxjs": "~6.5.4",
"tslib": "^1.10.0",
"tslib": "^1.14.1",
"zone.js": "~0.10.2"
},
"devDependencies": {
Expand All @@ -72,14 +72,15 @@
"@angular/language-service": "~9.0.7",
"@datorama/akita-ng-router-store": "^3.1.4",
"@datorama/akita-ngdevtools": "^3.0.2",
"@jest/globals": "^26.6.2",
"@types/jasmine": "~3.4.0",
"@types/jasminewd2": "~2.0.6",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"jest": "^24.8.0",
"jest-localstorage-mock": "^2.4.0",
"jest": "^26.6.3",
"jest-localstorage-mock": "^2.4.6",
"karma": "~4.2.0",
"karma-chrome-launcher": "~3.0.0",
"karma-coverage-istanbul-reporter": "~2.1.0",
Expand All @@ -88,9 +89,9 @@
"ng-packagr": "^9.0.0",
"protractor": "~5.4.2",
"semantic-release": "^17.0.4",
"ts-jest": "^24.0.2",
"ts-node": "~8.3.0",
"tslint": "~5.18.0",
"ts-jest": "^26.4.4",
"ts-node": "~9.1.1",
"tslint": "~6.1.3",
"typescript": "~3.7.5"
},
"repository": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import {skip, take} from 'rxjs/operators';
import {createWidget, createWidgetCompleted, WidgetsQuery, WidgetsStore} from './setup';
import {AkitaFiltersPlugin} from '../lib/akita-filters-plugin';
import {Order} from '@datorama/akita';
import jest from '@types/jest';
import {jest} from '@jest/globals';
import {of} from 'rxjs';

declare var jest: jest;

const widgetsStore = new WidgetsStore();
const widgetsQuery = new WidgetsQuery(widgetsStore);
const filters = new AkitaFiltersPlugin(widgetsQuery);
Expand Down
28 changes: 19 additions & 9 deletions projects/akita-filters-plugin/src/lib/akita-filters-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export class AkitaFiltersPlugin<S extends EntityState, E = getEntityType<S>, I =
private readonly _selectFiltersAll$: Observable<Array<AkitaFilter<S>>>;
private _onChangeFilter: (filtersNormalized: (string | HashMap<any>)) => any | boolean | Observable<Array<getEntityType<S>>>;
private _lastServerSubscribtion: Subscription;
private _withServerOptions: WithServerOptions;

constructor(protected query: QueryEntity<S>, private params: FiltersParams<S> = {}) {
super(query, params.entityIds);
Expand Down Expand Up @@ -90,6 +91,7 @@ export class AkitaFiltersPlugin<S extends EntityState, E = getEntityType<S>, I =
options = {...options};

this.server = true;
this._withServerOptions = options;
this._onChangeFilter = onChangeFilter;

// Change default select filters to remove server filters, if you use selectAllByFilters();
Expand Down Expand Up @@ -173,17 +175,26 @@ export class AkitaFiltersPlugin<S extends EntityState, E = getEntityType<S>, I =
selectAllByFilters(options?: SelectAllOptionsA<E>
| SelectAllOptionsB<E> | SelectAllOptionsC<E> |
SelectAllOptionsD<E> | SelectAllOptionsE<E> | any): Observable<Array<getEntityType<S>> | HashMap<getEntityType<S>>> {
const listObservable: Array<Observable<any>> = [];
listObservable.push(this._selectFilters$, this.getQuery().selectAll(options));
let sortBy = this.selectSortBy();
if (options && options.asObject) {
return combineLatest(this._selectFilters$, this.getQuery().selectAll(options)).pipe(
map(([filters, entities]) => {
return combineLatest(listObservable).pipe(
map((values) => {
const [filters, entities] = values;
const unkNowEntity: unknown = entities;
return this._applyFiltersForHashMap((unkNowEntity as HashMap<getEntityType<S>>), filters);
}),
);
} else {
if (this.server && this._withServerOptions?.withSort) {
sortBy = sortBy.pipe(map(data => null));
}
listObservable.push(sortBy);

return combineLatest(this._selectFilters$, this.getQuery().selectAll(options), this.selectSortBy()).pipe(
map(([filters, entities, sort]) => {
return combineLatest(listObservable).pipe(
map((values) => {
const [filters, entities, sort] = values;
const unkNowEntity: unknown = entities;
return this._applyFiltersForArray((unkNowEntity as Array<getEntityType<S>>), filters, sort);
}),
Expand Down Expand Up @@ -284,11 +295,10 @@ export class AkitaFiltersPlugin<S extends EntityState, E = getEntityType<S>, I =
for (const filter of this.getServerFilters()) {
result[filter.id] = filter.value;
}

if (options.withSort) {
const sort = this.getSortValue();
result[options.sortByKey] = sort.sortBy;
result[options.sortByOrderKey] = sort.sortByOrder;
const sort = this.getSortValue();
if (options.withSort && sort?.sortBy) {
result[options.sortByKey] = sort?.sortBy;
result[options.sortByOrderKey] = sort?.sortByOrder;
}

if (options.asQueryParams) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export class AkitaMatDataSource<S extends EntityState = any, E = getEntityType<S
* Instance of the MatSort directive used by the table to control its sorting. Sort changes
* emitted by the MatSort will trigger an update to the table's rendered data.
*
* Important : Must be a MatSort, the type any added was to evit a bug with typescript where MatSort was different in external project.
* Important : Must be a MatSort, the type any added was to avoid a bug with typescript where MatSort was different in external project.
*/
set sort(sort: MatSort | any) {
this._sort = sort;
Expand Down
4 changes: 2 additions & 2 deletions src/app/with-server/with-server-demo.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
<mat-icon matSuffix>collections</mat-icon>
</mat-form-field>
<mat-slide-toggle (change)="updatePaginator($event)" [checked]="usePaginator">Use pagninator </mat-slide-toggle>
<mat-chip-list>
<mat-chip *ngFor="let filter of (dataSource.akitaFiltersPlugIn.selectFilters() | async)">
<mat-chip-list *ngIf="dataSource.akitaFiltersPlugIn.selectFilters() | async as filters">
<mat-chip *ngFor="let filter of filters">
{{filter.name}} <mat-icon matChipRemove (click)="dataSource.removeFilter(filter.id)">cancel</mat-icon>
</mat-chip>
</mat-chip-list>
Expand Down
21 changes: 15 additions & 6 deletions src/app/with-server/with-server-demo.component.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import {Component, OnInit, ViewChild, ViewEncapsulation} from '@angular/core';
import {AfterViewInit, Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation} from '@angular/core';
import {AkitaMatDataSource} from '../../../projects/akita-mat-datasource/src/lib/akita-mat-data-source';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import {PhotosState} from './with-server/state/photos-store.service';
import {PhotosQuery} from './with-server/state/users-query.service';
import {PhotosFiltersService} from './with-server/photos-filters.service';
import {Observable} from 'rxjs';
import {Observable, Subscription} from 'rxjs';

@Component({
selector: 'app-angular-material-demo',
templateUrl: './with-server-demo.component.html',
styleUrls: ['./with-server-demo.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class WithServerDemoComponent implements OnInit {
export class WithServerDemoComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
@ViewChild(MatSort, {static: true}) sort: MatSort;
dataSource: AkitaMatDataSource<PhotosState>;
Expand All @@ -22,6 +22,7 @@ export class WithServerDemoComponent implements OnInit {
displayedColumns = ['id', 'albumId', 'title', 'thumbnailUrl'];
public usePaginator: boolean = true;
count$: Observable<number>;
private _subscribeTotal: Subscription;

constructor(
private photosService: PhotosFiltersService,
Expand Down Expand Up @@ -87,8 +88,7 @@ export class WithServerDemoComponent implements OnInit {
this.dataSource = new AkitaMatDataSource<PhotosState>(this.photosQuery, this.photosService, {
searchFilterId: 'title_like', serverPagination: false,
});
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;

this.dataSource.total = 5000;
this.count$ = this.dataSource.selectCount();
this.dataSource.withOptions({
Expand All @@ -98,8 +98,12 @@ export class WithServerDemoComponent implements OnInit {
pageIndexDisplay: true,
serverPagination: true,
});
this.dataSource.sort = this.sort;
this._subscribeTotal = this.photosService.total$.subscribe((total) => this.dataSource.total = total);
}

this.photosService.total$.subscribe((total) => this.dataSource.total = total);
ngOnDestroy(): void {
this._subscribeTotal?.unsubscribe();
}

updatePaginator($event) {
Expand All @@ -109,4 +113,9 @@ export class WithServerDemoComponent implements OnInit {
this.limit = '30';
}
}

ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;

}
}
20 changes: 10 additions & 10 deletions src/app/with-server/with-server/photos-filters.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,40 @@ import {Injectable} from '@angular/core';
import {PhotosState} from './state/photos-store.service';
import {AkitaFiltersPlugin} from 'akita-filters-plugin';
import {PhotosQuery} from './state/users-query.service';
import {HashMap, PaginationResponse} from '@datorama/akita';
import {HashMap} from '@datorama/akita';
import {PhotosService} from './state/photos.service';
import {map, tap} from 'rxjs/operators';
import {PhotosModel} from './state/photosModel';
import {HttpResponse} from '@angular/common/http';
import {BehaviorSubject, Observable} from 'rxjs';


@Injectable({providedIn: 'root'})
export class PhotosFiltersService extends AkitaFiltersPlugin<PhotosState> {
get total$(): Observable<number> {
return this._total$.asObservable();
}
private _total$ = new BehaviorSubject<number>(0);

constructor(protected query: PhotosQuery, protected photosApi: PhotosService) {
super(query);
this.withServer(this.getOnChangeFilter());
this.withServer(this.getOnChangeFilter(), {withSort: true, sortByKey: '_sort', sortByOrderKey: '_order'});
}

private _total$ = new BehaviorSubject<number>(0);

get total$(): Observable<number> {
return this._total$.asObservable();
}

public getOnChangeFilter() {
return (filtersNormalized: string | HashMap<any>) => {
const filtersObject = filtersNormalized as HashMap<any>;
if (filtersObject?._page) {
filtersObject._page = filtersObject._page + 1;
}
return this.photosApi.get({params: filtersObject,
return this.photosApi.get({
params: filtersObject,
mapResponseFn: (res: HttpResponse<PhotosModel[]>): PhotosModel[] => {
this._total$.next(Number(res.headers.get('x-total-count')));

return res.body;
},
observe: 'response', // <----- this
observe: 'response', // <----- this was to access to header of the request
});
};
}
Expand Down
Loading

0 comments on commit 0e15be6

Please sign in to comment.