Skip to content

Commit

Permalink
Implement Pagintion. Move filter to state. (#3)
Browse files Browse the repository at this point in the history
Co-authored-by: Philipp Meier <philipp.meier@ipt.ch>
  • Loading branch information
nevius and Philipp Meier authored Sep 29, 2023
1 parent df024ea commit 212c3f0
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { AlertComponent } from './components/alert/alert.component';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatSelectModule } from '@angular/material/select';
import { FormsModule } from '@angular/forms';
import { MatPaginatorModule } from '@angular/material/paginator';

const GRAPH_ENDPOINT = 'https://graph.microsoft.com/v1.0/me';

Expand Down Expand Up @@ -134,6 +135,7 @@ export function MSALGuardConfigFactory(): MsalGuardConfiguration {
QRCodeModule,
MatSlideToggleModule,
MatSelectModule,
MatPaginatorModule,
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: !isDevMode(),
// Register the ServiceWorker as soon as the application is stable
Expand Down
17 changes: 15 additions & 2 deletions src/app/components/cards/cards.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<mat-slide-toggle
class="pr-2 pt-2"
[ngModel]="showAll$ | async"
(ngModelChange)="showAll$.next($event)"
(ngModelChange)="onShowAllChange($event)"
>Alle</mat-slide-toggle
>
</div>
Expand All @@ -25,14 +25,27 @@
</mat-option>
</mat-select>
</mat-form-field>

<div *ngIf="cards$ | async as cards">
<div class="grid grid-cols-3 gap-4">
<div class="grid grid-cols-3 gap-4 mb-2">
<app-card-thumbnail
*ngFor="let card of cards"
[card]="card"
[routerLink]="'' + card.id"
></app-card-thumbnail>
</div>

<mat-paginator
*ngIf="initialPageInfo$ | async as pageInfo"
[length]="cardsCount$ | async"
[pageIndex]="pageInfo.pageIndex"
[pageSize]="pageInfo.pageSize"
[pageSizeOptions]="[5, 10, 20, 50]"
[showFirstLastButtons]="true"
class="p-1"
(page)="onPage($event)"
>
</mat-paginator>
</div>
</ng-container>
</app-panel>
38 changes: 28 additions & 10 deletions src/app/components/cards/cards.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { Component } from '@angular/core';
import { PageEvent } from '@angular/material/paginator';
import { Store } from '@ngrx/store';
import { BehaviorSubject, Observable, switchMap } from 'rxjs';
import { Observable, first } from 'rxjs';
import { Card } from 'src/app/models/card.model';
import { loadCards } from 'src/app/state/card/card.actions';
import {
selectAllCards,
changeCardsFilter,
changeCardsPage,
loadCards,
} from 'src/app/state/card/card.actions';
import {
selectCardError,
selectCardLoading,
selectOwnedCards,
selectCardsFilteredAndPaged,
selectCardsFilteredCount,
selectCardsPageInfo,
selectCardsShowAll,
} from 'src/app/state/card/card.selectors';

interface SortCriterion {
Expand All @@ -23,8 +30,9 @@ export class CardsComponent {
loading$?: Observable<boolean>;
error$?: Observable<boolean>;
cards$?: Observable<Card[]>;

showAll$ = new BehaviorSubject<boolean>(false);
cardsCount$: Observable<number>;
showAll$: Observable<boolean>;
initialPageInfo$: Observable<{ pageIndex: number; pageSize: number }>;

readonly sortCriteria: SortCriterion[] = [
{ value: 'received', viewValue: 'Erhalt des Chärtlis' },
Expand All @@ -37,11 +45,21 @@ export class CardsComponent {
this.store.dispatch(loadCards());
this.loading$ = this.store.select(selectCardLoading);
this.error$ = this.store.select(selectCardError);
this.showAll$ = this.store.select(selectCardsShowAll);
this.cardsCount$ = this.store.select(selectCardsFilteredCount);
this.cards$ = this.store.select(selectCardsFilteredAndPaged);
this.initialPageInfo$ = this.store
.select(selectCardsPageInfo)
.pipe(first());
}

onShowAllChange(value: boolean) {
this.store.dispatch(changeCardsFilter({ showAll: value }));
}

const allCards$ = this.store.select(selectAllCards);
const ownedCards$ = this.store.select(selectOwnedCards);
this.cards$ = this.showAll$.pipe(
switchMap((showAll) => (showAll ? allCards$ : ownedCards$)),
onPage(event: PageEvent) {
this.store.dispatch(
changeCardsPage({ pageSize: event.pageSize, pageIndex: event.pageIndex }),
);
}
}
10 changes: 10 additions & 0 deletions src/app/state/card/card.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ export const loadCardByIdSuccess = createAction(
);

export const loadCardByIdError = createAction('[Cards] Load card by id error');

export const changeCardsFilter = createAction(
'[Cards] Change Filter',
props<{ showAll: boolean }>(),
);

export const changeCardsPage = createAction(
'[Cards] Change Page',
props<{ pageIndex: number; pageSize: number }>(),
);
11 changes: 11 additions & 0 deletions src/app/state/card/card.reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,15 @@ export const cardReducer = createReducer(
error: false,
};
}),

on(CardActions.changeCardsFilter, (state, { showAll }): CardState => {
return { ...state, showAll };
}),

on(
CardActions.changeCardsPage,
(state, { pageIndex, pageSize }): CardState => {
return { ...state, pageIndex, pageSize };
},
),
);
44 changes: 40 additions & 4 deletions src/app/state/card/card.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ export const selectAllCards = createSelector(selectCardState, (state) =>
selectAll(state),
);

export const selectOwnedCards = createSelector(selectAllCards, (cards) => {
return cards.filter((card) => card.owned > 0);
});

export const selectCardEntities = createSelector(selectCardState, (state) =>
selectEntities(state),
);
Expand Down Expand Up @@ -59,3 +55,43 @@ export const selectCardWithProfileError = createSelector(
selectProfileState,
(cardState, profileState) => cardState.error || profileState.error,
);

export const selectCardsShowAll = createSelector(
selectCardState,
(cardState) => cardState.showAll,
);

export const selectCardsPageInfo = createSelector(
selectCardState,
(cardState) => ({
pageSize: cardState.pageSize,
pageIndex: cardState.pageIndex,
}),
);

export const selectCardsFiltered = createSelector(
selectAllCards,
selectCardsShowAll,
(allCards, showAll) => {
if (showAll) {
return allCards;
} else {
return allCards.filter((card) => card.owned > 0);
}
},
);

export const selectCardsFilteredCount = createSelector(
selectCardsFiltered,
(cardsFiltered) => cardsFiltered.length,
);

export const selectCardsFilteredAndPaged = createSelector(
selectCardsFiltered,
selectCardsPageInfo,
(cardsFiltered, pageInfo) => {
const start = pageInfo.pageIndex * pageInfo.pageSize;
const end = start + pageInfo.pageSize;
return cardsFiltered.slice(start, end);
},
);
6 changes: 6 additions & 0 deletions src/app/state/card/card.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export interface CardState extends EntityState<Card> {
previous: string | null;
loading: boolean;
error: boolean;
showAll: boolean;
pageSize: number;
pageIndex: number;
}

export const cardAdapter = createEntityAdapter<Card>();
Expand All @@ -17,4 +20,7 @@ export const initialCardState: CardState = cardAdapter.getInitialState({
previous: null,
loading: false,
error: false,
showAll: false,
pageSize: 20,
pageIndex: 0,
});

0 comments on commit 212c3f0

Please sign in to comment.