Przeglądaj źródła

Added copy form button

Kenric Nugteren 1 rok temu
rodzic
commit
6cad484e19

+ 28 - 0
InABox.Core/Column.cs

@@ -14,6 +14,8 @@ namespace InABox.Core
     {
         string Property { get; }
 
+        Expression Expression { get; }
+
         Type Type { get; }
     }
 
@@ -153,6 +155,10 @@ namespace InABox.Core
         IncludeNestedLinks,
         IncludeEditable,
         /// <summary>
+        /// Add all columns that are data actually on the entity, and not on entity links or calculated fields.
+        /// </summary>
+        DataColumns,
+        /// <summary>
         /// Add all columns found.
         /// </summary>
         All
@@ -434,6 +440,28 @@ namespace InABox.Core
                     columns.Add(new Column<T>(prop.Name));
                 return this;
             }
+            else if (types.Contains(ColumnType.DataColumns))
+            {
+                foreach(var prop in props)
+                {
+                    if (prop.IsCalculated)
+                    {
+                        continue;
+                    }
+                    if (prop.HasParentEntityLink())
+                    {
+                        if(prop.Parent?.HasParentEntityLink() == true || !prop.Name.EndsWith(".ID"))
+                        {
+                            continue;
+                        }
+                    }
+                    columns.Add(new Column<T>(prop.Name));
+                }
+                if(types.Length == 1)
+                {
+                    return this;
+                }
+            }
 
             if (typeof(T).IsSubclassOf(typeof(Entity)) && !types.Contains(ColumnType.ExcludeID))
                 columns.Add(new Column<T>("ID"));

+ 1 - 1
InABox.Core/DigitalForms/Forms/EntityForm.cs

@@ -7,7 +7,7 @@ namespace InABox.Core
 
     public interface IEntityForm
     {
-
+        string Description { get; set; }
     }
 
     [Caption("Digital Forms")]

+ 63 - 16
InABox.Core/Entity.cs

