Преглед изворни кода

Added Copy from Previous option when creating new Document Milestones
Job Documents can now be editied by double-click and right-click -> Edit
DocumentSet grid refresh now retains previous scroll position
Editing Document Sets updates grid without refreshing

Frank van den Bos пре 2 година
родитељ
комит
2af0c977a3

+ 3 - 0
prs.classes/Entities/Job/DocumentSet/JobDocumentSetMileStoneLink.cs

@@ -7,6 +7,9 @@ namespace Comal.Classes
     {
         [NullEditor]
         public override Guid ID { get; set; }
+        
+        [NullEditor]
+        public JobDocumentSetLink DocumentSet { get; set; }
 
         [EditorSequence(1)]
         public JobDocumentSetMileStoneTypelink Type { get; set; }

+ 5 - 1
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetMileStoneGrid.cs

@@ -1,11 +1,15 @@
+using System.Linq;
+using com.sun.org.apache.xpath.@internal.operations;
 using Comal.Classes;
 using InABox.Core;
 using InABox.DynamicGrid;
+using Microsoft.Office.Interop.Outlook;
 
 namespace PRSDesktop
 {
     public class JobDocumentSetMileStoneGrid : DynamicDataGrid<JobDocumentSetMileStone>
     {
+
         public JobDocumentSetMileStoneGrid() : base()
         {
             OnCustomiseEditor += OnOnCustomiseEditor;
@@ -15,7 +19,7 @@ namespace PRSDesktop
         {
             if (string.Equals(column.ColumnName, "Issued") || string.Equals(column.ColumnName, "Closed"))
                 editor.Editable = Security.IsAllowed<CanEditJobDocumentSetMileStoneDates>() ? Editable.Enabled : Editable.Disabled;
-
         }
+        
     }
 }

+ 1 - 0
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetTree.xaml

@@ -170,6 +170,7 @@
             ItemsSourceChanged="TreeGrid_OnItemsSourceChanged"
             SelectionChanged="TreeGrid_OnSelectionChanged"
             CurrentCellActivated="TreeGrid_OnCurrentCellActivated"
+            CellDoubleTapped="TreeGrid_OnCellDoubleTapped"
         >
             <Syncfusion:SfTreeGrid.StackedHeaderRows>
                 <Syncfusion:StackedHeaderRow x:Name="stackedHeaderRow" />

+ 161 - 17
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetTree.xaml.cs

@@ -2,25 +2,21 @@ using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.ComponentModel;
-using System.Data;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
-using System.Reflection;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Documents;
 using System.Windows.Forms;
-using System.Windows.Forms.VisualStyles;
 using System.Windows.Input;
 using System.Windows.Media;
 using Comal.Classes;
-using H.Pipes.Extensions;
 using InABox.Clients;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.WPF;
-using Microsoft.Office.Interop.Outlook;
+using Syncfusion.Data.Extensions;
 using Syncfusion.UI.Xaml.Grid;
 using Syncfusion.UI.Xaml.TreeGrid;
 using Syncfusion.UI.Xaml.TreeGrid.Helpers;
@@ -132,6 +128,11 @@ namespace PRSDesktop
         {
             return new ObservableCollection<DocumentSetNode>(_nodes.Where(x => x.Parent.Equals(id) && (x.ID != id)));
         }
+  
+        public DocumentSetNode? GetNode(Guid id)
+        {
+            return _nodes.FirstOrDefault(x => x.ID == id);
+        }
         
     }
 
@@ -205,6 +206,7 @@ namespace PRSDesktop
         private bool _flatlist = false;
         private bool _includeretired = false;
 
+        private DocumentSetNodes _documentsets = null;
         
         public JobDocumentSetTree()
         {
@@ -222,8 +224,12 @@ namespace PRSDesktop
         
         public void Refresh()
         {
+
             using (new WaitCursor())
             {
+                var scrollviewer = WPFUtils.FindVisualChildren<ScrollViewer>(treeGrid).FirstOrDefault();
+                var verticalOffset = scrollviewer != null ? scrollviewer.VerticalOffset : 0;
+                var horizontalOffset = treeGrid.SelectedItem != null ? scrollviewer.HorizontalOffset : 0;
                 treeGrid.ItemsSource = null;
 
                 var setfilter = new Filter<JobDocumentSet>(x => x.Job.ID).IsEqualTo(JobID);
@@ -354,14 +360,18 @@ namespace PRSDesktop
                     }
                 }
 
-                var documentsets = new DocumentSetNodes(columns);
+                _documentsets = new DocumentSetNodes(columns);
 
                 foreach (var setrow in Data.Rows)
                 {
+                    
+                    
                     Guid setid = setrow.Get<JobDocumentSet, Guid>(x => x.ID);
                     Guid parentid = _flatlist ? Guid.Empty : setrow.Get<JobDocumentSet, Guid>(x => x.Parent.ID);
 
-                    var node = documentsets.Add(setid, parentid);
+                    var node = _documentsets.Add(setid, parentid);
+                    
+                    
                     JobDocumentSetDescriptionBlock desc = new JobDocumentSetDescriptionBlock()
                     {
                         ID = setid,
@@ -416,12 +426,17 @@ namespace PRSDesktop
                     }
                 }
 
-                ConfigureColumns(documentsets);
+                ConfigureColumns(_documentsets);
 
                 ConfigureStackedHeader();
 
-                treeGrid.ItemsSource = documentsets.Nodes;
-                DocumentCount.Content = $"{documentsets.Nodes.Count} {(documentsets.Nodes.Count > 1 ? "Records" : "Record")}";
+                treeGrid.ItemsSource = _documentsets.Nodes;
+                DocumentCount.Content = $"{_documentsets.Nodes.Count} {(_documentsets.Nodes.Count > 1 ? "Records" : "Record")}";
+                if (scrollviewer != null)
+                {
+                    scrollviewer.ScrollToVerticalOffset(verticalOffset);
+                    scrollviewer.ScrollToHorizontalOffset(horizontalOffset);
+                }
             }
 
         }
