Ver código fonte

Updates to Filter UI

Kenric Nugteren 7 meses atrás
pai
commit
77f85049d1

+ 5 - 5
prs.desktop/DockPanels/DigitalForms/DigitalFormDockGrid.cs

@@ -58,8 +58,9 @@ public class DigitalFormDockGrid : DynamicGrid<DigitalFormDockModel>
         ActionColumns.Add(new DynamicImageColumn(TypeImage)
         {
             Position = DynamicActionColumnPosition.Start,
-            Filters = Images.Keys.Select(x => x.EntityName().Split('.').Last().SplitCamelCase()).ToArray(),
-            FilterRecord = TypeFilter
+            GetFilter = () => new StaticColumnFilter<Type>(
+                FormType,
+                Images.Keys.Select(x => new Tuple<string, Type>(x.EntityName().Split('.').Last().SplitCamelCase(), x)).ToArray())
         });
 
         ActionColumns.Add(new DynamicMenuColumn(MenuBuild, MenuStatus) { Position = DynamicActionColumnPosition.End });
@@ -86,10 +87,9 @@ public class DigitalFormDockGrid : DynamicGrid<DigitalFormDockModel>
         return result;
     }
 
-    private bool TypeFilter(CoreRow row, string[] filter)
+    private Type FormType(CoreRow row)
     {
-        string typename = row.Get<DigitalFormDockModel, Type>(x => x.FormType).EntityName().Split('.').Last().SplitCamelCase();
-        return filter.Contains(typename);
+        return row.Get<DigitalFormDockModel, Type>(x => x.FormType);
     }
 
     private BitmapImage? TypeImage(CoreRow? arg)

+ 13 - 22
prs.desktop/DockPanels/Problems/ProblemsDockGrid.cs

@@ -5,6 +5,7 @@ using System.Linq;
 using System.Windows.Controls;
 using System.Windows.Media.Imaging;
 using com.healthmarketscience.jackcess.query;
+using com.sun.istack.@internal.localization;
 using Comal.Classes;
 using InABox.Clients;
 using InABox.Core;
@@ -25,9 +26,8 @@ public class ProblemsDockGrid : DynamicDataGrid<Problems>
         
         ActionColumns.Add(new DynamicImageColumn(TypeImage)
         {
-            Position = DynamicActionColumnPosition.Start, 
-            Filters = IMAGES.Keys.Select(x=>x.Name.Split('.').Last()).ToArray(),
-            GetFilterExpression = (col) => TypeExpression(col),
+            Position = DynamicActionColumnPosition.Start,
+            GetFilter = () => new StaticColumnFilter<Type?>(GetType, IMAGES.Keys.Select(x => new Tuple<string, Type?>(x.Name, x)).ToArray())
         });
         
 
@@ -40,16 +40,11 @@ public class ProblemsDockGrid : DynamicDataGrid<Problems>
         AddButton("Mark Resolved", InABox.Wpf.Resources.delete.AsBitmapImage(), MarkResolved,
             position: DynamicGridButtonPosition.Right);
     }
-    
-    private string TypeExpression(DynamicActionColumn column)
-    {
-        return column.CreateFilterExpression("Type") ?? "";
-    }
-    
-    private bool TypeFilter(CoreRow row, string[] filter)
+
+    private Type? GetType(CoreRow row)
     {
-        string typename = row.Get<Problems, string>(x => x.Type);
-        return filter.Contains(typename);
+        var typeName = row.Get<Problems, string>(x => x.Type);
+        return IMAGES.Keys.FirstOrDefault(x => x.Name == typeName);
     }
 
     private object? GetAssignedTo(CoreRow? row) => row?.Get<Problems, string>(x => x.Problem.AssignedTo.Code);
@@ -109,16 +104,10 @@ public class ProblemsDockGrid : DynamicDataGrid<Problems>
         menu.AddItem("Mark as Resolved", null, MarkResolved);
     }
     
