Browse Source

Added Configurabel Job Document Filters
Added Document Count to Grid View
Job Document Folder Row Height is now fixed at 30 pixles

Frank van den Bos 2 years ago
parent
commit
87832da2dc

+ 26 - 8
prs.classes/Entities/Job/DocumentSet/JobDocumentSet.cs

@@ -1,9 +1,11 @@
 using System;
+using System.Linq;
+using InABox.Clients;
 using InABox.Core;
 
 namespace Comal.Classes
 {
-
+    
     public enum PaperSize
     {
         A0,
@@ -39,23 +41,35 @@ namespace Comal.Classes
         [EditorSequence(2)]
         public string Description { get; set; }
         
-        [DateTimeEditor]
         [EditorSequence(3)]
-        public DateTime Date { get; set; }
+        public JobDocumentSetDisciplineLink Discipline { get; set; }
         
-        [EnumLookupEditor(typeof(PaperSize))]
         [EditorSequence(4)]
-        public PaperSize Size { get; set; }
+        public JobDocumentSetTypeLink Type { get; set; }
         
-        [CodeEditor(Editable=Editable.Enabled)]
+        [DateTimeEditor]
         [EditorSequence(5)]
-        public String Scale { get; set; }
+        public DateTime Date { get; set; }
         
         [Caption("Assigned To")]
         [EditorSequence(6)]
         public EmployeeLink Employee { get; set; }
         
-        [EditorSequence(7)]
+        [EnumLookupEditor(typeof(PaperSize))]
+        [EditorSequence("Advanced",1)]
+        public PaperSize Size { get; set; }
+        
+        [CodeEditor(Editable=Editable.Enabled)]
+        [EditorSequence("Advanced",2)]
+        public String Scale { get; set; }
+        
+        [EditorSequence("Advanced",3)]
+        public JobDocumentSetCategoryLink Category { get; set; }
+        
+        [EditorSequence("Advanced",4)]
+        public JobDocumentSetAreaLink Area { get; set; }
+        
+        [EditorSequence("Advanced", 5)]
         public DateTime Retired { get; set; }
         
         protected override void Init()
@@ -67,6 +81,10 @@ namespace Comal.Classes
             Employee = new EmployeeLink();
             Size = PaperSize.NotSet;
             Scale = "";
+            Discipline = new JobDocumentSetDisciplineLink();
+            Category = new JobDocumentSetCategoryLink();
+            Type = new JobDocumentSetTypeLink();
+            Area = new JobDocumentSetAreaLink();
         }
     }
 }

+ 119 - 0
prs.classes/Entities/Job/DocumentSet/JobDocumentSetTag.cs

