From 71ce2a8a71398ab31b38ff1ed55c415cae3a4e52 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Wed, 19 Jun 2019 19:19:53 +0200 Subject: [PATCH 01/16] Fix status null checks. --- .../Contents/MongoContentRepository.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs index d28d8078d..aa24583e6 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs @@ -87,9 +87,8 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents public async Task> QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, HashSet ids, bool includeDraft = true) { Guard.NotNull(app, nameof(app)); - Guard.NotNull(schema, nameof(schema)); - Guard.NotNull(status, nameof(status)); Guard.NotNull(ids, nameof(ids)); + Guard.NotNull(schema, nameof(schema)); using (Profiler.TraceMethod("QueryAsyncByIds")) { @@ -100,7 +99,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents public async Task> QueryAsync(IAppEntity app, Status[] status, HashSet ids, bool includeDraft = true) { Guard.NotNull(app, nameof(app)); - Guard.NotNull(status, nameof(status)); Guard.NotNull(ids, nameof(ids)); using (Profiler.TraceMethod("QueryAsyncByIdsWithoutSchema")) @@ -113,7 +111,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents { Guard.NotNull(app, nameof(app)); Guard.NotNull(schema, nameof(schema)); - Guard.NotNull(status, nameof(status)); using (Profiler.TraceMethod()) { From 2c1a5ba22af8ba559fe0a5c519fa0d8747a9fd92 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Wed, 19 Jun 2019 20:14:20 +0200 Subject: [PATCH 02/16] Bugfixes. --- .../Apps/RoleExtensions.cs | 2 +- .../Api/Controllers/Apps/Models/AppDto.cs | 5 ++ .../Controllers/Assets/Models/AssetsDto.cs | 2 +- .../pages/content/content-page.component.ts | 2 +- .../shared/assets-editor.component.html | 4 +- .../pages/backups/backups-page.component.html | 2 +- .../pages/clients/client.component.ts | 20 +++--- .../pages/languages/language.component.ts | 16 ++--- .../pages/patterns/pattern.component.ts | 18 ++--- .../angular/forms/file-drop.directive.ts | 13 ++-- .../components/asset-dialog.component.ts | 2 +- .../components/asset-uploader.component.html | 72 ++++++++++--------- .../shared/components/asset.component.html | 12 +++- .../components/assets-list.component.html | 2 +- .../components/markdown-editor.component.html | 2 +- .../components/rich-editor.component.html | 2 +- .../app/shared/services/apps.service.ts | 2 + .../app/shared/services/assets.service.ts | 6 +- src/Squidex/app/shared/state/assets.state.ts | 10 ++- .../Apps/RoleExtensionsTests.cs | 9 +++ 20 files changed, 120 insertions(+), 83 deletions(-) diff --git a/src/Squidex.Domain.Apps.Entities/Apps/RoleExtensions.cs b/src/Squidex.Domain.Apps.Entities/Apps/RoleExtensions.cs index 0e0eddad9..f6464d5dc 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/RoleExtensions.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/RoleExtensions.cs @@ -55,7 +55,7 @@ namespace Squidex.Domain.Apps.Entities.Apps { return id; } - })); + }).Where(x => x != "common")); } } } diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs index 1c2c28920..6d706dc30 100644 --- a/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs @@ -182,6 +182,11 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models AddPostLink("schemas/create", controller.Url(x => nameof(x.PostSchema), values)); } + if (controller.HasPermission(AllPermissions.AppAssetsCreate, Name, permissions: permissions)) + { + AddPostLink("assets/create", controller.Url(x => nameof(x.PostSchema), values)); + } + return this; } } diff --git a/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs b/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs index c0870d583..f6ceca82d 100644 --- a/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs @@ -59,7 +59,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models response.AddPostLink("create", controller.Url(x => nameof(x.PostAsset), values)); } - response.AddDeleteLink("tags", controller.Url(x => nameof(x.GetTags), values)); + response.AddGetLink("tags", controller.Url(x => nameof(x.GetTags), values)); return response; } diff --git a/src/Squidex/app/features/content/pages/content/content-page.component.ts b/src/Squidex/app/features/content/pages/content/content-page.component.ts index fd4afb1a6..94c3f79c2 100644 --- a/src/Squidex/app/features/content/pages/content/content-page.component.ts +++ b/src/Squidex/app/features/content/pages/content/content-page.component.ts @@ -183,7 +183,7 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD private loadContent(data: any) { this.contentForm.loadContent(data); - this.contentForm.setEnabled(!this.content || this.content.canUpdate); + this.contentForm.setEnabled(this.content && !this.content.canUpdate); } public discardChanges() { diff --git a/src/Squidex/app/features/content/shared/assets-editor.component.html b/src/Squidex/app/features/content/shared/assets-editor.component.html index 4bf9cdadf..01e7337ca 100644 --- a/src/Squidex/app/features/content/shared/assets-editor.component.html +++ b/src/Squidex/app/features/content/shared/assets-editor.component.html @@ -1,9 +1,9 @@ -
+
-
+
Drop files or click
diff --git a/src/Squidex/app/features/settings/pages/backups/backups-page.component.html b/src/Squidex/app/features/settings/pages/backups/backups-page.component.html index 0c326e4ca..94ade6d25 100644 --- a/src/Squidex/app/features/settings/pages/backups/backups-page.component.html +++ b/src/Squidex/app/features/settings/pages/backups/backups-page.component.html @@ -52,7 +52,7 @@ Duration:
-
+
{{backup.started | sqxFromNow}}
diff --git a/src/Squidex/app/features/settings/pages/clients/client.component.ts b/src/Squidex/app/features/settings/pages/clients/client.component.ts index dcc038b66..76c7bc9d3 100644 --- a/src/Squidex/app/features/settings/pages/clients/client.component.ts +++ b/src/Squidex/app/features/settings/pages/clients/client.component.ts @@ -5,7 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { Component, Input, OnChanges } from '@angular/core'; +import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { FormBuilder } from '@angular/forms'; import { @@ -58,16 +58,18 @@ export class ClientComponent implements OnChanges { ) { } - public ngOnChanges() { - this.renameForm.load(this.client); + public ngOnChanges(changes: SimpleChanges) { + if (changes['client']) { + this.renameForm.load(this.client); - const app = this.appsState.appName; + const app = this.appsState.appName; - this.connectHttpText = connectHttpText(this.apiUrl, app, this.client); - this.connectCLINetText = connectCLINetText(app, this.client, this.apiUrl); - this.connectCLINixText = connectCLINixText(app, this.client, this.apiUrl); - this.connectCLIWinText = connectCLIWinText(app, this.client, this.apiUrl); - this.connectLibraryText = connectLibrary(this.apiUrl, app, this.client); + this.connectHttpText = connectHttpText(this.apiUrl, app, this.client); + this.connectCLINetText = connectCLINetText(app, this.client, this.apiUrl); + this.connectCLINixText = connectCLINixText(app, this.client, this.apiUrl); + this.connectCLIWinText = connectCLIWinText(app, this.client, this.apiUrl); + this.connectLibraryText = connectLibrary(this.apiUrl, app, this.client); + } } public revoke() { diff --git a/src/Squidex/app/features/settings/pages/languages/language.component.ts b/src/Squidex/app/features/settings/pages/languages/language.component.ts index 8956b6a2a..ecfc7a583 100644 --- a/src/Squidex/app/features/settings/pages/languages/language.component.ts +++ b/src/Squidex/app/features/settings/pages/languages/language.component.ts @@ -48,7 +48,12 @@ export class LanguageComponent implements OnChanges { } public ngOnChanges() { - this.resetForm(); + this.isEditable = this.language.canUpdate; + + this.editForm.load(this.language); + this.editForm.setEnabled(this.isEditable); + + this.otherLanguage = this.fallbackLanguagesNew.at(0); } public toggleEditing() { @@ -94,15 +99,6 @@ export class LanguageComponent implements OnChanges { this.otherLanguage = this.fallbackLanguagesNew.at(0); } - private resetForm() { - this.isEditable = this.language.canUpdate; - - this.editForm.load(this.language); - this.editForm.setEnabled(this.isEditable); - - this.otherLanguage = this.fallbackLanguagesNew.at(0); - } - public trackByLanguage(index: number, language: AppLanguageDto) { return language.iso2Code; } diff --git a/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts b/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts index a4cd887b1..43572f708 100644 --- a/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts +++ b/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts @@ -5,7 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { FormBuilder } from '@angular/forms'; import { @@ -19,7 +19,7 @@ import { styleUrls: ['./pattern.component.scss'], templateUrl: './pattern.component.html' }) -export class PatternComponent implements OnInit { +export class PatternComponent implements OnChanges { @Input() public pattern: PatternDto; @@ -34,12 +34,14 @@ export class PatternComponent implements OnInit { ) { } - public ngOnInit() { - this.isEditable = !this.pattern || this.pattern.canUpdate; - this.isDeletable = this.pattern && this.pattern.canDelete; + public ngOnChanges(changes: SimpleChanges) { + if (changes['pattern']) { + this.isEditable = !this.pattern || this.pattern.canUpdate; + this.isDeletable = this.pattern && this.pattern.canDelete; - this.editForm.load(this.pattern); - this.editForm.setEnabled(this.isEditable); + this.editForm.load(this.pattern); + this.editForm.setEnabled(this.isEditable); + } } public cancel() { @@ -61,7 +63,7 @@ export class PatternComponent implements OnInit { if (this.pattern) { this.patternsState.update(this.pattern, value) .subscribe(newPattern => { - this.editForm.submitCompleted({ newValue: newPattern }); + this.editForm.submitCompleted(newPattern); }, error => { this.editForm.submitFailed(error); }); diff --git a/src/Squidex/app/framework/angular/forms/file-drop.directive.ts b/src/Squidex/app/framework/angular/forms/file-drop.directive.ts index 027413c90..adf2eec5c 100644 --- a/src/Squidex/app/framework/angular/forms/file-drop.directive.ts +++ b/src/Squidex/app/framework/angular/forms/file-drop.directive.ts @@ -19,7 +19,7 @@ const ImageTypes = [ ]; @Directive({ - selector: '[sqxFileDrop]' + selector: '[sqxDropFile]' }) export class FileDropDirective { private dragCounter = 0; @@ -33,7 +33,10 @@ export class FileDropDirective { @Input() public noDrop: boolean; - @Output('sqxFileDrop') + @Input('sqxDropDisabled') + public disabled = false; + + @Output('sqxDropFile') public drop = new EventEmitter(); constructor( @@ -60,7 +63,7 @@ export class FileDropDirective { } } - if (result.length > 0) { + if (result.length > 0 && !this.disabled) { this.drop.emit(result); } @@ -127,7 +130,7 @@ export class FileDropDirective { private dragStart() { this.dragCounter++; - if (this.dragCounter === 1) { + if (this.dragCounter === 1 && !this.disabled) { this.renderer.addClass(this.element.nativeElement, 'drag'); } } @@ -135,7 +138,7 @@ export class FileDropDirective { private dragEnd(number?: number ) { this.dragCounter = number || this.dragCounter - 1; - if (this.dragCounter === 0) { + if (this.dragCounter === 0 && !this.disabled) { this.renderer.removeClass(this.element.nativeElement, 'drag'); } } diff --git a/src/Squidex/app/shared/components/asset-dialog.component.ts b/src/Squidex/app/shared/components/asset-dialog.component.ts index 463267626..564b35b52 100644 --- a/src/Squidex/app/shared/components/asset-dialog.component.ts +++ b/src/Squidex/app/shared/components/asset-dialog.component.ts @@ -55,7 +55,7 @@ export class AssetDialogComponent extends StatefulComponent implements OnInit { this.isEditable = this.asset.canUpdate; this.annotateForm.load(this.asset); - this.annotateForm.setEnabled(!this.isEditable); + this.annotateForm.setEnabled(this.isEditable); } public generateSlug() { diff --git a/src/Squidex/app/shared/components/asset-uploader.component.html b/src/Squidex/app/shared/components/asset-uploader.component.html index 01abb1b31..3f9a43764 100644 --- a/src/Squidex/app/shared/components/asset-uploader.component.html +++ b/src/Squidex/app/shared/components/asset-uploader.component.html @@ -1,44 +1,46 @@ - - + \ No newline at end of file diff --git a/src/Squidex/app/shared/components/asset.component.html b/src/Squidex/app/shared/components/asset.component.html index 2cfdedcd1..583b66749 100644 --- a/src/Squidex/app/shared/components/asset.component.html +++ b/src/Squidex/app/shared/components/asset.component.html @@ -1,5 +1,8 @@ -
+
@@ -74,7 +77,10 @@ -
+
@@ -125,7 +131,7 @@ - diff --git a/src/Squidex/app/shared/components/assets-list.component.html b/src/Squidex/app/shared/components/assets-list.component.html index 592e44e29..99d7e82ab 100644 --- a/src/Squidex/app/shared/components/assets-list.component.html +++ b/src/Squidex/app/shared/components/assets-list.component.html @@ -1,4 +1,4 @@ -
+

Drop files here to upload

or
diff --git a/src/Squidex/app/shared/components/markdown-editor.component.html b/src/Squidex/app/shared/components/markdown-editor.component.html index 322e46392..819a39c12 100644 --- a/src/Squidex/app/shared/components/markdown-editor.component.html +++ b/src/Squidex/app/shared/components/markdown-editor.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/Squidex/app/shared/components/rich-editor.component.html b/src/Squidex/app/shared/components/rich-editor.component.html index 36cb40d19..44a1469e8 100644 --- a/src/Squidex/app/shared/components/rich-editor.component.html +++ b/src/Squidex/app/shared/components/rich-editor.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/Squidex/app/shared/services/apps.service.ts b/src/Squidex/app/shared/services/apps.service.ts index e5a82b468..9ed139d17 100644 --- a/src/Squidex/app/shared/services/apps.service.ts +++ b/src/Squidex/app/shared/services/apps.service.ts @@ -35,6 +35,7 @@ export class AppDto { public readonly canReadRoles: boolean; public readonly canReadRules: boolean; public readonly canReadSchemas: boolean; + public readonly canUploadAssets: boolean; constructor(links: ResourceLinks, public readonly id: string, @@ -61,6 +62,7 @@ export class AppDto { this.canReadRoles = hasAnyLink(links, 'roles'); this.canReadRules = hasAnyLink(links, 'rules'); this.canReadSchemas = hasAnyLink(links, 'schemas'); + this.canUploadAssets = hasAnyLink(links, 'assets/create'); } } diff --git a/src/Squidex/app/shared/services/assets.service.ts b/src/Squidex/app/shared/services/assets.service.ts index 715047113..9e840e4cf 100644 --- a/src/Squidex/app/shared/services/assets.service.ts +++ b/src/Squidex/app/shared/services/assets.service.ts @@ -27,7 +27,11 @@ import { Versioned } from '@app/framework'; -export class AssetsDto extends ResultSet {} +export class AssetsDto extends ResultSet { + public get canCreate() { + return hasAnyLink(this._links, 'create'); + } +} export class AssetDto { public readonly _meta: Metadata = {}; diff --git a/src/Squidex/app/shared/state/assets.state.ts b/src/Squidex/app/shared/state/assets.state.ts index 4b50f56a9..09eeabc0a 100644 --- a/src/Squidex/app/shared/state/assets.state.ts +++ b/src/Squidex/app/shared/state/assets.state.ts @@ -39,6 +39,9 @@ interface Snapshot { // Indicates if the assets are loaded. isLoaded?: boolean; + + // Indicates if the user can create assets. + canCreate?: boolean; } @Injectable() @@ -64,6 +67,9 @@ export class AssetsState extends State { public isLoaded = this.project(x => !!x.isLoaded); + public canCreate = + this.project(x => !!x.canCreate); + constructor( private readonly appsState: AppsState, private readonly assetsService: AssetsService, @@ -89,7 +95,7 @@ export class AssetsState extends State { Object.keys(this.snapshot.tagsSelected)), this.assetsService.getTags(this.appName) ).pipe( - tap(([ { items, total }, tags ]) => { + tap(([ { items, total, canCreate }, tags ]) => { if (isReload) { this.dialogs.notifyInfo('Assets reloaded.'); } @@ -98,7 +104,7 @@ export class AssetsState extends State { const assets = ImmutableArray.of(items); const assetsPager = s.assetsPager.setCount(total); - return { ...s, assets, assetsPager, isLoaded: true, tags }; + return { ...s, assets, assetsPager, isLoaded: true, tags, canCreate }; }); }), shareSubscribed(this.dialogs)); diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/RoleExtensionsTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/RoleExtensionsTests.cs index 5cb8fb01b..cfd3c06af 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/RoleExtensionsTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/RoleExtensionsTests.cs @@ -67,5 +67,14 @@ namespace Squidex.Domain.Apps.Entities.Apps Assert.Equal(Permission.Any, result.First().Id); } + + [Fact] + public void Should_remove_common_permission() + { + var source = new PermissionSet("squidex.apps.my-app.common"); + var result = source.WithoutApp("my-app"); + + Assert.Empty(result); + } } } From 6ac7dbc682b2c1e2f2080d90bc2ce4b88d8094ed Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Wed, 19 Jun 2019 20:19:26 +0200 Subject: [PATCH 03/16] Small firefox fix. --- .../app/features/assets/pages/assets-page.component.html | 2 +- .../app/shared/components/assets-selector.component.html | 2 +- .../app/shared/components/language-selector.component.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Squidex/app/features/assets/pages/assets-page.component.html b/src/Squidex/app/features/assets/pages/assets-page.component.html index d169e27fe..a16cf64f0 100644 --- a/src/Squidex/app/features/assets/pages/assets-page.component.html +++ b/src/Squidex/app/features/assets/pages/assets-page.component.html @@ -25,7 +25,7 @@
-
-
diff --git a/src/Squidex/app/shared/components/language-selector.component.html b/src/Squidex/app/shared/components/language-selector.component.html index d56354bce..9dd44cb9b 100644 --- a/src/Squidex/app/shared/components/language-selector.component.html +++ b/src/Squidex/app/shared/components/language-selector.component.html @@ -1,6 +1,6 @@
From db23867b4183304e59a60552395d48a848de38f8 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 19 Jun 2019 21:47:10 +0200 Subject: [PATCH 04/16] Build fix. --- src/Squidex/app/shared/components/assets-list.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Squidex/app/shared/components/assets-list.component.html b/src/Squidex/app/shared/components/assets-list.component.html index 99d7e82ab..c4971aabe 100644 --- a/src/Squidex/app/shared/components/assets-list.component.html +++ b/src/Squidex/app/shared/components/assets-list.component.html @@ -1,4 +1,4 @@ -
+

Drop files here to upload

or
From c49932a485dc181a78b6c9eea58719134fb34c57 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 14:28:54 +0200 Subject: [PATCH 05/16] Fix creating patterns. --- .../app/features/settings/pages/patterns/pattern.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts b/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts index 43572f708..b5cbec0a8 100644 --- a/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts +++ b/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts @@ -25,7 +25,7 @@ export class PatternComponent implements OnChanges { public editForm = new EditPatternForm(this.formBuilder); - public isEditable = false; + public isEditable = true; public isDeletable = false; constructor( From bd23785ff1c89d254196ab5b6b2df073bc0fa03b Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 14:41:45 +0200 Subject: [PATCH 06/16] Correct handling of duplicates. --- .../Controllers/Assets/AssetsController.cs | 5 ++++- .../components/assets-list.component.ts | 19 ++++++++++++++++--- .../app/shared/services/assets.service.ts | 4 ++++ .../app/shared/state/asset-uploader.state.ts | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs b/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs index 1db6f0659..8f0f95fa2 100644 --- a/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs +++ b/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs @@ -179,7 +179,10 @@ namespace Squidex.Areas.Api.Controllers.Assets var command = new CreateAsset { File = assetFile }; - var response = await InvokeCommandAsync(app, command); + var context = await CommandBus.PublishAsync(command); + + var result = context.Result(); + var response = AssetDto.FromAsset(result.Asset, this, app, result.IsDuplicate); return CreatedAtAction(nameof(GetAsset), new { app, id = response.Id }, response); } diff --git a/src/Squidex/app/shared/components/assets-list.component.ts b/src/Squidex/app/shared/components/assets-list.component.ts index 4838ef066..a2d10af80 100644 --- a/src/Squidex/app/shared/components/assets-list.component.ts +++ b/src/Squidex/app/shared/components/assets-list.component.ts @@ -5,7 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core'; import { onErrorResumeNext } from 'rxjs/operators'; import { @@ -38,10 +38,23 @@ export class AssetsListComponent { @Output() public select = new EventEmitter(); + constructor( + private readonly changeDetector: ChangeDetectorRef + ) { + } + public add(file: File, asset: AssetDto) { - this.newFiles = this.newFiles.remove(file); + if (asset.isDuplicate) { + setTimeout(() => { + this.newFiles = this.newFiles.remove(file); - this.state.add(asset); + this.changeDetector.detectChanges(); + }, 2000); + } else { + this.newFiles = this.newFiles.remove(file); + + this.state.add(asset); + } } public search() { diff --git a/src/Squidex/app/shared/services/assets.service.ts b/src/Squidex/app/shared/services/assets.service.ts index 9e840e4cf..429c225e7 100644 --- a/src/Squidex/app/shared/services/assets.service.ts +++ b/src/Squidex/app/shared/services/assets.service.ts @@ -43,6 +43,10 @@ export class AssetDto { public readonly canUpdate: boolean; public readonly canUpload: boolean; + public get isDuplicate() { + return this._meta && this._meta['isDuplicate'] === 'true'; + } + public get contentUrl() { return this._links['content'].href; } diff --git a/src/Squidex/app/shared/state/asset-uploader.state.ts b/src/Squidex/app/shared/state/asset-uploader.state.ts index 04f35ec25..4b16ade66 100644 --- a/src/Squidex/app/shared/state/asset-uploader.state.ts +++ b/src/Squidex/app/shared/state/asset-uploader.state.ts @@ -75,7 +75,7 @@ export class AssetUploaderState extends State { const stream = this.assetsService.uploadFile(this.appName, file); return this.upload(stream, MathHelper.guid(), file, asset => { - if (asset._meta && asset._meta['isDuplicate'] === 'true') { + if (asset.isDuplicate) { this.dialogs.notifyError('Asset has already been uploaded.'); } else if (target) { target.add(asset); From d7b511c852526106aef15d5a6bb6b95552a1c8a4 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 14:44:30 +0200 Subject: [PATCH 07/16] Confirmation before deleting asset. --- src/Squidex/app/shared/components/asset.component.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Squidex/app/shared/components/asset.component.html b/src/Squidex/app/shared/components/asset.component.html index 583b66749..7fe2798ce 100644 --- a/src/Squidex/app/shared/components/asset.component.html +++ b/src/Squidex/app/shared/components/asset.component.html @@ -26,7 +26,10 @@ - + @@ -109,7 +112,10 @@ -
diff --git a/src/Squidex/app/shared/components/schema-category.component.ts b/src/Squidex/app/shared/components/schema-category.component.ts index b5d714d9d..bd6479e09 100644 --- a/src/Squidex/app/shared/components/schema-category.component.ts +++ b/src/Squidex/app/shared/components/schema-category.component.ts @@ -24,6 +24,8 @@ interface State { schemasFiltered: ImmutableArray; schemasForCategory: ImmutableArray; + isDeletable: boolean; + isOpen: boolean; } @@ -64,6 +66,7 @@ export class SchemaCategoryComponent extends StatefulComponent implements private readonly schemasState: SchemasState ) { super(changeDetector, { + isDeletable: true, schemasFiltered: ImmutableArray.empty(), schemasForCategory: ImmutableArray.empty(), isOpen: true @@ -104,12 +107,15 @@ export class SchemaCategoryComponent extends StatefulComponent implements if (changes['name']) { let displayName = 'Schemas'; + let isDeletable = true; if (this.name && this.name.length > 0) { displayName = this.name; + } else { + isDeletable = false; } - this.next(s => ({ ...s, displayName })); + this.next(s => ({ ...s, isDeletable, displayName })); } } diff --git a/src/Squidex/app/shared/services/schemas.service.spec.ts b/src/Squidex/app/shared/services/schemas.service.spec.ts index 0a0f09e24..f9cc8ba60 100644 --- a/src/Squidex/app/shared/services/schemas.service.spec.ts +++ b/src/Squidex/app/shared/services/schemas.service.spec.ts @@ -205,7 +205,7 @@ describe('SchemasService', () => { const resource: Resource = { _links: { - updateCategory: { method: 'PUT', href: '/api/apps/my-app/schemas/my-schema/category' } + ['update/category']: { method: 'PUT', href: '/api/apps/my-app/schemas/my-schema/category' } } }; diff --git a/src/Squidex/app/shared/services/schemas.service.ts b/src/Squidex/app/shared/services/schemas.service.ts index d1a8caecb..fc0622809 100644 --- a/src/Squidex/app/shared/services/schemas.service.ts +++ b/src/Squidex/app/shared/services/schemas.service.ts @@ -310,7 +310,7 @@ export class SchemasService { } public putCategory(appName: string, resource: Resource, dto: UpdateSchemaCategoryDto, version: Version): Observable { - const link = resource._links['updateCategory']; + const link = resource._links['update/category']; const url = this.apiUrl.buildUrl(link.href); From 6c2a75bf1355817c1f40e292c93e7765390637c9 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 15:25:07 +0200 Subject: [PATCH 11/16] Better fix for Categories. --- .../app/shared/components/schema-category.component.html | 2 +- .../app/shared/components/schema-category.component.ts | 8 +------- src/Squidex/app/shared/state/schemas.state.ts | 6 +++--- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Squidex/app/shared/components/schema-category.component.html b/src/Squidex/app/shared/components/schema-category.component.html index 3bf359965..406e91f13 100644 --- a/src/Squidex/app/shared/components/schema-category.component.html +++ b/src/Squidex/app/shared/components/schema-category.component.html @@ -8,7 +8,7 @@

{{snapshot.displayName}} ({{snapshot.schemasFiltered.length}})

-
diff --git a/src/Squidex/app/shared/components/schema-category.component.ts b/src/Squidex/app/shared/components/schema-category.component.ts index bd6479e09..b5d714d9d 100644 --- a/src/Squidex/app/shared/components/schema-category.component.ts +++ b/src/Squidex/app/shared/components/schema-category.component.ts @@ -24,8 +24,6 @@ interface State { schemasFiltered: ImmutableArray; schemasForCategory: ImmutableArray; - isDeletable: boolean; - isOpen: boolean; } @@ -66,7 +64,6 @@ export class SchemaCategoryComponent extends StatefulComponent implements private readonly schemasState: SchemasState ) { super(changeDetector, { - isDeletable: true, schemasFiltered: ImmutableArray.empty(), schemasForCategory: ImmutableArray.empty(), isOpen: true @@ -107,15 +104,12 @@ export class SchemaCategoryComponent extends StatefulComponent implements if (changes['name']) { let displayName = 'Schemas'; - let isDeletable = true; if (this.name && this.name.length > 0) { displayName = this.name; - } else { - isDeletable = false; } - this.next(s => ({ ...s, isDeletable, displayName })); + this.next(s => ({ ...s, displayName })); } } diff --git a/src/Squidex/app/shared/state/schemas.state.ts b/src/Squidex/app/shared/state/schemas.state.ts index f26604e47..3cdc39c85 100644 --- a/src/Squidex/app/shared/state/schemas.state.ts +++ b/src/Squidex/app/shared/state/schemas.state.ts @@ -140,7 +140,9 @@ export class SchemasState extends State { this.next(s => { const schemas = s.schemas.push(created).sortByStringAsc(x => x.displayName); - return { ...s, schemas }; + const categories = buildCategories(s.categories, schemas); + + return { ...s, schemas, categories }; }); }), shareSubscribed(this.dialogs, { silent: true })); @@ -343,8 +345,6 @@ function buildCategories(categories: { [name: string]: boolean }, schemas?: Sche } } - categories[''] = true; - return categories; } From 9b6e1a6cfa921161bce9f3bb3064dab993ed7a0e Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 15:28:33 +0200 Subject: [PATCH 12/16] Fix for preview urls. --- src/Squidex/app/shared/services/schemas.service.spec.ts | 2 +- src/Squidex/app/shared/services/schemas.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Squidex/app/shared/services/schemas.service.spec.ts b/src/Squidex/app/shared/services/schemas.service.spec.ts index f9cc8ba60..0daacd8e9 100644 --- a/src/Squidex/app/shared/services/schemas.service.spec.ts +++ b/src/Squidex/app/shared/services/schemas.service.spec.ts @@ -236,7 +236,7 @@ describe('SchemasService', () => { const resource: Resource = { _links: { - updateUrls: { method: 'PUT', href: '/api/apps/my-app/schemas/my-schema/preview-urls' } + ['update/urls'] { method: 'PUT', href: '/api/apps/my-app/schemas/my-schema/preview-urls' } } }; diff --git a/src/Squidex/app/shared/services/schemas.service.ts b/src/Squidex/app/shared/services/schemas.service.ts index fc0622809..d74774141 100644 --- a/src/Squidex/app/shared/services/schemas.service.ts +++ b/src/Squidex/app/shared/services/schemas.service.ts @@ -325,7 +325,7 @@ export class SchemasService { } public putPreviewUrls(appName: string, resource: Resource, dto: {}, version: Version): Observable { - const link = resource._links['updateUrls']; + const link = resource._links['update/urls']; const url = this.apiUrl.buildUrl(link.href); From 275c601afe5e262c90f0c9ea1bb3ce0b771f56a6 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 15:33:56 +0200 Subject: [PATCH 13/16] Fix for disabling field. --- .../Schemas/Guards/GuardSchemaField.cs | 2 +- src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs b/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs index 93b152d8c..92ccf8142 100644 --- a/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs +++ b/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs @@ -121,7 +121,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards throw new DomainException("Schema field is already disabled."); } - if (!field.IsForApi()) + if (!field.IsForApi(true)) { throw new DomainException("UI field cannot be disabled."); } diff --git a/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs b/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs index 97ad65125..16ad30e3c 100644 --- a/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs @@ -83,7 +83,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models } else { - AddPutLink("show", controller.Url(x => nameof(x.DisableField), values)); + AddPutLink("disable", controller.Url(x => nameof(x.DisableField), values)); } if (Properties is ArrayFieldPropertiesDto) From f8520d2bc1bceafe7d8b1f861dc8a3973c3e86c0 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 15:47:02 +0200 Subject: [PATCH 14/16] Field ordering fixed. --- .../Areas/Api/Controllers/Schemas/Models/FieldDto.cs | 6 ++++-- .../Areas/Api/Controllers/Schemas/Models/SchemaDto.cs | 2 +- .../app/features/schemas/pages/schema/field.component.ts | 2 +- .../features/schemas/pages/schema/schema-page.component.ts | 2 +- src/Squidex/app/shared/services/schemas.service.spec.ts | 4 ++-- src/Squidex/app/shared/services/schemas.service.ts | 4 ++-- src/Squidex/app/shared/state/schemas.state.spec.ts | 4 ++-- src/Squidex/app/shared/state/schemas.state.ts | 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs b/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs index 16ad30e3c..bc583bb03 100644 --- a/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs @@ -88,9 +88,11 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models if (Properties is ArrayFieldPropertiesDto) { - AddPostLink("fields/add", controller.Url(x => nameof(x.PostNestedField), values)); + var parentValues = new { app, name = schema, parentId = FieldId }; - AddPutLink("order", controller.Url(x => nameof(x.PutNestedFieldOrdering), values)); + AddPostLink("fields/add", controller.Url(x => nameof(x.PostNestedField), parentValues)); + + AddPutLink("fields/order", controller.Url(x => nameof(x.PutNestedFieldOrdering), parentValues)); } AddPutLink("lock", controller.Url(x => nameof(x.LockField), values)); diff --git a/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDto.cs b/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDto.cs index 7a48b73d9..35fafd420 100644 --- a/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDto.cs @@ -119,7 +119,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models if (allowUpdate) { - AddPutLink("order", controller.Url(x => nameof(x.PutSchemaFieldOrdering), values)); + AddPutLink("fields/order", controller.Url(x => nameof(x.PutSchemaFieldOrdering), values)); AddPutLink("update", controller.Url(x => nameof(x.PutSchema), values)); AddPutLink("update/category", controller.Url(x => nameof(x.PutCategory), values)); diff --git a/src/Squidex/app/features/schemas/pages/schema/field.component.ts b/src/Squidex/app/features/schemas/pages/schema/field.component.ts index db2288385..848aef0f8 100644 --- a/src/Squidex/app/features/schemas/pages/schema/field.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/field.component.ts @@ -95,7 +95,7 @@ export class FieldComponent implements OnChanges { } public sortFields(fields: NestedFieldDto[]) { - this.schemasState.sortFields(this.schema, fields, this.field).subscribe(); + this.schemasState.orderFields(this.schema, fields, this.field).subscribe(); } public lockField() { diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts index abc5b1f46..d9957a1f0 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts @@ -87,7 +87,7 @@ export class SchemaPageComponent extends ResourceOwner implements OnInit { } public sortFields(fields: FieldDto[]) { - this.schemasState.sortFields(this.schema, fields).subscribe(); + this.schemasState.orderFields(this.schema, fields).subscribe(); } public trackByField(index: number, field: FieldDto) { diff --git a/src/Squidex/app/shared/services/schemas.service.spec.ts b/src/Squidex/app/shared/services/schemas.service.spec.ts index 0daacd8e9..cec206ce2 100644 --- a/src/Squidex/app/shared/services/schemas.service.spec.ts +++ b/src/Squidex/app/shared/services/schemas.service.spec.ts @@ -236,7 +236,7 @@ describe('SchemasService', () => { const resource: Resource = { _links: { - ['update/urls'] { method: 'PUT', href: '/api/apps/my-app/schemas/my-schema/preview-urls' } + ['update/urls']: { method: 'PUT', href: '/api/apps/my-app/schemas/my-schema/preview-urls' } } }; @@ -387,7 +387,7 @@ describe('SchemasService', () => { const resource: Resource = { _links: { - order: { method: 'PUT', href: '/api/apps/my-app/schemas/my-schema/fields/ordering' } + ['fields/order']: { method: 'PUT', href: '/api/apps/my-app/schemas/my-schema/fields/ordering' } } }; diff --git a/src/Squidex/app/shared/services/schemas.service.ts b/src/Squidex/app/shared/services/schemas.service.ts index d74774141..e02391b2a 100644 --- a/src/Squidex/app/shared/services/schemas.service.ts +++ b/src/Squidex/app/shared/services/schemas.service.ts @@ -385,11 +385,11 @@ export class SchemasService { } public putFieldOrdering(appName: string, resource: Resource, dto: number[], version: Version): Observable { - const link = resource._links['order']; + const link = resource._links['fields/order']; const url = this.apiUrl.buildUrl(link.href); - return HTTP.requestVersioned(this.http, link.method, url, version, dto).pipe( + return HTTP.requestVersioned(this.http, link.method, url, version, { fieldIds: dto }).pipe( map(({ version: newVersion, payload }) => { return parseSchemaWithDetails(payload.body, newVersion); }), diff --git a/src/Squidex/app/shared/state/schemas.state.spec.ts b/src/Squidex/app/shared/state/schemas.state.spec.ts index 394599074..8668a17f8 100644 --- a/src/Squidex/app/shared/state/schemas.state.spec.ts +++ b/src/Squidex/app/shared/state/schemas.state.spec.ts @@ -373,7 +373,7 @@ describe('SchemasState', () => { schemasService.setup(x => x.putFieldOrdering(app, schema1, [schema.fields[1].fieldId, schema.fields[2].fieldId], version)) .returns(() => of(updated)).verifiable(); - schemasState.sortFields(schema1, [schema.fields[1], schema.fields[2]]).subscribe(); + schemasState.orderFields(schema1, [schema.fields[1], schema.fields[2]]).subscribe(); const schema1New = schemasState.snapshot.schemas.at(0); @@ -387,7 +387,7 @@ describe('SchemasState', () => { schemasService.setup(x => x.putFieldOrdering(app, schema.fields[0], [schema.fields[1].fieldId, schema.fields[2].fieldId], version)) .returns(() => of(updated)).verifiable(); - schemasState.sortFields(schema1, [schema.fields[1], schema.fields[2]], schema.fields[0]).subscribe(); + schemasState.orderFields(schema1, [schema.fields[1], schema.fields[2]], schema.fields[0]).subscribe(); const schema1New = schemasState.snapshot.schemas.at(0); diff --git a/src/Squidex/app/shared/state/schemas.state.ts b/src/Squidex/app/shared/state/schemas.state.ts index 3cdc39c85..68c3ea6d5 100644 --- a/src/Squidex/app/shared/state/schemas.state.ts +++ b/src/Squidex/app/shared/state/schemas.state.ts @@ -233,7 +233,7 @@ export class SchemasState extends State { shareMapSubscribed(this.dialogs, x => getField(x, request, parent), { silent: true })); } - public sortFields(schema: SchemaDto, fields: any[], parent?: RootFieldDto): Observable { + public orderFields(schema: SchemaDto, fields: any[], parent?: RootFieldDto): Observable { return this.schemasService.putFieldOrdering(this.appName, parent || schema, fields.map(t => t.fieldId), schema.version).pipe( tap(updated => { this.replaceSchema(updated); From d01640e13e0028834fbfec00f107d8602ad5e96b Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 16:01:14 +0200 Subject: [PATCH 15/16] Fix for selecting content. --- .../Areas/Api/Controllers/Contents/Models/ContentDto.cs | 2 +- .../content/pages/content/content-page.component.ts | 2 +- .../features/content/shared/content-item.component.html | 2 +- .../app/shared/components/markdown-editor.component.ts | 8 ++++++++ .../app/shared/components/rich-editor.component.ts | 4 ++++ 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs b/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs index 3939cfd67..b2db0db33 100644 --- a/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs @@ -142,7 +142,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models if (controller.HasPermission(Permissions.AppContentsDelete, app, schema)) { - AddPutLink("delete", controller.Url(x => nameof(x.DeleteContent), values)); + AddDeleteLink("delete", controller.Url(x => nameof(x.DeleteContent), values)); } foreach (var next in StatusFlow.Next(Status)) diff --git a/src/Squidex/app/features/content/pages/content/content-page.component.ts b/src/Squidex/app/features/content/pages/content/content-page.component.ts index 94c3f79c2..fd4afb1a6 100644 --- a/src/Squidex/app/features/content/pages/content/content-page.component.ts +++ b/src/Squidex/app/features/content/pages/content/content-page.component.ts @@ -183,7 +183,7 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD private loadContent(data: any) { this.contentForm.loadContent(data); - this.contentForm.setEnabled(this.content && !this.content.canUpdate); + this.contentForm.setEnabled(!this.content || this.content.canUpdate); } public discardChanges() { diff --git a/src/Squidex/app/features/content/shared/content-item.component.html b/src/Squidex/app/features/content/shared/content-item.component.html index 1b84a7d20..2569c05e1 100644 --- a/src/Squidex/app/features/content/shared/content-item.component.html +++ b/src/Squidex/app/features/content/shared/content-item.component.html @@ -11,7 +11,7 @@ - + diff --git a/src/Squidex/app/shared/components/markdown-editor.component.ts b/src/Squidex/app/shared/components/markdown-editor.component.ts index bc7ed55a6..2197c1fdd 100644 --- a/src/Squidex/app/shared/components/markdown-editor.component.ts +++ b/src/Squidex/app/shared/components/markdown-editor.component.ts @@ -78,6 +78,10 @@ export class MarkdownEditorComponent extends StatefulControlComponent { + if (this.isDisabled) { + return; + } + this.assetsDialog.show(); } @@ -220,6 +224,10 @@ export class MarkdownEditorComponent extends StatefulControlComponent i } private showSelector = () => { + if (this.isDisabled) { + return; + } + this.assetsDialog.show(); } From 1254cf98f17e2e81211fe8a2b1b142d14df6aafc Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 20 Jun 2019 16:44:48 +0200 Subject: [PATCH 16/16] Tests fixed. --- src/Squidex/app/shared/state/schemas.state.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Squidex/app/shared/state/schemas.state.spec.ts b/src/Squidex/app/shared/state/schemas.state.spec.ts index 8668a17f8..4e8c74c74 100644 --- a/src/Squidex/app/shared/state/schemas.state.spec.ts +++ b/src/Squidex/app/shared/state/schemas.state.spec.ts @@ -69,7 +69,7 @@ describe('SchemasState', () => { expect(schemasState.snapshot.schemas.values).toEqual(oldSchemas.items); expect(schemasState.snapshot.isLoaded).toBeTruthy(); - expect(schemasState.snapshot.categories).toEqual({ 'category1': false, 'category2': false, '': true }); + expect(schemasState.snapshot.categories).toEqual({ 'category1': false, 'category2': false }); schemasService.verifyAll(); }); @@ -83,7 +83,7 @@ describe('SchemasState', () => { expect(schemasState.snapshot.schemas.values).toEqual(oldSchemas.items); expect(schemasState.snapshot.isLoaded).toBeTruthy(); - expect(schemasState.snapshot.categories).toEqual({ 'category1': false, 'category2': false, 'category3': true, '': true }); + expect(schemasState.snapshot.categories).toEqual({ 'category1': false, 'category2': false, 'category3': true }); schemasService.verifyAll(); }); @@ -111,13 +111,13 @@ describe('SchemasState', () => { it('should add category', () => { schemasState.addCategory('category3'); - expect(schemasState.snapshot.categories).toEqual({ 'category1': false, 'category2': false, 'category3': true, '': true }); + expect(schemasState.snapshot.categories).toEqual({ 'category1': false, 'category2': false, 'category3': true }); }); it('should remove category', () => { schemasState.removeCategory('category1'); - expect(schemasState.snapshot.categories).toEqual({ 'category2': false, '': true }); + expect(schemasState.snapshot.categories).toEqual({ 'category2': false }); }); it('should return schema on select and reload when already loaded', () => {