diff --git a/zero.Core/Blueprints/Blueprint.cs b/zero.Core/Blueprints/Blueprint.cs index 3642883a..4a448556 100644 --- a/zero.Core/Blueprints/Blueprint.cs +++ b/zero.Core/Blueprints/Blueprint.cs @@ -15,18 +15,14 @@ namespace zero.Core.Blueprints { public List> UnlockedFields { get; private set; } = new(); - protected static string[] DefaultFields { get; set; } = new[] { "name", "alias", "key", "sort", "isActive", "hash", "languageId", "createdById", "createdDate", "lastModifiedById", "lastModifiedDate", "blueprint" }; + /// + /// These fields are not copied by the ObjectCloner + /// as they are either locked or copied manually by ApplyDefaults() + /// + protected static string[] DefaultUncopyFields { get; set; } = new[] { "id", "url", "name", "alias", "key", "sort", "isActive", "hash", "languageId", "createdById", "createdDate", "lastModifiedById", "lastModifiedDate", "blueprint" }; - public Blueprint() : base(typeof(T)) - { - //Sync(x => x.Name); - //Sync(x => x.Alias); - //Sync(x => x.Sort); - //Sync(x => x.IsActive); - //Sync(x => x.LanguageId); - //Sync(x => x.Key); - } + public Blueprint() : base(typeof(T)) { } /// @@ -43,7 +39,7 @@ namespace zero.Core.Blueprints // copy all properties which are synced from the blueprint to the model ApplyDefaults(blueprint, model); - ObjectCloner.CopyProperties(blueprint, model, DefaultFields.Union(model.Blueprint.Desync).ToArray()); + ObjectCloner.CopyProperties(blueprint, model, DefaultUncopyFields.Union(model.Blueprint.Desync).ToArray()); return model; } diff --git a/zero.Core/Blueprints/BlueprintChildInterceptor.cs b/zero.Core/Blueprints/BlueprintChildInterceptor.cs new file mode 100644 index 00000000..3060bacc --- /dev/null +++ b/zero.Core/Blueprints/BlueprintChildInterceptor.cs @@ -0,0 +1,50 @@ +using Microsoft.Extensions.Logging; +using Raven.Client.Documents.Session; +using System.Threading.Tasks; +using zero.Core.Collections; +using zero.Core.Database; +using zero.Core.Entities; + +namespace zero.Core.Blueprints +{ + public class BlueprintChildInterceptor : CollectionInterceptor + { + protected IZeroContext Context { get; set; } + + protected IZeroStore Store { get; set; } + + protected ILogger Logger { get; set; } + + protected IBlueprintService BlueprintService { get; set; } + + + public BlueprintChildInterceptor(IZeroContext context, IZeroStore store, ILogger logger, IBlueprintService blueprintService) + { + Context = context; + Store = store; + Logger = logger; + BlueprintService = blueprintService; + } + + /// + public override bool CanRun(Parameters args) + { + // this interceptor does only work for child entities + return (args.Session as AsyncDocumentSession)?.DatabaseName != Context.Options.Raven.Database; + } + + + /// + public override Task> Deleting(DeleteParameters args) + { + if (args.Model.Blueprint != null) + { + InterceptorResult result = new(); + result.Result = EntityResult.Fail("@blueprint.errors.cannotDeleteChild"); + return Task.FromResult(result); + } + + return base.Deleting(args); + } + } +} diff --git a/zero.Core/Blueprints/BlueprintInterceptor.cs b/zero.Core/Blueprints/BlueprintInterceptor.cs index 096eed8b..545cae82 100644 --- a/zero.Core/Blueprints/BlueprintInterceptor.cs +++ b/zero.Core/Blueprints/BlueprintInterceptor.cs @@ -3,13 +3,12 @@ using Raven.Client.Documents; using Raven.Client.Documents.Session; using System.Collections.Generic; using System.Threading.Tasks; -using zero.Core.Blueprints; using zero.Core.Collections; using zero.Core.Database; using zero.Core.Entities; using zero.Core.Extensions; -namespace zero.Core.Routing +namespace zero.Core.Blueprints { public class BlueprintInterceptor : CollectionInterceptor { diff --git a/zero.Core/Utils/ObjectCloner.cs b/zero.Core/Utils/ObjectCloner.cs index 0c76c979..7daf97e6 100644 --- a/zero.Core/Utils/ObjectCloner.cs +++ b/zero.Core/Utils/ObjectCloner.cs @@ -46,7 +46,6 @@ namespace zero.Core.Utils if (property.PropertyType.IsValueType || property.PropertyType.IsEnum || property.PropertyType.Equals(STRING_TYPE) || propertyValue == null || propertyValue is IEnumerable) { - Console.WriteLine("copy: " + propertyNameWithPrefix); property.SetValue(target, propertyValue, null); } else if (property.PropertyType.IsClass) diff --git a/zero.Web.UI/app/core/editor-blueprint.ts b/zero.Web.UI/app/core/editor-blueprint.ts index a696d52f..ee204095 100644 --- a/zero.Web.UI/app/core/editor-blueprint.ts +++ b/zero.Web.UI/app/core/editor-blueprint.ts @@ -21,7 +21,7 @@ function canUnlock(config, model, field) { if (!config || !model || !model.blueprint) { - return true; + return false; } return config.unlocked.indexOf(field.path) > -1 @@ -49,7 +49,7 @@ async function lock(config, model, field) } -async function unlock(config, model, field) +function unlock(config, model, field) { model.blueprint.desync.push(field.path); } diff --git a/zero.Web/Defaults/ZeroBackofficePlugin.cs b/zero.Web/Defaults/ZeroBackofficePlugin.cs index 0ee4f7b6..54b95295 100644 --- a/zero.Web/Defaults/ZeroBackofficePlugin.cs +++ b/zero.Web/Defaults/ZeroBackofficePlugin.cs @@ -53,6 +53,7 @@ namespace zero.Web.Defaults zero.Interceptors.Add(gravity: 100); zero.Interceptors.Add(gravity: -1); + zero.Interceptors.Add(gravity: -1); } @@ -138,6 +139,7 @@ namespace zero.Web.Defaults services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); } diff --git a/zero.Web/Resources/Localization/zero.en-us.json b/zero.Web/Resources/Localization/zero.en-us.json index 894fef53..df1ba925 100644 --- a/zero.Web/Resources/Localization/zero.en-us.json +++ b/zero.Web/Resources/Localization/zero.en-us.json @@ -711,6 +711,9 @@ "goToChild": "View child", "settingsButton": "Settings", "xUnlocked": "{count} unlocked" + }, + "errors": { + "cannotDeleteChild": "Entities which are synchronized with a blueprint cannot be deleted" } },