@@ -0,0 +1,119 @@
+using System;
+using InABox.Clients;
+using InABox.Core;
+
+namespace Comal.Classes
+{
+    
+    public enum JobDocumentSetTagType
+    {
+        Discipline,
+        Type,
+        Category,
+        Area
+    }
+    
+    public class JobDocumentSetTag : Entity, IRemotable, IPersistent
+    {
+        [EnumLookupEditor(typeof(JobDocumentSetTagType), Visible = Visible.Default, Width = 100)]
+        [EditorSequence(1)]
+        public JobDocumentSetTagType Type { get; set; }
+        
+        [TextBoxEditor]
+        [EditorSequence(2)]
+        public string Description { get; set; }
+    }
+    
+    public abstract class JobDocumentSetTagLink : EntityLink<JobDocumentSetTag>
+    {
+        public String Description { get; set; }
+    }
+    
+    public abstract class JobDocumentSetTagLookup : LookupGenerator<JobDocumentSet>
+    {
+        
+        public JobDocumentSetTagLookup(JobDocumentSet[]? items) : base(items)
+        {
+            AddColumn("Description", typeof(string));
+        }
+
+        protected abstract JobDocumentSetTagType Type {get; }
+        
+        protected override void DoGenerateLookups()
+        {
+            Clear();
+            var tags = new Client<JobDocumentSetTag>().Query(
+                new Filter<JobDocumentSetTag>(x=>x.Type).IsEqualTo(Type),
+                new Columns<JobDocumentSetTag>(x => x.ID, x => x.Description),
+                new SortOrder<JobDocumentSetTag>(x => x.Description)
+            );
+
+            foreach (var row in tags.Rows)
+                AddValue(
+                    row.Get<JobDocumentSetTag, Guid>(col => col.ID),
+                    row.Get<JobDocumentSetTag, string>(col => col.Description),
+                    row.Get<JobDocumentSetTag, string>(col => col.Description)
+                );
+        }
+    }
+
+    public class JobDocumentSetDisciplineLookup : JobDocumentSetTagLookup
+    {
+        public JobDocumentSetDisciplineLookup(JobDocumentSet[]? items) : base(items)
+        {
+        }
+
+        protected override JobDocumentSetTagType Type => JobDocumentSetTagType.Discipline;
+    }
+    
+    public class JobDocumentSetDisciplineLink : JobDocumentSetTagLink
+    {
+        [ComboLookupEditor(typeof(JobDocumentSetDisciplineLookup))]
+        public override Guid ID { get; set; }
+    }
+    
+    public class JobDocumentSetTypeLookup : JobDocumentSetTagLookup
+    {
+        public JobDocumentSetTypeLookup(JobDocumentSet[]? items) : base(items)
+        {
+        }
+
+        protected override JobDocumentSetTagType Type => JobDocumentSetTagType.Type;
+    }  
+    
+    public class JobDocumentSetTypeLink : JobDocumentSetTagLink
+    {
+        [ComboLookupEditor(typeof(JobDocumentSetTypeLookup))]
+        public override Guid ID { get; set; }
+    }
+    
+    public class JobDocumentSetCategoryLookup : JobDocumentSetTagLookup
+    {
+        public JobDocumentSetCategoryLookup(JobDocumentSet[]? items) : base(items)
+        {
+        }
+
+        protected override JobDocumentSetTagType Type => JobDocumentSetTagType.Category;
+    }
+        
+    public class JobDocumentSetCategoryLink : JobDocumentSetTagLink
+    {
+        [ComboLookupEditor(typeof(JobDocumentSetCategoryLookup))]
+        public override Guid ID { get; set; }
+    }
+
+    public class JobDocumentSetAreaLookup : JobDocumentSetTagLookup
+    {
+        public JobDocumentSetAreaLookup(JobDocumentSet[]? items) : base(items)
+        {
+        }
+
+        protected override JobDocumentSetTagType Type => JobDocumentSetTagType.Area;
+    }
+        
+    public class JobDocumentSetAreaLink : JobDocumentSetTagLink
+    {
+        [ComboLookupEditor(typeof(JobDocumentSetAreaLookup))]
+        public override Guid ID { get; set; }
+    }
+}

+ 8 - 0
prs.desktop/MainWindow.xaml.cs

@@ -584,6 +584,8 @@ namespace PRSDesktop
                         AddSetupAction(ProjectsTab, "Job Statuses", JobStatusButton_Click, PRSDesktop.Resources.view,
                             Security.CanView<JobStatus>());
                         AddSetupAction(ProjectsTab, "Document MileStones", JobDocumentMileStoneButton_OnClick, PRSDesktop.Resources.revision,
+                            true);                        
+                        AddSetupAction(ProjectsTab, "Document Tags", JobDocumentTagButton_OnClick, PRSDesktop.Resources.checklist,
                             true);
                         AddSetupAction(ProjectsTab, "Financial Statuses", FinancialStatusButton_Click, PRSDesktop.Resources.view,
                             Security.CanView<JobFinancial>());
@@ -2466,6 +2468,12 @@ namespace PRSDesktop
             var list = new MasterList(typeof(JobDocumentSetMileStoneType));
             list.ShowDialog();
         }
