瀏覽代碼

Removed ClientFactory.IsSupported

Kenric Nugteren 6 天之前
父節點
當前提交
fac9f0795c

+ 0 - 19
InABox.Core/Client/Client.cs

@@ -549,19 +549,11 @@ namespace InABox.Clients
         {
         }
 
-
-        private void CheckSupported()
-        {
-            if (!ClientFactory.IsSupported<TEntity>())
-                throw new NotSupportedException(string.Format("{0} is not supported in this context", typeof(TEntity).EntityName()));
-        }
-
         public CoreTable Query(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? orderby = null, CoreRange? range = null)
         {
             try
             {
                 using var timer = new Profiler<TEntity>(false);
-                CheckSupported();
                 
                 if (columns != null)
                 {
@@ -590,7 +582,6 @@ namespace InABox.Clients
             try
             {
                 var timer = new Profiler<TEntity>(false);
-                CheckSupported();
                 _client.Query(filter, columns, sort, range, (c, e) =>
                 {
                     timer.Log(c != null ? c.Rows.Count : -1);
@@ -611,7 +602,6 @@ namespace InABox.Clients
 
                 using (var timer = new Profiler<TEntity>(false))
                 {
-                    CheckSupported();
                     var result = _client.Load(filter, sort, range);
                     foreach (var entity in result)
                         entity.CommitChanges();
@@ -631,7 +621,6 @@ namespace InABox.Clients
             try
             {
                 var timer = new Profiler<TEntity>(false);
-                CheckSupported();
                 _client.Load(filter, sort, range,(i, e) =>
                 {
                     timer.Dispose(i != null ? i.Length : -1);
@@ -676,7 +665,6 @@ namespace InABox.Clients
 
                 using (new Profiler<TEntity>(true))
                 {
-                    CheckSupported();
                     entity.LastUpdate = DateTime.Now;
                     entity.LastUpdateBy = ClientFactory.UserID;
                     _client.Save(entity, auditnote);
@@ -695,7 +683,6 @@ namespace InABox.Clients
             try
             {
                 var timer = new Profiler<TEntity>(false);
-                CheckSupported();
                 _client.Save(entity, auditnote, (i, c) =>
                 {
                     timer.Dispose();
@@ -714,7 +701,6 @@ namespace InABox.Clients
             try
             {
                 using var timer = new Profiler<TEntity>(false);
-                CheckSupported();
                 var items = entities.AsArray();
                 if (items.Any())
                     _client.Save(items, auditnote);
@@ -732,7 +718,6 @@ namespace InABox.Clients
             try
             {
                 var timer = new Profiler<TEntity>(false);
-                CheckSupported();
                 var items = entities.AsArray();
                 if (items.Any())
                 {
@@ -762,7 +747,6 @@ namespace InABox.Clients
             {
                 using (new Profiler<TEntity>(true))
                 {
-                    CheckSupported();
                     _client.Delete(entity, auditnote);
                 }
             }
@@ -778,7 +762,6 @@ namespace InABox.Clients
             try
             {
                 var timer = new Profiler<TEntity>(true);
-                CheckSupported();
                 _client.Delete(entity, auditnote, (i, e) =>
                 {
                     timer.Dispose();
@@ -797,7 +780,6 @@ namespace InABox.Clients
             try
             {
                 using var timer = new Profiler<TEntity>(false);
-                CheckSupported();
                 var items = entities.AsArray();
                 _client.Delete(items, auditnote);
                 timer.Log(items.Length);
@@ -814,7 +796,6 @@ namespace InABox.Clients
             try
             {
                 var timer = new Profiler<TEntity>(false);
-                CheckSupported();
                 var items = entities.AsArray();
                 _client.Delete(items, auditnote, (i, e) =>
                 {

+ 0 - 37
InABox.Core/Client/ClientFactory.cs

@@ -65,43 +65,6 @@ namespace InABox.Clients
             OnRequestError?.Invoke(e);
         }
 
-        public static bool IsSupported<T>() where T : Entity, new()
-        {
-            return true;
-        }
-
-        public static bool IsSupported<T1, T2>() where T1 : Entity, new() where T2 : Entity, new()
-        {
-            return IsSupported<T1>() && IsSupported<T2>();
-        }
-
-        public static bool IsSupported<T1, T2, T3>() where T1 : Entity, new() where T2 : Entity, new() where T3 : Entity, new()
-        {
-            return IsSupported<T1>() && IsSupported<T2>() && IsSupported<T3>();
-        }
-
-        public static bool IsSupported<T1, T2, T3, T4>() where T1 : Entity, new()
-            where T2 : Entity, new()
-            where T3 : Entity, new()
-            where T4 : Entity, new()
-        {
-            return IsSupported<T1>() && IsSupported<T2>() && IsSupported<T3>() && IsSupported<T4>();
-        }
-
-        public static bool IsSupported<T1, T2, T3, T4, T5>() where T1 : Entity, new()
-            where T2 : Entity, new()
-            where T3 : Entity, new()
-            where T4 : Entity, new()
-            where T5 : Entity, new()
-        {
-            return IsSupported<T1>() && IsSupported<T2>() && IsSupported<T3>() && IsSupported<T4>() && IsSupported<T4>();
-        }
-
-        public static bool IsSupported(params Type[] types)
-        {
-            return true;
-        }
-
         public static void SetClientType(Type type, Platform platform, string? version, params object[]? parameters)
         {
             ClientType = type;

+ 8 - 0
InABox.Core/CoreTable/CoreTable.cs

@@ -640,4 +640,12 @@ namespace InABox.Core
 
         #endregion
     }
+
+    public class CoreTable<T> : CoreTable
+        where T : BaseObject, new()
+    {
+        public IEnumerable<T> ToObjects() => ToObjects<T>();
+        public List<T> ToList() => ToList<T>();
+        public T[] ToArray() => ToArray<T>();
+    }
 }

+ 1 - 2
InABox.Core/DatabaseSchema/PropertyClassLookups.cs

@@ -10,8 +10,7 @@ namespace InABox.Core
             var classes = CoreUtils.Entities.Where(x => x.IsSubclassOf(typeof(Entity)) && x.GetInterfaces().Contains(typeof(IPersistent)))
                 .OrderBy(x => x.EntityName().Split('.').Last()).ToArray();
             foreach (var entity in classes)
-                if (ClientFactory.IsSupported(entity))
-                    AddValue(entity.EntityName(), entity.EntityName().Split('.').Last());
+                AddValue(entity.EntityName(), entity.EntityName().Split('.').Last());
         }
     }
 }

+ 1 - 2
InABox.Core/Postable/PosterTypeLookup.cs

@@ -13,8 +13,7 @@ namespace InABox.Core
             var postableType = CoreUtils.GetEntity(settings.PostableType);
 
             foreach (var entity in PosterUtils.GetPosters())
-                if (ClientFactory.IsSupported(entity)
-                    && entity.GetInterfaceDefinition(typeof(IPoster<,>))!.GenericTypeArguments[0] == postableType)
+                if (entity.GetInterfaceDefinition(typeof(IPoster<,>))!.GenericTypeArguments[0] == postableType)
                 {
                     AddValue(
                         entity.EntityName(),

+ 1 - 1
InABox.Core/Security/BaseSecurityDescriptor.cs

@@ -4,7 +4,7 @@ namespace InABox.Core
 {
     public abstract class BaseSecurityDescriptor<T> : ISecurityDescriptor where T : LicenseToken
     {
-        public virtual bool Visible => SecurityDescriptorUtils.IsSupported(GetType());
+        public virtual bool Visible => true;
 
         public virtual string Category => "";
 

+ 21 - 1
InABox.Core/Security/ISecurityDescriptor.cs

@@ -1,4 +1,7 @@
-namespace InABox.Core
+using System;
+using System.Collections.Generic;
+
+namespace InABox.Core
 {
     public interface ISecurityDescriptor
     {
@@ -10,4 +13,21 @@
         bool Value { get; }
         bool HasScope(SecurityDescriptorScope scope);
     }
+
+    public interface IDependentSecurityDescriptor
+    {
+        IEnumerable<Type> DependsOn { get; }
+    }
+
+    public interface IDependentSecurityDescriptor<T1> : IDependentSecurityDescriptor
+        where T1 : ISecurityDescriptor
+    {
+        IEnumerable<Type> IDependentSecurityDescriptor.DependsOn
+        {
+            get
+            {
+                yield return typeof(T1);
+            }
+        }
+    }
 }

+ 60 - 47
InABox.Core/Security/Security.cs

@@ -126,39 +126,59 @@ namespace InABox.Core
                 _descriptors.Add(descriptor);
         }
 
+        private static bool IsAllowedInternal(ISecurityDescriptor descriptor, Guid userGuid)
+        {
+            // If you're not logged in, you can't do jack!
+            if (userGuid == Guid.Empty)
+                return false;
+
+            CheckTokens();
+            
+            // First Check for a matching User Token (override)
+            var usertoken = _usertokens.FirstOrDefault(x => x.Descriptor.Equals(descriptor.Code));
+            if (usertoken != null)
+                return usertoken.Enabled;
+
+            // If not found, fall back to the Group Token
+            var grouptoken = _grouptokens.FirstOrDefault(x => x.Descriptor.Equals(descriptor.Code));
+            if (grouptoken != null)
+                return grouptoken.Enabled;
+
+            // Still not found? fall back to the Global Token
+            var globaltoken = _globaltokens.FirstOrDefault(x => x.Descriptor.Equals(descriptor.Code));
+            if (globaltoken != null)
+                return globaltoken.Enabled;
+
+            // Aaand finally, just return the default for the descriptor
+            return descriptor.Value;
+        }
+
         public static bool IsAllowed(Type T, Guid userGuid, Guid securityId)
         {
             var descriptor = (Activator.CreateInstance(T) as ISecurityDescriptor)!;
             try
             {
-                // If you're not logged in, you can't do jack!
-                if (userGuid == Guid.Empty)
+                if(IsAllowedInternal(descriptor, userGuid))
+                {
+                    if(descriptor is IDependentSecurityDescriptor dependent)
+                    {
+                        return dependent.DependsOn.All(x => IsAllowed(T, userGuid, securityId));
+                    }
+                    else
+                    {
+                        return true;
+                    }
+                }
+                else
+                {
                     return false;
-
-                CheckTokens();
-                
-                // First Check for a matching User Token (override)
-                var usertoken = _usertokens.FirstOrDefault(x => x.Descriptor.Equals(descriptor.Code));
-                if (usertoken != null)
-                    return usertoken.Enabled;
-
-                // If not found, fall back to the Group Token
-                var grouptoken = _grouptokens.FirstOrDefault(x => x.Descriptor.Equals(descriptor.Code));
-                if (grouptoken != null)
-                    return grouptoken.Enabled;
-
-                // Still not found? fall back to the Global Token
-                var globaltoken = _globaltokens.FirstOrDefault(x => x.Descriptor.Equals(descriptor.Code));
-                if (globaltoken != null)
-                    return globaltoken.Enabled;
+                }
             }
             catch (Exception e)
             {
                 Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
+                return false;
             }
-
-            // Aaand finally, just return the default for the descriptor
-            return descriptor.Value;
         }
 
         public static bool IsAllowed<T>(Guid userGuid, Guid securityId) where T : ISecurityDescriptor, new() 
@@ -172,96 +192,89 @@ namespace InABox.Core
 
         public static bool CanView<TEntity>(Guid userGuid, Guid securityId) where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() 
-                   && IsAllowed<AutoSecurityDescriptor<TEntity, CanView<TEntity>>>(userGuid, securityId);
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanView<TEntity>>>(userGuid, securityId);
         }
 
         public static bool CanView(Type TEntity)
         {
-            return ClientFactory.IsSupported(TEntity) &&
-                IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanView<>).MakeGenericType(TEntity)));
+            return IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanView<>).MakeGenericType(TEntity)));
         }
         public static bool CanView<TEntity>() where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanView<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanView<TEntity>>>();
         }
 
         public static bool CanEdit(Type TEntity, Guid userGuid, Guid securityId)
         {
-            return ClientFactory.IsSupported(TEntity) &&
-                IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanEdit<>).MakeGenericType(TEntity)), userGuid, securityId);
+            return IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanEdit<>).MakeGenericType(TEntity)), userGuid, securityId);
         }
         public static bool CanEdit<TEntity>(Guid userGuid, Guid securityId) where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanEdit<TEntity>>>(userGuid, securityId);
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanEdit<TEntity>>>(userGuid, securityId);
         }
 
         public static bool CanEdit(Type TEntity)
         {
-            return ClientFactory.IsSupported(TEntity) &&
-                IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanEdit<>).MakeGenericType(TEntity)));
+            return IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanEdit<>).MakeGenericType(TEntity)));
         }
         public static bool CanEdit<TEntity>() where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanEdit<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanEdit<TEntity>>>();
         }
 
         public static bool CanImport<TEntity>() where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanImport<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanImport<TEntity>>>();
         }
 
         public static bool CanExport<TEntity>() where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanExport<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanExport<TEntity>>>();
         }
 
         public static bool CanMerge<TEntity>() where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanMerge<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanMerge<TEntity>>>();
         }
 
         public static bool CanPost<TEntity>() where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanPost<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanPost<TEntity>>>();
         }
 
         public static bool CanConfigurePost<TEntity>() where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanConfigurePost<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanConfigurePost<TEntity>>>();
         }
 
         public static bool CanDelete<TEntity>() where TEntity : Entity, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanDelete<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanDelete<TEntity>>>();
         }
         
         public static bool CanDelete(Type TEntity)
         {
-            return ClientFactory.IsSupported(TEntity) &&
-                   IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanDelete<>).MakeGenericType(TEntity)));
+            return IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanDelete<>).MakeGenericType(TEntity)));
         }
 
         public static bool CanManageIssues(Type TEntity)
         {
-            return ClientFactory.IsSupported(TEntity)
-                && IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanManageIssues<>).MakeGenericType(TEntity)));
+            return IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanManageIssues<>).MakeGenericType(TEntity)));
         }
 
         public static bool CanManageIssues<TEntity>() where TEntity : Entity, IIssues, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanManageIssues<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanManageIssues<TEntity>>>();
         }
         
         public static bool CanManageProblems(Type TEntity)
         {
-            return ClientFactory.IsSupported(TEntity)
-                   && IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanManageProblems<>).MakeGenericType(TEntity)));
+            return IsAllowed(typeof(AutoSecurityDescriptor<,>).MakeGenericType(TEntity, typeof(CanManageProblems<>).MakeGenericType(TEntity)));
         }
 
         public static bool CanManageProblems<TEntity>() where TEntity : Entity, IProblems, new()
         {
-            return ClientFactory.IsSupported<TEntity>() && IsAllowed<AutoSecurityDescriptor<TEntity, CanManageProblems<TEntity>>>();
+            return IsAllowed<AutoSecurityDescriptor<TEntity, CanManageProblems<TEntity>>>();
         }
     }
 }

