|
|
@@ -21,1533 +21,1563 @@ using PRSDesktop.Grids;
|
|
|
using Selection = InABox.Core.Selection;
|
|
|
using SelectionChangedEventArgs = System.Windows.Controls.SelectionChangedEventArgs;
|
|
|
|
|
|
-namespace PRSDesktop
|
|
|
+namespace PRSDesktop;
|
|
|
+
|
|
|
+public partial class Calendar
|
|
|
{
|
|
|
- public partial class Calendar
|
|
|
+
|
|
|
+ private enum Suppress
|
|
|
{
|
|
|
+ Selector, // Prevent the Selector from Being Changed
|
|
|
+ Calendar, // Prevent the Calendar from Being Reconfigured
|
|
|
+ Events, // Prevent the Selectors from Responding to Events
|
|
|
+ Refresh, // Stop the Data from Being refreshed
|
|
|
+ Settings // Dont allow settings to be updated
|
|
|
+ }
|
|
|
|
|
|
- private enum Suppress
|
|
|
- {
|
|
|
- Selector, // Prevent the Selector from Being Changed
|
|
|
- Calendar, // Prevent the Calendar from Being Reconfigured
|
|
|
- Events, // Prevent the Selectors from Responding to Events
|
|
|
- Refresh, // Stop the Data from Being refreshed
|
|
|
- Settings // Dont allow settings to be updated
|
|
|
- }
|
|
|
+ private EventSuppressor? suppressor = null;
|
|
|
+ public void DisableUpdate()
|
|
|
+ {
|
|
|
+ suppressor ??= new EventSuppressor(Suppress.Refresh, Suppress.Settings);
|
|
|
+ }
|
|
|
|
|
|
- private EventSuppressor? suppressor = null;
|
|
|
- public void DisableUpdate()
|
|
|
+ public void EnableUpdate()
|
|
|
+ {
|
|
|
+ if (suppressor != null)
|
|
|
{
|
|
|
- suppressor ??= new EventSuppressor(Suppress.Refresh, Suppress.Settings);
|
|
|
+ suppressor.Dispose();
|
|
|
+ suppressor = null;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public void EnableUpdate()
|
|
|
- {
|
|
|
- if (suppressor != null)
|
|
|
- {
|
|
|
- suppressor.Dispose();
|
|
|
- suppressor = null;
|
|
|
- }
|
|
|
- }
|
|
|
+ #region Converters
|
|
|
|
|
|
- #region Converters
|
|
|
+ public static readonly IValueConverter DayOfWeekConverter = new FuncConverter<DateTime, string>(x => x.DayOfWeek.ToString());
|
|
|
|
|
|
- public static readonly IValueConverter DayOfWeekConverter = new FuncConverter<DateTime, string>(x => x.DayOfWeek.ToString());
|
|
|
+ #endregion
|
|
|
|
|
|
- #endregion
|
|
|
+ #region Dependency Properties
|
|
|
|
|
|
- #region Dependency Properties
|
|
|
+ #region HeaderVisibility Dependency Property
|
|
|
|
|
|
- #region HeaderVisibility Dependency Property
|
|
|
+ public static readonly DependencyProperty HeaderVisibilityProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(HeaderVisibility),
|
|
|
+ typeof(Visibility),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(Visibility.Collapsed)
|
|
|
+ );
|
|
|
+
|
|
|
+ public Visibility HeaderVisibility
|
|
|
+ {
|
|
|
+ get => (Visibility)GetValue(HeaderVisibilityProperty);
|
|
|
+ set => SetValue(HeaderVisibilityProperty,value);
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region SettingsVisible Dependency Property
|
|
|
+
|
|
|
+ public static readonly DependencyProperty SettingsVisibleProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(SettingsVisible),
|
|
|
+ typeof(CalendarSettingsVisibility),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(CalendarSettingsVisibility.Disabled, SettingsVisible_Changed)
|
|
|
+ );
|
|
|
+
|
|
|
+ private static void SettingsVisible_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
+ var value = (CalendarSettingsVisibility)e.NewValue;
|
|
|
|
|
|
- public static readonly DependencyProperty HeaderVisibilityProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(HeaderVisibility),
|
|
|
- typeof(Visibility),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(Visibility.Collapsed)
|
|
|
- );
|
|
|
-
|
|
|
- public Visibility HeaderVisibility
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- get => (Visibility)GetValue(HeaderVisibilityProperty);
|
|
|
- set => SetValue(HeaderVisibilityProperty,value);
|
|
|
+ calendar.Properties.SettingsVisible = value;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region SettingsVisible Dependency Property
|
|
|
-
|
|
|
- public static readonly DependencyProperty SettingsVisibleProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(SettingsVisible),
|
|
|
- typeof(CalendarSettingsVisibility),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(CalendarSettingsVisibility.Disabled, SettingsVisible_Changed)
|
|
|
- );
|
|
|
-
|
|
|
- private static void SettingsVisible_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
- var value = (CalendarSettingsVisibility)e.NewValue;
|
|
|
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.SettingsVisible = value;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
+ calendar._splitPanel.View = value == CalendarSettingsVisibility.Visible
|
|
|
+ ? DynamicSplitPanelView.Combined
|
|
|
+ : DynamicSplitPanelView.Master;
|
|
|
+ calendar._splitPanel.AllowableViews = value == CalendarSettingsVisibility.Disabled
|
|
|
+ ? DynamicSplitPanelView.Master
|
|
|
+ : DynamicSplitPanelView.Master | DynamicSplitPanelView.Combined;
|
|
|
+ }
|
|
|
|
|
|
- calendar._splitPanel.View = value == CalendarSettingsVisibility.Visible
|
|
|
- ? DynamicSplitPanelView.Combined
|
|
|
- : DynamicSplitPanelView.Master;
|
|
|
- calendar._splitPanel.AllowableViews = value == CalendarSettingsVisibility.Disabled
|
|
|
- ? DynamicSplitPanelView.Master
|
|
|
- : DynamicSplitPanelView.Master | DynamicSplitPanelView.Combined;
|
|
|
- }
|
|
|
+ public CalendarSettingsVisibility SettingsVisible
|
|
|
+ {
|
|
|
+ get => (CalendarSettingsVisibility)GetValue(SettingsVisibleProperty);
|
|
|
+ set => SetValue(SettingsVisibleProperty, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region CalendarView Dependency Property
|
|
|
+
|
|
|
+ public static readonly DependencyProperty CalendarViewProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(CalendarView),
|
|
|
+ typeof(CalendarViewType),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(CalendarViewType.Day, CalendarView_Changed)
|
|
|
+ );
|
|
|
+
|
|
|
+ public CalendarViewType CalendarView
|
|
|
+ {
|
|
|
+ get => (CalendarViewType)GetValue(CalendarViewProperty);
|
|
|
+ set => SetValue(CalendarViewProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- public CalendarSettingsVisibility SettingsVisible
|
|
|
- {
|
|
|
- get => (CalendarSettingsVisibility)GetValue(SettingsVisibleProperty);
|
|
|
- set => SetValue(SettingsVisibleProperty, value);
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region CalendarView Dependency Property
|
|
|
-
|
|
|
- public static readonly DependencyProperty CalendarViewProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(CalendarView),
|
|
|
- typeof(CalendarViewType),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(CalendarViewType.Day, CalendarView_Changed)
|
|
|
- );
|
|
|
+ private static void CalendarView_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- public CalendarViewType CalendarView
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- get => (CalendarViewType)GetValue(CalendarViewProperty);
|
|
|
- set => SetValue(CalendarViewProperty, value);
|
|
|
+ calendar.Properties.CalendarView = calendar.CalendarView;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
|
|
|
- private static void CalendarView_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
-
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.CalendarView = calendar.CalendarView;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
+ calendar.Refresh();
|
|
|
+ }
|
|
|
|
|
|
- calendar.Refresh();
|
|
|
- }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region EmployeeSelector Dependency Property
|
|
|
+
|
|
|
+ public static readonly DependencyProperty EmployeeSelectionProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(EmployeeSelection),
|
|
|
+ typeof(EmployeeSelectorData),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(new EmployeeSelectorData(), EmployeeSelection_Changed)
|
|
|
+ );
|
|
|
+
|
|
|
+ public EmployeeSelectorData EmployeeSelection
|
|
|
+ {
|
|
|
+ get => (EmployeeSelectorData)GetValue(EmployeeSelectionProperty);
|
|
|
+ set => SetValue(EmployeeSelectionProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region EmployeeSelector Dependency Property
|
|
|
-
|
|
|
- public static readonly DependencyProperty EmployeeSelectionProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(EmployeeSelection),
|
|
|
- typeof(EmployeeSelectorData),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(new EmployeeSelectorData(), EmployeeSelection_Changed)
|
|
|
- );
|
|
|
+ private static void EmployeeSelection_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- public EmployeeSelectorData EmployeeSelection
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- get => (EmployeeSelectorData)GetValue(EmployeeSelectionProperty);
|
|
|
- set => SetValue(EmployeeSelectionProperty, value);
|
|
|
+ calendar.Properties.EmployeeSelection = calendar.EmployeeSelection;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
|
|
|
- private static void EmployeeSelection_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
-
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.EmployeeSelection = calendar.EmployeeSelection;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
+ calendar.EmployeeSelector.Selection = calendar.EmployeeSelection;
|
|
|
+ calendar._employees = calendar.EmployeeSelector.GetEmployeeData((row, rosters) => row.ToObject<Employee>());
|
|
|
+ calendar.ReloadColumns();
|
|
|
+ calendar.Refresh();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void EmployeeSelector_OnSelectionChanged(object sender, EmployeeSelectorSelectionChangedArgs args)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ EmployeeSelection = args.Selection;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region EmployeeSettings Dependency Property
|
|
|
+
|
|
|
+ public static readonly DependencyProperty EmployeeSettingsProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(EmployeeSettings),
|
|
|
+ typeof(EmployeeSelectorSettings),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(new EmployeeSelectorSettings(), EmployeeSettings_Changed)
|
|
|
+ );
|
|
|
+
|
|
|
+ private static void EmployeeSettings_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- calendar.EmployeeSelector.Selection = calendar.EmployeeSelection;
|
|
|
- calendar._employees = calendar.EmployeeSelector.GetEmployeeData((row, rosters) => row.ToObject<Employee>());
|
|
|
- calendar.ReloadColumns();
|
|
|
- calendar.Refresh();
|
|
|
- }
|
|
|
-
|
|
|
- private void EmployeeSelector_OnSelectionChanged(object sender, EmployeeSelectorSelectionChangedArgs args)
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- EmployeeSelection = args.Selection;
|
|
|
+ calendar.Properties.EmployeeSelector = calendar.EmployeeSettings;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region EmployeeSettings Dependency Property
|
|
|
-
|
|
|
- public static readonly DependencyProperty EmployeeSettingsProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(EmployeeSettings),
|
|
|
- typeof(EmployeeSelectorSettings),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(new EmployeeSelectorSettings(), EmployeeSettings_Changed)
|
|
|
- );
|
|
|
-
|
|
|
- private static void EmployeeSettings_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
+ calendar.EmployeeSelector.Settings = calendar.EmployeeSettings;
|
|
|
+ }
|
|
|
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.EmployeeSelector = calendar.EmployeeSettings;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
- calendar.EmployeeSelector.Settings = calendar.EmployeeSettings;
|
|
|
- }
|
|
|
+ public EmployeeSelectorSettings EmployeeSettings
|
|
|
+ {
|
|
|
+ get => (EmployeeSelectorSettings)GetValue(EmployeeSettingsProperty);
|
|
|
+ set => SetValue(EmployeeSettingsProperty, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void EmployeeSelector_OnSettingsChanged(object sender, EmployeeSelectorSettingsChangedArgs args)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ EmployeeSettings = args.Settings;
|
|
|
+ }
|
|
|
|
|
|
- public EmployeeSelectorSettings EmployeeSettings
|
|
|
- {
|
|
|
- get => (EmployeeSelectorSettings)GetValue(EmployeeSettingsProperty);
|
|
|
- set => SetValue(EmployeeSettingsProperty, value);
|
|
|
- }
|
|
|
-
|
|
|
- private void EmployeeSelector_OnSettingsChanged(object sender, EmployeeSelectorSettingsChangedArgs args)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- EmployeeSettings = args.Settings;
|
|
|
- }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region TimeInterval DependencyProperty
|
|
|
+
|
|
|
+ public static readonly DependencyProperty TimeIntervalProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ "TimeInterval",
|
|
|
+ typeof(CalendarTimeInterval),
|
|
|
+ typeof(Calendar),
|
|
|
+ new PropertyMetadata(CalendarTimeInterval.FifteenMinutes, TimeInterval_Changed)
|
|
|
+ );
|
|
|
+
|
|
|
+ public CalendarTimeInterval TimeInterval
|
|
|
+ {
|
|
|
+ get => (CalendarTimeInterval)GetValue(TimeIntervalProperty);
|
|
|
+ set => SetValue(TimeIntervalProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region TimeInterval DependencyProperty
|
|
|
-
|
|
|
- public static readonly DependencyProperty TimeIntervalProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- "TimeInterval",
|
|
|
- typeof(CalendarTimeInterval),
|
|
|
- typeof(Calendar),
|
|
|
- new PropertyMetadata(CalendarTimeInterval.FifteenMinutes, TimeInterval_Changed)
|
|
|
- );
|
|
|
+ private static void TimeInterval_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- public CalendarTimeInterval TimeInterval
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- get => (CalendarTimeInterval)GetValue(TimeIntervalProperty);
|
|
|
- set => SetValue(TimeIntervalProperty, value);
|
|
|
+ calendar.Properties.TimeInterval = calendar.TimeInterval;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
+ calendar.IntervalSelector.SelectedIndex = (int)calendar.TimeInterval;
|
|
|
|
|
|
- private static void TimeInterval_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
-
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.TimeInterval = calendar.TimeInterval;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
- calendar.IntervalSelector.SelectedIndex = (int)calendar.TimeInterval;
|
|
|
+ calendar.CalendarControl.RowInterval = TimeIntervalToTimeSpan(calendar.TimeInterval);
|
|
|
+ }
|
|
|
|
|
|
- calendar.CalendarControl.RowInterval = TimeIntervalToTimeSpan(calendar.TimeInterval);
|
|
|
- }
|
|
|
+ private void IntervalSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ TimeInterval = (CalendarTimeInterval)IntervalSelector.SelectedIndex;
|
|
|
+ }
|
|
|
|
|
|
- private void IntervalSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- TimeInterval = (CalendarTimeInterval)IntervalSelector.SelectedIndex;
|
|
|
- }
|
|
|
+ private static TimeSpan TimeIntervalToTimeSpan(CalendarTimeInterval interval)
|
|
|
+ {
|
|
|
+ return interval switch
|
|
|
+ {
|
|
|
+ CalendarTimeInterval.FiveMinutes => new TimeSpan(0, 5, 0),
|
|
|
+ CalendarTimeInterval.SixMinutes => new TimeSpan(0, 6, 0),
|
|
|
+ CalendarTimeInterval.TenMinutes => new TimeSpan(0, 10, 0),
|
|
|
+ CalendarTimeInterval.FifteenMinutes => new TimeSpan(0, 15, 0),
|
|
|
+ CalendarTimeInterval.TwentyMinutes => new TimeSpan(0, 20, 0),
|
|
|
+ CalendarTimeInterval.ThirtyMinutes => new TimeSpan(0, 30, 0),
|
|
|
+ CalendarTimeInterval.SixtyMinutes or _ => new TimeSpan(1, 0, 0)
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region SelectedDate Dependency Property
|
|
|
+
|
|
|
+ public static readonly DependencyProperty SelectedDateProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(SelectedDate),
|
|
|
+ typeof(DateTime),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(DateTime.Today, SelectedDate_Changed)
|
|
|
+ );
|
|
|
+
|
|
|
+ public DateTime SelectedDate
|
|
|
+ {
|
|
|
+ get => (DateTime)GetValue(SelectedDateProperty);
|
|
|
+ set => SetValue(SelectedDateProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- private static TimeSpan TimeIntervalToTimeSpan(CalendarTimeInterval interval)
|
|
|
- {
|
|
|
- return interval switch
|
|
|
- {
|
|
|
- CalendarTimeInterval.FiveMinutes => new TimeSpan(0, 5, 0),
|
|
|
- CalendarTimeInterval.SixMinutes => new TimeSpan(0, 6, 0),
|
|
|
- CalendarTimeInterval.TenMinutes => new TimeSpan(0, 10, 0),
|
|
|
- CalendarTimeInterval.FifteenMinutes => new TimeSpan(0, 15, 0),
|
|
|
- CalendarTimeInterval.TwentyMinutes => new TimeSpan(0, 20, 0),
|
|
|
- CalendarTimeInterval.ThirtyMinutes => new TimeSpan(0, 30, 0),
|
|
|
- CalendarTimeInterval.SixtyMinutes or _ => new TimeSpan(1, 0, 0)
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region SelectedDate Dependency Property
|
|
|
-
|
|
|
- public static readonly DependencyProperty SelectedDateProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(SelectedDate),
|
|
|
- typeof(DateTime),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(DateTime.Today, SelectedDate_Changed)
|
|
|
- );
|
|
|
+ private static void SelectedDate_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- public DateTime SelectedDate
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- get => (DateTime)GetValue(SelectedDateProperty);
|
|
|
- set => SetValue(SelectedDateProperty, value);
|
|
|
+ calendar.Properties.Date = calendar.SelectedDate;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
|
|
|
- private static void SelectedDate_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
-
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.Date = calendar.SelectedDate;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
-
|
|
|
- calendar.Refresh();
|
|
|
- }
|
|
|
+ calendar.Refresh();
|
|
|
+ }
|
|
|
|
|
|
- public DateTime StartDate => (Properties?.CalendarView ?? CalendarViewType.Day) == CalendarViewType.Day
|
|
|
- ? SelectedDate
|
|
|
- : SelectedDate.StartOfWeek(DayOfWeek.Monday);
|
|
|
+ public DateTime StartDate => (Properties?.CalendarView ?? CalendarViewType.Day) == CalendarViewType.Day
|
|
|
+ ? SelectedDate
|
|
|
+ : SelectedDate.StartOfWeek(DayOfWeek.Monday);
|
|
|
+
|
|
|
+ public DateTime EndDate => Properties.CalendarView == CalendarViewType.Day
|
|
|
+ ? StartDate.AddDays(1)
|
|
|
+ : Properties.CalendarView == CalendarViewType.WorkWeek
|
|
|
+ ? StartDate.AddDays(5)
|
|
|
+ : StartDate.AddDays(7);
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region StartHour Dependency Properties
|
|
|
+
|
|
|
+ public static readonly DependencyProperty StartHourProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(StartHour),
|
|
|
+ typeof(int),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(6, StartHour_Changed, StartHour_Coerce)
|
|
|
+ );
|
|
|
+
|
|
|
+ private static object StartHour_Coerce(DependencyObject d, object baseValue)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar || baseValue is not int value) return baseValue;
|
|
|
|
|
|
- public DateTime EndDate => Properties.CalendarView == CalendarViewType.Day
|
|
|
- ? StartDate.AddDays(1)
|
|
|
- : Properties.CalendarView == CalendarViewType.WorkWeek
|
|
|
- ? StartDate.AddDays(5)
|
|
|
- : StartDate.AddDays(7);
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region StartHour Dependency Properties
|
|
|
-
|
|
|
- public static readonly DependencyProperty StartHourProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(StartHour),
|
|
|
- typeof(int),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(6, StartHour_Changed, StartHour_Coerce)
|
|
|
- );
|
|
|
+ return Math.Min(calendar.EndHour - 1, Math.Max(0, value));
|
|
|
+ }
|
|
|
|
|
|
- private static object StartHour_Coerce(DependencyObject d, object baseValue)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar || baseValue is not int value) return baseValue;
|
|
|
+ public int StartHour
|
|
|
+ {
|
|
|
+ get => (int)GetValue(StartHourProperty);
|
|
|
+ set => SetValue(StartHourProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- return Math.Min(calendar.EndHour - 1, Math.Max(0, value));
|
|
|
- }
|
|
|
+ private static void StartHour_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- public int StartHour
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- get => (int)GetValue(StartHourProperty);
|
|
|
- set => SetValue(StartHourProperty, value);
|
|
|
+ calendar.Properties.StartHour = calendar.StartHour;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
+ calendar.StartTimeSelector.Text = FormatHour(calendar.StartHour);
|
|
|
+ calendar.CalendarControl.StartHour = TimeSpan.FromHours(calendar.StartHour);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void StartTimeSelector_Down_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
|
|
|
- private static void StartHour_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
+ StartHour -= 1;
|
|
|
+ }
|
|
|
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.StartHour = calendar.StartHour;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
- calendar.StartTimeSelector.Text = FormatHour(calendar.StartHour);
|
|
|
- calendar.CalendarControl.StartHour = TimeSpan.FromHours(calendar.StartHour);
|
|
|
- }
|
|
|
-
|
|
|
- private void StartTimeSelector_Down_Click(object sender, RoutedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
+ private void StartTimeSelector_Up_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
|
|
|
- StartHour -= 1;
|
|
|
- }
|
|
|
+ StartHour += 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region End Hour Property
|
|
|
+
|
|
|
+ public static readonly DependencyProperty EndHourProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(EndHour),
|
|
|
+ typeof(int),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(18, EndHour_Changed, EndHour_Coerce)
|
|
|
+ );
|
|
|
+
|
|
|
+ public int EndHour
|
|
|
+ {
|
|
|
+ get => (int)GetValue(EndHourProperty);
|
|
|
+ set => SetValue(EndHourProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- private void StartTimeSelector_Up_Click(object sender, RoutedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
+ private static object EndHour_Coerce(DependencyObject d, object baseValue)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar || baseValue is not int value) return baseValue;
|
|
|
|
|
|
- StartHour += 1;
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region End Hour Property
|
|
|
-
|
|
|
- public static readonly DependencyProperty EndHourProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(EndHour),
|
|
|
- typeof(int),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(18, EndHour_Changed, EndHour_Coerce)
|
|
|
- );
|
|
|
+ return Math.Max(calendar.StartHour + 1, Math.Min(24, value));
|
|
|
+ }
|
|
|
|
|
|
- public int EndHour
|
|
|
- {
|
|
|
- get => (int)GetValue(EndHourProperty);
|
|
|
- set => SetValue(EndHourProperty, value);
|
|
|
- }
|
|
|
+ private static void EndHour_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- private static object EndHour_Coerce(DependencyObject d, object baseValue)
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- if (d is not Calendar calendar || baseValue is not int value) return baseValue;
|
|
|
-
|
|
|
- return Math.Max(calendar.StartHour + 1, Math.Min(24, value));
|
|
|
+ calendar.Properties.EndHour = calendar.EndHour;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
+ calendar.FinishTimeSelector.Text = FormatHour(calendar.EndHour);
|
|
|
+ calendar.CalendarControl.EndHour = TimeSpan.FromHours(calendar.EndHour);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void FinishTimeSelector_Down_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ EndHour -= 1;
|
|
|
+ }
|
|
|
|
|
|
- private static void EndHour_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
-
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.EndHour = calendar.EndHour;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
- calendar.FinishTimeSelector.Text = FormatHour(calendar.EndHour);
|
|
|
- calendar.CalendarControl.EndHour = TimeSpan.FromHours(calendar.EndHour);
|
|
|
- }
|
|
|
-
|
|
|
- private void FinishTimeSelector_Down_Click(object sender, RoutedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- EndHour -= 1;
|
|
|
- }
|
|
|
+ private void FinishTimeSelector_Up_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ EndHour += 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string FormatHour(int hour)
|
|
|
+ {
|
|
|
+ return hour <= 0 || hour >= 24
|
|
|
+ ? "Midnight"
|
|
|
+ : hour < 12
|
|
|
+ ? string.Format("{0}:00 AM", hour)
|
|
|
+ : hour > 12
|
|
|
+ ? string.Format("{0}:00 PM", hour)
|
|
|
+ : "12:00 NN";
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region AssignmentType Dependency Property
|
|
|
+
|
|
|
+ public static readonly DependencyProperty AssignmentTypeProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(AssignmentType),
|
|
|
+ typeof(CalendarAssignmentType),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(CalendarAssignmentType.Booked, AssignmentType_Changed)
|
|
|
+ );
|
|
|
+
|
|
|
+ public CalendarAssignmentType AssignmentType
|
|
|
+ {
|
|
|
+ get => (CalendarAssignmentType)GetValue(AssignmentTypeProperty);
|
|
|
+ set => SetValue(AssignmentTypeProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- private void FinishTimeSelector_Up_Click(object sender, RoutedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- EndHour += 1;
|
|
|
- }
|
|
|
-
|
|
|
- private static string FormatHour(int hour)
|
|
|
- {
|
|
|
- return hour <= 0 || hour >= 24
|
|
|
- ? "Midnight"
|
|
|
- : hour < 12
|
|
|
- ? string.Format("{0}:00 AM", hour)
|
|
|
- : hour > 12
|
|
|
- ? string.Format("{0}:00 PM", hour)
|
|
|
- : "12:00 NN";
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region AssignmentType Dependency Property
|
|
|
-
|
|
|
- public static readonly DependencyProperty AssignmentTypeProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(AssignmentType),
|
|
|
- typeof(CalendarAssignmentType),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(CalendarAssignmentType.Booked, AssignmentType_Changed)
|
|
|
- );
|
|
|
+ private static void AssignmentType_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- public CalendarAssignmentType AssignmentType
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- get => (CalendarAssignmentType)GetValue(AssignmentTypeProperty);
|
|
|
- set => SetValue(AssignmentTypeProperty, value);
|
|
|
+ calendar.Properties.AssignmentType = calendar.AssignmentType;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
+ calendar.AssignmentTypeSelector.SelectedIndex = (int)calendar.AssignmentType;
|
|
|
+ calendar.Refresh();
|
|
|
+ }
|
|
|
|
|
|
- private static void AssignmentType_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ private void AssignmentTypeSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ using (new EventSuppressor(Suppress.Selector))
|
|
|
{
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
-
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.AssignmentType = calendar.AssignmentType;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
- calendar.AssignmentTypeSelector.SelectedIndex = (int)calendar.AssignmentType;
|
|
|
- calendar.Refresh();
|
|
|
+ AssignmentType = (CalendarAssignmentType)AssignmentTypeSelector.SelectedIndex;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region BackgroundType Dependency Property
|
|
|
+
|
|
|
+ public static readonly DependencyProperty BackgroundTypeProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(BackgroundType),
|
|
|
+ typeof(CalendarBackgroundType),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(CalendarBackgroundType.Roster, BackgroundType_Changed)
|
|
|
+ );
|
|
|
+
|
|
|
+ public CalendarBackgroundType BackgroundType
|
|
|
+ {
|
|
|
+ get => (CalendarBackgroundType)GetValue(BackgroundTypeProperty);
|
|
|
+ set => SetValue(BackgroundTypeProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- private void AssignmentTypeSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- using (new EventSuppressor(Suppress.Selector))
|
|
|
- {
|
|
|
- AssignmentType = (CalendarAssignmentType)AssignmentTypeSelector.SelectedIndex;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region BackgroundType Dependency Property
|
|
|
-
|
|
|
- public static readonly DependencyProperty BackgroundTypeProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(BackgroundType),
|
|
|
- typeof(CalendarBackgroundType),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(CalendarBackgroundType.Roster, BackgroundType_Changed)
|
|
|
- );
|
|
|
+ private static void BackgroundType_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- public CalendarBackgroundType BackgroundType
|
|
|
+ if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
{
|
|
|
- get => (CalendarBackgroundType)GetValue(BackgroundTypeProperty);
|
|
|
- set => SetValue(BackgroundTypeProperty, value);
|
|
|
+ calendar.Properties.BackgroundType = calendar.BackgroundType;
|
|
|
+ calendar.DoSaveSettings();
|
|
|
}
|
|
|
+ calendar.BackgroundTypeSelector.SelectedIndex = (int)calendar.BackgroundType;
|
|
|
+ calendar.Refresh();
|
|
|
+ }
|
|
|
|
|
|
- private static void BackgroundType_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
+ private void BackgroundTypeSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ using (new EventSuppressor(Suppress.Selector))
|
|
|
+ BackgroundType = (CalendarBackgroundType)BackgroundTypeSelector.SelectedIndex;
|
|
|
+ }
|
|
|
|
|
|
- if (!EventSuppressor.IsSet(Suppress.Settings))
|
|
|
- {
|
|
|
- calendar.Properties.BackgroundType = calendar.BackgroundType;
|
|
|
- calendar.DoSaveSettings();
|
|
|
- }
|
|
|
- calendar.BackgroundTypeSelector.SelectedIndex = (int)calendar.BackgroundType;
|
|
|
- calendar.Refresh();
|
|
|
- }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region Zoom Dependency Properties
|
|
|
+
|
|
|
+ public static readonly DependencyProperty ZoomProperty =
|
|
|
+ DependencyProperty.Register(
|
|
|
+ nameof(Zoom),
|
|
|
+ typeof(double),
|
|
|
+ typeof(Calendar),
|
|
|
+ new UIPropertyMetadata(100.0, Zoom_Changed, Zoom_Coerce)
|
|
|
+ );
|
|
|
+
|
|
|
+ private static object Zoom_Coerce(DependencyObject d, object baseValue)
|
|
|
+ {
|
|
|
+ if (baseValue is not double zoom) return baseValue;
|
|
|
+ return Math.Max(zoom, 100.0);
|
|
|
+ }
|
|
|
|
|
|
- private void BackgroundTypeSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- using (new EventSuppressor(Suppress.Selector))
|
|
|
- BackgroundType = (CalendarBackgroundType)BackgroundTypeSelector.SelectedIndex;
|
|
|
- }
|
|
|
+ public double Zoom
|
|
|
+ {
|
|
|
+ get => (double)GetValue(ZoomProperty);
|
|
|
+ set => SetValue(ZoomProperty, value);
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region Zoom Dependency Properties
|
|
|
-
|
|
|
- public static readonly DependencyProperty ZoomProperty =
|
|
|
- DependencyProperty.Register(
|
|
|
- nameof(Zoom),
|
|
|
- typeof(double),
|
|
|
- typeof(Calendar),
|
|
|
- new UIPropertyMetadata(100.0, Zoom_Changed, Zoom_Coerce)
|
|
|
- );
|
|
|
+ private static void Zoom_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (d is not Calendar calendar) return;
|
|
|
|
|
|
- private static object Zoom_Coerce(DependencyObject d, object baseValue)
|
|
|
- {
|
|
|
- if (baseValue is not double zoom) return baseValue;
|
|
|
- return Math.Max(zoom, 100.0);
|
|
|
- }
|
|
|
+ calendar.CalendarControl.Zoom = calendar.Zoom / 100;
|
|
|
+ calendar.ZoomSelector.Text = $"{calendar.Zoom:F0}%";
|
|
|
+ }
|
|
|
|
|
|
- public double Zoom
|
|
|
- {
|
|
|
- get => (double)GetValue(ZoomProperty);
|
|
|
- set => SetValue(ZoomProperty, value);
|
|
|
- }
|
|
|
+ private void ZoomSelector_Down_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ ZoomOut();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ZoomSelector_Up_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ ZoomIn();
|
|
|
+ }
|
|
|
|
|
|
- private static void Zoom_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
|
- {
|
|
|
- if (d is not Calendar calendar) return;
|
|
|
+ public void ZoomIn() => Zoom *= 1.125;
|
|
|
+ public void ZoomOut() => Zoom /= 1.125;
|
|
|
+ public void ResetZoom() => Zoom = 100;
|
|
|
|
|
|
- calendar.CalendarControl.Zoom = calendar.Zoom / 100;
|
|
|
- calendar.ZoomSelector.Text = $"{calendar.Zoom:F0}%";
|
|
|
- }
|
|
|
+ #endregion
|
|
|
|
|
|
- private void ZoomSelector_Down_Click(object sender, RoutedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- ZoomOut();
|
|
|
- }
|
|
|
-
|
|
|
- private void ZoomSelector_Up_Click(object sender, RoutedEventArgs e)
|
|
|
- {
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- ZoomIn();
|
|
|
- }
|
|
|
+ #endregion
|
|
|
|
|
|
- public void ZoomIn() => Zoom *= 1.125;
|
|
|
- public void ZoomOut() => Zoom /= 1.125;
|
|
|
- public void ResetZoom() => Zoom = 100;
|
|
|
+ #region Event Handlers
|
|
|
|
|
|
- #endregion
|
|
|
+ public event LoadSettings<CalendarSettings>? LoadSettings;
|
|
|
+
|
|
|
+ public event SaveSettings<CalendarSettings>? SaveSettings;
|
|
|
|
|
|
- #endregion
|
|
|
+ public CalendarConfigurationEvent? ConfigurationChanged;
|
|
|
+
|
|
|
+ public event CalendarDataMenuEvent? CustomiseContextMenu;
|
|
|
+
|
|
|
+ public event CalendarDataEvent? SelectionChanged;
|
|
|
|
|
|
- #region Event Handlers
|
|
|
+ public event CalendarDataEvent? ItemCreated;
|
|
|
+
|
|
|
+ public event CalendarDataEvent? ItemChanged;
|
|
|
|
|
|
- public event LoadSettings<CalendarSettings>? LoadSettings;
|
|
|
-
|
|
|
- public event SaveSettings<CalendarSettings>? SaveSettings;
|
|
|
+ public event CalendarHandledEvent? ItemEditing;
|
|
|
+
|
|
|
+ #endregion
|
|
|
|
|
|
- public CalendarConfigurationEvent? ConfigurationChanged;
|
|
|
-
|
|
|
- public event CalendarDataMenuEvent? CustomiseContextMenu;
|
|
|
-
|
|
|
- public event CalendarDataEvent? SelectionChanged;
|
|
|
+ public void SelectEmployee(Guid employeeid) => EmployeeSelector.SelectEmployee(employeeid);
|
|
|
|
|
|
- public event CalendarDataEvent? ItemCreated;
|
|
|
-
|
|
|
- public event CalendarDataEvent? ItemChanged;
|
|
|
+ // Populated as requiew when EmployeeSelector.SelectionChanged is triggered
|
|
|
+ private Employee[] _employees = [];
|
|
|
|
|
|
- public event CalendarHandledEvent? ItemEditing;
|
|
|
-
|
|
|
- #endregion
|
|
|
+ // Populated once at startup
|
|
|
+ private StandardLeave[] _standardleaves = [];
|
|
|
+ private LeaveRequest[] _leaverequests = [];
|
|
|
|
|
|
- public void SelectEmployee(Guid employeeid) => EmployeeSelector.SelectEmployee(employeeid);
|
|
|
+ // Populated on each Refresh
|
|
|
+ private TimeSheet[] _timesheets = [];
|
|
|
|
|
|
- // Populated as requiew when EmployeeSelector.SelectionChanged is triggered
|
|
|
- private Employee[] _employees = [];
|
|
|
+ // Populated on each Refresh
|
|
|
+ private List<Assignment> _assignments = [];
|
|
|
|
|
|
- // Populated once at startup
|
|
|
- private StandardLeave[] _standardleaves = [];
|
|
|
- private LeaveRequest[] _leaverequests = [];
|
|
|
+ private MeetingTemplate[]? _meetingTemplates;
|
|
|
|
|
|
- // Populated on each Refresh
|
|
|
- private TimeSheet[] _timesheets = [];
|
|
|
+ private MeetingTemplate[] MeetingTemplates
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ _meetingTemplates ??= Client.Query(
|
|
|
+ Filter.All<MeetingTemplate>(),
|
|
|
+ MeetingGrid.RequiredTemplateColumns())
|
|
|
+ .ToArray<MeetingTemplate>();
|
|
|
+ return _meetingTemplates;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // Populated on each Refresh
|
|
|
- private List<Assignment> _assignments = [];
|
|
|
|
|
|
- private ObservableCollection<ICalendarAppointment> _appointments = new();
|
|
|
-
|
|
|
- private bool bColumnsLoaded;
|
|
|
-
|
|
|
- private AssignmentGrid? ag;
|
|
|
- private LeaveRequestGrid? lg;
|
|
|
- private StandardLeaveGrid? slg;
|
|
|
- private DynamicDataGrid<Meeting>? mg;
|
|
|
-
|
|
|
- public bool IsReady { get; set; }
|
|
|
+ private ObservableCollection<ICalendarAppointment> _appointments = new();
|
|
|
+
|
|
|
+ private bool bColumnsLoaded;
|
|
|
+
|
|
|
+ private AssignmentGrid? ag;
|
|
|
+ private LeaveRequestGrid? lg;
|
|
|
+ private StandardLeaveGrid? slg;
|
|
|
+
|
|
|
+ public bool IsReady { get; set; }
|
|
|
|
|
|
- public CalendarSettings Properties { get; set; } = new();
|
|
|
+ public CalendarSettings Properties { get; set; } = new();
|
|
|
|
|
|
- public Calendar()
|
|
|
+ public Calendar()
|
|
|
+ {
|
|
|
+ using (EventSuppressor.All<Suppress>())
|
|
|
{
|
|
|
- using (EventSuppressor.All<Suppress>())
|
|
|
- {
|
|
|
- InitializeComponent();
|
|
|
-
|
|
|
- _splitPanel.DataContext = this;
|
|
|
+ InitializeComponent();
|
|
|
|
|
|
- StartHour = 0;
|
|
|
- EndHour = 24;
|
|
|
- }
|
|
|
-
|
|
|
- CalendarControl.GetFillBlockStart = GetFillBlockStart;
|
|
|
- CalendarControl.GetFillBlockEnd = GetFillBlockEnd;
|
|
|
+ _splitPanel.DataContext = this;
|
|
|
|
|
|
- CalendarControl.RowInterval = TimeIntervalToTimeSpan(TimeInterval);
|
|
|
- CalendarViewSelector.ItemsSource = new List<KeyValuePair<CalendarViewType, string>>
|
|
|
- {
|
|
|
- new(CalendarViewType.Day, "Day"),
|
|
|
- new(CalendarViewType.WorkWeek, "Work Week"),
|
|
|
- new(CalendarViewType.Week, "Week"),
|
|
|
- };
|
|
|
- CalendarViewSelector.DisplayMemberPath = "Value";
|
|
|
- CalendarViewSelector.SelectedValuePath = "Key";
|
|
|
+ StartHour = 0;
|
|
|
+ EndHour = 24;
|
|
|
}
|
|
|
|
|
|
- public virtual void Setup()
|
|
|
- {
|
|
|
- using (new EventSuppressor(Suppress.Settings, Suppress.Refresh, Suppress.Events))
|
|
|
- {
|
|
|
- Properties = LoadSettings?.Invoke(this) ?? new CalendarSettings();
|
|
|
- SettingsVisible = Properties.SettingsVisible;
|
|
|
- SelectedDate = Properties.AlwaysStartOnToday ? DateTime.Today : Properties.Date;
|
|
|
- StartHour = Properties.StartHour;
|
|
|
- EndHour = Properties.EndHour;
|
|
|
- TimeInterval = Properties.TimeInterval;
|
|
|
- AssignmentType = Properties.AssignmentType;
|
|
|
- BackgroundType = Properties.BackgroundType;
|
|
|
- CalendarView = Properties.CalendarView;
|
|
|
- Zoom = Properties.Zoom;
|
|
|
- EmployeeSelector.Setup();
|
|
|
- EmployeeSettings = Properties.EmployeeSelector;
|
|
|
- EmployeeSelection = Properties.EmployeeSelection;
|
|
|
- AlwaysTodayBox.IsChecked = Properties.AlwaysStartOnToday;
|
|
|
+ CalendarControl.GetFillBlockStart = GetFillBlockStart;
|
|
|
+ CalendarControl.GetFillBlockEnd = GetFillBlockEnd;
|
|
|
|
|
|
- ReloadColumns();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual void Shutdown(CancelEventArgs? cancel)
|
|
|
+ CalendarControl.RowInterval = TimeIntervalToTimeSpan(TimeInterval);
|
|
|
+ CalendarViewSelector.ItemsSource = new List<KeyValuePair<CalendarViewType, string>>
|
|
|
{
|
|
|
- }
|
|
|
+ new(CalendarViewType.Day, "Day"),
|
|
|
+ new(CalendarViewType.WorkWeek, "Work Week"),
|
|
|
+ new(CalendarViewType.Week, "Week"),
|
|
|
+ };
|
|
|
+ CalendarViewSelector.DisplayMemberPath = "Value";
|
|
|
+ CalendarViewSelector.SelectedValuePath = "Key";
|
|
|
+ }
|
|
|
|
|
|
- private void DoSaveSettings()
|
|
|
- {
|
|
|
- SaveSettings?.Invoke(this, Properties);
|
|
|
- }
|
|
|
-
|
|
|
- private bool bFirst = true;
|
|
|
-
|
|
|
- public virtual void Refresh()
|
|
|
- {
|
|
|
- RefreshData(StartDate, EndDate);
|
|
|
+ public virtual void Setup()
|
|
|
+ {
|
|
|
+ using (new EventSuppressor(Suppress.Settings, Suppress.Refresh, Suppress.Events))
|
|
|
+ {
|
|
|
+ Properties = LoadSettings?.Invoke(this) ?? new CalendarSettings();
|
|
|
+ SettingsVisible = Properties.SettingsVisible;
|
|
|
+ SelectedDate = Properties.AlwaysStartOnToday ? DateTime.Today : Properties.Date;
|
|
|
+ StartHour = Properties.StartHour;
|
|
|
+ EndHour = Properties.EndHour;
|
|
|
+ TimeInterval = Properties.TimeInterval;
|
|
|
+ AssignmentType = Properties.AssignmentType;
|
|
|
+ BackgroundType = Properties.BackgroundType;
|
|
|
+ CalendarView = Properties.CalendarView;
|
|
|
+ Zoom = Properties.Zoom;
|
|
|
+ EmployeeSelector.Setup();
|
|
|
+ EmployeeSettings = Properties.EmployeeSelector;
|
|
|
+ EmployeeSelection = Properties.EmployeeSelection;
|
|
|
+ AlwaysTodayBox.IsChecked = Properties.AlwaysStartOnToday;
|
|
|
+
|
|
|
+ ReloadColumns();
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ public virtual void Shutdown(CancelEventArgs? cancel)
|
|
|
+ {
|
|
|
+ }
|
|
|
|
|
|
- private bool _refreshing = false;
|
|
|
+ private void DoSaveSettings()
|
|
|
+ {
|
|
|
+ SaveSettings?.Invoke(this, Properties);
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool bFirst = true;
|
|
|
+
|
|
|
+ public virtual void Refresh()
|
|
|
+ {
|
|
|
+ RefreshData(StartDate, EndDate);
|
|
|
+ }
|
|
|
|
|
|
- private void RefreshData(DateTime startDate, DateTime endDate)
|
|
|
+ private bool _refreshing = false;
|
|
|
+
|
|
|
+ private void RefreshData(DateTime startDate, DateTime endDate)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Refresh))
|
|
|
+ return;
|
|
|
+ if (!_refreshing)
|
|
|
{
|
|
|
- if (EventSuppressor.IsSet(Suppress.Refresh))
|
|
|
- return;
|
|
|
- if (!_refreshing)
|
|
|
- {
|
|
|
- _refreshing = true;
|
|
|
- Dispatcher.BeginInvoke(() => DoRefreshData(startDate, endDate));
|
|
|
- }
|
|
|
+ _refreshing = true;
|
|
|
+ Dispatcher.BeginInvoke(() => DoRefreshData(startDate, endDate));
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- private void DoRefreshData(DateTime startDate, DateTime endDate)
|
|
|
+ private void DoRefreshData(DateTime startDate, DateTime endDate)
|
|
|
+ {
|
|
|
+ _refreshing = false;
|
|
|
+ using (new WaitCursor())
|
|
|
{
|
|
|
- _refreshing = false;
|
|
|
- using (new WaitCursor())
|
|
|
- {
|
|
|
- if (!bColumnsLoaded)
|
|
|
- ReloadColumns();
|
|
|
+ if (!bColumnsLoaded)
|
|
|
+ ReloadColumns();
|
|
|
|
|
|
- var query = new MultiQuery();
|
|
|
+ var query = new MultiQuery();
|
|
|
|
|
|
- var empids = _employees.ToArray(x => x.ID);
|
|
|
-
|
|
|
- if (BackgroundType != CalendarBackgroundType.Roster)
|
|
|
- {
|
|
|
- query.Add(
|
|
|
- Filter<TimeSheet>.Where(x => x.Employee.ID).InList(empids)
|
|
|
- .And(x => x.Date).IsGreaterThanOrEqualTo(startDate)
|
|
|
- .And(x => x.Date).IsLessThanOrEqualTo(endDate)
|
|
|
- .And(x=>x.LeaveRequest.ID).IsEqualTo(Guid.Empty)
|
|
|
- .And(x=>x.StandardLeave.ID).IsEqualTo(Guid.Empty),
|
|
|
- TimeSheetModel.Columns
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
+ var empids = _employees.ToArray(x => x.ID);
|
|
|
+
|
|
|
+ if (BackgroundType != CalendarBackgroundType.Roster)
|
|
|
+ {
|
|
|
query.Add(
|
|
|
- Filter<Assignment>.Where(x => x.Employee.ID).InList(empids)
|
|
|
+ Filter<TimeSheet>.Where(x => x.Employee.ID).InList(empids)
|
|
|
.And(x => x.Date).IsGreaterThanOrEqualTo(startDate)
|
|
|
- .And(x => x.Date).IsLessThanOrEqualTo(endDate),
|
|
|
- AssignmentModel.Columns,
|
|
|
- new SortOrder<Assignment>(x => x.Employee.ID).ThenBy(x => x.Date).ThenBy(x => x.Booked.Duration, SortDirection.Descending)
|
|
|
+ .And(x => x.Date).IsLessThanOrEqualTo(endDate)
|
|
|
+ .And(x=>x.LeaveRequest.ID).IsEqualTo(Guid.Empty)
|
|
|
+ .And(x=>x.StandardLeave.ID).IsEqualTo(Guid.Empty),
|
|
|
+ TimeSheetModel.Columns
|
|
|
);
|
|
|
-
|
|
|
- query.Add(
|
|
|
- Filter<LeaveRequest>
|
|
|
- .Where(x => x.Status).IsNotEqualTo(LeaveRequestStatus.Rejected)
|
|
|
- .And(x => x.Employee.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.Employee.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();
|
|
|
+ }
|
|
|
+
|
|
|
+ query.Add(
|
|
|
+ Filter<Assignment>.Where(x => x.Employee.ID).InList(empids)
|
|
|
+ .And(x => x.Date).IsGreaterThanOrEqualTo(startDate)
|
|
|
+ .And(x => x.Date).IsLessThanOrEqualTo(endDate),
|
|
|
+ AssignmentModel.Columns,
|
|
|
+ new SortOrder<Assignment>(x => x.Employee.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.Employee.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.Employee.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>();
|
|
|
+ _timesheets = (BackgroundType == CalendarBackgroundType.Roster)
|
|
|
+ ? []
|
|
|
+ : query.Get<TimeSheet>().ToArray<TimeSheet>();
|
|
|
|
|
|
- _leaverequests = query.Get<LeaveRequest>().ToArray<LeaveRequest>();
|
|
|
- _assignments = query.Get<Assignment>().ToList<Assignment>();
|
|
|
+ _leaverequests = query.Get<LeaveRequest>().ToArray<LeaveRequest>();
|
|
|
+ _assignments = query.Get<Assignment>().ToList<Assignment>();
|
|
|
|
|
|
- _standardleaves = query.Get<StandardLeave>().ToArray<StandardLeave>();
|
|
|
-
|
|
|
- LoadBackground();
|
|
|
-
|
|
|
- _appointments.Clear();
|
|
|
- LoadStandardLeaves(_appointments);
|
|
|
- LoadLeaveRequests(_appointments);
|
|
|
- LoadAssignments(_appointments);
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- CalendarControl.Dates = CoreUtils.Range(startDate, endDate, x => x.AddDays(1));
|
|
|
- CalendarControl.ItemsSource = _appointments;
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
|
|
|
- }
|
|
|
+ _standardleaves = query.Get<StandardLeave>().ToArray<StandardLeave>();
|
|
|
+
|
|
|
+ LoadBackground();
|
|
|
|
|
|
- bFirst = false;
|
|
|
+ _appointments.Clear();
|
|
|
+ LoadStandardLeaves(_appointments);
|
|
|
+ LoadLeaveRequests(_appointments);
|
|
|
+ LoadAssignments(_appointments);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ CalendarControl.Dates = CoreUtils.Range(startDate, endDate, x => x.AddDays(1));
|
|
|
+ CalendarControl.ItemsSource = _appointments;
|
|
|
}
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
|
|
|
+ }
|
|
|
+
|
|
|
+ bFirst = false;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public EmployeeRosterItem? GetRoster(Guid employeeid, DateTime date)
|
|
|
- {
|
|
|
- var employee = _employees.FirstOrDefault(x => x.ID == employeeid);
|
|
|
- if (employee is null) return null;
|
|
|
+ public EmployeeRosterItem? GetRoster(Guid employeeid, DateTime date)
|
|
|
+ {
|
|
|
+ var employee = _employees.FirstOrDefault(x => x.ID == employeeid);
|
|
|
+ if (employee is null) return null;
|
|
|
|
|
|
- var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employeeid), employee.RosterStart, date);
|
|
|
- return roster;
|
|
|
- }
|
|
|
+ var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employeeid), employee.RosterStart, date);
|
|
|
+ return roster;
|
|
|
+ }
|
|
|
|
|
|
- public bool GetActiveWindow(Guid employeeid, DateTime date, ref TimeSpan start, ref TimeSpan finish)
|
|
|
- {
|
|
|
- var result = false;
|
|
|
+ public bool GetActiveWindow(Guid employeeid, DateTime date, ref TimeSpan start, ref TimeSpan finish)
|
|
|
+ {
|
|
|
+ var result = false;
|
|
|
|
|
|
- foreach (var assignment in _assignments.Where(a => (a.Employee.ID == employeeid) && (a.Date) == date))
|
|
|
+ foreach (var assignment in _assignments.Where(a => (a.Employee.ID == employeeid) && (a.Date) == date))
|
|
|
+ {
|
|
|
+ result = true;
|
|
|
+ var curstart = AssignmentType switch
|
|
|
{
|
|
|
- result = true;
|
|
|
- var curstart = AssignmentType switch
|
|
|
- {
|
|
|
- CalendarAssignmentType.Booked => assignment.Booked.Start,
|
|
|
- CalendarAssignmentType.Actual => assignment.Actual.Start,
|
|
|
- _ => Assignment.EffectiveTime(assignment.Actual.Start, assignment.Booked.Start)
|
|
|
- };
|
|
|
-
|
|
|
- var curfinish = AssignmentType switch
|
|
|
- {
|
|
|
- CalendarAssignmentType.Booked => assignment.Booked.Finish,
|
|
|
- CalendarAssignmentType.Actual => assignment.Actual.Finish,
|
|
|
- _ => Assignment.EffectiveTime(
|
|
|
- assignment.Actual.Finish,
|
|
|
- Assignment.EffectiveTime(assignment.Actual.Start, assignment.Booked.Start)
|
|
|
- .Add(assignment.Booked.Duration)
|
|
|
- )
|
|
|
- };
|
|
|
-
|
|
|
- start = start > curstart ? curstart : start;
|
|
|
- finish = finish < curfinish ? curfinish : finish;
|
|
|
- }
|
|
|
+ CalendarAssignmentType.Booked => assignment.Booked.Start,
|
|
|
+ CalendarAssignmentType.Actual => assignment.Actual.Start,
|
|
|
+ _ => Assignment.EffectiveTime(assignment.Actual.Start, assignment.Booked.Start)
|
|
|
+ };
|
|
|
+
|
|
|
+ var curfinish = AssignmentType switch
|
|
|
+ {
|
|
|
+ CalendarAssignmentType.Booked => assignment.Booked.Finish,
|
|
|
+ CalendarAssignmentType.Actual => assignment.Actual.Finish,
|
|
|
+ _ => Assignment.EffectiveTime(
|
|
|
+ assignment.Actual.Finish,
|
|
|
+ Assignment.EffectiveTime(assignment.Actual.Start, assignment.Booked.Start)
|
|
|
+ .Add(assignment.Booked.Duration)
|
|
|
+ )
|
|
|
+ };
|
|
|
+
|
|
|
+ start = start > curstart ? curstart : start;
|
|
|
+ finish = finish < curfinish ? curfinish : finish;
|
|
|
+ }
|
|
|
|
|
|
- if ((BackgroundType == CalendarBackgroundType.Roster) ||
|
|
|
- ((BackgroundType == CalendarBackgroundType.Automatic) && (date >= DateTime.Today)))
|
|
|
+ if ((BackgroundType == CalendarBackgroundType.Roster) ||
|
|
|
+ ((BackgroundType == CalendarBackgroundType.Automatic) && (date >= DateTime.Today)))
|
|
|
+ {
|
|
|
+ var employee = _employees.FirstOrDefault(x => x.ID == employeeid);
|
|
|
+ if (employee != null)
|
|
|
{
|
|
|
- var employee = _employees.FirstOrDefault(x => x.ID == employeeid);
|
|
|
- if (employee != null)
|
|
|
+ var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employeeid), employee.RosterStart, date);
|
|
|
+ if (roster != null)
|
|
|
{
|
|
|
- var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employeeid), employee.RosterStart, date);
|
|
|
- if (roster != null)
|
|
|
+ var blocks = roster.GetBlocks(date, TimeSpan.MinValue, TimeSpan.MaxValue);
|
|
|
+ foreach (var block in blocks)
|
|
|
{
|
|
|
- var blocks = roster.GetBlocks(date, TimeSpan.MinValue, TimeSpan.MaxValue);
|
|
|
- foreach (var block in blocks)
|
|
|
- {
|
|
|
- start = start > block.Start ? block.Start : start;
|
|
|
- finish = finish < block.Finish ? block.Finish : finish;
|
|
|
- }
|
|
|
+ start = start > block.Start ? block.Start : start;
|
|
|
+ finish = finish < block.Finish ? block.Finish : finish;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- foreach (var timesheet in _timesheets.Where(t => (t.Employee.ID == employeeid) && (t.Date == date)))
|
|
|
- {
|
|
|
- result = true;
|
|
|
- var curstart = !timesheet.Approved.IsEmpty()
|
|
|
- ? timesheet.ApprovedStart
|
|
|
- : timesheet.Start;
|
|
|
- var curfinish = !timesheet.Approved.IsEmpty()
|
|
|
- ? timesheet.ApprovedFinish
|
|
|
- : timesheet.Finish;
|
|
|
- start = start > curstart ? curstart : start;
|
|
|
- finish = finish < curfinish ? curfinish : finish;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
}
|
|
|
-
|
|
|
- public Assignment[] GetAssignments(Guid employeeid, DateTime date)
|
|
|
+ else
|
|
|
{
|
|
|
- return _assignments.Where(a => (a.Employee.ID == employeeid) && (a.Date == date)).ToArray();
|
|
|
+ foreach (var timesheet in _timesheets.Where(t => (t.Employee.ID == employeeid) && (t.Date == date)))
|
|
|
+ {
|
|
|
+ result = true;
|
|
|
+ var curstart = !timesheet.Approved.IsEmpty()
|
|
|
+ ? timesheet.ApprovedStart
|
|
|
+ : timesheet.Start;
|
|
|
+ var curfinish = !timesheet.Approved.IsEmpty()
|
|
|
+ ? timesheet.ApprovedFinish
|
|
|
+ : timesheet.Finish;
|
|
|
+ start = start > curstart ? curstart : start;
|
|
|
+ finish = finish < curfinish ? curfinish : finish;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private void LoadBackground()
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Assignment[] GetAssignments(Guid employeeid, DateTime date)
|
|
|
+ {
|
|
|
+ return _assignments.Where(a => (a.Employee.ID == employeeid) && (a.Date == date)).ToArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LoadBackground()
|
|
|
+ {
|
|
|
+ var regions = new ObservableCollection<CalendarRegion>();
|
|
|
+ foreach (var employee in _employees)
|
|
|
{
|
|
|
- var regions = new ObservableCollection<CalendarRegion>();
|
|
|
- foreach (var employee in _employees)
|
|
|
+ for (var date = StartDate; date < EndDate; date = date.AddDays(1))
|
|
|
{
|
|
|
- for (var date = StartDate; date < EndDate; date = date.AddDays(1))
|
|
|
+ if ((BackgroundType == CalendarBackgroundType.Roster) ||
|
|
|
+ ((BackgroundType == CalendarBackgroundType.Automatic) && (date >= DateTime.Today)))
|
|
|
{
|
|
|
- if ((BackgroundType == CalendarBackgroundType.Roster) ||
|
|
|
- ((BackgroundType == CalendarBackgroundType.Automatic) && (date >= DateTime.Today)))
|
|
|
- {
|
|
|
- var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employee.ID), employee.RosterStart, date);
|
|
|
- if (roster != null)
|
|
|
- {
|
|
|
- var blocks = roster.GetBlocks(date, TimeSpan.FromSeconds(0), TimeSpan.FromDays(1));
|
|
|
- foreach (var block in blocks)
|
|
|
- {
|
|
|
- regions.Add(new CalendarRegion
|
|
|
- {
|
|
|
- Date = date,
|
|
|
- Column = employee,
|
|
|
- Start = block.Start,
|
|
|
- End = block.Finish,
|
|
|
- Background = Colors.Yellow.ToBrush(0.3)
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
+ var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employee.ID), employee.RosterStart, date);
|
|
|
+ if (roster != null)
|
|
|
{
|
|
|
- foreach (var timesheet in _timesheets.Where(t => (t.Employee.ID == employee.ID) && (t.Date == date)))
|
|
|
+ var blocks = roster.GetBlocks(date, TimeSpan.FromSeconds(0), TimeSpan.FromDays(1));
|
|
|
+ foreach (var block in blocks)
|
|
|
{
|
|
|
- var start = !timesheet.Approved.IsEmpty()
|
|
|
- ? timesheet.ApprovedStart
|
|
|
- : timesheet.Start;
|
|
|
- var finish = !timesheet.Approved.IsEmpty()
|
|
|
- ? timesheet.ApprovedFinish
|
|
|
- : timesheet.Finish;
|
|
|
- if(finish == default)
|
|
|
- {
|
|
|
- finish = TimeSpan.FromHours(24);
|
|
|
- }
|
|
|
regions.Add(new CalendarRegion
|
|
|
{
|
|
|
Date = date,
|
|
|
Column = employee,
|
|
|
- Start = start,
|
|
|
- End = finish,
|
|
|
- Background = (!timesheet.Approved.IsEmpty() ? Colors.LightGreen : Colors.LightSalmon).ToBrush(0.4),
|
|
|
+ Start = block.Start,
|
|
|
+ End = block.Finish,
|
|
|
+ Background = Colors.Yellow.ToBrush(0.3)
|
|
|
});
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- CalendarControl.Regions = regions;
|
|
|
- }
|
|
|
-
|
|
|
- private void LoadStandardLeaves(IList<ICalendarAppointment> appointments)
|
|
|
- {
|
|
|
- for (var date = StartDate; date < EndDate; date = date.AddDays(1))
|
|
|
- {
|
|
|
- var leaves = _standardleaves.Where(x =>
|
|
|
- (x.From <= date)
|
|
|
- && (x.To.Add(x.ToTime) > date)
|
|
|
- ).ToArray();
|
|
|
- foreach (var leave in leaves)
|
|
|
+ else
|
|
|
{
|
|
|
- foreach (var employee in _employees)
|
|
|
+ foreach (var timesheet in _timesheets.Where(t => (t.Employee.ID == employee.ID) && (t.Date == date)))
|
|
|
{
|
|
|
- var start = (date.Date == leave.From.Date) ? leave.FromTime : TimeSpan.FromSeconds(0);
|
|
|
- var finish = (date.Date == leave.To.Date) ? leave.ToTime : TimeSpan.FromDays(1).Subtract(TimeSpan.FromSeconds(1));
|
|
|
-
|
|
|
- var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employee.ID), employee.RosterStart, date);
|
|
|
- if (roster != null)
|
|
|
+ var start = !timesheet.Approved.IsEmpty()
|
|
|
+ ? timesheet.ApprovedStart
|
|
|
+ : timesheet.Start;
|
|
|
+ var finish = !timesheet.Approved.IsEmpty()
|
|
|
+ ? timesheet.ApprovedFinish
|
|
|
+ : timesheet.Finish;
|
|
|
+ if(finish == default)
|
|
|
{
|
|
|
- var blocks = roster.GetBlocks(date, start, finish);
|
|
|
- foreach (var block in blocks)
|
|
|
- {
|
|
|
- var appt = new StandardLeaveAppointment(leave, employee, block);
|
|
|
- appointments.Add(appt);
|
|
|
- }
|
|
|
+ finish = TimeSpan.FromHours(24);
|
|
|
}
|
|
|
- }
|
|
|
+ regions.Add(new CalendarRegion
|
|
|
+ {
|
|
|
+ Date = date,
|
|
|
+ Column = employee,
|
|
|
+ Start = start,
|
|
|
+ End = finish,
|
|
|
+ Background = (!timesheet.Approved.IsEmpty() ? Colors.LightGreen : Colors.LightSalmon).ToBrush(0.4),
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void LoadLeaveRequests(IList<ICalendarAppointment> appointments)
|
|
|
+ CalendarControl.Regions = regions;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LoadStandardLeaves(IList<ICalendarAppointment> appointments)
|
|
|
+ {
|
|
|
+ for (var date = StartDate; date < EndDate; date = date.AddDays(1))
|
|
|
{
|
|
|
- for (var date = StartDate; date < EndDate; date = date.AddDays(1))
|
|
|
+ var leaves = _standardleaves.Where(x =>
|
|
|
+ (x.From <= date)
|
|
|
+ && (x.To.Add(x.ToTime) > date)
|
|
|
+ ).ToArray();
|
|
|
+ foreach (var leave in leaves)
|
|
|
{
|
|
|
- var ids = _employees.ToArray(x => x.ID);
|
|
|
-
|
|
|
- var leaves = _leaverequests.Where(x =>
|
|
|
- (x.From <= date)
|
|
|
- && (x.To.Add(x.ToTime) > date)
|
|
|
- && ids.Contains(x.Employee.ID)
|
|
|
- ).ToArray();
|
|
|
-
|
|
|
- foreach (var leave in leaves)
|
|
|
+ foreach (var employee in _employees)
|
|
|
{
|
|
|
- var employee = _employees.FirstOrDefault(x => x.ID == leave.Employee.ID);
|
|
|
- if (employee is null) return;
|
|
|
-
|
|
|
+ var start = (date.Date == leave.From.Date) ? leave.FromTime : TimeSpan.FromSeconds(0);
|
|
|
+ var finish = (date.Date == leave.To.Date) ? leave.ToTime : TimeSpan.FromDays(1).Subtract(TimeSpan.FromSeconds(1));
|
|
|
+
|
|
|
var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employee.ID), employee.RosterStart, date);
|
|
|
if (roster != null)
|
|
|
{
|
|
|
- var start = (date.Date == leave.From.Date) ? leave.FromTime : TimeSpan.FromSeconds(0);
|
|
|
- var finish = (date.Date == leave.To.Date) ? leave.ToTime : TimeSpan.FromDays(1).Subtract(TimeSpan.FromSeconds(1));
|
|
|
var blocks = roster.GetBlocks(date, start, finish);
|
|
|
- foreach(var block in blocks)
|
|
|
+ foreach (var block in blocks)
|
|
|
{
|
|
|
- appointments.Add(new LeaveRequestAppointment(leave, employee, block));
|
|
|
+ var appt = new StandardLeaveAppointment(leave, employee, block);
|
|
|
+ appointments.Add(appt);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- private HashSet<Assignment> _savingAssignments = new();
|
|
|
-
|
|
|
- private AssignmentAppointment? LoadAssignment(Assignment assignment, IList<ICalendarAppointment> appointments)
|
|
|
- {
|
|
|
- var employee = _employees.FirstOrDefault(x => x.ID == assignment.Employee.ID);
|
|
|
- if (employee is null) return null;
|
|
|
-
|
|
|
- var model = new AssignmentAppointment(assignment, employee, AssignmentType);
|
|
|
- model.OnUpdate += () =>
|
|
|
- {
|
|
|
- if (_savingAssignments.Add(assignment))
|
|
|
- {
|
|
|
- Dispatcher.BeginInvoke(() =>
|
|
|
- {
|
|
|
- _savingAssignments.Remove(assignment);
|
|
|
- Client.SaveAsync(assignment, "Edited by user").LogIfFail();
|
|
|
- });
|
|
|
- }
|
|
|
- };
|
|
|
- model.EmployeeChanged += (o, e) =>
|
|
|
- {
|
|
|
- model.Employee = _employees.FirstOrDefault(x => x.ID == assignment.Employee.ID);
|
|
|
- };
|
|
|
- appointments.Add(model);
|
|
|
- return model;
|
|
|
- }
|
|
|
-
|
|
|
- private void LoadAssignments(IList<ICalendarAppointment> appointments)
|
|
|
- {
|
|
|
- foreach (var assignment in _assignments)
|
|
|
- LoadAssignment(assignment, appointments);
|
|
|
- }
|
|
|
-
|
|
|
- public DataModel DataModel(Selection selection)
|
|
|
- {
|
|
|
- var ids = _assignments.Select(x => x.ID).ToArray();
|
|
|
- return new AutoDataModel<Assignment>(Filter<Assignment>.Where(x => x.ID).InList(ids));
|
|
|
- }
|
|
|
-
|
|
|
- private static T CheckGrid<T>([NotNull] ref T? grid) where T : new()
|
|
|
- {
|
|
|
- grid ??= new T();
|
|
|
- return grid;
|
|
|
- }
|
|
|
-
|
|
|
- private void ReloadColumns()
|
|
|
- {
|
|
|
- CalendarControl.Columns = _employees.OrderBy(x => x.Name);
|
|
|
- bColumnsLoaded = true;
|
|
|
- }
|
|
|
-
|
|
|
- #region Block
|
|
|
-
|
|
|
- private (TimeSpan Start, TimeSpan End)? GetFillBlock(DateTime date, object? column, TimeSpan time)
|
|
|
+ private void LoadLeaveRequests(IList<ICalendarAppointment> appointments)
|
|
|
+ {
|
|
|
+ for (var date = StartDate; date < EndDate; date = date.AddDays(1))
|
|
|
{
|
|
|
- if (column is not Employee employee) return null;
|
|
|
-
|
|
|
- if ((BackgroundType == CalendarBackgroundType.Roster) ||
|
|
|
- ((BackgroundType == CalendarBackgroundType.Automatic) && (date >= DateTime.Today)))
|
|
|
- {
|
|
|
- var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employee.ID), employee.RosterStart, date);
|
|
|
- if (roster is null) return null;
|
|
|
+ var ids = _employees.ToArray(x => x.ID);
|
|
|
|
|
|
- var blocks = roster.GetBlocks(date, TimeSpan.Zero, TimeSpan.FromDays(1));
|
|
|
- var block = blocks.FirstOrDefault(x => x.Start <= time && time <= x.Finish);
|
|
|
- if (block is null) return null;
|
|
|
+ var leaves = _leaverequests.Where(x =>
|
|
|
+ (x.From <= date)
|
|
|
+ && (x.To.Add(x.ToTime) > date)
|
|
|
+ && ids.Contains(x.Employee.ID)
|
|
|
+ ).ToArray();
|
|
|
|
|
|
- return (block.Start, block.Finish);
|
|
|
- }
|
|
|
- else
|
|
|
+ foreach (var leave in leaves)
|
|
|
{
|
|
|
- foreach (var timesheet in _timesheets.Where(t => (t.Employee.ID == employee.ID) && (t.Date == date)))
|
|
|
+ var employee = _employees.FirstOrDefault(x => x.ID == leave.Employee.ID);
|
|
|
+ if (employee is null) return;
|
|
|
+
|
|
|
+ var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employee.ID), employee.RosterStart, date);
|
|
|
+ if (roster != null)
|
|
|
{
|
|
|
- var start = !timesheet.Approved.IsEmpty()
|
|
|
- ? timesheet.ApprovedStart
|
|
|
- : timesheet.Start;
|
|
|
- var finish = !timesheet.Approved.IsEmpty()
|
|
|
- ? timesheet.ApprovedFinish
|
|
|
- : timesheet.Finish;
|
|
|
- if(finish == default)
|
|
|
+ var start = (date.Date == leave.From.Date) ? leave.FromTime : TimeSpan.FromSeconds(0);
|
|
|
+ var finish = (date.Date == leave.To.Date) ? leave.ToTime : TimeSpan.FromDays(1).Subtract(TimeSpan.FromSeconds(1));
|
|
|
+ var blocks = roster.GetBlocks(date, start, finish);
|
|
|
+ foreach(var block in blocks)
|
|
|
{
|
|
|
- finish = TimeSpan.FromHours(24);
|
|
|
+ appointments.Add(new LeaveRequestAppointment(leave, employee, block));
|
|
|
}
|
|
|
- if(start <= time && time <= finish)
|
|
|
- {
|
|
|
- return (start, finish);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- private TimeSpan? GetFillBlockStart(DateTime date, object? column, TimeSpan time)
|
|
|
- {
|
|
|
- var block = GetFillBlock(date, column, time);
|
|
|
- return block?.Start;
|
|
|
- }
|
|
|
+ private HashSet<Assignment> _savingAssignments = new();
|
|
|
+
|
|
|
+ private AssignmentAppointment? LoadAssignment(Assignment assignment, IList<ICalendarAppointment> appointments)
|
|
|
+ {
|
|
|
+ var employee = _employees.FirstOrDefault(x => x.ID == assignment.Employee.ID);
|
|
|
+ if (employee is null) return null;
|
|
|
|
|
|
- private TimeSpan? GetFillBlockEnd(DateTime date, object? column, TimeSpan time)
|
|
|
+ var model = new AssignmentAppointment(assignment, employee, AssignmentType);
|
|
|
+ model.OnUpdate += () =>
|
|
|
{
|
|
|
- var block = GetFillBlock(date, column, time);
|
|
|
- return block?.End;
|
|
|
- }
|
|
|
-
|
|
|
- private void Calendar_BlockHeld(object sender, CalendarBlockEventArgs e)
|
|
|
+ if (_savingAssignments.Add(assignment))
|
|
|
+ {
|
|
|
+ Dispatcher.BeginInvoke(() =>
|
|
|
+ {
|
|
|
+ _savingAssignments.Remove(assignment);
|
|
|
+ Client.SaveAsync(assignment, "Edited by user").LogIfFail();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
+ model.EmployeeChanged += (o, e) =>
|
|
|
{
|
|
|
- OpenContextMenu(sender, e, false);
|
|
|
- }
|
|
|
+ model.Employee = _employees.FirstOrDefault(x => x.ID == assignment.Employee.ID);
|
|
|
+ };
|
|
|
+ appointments.Add(model);
|
|
|
+ return model;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LoadAssignments(IList<ICalendarAppointment> appointments)
|
|
|
+ {
|
|
|
+ foreach (var assignment in _assignments)
|
|
|
+ LoadAssignment(assignment, appointments);
|
|
|
+ }
|
|
|
+
|
|
|
+ public DataModel DataModel(Selection selection)
|
|
|
+ {
|
|
|
+ var ids = _assignments.Select(x => x.ID).ToArray();
|
|
|
+ return new AutoDataModel<Assignment>(Filter<Assignment>.Where(x => x.ID).InList(ids));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static T CheckGrid<T>([NotNull] ref T? grid) where T : new()
|
|
|
+ {
|
|
|
+ grid ??= new T();
|
|
|
+ return grid;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ReloadColumns()
|
|
|
+ {
|
|
|
+ CalendarControl.Columns = _employees.OrderBy(x => x.Name);
|
|
|
+ bColumnsLoaded = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ #region Block
|
|
|
+
|
|
|
+ private (TimeSpan Start, TimeSpan End)? GetFillBlock(DateTime date, object? column, TimeSpan time)
|
|
|
+ {
|
|
|
+ if (column is not Employee employee) return null;
|
|
|
|
|
|
- public enum ContextMenuItems
|
|
|
+ if ((BackgroundType == CalendarBackgroundType.Roster) ||
|
|
|
+ ((BackgroundType == CalendarBackgroundType.Automatic) && (date >= DateTime.Today)))
|
|
|
{
|
|
|
- Create,
|
|
|
- Fill
|
|
|
- }
|
|
|
+ var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employee.ID), employee.RosterStart, date);
|
|
|
+ if (roster is null) return null;
|
|
|
|
|
|
- public CalendarTimeSlot FillSlot(CalendarBlockEventArgs e, CalendarTimeSlot slot)
|
|
|
+ var blocks = roster.GetBlocks(date, TimeSpan.Zero, TimeSpan.FromDays(1));
|
|
|
+ var block = blocks.FirstOrDefault(x => x.Start <= time && time <= x.Finish);
|
|
|
+ if (block is null) return null;
|
|
|
+
|
|
|
+ return (block.Start, block.Finish);
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- if(CalendarControl.GetEmptySpace(e.Point, out var start, out var end))
|
|
|
+ foreach (var timesheet in _timesheets.Where(t => (t.Employee.ID == employee.ID) && (t.Date == date)))
|
|
|
{
|
|
|
- if(start is null || end is null)
|
|
|
+ var start = !timesheet.Approved.IsEmpty()
|
|
|
+ ? timesheet.ApprovedStart
|
|
|
+ : timesheet.Start;
|
|
|
+ var finish = !timesheet.Approved.IsEmpty()
|
|
|
+ ? timesheet.ApprovedFinish
|
|
|
+ : timesheet.Finish;
|
|
|
+ if(finish == default)
|
|
|
{
|
|
|
- var block = GetFillBlock(e.Date, e.Column, CalendarControl.GetTime(e.Point));
|
|
|
- return new(slot.EmployeeID, e.Date, start ?? block?.Start ?? e.Start, end ?? block?.End ?? e.End);
|
|
|
+ finish = TimeSpan.FromHours(24);
|
|
|
}
|
|
|
- else
|
|
|
+ if(start <= time && time <= finish)
|
|
|
{
|
|
|
- return new(slot.EmployeeID, e.Date, start.Value, end.Value);
|
|
|
+ return (start, finish);
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private TimeSpan? GetFillBlockStart(DateTime date, object? column, TimeSpan time)
|
|
|
+ {
|
|
|
+ var block = GetFillBlock(date, column, time);
|
|
|
+ return block?.Start;
|
|
|
+ }
|
|
|
+
|
|
|
+ private TimeSpan? GetFillBlockEnd(DateTime date, object? column, TimeSpan time)
|
|
|
+ {
|
|
|
+ var block = GetFillBlock(date, column, time);
|
|
|
+ return block?.End;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Calendar_BlockHeld(object sender, CalendarBlockEventArgs e)
|
|
|
+ {
|
|
|
+ OpenContextMenu(sender, e, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ public enum ContextMenuItems
|
|
|
+ {
|
|
|
+ Create,
|
|
|
+ Fill
|
|
|
+ }
|
|
|
+
|
|
|
+ public CalendarTimeSlot FillSlot(CalendarBlockEventArgs e, CalendarTimeSlot slot)
|
|
|
+ {
|
|
|
+ if(CalendarControl.GetEmptySpace(e.Point, out var start, out var end))
|
|
|
+ {
|
|
|
+ if(start is null || end is null)
|
|
|
+ {
|
|
|
+ var block = GetFillBlock(e.Date, e.Column, CalendarControl.GetTime(e.Point));
|
|
|
+ return new(slot.EmployeeID, e.Date, start ?? block?.Start ?? e.Start, end ?? block?.End ?? e.End);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- return slot;
|
|
|
+ return new(slot.EmployeeID, e.Date, start.Value, end.Value);
|
|
|
}
|
|
|
}
|
|
|
- private void Calendar_BlockRightClicked(object sender, CalendarBlockEventArgs e)
|
|
|
+ else
|
|
|
{
|
|
|
- OpenContextMenu(sender, e, true);
|
|
|
+ return slot;
|
|
|
}
|
|
|
+ }
|
|
|
+ private void Calendar_BlockRightClicked(object sender, CalendarBlockEventArgs e)
|
|
|
+ {
|
|
|
+ OpenContextMenu(sender, e, true);
|
|
|
+ }
|
|
|
|
|
|
- private void OpenContextMenu(object sender, CalendarBlockEventArgs e, bool allowFill)
|
|
|
+ private void OpenContextMenu(object sender, CalendarBlockEventArgs e, bool allowFill)
|
|
|
+ {
|
|
|
+ object? value;
|
|
|
+ if(e.Value is AssignmentAppointment appointment)
|
|
|
{
|
|
|
- object? value;
|
|
|
- if(e.Value is AssignmentAppointment appointment)
|
|
|
+ if (appointment.Model.Meeting.Link.ID != Guid.Empty)
|
|
|
{
|
|
|
- if (appointment.Model.Meeting.Link.ID != Guid.Empty)
|
|
|
- {
|
|
|
- e.Menu.AddItem("Edit Meeting", null, appointment.Model, EditMeeting);
|
|
|
- }
|
|
|
- else
|
|
|
+ e.Menu.AddItem("Edit Meeting", null, appointment.Model, EditMeeting);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ e.Menu.AddItem("Edit Assignment", null, appointment.Model, EditAssignment);
|
|
|
+ e.Menu.AddSeparator();
|
|
|
+ e.Menu.AddItem("Copy Assignment", null, appointment.Model, CopyAssignment);
|
|
|
+ e.Menu.AddSeparator();
|
|
|
+ e.Menu.AddItem("Fill Available Time", null, () =>
|
|
|
{
|
|
|
- e.Menu.AddItem("Edit Assignment", null, appointment.Model, EditAssignment);
|
|
|
- e.Menu.AddSeparator();
|
|
|
- e.Menu.AddItem("Copy Assignment", null, appointment.Model, CopyAssignment);
|
|
|
- e.Menu.AddSeparator();
|
|
|
- e.Menu.AddItem("Fill Available Time", null, () =>
|
|
|
+ if(CalendarControl.GetEmptySpace(e.Point, out var start, out var end, time: e.Start, exclude: [appointment]))
|
|
|
{
|
|
|
- if(CalendarControl.GetEmptySpace(e.Point, out var start, out var end, time: e.Start, exclude: [appointment]))
|
|
|
+ var time = AssignmentType switch
|
|
|
{
|
|
|
- var time = AssignmentType switch
|
|
|
- {
|
|
|
- CalendarAssignmentType.Automatic or CalendarAssignmentType.Actual => appointment.Model.Actual,
|
|
|
- CalendarAssignmentType.Booked => appointment.Model.Booked,
|
|
|
- _ => throw new InvalidEnumException<CalendarAssignmentType>(AssignmentType)
|
|
|
- };
|
|
|
- if(start is null || end is null)
|
|
|
- {
|
|
|
- var block = GetFillBlock(e.Date, e.Column, e.Start);
|
|
|
- time.Start = start ?? block?.Start ?? time.Start;
|
|
|
- time.Finish = end ?? block?.End ?? time.Finish;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- time.Start = start.Value;
|
|
|
- time.Finish = end.Value;
|
|
|
- }
|
|
|
- Client.Save(appointment.Model, "Adjusted to fill time");
|
|
|
+ CalendarAssignmentType.Automatic or CalendarAssignmentType.Actual => appointment.Model.Actual,
|
|
|
+ CalendarAssignmentType.Booked => appointment.Model.Booked,
|
|
|
+ _ => throw new InvalidEnumException<CalendarAssignmentType>(AssignmentType)
|
|
|
+ };
|
|
|
+ if(start is null || end is null)
|
|
|
+ {
|
|
|
+ var block = GetFillBlock(e.Date, e.Column, e.Start);
|
|
|
+ time.Start = start ?? block?.Start ?? time.Start;
|
|
|
+ time.Finish = end ?? block?.End ?? time.Finish;
|
|
|
}
|
|
|
- });
|
|
|
- }
|
|
|
- e.Menu.AddSeparatorIfNeeded();
|
|
|
-
|
|
|
- CreateDigitalFormsMenu(e.Menu, appointment);
|
|
|
-
|
|
|
- e.Menu.AddSeparatorIfNeeded();
|
|
|
- if (appointment.Model.Meeting.Link.ID != Guid.Empty)
|
|
|
- {
|
|
|
- e.Menu.AddItem("Delete Meeting", null, appointment.Model, DeleteMeeting);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- e.Menu.AddItem("Delete Assignment", null, appointment.Model, DeleteAssignment);
|
|
|
- }
|
|
|
-
|
|
|
- value = appointment.Model;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ time.Start = start.Value;
|
|
|
+ time.Finish = end.Value;
|
|
|
+ }
|
|
|
+ Client.Save(appointment.Model, "Adjusted to fill time");
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
- 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.AddSeparatorIfNeeded();
|
|
|
+
|
|
|
+ CreateDigitalFormsMenu(e.Menu, appointment);
|
|
|
|
|
|
- value = leaveAppointment.Model;
|
|
|
+ e.Menu.AddSeparatorIfNeeded();
|
|
|
+ if (appointment.Model.Meeting.Link.ID != Guid.Empty)
|
|
|
+ {
|
|
|
+ e.Menu.AddItem("Delete Meeting", null, appointment.Model, DeleteMeeting);
|
|
|
}
|
|
|
- else if(e.Value is StandardLeaveAppointment standardLeaveAppointment)
|
|
|
+ else
|
|
|
{
|
|
|
- if (Security.CanView<StandardLeave>())
|
|
|
- {
|
|
|
- e.Menu.AddItem(
|
|
|
- Security.CanEdit<StandardLeave>() ? "Edit Standard Leave" : "View Standard Leave",
|
|
|
- null,
|
|
|
- standardLeaveAppointment.Model,
|
|
|
- EditStandardLeave);
|
|
|
- }
|
|
|
+ e.Menu.AddItem("Delete Assignment", null, appointment.Model, DeleteAssignment);
|
|
|
+ }
|
|
|
|
|
|
- value = standardLeaveAppointment.Model;
|
|
|
+ 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);
|
|
|
}
|
|
|
- else if (e.Value is null)
|
|
|
+
|
|
|
+ value = leaveAppointment.Model;
|
|
|
+ }
|
|
|
+ else if(e.Value is StandardLeaveAppointment standardLeaveAppointment)
|
|
|
+ {
|
|
|
+ if (Security.CanView<StandardLeave>())
|
|
|
{
|
|
|
- if (e.Column is not Employee employee) return;
|
|
|
+ e.Menu.AddItem(
|
|
|
+ Security.CanEdit<StandardLeave>() ? "Edit Standard Leave" : "View Standard Leave",
|
|
|
+ null,
|
|
|
+ standardLeaveAppointment.Model,
|
|
|
+ EditStandardLeave);
|
|
|
+ }
|
|
|
|
|
|
- var slot = new CalendarTimeSlot(employee.ID, e.Date, e.Start, e.End);
|
|
|
+ value = standardLeaveAppointment.Model;
|
|
|
+ }
|
|
|
+ else if (e.Value is null)
|
|
|
+ {
|
|
|
+ if (e.Column is not Employee employee) return;
|
|
|
|
|
|
- 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);
|
|
|
+ var slot = new CalendarTimeSlot(employee.ID, e.Date, e.Start, e.End);
|
|
|
|
|
|
- if (allowFill)
|
|
|
+ var createmenu = e.Menu.AddItem("Create...", null, null)
|
|
|
+ .WithName($"Menu_{nameof(ContextMenuItems.Create)}");
|
|
|
+ createmenu.AddItem("New Assignment", null, slot, slot => CreateAssignment(slot));
|
|
|
+
|
|
|
+ void AddNewMeetingItem(MenuItem item, Func<CalendarTimeSlot> getSlot)
|
|
|
+ {
|
|
|
+ if(MeetingTemplates.Length == 0)
|
|
|
{
|
|
|
- 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)));
|
|
|
+ item.AddItem("New Meeting", null, () => CreateMeeting(getSlot(), null));
|
|
|
}
|
|
|
-
|
|
|
- if (_copiedmodel != null)
|
|
|
+ else
|
|
|
{
|
|
|
- e.Menu.AddSeparator();
|
|
|
- e.Menu.AddItem("Paste Assignment", null, slot, slot => PasteAssignment(slot, _copiedmodel));
|
|
|
+ var newMeetingItem = item.AddItem("New Meeting", null, null);
|
|
|
+ newMeetingItem.AddItem("Blank Meeting", null, () => CreateMeeting(getSlot(), null));
|
|
|
+ newMeetingItem.AddSeparator();
|
|
|
+ foreach(var template in MeetingTemplates)
|
|
|
+ {
|
|
|
+ newMeetingItem.AddItem(template.Title, null, () => CreateMeeting(getSlot(), template));
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- value = slot;
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ AddNewMeetingItem(createmenu, () => slot);
|
|
|
+
|
|
|
+ if (allowFill)
|
|
|
{
|
|
|
- value = null;
|
|
|
+ var fillMenu = e.Menu.AddItem("Fill...", null, null)
|
|
|
+ .WithName($"Menu_{nameof(ContextMenuItems.Fill)}");
|
|
|
+ fillMenu.AddItem("New Assignment", null, () => CreateAssignment(FillSlot(e, slot)));
|
|
|
+ AddNewMeetingItem(fillMenu, () => FillSlot(e, slot));
|
|
|
}
|
|
|
|
|
|
- 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);
|
|
|
+ if (_copiedmodel != null)
|
|
|
+ {
|
|
|
+ e.Menu.AddSeparator();
|
|
|
+ e.Menu.AddItem("Paste Assignment", null, slot, slot => PasteAssignment(slot, _copiedmodel));
|
|
|
+ }
|
|
|
|
|
|
- CustomiseContextMenu?.Invoke(e.Menu, new CalendarDataMenuEventArgs(value, e));
|
|
|
+ value = slot;
|
|
|
}
|
|
|
-
|
|
|
- private static void CreateDigitalFormsMenu(ContextMenu menu, AssignmentAppointment appointment)
|
|
|
+ else
|
|
|
{
|
|
|
- var digitalForms = menu.AddItem("Digital Forms", null, null);
|
|
|
- DynamicGridUtils.PopulateFormMenu<AssignmentForm, Assignment, AssignmentLink>(
|
|
|
- digitalForms,
|
|
|
- appointment.Model.ID,
|
|
|
- () => new Client<Assignment>().Load(Filter<Assignment>.Where(x => x.ID).IsEqualTo(appointment.Model.ID)).First(),
|
|
|
- false);
|
|
|
+ value = null;
|
|
|
}
|
|
|
|
|
|
- public void CreateMeeting(CalendarTimeSlot slot)
|
|
|
- {
|
|
|
- var meeting = new Meeting
|
|
|
- {
|
|
|
- Date = slot.Date
|
|
|
- };
|
|
|
+ e.Menu.AddSeparatorIfNeeded();
|
|
|
|
|
|
- meeting.Time.Start = slot.Start;
|
|
|
- meeting.Time.Finish = slot.End;
|
|
|
-
|
|
|
- ItemCreated?.Invoke(this, new CalendarDataEventArgs(meeting));
|
|
|
-
|
|
|
- var args = new CalendarHandledEventArgs<Meeting>(meeting);
|
|
|
- ItemEditing?.Invoke(this, args);
|
|
|
-
|
|
|
- if (args.Status == CalendarHandledStatus.Cancel)
|
|
|
- return;
|
|
|
- if (args.Status == CalendarHandledStatus.Handled)
|
|
|
- {
|
|
|
- Refresh();
|
|
|
- return;
|
|
|
- }
|
|
|
- CheckGrid(ref mg);
|
|
|
- var items = new[] { meeting };
|
|
|
- bool bOK = mg.EditItems(
|
|
|
- items,
|
|
|
- (type) =>
|
|
|
- {
|
|
|
- if (type == typeof(Assignment))
|
|
|
- return LoadMeetingEmployees(slot.EmployeeID);
|
|
|
- else if (type == typeof(MeetingItem))
|
|
|
- return LoadMeetingItems();
|
|
|
- return null;
|
|
|
- },
|
|
|
- true
|
|
|
- );
|
|
|
- if (bOK)
|
|
|
- Refresh();
|
|
|
- }
|
|
|
+ e.Menu.AddItem("Zoom In", null, ZoomIn);
|
|
|
+ e.Menu.AddItem("Zoom Out", null, ZoomOut, enabled: Zoom > 100);
|
|
|
+ e.Menu.AddItem("Reset Zoom", null, ResetZoom);
|
|
|
|
|
|
- private static CoreTable LoadMeetingEmployees(Guid employeeid)
|
|
|
- {
|
|
|
- var result = new CoreTable();
|
|
|
- result.LoadColumns(typeof(Assignment));
|
|
|
- var assignment = new Assignment();
|
|
|
- LookupFactory.DoLookup<Assignment, Employee, EmployeeLink>(assignment, x => x.Employee, employeeid);
|
|
|
- result.LoadRows([assignment]);
|
|
|
- return result;
|
|
|
- }
|
|
|
+ CustomiseContextMenu?.Invoke(e.Menu, new CalendarDataMenuEventArgs(value, e));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void CreateDigitalFormsMenu(ContextMenu menu, AssignmentAppointment appointment)
|
|
|
+ {
|
|
|
+ var digitalForms = menu.AddItem("Digital Forms", null, null);
|
|
|
+ DynamicGridUtils.PopulateFormMenu<AssignmentForm, Assignment, AssignmentLink>(
|
|
|
+ digitalForms,
|
|
|
+ appointment.Model.ID,
|
|
|
+ () => new Client<Assignment>().Load(Filter<Assignment>.Where(x => x.ID).IsEqualTo(appointment.Model.ID)).First(),
|
|
|
+ false);
|
|
|
+ }
|
|
|
|
|
|
- private static CoreTable LoadMeetingItems()
|
|
|
+ public void CreateMeeting(CalendarTimeSlot slot, MeetingTemplate? template)
|
|
|
+ {
|
|
|
+ var meeting = new Meeting
|
|
|
{
|
|
|
- var result = new CoreTable();
|
|
|
- result.LoadColumns(typeof(MeetingItem));
|
|
|
- return result;
|
|
|
- }
|
|
|
+ Date = slot.Date
|
|
|
+ };
|
|
|
+
|
|
|
+ meeting.Time.Start = slot.Start;
|
|
|
+ meeting.Time.Finish = slot.End;
|
|
|
|
|
|
- private void EditMeeting(Assignment model)
|
|
|
+ if(template is not null)
|
|
|
{
|
|
|
- CheckGrid(ref mg);
|
|
|
-
|
|
|
- if (DynamicGridUtils.EditEntity<Meeting>(model.Meeting.Link.ID, out var meeting))
|
|
|
- {
|
|
|
- ItemChanged?.Invoke(this, new CalendarDataEventArgs(meeting));
|
|
|
- Refresh();
|
|
|
- }
|
|
|
+ meeting.Title = template.Title;
|
|
|
+ meeting.Description = template.Description;
|
|
|
+ meeting.Activity.CopyFrom(template.Activity);
|
|
|
}
|
|
|
|
|
|
- private void DeleteMeeting(Assignment model)
|
|
|
+ ItemCreated?.Invoke(this, new CalendarDataEventArgs(meeting));
|
|
|
+
|
|
|
+ var args = new CalendarHandledEventArgs<Meeting>(meeting);
|
|
|
+ ItemEditing?.Invoke(this, args);
|
|
|
+
|
|
|
+ if (args.Status == CalendarHandledStatus.Cancel)
|
|
|
+ return;
|
|
|
+ if (args.Status == CalendarHandledStatus.Handled)
|
|
|
{
|
|
|
- if (!MessageWindow.ShowYesNo("Are you sure you wish to delete this meeting?", "Confirm Delete"))
|
|
|
- return;
|
|
|
-
|
|
|
- var meeting = new Meeting { ID = model.Meeting.Link.ID };
|
|
|
- Client.Delete(meeting, "Meeting Deleted from Scheduler");
|
|
|
- ItemChanged?.Invoke(this, new CalendarDataEventArgs(meeting));
|
|
|
Refresh();
|
|
|
- SelectionChanged?.Invoke(this, new CalendarDataEventArgs(null));
|
|
|
+ return;
|
|
|
}
|
|
|
-
|
|
|
- public Assignment? CreateAssignment(CalendarTimeSlot slot)
|
|
|
+ if (DynamicGridUtils.EditEntity(meeting))
|
|
|
{
|
|
|
- var ass = new Assignment
|
|
|
- {
|
|
|
- Date = slot.Date
|
|
|
- };
|
|
|
-
|
|
|
- ass.Booked.Start = slot.Start;
|
|
|
- ass.Booked.Finish = slot.End;
|
|
|
- if ((AssignmentType == CalendarAssignmentType.Actual) || ((AssignmentType == CalendarAssignmentType.Automatic) && (ass.Date <= DateTime.Today)))
|
|
|
+ var makeAssignment = true;
|
|
|
+ if(template is not null)
|
|
|
{
|
|
|
- ass.Actual.Start = ass.Booked.Start;
|
|
|
- ass.Actual.Finish = ass.Booked.Finish;
|
|
|
+ MeetingGrid.InitialiseMeetingChildrenFromTemplate(meeting, template, out var assignments);
|
|
|
+ makeAssignment = !assignments.Any(x => x.Employee.ID == slot.EmployeeID);
|
|
|
}
|
|
|
-
|
|
|
- ass.Employee.ID = slot.EmployeeID;
|
|
|
|
|
|
- ItemCreated?.Invoke(this, new CalendarDataEventArgs(ass));
|
|
|
-
|
|
|
- var args = new CalendarHandledEventArgs<Assignment>(ass);
|
|
|
- ItemEditing?.Invoke(this, args);
|
|
|
- if (args.Status == CalendarHandledStatus.Cancel)
|
|
|
- return null;
|
|
|
-
|
|
|
- if ((args.Status == CalendarHandledStatus.Handled) || CheckGrid(ref ag).EditItems([ass]))
|
|
|
+ if (makeAssignment)
|
|
|
{
|
|
|
- _assignments.Add(ass);
|
|
|
- CalendarControl.SelectItem(LoadAssignment(ass, _appointments));
|
|
|
- _copiedmodel = null;
|
|
|
+ var assignment = new Assignment();
|
|
|
+ assignment.Employee.ID = slot.EmployeeID;
|
|
|
+ assignment.Meeting.Link.CopyFrom(meeting);
|
|
|
+ assignment.Meeting.IsAdmin = true;
|
|
|
+ assignment.Date = meeting.Date;
|
|
|
+ assignment.Booked.Start = meeting.Time.Start;
|
|
|
+ assignment.Booked.Finish = meeting.Time.Finish;
|
|
|
+ assignment.Activity.CopyFrom(meeting.Activity);
|
|
|
+ assignment.Title = meeting.Title;
|
|
|
+ assignment.Description = meeting.Description;
|
|
|
+ Client.Save(assignment, "Created Assignment from meeting.");
|
|
|
}
|
|
|
|
|
|
- return ass;
|
|
|
-
|
|
|
+ Refresh();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- private void EditAssignment(Assignment model)
|
|
|
+ private void EditMeeting(Assignment model)
|
|
|
+ {
|
|
|
+ if (DynamicGridUtils.EditEntity<Meeting>(model.Meeting.Link.ID, out var meeting))
|
|
|
{
|
|
|
- var grid = CheckGrid(ref ag);
|
|
|
- Client.EnsureColumns(model, grid.LoadEditorColumns());
|
|
|
-
|
|
|
- if (DynamicGridUtils.EditEntity<Assignment>(model))
|
|
|
- {
|
|
|
- ItemChanged?.Invoke(this, new CalendarDataEventArgs(model));
|
|
|
- // Refresh();
|
|
|
- }
|
|
|
+ ItemChanged?.Invoke(this, new CalendarDataEventArgs(meeting));
|
|
|
+ Refresh();
|
|
|
}
|
|
|
-
|
|
|
- private void DeleteAssignment(Assignment model)
|
|
|
+ }
|
|
|
+
|
|
|
+ private void DeleteMeeting(Assignment model)
|
|
|
+ {
|
|
|
+ if (!MessageWindow.ShowYesNo("Are you sure you wish to delete this meeting?", "Confirm Delete"))
|
|
|
+ return;
|
|
|
+
|
|
|
+ var meeting = new Meeting { ID = model.Meeting.Link.ID };
|
|
|
+ Client.Delete(meeting, "Meeting Deleted from Scheduler");
|
|
|
+ ItemChanged?.Invoke(this, new CalendarDataEventArgs(meeting));
|
|
|
+ Refresh();
|
|
|
+ SelectionChanged?.Invoke(this, new CalendarDataEventArgs(null));
|
|
|
+ }
|
|
|
+
|
|
|
+ public Assignment? CreateAssignment(CalendarTimeSlot slot)
|
|
|
+ {
|
|
|
+ var ass = new Assignment
|
|
|
{
|
|
|
- if (!MessageWindow.ShowYesNo("Are you sure you wish to delete this assignment?", "Confirm Delete"))
|
|
|
- return;
|
|
|
-
|
|
|
- var ass = new Assignment { ID = model.ID };
|
|
|
- Client.Delete(ass, "Assignment Deleted from Scheduler");
|
|
|
- ItemChanged?.Invoke(this, new CalendarDataEventArgs(ass));
|
|
|
- Refresh();
|
|
|
- SelectionChanged?.Invoke(this, new CalendarDataEventArgs(null));
|
|
|
+ Date = slot.Date
|
|
|
+ };
|
|
|
|
|
|
+ ass.Booked.Start = slot.Start;
|
|
|
+ ass.Booked.Finish = slot.End;
|
|
|
+ if ((AssignmentType == CalendarAssignmentType.Actual) || ((AssignmentType == CalendarAssignmentType.Automatic) && (ass.Date <= DateTime.Today)))
|
|
|
+ {
|
|
|
+ ass.Actual.Start = ass.Booked.Start;
|
|
|
+ ass.Actual.Finish = ass.Booked.Finish;
|
|
|
}
|
|
|
|
|
|
- private Assignment? _copiedmodel;
|
|
|
+ ass.Employee.ID = slot.EmployeeID;
|
|
|
|
|
|
- private void CopyAssignment(Assignment model)
|
|
|
+ ItemCreated?.Invoke(this, new CalendarDataEventArgs(ass));
|
|
|
+
|
|
|
+ var args = new CalendarHandledEventArgs<Assignment>(ass);
|
|
|
+ ItemEditing?.Invoke(this, args);
|
|
|
+ if (args.Status == CalendarHandledStatus.Cancel)
|
|
|
+ return null;
|
|
|
+
|
|
|
+ if ((args.Status == CalendarHandledStatus.Handled) || CheckGrid(ref ag).EditItems([ass]))
|
|
|
{
|
|
|
- _copiedmodel = model;
|
|
|
+ _assignments.Add(ass);
|
|
|
+ CalendarControl.SelectItem(LoadAssignment(ass, _appointments));
|
|
|
+ _copiedmodel = null;
|
|
|
}
|
|
|
|
|
|
- private Assignment PasteAssignment(CalendarTimeSlot slot, Assignment copied)
|
|
|
+ return ass;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void EditAssignment(Assignment model)
|
|
|
+ {
|
|
|
+ var grid = CheckGrid(ref ag);
|
|
|
+ Client.EnsureColumns(model, grid.LoadEditorColumns());
|
|
|
+
|
|
|
+ if (DynamicGridUtils.EditEntity<Assignment>(model))
|
|
|
{
|
|
|
- var ass = copied.Clone();
|
|
|
+ ItemChanged?.Invoke(this, new CalendarDataEventArgs(model));
|
|
|
+ // Refresh();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- ass.Date = slot.Date;
|
|
|
- ass.ID = Guid.Empty;
|
|
|
- ass.Number = 0;
|
|
|
- ass.CommitChanges();
|
|
|
+ private void DeleteAssignment(Assignment model)
|
|
|
+ {
|
|
|
+ if (!MessageWindow.ShowYesNo("Are you sure you wish to delete this assignment?", "Confirm Delete"))
|
|
|
+ return;
|
|
|
+
|
|
|
+ var ass = new Assignment { ID = model.ID };
|
|
|
+ Client.Delete(ass, "Assignment Deleted from Scheduler");
|
|
|
+ ItemChanged?.Invoke(this, new CalendarDataEventArgs(ass));
|
|
|
+ Refresh();
|
|
|
+ SelectionChanged?.Invoke(this, new CalendarDataEventArgs(null));
|
|
|
|
|
|
- ass.Booked.Start = slot.Start;
|
|
|
- ass.Booked.Finish = slot.End;
|
|
|
- if ((AssignmentType == CalendarAssignmentType.Actual) || ((AssignmentType == CalendarAssignmentType.Automatic) && (ass.Date <= DateTime.Today)))
|
|
|
- {
|
|
|
- ass.Actual.Start = ass.Booked.Start;
|
|
|
- ass.Actual.Finish = ass.Booked.Finish;
|
|
|
- }
|
|
|
-
|
|
|
- ass.Employee.ID = slot.EmployeeID;
|
|
|
- ass.Employee.Clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ private Assignment? _copiedmodel;
|
|
|
|
|
|
- Client.Save(ass, "");
|
|
|
+ private void CopyAssignment(Assignment model)
|
|
|
+ {
|
|
|
+ _copiedmodel = model;
|
|
|
+ }
|
|
|
|
|
|
- _assignments.Add(ass);
|
|
|
- CalendarControl.SelectItem(LoadAssignment(ass, _appointments));
|
|
|
- _copiedmodel = null;
|
|
|
- return ass;
|
|
|
+ private Assignment PasteAssignment(CalendarTimeSlot slot, Assignment copied)
|
|
|
+ {
|
|
|
+ var ass = copied.Clone();
|
|
|
|
|
|
- }
|
|
|
+ ass.Date = slot.Date;
|
|
|
+ ass.ID = Guid.Empty;
|
|
|
+ ass.Number = 0;
|
|
|
+ ass.CommitChanges();
|
|
|
|
|
|
- private void EditLeave(LeaveRequest model)
|
|
|
+ ass.Booked.Start = slot.Start;
|
|
|
+ ass.Booked.Finish = slot.End;
|
|
|
+ if ((AssignmentType == CalendarAssignmentType.Actual) || ((AssignmentType == CalendarAssignmentType.Automatic) && (ass.Date <= DateTime.Today)))
|
|
|
{
|
|
|
- var grid = CheckGrid(ref lg);
|
|
|
- Client.EnsureColumns(model, grid.LoadEditorColumns());
|
|
|
-
|
|
|
- if (DynamicGridUtils.EditEntity(model))
|
|
|
- {
|
|
|
- ItemChanged?.Invoke(this, new CalendarDataEventArgs(model));
|
|
|
- Refresh();
|
|
|
- }
|
|
|
+ ass.Actual.Start = ass.Booked.Start;
|
|
|
+ ass.Actual.Finish = ass.Booked.Finish;
|
|
|
}
|
|
|
+
|
|
|
+ ass.Employee.ID = slot.EmployeeID;
|
|
|
+ ass.Employee.Clear();
|
|
|
|
|
|
- private void EditStandardLeave(StandardLeave model)
|
|
|
- {
|
|
|
- var grid = CheckGrid(ref slg);
|
|
|
- Client.EnsureColumns(model, grid.LoadEditorColumns());
|
|
|
+ Client.Save(ass, "");
|
|
|
|
|
|
- if (DynamicGridUtils.EditEntity(model))
|
|
|
- {
|
|
|
- ItemChanged?.Invoke(this, new CalendarDataEventArgs(model));
|
|
|
- Refresh();
|
|
|
- }
|
|
|
- }
|
|
|
+ _assignments.Add(ass);
|
|
|
+ CalendarControl.SelectItem(LoadAssignment(ass, _appointments));
|
|
|
+ _copiedmodel = null;
|
|
|
+ return ass;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void EditLeave(LeaveRequest model)
|
|
|
+ {
|
|
|
+ var grid = CheckGrid(ref lg);
|
|
|
+ Client.EnsureColumns(model, grid.LoadEditorColumns());
|
|
|
|
|
|
- private void Calendar_BlockClicked(object sender, CalendarBlockEventArgs e)
|
|
|
+ if (DynamicGridUtils.EditEntity(model))
|
|
|
{
|
|
|
- if(e.Value is AssignmentAppointment appointment)
|
|
|
- {
|
|
|
- var args = new CalendarDataEventArgs(appointment.Model);
|
|
|
- SelectionChanged?.Invoke(this, args);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- SelectionChanged?.Invoke(this, new CalendarDataEventArgs(null));
|
|
|
- }
|
|
|
+ ItemChanged?.Invoke(this, new CalendarDataEventArgs(model));
|
|
|
+ Refresh();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region Layout
|
|
|
+ private void EditStandardLeave(StandardLeave model)
|
|
|
+ {
|
|
|
+ var grid = CheckGrid(ref slg);
|
|
|
+ Client.EnsureColumns(model, grid.LoadEditorColumns());
|
|
|
|
|
|
- private void _settingsButton_OnClick(object sender, RoutedEventArgs e)
|
|
|
+ if (DynamicGridUtils.EditEntity(model))
|
|
|
{
|
|
|
- _splitPanel.View = DynamicSplitPanelView.Master;
|
|
|
+ ItemChanged?.Invoke(this, new CalendarDataEventArgs(model));
|
|
|
+ Refresh();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- private void _splitPanel_OnOnChanged(object sender, DynamicSplitPanelSettings e)
|
|
|
+ private void Calendar_BlockClicked(object sender, CalendarBlockEventArgs e)
|
|
|
+ {
|
|
|
+ if(e.Value is AssignmentAppointment appointment)
|
|
|
+ {
|
|
|
+ var args = new CalendarDataEventArgs(appointment.Model);
|
|
|
+ SelectionChanged?.Invoke(this, args);
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
- return;
|
|
|
- if (e.View == DynamicSplitPanelView.Combined && SettingsVisible != CalendarSettingsVisibility.Visible)
|
|
|
- SettingsVisible = CalendarSettingsVisibility.Visible;
|
|
|
- else if (e.View == DynamicSplitPanelView.Master && SettingsVisible == CalendarSettingsVisibility.Visible)
|
|
|
- SettingsVisible = CalendarSettingsVisibility.Hidden;
|
|
|
+ SelectionChanged?.Invoke(this, new CalendarDataEventArgs(null));
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
+ #endregion
|
|
|
|
|
|
- private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
|
|
|
- {
|
|
|
- if (sender is not TextBlock block || block.Tag is not Employee employee) return;
|
|
|
+ #region Layout
|
|
|
|
|
|
- var display = employee.Name;
|
|
|
- var comps = employee.Name.Split(' ');
|
|
|
+ private void _settingsButton_OnClick(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ _splitPanel.View = DynamicSplitPanelView.Master;
|
|
|
+ }
|
|
|
|
|
|
- if(block.ActualWidth < 75)
|
|
|
- {
|
|
|
- display = (comps[0].Length > 0 ? comps[0][..1] : "")
|
|
|
- + (comps.Length > 1 ? comps.Skip(1).First()[..1].ToUpper() : "");
|
|
|
- }
|
|
|
- else if(block.ActualWidth < 150)
|
|
|
- {
|
|
|
- display = comps.First() + " " + (comps.Length > 1 ? comps.Skip(1).First()[..1].ToUpper() : "");
|
|
|
- }
|
|
|
- block.Text = display;
|
|
|
- }
|
|
|
+ private void _splitPanel_OnOnChanged(object sender, DynamicSplitPanelSettings e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events))
|
|
|
+ return;
|
|
|
+ if (e.View == DynamicSplitPanelView.Combined && SettingsVisible != CalendarSettingsVisibility.Visible)
|
|
|
+ SettingsVisible = CalendarSettingsVisibility.Visible;
|
|
|
+ else if (e.View == DynamicSplitPanelView.Master && SettingsVisible == CalendarSettingsVisibility.Visible)
|
|
|
+ SettingsVisible = CalendarSettingsVisibility.Hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (sender is not TextBlock block || block.Tag is not Employee employee) return;
|
|
|
|
|
|
- #region Date Selection
|
|
|
+ var display = employee.Name;
|
|
|
+ var comps = employee.Name.Split(' ');
|
|
|
|
|
|
- private void Left_Click(object sender, RoutedEventArgs e)
|
|
|
+ if(block.ActualWidth < 75)
|
|
|
{
|
|
|
- SelectedDate = SelectedDate.AddDays(CalendarView switch
|
|
|
- {
|
|
|
- CalendarViewType.Day => -1,
|
|
|
- CalendarViewType.WorkWeek or CalendarViewType.Week => -7,
|
|
|
- _ => throw new InvalidEnumException<CalendarViewType>(CalendarView)
|
|
|
- });
|
|
|
+ display = (comps[0].Length > 0 ? comps[0][..1] : "")
|
|
|
+ + (comps.Length > 1 ? comps.Skip(1).First()[..1].ToUpper() : "");
|
|
|
}
|
|
|
-
|
|
|
- private void Right_Click(object sender, RoutedEventArgs e)
|
|
|
+ else if(block.ActualWidth < 150)
|
|
|
{
|
|
|
- SelectedDate = SelectedDate.AddDays(CalendarView switch
|
|
|
- {
|
|
|
- CalendarViewType.Day => 1,
|
|
|
- CalendarViewType.WorkWeek or CalendarViewType.Week => 7,
|
|
|
- _ => throw new InvalidEnumException<CalendarViewType>(CalendarView)
|
|
|
- });
|
|
|
+ display = comps.First() + " " + (comps.Length > 1 ? comps.Skip(1).First()[..1].ToUpper() : "");
|
|
|
}
|
|
|
+ block.Text = display;
|
|
|
+ }
|
|
|
|
|
|
- private void Today_Click(object sender, RoutedEventArgs e)
|
|
|
+ #region Date Selection
|
|
|
+
|
|
|
+ private void Left_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ SelectedDate = SelectedDate.AddDays(CalendarView switch
|
|
|
{
|
|
|
- SelectedDate = DateTime.Today;
|
|
|
- }
|
|
|
+ CalendarViewType.Day => -1,
|
|
|
+ CalendarViewType.WorkWeek or CalendarViewType.Week => -7,
|
|
|
+ _ => throw new InvalidEnumException<CalendarViewType>(CalendarView)
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- private void AlwaysTodayBox_Checked(object sender, RoutedEventArgs e)
|
|
|
+ private void Right_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ SelectedDate = SelectedDate.AddDays(CalendarView switch
|
|
|
{
|
|
|
- if (EventSuppressor.IsSet(Suppress.Events)) return;
|
|
|
+ CalendarViewType.Day => 1,
|
|
|
+ CalendarViewType.WorkWeek or CalendarViewType.Week => 7,
|
|
|
+ _ => throw new InvalidEnumException<CalendarViewType>(CalendarView)
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- Properties.AlwaysStartOnToday = AlwaysTodayBox.IsChecked == true;
|
|
|
- DoSaveSettings();
|
|
|
- }
|
|
|
+ private void Today_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ SelectedDate = DateTime.Today;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AlwaysTodayBox_Checked(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ if (EventSuppressor.IsSet(Suppress.Events)) return;
|
|
|
|
|
|
- #endregion
|
|
|
+ Properties.AlwaysStartOnToday = AlwaysTodayBox.IsChecked == true;
|
|
|
+ DoSaveSettings();
|
|
|
}
|
|
|
+
|
|
|
+ #endregion
|
|
|
}
|