Explorar o código

Added Calendar borders; fixed leave request and standard leave problems; made them viewable on right-click; hid meetings for the time being.

Kenric Nugteren hai 1 semana
pai
achega
8d522797b1

+ 76 - 30
prs.desktop/Components/Calendar/Calendar.xaml

@@ -123,38 +123,84 @@
                         </wpf:CalendarControl.HeaderTemplate>
                         <wpf:CalendarControl.ItemTemplate>
                             <DataTemplate DataType="local:ICalendarAppointment">
-                                <Border BorderBrush="Black" BorderThickness="1"
-                                        Margin="2" Padding="2" CornerRadius="2"
-                                        Background="{Binding Background}">
-                                    <Grid>
-                                        <Grid.ColumnDefinitions>
-                                            <ColumnDefinition Width="*" />
-                                        </Grid.ColumnDefinitions>
-                                        <Grid.RowDefinitions>
-                                            <RowDefinition Height="20" />
-                                            <RowDefinition Height="*" />
-                                        </Grid.RowDefinitions>
+                                <Grid>
+                                    <Grid.RowDefinitions>
+                                        <RowDefinition Height="Auto"/>
+                                        <RowDefinition Height="*"/>
+                                        <RowDefinition Height="Auto"/>
+                                    </Grid.RowDefinitions>
+                                    <Border BorderBrush="{Binding BorderBrush}"
+                                            Margin="2" CornerRadius="2"
+                                            Grid.RowSpan="3"
+                                            Background="{Binding Background}">
+                                        <Border.Style>
+                                            <Style TargetType="Border">
+                                                <Setter Property="BorderThickness" Value="1"/>
+                                                <Setter Property="Padding" Value="2"/>
+                                                <Style.Triggers>
+                                                    <Trigger Property="IsMouseOver" Value="True">
+                                                        <Setter Property="BorderThickness" Value="2"/>
+                                                        <Setter Property="Padding" Value="1"/>
+                                                    </Trigger>
+                                                </Style.Triggers>
+                                            </Style>
+                                        </Border.Style>
+                                        <Grid>
+                                            <Grid.ColumnDefinitions>
+                                                <ColumnDefinition Width="*" />
+                                            </Grid.ColumnDefinitions>
+                                            <Grid.RowDefinitions>
+                                                <RowDefinition Height="20" />
+                                                <RowDefinition Height="*" />
+                                            </Grid.RowDefinitions>
 
-                                        <DockPanel Grid.Row="0" Grid.Column="0">
-                                            <Image Source="{Binding Image}"
-                                                   DockPanel.Dock="Right"
-                                                   VerticalAlignment="Center"/>
-                                            
-                                            <TextBlock Text="{Binding Subject}"
-                                                       Foreground="{Binding Foreground}" 
-                                                       DockPanel.Dock="Left"
-                                                       VerticalAlignment="Center" 
-                                                       FontWeight="DemiBold"/>
-                                        </DockPanel>
+                                            <DockPanel Grid.Row="0" Grid.Column="0">
+                                                <Image Source="{Binding Image}"
+                                                       DockPanel.Dock="Right"
+                                                       VerticalAlignment="Center"/>
+                                                
+                                                <TextBlock Text="{Binding Subject}"
+                                                           Foreground="{Binding Foreground}" 
+                                                           DockPanel.Dock="Left"
+                                                           VerticalAlignment="Center" 
+                                                           FontWeight="DemiBold"/>
+                                            </DockPanel>
 
-                                        <TextBlock Grid.Row="1"
-                                                   Grid.Column="0"
-                                                   HorizontalAlignment="Left"
-                                                   Text="{Binding Notes}"
-                                                   TextWrapping="Wrap"
-                                                   Foreground="{Binding Foreground}"/>
-                                    </Grid>
-                                </Border>
+                                            <TextBlock Grid.Row="1"
+                                                       Grid.Column="0"
+                                                       HorizontalAlignment="Left"
+                                                       Text="{Binding Notes}"
+                                                       TextWrapping="Wrap"
+                                                       Foreground="{Binding Foreground}"/>
+                                        </Grid>
+                                        <Border.ToolTip>
+                                            <ToolTip>
+                                                <Grid>
+                                                    <Grid.ColumnDefinitions>
+                                                        <ColumnDefinition Width="Auto" MaxWidth="200"/>
+                                                    </Grid.ColumnDefinitions>
+                                                    <Grid.RowDefinitions>
+                                                        <RowDefinition Height="20" />
+                                                        <RowDefinition Height="Auto" />
+                                                    </Grid.RowDefinitions>
+
+                                                    <TextBlock Grid.Row="0" Grid.Column="0"
+                                                               Text="{Binding Subject}"
+                                                               Foreground="{Binding Foreground}" 
+                                                               DockPanel.Dock="Left"
+                                                               VerticalAlignment="Center" 
+                                                               FontWeight="DemiBold"/>
+                                                    <TextBlock Grid.Row="1"
+                                                               Grid.Column="0"
+                                                               HorizontalAlignment="Left"
+                                                               Text="{Binding Notes}"
+                                                               TextWrapping="Wrap"
+                                                               Foreground="{Binding Foreground}"/>
+                                                </Grid>
+                                            </ToolTip>
+                                        </Border.ToolTip>
+                                    </Border>
+                                </Grid>
                             </DataTemplate>
                         </wpf:CalendarControl.ItemTemplate>
                     </wpf:CalendarControl>

