Browse Source

Fix for validate on publish. (#680)

pull/681/head
Sebastian Stehle 5 years ago
committed by GitHub
parent
commit
e59cfe2d93
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      backend/src/Squidex.Domain.Apps.Entities/Contents/ContentExtensions.cs
  2. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.State.cs
  3. 18
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs
  4. 20
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/ValidationExtensions.cs
  5. 6
      frontend/app/shared/state/assets.state.ts
  6. 8
      frontend/app/shared/state/contents.state.ts

5
backend/src/Squidex.Domain.Apps.Entities/Contents/ContentExtensions.cs

@ -45,6 +45,11 @@ namespace Squidex.Domain.Apps.Entities.Contents
return content.NewStatus ?? content.Status;
}
public static bool IsPublished(this IContentEntity content)
{
return content.EditingStatus() == Status.Published;
}
public static SearchScope Scope(this Context context)
{
return context.ShouldProvideUnpublished() || context.IsFrontendClient ? SearchScope.All : SearchScope.Published;

2
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.State.cs

@ -49,7 +49,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[IgnoreDataMember]
public Status Status
{
get => CurrentVersion.Status;
get => CurrentVersion?.Status ?? Status.Draft;
}
public override bool ApplyEvent(IEvent @event, EnvelopeHeaders headers)

18
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs

@ -114,7 +114,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
operation.MustHavePermission(Permissions.AppContentsReadOwn);
await operation.ValidateContentAndInputAsync(Snapshot.Data, false);
await operation.ValidateContentAndInputAsync(Snapshot.Data, false, Snapshot.IsPublished());
return true;
});
@ -226,7 +226,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (!c.DoNotValidate)
{
await operation.ValidateInputAsync(c.Data, c.OptimizeValidation);
await operation.ValidateInputAsync(c.Data, c.OptimizeValidation, Snapshot.IsPublished());
}
var status = await operation.GetInitialStatusAsync();
@ -240,7 +240,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (!c.DoNotValidate)
{
await operation.ValidateContentAsync(c.Data, c.OptimizeValidation);
await operation.ValidateContentAsync(c.Data, c.OptimizeValidation, Snapshot.IsPublished());
}
Create(c, status);
@ -293,7 +293,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (!c.DoNotValidate && c.Status == Status.Published && operation.SchemaDef.Properties.ValidateOnPublish)
{
await operation.ValidateContentAndInputAsync(Snapshot.Data, c.OptimizeValidation);
await operation.ValidateContentAndInputAsync(Snapshot.Data, c.OptimizeValidation, true);
}
ChangeStatus(c);
@ -306,7 +306,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (!c.DoNotValidate)
{
await operation.ValidateInputPartialAsync(c.Data, c.OptimizeValidation);
await operation.ValidateInputPartialAsync(c.Data, c.OptimizeValidation, Snapshot.IsPublished());
}
if (!c.DoNotValidateWorkflow)
@ -328,7 +328,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (!c.DoNotValidate)
{
await operation.ValidateContentAsync(newData, c.OptimizeValidation);
await operation.ValidateContentAsync(newData, c.OptimizeValidation, Snapshot.IsPublished());
}
Update(c, newData);
@ -341,7 +341,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (!c.DoNotValidate)
{
await operation.ValidateInputPartialAsync(c.Data, c.OptimizeValidation);
await operation.ValidateInputPartialAsync(c.Data, c.OptimizeValidation, Snapshot.IsPublished());
}
if (!c.DoNotValidateWorkflow)
@ -363,7 +363,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
if (!c.DoNotValidate)
{
await operation.ValidateContentAsync(newData, c.OptimizeValidation);
await operation.ValidateContentAsync(newData, c.OptimizeValidation, Snapshot.IsPublished());
}
Update(c, newData);
@ -438,7 +438,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
return StatusChange.Published;
}
else if (Snapshot.EditingStatus() == Status.Published)
else if (Snapshot.IsPublished())
{
return StatusChange.Unpublished;
}

20
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/ValidationExtensions.cs