@@ -534,14 +549,20 @@ namespace PRSDesktop
             {
 
                 var document = treeGrid.SelectedItem as DocumentSetNode;
-                
 
+
+                MenuItem edit = new MenuItem();
+                edit.Header = "Edit Document Set";
+                edit.Click += (o, args) => { EditDocumentSets(new Guid[] { document.ID }); };
+                MileStoneMenu.Items.Add(edit);
+
+                MileStoneMenu.Items.Add(new Separator());
+                
                 MenuItem addchild = new MenuItem();
                 addchild.Header = "Add Child";
                 addchild.Click += (o,args) => { AddChildDocument(document); };
                 MileStoneMenu.Items.Add(addchild);
-
-
+                
                 var documents = treeGrid.SelectedItems.Select(x => (x as DocumentSetNode));
                 MenuItem movetofolder = new MenuItem();
                 movetofolder.Header = "Move To Folder";
@@ -581,6 +602,7 @@ namespace PRSDesktop
                 );
                 if (openmilestones)
                     canCreateNewMileStones = false;
+                
             }
             
             if (canCreateNewMileStones)
@@ -988,9 +1010,43 @@ namespace PRSDesktop
             }
         }
 
+        private Dictionary<Guid, JobDocumentSetMileStone> GetPreviousMileStones(Guid[] setids, Guid typeid)
+        {
+            var result = new Dictionary<Guid, JobDocumentSetMileStone>();
+            foreach (var setid in setids)
+            {
+                var typeindex = _types.Keys.IndexOf(typeid);
+                JobDocumentSetMileStone? last = null;
+                while ((last == null) && (typeindex > 0))
+                {
+                    last = _milestones.Rows.LastOrDefault(r =>
+                            (r.Get<JobDocumentSetMileStone, Guid>(c => c.DocumentSet.ID) == setid) &&
+                            (r.Get<JobDocumentSetMileStone, Guid>(c => c.Type.ID) == _types.Keys.ToArray()[typeindex]))
+                        ?.ToObject<JobDocumentSetMileStone>();
+                    typeindex--;
+                }
+
+                if (last != null)
+                    result[setid] = last;
+
+            }
+            return result;
+        }
+
         private void CreateMileStone(Guid[] setids, Guid typeid, DateTime duedate)
         {
-            List<JobDocumentSetMileStone> updates = new List<JobDocumentSetMileStone>();
+            bool bCopy = false;
+            var lastmilestones = GetPreviousMileStones(setids, typeid);
+            if (lastmilestones.Any(x => x.Value.Attachments > 0))
+            {
+                var confirm = MessageBox.Show("Do you wish to copy the files from the previous milestones?", "Copy Files",
+                    MessageBoxButton.YesNoCancel);
+                if (confirm == MessageBoxResult.Cancel)
+                    return;
+                bCopy = confirm == MessageBoxResult.Yes;
+            }
+
+            Dictionary<JobDocumentSetMileStone,JobDocumentSetMileStoneFile[]> updates = new Dictionary<JobDocumentSetMileStone, JobDocumentSetMileStoneFile[]>();
             foreach (var setid in setids)
             {
                 JobDocumentSetMileStone milestone = new JobDocumentSetMileStone();
@@ -998,10 +1054,55 @@ namespace PRSDesktop
                 milestone.Type.ID = typeid;
                 milestone.Status = JobDocumentSetMileStoneStatus.NotStarted;
                 milestone.Due = duedate;
-                updates.Add(milestone);
+
+                JobDocumentSetMileStoneFile[] files = new JobDocumentSetMileStoneFile[] { };
+                if (bCopy && lastmilestones.TryGetValue(setid, out var lastmilestone))
+                {
+                    if (lastmilestone.Attachments > 0)
+                    {
+                        files = new Client<JobDocumentSetMileStoneFile>().Query(
+                            new Filter<JobDocumentSetMileStoneFile>(x => x.EntityLink.ID).InList(lastmilestone.ID),
+                            new Columns<JobDocumentSetMileStoneFile>(x=>x.EntityLink.DocumentSet.ID)
+                                .Add(x => x.DocumentLink.FileName)
+                                .Add(x => x.DocumentLink.ID),
+                            new SortOrder<JobDocumentSetMileStoneFile>(x => x.DocumentLink.FileName)
+                        ).Rows.Select(r=>r.ToObject<JobDocumentSetMileStoneFile>()).ToArray();                        
+                    }
+                }
+                
+                updates[milestone] = files;
             }
             var grid = new JobDocumentSetMileStoneGrid();
-            if (grid.EditItems(updates.ToArray()))
+            grid.OnAfterSave += (editor, items) =>
+            {
+                if (updates.Keys.Count == 1)
+                    return;
+                List<JobDocumentSetMileStoneFile> fileupdates = new List<JobDocumentSetMileStoneFile>();
+                foreach (var milestone in updates.Keys)
+                {
+                    foreach (var file in updates[milestone])
+                    {
+                        file.EntityLink.ID = milestone.ID;
+                        fileupdates.Add(file);
+                    }
+                }
+
+                if (fileupdates.Any())
+                    new Client<JobDocumentSetMileStoneFile>().Save(fileupdates,"");
+            };
+
+            if (grid.EditItems(updates.Keys.ToArray(), (t) =>
+                {
+                    if ((t == typeof(JobDocumentSetMileStoneFile)) && (updates.Keys.Count == 1))
+                    {
+                        CoreTable result = new CoreTable();
+                        result.LoadColumns(typeof(JobDocumentSetMileStoneFile));
+                        result.LoadRows(updates[updates.Keys.First()]);
+                        return result;
+                    }
+                    return null;
+                }, true)
+            )
                 Refresh();
         }
 