+ 132 - 59
prs.desktop/Components/Calendar/Calendar.xaml.cs

@@ -17,6 +17,7 @@ using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.Wpf;
 using InABox.WPF;
+using PRSDesktop.Grids;
 using Selection = InABox.Core.Selection;
 using SelectionChangedEventArgs = System.Windows.Controls.SelectionChangedEventArgs;
 
@@ -604,6 +605,8 @@ namespace PRSDesktop
         private bool bColumnsLoaded;
         
         private AssignmentGrid? ag;
+        private LeaveRequestGrid? lg;
+        private StandardLeaveGrid? slg;
         private DynamicDataGrid<Meeting>? mg;
         
         public bool IsReady { get; set; }
@@ -612,8 +615,6 @@ namespace PRSDesktop
 
         public Calendar()
         {
-            // TODO: SaveSettings
-
             using (EventSuppressor.All<Suppress>())
             {
                 InitializeComponent();
@@ -657,40 +658,6 @@ namespace PRSDesktop
                 EmployeeSettings = Properties.EmployeeSelector;
                 EmployeeSelection = Properties.EmployeeSelection;
                 AlwaysTodayBox.IsChecked = Properties.AlwaysStartOnToday;
-                
-                var query = new MultiQuery();
-                
-                query.Add(
-                    Filter<LeaveRequest>.Where(x =>x.Status).IsNotEqualTo(LeaveRequestStatus.Rejected), 
-                    Columns.None<LeaveRequest>()
-                        .Add(x => x.ID)
-                        .Add(x => x.EmployeeLink.ID)
-                        .Add(x => x.From)
-                        .Add(x => x.FromTime)
-                        .Add(x => x.To)
-                        .Add(x => x.ToTime)
-                        .Add(x => x.LeaveType.Description)
-                        .Add(x => x.LeaveType.Color)
-                        .Add(x => x.Status)
-                        .Add(x => x.Notes));
-                
-                query.Add(
-                    null,
-                    Columns.None<StandardLeave>()
-                        .Add(x => x.ID)
-                        .Add(c => c.ID)
-                        .Add(c => c.LeaveType.Description)
-                        .Add(c => c.Name)
-                        .Add(c => c.LeaveType.Color)
-                        .Add(c => c.From)
-                        .Add(c => c.FromTime)
-                        .Add(c => c.To)
-                        .Add(c => c.ToTime));
-
-                query.Query();
-
-                _standardleaves = query.Get<StandardLeave>().ToArray<StandardLeave>();
-                _leaverequests = query.Get<LeaveRequest>().ToArray<LeaveRequest>();
 
                 ReloadColumns();
                 // var widthtimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
@@ -768,13 +735,49 @@ namespace PRSDesktop
                     new SortOrder<Assignment>(x => x.EmployeeLink.ID).ThenBy(x => x.Date).ThenBy(x => x.Booked.Duration, SortDirection.Descending)
                 );
                 
+                query.Add(
+                    Filter<LeaveRequest>
+                        .Where(x => x.Status).IsNotEqualTo(LeaveRequestStatus.Rejected)
+                        .And(x => x.EmployeeLink.ID).InList(empids)
+                        .And(x => x.From).IsLessThanOrEqualTo(endDate)
+                        .And(x => x.To).IsGreaterThanOrEqualTo(startDate),
+                    Columns.None<LeaveRequest>()
+                        .Add(x => x.ID)
+                        .Add(x => x.EmployeeLink.ID)
+                        .Add(x => x.From)
+                        .Add(x => x.FromTime)
+                        .Add(x => x.To)
+                        .Add(x => x.ToTime)
+                        .Add(x => x.LeaveType.Description)
+                        .Add(x => x.LeaveType.Color)
+                        .Add(x => x.Status)
+                        .Add(x => x.Notes));
+                
+                query.Add(
+                    Filter<StandardLeave>
+                        .Where(x => x.From).IsLessThanOrEqualTo(endDate)
+                        .And(x => x.To).IsGreaterThanOrEqualTo(startDate),
+                    Columns.None<StandardLeave>()
+                        .Add(x => x.ID)
+                        .Add(c => c.ID)
+                        .Add(c => c.LeaveType.Description)
+                        .Add(c => c.Name)
+                        .Add(c => c.LeaveType.Color)
+                        .Add(c => c.From)
+                        .Add(c => c.FromTime)
+                        .Add(c => c.To)
+                        .Add(c => c.ToTime));
+                
                 query.Query();
 
                 _timesheets = (BackgroundType == CalendarBackgroundType.Roster)
                     ? []
                     : query.Get<TimeSheet>().ToArray<TimeSheet>();
 
+                _leaverequests = query.Get<LeaveRequest>().ToArray<LeaveRequest>();
                 _assignments = query.Get<Assignment>().ToList<Assignment>();
+
+                _standardleaves = query.Get<StandardLeave>().ToArray<StandardLeave>();
                 
                 LoadBackground();
 
@@ -1002,6 +1005,10 @@ namespace PRSDesktop
             if (employee is null) return;
 
             var model = new AssignmentAppointment(assignment, employee, AssignmentType);
+            model.OnUpdate += () =>
+            {
+                Client.Save(assignment, "Edited by user");
+            };
             model.EmployeeChanged += (o, e) =>
             {
                 model.Employee = _employees.FirstOrDefault(x => x.ID == assignment.EmployeeLink.ID);
@@ -1033,6 +1040,8 @@ namespace PRSDesktop
             bColumnsLoaded = true;
         }
 
+        #region Block
+
         private (TimeSpan Start, TimeSpan End)? GetFillBlock(DateTime date, object? column, TimeSpan time)
         {
             if (column is not Employee employee) return null;
@@ -1118,6 +1127,7 @@ namespace PRSDesktop
 
         private void Calendar_BlockRightClicked(object sender, CalendarBlockEventArgs e)
         {
+            object? value;
             if(e.Value is AssignmentAppointment appointment)
             {
                 if (appointment.Model.Meeting.Link.ID != Guid.Empty)
@@ -1169,15 +1179,35 @@ namespace PRSDesktop
                     e.Menu.AddItem("Delete Assignment", null, appointment.Model, DeleteAssignment);
                 }
 
-                e.Menu.AddSeparatorIfNeeded();
+                value = appointment.Model;
+            }
+            else if(e.Value is LeaveRequestAppointment leaveAppointment)
+            {
+                if (Security.CanView<LeaveRequest>())
+                {
+                    e.Menu.AddItem(
+                        Security.CanEdit<LeaveRequest>() ? "Edit Leave" : "View Leave",
+                        null,
+                        leaveAppointment.Model,
+                        EditLeave);
+                }
 
-                e.Menu.AddItem("Zoom In", null, ZoomIn);
-                e.Menu.AddItem("Zoom Out", null, ZoomOut);
-                e.Menu.AddItem("Reset Zoom", null, ResetZoom);
-                
-                CustomiseContextMenu?.Invoke(e.Menu, new CalendarDataMenuEventArgs(appointment.Model, e));
+                value = leaveAppointment.Model;
             }
-            else if(e.Value is null)
+            else if(e.Value is StandardLeaveAppointment standardLeaveAppointment)
+            {
+                if (Security.CanView<StandardLeave>())
+                {
+                    e.Menu.AddItem(
+                        Security.CanEdit<StandardLeave>() ? "Edit Standard Leave" : "View Standard Leave",
+                        null,
+                        standardLeaveAppointment.Model,
+                        EditStandardLeave);
+                }
+
+                value = standardLeaveAppointment.Model;
+            }
+            else if (e.Value is null)
             {
                 if (e.Column is not Employee employee) return;
 
@@ -1186,26 +1216,33 @@ namespace PRSDesktop
                 var createmenu = e.Menu.AddItem("Create...", null, null)
                     .WithName($"Menu_{nameof(ContextMenuItems.Create)}");
                 createmenu.AddItem("New Assignment", null, slot, slot => CreateAssignment(slot));
-                createmenu.AddItem("New Meeting", null, slot, CreateMeeting);
+                // createmenu.AddItem("New Meeting", null, slot, CreateMeeting);
 
                 var fillMenu = e.Menu.AddItem("Fill...", null, null)
                     .WithName($"Menu_{nameof(ContextMenuItems.Fill)}");
                 fillMenu.AddItem("New Assignment", null, () => CreateAssignment(FillSlot(e, slot)));
-                fillMenu.AddItem("New Meeting", null, () => CreateMeeting(FillSlot(e, slot)));
+                // fillMenu.AddItem("New Meeting", null, () => CreateMeeting(FillSlot(e, slot)));
 
                 if (_copiedmodel != null)
                 {
                     e.Menu.AddSeparator();
                     e.Menu.AddItem("Paste Assignment", null, slot, slot => PasteAssignment(slot, _copiedmodel));
                 }
-                e.Menu.AddSeparator();
-
-                e.Menu.AddItem("Zoom In", null, ZoomIn);
-                e.Menu.AddItem("Zoom Out", null, ZoomOut);
-                e.Menu.AddItem("Reset Zoom", null, ResetZoom);
 
-                CustomiseContextMenu?.Invoke(e.Menu, new CalendarDataMenuEventArgs(slot, e));
+                value = slot;
             }
+            else
+            {
+                value = null;
+            }
+
+            e.Menu.AddSeparatorIfNeeded();
+
+            e.Menu.AddItem("Zoom In", null, ZoomIn);
+            e.Menu.AddItem("Zoom Out", null, ZoomOut, enabled: Zoom > 100);
+            e.Menu.AddItem("Reset Zoom", null, ResetZoom);
+
+            CustomiseContextMenu?.Invoke(e.Menu, new CalendarDataMenuEventArgs(value, e));
         }
         
         private static void CreateDigitalFormsMenu(ContextMenu menu, AssignmentAppointment appointment)
@@ -1386,12 +1423,38 @@ namespace PRSDesktop
             ass.EmployeeLink.Clear();
 
             Client.Save(ass, "");
-            // TODO: UpdateAssignment(ass);
+
+            _assignments.Add(ass);
+            LoadAssignment(ass, _appointments);
             _copiedmodel = null;
             return ass;
 
         }
 