-    private Type? GetType(CoreRow? row)
-    {
-        var _name = row?.Get<Problems, string>(x => x.Type) ?? "";
-        var _type = IMAGES.Keys.FirstOrDefault(x => string.Equals(x.Name.Split('.').Last(), _name));
-        return _type;
-
-    }
-    
     private IProblems<ManagedProblem>? GetItem(CoreRow? row)
     {
+        if (row is null) return null;
+
         var _type = GetType(row);
         if (_type == null)
             return null;
@@ -269,9 +258,9 @@ public class ProblemsDockGrid : DynamicDataGrid<Problems>
 
     private void AssignTo(CoreRow? row)
     {
-        if (row != null)
+        if (row is null)
             return;
-        AssignTo([ row ]);
+        AssignTo([row]);
     }
 
     protected override void DoDoubleClick(object sender, DynamicGridCellClickEventArgs args)
@@ -284,6 +273,8 @@ public class ProblemsDockGrid : DynamicDataGrid<Problems>
 
     private void EditItem(CoreRow? row)
     {
+        if (row is null) return;
+
         var _type = GetType(row);
         if (_type == null)
             return;

+ 4 - 11
prs.desktop/Panels/DynamicMapColumn.cs

@@ -31,17 +31,10 @@ namespace PRSDesktop
             Image = MapImage;
             Action = MapClick;
 
-            Filters = new[] { "(Blank)", "(Not Blank)" };
-            FilterRecord = MapFilter;
-        }
-
-        private bool MapFilter(CoreRow row, string[] filter)
-        {
-            if (filter.Contains("(Blank)") && !HasLocation(row))
-                return true;
-            if (filter.Contains("(Not Blank)") && HasLocation(row))
-                return true;
-            return false;
+            GetFilter = () => new StaticColumnFilter<bool>(HasLocation, [
+                new("(Blank)", false),
+                new("(Not Blank)", true)
+                ]);
         }
 
         public Expression<Func<T, object>> Property { get; }

+ 6 - 8
prs.desktop/Panels/DynamicScheduleEditorColumn.cs

@@ -21,18 +21,16 @@ namespace PRSDesktop
         {
             Image = ScheduleImage;
             Action = EditSchedule;
-            Filters = new[] { "Active Schedules", "No/Inactive Schedules" };
-            FilterRecord = ScheduleFilter;
+            GetFilter = () => new StaticColumnFilter<bool>(ActiveSchedules, [
+                new("Active Schedules", true),
+                new("No/Inactive Schedules", false)
+                ]);
         }
 
-        private bool ScheduleFilter(CoreRow row, string[] filter)
+        private bool ActiveSchedules(CoreRow row)
         {
             int schedules = row.Get<T, int>(x => x.ActiveSchedules);
-            if (filter.Contains("Active Schedules") && (schedules > 0))
-                return true;
-            if (filter.Contains("No/Inactive Schedules") && (schedules == 0))
-                return true;
-            return false;
+            return schedules > 0;
         }
 
         private BitmapImage ScheduleImage(CoreRow? row)

+ 20 - 29
prs.desktop/Panels/Security/Global/GlobalTokenGrid.cs

@@ -85,8 +85,7 @@ namespace PRSDesktop
                     )
                     {
                         HeaderText = "Default",
-                        Filters = ALL_FILTERS,
-                        FilterRecord = (r,f) => GlobalFilter(r,f)
+                        GetFilter = () => new FuncCheckBoxDynamicGridColumnFilter(GlobalFilter, AllFilterData)
                     });
                 
                 foreach (var groupid in GroupNames.Keys)
@@ -99,8 +98,7 @@ namespace PRSDesktop
                         )
                         {
                             HeaderText = GroupNames[groupid],
-                            Filters = ALL_FILTERS,
-                            FilterRecord = (r,f) => GroupFilter(r,f,groupid)
+                            GetFilter = () => new FuncCheckBoxDynamicGridColumnFilter((row, pred) => GroupFilter(row, pred, groupid), AllFilterData)
                         }
                     );
             }
@@ -115,8 +113,7 @@ namespace PRSDesktop
                     )
                     {
                         HeaderText = GroupNames[GroupID],
-                        Filters = ALL_FILTERS,
-                        FilterRecord = (r,f) => GroupFilter(r,f, GroupID)
+                        GetFilter = () => new FuncCheckBoxDynamicGridColumnFilter((row, pred) => GroupFilter(row, pred, GroupID), AllFilterData)
                     }
                 );
 
@@ -131,8 +128,7 @@ namespace PRSDesktop
                             )
                             {
                                 HeaderText = UserNames[userid],
-                                Filters = ALL_FILTERS,
-                                FilterRecord = (r,f) => UserFilter(r,f, GroupID, userid)
+                                GetFilter = () => new FuncCheckBoxDynamicGridColumnFilter((row, pred) => UserFilter(row, pred, GroupID, userid), AllFilterData)
                             }
                         );
             }
