diff --git a/src/Squidex.Domain.Apps.Core.Model/Contents/Workflow.cs b/src/Squidex.Domain.Apps.Core.Model/Contents/Workflow.cs index 90a430965..391863c0e 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Contents/Workflow.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Contents/Workflow.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; using System.Collections.Generic; namespace Squidex.Domain.Apps.Core.Contents @@ -13,26 +14,41 @@ namespace Squidex.Domain.Apps.Core.Contents { private const string DefaultName = "Unnamed"; private static readonly IReadOnlyDictionary EmptySteps = new Dictionary(); + private static readonly IReadOnlyList EmptySchemaIds = new List(); public static readonly Workflow Default = CreateDefault(); - public static readonly Workflow Empty = new Workflow(EmptySteps, default); + public static readonly Workflow Empty = new Workflow(default, EmptySteps); - public IReadOnlyDictionary Steps { get; } + public IReadOnlyDictionary Steps { get; } = EmptySteps; + + public IReadOnlyList SchemaIds { get; } = EmptySchemaIds; public Status Initial { get; } - public Workflow(IReadOnlyDictionary steps, Status initial, string name = null) + public Workflow( + Status initial, + IReadOnlyDictionary steps, + IReadOnlyList schemaIds = null, + string name = null) : base(name ?? DefaultName) { - Steps = steps ?? EmptySteps; - Initial = initial; + + if (steps != null) + { + Steps = steps; + } + + if (schemaIds != null) + { + SchemaIds = schemaIds; + } } public static Workflow CreateDefault(string name = null) { return new Workflow( - new Dictionary + Status.Draft, new Dictionary { [Status.Archived] = new WorkflowStep( @@ -57,7 +73,7 @@ namespace Squidex.Domain.Apps.Core.Contents [Status.Draft] = new WorkflowTransition() }, StatusColors.Published) - }, Status.Draft, name); + }, null, name); } public IEnumerable<(Status Status, WorkflowStep Step, WorkflowTransition Transition)> GetTransitions(Status status) diff --git a/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs index fd7b6d533..a560e4abc 100644 --- a/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs @@ -36,6 +36,18 @@ namespace Squidex.Infrastructure.Json.Newtonsoft } } + protected override JsonArrayContract CreateArrayContract(Type objectType) + { + if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(IReadOnlyList<>)) + { + var implementationType = typeof(List<>).MakeGenericType(objectType.GetGenericArguments()); + + return base.CreateArrayContract(implementationType); + } + + return base.CreateArrayContract(objectType); + } + protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) { if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary<,>)) diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs index 6a6f0bfa6..4831f5ec0 100644 --- a/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; @@ -26,6 +27,11 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models [Required] public Dictionary Steps { get; set; } + /// + /// The schema ids. + /// + public List SchemaIds { get; set; } + /// /// The initial step. /// @@ -34,6 +40,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models public UpdateWorkflow ToCommand() { var workflow = new Workflow( + Initial, Steps?.ToDictionary( x => x.Key, x => new WorkflowStep( @@ -42,7 +49,8 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models y => new WorkflowTransition(y.Value.Expression, y.Value.Role)), x.Value.Color, x.Value.NoUpdate)), - Initial, Name); + SchemaIds, + Name); return new UpdateWorkflow { Workflow = workflow }; } diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs index 7906addaa..5e249085b 100644 --- a/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs @@ -34,6 +34,11 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models [Required] public Dictionary Steps { get; set; } + /// + /// The schema ids. + /// + public IReadOnlyList SchemaIds { get; set; } + /// /// The initial step. /// @@ -41,18 +46,16 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models public static WorkflowDto FromWorkflow(Guid id, Workflow workflow, ApiController controller, string app) { - var result = new WorkflowDto - { - Steps = workflow.Steps.ToDictionary( - x => x.Key, - x => SimpleMapper.Map(x.Value, new WorkflowStepDto - { - Transitions = x.Value.Transitions.ToDictionary( - y => y.Key, - y => new WorkflowTransitionDto { Expression = y.Value.Expression, Role = y.Value.Role }) - })), - Id = id, Name = workflow.Name, Initial = workflow.Initial - }; + var result = SimpleMapper.Map(workflow, new WorkflowDto { Id = id }); + + result.Steps = workflow.Steps.ToDictionary( + x => x.Key, + x => SimpleMapper.Map(x.Value, new WorkflowStepDto + { + Transitions = x.Value.Transitions.ToDictionary( + y => y.Key, + y => new WorkflowTransitionDto { Expression = y.Value.Expression, Role = y.Value.Role }) + })); return result.CreateLinks(controller, app, id); } diff --git a/src/Squidex/app/features/settings/pages/workflows/schema-tag-converter.ts b/src/Squidex/app/features/settings/pages/workflows/schema-tag-converter.ts new file mode 100644 index 000000000..1f3bd4ab0 --- /dev/null +++ b/src/Squidex/app/features/settings/pages/workflows/schema-tag-converter.ts @@ -0,0 +1,38 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { Converter, SchemaDto, TagValue } from '@app/shared'; + +export class SchemaTagConverter implements Converter { + public readonly suggestions: TagValue[]; + + constructor( + private readonly schemas: SchemaDto[] + ) { + this.suggestions = schemas.map(x => new TagValue(x.id, x.name, x.id)); + } + + public convertInput(input: string): TagValue | null { + const schema = this.schemas.find(x => x.name === input); + + if (schema) { + return new TagValue(schema.id, schema.name, schema.id); + } + + return null; + } + + public convertValue(value: any): TagValue | null { + const schema = this.schemas.find(x => x.id === value); + + if (schema) { + return new TagValue(schema.id, schema.name, schema.id); + } + + return null; + } +} \ No newline at end of file diff --git a/src/Squidex/app/features/settings/pages/workflows/workflow.component.html b/src/Squidex/app/features/settings/pages/workflows/workflow.component.html index 14b64d4e1..671b50f2e 100644 --- a/src/Squidex/app/features/settings/pages/workflows/workflow.component.html +++ b/src/Squidex/app/features/settings/pages/workflows/workflow.component.html @@ -36,7 +36,7 @@
-
+
+
+ + +
+ + + + Restrict this workflow to specific schemas or keep it empty for all schemas. + +
+
+ - +
No workflows created yet.
+ [workflow]="workflow" [roles]="roles" [schemasSource]="schemasSource">