+        private void EditLeave(LeaveRequest model)
+        {
+            var grid = CheckGrid(ref lg);
+            Client.EnsureColumns(model, grid.LoadEditorColumns());
+
+            if (DynamicGridUtils.EditEntity(model))
+            {
+                ItemChanged?.Invoke(this, new CalendarDataEventArgs(model));
+                Refresh();
+            }
+        }
+
+        private void EditStandardLeave(StandardLeave model)
+        {
+            var grid = CheckGrid(ref slg);
+            Client.EnsureColumns(model, grid.LoadEditorColumns());
+
+            if (DynamicGridUtils.EditEntity(model))
+            {
+                ItemChanged?.Invoke(this, new CalendarDataEventArgs(model));
+                Refresh();
+            }
+        }
+
         private void Calendar_BlockClicked(object sender, CalendarBlockEventArgs e)
         {
             if(e.Value is AssignmentAppointment appointment)
@@ -1405,6 +1468,10 @@ namespace PRSDesktop
             }
         }
 
+        #endregion
+
+        #region Layout
+
         private void _settingsButton_OnClick(object sender, RoutedEventArgs e)
         {
             _splitPanel.View = DynamicSplitPanelView.Master;
@@ -1420,13 +1487,7 @@ namespace PRSDesktop
                 SettingsVisible = CalendarSettingsVisibility.Hidden;
         }
 
-        private void AlwaysTodayBox_Checked(object sender, RoutedEventArgs e)
-        {
-            if (EventSuppressor.IsSet(Suppress.Events)) return;
-
-            Properties.AlwaysStartOnToday = AlwaysTodayBox.IsChecked == true;
-            DoSaveSettings();
-        }
+        #endregion
 
         private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
         {
@@ -1447,6 +1508,8 @@ namespace PRSDesktop
             block.Text = display;
         }
 
+        #region Date Selection
+
         private void Left_Click(object sender, RoutedEventArgs e)
         {
             SelectedDate = SelectedDate.AddDays(CalendarView switch
@@ -1471,5 +1534,15 @@ namespace PRSDesktop
         {
             SelectedDate = DateTime.Today;
         }
+
+        private void AlwaysTodayBox_Checked(object sender, RoutedEventArgs e)
+        {
+            if (EventSuppressor.IsSet(Suppress.Events)) return;
+
+            Properties.AlwaysStartOnToday = AlwaysTodayBox.IsChecked == true;
+            DoSaveSettings();
+        }
+
+        #endregion
     }
 }