+        
+        private void JobDocumentTagButton_OnClick()
+        {
+            var list = new MasterList(typeof(JobDocumentSetTag));
+            list.ShowDialog();
+        }
 
         private void Setup_Click(object sender, RoutedEventArgs e)
         {

+ 1 - 1
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetFolderTree.cs

@@ -17,7 +17,7 @@ namespace PRSDesktop
         public JobDocumentSetFolderTree() : base()
         {
             Options.AddRange(DynamicTreeOption.Add, DynamicTreeOption.Edit, DynamicTreeOption.Delete);
-            MaxRowHeight = 60D;
+            MaxRowHeight = 30D;
         }
         
         protected override Expression<Func<JobDocumentSetFolder, Guid>> ID => x => x.ID;

+ 26 - 2
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetPanel.xaml

@@ -11,11 +11,35 @@
     <dynamicGrid:DynamicSplitPanel MasterWidth="250" MasterCaption="Folders" DetailCaption="Documents" View="Combined" OnChanged="DynamicSplitPanel_OnOnChanged">
         <dynamicGrid:DynamicSplitPanel.Header>
             <Border DockPanel.Dock="Top" BorderBrush="Gray" BorderThickness="0.75,0.75,0.75,0" Background="Gainsboro" Height="30">
-                <Label Content="Folders" HorizontalContentAlignment="Center" FontWeight="Bold" FontSize="12"/>
+                <Label Content="Search" HorizontalContentAlignment="Center" FontWeight="Bold" FontSize="12"/>
             </Border>
         </dynamicGrid:DynamicSplitPanel.Header>
         <dynamicGrid:DynamicSplitPanel.Master>
-            <local:JobDocumentSetFolderTree x:Name="Folders" OnSelectItem="Folders_OnOnSelectItem"/>
+            <DockPanel>
+                <Grid DockPanel.Dock="Top">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="Auto"/>
+                        <ColumnDefinition Width="*"/>
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="0" x:Name="DisciplineRow"/>
+                        <RowDefinition Height="0" x:Name="TypeRow"/>
+                        <RowDefinition Height="0" x:Name="CategoryRow"/>
+                        <RowDefinition Height="0" x:Name="AreaRow"/>
+                    </Grid.RowDefinitions>
+                    <Label Grid.Row="0" Grid.Column="0" Content="Discipline" VerticalContentAlignment="Center"/>
+                    <ComboBox Grid.Row="0" Grid.Column="1" x:Name="Discipline" Margin="5,1,0,2" SelectedValuePath="Key" DisplayMemberPath="Value" />
+                    <Label Grid.Row="1" Grid.Column="0" Content="Type" VerticalContentAlignment="Center"/>
+                    <ComboBox Grid.Row="1" Grid.Column="1" x:Name="Type" Margin="5,1,0,2" SelectedValuePath="Key" DisplayMemberPath="Value" />
+                    <Label Grid.Row="2" Grid.Column="0" Content="Category" VerticalContentAlignment="Center"/>
+                    <ComboBox Grid.Row="2" Grid.Column="1" x:Name="Category" Margin="5,1,0,2" SelectedValuePath="Key" DisplayMemberPath="Value" />
+                    <Label Grid.Row="3" Grid.Column="0" Content="Area" VerticalContentAlignment="Center"/>
+                    <ComboBox Grid.Row="3" Grid.Column="1" x:Name="Area" Margin="5,1,0,2" SelectedValuePath="Key" DisplayMemberPath="Value" />
+                </Grid>
+                <local:JobDocumentSetFolderTree x:Name="Folders" OnSelectItem="Folders_OnOnSelectItem" DockPanel.Dock="Top"/>
+            </DockPanel>
+                    
+            
         </dynamicGrid:DynamicSplitPanel.Master>
 
         <dynamicGrid:DynamicSplitPanel.Detail>

+ 37 - 1
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetPanel.xaml.cs

@@ -10,6 +10,7 @@ using InABox.Clients;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.WPF;
+using Inflector;
 using Color = System.Drawing.Color;
 
 
@@ -39,9 +40,35 @@ namespace PRSDesktop
         }
 
         public event DataModelUpdateEvent OnUpdateDataModel;