@@ -1308,6 +1409,11 @@ namespace PRSDesktop
 
             Guid[] setIDs = treeGrid.SelectedItems.Select(x => (x as DocumentSetNode).ID).ToArray();
 
+            EditDocumentSets(setIDs);
+        }
+
+        private void EditDocumentSets(Guid[] setIDs)
+        {
             var sets = new Client<JobDocumentSet>().Query(
                 new Filter<JobDocumentSet>(x => x.ID).InList(setIDs)
             ).Rows.Select(x => x.ToObject<JobDocumentSet>()).ToArray();
@@ -1324,7 +1430,38 @@ namespace PRSDesktop
                     editor.Editable = AreaVisible ? Editable.Enabled : Editable.Hidden;
             };
             if (grid.EditItems(sets))
-                Refresh();
+                UpdateNodes(sets);
+        }
+
+        private void UpdateNodes(IEnumerable<JobDocumentSet> sets)
+        {
+            if (_documentsets == null)
+                return;
+            foreach (var set in sets)
+            {
+                var node = _documentsets.GetNode(set.ID);
+                if (node != null)
+                {
+                    JobDocumentSetDescriptionBlock desc = new JobDocumentSetDescriptionBlock()
+                    {
+                        ID = set.ID,
+                        Code = set.Code,
+                        Description = set.Description,
+                    };
+                    node.Description = Serialization.Serialize(desc);
+
+                    JobDocumentSetDetailsBlock dets = new JobDocumentSetDetailsBlock()
+                    {
+                        ID = set.ID,
+                        Date = set.Date,
+                        Size = set.Size,
+                        Scale = set.Scale,
+                        Employee = set.Employee.Name
+                    };
+                    node.Details = Serialization.Serialize(dets);
+                }
+            }
+            
         }
 
         private void HideRejected_OnClick(object sender, RoutedEventArgs e)
@@ -1441,5 +1578,12 @@ namespace PRSDesktop
 
             
         }
+
+        private void TreeGrid_OnCellDoubleTapped(object? sender, TreeGridCellDoubleTappedEventArgs e)
+        {
+            var set = e.Record as DocumentSetNode;
+            if (set != null)
+                EditDocumentSets(new Guid[] { set.ID });
+        }
     }
 }