@ -48,36 +48,36 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
}
}
public static async Task ValidateInputAsync(this OperationContext context, ContentData data, bool optimize)
public static async Task ValidateInputAsync(this OperationContext context, ContentData data, bool optimize, bool published)
{
var validator = GetValidator(context, optimize);
var validator = GetValidator(context, optimize, published);
await validator.ValidateInputAsync(data);
context.AddErrors(validator.Errors).ThrowOnErrors();
}
public static async Task ValidateInputPartialAsync(this OperationContext context, ContentData data, bool optimize)
public static async Task ValidateInputPartialAsync(this OperationContext context, ContentData data, bool optimize, bool published)
{
var validator = GetValidator(context, optimize);
var validator = GetValidator(context, optimize, published);
await validator.ValidateInputPartialAsync(data);
context.AddErrors(validator.Errors).ThrowOnErrors();
}
public static async Task ValidateContentAsync(this OperationContext context, ContentData data, bool optimize)
public static async Task ValidateContentAsync(this OperationContext context, ContentData data, bool optimize, bool published)
{
var validator = GetValidator(context, optimize);
var validator = GetValidator(context, optimize, published);
await validator.ValidateContentAsync(data);
context.AddErrors(validator.Errors).ThrowOnErrors();
}
public static async Task ValidateContentAndInputAsync(this OperationContext operation, ContentData data, bool optimize)
public static async Task ValidateContentAndInputAsync(this OperationContext operation, ContentData data, bool optimize, bool published)
{
var validator = GetValidator(operation, optimize);
var validator = GetValidator(operation, optimize, published);
await validator.ValidateInputAsync(data);
await validator.ValidateContentAsync(data);
@ -102,7 +102,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
}
}
private static ContentValidator GetValidator(this OperationContext context, bool optimize)
private static ContentValidator GetValidator(this OperationContext context, bool optimize, bool published)
{
var validationContext =
new ValidationContext(context.Resolve<IJsonSerializer>(),
@ -110,7 +110,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
context.Schema.NamedId(),
context.SchemaDef,
context.ContentId)
.Optimized(optimize);
.Optimized(optimize).AsPublishing(published);
var validator =
new ContentValidator(context.Partition(),

6
frontend/app/shared/state/assets.state.ts

@ -286,7 +286,7 @@ export abstract class AssetsStateBase extends State<Snapshot> {
public deleteAsset(asset: AssetDto) {
return this.assetsService.deleteAssetItem(this.appName, asset, true, asset.version).pipe(
catchError((error: ErrorDto) => {
if (error.statusCode === 400) {
if (isReferrerError(error)) {
return this.dialogs.confirm(
'i18n:assets.deleteReferrerConfirmTitle',
'i18n:assets.deleteReferrerConfirmText',
@ -401,6 +401,10 @@ export abstract class AssetsStateBase extends State<Snapshot> {
}
}
function isReferrerError(error?: ErrorDto) {
return error?.statusCode === 400 && (!error?.details || error?.details.length === 0);
}
function updateTags(snapshot: Snapshot, newAsset?: AssetDto, oldAsset?: AssetDto) {
if (!oldAsset && newAsset) {
oldAsset = snapshot.assets.find(x => x.id === newAsset.id);

8
frontend/app/shared/state/contents.state.ts

@ -6,7 +6,7 @@
*/
import { Injectable } from '@angular/core';
import { DialogService, getPagingInfo, ListState, shareSubscribed, State, Types, Version, Versioned } from '@app/framework';
import { DialogService, ErrorDto, getPagingInfo, ListState, shareSubscribed, State, Types, Version, Versioned } from '@app/framework';
import { EMPTY, Observable, of } from 'rxjs';
import { catchError, finalize, map, switchMap, tap } from 'rxjs/operators';
import { BulkResultDto, BulkUpdateJobDto, ContentDto, ContentsDto, ContentsService, StatusInfo } from './../services/contents.service';
@ -342,7 +342,7 @@ export abstract class ContentsStateBase extends State<Snapshot> {
private bulkWithRetry(contents: ReadonlyArray<ContentDto>, job: Partial<BulkUpdateJobDto>, confirmTitle: string, confirmText: string, confirmKey: string): Observable<ReadonlyArray<BulkResultDto>> {
return this.bulkMany(contents, true, job).pipe(
switchMap(results => {
const failed = contents.filter(x => results.find(r => r.contentId === x.id)?.error?.statusCode === 400);
const failed = contents.filter(x => isReferrerError(results.find(r => r.contentId === x.id)?.error));
if (failed.length > 0) {
return this.dialogs.confirm(confirmTitle, confirmText, confirmKey).pipe(
@ -395,6 +395,10 @@ export abstract class ContentsStateBase extends State<Snapshot> {
public abstract get schemaName(): string;
}
function isReferrerError(error?: ErrorDto) {
return error?.statusCode === 400 && (!error?.details || error?.details.length === 0);
}
@Injectable()
export class ContentsState extends ContentsStateBase {
constructor(appsState: AppsState, contentsService: ContentsService, dialogs: DialogService,

Loading…
Cancel
Save