@@ -140,22 +136,17 @@ namespace PRSDesktop
             return columns;
         }
 
-        private static bool MatchFilter(string[] filter, string[] test)
+        private static bool MatchFilter(Predicate<object?> filter, string[] test)
         {
-            if ((filter == null) && (test == null))
-                return true;
-            if ((filter == null) || (test == null))
-                return false;
-            if (filter.Length != test.Length)
-                return false;
-            if (filter.Except(test).Any())
-                return false;
-            if (test.Except(filter).Any())
-                return false;
-            return true;
+            return test.All(x => filter(x));
+        }
+
+        private IEnumerable<Tuple<string, object?>> AllFilterData()
+        {
+            return ALL_FILTERS.Select(x => new Tuple<string, object?>(x, x));
         }
         
-        private bool GlobalFilter(CoreRow row, string[] filter)
+        private bool GlobalFilter(CoreRow row, Predicate<object?> filter)
         {
             if (MatchFilter(filter, ALL_FILTERS))
                 return true;
@@ -166,7 +157,7 @@ namespace PRSDesktop
             if (!MatchFilter(filter, ENABLED_FILTERS))
             {
                 bool isenabled = GetGlobalOrDefault(descriptor, globaldefault);
-                var check = (filter.Contains(ENABLED_TOKENS) && isenabled) || (filter.Contains(DISABLED_TOKENS) && !isenabled);
+                var check = (filter(ENABLED_TOKENS) && isenabled) || (filter(DISABLED_TOKENS) && !isenabled);
                 if (!check)
                     return false;
             }
@@ -174,7 +165,7 @@ namespace PRSDesktop
             if (!MatchFilter(filter, OVERRIDDEN_FILTERS))
             {
                 bool isoverridden = Items.Any(x => String.Equals(x.Descriptor, descriptor) && (x.Type == SecurityTokenType.Global));
-                var check = (filter.Contains(OVERRIDDEN_TOKENS) && isoverridden) || (filter.Contains(DEFAULT_TOKENS) && !isoverridden);
+                var check = (filter(OVERRIDDEN_TOKENS) && isoverridden) || (filter(DEFAULT_TOKENS) && !isoverridden);
                 if (!check)
                     return false;
             }
@@ -182,7 +173,7 @@ namespace PRSDesktop
             return true;
         }
 
-        private bool GroupFilter(CoreRow row, string[] filter, Guid groupid)
+        private bool GroupFilter(CoreRow row, Predicate<object?> filter, Guid groupid)
         {
             if (MatchFilter(filter, ALL_FILTERS))
                 return true;
@@ -193,7 +184,7 @@ namespace PRSDesktop
             if (!MatchFilter(filter, ENABLED_FILTERS))
             {
                 bool isenabled = GetGroupOrDefault(descriptor, groupid, globaldefault);
-                var check = (filter.Contains(ENABLED_TOKENS) && isenabled) || (filter.Contains(DISABLED_TOKENS) && !isenabled);
+                var check = (filter(ENABLED_TOKENS) && isenabled) || (filter(DISABLED_TOKENS) && !isenabled);
                 if (!check)
                     return false;
             }
@@ -201,7 +192,7 @@ namespace PRSDesktop
             if (!MatchFilter(filter, OVERRIDDEN_FILTERS))
             {
                 bool isoverridden = Items.Any(x => String.Equals(x.Descriptor, descriptor) && (x.Type == SecurityTokenType.Group));
-                var check = (filter.Contains(OVERRIDDEN_TOKENS) && isoverridden) || (filter.Contains(DEFAULT_TOKENS) && !isoverridden);
+                var check = (filter(OVERRIDDEN_TOKENS) && isoverridden) || (filter(DEFAULT_TOKENS) && !isoverridden);
                 if (!check)
                     return false;
             }
@@ -209,7 +200,7 @@ namespace PRSDesktop
             return true;
         }
 
