|
@@ -3,6 +3,7 @@ using InABox.Clients;
|
|
|
using InABox.Core;
|
|
|
using InABox.DynamicGrid;
|
|
|
using InABox.WPF;
|
|
|
+using jdk.nashorn.@internal.ir;
|
|
|
using Microsoft.Win32;
|
|
|
using Org.BouncyCastle.Crypto;
|
|
|
using PRSDesktop.WidgetGroups;
|
|
@@ -24,22 +25,39 @@ namespace PRSDesktop
|
|
|
|
|
|
class CellBackgroundConverter : IValueConverter
|
|
|
{
|
|
|
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
|
+ private EmployeeQualificationDashboard Dashboard;
|
|
|
+
|
|
|
+ public CellBackgroundConverter(EmployeeQualificationDashboard dashboard)
|
|
|
{
|
|
|
- if (value is null || value is not DateTime date)
|
|
|
- return DependencyProperty.UnsetValue;
|
|
|
+ Dashboard = dashboard;
|
|
|
+ }
|
|
|
|
|
|
- if (date == DateTime.MinValue || date == DateTime.MaxValue)
|
|
|
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
|
+ {
|
|
|
+ if(value is DateTime date)
|
|
|
+ {
|
|
|
+ if (date == DateTime.MinValue || date == DateTime.MaxValue)
|
|
|
+ return DependencyProperty.UnsetValue;
|
|
|
+
|
|
|
+ var diff = date - DateTime.Now;
|
|
|
+ if (diff <= TimeSpan.Zero)
|
|
|
+ return new SolidColorBrush(Colors.Salmon);
|
|
|
+ else if (diff.TotalDays < 7)
|
|
|
+ return new SolidColorBrush(Colors.Orange);
|
|
|
+ else if (diff.TotalDays < 30)
|
|
|
+ return new SolidColorBrush(Colors.Yellow);
|
|
|
return DependencyProperty.UnsetValue;
|
|
|
-
|
|
|
- var diff = date - DateTime.Now;
|
|
|
- if (diff <= TimeSpan.Zero)
|
|
|
- return new SolidColorBrush(Colors.Salmon);
|
|
|
- else if (diff.TotalDays < 7)
|
|
|
- return new SolidColorBrush(Colors.Orange);
|
|
|
- else if (diff.TotalDays < 30)
|
|
|
- return new SolidColorBrush(Colors.Yellow);
|
|
|
-
|
|
|
+ }
|
|
|
+ if(value is EmployeeQualificationDashboard.CellValue cellValue)
|
|
|
+ {
|
|
|
+ switch (cellValue)
|
|
|
+ {
|
|
|
+ case EmployeeQualificationDashboard.CellValue.Required:
|
|
|
+ return Dashboard.Resources["shadedBackground"];
|
|
|
+ case EmployeeQualificationDashboard.CellValue.None:
|
|
|
+ return DependencyProperty.UnsetValue;
|
|
|
+ }
|
|
|
+ }
|
|
|
return DependencyProperty.UnsetValue;
|
|
|
}
|
|
|
|
|
@@ -92,6 +110,12 @@ namespace PRSDesktop
|
|
|
private List<Guid> QualificationIDs;
|
|
|
private List<Guid> EmployeeIDs;
|
|
|
|
|
|
+ public enum CellValue
|
|
|
+ {
|
|
|
+ None,
|
|
|
+ Required
|
|
|
+ }
|
|
|
+
|
|
|
private Filter<Employee> EmployeeFilter { get; set; } = new Filter<Employee>().All()
|
|
|
.And(new Filter<Employee>(x => x.StartDate).IsEqualTo(DateTime.MinValue)
|
|
|
.Or(x => x.StartDate).IsLessThan(DateTime.Now))
|
|
@@ -116,19 +140,23 @@ namespace PRSDesktop
|
|
|
ColumnHeaders = new();
|
|
|
|
|
|
var employeeFilter = EmployeeFilter;
|
|
|
+ var employeeIDs = Employees.Where(x => x.Value).Select(x => x.Key).ToArray();
|
|
|
var results = Client.QueryMultiple(
|
|
|
new KeyedQueryDef<Employee>(nameof(Employee),
|
|
|
- new Filter<Employee>(x => x.ID).InList(Employees.Where(x => x.Value).Select(x => x.Key).ToArray()),
|
|
|
+ new Filter<Employee>(x => x.ID).InList(employeeIDs),
|
|
|
new Columns<Employee>(x => x.ID, x => x.Name)),
|
|
|
new KeyedQueryDef<EmployeeQualification>(nameof(EmployeeQualification),
|
|
|
- new Filter<EmployeeQualification>(x => x.Employee.ID).InQuery(employeeFilter, x => x.ID),
|
|
|
+ new Filter<EmployeeQualification>(x => x.Employee.ID).InList(employeeIDs),
|
|
|
new Columns<EmployeeQualification>(
|
|
|
x => x.Employee.ID,
|
|
|
x => x.Qualification.ID,
|
|
|
x => x.Expiry)),
|
|
|
new KeyedQueryDef<Qualification>(nameof(Qualification),
|
|
|
new Filter<Qualification>(x => x.ID).InList(Qualifications.Where(x => x.Value).Select(x => x.Key).ToArray()),
|
|
|
- new Columns<Qualification>(x => x.ID, x => x.Description)));
|
|
|
+ new Columns<Qualification>(x => x.ID, x => x.Description)),
|
|
|
+ new KeyedQueryDef<EmployeeRequiredQualification>(
|
|
|
+ new Filter<EmployeeRequiredQualification>(x => x.Employee.ID).InList(employeeIDs),
|
|
|
+ new Columns<EmployeeRequiredQualification>(x => x.Employee.ID, x => x.Qualification.ID)));
|
|
|
|
|
|
CoreTable.Columns.Add(new CoreColumn() { ColumnName = "Employee", DataType = typeof(string) });
|
|
|
|
|
@@ -140,7 +168,7 @@ namespace PRSDesktop
|
|
|
var qID = qualification.Get<Qualification, Guid>(x => x.ID);
|
|
|
if (!columns.Contains(qID))
|
|
|
{
|
|
|
- CoreTable.Columns.Add(new CoreColumn() { ColumnName = qID.ToString(), DataType = typeof(DateTime) });
|
|
|
+ CoreTable.Columns.Add(new CoreColumn() { ColumnName = qID.ToString(), DataType = typeof(object) });
|
|
|
columns.Add(qID);
|
|
|
ColumnHeaders.Add(qID, qualification.Get<Qualification, string>(x => x.Description));
|
|
|
}
|
|
@@ -149,12 +177,19 @@ namespace PRSDesktop
|
|
|
|
|
|
EmployeeIDs = new();
|
|
|
|
|
|
+ var requiredQualifications = results.Get<EmployeeRequiredQualification>()
|
|
|
+ .ToObjects<EmployeeRequiredQualification>()
|
|
|
+ .GroupBy(x => x.Employee.ID, x => x.Qualification.ID)
|
|
|
+ .ToDictionary(x => x.Key, x => x.ToHashSet());
|
|
|
+
|
|
|
var employeeQualifications = results[nameof(EmployeeQualification)];
|
|
|
foreach (var employee in results[nameof(Employee)].Rows)
|
|
|
{
|
|
|
var employeeID = employee.Get<Employee, Guid>(x => x.ID);
|
|
|
EmployeeIDs.Add(employeeID);
|
|
|
|
|
|
+ var required = requiredQualifications.GetValueOrDefault(employeeID) ?? new HashSet<Guid>();
|
|
|
+
|
|
|
List<object?> values = new()
|
|
|
{
|
|
|
employee["Name"]
|
|
@@ -180,9 +215,13 @@ namespace PRSDesktop
|
|
|
values.Add(expiry);
|
|
|
}
|
|
|
}
|
|
|
+ else if (required.Contains(qID))
|
|
|
+ {
|
|
|
+ values.Add(CellValue.Required);
|
|
|
+ }
|
|
|
else
|
|
|
{
|
|
|
- values.Add(null);
|
|
|
+ values.Add(CellValue.None);
|
|
|
}
|
|
|
}
|
|
|
var row = CoreTable.NewRow();
|
|
@@ -270,6 +309,10 @@ namespace PRSDesktop
|
|
|
else
|
|
|
newValue = date;
|
|
|
}
|
|
|
+ else if(value is CellValue cellValue)
|
|
|
+ {
|
|
|
+ newValue = "";
|
|
|
+ }
|
|
|
else
|
|
|
{
|
|
|
newValue = value;
|
|
@@ -315,6 +358,15 @@ namespace PRSDesktop
|
|
|
var propertyCollection = DataGrid.View.GetPropertyAccessProvider();
|
|
|
return propertyCollection.GetValue(cell.RowData, cell.Column.MappingName);
|
|
|
}
|
|
|
+ private string GetColumnHeader(int column)
|
|
|
+ {
|
|
|
+ var header = DataGrid.GetHeaderCell(DataGrid.Columns[column]);
|
|
|
+
|
|
|
+ if (header is null)
|
|
|
+ return "";
|
|
|
+ return header.Content?.ToString() ?? "";
|
|
|
+ }
|
|
|
+ private string GetRowHeader(int row) => GetCellData(row, 0)?.ToString() ?? "";
|
|
|
|
|
|
private void DoEditQualification(int row, int column)
|
|
|
{
|
|
@@ -350,10 +402,11 @@ namespace PRSDesktop
|
|
|
e.Column.Width = 55;
|
|
|
e.Column.TextAlignment = TextAlignment.Center;
|
|
|
e.Column.ShowHeaderToolTip = true;
|
|
|
+ e.Column.ShowToolTip = true;
|
|
|
|
|
|
var style = new Style();
|
|
|
style.Setters.Add(new Setter(BackgroundProperty,
|
|
|
- new Binding(value.Path.Path) { Converter = new CellBackgroundConverter() }));
|
|
|
+ new Binding(value.Path.Path) { Converter = new CellBackgroundConverter(this) }));
|
|
|
e.Column.CellStyle = style;
|
|
|
e.Column.DisplayBinding = new Binding
|
|
|
{ Path = new PropertyPath(e.Column.MappingName), Converter = new CellContentConverter() };
|
|
@@ -364,6 +417,39 @@ namespace PRSDesktop
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private bool OpenCellTooltip(ToolTip tooltip, int row, int column)
|
|
|
+ {
|
|
|
+ var data = GetCellData(row, column);
|
|
|
+ if(data is CellValue cellValue)
|
|
|
+ {
|
|
|
+ if (cellValue == CellValue.Required)
|
|
|
+ {
|
|
|
+ tooltip.Content = new TextBlock { Text = $"{GetRowHeader(row)} requires '{GetColumnHeader(column)}', but they do not have it." };
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ private void DataGrid_CellToolTipOpening(object sender, Syncfusion.UI.Xaml.Grid.GridCellToolTipOpeningEventArgs e)
|
|
|
+ {
|
|
|
+ var vc = DataGrid.GetVisualContainer();
|
|
|
+ var p = Mouse.GetPosition(vc);
|
|
|
+ var rci = vc.PointToCellRowColumnIndex(p);
|
|
|
+
|
|
|
+ if (rci.RowIndex > 0 && rci.ColumnIndex > 0)
|
|
|
+ {
|
|
|
+ if(!OpenCellTooltip(e.ToolTip, rci.RowIndex, rci.ColumnIndex))
|
|
|
+ {
|
|
|
+ e.ToolTip.IsOpen = false;
|
|
|
+ e.ToolTip.Visibility = Visibility.Collapsed;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ e.ToolTip.Visibility = Visibility.Visible;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private void PopulateCellMenu(ContextMenu menu, int row, int column)
|
|
|
{
|
|
|
var data = GetCellData(row, column);
|
|
@@ -455,6 +541,7 @@ namespace PRSDesktop
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
+
|
|
|
}
|
|
|
|
|
|
class EmployeeSelectionGrid : EntitySelectionGrid<Employee>
|