+ 0 - 8
InABox.Core/Security/SecurityDescriptorUtils.cs

@@ -6,14 +6,6 @@ namespace InABox.Core
 {
     public static class SecurityDescriptorUtils
     {
-        public static bool IsSupported(Type type)
-        {
-            var entities = type.GetInheritedGenericTypeArguments().ToArray();
-            if (entities.Length > 1)
-                return ClientFactory.IsSupported(entities.Skip(1).ToArray());
-            return true;
-        }
-
         public static string Type(Type type)
         {
             type = type.BaseType?.GetGenericArguments().FirstOrDefault();

+ 40 - 47
inabox.wpf/DynamicGrid/DynamicGridUtils.cs

@@ -132,30 +132,26 @@ public static class DynamicGridUtils
 
             foreach (var map in maps)
             {
-                if (ClientFactory.IsSupported(map))
+                _allm2mpages ??= CoreUtils.Entities.Where(
+                        x => x.IsClass
+                             && !x.IsGenericType
+                             && x.HasInterface(typeof(IDynamicManyToManyGrid<,>)))
+                    .ToArray();
+
+                var subtypes = _allm2mpages.Where(
+                    x => x.GetInterfaces().Any(i =>
+                        i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDynamicManyToManyGrid<,>) &&
+                        i.GenericTypeArguments.First().Equals(map) && i.GenericTypeArguments.Last().Equals(type))
+                );
+
+                if (subtypes.Any())
                 {
-                    _allm2mpages ??= CoreUtils.Entities.Where(
-                            x => x.IsClass
-                                 && !x.IsGenericType
-                                 && x.HasInterface(typeof(IDynamicManyToManyGrid<,>)))
-                        .ToArray();
-
-                    var subtypes = _allm2mpages.Where(
-                        x => x.GetInterfaces().Any(i =>
-                            i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDynamicManyToManyGrid<,>) &&
-                            i.GenericTypeArguments.First().Equals(map) && i.GenericTypeArguments.Last().Equals(type))
-                    );
-
-                    if (subtypes.Any())
-                    {
-                        pageTypes.Add(subtypes.First());
-                    }
-                    else
-                    {
-                        pageTypes.Add(typeof(DynamicManyToManyGrid<,>).MakeGenericType(map, type));
-                    }
+                    pageTypes.Add(subtypes.First());
+                }
+                else
+                {
+                    pageTypes.Add(typeof(DynamicManyToManyGrid<,>).MakeGenericType(map, type));
                 }
-
             }
             _manytomanytomanypages[type] = pageTypes.ToArray();
         }