-        private bool UserFilter(CoreRow row, string[] filter, Guid groupid, Guid userid)
+        private bool UserFilter(CoreRow row, Predicate<object?> filter, Guid groupid, Guid userid)
         {
             if (MatchFilter(filter, ALL_FILTERS))
                 return true;
@@ -220,7 +211,7 @@ namespace PRSDesktop
             if (!MatchFilter(filter, ENABLED_FILTERS))
             {
                 bool isenabled = GetUserOrDefault(descriptor, userid, groupid, globaldefault);
-                var check = (filter.Contains(ENABLED_TOKENS) && isenabled) || (filter.Contains(DISABLED_TOKENS) && !isenabled);
+                var check = (filter(ENABLED_TOKENS) && isenabled) || (filter(DISABLED_TOKENS) && !isenabled);
                 if (!check)
                     return false;
             }
@@ -228,7 +219,7 @@ namespace PRSDesktop
             if (!MatchFilter(filter, OVERRIDDEN_FILTERS))
             {
                 bool isoverridden = Items.Any(x => string.Equals(x.Descriptor, descriptor) && (x.Type == SecurityTokenType.User));
-                var check = (filter.Contains(OVERRIDDEN_TOKENS) && isoverridden) || (filter.Contains(DEFAULT_TOKENS) && !isoverridden);
+                var check = (filter(OVERRIDDEN_TOKENS) && isoverridden) || (filter(DEFAULT_TOKENS) && !isoverridden);
                 if (!check)
                     return false;
             }

+ 25 - 17
prs.desktop/Panels/Security/Groups/GroupTokenGrid.cs

@@ -52,7 +52,9 @@ namespace PRSDesktop
             }
 
             ActionColumns.Add(new DynamicImageColumn(TokenImage, TokenAction)
-                { Filters = new[] { "Enabled", "Disabled", "Overridden" }, FilterRecord = TokenFilter });
+            {
+                GetFilter = () => new FuncCheckBoxDynamicGridColumnFilter(TokenFilter, TokenFilterData)
+            });
             //ActionColumns.Add(new DynamicTickColumn<TokenItem,bool>(x => x.Checked, tick, tick, disabled) { Action = CheckClick, AllowHeaderClick = true });
             HiddenColumns.Add(x => x.Code);
             HiddenColumns.Add(x => x.Value);
@@ -122,29 +124,35 @@ namespace PRSDesktop
             action.Invoke(table, null);
         }
 
-        private bool TokenFilter(CoreRow row, string[] filter)
+        private IEnumerable<Tuple<string, object?>> TokenFilterData()
         {
-            
-            var defvalue = row.Get<GroupTokenItem, bool>(x => x.Default);
-            var hasvalue = row.Get<GroupTokenItem, bool>(x => x.HasValue);
-            var actvalue = row.Get<GroupTokenItem, bool>(x => x.Value);
-
-            bool bOK = false;
+            yield return new("Enabled", "Enabled");
+            yield return new("Disabled", "Disabled");
+            yield return new("Overriden", "Overriden");
+        }
 
-            if (filter.Contains("Enabled") && (hasvalue ? actvalue : defvalue))
-                return true;
+        private bool TokenFilter(CoreRow row, Predicate<object?> filter)
+        {
+            var hasvalue = row.Get<GroupTokenItem, bool>(x => x.HasValue);
 
-            if (filter.Contains("Disabled") && (hasvalue ? !actvalue : !defvalue))
-                return true;
+            if (hasvalue && filter("Overriden")) return true;
 
-            if (filter.Contains("Overridden") && hasvalue)
-                return true;
+            var value = row.Get<GroupTokenItem, bool>(x => x.Value);
+            var defvalue = row.Get<GroupTokenItem, bool>(x => x.Default);
 
-            return false;
+            var actualValue = hasvalue ? value : defvalue;
 
+            if (actualValue)
+            {
+                return filter("Enabled");
+            }
+            else
+            {
+                return filter("Disabled");
+            }
         }
 
-        private bool TokenAction(CoreRow row)
+        private bool TokenAction(CoreRow? row)
         {
             var result = false;
             var rows = row == null ? Data.Rows.ToArray() : new[] { row };
@@ -189,7 +197,7 @@ namespace PRSDesktop
             return result;
         }
 
-        private BitmapImage TokenImage(CoreRow row)
+        private BitmapImage TokenImage(CoreRow? row)
         {
             if (row == null)
                 return tick;

+ 25 - 14
prs.desktop/Panels/Security/User/UserTokenGrid.cs

@@ -28,7 +28,9 @@ namespace PRSDesktop
             LoadGlobalTokens();
 
             ActionColumns.Add(new DynamicImageColumn(TokenImage, TokenAction)
-                { Filters = new[] { "Enabled", "Disabled", "Overridden" }, FilterRecord = TokenFilter });
+            {
+                GetFilter = () => new FuncCheckBoxDynamicGridColumnFilter(TokenFilter, TokenFilterData)
+            });
             HiddenColumns.Add(x => x.Code);
             HiddenColumns.Add(x => x.Value);
             HiddenColumns.Add(x => x.Default);
