123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518 |
- using Comal.Classes;
- using InABox.Clients;
- using InABox.Core;
- using InABox.DynamicGrid;
- using InABox.WPF;
- using Microsoft.CodeAnalysis.VisualBasic.Syntax;
- using org.omg.PortableInterceptor;
- using PRSDesktop.Forms;
- using PRSDesktop.WidgetGroups;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Globalization;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Threading.Tasks;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using InABox.Configuration;
- using Client = InABox.Clients.Client;
- using System.Windows;
- using InABox.Wpf;
- namespace PRSDesktop.Dashboards;
- public class EquipmentSchedulesDashboardProperties : IUserConfigurationSettings, IDashboardProperties
- {
- public bool OnlyShowSchedules { get; set; } = true;
- public DynamicGridSelectedFilterSettings Filters { get; set; } = new();
- }
- public class ScheduleViewModel : INotifyPropertyChanged
- {
- private Guid employeeID;
- private string? employeeName;
- private string? employeeMobile;
- private string? employeeEmail;
- private BitmapImage? employeeImage;
- public bool HasEmployee => EmployeeID != Guid.Empty;
- public Guid ID { get; set; }
- public string Title { get; set; }
- public DateTime DueDate { get; set; }
- public BitmapImage? EmployeeImage
- {
- get => employeeImage;
- set
- {
- employeeImage = value;
- NotifyPropertyChanged();
- }
- }
- public Guid EmployeeID
- {
- get => employeeID;
- set
- {
- employeeID = value;
- NotifyPropertyChanged(nameof(HasEmployee));
- }
- }
- public string? EmployeeName
- {
- get => employeeName;
- set
- {
- employeeName = value;
- NotifyPropertyChanged();
- }
- }
- public string? EmployeeMobile
- {
- get => employeeMobile;
- set
- {
- employeeMobile = value;
- NotifyPropertyChanged();
- NotifyPropertyChanged(nameof(EmployeeContact));
- }
- }
- public string? EmployeeEmail
- {
- get => employeeEmail;
- set
- {
- employeeEmail = value;
- NotifyPropertyChanged();
- NotifyPropertyChanged(nameof(EmployeeContact));
- }
- }
- public string? EmployeeContact
- {
- get
- {
- var str = "";
- if (EmployeeEmail is not null) str = EmployeeEmail;
- if(EmployeeMobile is not null)
- {
- if (string.IsNullOrWhiteSpace(str))
- {
- str = EmployeeMobile;
- }
- else
- {
- str += $", {EmployeeMobile}";
- }
- }
- return string.IsNullOrWhiteSpace(str) ? null : str;
- }
- }
- public event PropertyChangedEventHandler? PropertyChanged;
- private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
- public class EquipmentScheduleViewModel
- {
- public bool HasLocation { get; set; }
- public Guid ID { get; set; }
- public string Code { get; set; }
- public string Description { get; set; }
- public List<ScheduleViewModel> Schedules { get; set; }
- }
- [ValueConversion(typeof(DateTime), typeof(SolidColorBrush))]
- class ScheduleBackgroundConverter : IValueConverter
- {
- public Color GetColor(DateTime date)
- {
- var diff = date - DateTime.Today;
- if (diff < TimeSpan.Zero)
- return Colors.Salmon;
- else if (diff.TotalDays <= 7)
- return Colors.Orange;
- else if (diff.Days <= 30)
- return Colors.LightYellow;
- else
- return Colors.LightGreen;
- }
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- var date = (DateTime)value;
- var color = GetColor(date);
- return new SolidColorBrush(color);
- }
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- throw new NotImplementedException();
- }
- }
- /// <summary>
- /// Interaction logic for EquipmentSchedulesDashboard.xaml
- /// </summary>
- public partial class EquipmentSchedulesDashboard : UserControl, IDashboardWidget<EquipmentDashboardGroup, EquipmentSchedulesDashboardProperties>, IHeaderDashboard, IBasePanel
- {
- public EquipmentSchedulesDashboardProperties Properties { get; set; } = null!;
- public DashboardHeader Header { get; set; } = new();
- public event LoadSettings<EquipmentSchedulesDashboardProperties>? LoadSettings;
- public event SaveSettings<EquipmentSchedulesDashboardProperties>? SaveSettings;
- public event DataModelUpdateEvent? OnUpdateDataModel;
- private Dictionary<Guid, Equipment> Equipment = new();
- private Dictionary<Guid, BitmapImage?> EmployeeImages = new();
- private Dictionary<Guid, Employee> Employees = new();
- private List<EquipmentScheduleViewModel> Models = new();
- public EquipmentSchedulesDashboard()
- {
- InitializeComponent();
- }
- public void Setup()
- {
- LoadEmployeeImages();
- SetupHeader();
- }
- #region IBasePanel
- public string SectionName => "EquipmentSchedules";
-
- public DataModel DataModel(Selection selection)
- {
- return new AutoDataModel<Equipment>(new Filter<Equipment>().All());
- }
-
- public bool IsReady { get; set; }
-
- public void CreateToolbarButtons(IPanelHost host)
- {
- }
- public Dictionary<string, object[]> Selected()
- {
- return new();
- }
- public void Heartbeat(TimeSpan time)
- {
-
- }
- #endregion
- #region Header
- private CheckBox ShowSchedulesBox = null!;
- private FilterButton<Equipment> FilterBtn = null!;
- public void SetupHeader()
- {
- ShowSchedulesBox = new CheckBox
- {
- Content = "Only show schedules?",
- IsChecked = Properties.OnlyShowSchedules,
- VerticalAlignment = VerticalAlignment.Center
- };
- ShowSchedulesBox.Checked += ShowSchedulesBox_Checked;
- ShowSchedulesBox.Unchecked += ShowSchedulesBox_Checked;
- FilterBtn = new FilterButton<Equipment>(
- new GlobalConfiguration<CoreFilterDefinitions>(nameof(EquipmentSchedulesDashboard)),
- new UserConfiguration<CoreFilterDefinitions>(nameof(EquipmentSchedulesDashboard)))
- {
- Width = 25,
- Height = 25,
- Padding = new()
- };
- FilterBtn.BuiltInFilters.Add(new("Exclude Disposed", () => new Filter<Equipment>(x => x.Disposed).IsEqualTo(null)));
- FilterBtn.SetSettings(Properties.Filters, false);
- FilterBtn.OnFiltersSelected += FilterBtn_OnFiltersSelected;
- FilterBtn.OnFilterRefresh += FilterBtn_OnFilterRefresh;
- Header.BeginUpdate()
- .Clear()
- .Add(ShowSchedulesBox)
- .AddRight(FilterBtn)
- .EndUpdate();
- }
- private void ShowSchedulesBox_Checked(object sender, RoutedEventArgs e)
- {
- Properties.OnlyShowSchedules = ShowSchedulesBox.IsChecked == true;
- Refresh();
- }
- private void FilterBtn_OnFilterRefresh()
- {
- Refresh();
- }
- private void FilterBtn_OnFiltersSelected(DynamicGridSelectedFilterSettings filters)
- {
- Properties.Filters = filters;
- }
- #endregion
- private void LoadEmployeeImages()
- {
- Task.Run(() =>
- {
- var employees = new Client<Employee>()
- .Query(
- LookupFactory.DefineFilter<Employee>(),
- Columns.None<Employee>().Add(
- x => x.ID,
- x => x.Thumbnail.ID,
- x => x.Name,
- x => x.Mobile,
- x => x.Email))
- .ToObjects<Employee>().ToList();
- var documents = new Client<Document>()
- .Query(
- new Filter<Document>(x => x.ID).InList(employees.Select(x => x.Thumbnail.ID).ToArray()),
- Columns.None<Document>().Add(x => x.ID).Add(x => x.Data))
- .ToDictionary<Document, Guid, byte[]>(x => x.ID, x => x.Data);
- return new { Employees = employees, Documents = documents };
- }).ContinueWith((task) =>
- {
- EmployeeImages = task.Result.Employees.ToDictionary(
- x => x.ID,
- x =>
- {
- var document = task.Result.Documents.GetValueOrDefault(x.Thumbnail.ID);
- if (document is null)
- return null;
- return ImageUtils.BitmapImageFromBytes(document);
- });
- Employees = task.Result.Employees.ToDictionary(x => x.ID, x => x);
- lock (Models)
- {
- var anonymous = PRSDesktop.Resources.anonymous.AsBitmapImage();
- foreach (var model in Models)
- {
- foreach (var schedule in model.Schedules)
- {
- var employee = Employees?.GetValueOrDefault(schedule.EmployeeID);
- schedule.EmployeeImage = EmployeeImages?.GetValueOrDefault(schedule.EmployeeID) ?? anonymous;
- schedule.EmployeeMobile = employee?.Mobile;
- schedule.EmployeeName = employee?.Name;
- schedule.EmployeeEmail = employee?.Email;
- }
- }
- }
- }, TaskScheduler.FromCurrentSynchronizationContext());
- }
- public void Refresh()
- {
- var eqFilter = FilterBtn.GetFilter();
- var results = Client.QueryMultiple(
- new KeyedQueryDef<Equipment>(
- eqFilter,
- Columns.None<Equipment>().Add(x => x.ID)
- .Add(x => x.Code)
- .Add(x => x.Description)
- .Add(x => x.TrackerLink.ID)
- .Add(x => x.TrackerLink.Location.Latitude)
- .Add(x => x.TrackerLink.Location.Longitude)
- .Add(x => x.TrackerLink.Location.Timestamp)),
- new KeyedQueryDef<Schedule>(
- new Filter<Schedule>(x => x.DocumentClass).IsEqualTo(typeof(Equipment).EntityName())
- .And(x => x.IncludeInAggregate).IsEqualTo(true),
- Columns.None<Schedule>().Add(x => x.ID)
- .Add(x => x.Title)
- .Add(x => x.DueDate)
- .Add(x => x.DocumentID)
- .Add(x => x.EmployeeLink.ID)));
- var equipmentItems = results.Get<Equipment>().Rows.Select(x => x.ToObject<Equipment>());
- Equipment = equipmentItems.ToDictionary(x => x.ID, x => x);
- var schedules = results.Get<Schedule>().Rows
- .Select(x => x.ToObject<Schedule>())
- .GroupBy(x => x.DocumentID)
- .ToDictionary(x => x.Key, x => x.OrderBy(x => x.DueDate).ToList());
- var anonymous = PRSDesktop.Resources.anonymous.AsBitmapImage();
- lock (Models)
- {
- Models = new List<EquipmentScheduleViewModel>();
- foreach (var equipmentItem in equipmentItems)
- {
- var equipmentSchedules = schedules.GetValueOrDefault(equipmentItem.ID);
- if(equipmentSchedules is null && Properties.OnlyShowSchedules)
- {
- continue;
- }
- var model = new EquipmentScheduleViewModel
- {
- Code = equipmentItem.Code,
- Description = equipmentItem.Description,
- ID = equipmentItem.ID,
- HasLocation = equipmentItem.TrackerLink.ID != Guid.Empty
- };
- model.Schedules = (equipmentSchedules ?? Enumerable.Empty<Schedule>())
- .Select(x =>
- {
- var employee = Employees.GetValueOrDefault(x.EmployeeLink.ID);
- return new ScheduleViewModel
- {
- Title = x.Title,
- DueDate = x.DueDate,
- ID = x.ID,
- EmployeeImage = EmployeeImages.GetValueOrDefault(x.EmployeeLink.ID) ?? anonymous,
- EmployeeID = x.EmployeeLink.ID,
- EmployeeEmail = employee?.Email,
- EmployeeMobile = employee?.Mobile,
- EmployeeName = employee?.Name
- };
- })
- .ToList() ?? [];
- Models.Add(model);
- }
- }
- EquipmentList.ItemsSource = Models;
- }
- public void Shutdown(CancelEventArgs? cancel)
- {
- }
- private void Border_ContextMenuOpening(object sender, ContextMenuEventArgs e)
- {
- if (sender is not FrameworkElement element || element.Tag is not Guid equipmentID) return;
- var menu = new ContextMenu();
- menu.AddItem("View Equipment", null, equipmentID, ViewEquipment_Click);
- menu.AddItem("Add Schedule", null, equipmentID, CreateSchedule_Click);
- menu.IsOpen = true;
- e.Handled = true;
- }
- private void CreateSchedule_Click(Guid equipmentID)
- {
- var schedule = new Schedule();
- schedule.DocumentClass = typeof(Equipment).EntityName();
- schedule.DocumentID = equipmentID;
- if (DynamicGridUtils.EditEntity(schedule))
- {
- Refresh();
- }
- }
- private void Grid_ContextMenuOpening(object sender, ContextMenuEventArgs e)
- {
- if (sender is not FrameworkElement element || element.Tag is not Guid equipmentID) return;
- var menu = new ContextMenu();
- menu.AddItem("Add Schedule", null, equipmentID, CreateSchedule_Click);
- menu.IsOpen = true;
- e.Handled = true;
- }
- private void Schedule_ContextMenuOpening(object sender, ContextMenuEventArgs e)
- {
- if (sender is not FrameworkElement element || element.Tag is not Guid scheduleID) return;
- var menu = new ContextMenu();
- menu.AddItem("View Schedule", null, scheduleID, ViewSchedule_Click);
- menu.IsOpen = true;
- e.Handled = true;
- }
- private void Employee_ContextMenuOpening(object sender, ContextMenuEventArgs e)
- {
- if (sender is not FrameworkElement element || element.Tag is not Guid employeeID) return;
- if (employeeID == Guid.Empty) return;
- var menu = new ContextMenu();
- menu.AddItem("View Employee", null, employeeID, ViewEmployee_Click);
- menu.IsOpen = true;
- e.Handled = true;
- }
- private void ViewEquipment_Click(Guid equipmentID)
- {
- if (DynamicGridUtils.EditEntity<Equipment>(equipmentID))
- {
- Refresh();
- }
- }
- private void ViewSchedule_Click(Guid scheduleID)
- {
- if (DynamicGridUtils.EditEntity<Schedule>(scheduleID))
- {
- Refresh();
- }
- }
- private void ViewEmployee_Click(Guid employeeID)
- {
- if (DynamicGridUtils.EditEntity<Employee>(employeeID))
- {
- Refresh();
- }
- }
- private void EquipmentLocation_Click(object sender, System.Windows.RoutedEventArgs e)
- {
- var equipmentID = (Guid)(sender as Button)!.Tag;
- if (!Equipment.TryGetValue(equipmentID, out var equipment))
- return;
- var form = new MapForm(
- equipment.TrackerLink.Location.Latitude,
- equipment.TrackerLink.Location.Longitude,
- equipment.TrackerLink.Location.Timestamp);
- form.ShowDialog();
- }
- }
- public class EquipmentSchedulesDashboardElement :
- DashboardElement<EquipmentSchedulesDashboard, EquipmentDashboardGroup, EquipmentSchedulesDashboardProperties> { }
|