using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Controls; using Comal.Classes; using InABox.Clients; using InABox.Configuration; using InABox.Core; using NPOI.HSSF.Util; using Syncfusion.Windows.Tools.Controls; namespace PRSDesktop { public class EmployeeSelectorData { // if first == FullGuid, remainder are selected // Otherwise, ignore the rest public Guid[] Teams { get; set; } // if first == FullGuid, select all public Guid[] Employees { get; set; } public EmployeeSelectorData( Guid[] teams, Guid[] employees) { Teams = teams; Employees = employees; } public EmployeeSelectorData() : this(new[] { Guid.Empty }, new[] { CoreUtils.FullGuid }) { } } public class EmployeeSelectorSettings { public double SplitPosition { get; set; } public EmployeeSelectorSettings() { SplitPosition = 200.0F; } } public class EmployeeSelectorSettingsChangedArgs : EventArgs { public EmployeeSelectorSettings Settings { get; private set; } public EmployeeSelectorSettingsChangedArgs(EmployeeSelectorSettings settings) { Settings = settings; } } public delegate void EmployeeSelectorSettingsChanged(object sender, EmployeeSelectorSettingsChangedArgs args); public class EmployeeSelectorSelectionChangedArgs : EventArgs { public EmployeeSelectorData Selection { get; private set; } public EmployeeSelectorSelectionChangedArgs(EmployeeSelectorData selection) { Selection = selection; } } public delegate void EmployeeSelectorSelectionChanged(object sender, EmployeeSelectorSelectionChangedArgs args); public partial class EmployeeSelector : UserControl { private enum Suppress { This } private class ListEntry { public Guid Key { get; set; } public String Value { get; set; } } public EmployeeSelectorSettings Settings { get; set; } public event EmployeeSelectorSettingsChanged SettingsChanged; public event EmployeeSelectorSelectionChanged SelectionChanged; private CoreTable _employees; private Dictionary _rosters; private ListEntry[] _teams; private Tuple[] _employeeteams; public T[] GetEmployeeData(Func transform) { List result = new List(); var selteams = GetSelectedTeams(); var selemps = GetSelectedEmployees(); var empids = _employeeteams .Where(x => selteams.Contains(x.Item1) && selemps.Contains(CoreUtils.FullGuid) || selemps.Contains(x.Item2)) .Select(x => x.Item2) .Distinct() .ToArray(); var rows = _employees.Rows.Where(r => empids.Contains(r.Get(c => c.ID))); foreach (var row in rows) { if(!_rosters.TryGetValue(row.Get(x => x.ID), out var rosters)) { rosters = Array.Empty(); } result.Add(transform.Invoke(row, rosters)); } return result.ToArray(); } public EmployeeSelector() { Settings = new EmployeeSelectorSettings(); using (new EventSuppressor(Suppress.This)) InitializeComponent(); } public void Setup() { using (new EventSuppressor(Suppress.This)) { var results = Client.QueryMultiple( new KeyedQueryDef( LookupFactory.DefineFilter(), EmployeeResourceModel.Columns), new KeyedQueryDef( new Filter(x => x.Employee.ID) .InQuery(LookupFactory.DefineFilter(), x => x.ID), sortorder: new SortOrder(x => x.Day)), new KeyedQueryDef( LookupFactory.DefineFilter(), Columns.None().Add(x => x.ID) .Add(x => x.Name), new SortOrder(x => x.Name)), new KeyedQueryDef( LookupFactory.DefineFilter(), Columns.None().Add(x => x.TeamLink.ID) .Add(x => x.EmployeeLink.ID) .Add(x => x.EmployeeLink.Name))); _employees = results.Get(); _rosters = results.Get().ToObjects() .GroupBy(x => x.Employee.ID, x => x).ToDictionary(x => x.Key, x => x.ToArray()); _teams = results.Get().Rows.Select(r => new ListEntry() { Key = r.Get(c => c.ID), Value = r.Get(c => c.Name) }).ToArray(); TeamList.ItemsSource = _teams; ObservableCollection teamdata = new() { new ListEntry() { Key = Guid.Empty, Value = "All Staff" } }; foreach (var team in _teams) teamdata.Add(team); teamdata.Add(new ListEntry() { Key = CoreUtils.FullGuid, Value = "Multiple Teams" }); Teams.ItemsSource = teamdata; _employeeteams = results.Get().Rows.Select( row => new Tuple( row.Get(c => c.TeamLink.ID), row.Get(c => c.EmployeeLink.ID), row.Get(c => c.EmployeeLink.Name) ) ).Union( _employees.Rows.Select( row => new Tuple( Guid.Empty, row.Get(c => c.ID), row.Get(c => c.Name) ) ) ).ToArray(); Teams.SelectedValue = Guid.Empty; } } private void UpdateSettings() { bool changed = false; var teams = GetSelectedTeams(); if (teams.Contains(CoreUtils.FullGuid) && (Math.Abs(Settings.SplitPosition - TeamListRow.Height.Value) >= 1.0F)) { changed = true; Settings.SplitPosition = TeamListRow.Height.Value; } if (changed && (!EventSuppressor.IsSet(Suppress.This))) SettingsChanged?.Invoke(this, new EmployeeSelectorSettingsChangedArgs(Settings)); } private Guid[] GetSelectedTeams() { Guid teamid = Teams.SelectedValue != null ? (Guid)Teams.SelectedValue : Guid.Empty; var teams = (teamid == CoreUtils.FullGuid) ? TeamList.SelectedItems .OfType() .Select(x => x.Key) .Prepend(teamid) .ToArray() : new Guid[] { teamid }; return teams; } private Guid[] GetSelectedEmployees() { var emps = (SelectedEmployees.SelectedItems.Count == SelectedEmployees.Items.Count) ? new Guid[] { CoreUtils.FullGuid } : SelectedEmployees.SelectedItems .OfType() .Select(x => x.Key) .ToArray(); return emps; } public EmployeeSelectorData Selection { get => GetSelectionData(); set => SelectEmployees(value); } private EmployeeSelectorData GetSelectionData() { return new EmployeeSelectorData( GetSelectedTeams(), GetSelectedEmployees() ); } private void SelectEmployees(EmployeeSelectorData selection) { using (new EventSuppressor(Suppress.This)) { Teams.SelectedValue = selection.Teams.Contains(CoreUtils.FullGuid) ? CoreUtils.FullGuid : selection.Teams.FirstOrDefault(); LoadTeams(selection.Teams); var employees = SelectedEmployees.ItemsSource as ObservableCollection; var pairs = employees.Where(x => selection.Employees.Contains(CoreUtils.FullGuid) || selection.Employees.Contains(x.Key)); SelectedEmployees.SelectedItems.Clear(); foreach (var pair in pairs) SelectedEmployees.SelectedItems.Add(pair); } } private void LoadTeams(Guid[] teamids) { using (new EventSuppressor(Suppress.This)) { Guid teamid = teamids.FirstOrDefault(); if (Guid.Equals(teamid, CoreUtils.FullGuid)) { TeamListRow.Height = new GridLength(Settings.SplitPosition, GridUnitType.Pixel); TeamListSplitterRow.Height = new GridLength(4, GridUnitType.Pixel); var selected = new ObservableCollection(_teams.Where(x => teamids.Contains(x.Key))); TeamList.SelectedItems = selected; LoadEmployees(teamids.Skip(1).ToArray()); } else { TeamListRow.Height = new GridLength(0, GridUnitType.Pixel); TeamListSplitterRow.Height = new GridLength(0, GridUnitType.Pixel); LoadEmployees(new Guid[] { teamid }); } } } private void LoadEmployees(Guid[] teamids) { using (new EventSuppressor(Suppress.This)) { var empids =_employeeteams .OrderBy(x => x.Item3) .Where(x => teamids.Contains(x.Item1)) .Select(x => new Tuple(x.Item2, x.Item3)) .Distinct(); var emps = empids.Select(x => new ListEntry() { Key = x.Item1, Value = x.Item2 }).ToArray(); SelectedEmployees.ItemsSource = new ObservableCollection(emps); SelectedEmployees.SelectedItems = new ObservableCollection(emps); } } public void SelectEmployee(Guid employeeid) { using (new EventSuppressor(Suppress.This)) { LoadTeams(new Guid[] { Guid.Empty }); if (SelectedEmployees.ItemsSource is ObservableCollection employees) { var emp = employees.FirstOrDefault(x => x.Key == employeeid); if (emp != null) SelectedEmployees.SelectedItems = new ObservableCollection() { emp }; } } } private void TeamsSelectionChanged(object sender, SelectionChangedEventArgs e) { if (EventSuppressor.IsSet(Suppress.This)) return; using (new EventSuppressor(Suppress.This)) LoadTeams(GetSelectedTeams()); UpdateSettings(); SelectionChanged?.Invoke(this, new EmployeeSelectorSelectionChangedArgs(GetSelectionData())); } private void SelectedTeams_ItemChecked(object? sender, ItemCheckedEventArgs e) { if (EventSuppressor.IsSet(Suppress.This)) return; using (new EventSuppressor(Suppress.This)) LoadEmployees(GetSelectedTeams()); UpdateSettings(); SelectionChanged?.Invoke(this, new EmployeeSelectorSelectionChangedArgs(GetSelectionData())); } private void SelectedEmployees_OnItemChecked(object? sender, ItemCheckedEventArgs e) { if (EventSuppressor.IsSet(Suppress.This)) return; UpdateSettings(); SelectionChanged?.Invoke(this, new EmployeeSelectorSelectionChangedArgs(GetSelectionData())); } private void SelectedTeams_SizeChanged(object sender, SizeChangedEventArgs e) { if (EventSuppressor.IsSet(Suppress.This)) return; UpdateSettings(); } } }