@@ -157,26 +159,35 @@ namespace PRSDesktop
             action.Invoke(table, null);
         }
 
-        private bool TokenFilter(CoreRow row, string[] filter)
+        private IEnumerable<Tuple<string, object?>> TokenFilterData()
         {
+            yield return new("Enabled", "Enabled");
+            yield return new("Disabled", "Disabled");
+            yield return new("Overriden", "Overriden");
+        }
 
-            var defvalue = row.Get<GroupTokenItem, bool>(x => x.Default);
+        private bool TokenFilter(CoreRow row, Predicate<object?> filter)
+        {
             var hasvalue = row.Get<GroupTokenItem, bool>(x => x.HasValue);
-            var actvalue = row.Get<GroupTokenItem, bool>(x => x.Value);
 
-            if (filter.Contains("Enabled") && (hasvalue ? actvalue : defvalue))
-                return true;
+            if (hasvalue && filter("Overriden")) return true;
+
+            var value = row.Get<GroupTokenItem, bool>(x => x.Value);
+            var defvalue = row.Get<GroupTokenItem, bool>(x => x.Default);
 
-            if (filter.Contains("Disabled") && (hasvalue ? !actvalue : !defvalue))
-                return true;
-            
-            if (filter.Contains("Overridden") && hasvalue)
-                return true;
+            var actualValue = hasvalue ? value : defvalue;
 
-            return false;
+            if (actualValue)
+            {
+                return filter("Enabled");
+            }
+            else
+            {
+                return filter("Disabled");
+            }
         }
 
-        private bool TokenAction(CoreRow row)
+        private bool TokenAction(CoreRow? row)
         {
             var result = false;
             var rows = row == null ? Data.Rows.ToArray() : new[] { row };
@@ -222,7 +233,7 @@ namespace PRSDesktop
             return result;
         }
 
-        private BitmapImage TokenImage(CoreRow row)
+        private BitmapImage TokenImage(CoreRow? row)
         {
             if (row == null)
                 return tick;

+ 7 - 27
prs.desktop/Panels/Stock Forecast/StockForecastGrid.cs

@@ -344,20 +344,9 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
             Position = DynamicActionColumnPosition.End, 
             Tag = tag,
             HeaderText = header,
-            FilterRecord = (row, filters) =>
-            {
-                if (filters.Length == 1 && filters[0].Length == 0) return true;
-
-                var value = GetColumnCalculatedData(tag, row);
-                if(!value.HasValue)
-                {
-                    return false;
-                }
-                else
-                {
-                    return filters.Contains(value.Value.ToString("F2"));
-                }
-            }
+            GetFilter = () => new DynamicColumnFilter<double?>(
+                r => GetColumnCalculatedData(tag, r),
+                () => GetColumnFilterItems(tag))
         };
         ActionColumns.Add(column);
     }
@@ -653,29 +642,20 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
         };
     }
 
-    private string[] GetColumnFilterItems(ColumnTag tag)
+    private IEnumerable<Tuple<string, double?>> GetColumnFilterItems(ColumnTag tag)
     {
-        var items = new HashSet<string>();
+        var items = new HashSet<double>();
         foreach(var row in Data.Rows)
         {
             var value = GetColumnCalculatedData(tag, row);
             if (value.HasValue)
             {
-                items.Add(value.Value.ToString("F2"));
+                items.Add(value.Value);
             }
         }
         var arr = items.ToArray();
         Array.Sort(arr);
-        return arr;
-    }
-
-    protected override IEnumerable<string>? GetColumnFilterItems(DynamicColumnBase column)
-    {
-        if (column.Tag is ColumnTag tag)
-        {
-            return GetColumnFilterItems(tag);
-        }
-        return base.GetColumnFilterItems(column);
+        return arr.Select(x => new Tuple<string, double?>(x.ToString("F2"), x));
     }
 
     private class ItemKey(Guid productID, Guid styleID, StockDimensions dimensions)

+ 33 - 0
prs.shared/Forms/NotesForm.xaml