+
+        private bool GetTags(CoreTable tags, JobDocumentSetTagType type, ComboBox target, RowDefinition row)
+        {
+            ;
+            Dictionary<Guid, String> result = new Dictionary<Guid, String>()
+            {
+                { Guid.Empty, "" } //$"All {type.ToString().Pluralize()}" }
+            };
+            foreach (var tag in tags.Rows.Where(x => x.Get<JobDocumentSetTag, JobDocumentSetTagType>(x => x.Type).Equals(type)))
+                result[tag.Get<JobDocumentSetTag, Guid>(c => c.ID)] = tag.Get<JobDocumentSetTag, String>(c => c.Description);
+            
+            row.Height = result.Count > 1
+                ? new GridLength(1, GridUnitType.Auto)
+                : new GridLength(0, GridUnitType.Pixel);
+            
+            target.ItemsSource = result;
+            target.SelectedIndex = 0;
+            target.SelectionChanged += Tag_OnSelectionChanged;
+            
+            return result.Count > 1;
+        }
         
         public void Setup()
         {
+            var tags = new Client<JobDocumentSetTag>().Query(null, null, new SortOrder<JobDocumentSetTag>(x => x.Description));
+            Documents.DisciplineVisible = GetTags(tags, JobDocumentSetTagType.Discipline, Discipline, DisciplineRow);
+            Documents.TypeVisible = GetTags(tags, JobDocumentSetTagType.Type, Type, TypeRow);
+            Documents.CategoryVisible = GetTags(tags, JobDocumentSetTagType.Category, Category, CategoryRow);
+            Documents.AreaVisible = GetTags(tags, JobDocumentSetTagType.Area, Area, AreaRow);
         }
 
         public void Shutdown()
@@ -51,8 +78,8 @@ namespace PRSDesktop
         public void Refresh()
         {
             Folders.JobID = this.JobID;
-            Documents.JobID = this.JobID;
             Folders.Refresh();
+            Documents.JobID = this.JobID;
             Documents.Refresh();
         }
 
@@ -130,5 +157,14 @@ namespace PRSDesktop
                 preview.ItemsSource =  new List<Tuple<Guid, String, BitmapImage>>();
             
         }
+
+        private void Tag_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            Documents.DisciplineID = (Guid)Discipline.SelectedValue;
+            Documents.TypeID = (Guid)Type.SelectedValue;
+            Documents.CategoryID = (Guid)Category.SelectedValue;
+            Documents.AreaID = (Guid)Area.SelectedValue;
+            Documents.Refresh();
+        }
     }
 }

+ 2 - 2
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetTree.xaml

@@ -7,7 +7,7 @@
              xmlns:Syncfusion="http://schemas.syncfusion.com/wpf"
              xmlns:sfgrid="clr-namespace:Syncfusion.UI.Xaml.Grid;assembly=Syncfusion.SfGrid.WPF"
              mc:Ignorable="d"
-             d:DesignHeight="300" d:DesignWidth="300">
+             d:DesignHeight="300" d:DesignWidth="800">
     <UserControl.Resources>
 
         <local:JobDocumentSetDescriptionConverter x:Key="descriptionConverter" />
@@ -206,7 +206,7 @@
                     Padding="2" Click="Delete_OnClick" BorderBrush="Gray" BorderThickness="0.75">
                 <Image x:Name="DeleteImage"  Source="../../Resources/delete.png" />
             </Button>
-            <Label DockPanel.Dock="Left"/>
+            <Label x:Name="DocumentCount" DockPanel.Dock="Left" Content="0 Document Sets" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
         </DockPanel>
     </Grid>
 </UserControl>

+ 53 - 4
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetTree.xaml.cs

@@ -183,6 +183,18 @@ namespace PRSDesktop
         public Guid JobID { get; set; }
         public Guid FolderID { get; set; }
 
+        public bool DisciplineVisible { get; set; }
+        public Guid DisciplineID { get; set; }
+        
+        public bool TypeVisible { get; set; }
+        public Guid TypeID { get; set; }
+        
+        public bool CategoryVisible { get; set; }
+        public Guid CategoryID { get; set; }
+        
+        public bool AreaVisible { get; set; }
+        public Guid AreaID { get; set; }
+
         private Dictionary<Guid,MileStoneType> _types = null;
         private CoreTable _milestones = null;
         public CoreTable Data { get; private set; } = null;
@@ -215,11 +227,22 @@ namespace PRSDesktop
                 treeGrid.ItemsSource = null;
 
                 var setfilter = new Filter<JobDocumentSet>(x => x.Job.ID).IsEqualTo(JobID);
-                if(FolderID != CoreUtils.FullGuid)
-                {
-                    setfilter = setfilter.And(x => x.Folder.ID).IsEqualTo(FolderID);
-                }
+                
+                if (FolderID != CoreUtils.FullGuid)
+                    setfilter = setfilter.And(x => x.Folder.ID).IsEqualTo(FolderID);  
+                
+                if (DisciplineID != Guid.Empty)
+                    setfilter = setfilter.And(x => x.Discipline.ID).IsEqualTo(DisciplineID);
 
