From 907733f445cef977029a20258503b1292ccdf77f Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 20 Nov 2019 16:58:46 +0100 Subject: [PATCH] Pager to local store. --- .../administration/state/users.state.spec.ts | 11 ++++++-- .../administration/state/users.state.ts | 11 +++++++- frontend/app/framework/utils/pager.spec.ts | 25 +++++++++++++++++++ frontend/app/framework/utils/pager.ts | 18 +++++++++++-- .../shared/services/autosave.service.spec.ts | 2 +- .../app/shared/state/clients.state.spec.ts | 2 +- frontend/app/shared/state/clients.state.ts | 2 +- frontend/app/shared/state/contents.state.ts | 22 +++++++++++----- .../shared/state/contributors.state.spec.ts | 6 ++++- .../app/shared/state/contributors.state.ts | 17 ++++++++++--- .../app/shared/state/patterns.state.spec.ts | 2 +- frontend/app/shared/state/patterns.state.ts | 4 +-- frontend/app/shared/state/roles.state.spec.ts | 2 +- frontend/app/shared/state/roles.state.ts | 4 +-- .../shared/state/rule-events.state.spec.ts | 7 ++++-- .../app/shared/state/rule-events.state.ts | 11 +++++++- .../app/shared/state/workflows.state.spec.ts | 2 +- frontend/app/shared/state/workflows.state.ts | 4 +-- 18 files changed, 122 insertions(+), 30 deletions(-) diff --git a/frontend/app/features/administration/state/users.state.spec.ts b/frontend/app/features/administration/state/users.state.spec.ts index e2d7f422c..eccc79f47 100644 --- a/frontend/app/features/administration/state/users.state.spec.ts +++ b/frontend/app/features/administration/state/users.state.spec.ts @@ -8,7 +8,11 @@ import { of, throwError } from 'rxjs'; import { IMock, It, Mock, Times } from 'typemoq'; -import { DialogService, Pager } from '@app/shared'; +import { + DialogService, + LocalStoreService, + Pager +} from '@app/shared'; import { UserDto, @@ -29,14 +33,17 @@ describe('UsersState', () => { const newUser = createUser(3); let dialogs: IMock; + let localStore: IMock; let usersService: IMock; let usersState: UsersState; beforeEach(() => { dialogs = Mock.ofType(); + localStore = Mock.ofType(); + usersService = Mock.ofType(); - usersState = new UsersState(dialogs.object, usersService.object); + usersState = new UsersState(dialogs.object, localStore.object, usersService.object); }); afterEach(() => { diff --git a/frontend/app/features/administration/state/users.state.ts b/frontend/app/features/administration/state/users.state.ts index 1ee2396ab..077a39851 100644 --- a/frontend/app/features/administration/state/users.state.ts +++ b/frontend/app/features/administration/state/users.state.ts @@ -13,6 +13,7 @@ import '@app/framework/utils/rxjs-extensions'; import { DialogService, + LocalStoreService, Pager, shareSubscribed, State @@ -67,9 +68,17 @@ export class UsersState extends State { constructor( private readonly dialogs: DialogService, + private readonly localStore: LocalStoreService, private readonly usersService: UsersService ) { - super({ users: [], usersPager: Pager.DEFAULT }); + super({ + users: [], + usersPager: Pager.fromLocalStore('users', localStore) + }); + + this.usersPager.subscribe(pager => { + pager.saveTo('users', this.localStore); + }); } public select(id: string | null): Observable { diff --git a/frontend/app/framework/utils/pager.spec.ts b/frontend/app/framework/utils/pager.spec.ts index 96e2e7fc2..ae4d43834 100644 --- a/frontend/app/framework/utils/pager.spec.ts +++ b/frontend/app/framework/utils/pager.spec.ts @@ -5,8 +5,12 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +import { Mock, Times } from 'typemoq'; + import { Pager } from './pager'; +import { LocalStoreService } from './../services/local-store.service'; + describe('Pager', () => { it('should init with default values', () => { const pager_1 = new Pager(0); @@ -211,4 +215,25 @@ describe('Pager', () => { canGoPrev: false }); }); + + it('should create pager from local store', () => { + const localStore = Mock.ofType(); + + localStore.setup(x => x.getInt('my.pageSize', 15)) + .returns((() => 25)); + + const pager = Pager.fromLocalStore('my', localStore.object, 15); + + expect(pager.pageSize).toBe(25); + }); + + it('should save pager to local store', () => { + const localStore = Mock.ofType(); + + const pager = new Pager(0, 0, 25); + + pager.saveTo('my', localStore.object); + + localStore.verify(x => x.setInt('my.pageSize', 25), Times.once()); + }); }); \ No newline at end of file diff --git a/frontend/app/framework/utils/pager.ts b/frontend/app/framework/utils/pager.ts index 7e77aa331..cb8fa0696 100644 --- a/frontend/app/framework/utils/pager.ts +++ b/frontend/app/framework/utils/pager.ts @@ -5,9 +5,9 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -export class Pager { - public static readonly DEFAULT = new Pager(0); +import { LocalStoreService } from './../services/local-store.service'; +export class Pager { public canGoNext = false; public canGoPrev = false; @@ -36,6 +36,20 @@ export class Pager { this.skip = page * pageSize; } + public static fromLocalStore(name: string, localStore: LocalStoreService, size = 10) { + let pageSize = localStore.getInt(`${name}.pageSize`, size); + + if (pageSize < 0 || pageSize > 100) { + pageSize = size; + } + + return new Pager(0, 0, pageSize); + } + + public saveTo(name: string, localStore: LocalStoreService) { + localStore.setInt(`${name}.pageSize`, this.pageSize); + } + public goNext(): Pager { if (!this.canGoNext) { return this; diff --git a/frontend/app/shared/services/autosave.service.spec.ts b/frontend/app/shared/services/autosave.service.spec.ts index cf758968d..fedbb8b70 100644 --- a/frontend/app/shared/services/autosave.service.spec.ts +++ b/frontend/app/shared/services/autosave.service.spec.ts @@ -19,7 +19,7 @@ describe('AutoSaveService', () => { let autoSaveService: AutoSaveService; beforeEach(() => { - localStore = Mock.ofType(LocalStoreService); + localStore = Mock.ofType(); autoSaveService = new AutoSaveService(localStore.object); }); diff --git a/frontend/app/shared/state/clients.state.spec.ts b/frontend/app/shared/state/clients.state.spec.ts index 023d985f7..0cd494fcd 100644 --- a/frontend/app/shared/state/clients.state.spec.ts +++ b/frontend/app/shared/state/clients.state.spec.ts @@ -38,7 +38,7 @@ describe('ClientsState', () => { dialogs = Mock.ofType(); clientsService = Mock.ofType(); - clientsState = new ClientsState(clientsService.object, appsState.object, dialogs.object); + clientsState = new ClientsState(appsState.object, clientsService.object, dialogs.object); }); afterEach(() => { diff --git a/frontend/app/shared/state/clients.state.ts b/frontend/app/shared/state/clients.state.ts index 5395ee3e7..4a0e7f81d 100644 --- a/frontend/app/shared/state/clients.state.ts +++ b/frontend/app/shared/state/clients.state.ts @@ -54,8 +54,8 @@ export class ClientsState extends State { this.project(x => x.canCreate === true); constructor( - private readonly clientsService: ClientsService, private readonly appsState: AppsState, + private readonly clientsService: ClientsService, private readonly dialogs: DialogService ) { super({ clients: [], version: Version.EMPTY }); diff --git a/frontend/app/shared/state/contents.state.ts b/frontend/app/shared/state/contents.state.ts index 3ca6e0353..52aaabe7c 100644 --- a/frontend/app/shared/state/contents.state.ts +++ b/frontend/app/shared/state/contents.state.ts @@ -12,6 +12,7 @@ import { catchError, switchMap, tap } from 'rxjs/operators'; import { DialogService, ErrorDto, + LocalStoreService, Pager, shareSubscribed, State, @@ -95,9 +96,18 @@ export abstract class ContentsStateBase extends State { constructor( private readonly appsState: AppsState, private readonly contentsService: ContentsService, - private readonly dialogs: DialogService + private readonly dialogs: DialogService, + private readonly localStore: LocalStoreService ) { - super({ contents: [], contentsPager: Pager.DEFAULT, contentsQueryJson: '' }); + super({ + contents: [], + contentsPager: Pager.fromLocalStore('contents', localStore), + contentsQueryJson: '' + }); + + this.contentsPager.subscribe(pager => { + pager.saveTo('contents', this.localStore); + }); } public select(id: string | null): Observable { @@ -349,10 +359,10 @@ export abstract class ContentsStateBase extends State { @Injectable() export class ContentsState extends ContentsStateBase { - constructor(appsState: AppsState, contentsService: ContentsService, dialogs: DialogService, + constructor(appsState: AppsState, contentsService: ContentsService, dialogs: DialogService, localStore: LocalStoreService, private readonly schemasState: SchemasState ) { - super(appsState, contentsService, dialogs); + super(appsState, contentsService, dialogs, localStore); } protected get schemaId() { @@ -365,9 +375,9 @@ export class ManualContentsState extends ContentsStateBase { public schema: SchemaDto; constructor( - appsState: AppsState, contentsService: ContentsService, dialogs: DialogService + appsState: AppsState, contentsService: ContentsService, dialogs: DialogService, localStore: LocalStoreService ) { - super(appsState, contentsService, dialogs); + super(appsState, contentsService, dialogs, localStore); } protected get schemaId() { diff --git a/frontend/app/shared/state/contributors.state.spec.ts b/frontend/app/shared/state/contributors.state.spec.ts index d260d902a..46897e05e 100644 --- a/frontend/app/shared/state/contributors.state.spec.ts +++ b/frontend/app/shared/state/contributors.state.spec.ts @@ -14,6 +14,7 @@ import { ContributorsService, ContributorsState, DialogService, + LocalStoreService, Pager, versioned } from '@app/shared/internal'; @@ -41,12 +42,15 @@ describe('ContributorsState', () => { let dialogs: IMock; let contributorsService: IMock; let contributorsState: ContributorsState; + let localStore: IMock; beforeEach(() => { dialogs = Mock.ofType(); + localStore = Mock.ofType(); + contributorsService = Mock.ofType(); - contributorsState = new ContributorsState(contributorsService.object, appsState.object, dialogs.object); + contributorsState = new ContributorsState(appsState.object, contributorsService.object, dialogs.object, localStore.object); contributorsService.setup(x => x.getContributors(app)) .returns(() => of(versioned(version, oldContributors))).verifiable(); diff --git a/frontend/app/shared/state/contributors.state.ts b/frontend/app/shared/state/contributors.state.ts index 4852e003e..b17419249 100644 --- a/frontend/app/shared/state/contributors.state.ts +++ b/frontend/app/shared/state/contributors.state.ts @@ -12,6 +12,7 @@ import { catchError, tap } from 'rxjs/operators'; import { DialogService, ErrorDto, + LocalStoreService, Pager, shareMapSubscribed, shareSubscribed, @@ -87,11 +88,21 @@ export class ContributorsState extends State { this.projectFrom2(this.contributorsPager, this.filtered, (p, c) => getPagedContributors(c, p)); constructor( - private readonly contributorsService: ContributorsService, private readonly appsState: AppsState, - private readonly dialogs: DialogService + private readonly contributorsService: ContributorsService, + private readonly dialogs: DialogService, + private readonly localStore: LocalStoreService ) { - super({ contributors: [], contributorsPager: Pager.DEFAULT, maxContributors: -1, version: Version.EMPTY }); + super({ + contributors: [], + contributorsPager: Pager.fromLocalStore('contributors', localStore), + maxContributors: -1, + version: Version.EMPTY + }); + + this.contributorsPager.subscribe(pager => { + pager.saveTo('contributors', this.localStore); + }); } public load(isReload = false): Observable { diff --git a/frontend/app/shared/state/patterns.state.spec.ts b/frontend/app/shared/state/patterns.state.spec.ts index acb2fe09c..e367b4dea 100644 --- a/frontend/app/shared/state/patterns.state.spec.ts +++ b/frontend/app/shared/state/patterns.state.spec.ts @@ -38,7 +38,7 @@ describe('PatternsState', () => { dialogs = Mock.ofType(); patternsService = Mock.ofType(); - patternsState = new PatternsState(patternsService.object, appsState.object, dialogs.object); + patternsState = new PatternsState(appsState.object, dialogs.object, patternsService.object); }); afterEach(() => { diff --git a/frontend/app/shared/state/patterns.state.ts b/frontend/app/shared/state/patterns.state.ts index f2fb1b570..7055d8191 100644 --- a/frontend/app/shared/state/patterns.state.ts +++ b/frontend/app/shared/state/patterns.state.ts @@ -54,9 +54,9 @@ export class PatternsState extends State { this.project(x => x.canCreate === true); constructor( - private readonly patternsService: PatternsService, private readonly appsState: AppsState, - private readonly dialogs: DialogService + private readonly dialogs: DialogService, + private readonly patternsService: PatternsService ) { super({ patterns: [], version: Version.EMPTY }); } diff --git a/frontend/app/shared/state/roles.state.spec.ts b/frontend/app/shared/state/roles.state.spec.ts index 022e0696d..78ff2ac80 100644 --- a/frontend/app/shared/state/roles.state.spec.ts +++ b/frontend/app/shared/state/roles.state.spec.ts @@ -38,7 +38,7 @@ describe('RolesState', () => { dialogs = Mock.ofType(); rolesService = Mock.ofType(); - rolesState = new RolesState(rolesService.object, appsState.object, dialogs.object); + rolesState = new RolesState(appsState.object, dialogs.object, rolesService.object); }); describe('Loading', () => { diff --git a/frontend/app/shared/state/roles.state.ts b/frontend/app/shared/state/roles.state.ts index 0d8e0979b..fade507e7 100644 --- a/frontend/app/shared/state/roles.state.ts +++ b/frontend/app/shared/state/roles.state.ts @@ -54,9 +54,9 @@ export class RolesState extends State { this.project(x => x.canCreate === true); constructor( - private readonly rolesService: RolesService, private readonly appsState: AppsState, - private readonly dialogs: DialogService + private readonly dialogs: DialogService, + private readonly rolesService: RolesService ) { super({ roles: [], version: Version.EMPTY }); } diff --git a/frontend/app/shared/state/rule-events.state.spec.ts b/frontend/app/shared/state/rule-events.state.spec.ts index a75db1811..b694c377d 100644 --- a/frontend/app/shared/state/rule-events.state.spec.ts +++ b/frontend/app/shared/state/rule-events.state.spec.ts @@ -10,6 +10,7 @@ import { IMock, It, Mock, Times } from 'typemoq'; import { DialogService, + LocalStoreService, Pager, RuleEventsDto, RuleEventsState, @@ -34,16 +35,18 @@ describe('RuleEventsState', () => { let dialogs: IMock; let rulesService: IMock; let ruleEventsState: RuleEventsState; + let localStore: IMock; beforeEach(() => { dialogs = Mock.ofType(); - rulesService = Mock.ofType(); + localStore = Mock.ofType(); + rulesService = Mock.ofType(); rulesService.setup(x => x.getEvents(app, 10, 0, undefined)) .returns(() => of(new RuleEventsDto(200, oldRuleEvents))); - ruleEventsState = new RuleEventsState(appsState.object, dialogs.object, rulesService.object); + ruleEventsState = new RuleEventsState(appsState.object, dialogs.object, localStore.object, rulesService.object); ruleEventsState.load().subscribe(); }); diff --git a/frontend/app/shared/state/rule-events.state.ts b/frontend/app/shared/state/rule-events.state.ts index 04c96b4f4..3d2fdc5e1 100644 --- a/frontend/app/shared/state/rule-events.state.ts +++ b/frontend/app/shared/state/rule-events.state.ts @@ -11,6 +11,7 @@ import { tap } from 'rxjs/operators'; import { DialogService, + LocalStoreService, Pager, shareSubscribed, State @@ -48,9 +49,17 @@ export class RuleEventsState extends State { constructor( private readonly appsState: AppsState, private readonly dialogs: DialogService, + private readonly localStore: LocalStoreService, private readonly rulesService: RulesService ) { - super({ ruleEvents: [], ruleEventsPager: Pager.DEFAULT }); + super({ + ruleEvents: [], + ruleEventsPager: Pager.fromLocalStore('rule-events', localStore) + }); + + this.ruleEventsPager.subscribe(pager => { + pager.saveTo('rule-events', this.localStore); + }); } public load(isReload = false): Observable { diff --git a/frontend/app/shared/state/workflows.state.spec.ts b/frontend/app/shared/state/workflows.state.spec.ts index 118c15d88..3ae064688 100644 --- a/frontend/app/shared/state/workflows.state.spec.ts +++ b/frontend/app/shared/state/workflows.state.spec.ts @@ -38,7 +38,7 @@ describe('WorkflowsState', () => { dialogs = Mock.ofType(); workflowsService = Mock.ofType(); - workflowsState = new WorkflowsState(workflowsService.object, appsState.object, dialogs.object); + workflowsState = new WorkflowsState(appsState.object, dialogs.object, workflowsService.object); }); afterEach(() => { diff --git a/frontend/app/shared/state/workflows.state.ts b/frontend/app/shared/state/workflows.state.ts index 1dd7f0ed8..4bb50b44a 100644 --- a/frontend/app/shared/state/workflows.state.ts +++ b/frontend/app/shared/state/workflows.state.ts @@ -56,9 +56,9 @@ export class WorkflowsState extends State { this.project(x => x.canCreate === true); constructor( - private readonly workflowsService: WorkflowsService, private readonly appsState: AppsState, - private readonly dialogs: DialogService + private readonly dialogs: DialogService, + private readonly workflowsService: WorkflowsService ) { super({ errors: [], workflows: [], version: Version.EMPTY }); }