@@ -185,32 +181,29 @@ public static class DynamicGridUtils
 
             foreach (var map in maps)
             {
-                if (ClientFactory.IsSupported(map))
+                _allo2mpages ??= CoreUtils.Entities.Where(
+                        x =>
+                            x.IsClass
+                            && !x.IsGenericType
+                            && x.HasInterface(typeof(IDynamicOneToManyGrid<,>))
+                            && !x.HasInterface<ISpecificGrid>())
+                    .ToArray();
+
+                var subtypes = _allo2mpages.Where(x => x.GetInterfaces().Any(
+                        i => i.IsGenericType
+                             && i.GetGenericTypeDefinition() == typeof(IDynamicOneToManyGrid<,>)
+                             && i.GenericTypeArguments.First().Equals(type)
+                             && i.GenericTypeArguments.Last().Equals(map)
+                    )
+                );
+
+                if (subtypes.Any())
                 {
-                    _allo2mpages ??= CoreUtils.Entities.Where(
-                            x =>
-                                x.IsClass
-                                && !x.IsGenericType
-                                && x.HasInterface(typeof(IDynamicOneToManyGrid<,>))
-                                && !x.HasInterface<ISpecificGrid>())
-                        .ToArray();
-
-                    var subtypes = _allo2mpages.Where(x => x.GetInterfaces().Any(
-                            i => i.IsGenericType
-                                 && i.GetGenericTypeDefinition() == typeof(IDynamicOneToManyGrid<,>)
-                                 && i.GenericTypeArguments.First().Equals(type)
-                                 && i.GenericTypeArguments.Last().Equals(map)
-                        )
-                    );
-
-                    if (subtypes.Any())
-                    {
-                        pageTypes.Add(subtypes.First());
-                    }
-                    else
-                    {
-                        pageTypes.Add(typeof(DynamicOneToManyGrid<,>).MakeGenericType(type, map));
-                    }
+                    pageTypes.Add(subtypes.First());
+                }
+                else
+                {
+                    pageTypes.Add(typeof(DynamicOneToManyGrid<,>).MakeGenericType(type, map));
                 }
             }
 