+                if (TypeID != Guid.Empty)
+                    setfilter = setfilter.And(x => x.Type.ID).IsEqualTo(TypeID);
+
+                if (CategoryID != Guid.Empty)
+                    setfilter = setfilter.And(x => x.Category.ID).IsEqualTo(CategoryID);
+
+                if (AreaID != Guid.Empty)
+                    setfilter = setfilter.And(x => x.Area.ID).IsEqualTo(AreaID);
+                
                 if (!_includeretired)
                     setfilter = setfilter.And(x => x.Retired).IsEqualTo(DateTime.MinValue);
 
@@ -398,6 +421,7 @@ namespace PRSDesktop
                 ConfigureStackedHeader();
 
                 treeGrid.ItemsSource = documentsets.Nodes;
+                DocumentCount.Content = $"{documentsets.Nodes.Count} {(documentsets.Nodes.Count > 1 ? "Records" : "Record")}";
             }
 
         }
@@ -1150,6 +1174,10 @@ namespace PRSDesktop
                     set.Folder.ID = FolderID;
                     set.Code = Path.GetFileNameWithoutExtension(filename).ToUpper();
                     set.Description = Path.GetFileNameWithoutExtension(filename).ToUpper();
+                    set.Discipline.ID = DisciplineID;
+                    set.Type.ID = TypeID;
+                    set.Category.ID = CategoryID;
+                    set.Area.ID = AreaID;
 
                     JobDocumentSetMileStone milestone = new JobDocumentSetMileStone();
                     milestone.Type.ID = type;
@@ -1201,6 +1229,11 @@ namespace PRSDesktop
             JobDocumentSet set = new JobDocumentSet();
             set.Job.ID = JobID;
             set.Folder.ID = FolderID;
+            set.Discipline.ID = DisciplineID;
+            set.Type.ID = TypeID;
+            set.Category.ID = CategoryID;
+            set.Area.ID = AreaID;
+            
             var grid = new DynamicDataGrid<JobDocumentSet>();
             grid.OnAfterSave += (form, items) =>
             {
@@ -1255,6 +1288,11 @@ namespace PRSDesktop
             JobDocumentSet set = new JobDocumentSet();
             set.Job.ID = JobID;
             set.Folder.ID = FolderID;
+            set.Discipline.ID = DisciplineID;
+            set.Type.ID = TypeID;
+            set.Category.ID = CategoryID;
+            set.Area.ID = AreaID;
+            
             var grid = new DynamicDataGrid<JobDocumentSet>();
             if (grid.EditItems(new[] { set }))
                 Refresh();
@@ -1274,6 +1312,17 @@ namespace PRSDesktop
                 new Filter<JobDocumentSet>(x => x.ID).InList(setIDs)
             ).Rows.Select(x => x.ToObject<JobDocumentSet>()).ToArray();
             var grid = new DynamicDataGrid<JobDocumentSet>();
+            grid.OnCustomiseEditor += (form, items, column, editor) =>
+            {
+                if (String.Equals(column.ColumnName, "Discipline.ID"))
+                    editor.Editable = DisciplineVisible ? Editable.Enabled : Editable.Hidden;
+                if (String.Equals(column.ColumnName, "Type.ID"))
+                    editor.Editable = TypeVisible ? Editable.Enabled : Editable.Hidden;
+                if (String.Equals(column.ColumnName, "Category.ID"))
+                    editor.Editable = CategoryVisible ? Editable.Enabled : Editable.Hidden;
+                if (String.Equals(column.ColumnName, "Area.ID"))
+                    editor.Editable = AreaVisible ? Editable.Enabled : Editable.Hidden;
+            };
             if (grid.EditItems(sets))
                 Refresh();
         }

+ 1 - 1
prs.desktop/Panels/Jobs/JobDocuments.xaml

@@ -28,7 +28,7 @@
                     <Button Content="New SubFolder" Margin="0,0,2,0" />
                     <Button Content="View Local Files" Margin="0,0,2,0" />
                 </StackPanel>
-
+                
                 <syncfusion:SfTreeGrid
                     DockPanel.Dock="Top"
                     x:Name="Folders"