@@ -71,20 +71,55 @@ namespace InABox.Core
 
     public class EntityDuplicator<TEntity> : IEntityDuplicator where TEntity : Entity, IRemotable, IPersistent
     {
-        private readonly List<Tuple<Type, Type, Expression>> _relationships = new List<Tuple<Type, Type, Expression>>();
+        private interface IRelationship
+        {
+            Type ParentType { get; }
 
-        public void Duplicate(IEnumerable<TEntity> entites) =>
-            Duplicate(typeof(TEntity),
-                new Filter<TEntity>(x => x.ID).InList(entites.Select(x => x.ID).ToArray()));
+            Type ChildType { get; }
 
-        public void Duplicate(IFilter filter)
+            IFilter GetFilter(Entity parent);
+        }
+        private class EntityLinkRelationship<TParent, TChild> : IRelationship
         {
-            Duplicate(typeof(TEntity), filter);
+            public Type ParentType => typeof(TParent);
+
+            public Type ChildType => typeof(TChild);
+
+            public Column<TChild> Column { get; set; }
+
+            public IFilter GetFilter(Entity parent)
+            {
+                return new Filter<TChild>(Column).IsEqualTo(parent.ID);
+            }
         }
 
+        private class GenericRelationship<TParent, TChild> : IRelationship
+            where TParent : Entity
+        {
+            public Type ParentType => typeof(TParent);
+
+            public Type ChildType => typeof(TChild);
+
+            public Column<TChild> Column { get; set; }
+
+            public Func<TParent, object?> Func { get; set; }
+
+            public IFilter GetFilter(Entity parent)
+            {
+                return new Filter<TChild>(Column).IsEqualTo(Func(parent as TParent));
+            }
+        }
+
+        private readonly List<IRelationship> _relationships = new List<IRelationship>();
+
+        public void Duplicate(IEnumerable<TEntity> entites) =>
+            Duplicate(typeof(TEntity),
+                new Filter<TEntity>(x => x.ID).InList(entites.Select(x => x.ID).ToArray()));
+
         private void Duplicate(Type parent, IFilter filter)
         {
-            var table = ClientFactory.CreateClient(parent).Query(filter);
+            var table = ClientFactory.CreateClient(parent)
+                .Query(filter, Columns.Create(parent).DefaultColumns(ColumnType.DataColumns));
             foreach (var row in table.Rows)
             {
                 var update = (row.ToObject(parent) as Entity)!;
@@ -92,21 +127,33 @@ namespace InABox.Core
                 update.ID = Guid.Empty;
                 update.CommitChanges();
                 ClientFactory.CreateClient(parent).Save(update, "Duplicated Record");
-                foreach (var relationship in _relationships.Where(x => x.Item1 == parent))
+                foreach (var relationship in _relationships.Where(x => x.ParentType == parent))
                 {
-                    var filtertype = typeof(Filter<>).MakeGenericType(relationship.Item2);
-                    var newfilter = Activator.CreateInstance(filtertype) as IFilter;
-                    filter.Expression = relationship.Item3;
-                    filter.Operator = Operator.IsEqualTo;
-                    filter.Value = id;
-                    Duplicate(relationship.Item2, filter);
+                    Duplicate(relationship.ChildType, relationship.GetFilter(update));
                 }
             }
         }
 
-        public void AddChild<TParent, TChild>(Expression<Func<TChild, IEntityLink<TParent>>> childkey) where TParent : Entity where TChild : Entity
+        public void AddChild<TParent, TChild, TParentLink>(Expression<Func<TChild, TParentLink>> childkey)
+            where TParent : Entity, IRemotable, IPersistent
+            where TChild : Entity, IRemotable, IPersistent
+            where TParentLink : IEntityLink<TParent>
         {
-            _relationships.Add(new Tuple<Type, Type, Expression>(typeof(TParent), typeof(TChild), childkey));
+            _relationships.Add(new EntityLinkRelationship<TParent, TChild>
+            {
+                Column = new Column<TChild>(CoreUtils.GetFullPropertyName(childkey, ".") + ".ID")
+            });
+        }
+
+        public void AddChild<TParent, TChild>(Column<TChild> linkColumn, Func<TParent, object?> value)
+            where TParent : Entity, IRemotable, IPersistent
+            where TChild : Entity, IRemotable, IPersistent
+        {
+            _relationships.Add(new GenericRelationship<TParent, TChild>
+            {
+                Column = linkColumn,
+                Func = value
+            });
         }
 
         void IEntityDuplicator.Duplicate(IEnumerable<BaseObject> entities) => Duplicate(entities.Cast<TEntity>());

+ 85 - 0
inabox.wpf/DigitalForms/DigitalFormGrid.cs

@@ -12,6 +12,7 @@ using InABox.Clients;
 using InABox.Core;
 using InABox.Core.Reports;
 using InABox.Scripting;
+using InABox.Wpf;
 using InABox.WPF;
 using Microsoft.Win32;
 
@@ -156,6 +157,8 @@ namespace InABox.DynamicGrid
     {
         private bool _showall;
 
+        private Button CopyForm = null!; // Late-initialised
+
         protected override void Init()
         {
             base.Init();
@@ -165,6 +168,13 @@ namespace InABox.DynamicGrid
             //ActionColumns.Add(new DynamicImageColumn(ReportImage, ReportClick));
 
             AddButton("Groups", null, EditGroupsClick);
+
+            CopyForm = AddButton("Copy Form", InABox.Wpf.Resources.copy.AsBitmapImage(), CopyForm_Click);
+            CopyForm.IsEnabled = false;
+            if (!Security.CanEdit<DigitalForm>())
+            {
+                CopyForm.Visibility = Visibility.Collapsed;
+            }
         }
 
         protected override void DoReconfigure(FluentList<DynamicGridOption> options)
@@ -174,6 +184,81 @@ namespace InABox.DynamicGrid
             options.AddRange(DynamicGridOption.ImportData, DynamicGridOption.ExportData, DynamicGridOption.FilterRows);
         }
 
+        protected override void SelectItems(CoreRow[]? rows)
+        {
+            base.SelectItems(rows);
+
+            CopyForm.IsEnabled = rows is not null && rows.Length == 1;
+        }
+
+        private bool CopyForm_Click(Button btn, CoreRow[] rows)
+        {
+            if(rows.Length != 1)
+            {
+                MessageWindow.ShowMessage("Please select one form to copy.", "Invalid selection.");
+                return false;
+            }
+
+            var form = rows[0].ToObject<DigitalForm>();
+            Client.EnsureColumns(form,
+                new Columns<DigitalForm>(x => x.Description)
+                    .Add(x => x.AppliesTo)
+                    .Add(x => x.Secure)
+                    .Add(x => x.Final)
+                    .Add(x => x.Group.ID));
+
+            var newForm = new DigitalForm();
+
+            newForm.Description = form.Description;
+            newForm.AppliesTo = form.AppliesTo;
+            newForm.Secure = form.Secure;
+            newForm.Final = form.Final;
+            newForm.Group.ID = form.Group.ID;
+
+            var children = Client.QueryMultiple(
+                new KeyedQueryDef<DigitalFormLayout>(
+                    new Filter<DigitalFormLayout>(x => x.Form.ID).IsEqualTo(form.ID),
+                    new Columns<DigitalFormLayout>(x => x.Code)
+                        .Add(x => x.Description)
+                        .Add(x => x.Type)
+                        .Add(x => x.Layout)
+                        .Add(x => x.Active)),
+                new KeyedQueryDef<DigitalFormVariable>(
+                    new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(form.ID),
+                    new Columns<DigitalFormVariable>(x => x.Code)
+                        .Add(x => x.Description)
+                        .Add(x => x.VariableType)
+                        .Add(x => x.Group)
+                        .Add(x => x.Parameters)
+                        .Add(x => x.Required)
+                        .Add(x => x.Secure)
+                        .Add(x => x.Retain)
+                        .Add(x => x.Hidden)
+                        .Add(x => x.Sequence)),
+                new KeyedQueryDef<ReportTemplate>(
+                    new Filter<ReportTemplate>(x => x.Section).IsEqualTo(form.ID.ToString()),
+                    null),
+                new KeyedQueryDef<DigitalFormDocument>(
+                    new Filter<DigitalFormDocument>(x => x.EntityLink.ID).IsEqualTo(form.ID),
+                    new Columns<DigitalFormDocument>(x => x.Type)
+                        .Add(x => x.DocumentLink.ID)
+                        .Add(x => x.Superceded)
+                        .Add(x => x.Thumbnail)
+                        .Add(x => x.Notes)));
+
+            if (EditItems(new[] { newForm }, type =>
+            {
+                return children.GetOrDefault(type.Name);
+            }))
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
         private bool EditGroupsClick(Button arg1, CoreRow[] arg2)
         {
             new MasterList(typeof(DigitalFormGroup)).ShowDialog();

+ 2 - 2
inabox.wpf/DynamicGrid/BaseDynamicGrid.cs

@@ -203,10 +203,10 @@ namespace InABox.DynamicGrid
 
         public abstract void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains);
 
-        public abstract Button AddButton(string? caption, BitmapImage? image, string? tooltip, Func<Button, CoreRow[], bool> action,
+        public abstract Button AddButton(string? caption, BitmapImage? image, string? tooltip, DynamicGridButtonClickEvent action,
             DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);
 
-        public Button AddButton(string? caption, BitmapImage? image, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left)
+        public Button AddButton(string? caption, BitmapImage? image, DynamicGridButtonClickEvent action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left)
         {
             var result = AddButton(caption, image, null, action, position);
             return result;

+ 2 - 2
inabox.wpf/DynamicGrid/DynamicGrid.cs

@@ -3354,7 +3354,7 @@ namespace InABox.DynamicGrid
         }
 
 
-        public override Button AddButton(string? caption, BitmapImage? image, string? tooltip, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left)
+        public override Button AddButton(string? caption, BitmapImage? image, string? tooltip, DynamicGridButtonClickEvent action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left)
         {
             var button = CreateButton(image, caption, tooltip);
             button.Margin = position == DynamicGridButtonPosition.Right
@@ -3376,7 +3376,7 @@ namespace InABox.DynamicGrid
         private void Button_Click(object sender, RoutedEventArgs e)
         {
             var button = (Button)sender;
-            var action = (Func<Button, CoreRow[], bool>)button.Tag;
+            var action = (DynamicGridButtonClickEvent)button.Tag;
 
             //CoreRow row = (CurrentRow > -1) && (CurrentRow < Data.Rows.Count) ? Data.Rows[this.CurrentRow] : null;
             if (action.Invoke(button, SelectedRows))

+ 3 - 0
inabox.wpf/DynamicGrid/DynamicGridCommon.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Windows.Controls;
 using InABox.Core;
 
 namespace InABox.DynamicGrid
@@ -99,6 +100,8 @@ namespace InABox.DynamicGrid
     
     public delegate void EntitySaveEvent(IDynamicEditorForm editor, BaseObject[] items);
 
+    public delegate bool DynamicGridButtonClickEvent(Button button, CoreRow[] rows);
+
 
     public class DynamicGridSelectionEventArgs : CancelEventArgs
     {

+ 2 - 2
inabox.wpf/DynamicGrid/IDynamicGrid.cs

@@ -66,9 +66,9 @@ namespace InABox.DynamicGrid
 
         void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains);
 
-        Button AddButton(string? caption, BitmapImage? image, string? tooltip, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);
+        Button AddButton(string? caption, BitmapImage? image, string? tooltip, DynamicGridButtonClickEvent action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);
 
-        Button AddButton(string? caption, BitmapImage? image, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);
+        Button AddButton(string? caption, BitmapImage? image, DynamicGridButtonClickEvent action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);
 
         void UpdateButton(Button button, BitmapImage? image, string? text, string? tooltip = null);