+ 1 - 2
inabox.wpf/DynamicGrid/Grids/DynamicDataGrid.cs

@@ -372,8 +372,7 @@ public class DynamicDataGrid<TEntity> : DynamicGrid<TEntity>, IDynamicDataGrid w
     public override void LoadEditorButtons(TEntity item, DynamicEditorButtons buttons)
     {
         base.LoadEditorButtons(item, buttons);
-        if (ClientFactory.IsSupported<AuditTrail>())
-            buttons.Add("Audit Trail", Wpf.Resources.view.AsBitmapImage(), item, AuditTrailClick);
+        buttons.Add("Audit Trail", Wpf.Resources.view.AsBitmapImage(), item, AuditTrailClick);
     }
 
     private void AuditTrailClick(object sender, TEntity entity)

+ 1 - 2
inabox.wpf/DynamicGrid/Grids/DynamicOneToManyGrid.cs

@@ -351,8 +351,7 @@ public class DynamicOneToManyGrid<TOne, TMany> : DynamicGrid<TMany>,
     public override void LoadEditorButtons(TMany item, DynamicEditorButtons buttons)
     {
         base.LoadEditorButtons(item, buttons);
-        if (ClientFactory.IsSupported<AuditTrail>())
-            buttons.Add("Audit Trail", Wpf.Resources.view.AsBitmapImage(), item, AuditTrailClick);
+        buttons.Add("Audit Trail", Wpf.Resources.view.AsBitmapImage(), item, AuditTrailClick);
     }
 
     private void AuditTrailClick(object sender, object? item)

+ 1 - 0
inabox.wpf/Panel/IPanel.cs

@@ -177,6 +177,7 @@ public class PanelAction : DependencyObject, IPanelActionItem
     }
     
 }
+
 public class PanelActionSeparator : IPanelActionItem
 {