mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
187 changed files with 2324 additions and 1137 deletions
@ -0,0 +1,43 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Schemas |
||||
|
{ |
||||
|
[Equals(DoNotAddEqualityOperators = true)] |
||||
|
public sealed class FieldRule |
||||
|
{ |
||||
|
public FieldRuleAction Action { get; } |
||||
|
|
||||
|
public string Field { get; } |
||||
|
|
||||
|
public string? Condition { get; } |
||||
|
|
||||
|
public FieldRule(FieldRuleAction action, string field, string? condition) |
||||
|
{ |
||||
|
Guard.Enum(action, nameof(action)); |
||||
|
Guard.NotNullOrEmpty(field, nameof(field)); |
||||
|
|
||||
|
Action = action; |
||||
|
|
||||
|
Field = field; |
||||
|
|
||||
|
Condition = condition; |
||||
|
} |
||||
|
|
||||
|
public static FieldRule Disable(string field, string? condition = null) |
||||
|
{ |
||||
|
return new FieldRule(FieldRuleAction.Disable, field, condition); |
||||
|
} |
||||
|
|
||||
|
public static FieldRule Hide(string field, string? condition = null) |
||||
|
{ |
||||
|
return new FieldRule(FieldRuleAction.Hide, field, condition); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Schemas |
||||
|
{ |
||||
|
public enum FieldRuleAction |
||||
|
{ |
||||
|
Disable, |
||||
|
Hide, |
||||
|
Require |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Schemas |
||||
|
{ |
||||
|
public sealed class FieldRules : ReadOnlyCollection<FieldRule> |
||||
|
{ |
||||
|
private static readonly List<FieldRule> EmptyRules = new List<FieldRule>(); |
||||
|
|
||||
|
public static readonly FieldRules Empty = new FieldRules(EmptyRules); |
||||
|
|
||||
|
public FieldRules(params FieldRule[] fields) |
||||
|
: base(fields?.ToList() ?? EmptyRules) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public FieldRules(IList<FieldRule> list) |
||||
|
: base(list ?? EmptyRules) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Schemas.Commands |
||||
|
{ |
||||
|
public sealed class ConfigureFieldRules : SchemaCommand |
||||
|
{ |
||||
|
public List<FieldRuleCommand>? FieldRules { get; set; } |
||||
|
|
||||
|
public FieldRules ToFieldRules() |
||||
|
{ |
||||
|
if (FieldRules?.Count > 0) |
||||
|
{ |
||||
|
return new FieldRules(FieldRules.Select(x => x.ToFieldRule()).ToList()); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return Core.Schemas.FieldRules.Empty; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Schemas.Commands |
||||
|
{ |
||||
|
public sealed class FieldRuleCommand |
||||
|
{ |
||||
|
public FieldRuleAction Action { get; set; } |
||||
|
|
||||
|
public string Field { get; set; } |
||||
|
|
||||
|
public string? Condition { get; set; } |
||||
|
|
||||
|
public FieldRule ToFieldRule() |
||||
|
{ |
||||
|
return new FieldRule(Action, Field, Condition); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Infrastructure.EventSourcing; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Events.Schemas |
||||
|
{ |
||||
|
[EventType(nameof(SchemaFieldRulesConfigured))] |
||||
|
public sealed class SchemaFieldRulesConfigured : SchemaEvent |
||||
|
{ |
||||
|
public FieldRules FieldRules { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace FluentValidation |
||||
|
{ |
||||
|
public static class CustomValidators |
||||
|
{ |
||||
|
public static IRuleBuilderOptions<T, string> Slug<T>(this IRuleBuilder<T, string> ruleBuilder) |
||||
|
{ |
||||
|
return ruleBuilder.Must(x => x.IsSlug()).WithMessage("{PropertyName} must be a valid slug."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
||||
|
|
||||
|
namespace Squidex.Areas.Api.Controllers.Schemas.Models |
||||
|
{ |
||||
|
public sealed class ConfigureFieldRulesDto |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The field rules to configure.
|
||||
|
/// </summary>
|
||||
|
public List<FieldRuleDto>? FieldRules { get; set; } |
||||
|
|
||||
|
public ConfigureFieldRules ToCommand() |
||||
|
{ |
||||
|
return new ConfigureFieldRules |
||||
|
{ |
||||
|
FieldRules = FieldRules?.Select(x => x.ToCommand()).ToList() |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
||||
|
using Squidex.Infrastructure.Reflection; |
||||
|
|
||||
|
namespace Squidex.Areas.Api.Controllers.Schemas.Models |
||||
|
{ |
||||
|
public sealed class FieldRuleDto |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The action to perform when the condition is met.
|
||||
|
/// </summary>
|
||||
|
[Required] |
||||
|
public FieldRuleAction Action { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The field to update.
|
||||
|
/// </summary>
|
||||
|
[Required] |
||||
|
public string Field { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The condition.
|
||||
|
/// </summary>
|
||||
|
public string? Condition { get; set; } |
||||
|
|
||||
|
public static FieldRuleDto FromFieldRule(FieldRule fieldRule) |
||||
|
{ |
||||
|
return SimpleMapper.Map(fieldRule, new FieldRuleDto()); |
||||
|
} |
||||
|
|
||||
|
public FieldRuleCommand ToCommand() |
||||
|
{ |
||||
|
return SimpleMapper.Map(this, new FieldRuleCommand()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,45 +0,0 @@ |
|||||
/* |
|
||||
* Squidex Headless CMS |
|
||||
* |
|
||||
* @license |
|
||||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|
||||
*/ |
|
||||
|
|
||||
import { Pipe, PipeTransform } from '@angular/core'; |
|
||||
import { FieldDto } from '@app/shared'; |
|
||||
|
|
||||
export interface FieldSection<T> { |
|
||||
separator?: T; |
|
||||
|
|
||||
fields: ReadonlyArray<T>; |
|
||||
} |
|
||||
|
|
||||
@Pipe({ |
|
||||
name: 'sqxGroupFields', |
|
||||
pure: true |
|
||||
}) |
|
||||
export class GroupFieldsPipe<T extends FieldDto> implements PipeTransform { |
|
||||
public transform(fields: ReadonlyArray<T>) { |
|
||||
const sections: FieldSection<T>[] = []; |
|
||||
|
|
||||
let currentSeparator: T | undefined = undefined; |
|
||||
let currentFields: T[] = []; |
|
||||
|
|
||||
for (const field of fields) { |
|
||||
if (field.properties.isContentField) { |
|
||||
currentFields.push(field); |
|
||||
} else { |
|
||||
sections.push({ separator: currentSeparator, fields: currentFields }); |
|
||||
|
|
||||
currentFields = []; |
|
||||
currentSeparator = field; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (currentFields.length > 0) { |
|
||||
sections.push({ separator: currentSeparator, fields: currentFields }); |
|
||||
} |
|
||||
|
|
||||
return sections; |
|
||||
} |
|
||||
} |
|
||||
@ -1,29 +1,29 @@ |
|||||
<ng-container [ngSwitch]="field.rawProperties.fieldType"> |
<ng-container [ngSwitch]="field.rawProperties.fieldType"> |
||||
<ng-container *ngSwitchCase="'Assets'"> |
<ng-container *ngSwitchCase="'Assets'"> |
||||
<sqx-assets-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-assets-ui> |
<sqx-assets-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-assets-ui> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Boolean'"> |
<ng-container *ngSwitchCase="'Boolean'"> |
||||
<sqx-boolean-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-boolean-ui> |
<sqx-boolean-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-boolean-ui> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'DateTime'"> |
<ng-container *ngSwitchCase="'DateTime'"> |
||||
<sqx-date-time-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-date-time-ui> |
<sqx-date-time-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-date-time-ui> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Geolocation'"> |
<ng-container *ngSwitchCase="'Geolocation'"> |
||||
<sqx-geolocation-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-geolocation-ui> |
<sqx-geolocation-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-geolocation-ui> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Json'"> |
<ng-container *ngSwitchCase="'Json'"> |
||||
<sqx-json-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-json-ui> |
<sqx-json-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-json-ui> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Number'"> |
<ng-container *ngSwitchCase="'Number'"> |
||||
<sqx-number-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-number-ui> |
<sqx-number-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-number-ui> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'References'"> |
<ng-container *ngSwitchCase="'References'"> |
||||
<sqx-references-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-references-ui> |
<sqx-references-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-references-ui> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'String'"> |
<ng-container *ngSwitchCase="'String'"> |
||||
<sqx-string-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-string-ui> |
<sqx-string-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-string-ui> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Tags'"> |
<ng-container *ngSwitchCase="'Tags'"> |
||||
<sqx-tags-ui [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-tags-ui> |
<sqx-tags-ui [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-tags-ui> |
||||
</ng-container> |
</ng-container> |
||||
</ng-container> |
</ng-container> |
||||
@ -1,32 +1,32 @@ |
|||||
<ng-container [ngSwitch]="field.rawProperties.fieldType"> |
<ng-container [ngSwitch]="field.rawProperties.fieldType"> |
||||
<ng-container *ngSwitchCase="'Array'"> |
<ng-container *ngSwitchCase="'Array'"> |
||||
<sqx-array-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-array-validation> |
<sqx-array-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-array-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Assets'"> |
<ng-container *ngSwitchCase="'Assets'"> |
||||
<sqx-assets-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-assets-validation> |
<sqx-assets-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-assets-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'DateTime'"> |
<ng-container *ngSwitchCase="'DateTime'"> |
||||
<sqx-date-time-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-date-time-validation> |
<sqx-date-time-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-date-time-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Boolean'"> |
<ng-container *ngSwitchCase="'Boolean'"> |
||||
<sqx-boolean-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-boolean-validation> |
<sqx-boolean-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-boolean-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Geolocation'"> |
<ng-container *ngSwitchCase="'Geolocation'"> |
||||
<sqx-geolocation-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-geolocation-validation> |
<sqx-geolocation-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-geolocation-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Json'"> |
<ng-container *ngSwitchCase="'Json'"> |
||||
<sqx-json-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-json-validation> |
<sqx-json-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-json-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Number'"> |
<ng-container *ngSwitchCase="'Number'"> |
||||
<sqx-number-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-number-validation> |
<sqx-number-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-number-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'References'"> |
<ng-container *ngSwitchCase="'References'"> |
||||
<sqx-references-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-references-validation> |
<sqx-references-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-references-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'String'"> |
<ng-container *ngSwitchCase="'String'"> |
||||
<sqx-string-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties" [patterns]="patterns"></sqx-string-validation> |
<sqx-string-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties" [patterns]="patterns"></sqx-string-validation> |
||||
</ng-container> |
</ng-container> |
||||
<ng-container *ngSwitchCase="'Tags'"> |
<ng-container *ngSwitchCase="'Tags'"> |
||||
<sqx-tags-validation [editForm]="editForm" [field]="field" [properties]="field.rawProperties"></sqx-tags-validation> |
<sqx-tags-validation [fieldForm]="fieldForm" [field]="field" [properties]="field.rawProperties"></sqx-tags-validation> |
||||
</ng-container> |
</ng-container> |
||||
</ng-container> |
</ng-container> |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue