From 714bc232ed3c53a9c53bc20ef9aa7fa132b8f708 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sat, 19 Jan 2019 18:29:23 +0100 Subject: [PATCH] UI fix and backup fix. --- .../Contents/BackupContents.cs | 11 +++++++++-- .../Schemas/BackupSchemas.cs | 3 +++ .../pages/contents/contents-filters-page.component.ts | 9 ++------- .../content/pages/contents/contents-page.component.ts | 11 +++-------- .../content/pages/schemas/schemas-page.component.html | 2 +- .../app/framework/angular/routers/router-utils.ts | 8 +------- .../shared/components/schema-category.component.ts | 5 ----- .../guards/schema-must-not-be-singleton.guard.spec.ts | 2 +- src/Squidex/app/shared/state/apps.state.ts | 6 +++++- src/Squidex/app/shared/state/contents.state.ts | 6 +++++- src/Squidex/app/shared/state/schemas.state.ts | 6 +++++- 11 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/Squidex.Domain.Apps.Entities/Contents/BackupContents.cs b/src/Squidex.Domain.Apps.Entities/Contents/BackupContents.cs index dd0f466cb..5f4bef81d 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/BackupContents.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/BackupContents.cs @@ -7,10 +7,12 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Squidex.Domain.Apps.Entities.Backup; using Squidex.Domain.Apps.Entities.Contents.State; using Squidex.Domain.Apps.Events.Contents; +using Squidex.Domain.Apps.Events.Schemas; using Squidex.Infrastructure; using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.States; @@ -20,7 +22,7 @@ namespace Squidex.Domain.Apps.Entities.Contents { public sealed class BackupContents : BackupHandlerWithStore { - private readonly HashSet contentIds = new HashSet(); + private readonly Dictionary> contentIdsBySchemaId = new Dictionary>(); public override string Name { get; } = "Contents"; @@ -34,7 +36,10 @@ namespace Squidex.Domain.Apps.Entities.Contents switch (@event.Payload) { case ContentCreated contentCreated: - contentIds.Add(contentCreated.ContentId); + contentIdsBySchemaId.GetOrAddNew(contentCreated.SchemaId.Id).Add(contentCreated.ContentId); + break; + case SchemaDeleted schemaDeleted: + contentIdsBySchemaId.Remove(schemaDeleted.SchemaId.Id); break; } @@ -43,6 +48,8 @@ namespace Squidex.Domain.Apps.Entities.Contents public override Task RestoreAsync(Guid appId, BackupReader reader) { + var contentIds = contentIdsBySchemaId.Values.SelectMany(x => x); + return RebuildManyAsync(contentIds, id => RebuildAsync(id, (e, s) => s.Apply(e))); } } diff --git a/src/Squidex.Domain.Apps.Entities/Schemas/BackupSchemas.cs b/src/Squidex.Domain.Apps.Entities/Schemas/BackupSchemas.cs index 371f957c8..3718ac35f 100644 --- a/src/Squidex.Domain.Apps.Entities/Schemas/BackupSchemas.cs +++ b/src/Squidex.Domain.Apps.Entities/Schemas/BackupSchemas.cs @@ -39,6 +39,9 @@ namespace Squidex.Domain.Apps.Entities.Schemas case SchemaCreated schemaCreated: schemasByName[schemaCreated.SchemaId.Name] = schemaCreated.SchemaId.Id; break; + case SchemaDeleted schemaDeleted: + schemasByName.Remove(schemaDeleted.SchemaId.Name); + break; } return TaskHelper.True; diff --git a/src/Squidex/app/features/content/pages/contents/contents-filters-page.component.ts b/src/Squidex/app/features/content/pages/contents/contents-filters-page.component.ts index 3f6263c7c..9701956cc 100644 --- a/src/Squidex/app/features/content/pages/contents/contents-filters-page.component.ts +++ b/src/Squidex/app/features/content/pages/contents/contents-filters-page.component.ts @@ -6,13 +6,11 @@ */ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; -import { filter, onErrorResumeNext, takeUntil } from 'rxjs/operators'; +import { onErrorResumeNext } from 'rxjs/operators'; import { ContentsState, - navigatedToOtherComponent, Queries, SchemasState, UIState @@ -31,7 +29,6 @@ export class ContentsFiltersPageComponent implements OnDestroy, OnInit { constructor( private readonly contentsState: ContentsState, private readonly schemasState: SchemasState, - private readonly router: Router, private readonly uiState: UIState ) { } @@ -41,10 +38,8 @@ export class ContentsFiltersPageComponent implements OnDestroy, OnInit { } public ngOnInit() { - const routeChanged = this.router.events.pipe(filter(navigatedToOtherComponent(this.router))); - this.selectedSchemaSubscription = - this.schemasState.selectedSchema.pipe(takeUntil(routeChanged)) + this.schemasState.selectedSchema .subscribe(schema => { if (schema) { this.schemaQueries = new Queries(this.uiState, `schemas.${schema.name}`); diff --git a/src/Squidex/app/features/content/pages/contents/contents-page.component.ts b/src/Squidex/app/features/content/pages/contents/contents-page.component.ts index 3dfc72f53..d0f79bd98 100644 --- a/src/Squidex/app/features/content/pages/contents/contents-page.component.ts +++ b/src/Squidex/app/features/content/pages/contents/contents-page.component.ts @@ -6,9 +6,8 @@ */ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; -import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; -import { filter, onErrorResumeNext, switchMap, takeUntil, tap } from 'rxjs/operators'; +import { onErrorResumeNext, switchMap, tap } from 'rxjs/operators'; import { AppLanguageDto, @@ -18,7 +17,6 @@ import { ImmutableArray, LanguagesState, ModalModel, - navigatedToOtherComponent, Queries, SchemaDetailsDto, SchemasState, @@ -61,7 +59,6 @@ export class ContentsPageComponent implements OnDestroy, OnInit { public readonly contentsState: ContentsState, private readonly languagesState: LanguagesState, private readonly schemasState: SchemasState, - private readonly router: Router, private readonly uiState: UIState ) { } @@ -73,10 +70,8 @@ export class ContentsPageComponent implements OnDestroy, OnInit { } public ngOnInit() { - const routeChanged = this.router.events.pipe(filter(navigatedToOtherComponent(this.router))); - this.selectedSchemaSubscription = - this.schemasState.selectedSchema.pipe(takeUntil(routeChanged)) + this.schemasState.selectedSchema .subscribe(schema => { this.resetSelection(); @@ -87,7 +82,7 @@ export class ContentsPageComponent implements OnDestroy, OnInit { }); this.contentsSubscription = - this.contentsState.contents.pipe(takeUntil(routeChanged)) + this.contentsState.contents .subscribe(() => { this.updateSelectionSummary(); }); diff --git a/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html b/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html index c1ecd5c9a..a270463cd 100644 --- a/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html +++ b/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html @@ -17,7 +17,7 @@ - Types.is(e, RoutesRecognized) && childComponent(e.state) !== childComponent(router.routerState.snapshot); } \ No newline at end of file diff --git a/src/Squidex/app/shared/components/schema-category.component.ts b/src/Squidex/app/shared/components/schema-category.component.ts index 923686972..7daecdf73 100644 --- a/src/Squidex/app/shared/components/schema-category.component.ts +++ b/src/Squidex/app/shared/components/schema-category.component.ts @@ -46,9 +46,6 @@ export class SchemaCategoryComponent implements OnInit, OnChanges { @Input() public schemas: ImmutableArray; - @Input() - public suffix: string; - public displayName: string; public schemasFiltered: ImmutableArray; @@ -106,8 +103,6 @@ export class SchemaCategoryComponent implements OnInit, OnChanges { public schemaRoute(schema: SchemaDto) { if (schema.isSingleton && this.routeSingletonToContent) { return [schema.name, schema.id]; - } else if (this.suffix) { - return [schema.name, this.suffix]; } else { return [schema.name]; } diff --git a/src/Squidex/app/shared/guards/schema-must-not-be-singleton.guard.spec.ts b/src/Squidex/app/shared/guards/schema-must-not-be-singleton.guard.spec.ts index ba845da60..2de66fc8b 100644 --- a/src/Squidex/app/shared/guards/schema-must-not-be-singleton.guard.spec.ts +++ b/src/Squidex/app/shared/guards/schema-must-not-be-singleton.guard.spec.ts @@ -56,7 +56,7 @@ describe('SchemaMustNotBeSingletonGuard', () => { const state: RouterStateSnapshot = { url: 'schemas/name/' }; schemasState.setup(x => x.selectedSchema) - .returns(() => of(null)); + .returns(() => of(undefined)); let result: boolean; diff --git a/src/Squidex/app/shared/state/apps.state.ts b/src/Squidex/app/shared/state/apps.state.ts index 517c42a76..1eff17ed3 100644 --- a/src/Squidex/app/shared/state/apps.state.ts +++ b/src/Squidex/app/shared/state/apps.state.ts @@ -28,6 +28,10 @@ interface Snapshot { selectedApp: AppDto | null; } +function sameApp(lhs: AppDto, rhs?: AppDto): boolean { + return lhs === rhs || (!!lhs && !!rhs && lhs.id === rhs.id); +} + @Injectable() export class AppsState extends State { public get appName() { @@ -36,7 +40,7 @@ export class AppsState extends State { public selectedApp = this.changes.pipe(map(s => s.selectedApp), - distinctUntilChanged()); + distinctUntilChanged(sameApp)); public apps = this.changes.pipe(map(s => s.apps), diff --git a/src/Squidex/app/shared/state/contents.state.ts b/src/Squidex/app/shared/state/contents.state.ts index 481bb0fa9..41612be52 100644 --- a/src/Squidex/app/shared/state/contents.state.ts +++ b/src/Squidex/app/shared/state/contents.state.ts @@ -39,10 +39,14 @@ interface Snapshot { selectedContent?: ContentDto | null; } +function sameContent(lhs: ContentDto, rhs?: ContentDto): boolean { + return lhs === rhs || (!!lhs && !!rhs && lhs.id === rhs.id && lhs.version === rhs.version); +} + export abstract class ContentsStateBase extends State { public selectedContent = this.changes.pipe(map(x => x.selectedContent), - distinctUntilChanged()); + distinctUntilChanged(sameContent)); public contents = this.changes.pipe(map(x => x.contents), diff --git a/src/Squidex/app/shared/state/schemas.state.ts b/src/Squidex/app/shared/state/schemas.state.ts index 4e3d65fd3..69819c518 100644 --- a/src/Squidex/app/shared/state/schemas.state.ts +++ b/src/Squidex/app/shared/state/schemas.state.ts @@ -53,11 +53,15 @@ interface Snapshot { selectedSchema?: SchemaDetailsDto | null; } +function sameSchema(lhs: SchemaDetailsDto | null, rhs?: SchemaDetailsDto | null): boolean { + return lhs === rhs || (!!lhs && !!rhs && lhs.id === rhs.id && lhs.version === rhs.version); +} + @Injectable() export class SchemasState extends State { public selectedSchema = this.changes.pipe(map(x => x.selectedSchema), - distinctUntilChanged()); + distinctUntilChanged(sameSchema)); public categories = this.changes.pipe(map(x => ImmutableArray.of(Object.keys(x.categories)).sortByStringAsc(s => s)),