@@ -0,0 +1,33 @@
+<wpf:ThemableWindow x:Class="PRS.Shared.NotesForm"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:wpf="clr-namespace:InABox.Wpf;assembly=InABox.Wpf"
+        mc:Ignorable="d"
+        Title="Edit Notes" Height="450" Width="800" WindowStartupLocation="CenterOwner" Closing="Window_Closing">
+    <Grid Margin="5">
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="Auto" />
+            <ColumnDefinition Width="*" />
+            <ColumnDefinition Width="80" />
+            <ColumnDefinition Width="80" />
+        </Grid.ColumnDefinitions>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto" />
+            <RowDefinition Height="*" />
+            <RowDefinition Height="40" />
+        </Grid.RowDefinitions>
+        <Label x:Name="Heading" Content=" " Grid.ColumnSpan="4" Margin="5" HorizontalContentAlignment="Center"
+               FontSize="16" />
+        <TextBox x:Name="Editor" Grid.Row="1" Grid.ColumnSpan="4" TextWrapping="Wrap" Margin="5,0,5,5"
+                 AcceptsReturn="True" VerticalScrollBarVisibility="Visible" FontSize="14" />
+        <Label x:Name="Task" Content="Create Task for" Grid.Row="2" Margin="5" HorizontalContentAlignment="Center"
+               VerticalAlignment="Center" Visibility="Hidden" />
+        <ComboBox x:Name="TaskEmployee" Grid.Row="2" Grid.Column="1" VerticalAlignment="Center"
+                  HorizontalAlignment="Left" Width="200" Visibility="Hidden" SelectedValuePath="Key"
+                  DisplayMemberPath="Value" />
+        <Button x:Name="OK" Content="OK" Grid.Row="2" Grid.Column="2" Click="OK_Click" Margin="0,0,5,5" />
+        <Button x:Name="Cancel" Content="Cancel" Grid.Row="2" Grid.Column="3" Click="Cancel_Click" Margin="0,0,5,5" />
+    </Grid>
+</wpf:ThemableWindow>

+ 77 - 0
prs.shared/Forms/NotesForm.xaml.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Windows;
+using InABox.Wpf;
+
+namespace PRS.Shared
+{
+    /// <summary>
+    ///     Interaction logic for NotesForm.xaml
+    /// </summary>
+    public partial class NotesForm : ThemableWindow
+    {
+        public NotesForm(Dictionary<Guid, string> employees = null)
+        {
+            InitializeComponent();
+
+            EmployeeID = Guid.Empty;
+            if (employees != null)
+            {
+                Task.Visibility = Visibility.Visible;
+                TaskEmployee.Visibility = Visibility.Visible;
+                TaskEmployee.ItemsSource = employees;
+            }
+        }
+
+        public string Caption
+        {
+            get => (string)Heading.Content;
+            set => Heading.Content = value;
+        }
+
+        public string Text
+        {
+            get => Editor.Text;
+            set => Editor.Text = value;
+        }
+
+        public bool OKEnabled
+        {
+            get => OK.IsEnabled;
+            set => OK.IsEnabled = value;
+        }
+
+        public bool CancelEnabled
+        {
+            get => Cancel.IsEnabled;
+            set => Cancel.IsEnabled = value;
+        }
+
+        public Guid EmployeeID { get; private set; }
+
+        private void OK_Click(object sender, RoutedEventArgs e)
+        {
+            if (Task.Visibility == Visibility.Visible && TaskEmployee.SelectedItem != null)
+            {
+                var emp = (KeyValuePair<Guid, string>)TaskEmployee.SelectedItem;
+                EmployeeID = emp.Key;
+            }
+
+            DialogResult = true;
+            Close();
+        }
+
+        private void Cancel_Click(object sender, RoutedEventArgs e)
+        {
+            DialogResult = false;
+            Close();
+        }
+
+        private void Window_Closing(object sender, CancelEventArgs e)
+        {
+            if (CancelEnabled == false && DialogResult != true)
+                e.Cancel = true;
+        }
+    }
+}

+ 4 - 0
prs.shared/PRS.Shared.csproj

@@ -39,6 +39,10 @@
   </ItemGroup>
 
   <ItemGroup>
+    <Page Update="Forms\NotesForm.xaml">
+      <XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
+      <SubType>Designer</SubType>
+    </Page>
     <Page Update="Forms\ScheduleForm.xaml">
       <XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
       <SubType>Designer</SubType>