Przeglądaj źródła

wpf: Digital form library is now a DynamicSPlitPanel

Kenric Nugteren 2 tygodni temu
rodzic
commit
4b1b97059f

+ 0 - 35
prs.desktop/Grids/DigitalFormLayoutGrids.cs

@@ -1,35 +0,0 @@
-using Comal.Classes;
-using InABox.Core;
-using InABox.DynamicGrid;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PRSDesktop.Grids
-{
-
-    public class QAFormLayoutGrid : DynamicFormLayoutGrid
-    {
-    }
-
-    public class KanbanQALayoutGrid : DynamicFormLayoutGrid
-    {
-    }
-
-    public class ITPQALayoutGrid : DynamicFormLayoutGrid
-    {
-    }
-
-    public class AssignmentQALayoutGrid : DynamicFormLayoutGrid
-    {
-    }
-
-    public class ManufacturingSectionQALayoutGrid : DynamicFormLayoutGrid
-    {
-    }
-
-    public class ManufacturingPacketStageQALayoutGrid : DynamicFormLayoutGrid
-    {
-    }
-}

+ 1 - 1
prs.desktop/Grids/EntityDocumentGrids/DigitalFormDocumentGrid.cs

@@ -8,6 +8,6 @@ using System.Threading.Tasks;
 
 namespace PRSDesktop;
 
-public class DigitalFormDocumentGrid : DynamicDocumentGrid<DigitalFormDocument, DigitalForm, DigitalFormLink>
+public class DigitalFormDocumentGrid : DynamicDocumentDataGrid<DigitalFormDocument, DigitalForm, DigitalFormLink>
 {
 }

+ 72 - 39
prs.desktop/Panels/DigitalForms/DigitalFormsLibrary.xaml

@@ -11,47 +11,80 @@
                                     SelectionChanged="Tab_SelectionChanged"
                                     TabStripPlacement="Bottom">
         <dynamic_grid:DynamicTabItem x:Name="FormsTab" Header="Digital Forms">
-            <Grid>
-                <Grid.ColumnDefinitions>
-                    <ColumnDefinition Width="Auto" />
-                    <ColumnDefinition Width="*" />
-                </Grid.ColumnDefinitions>
-                <Grid.RowDefinitions>
-                    <RowDefinition Height="*"/>
-                </Grid.RowDefinitions>
+            <dynamic_grid:DynamicSplitPanel Name="FormsSplitPanel"
+                                            AllowableViews="Combined,Master"
+                                            View="Master"
+                                            OnChanged="DynamicSplitPanel_OnChanged"
+                                            MasterCaption="Forms"
+                                            DetailCaption="Form Details"
+                                            Anchor="Master"
+                                            AnchorWidth="600">
+                <dynamic_grid:DynamicSplitPanel.Header>
+                    <Border BorderBrush="Gray" BorderThickness="0.75">
+                        <Label Content="Forms List" HorizontalContentAlignment="Center"/>
+                    </Border>
+                </dynamic_grid:DynamicSplitPanel.Header>
+                <dynamic_grid:DynamicSplitPanel.Master>
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="Auto" />
+                            <ColumnDefinition Width="*" />
+                        </Grid.ColumnDefinitions>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="*"/>
+                        </Grid.RowDefinitions>
 
-                <ListView x:Name="Groups"
-                          Grid.Column="0" Grid.Row="0"
-                          SelectionChanged="Groups_SelectionChanged"
-                          Width="Auto"
-                          Margin="0,0,5,0" BorderBrush="Gray" BorderThickness="0.75" Visibility="Collapsed">
-                    <ListView.ItemTemplate>
-                        <DataTemplate>
-                            <Grid Width="Auto" Margin="0,0,5,0">
-                                <Grid.ColumnDefinitions>
-                                    <ColumnDefinition Width="Auto" />
-                                    <ColumnDefinition Width="*" />
-                                </Grid.ColumnDefinitions>
-                                <Border Width="32" Height="32" CornerRadius="8" Grid.Column="0" Margin="0,5,5,5"
-                                        BorderBrush="Gray" BorderThickness="0.75" HorizontalAlignment="Center">
-                                    <Border.Background>
-                                        <ImageBrush ImageSource="{Binding Path=Item3}" Stretch="UniformToFill" />
-                                    </Border.Background>
-                                </Border>
-                                <TextBlock x:Name="PCName" Grid.Column="1" TextWrapping="WrapWithOverflow" Width="Auto"
-                                           MaxWidth="200" TextAlignment="Left" VerticalAlignment="Center"
-                                           Text="{Binding Item1}" />
-                            </Grid>
-                        </DataTemplate>
-                    </ListView.ItemTemplate>
-                </ListView>
+                        <ListView x:Name="Groups"
+                                  Grid.Column="0" Grid.Row="0"
+                                  SelectionChanged="Groups_SelectionChanged"
+                                  Width="Auto"
+                                  Margin="0,0,5,0" BorderBrush="Gray" BorderThickness="0.75" Visibility="Collapsed">
+                            <ListView.ItemTemplate>
+                                <DataTemplate>
+                                    <Grid Width="Auto" Margin="0,0,5,0">
+                                        <Grid.ColumnDefinitions>
+                                            <ColumnDefinition Width="Auto" />
+                                            <ColumnDefinition Width="*" />
+                                        </Grid.ColumnDefinitions>
+                                        <Border Width="32" Height="32" CornerRadius="8" Grid.Column="0" Margin="0,5,5,5"
+                                                BorderBrush="Gray" BorderThickness="0.75" HorizontalAlignment="Center">
+                                            <Border.Background>
+                                                <ImageBrush ImageSource="{Binding Path=Item3}" Stretch="UniformToFill" />
+                                            </Border.Background>
+                                        </Border>
+                                        <TextBlock x:Name="PCName" Grid.Column="1" TextWrapping="WrapWithOverflow" Width="Auto"
+                                                   MaxWidth="200" TextAlignment="Left" VerticalAlignment="Center"
+                                                   Text="{Binding Item1}" />
+                                    </Grid>
+                                </DataTemplate>
+                            </ListView.ItemTemplate>
+                        </ListView>
 
-                <dynamic_grid:DigitalFormGrid x:Name="Forms"
-                                              Grid.Row="0" Grid.Column="1"
-                                              AfterRefresh="Forms_AfterRefresh"
-                                              OnCreateItem="Forms_OnCreateItem"
-                                              OnFilterRecord="Forms_OnFilterRecord"/>
-            </Grid>
+                        <dynamic_grid:DigitalFormGrid x:Name="Forms"
+                                                      Grid.Row="0" Grid.Column="1"
+                                                      AfterRefresh="Forms_AfterRefresh"
+                                                      OnCreateItem="Forms_OnCreateItem"
+                                                      OnFilterRecord="Forms_OnFilterRecord"
+                                                      OnSelectItem="Forms_OnSelectItem"/>
+                    </Grid>
+                </dynamic_grid:DynamicSplitPanel.Master>
+                <dynamic_grid:DynamicSplitPanel.Detail>
+                    <dynamic_grid:DynamicTabControl Name="DetailsTabControl">
+                        <dynamic_grid:DynamicTabItem Header="Variables">
+                            <dynamic_grid:DynamicVariableGrid Name="Variables"/>
+                        </dynamic_grid:DynamicTabItem>
+                        <dynamic_grid:DynamicTabItem Header="Layouts">
+                            <dynamic_grid:DynamicFormLayoutGrid Name="Layouts"/>
+                        </dynamic_grid:DynamicTabItem>
+                        <dynamic_grid:DynamicTabItem Header="Documents">
+                            <local:DigitalFormDocumentGrid x:Name="Documents"/>
+                        </dynamic_grid:DynamicTabItem>
+                        <dynamic_grid:DynamicTabItem Header="Reports">
+                            <dynamic_grid:DigitalFormReportGrid Name="Reports"/>
+                        </dynamic_grid:DynamicTabItem>
+                    </dynamic_grid:DynamicTabControl>
+                </dynamic_grid:DynamicSplitPanel.Detail>
+            </dynamic_grid:DynamicSplitPanel>
         </dynamic_grid:DynamicTabItem>
         <dynamic_grid:DynamicTabItem x:Name="RolesTab" Header="Roles">
             <local:DigitalFormRoleCrossTab x:Name="DigitalFormRoles"/>

+ 90 - 1
prs.desktop/Panels/DigitalForms/DigitalFormsLibrary.xaml.cs

@@ -18,13 +18,27 @@ using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using System.Windows.Shapes;
+using InABox.Configuration;
+using System.Runtime.CompilerServices;
 
 namespace PRSDesktop;
 
+public class DigitalFormsLibrarySettings : IUserConfigurationSettings
+{
+    public DynamicSplitPanelView View { get; set; }
+    public double AnchorWidth { get; set; }
+
+    public DigitalFormsLibrarySettings()
+    {
+        View = DynamicSplitPanelView.Combined;
+        AnchorWidth = 700;
+    }
+}
+
 /// <summary>
 /// Interaction logic for DigitalFormsLibrary.xaml
 /// </summary>
-public partial class DigitalFormsLibrary : UserControl, IPanel<DigitalForm>
+public partial class DigitalFormsLibrary : UserControl, IPanel<DigitalForm>, INotifyPropertyChanged
 {
     private string? CurrentGroup = null;
 
@@ -34,11 +48,47 @@ public partial class DigitalFormsLibrary : UserControl, IPanel<DigitalForm>
 
     private bool _refreshing;
 
+    private DigitalFormsLibrarySettings _settings;
+
+    public event PropertyChangedEventHandler? PropertyChanged;
+
+    private bool _detailsEnabled;
+    public bool DetailsEnabled
+    {
+        get => _detailsEnabled;
+        set
+        {
+            _detailsEnabled = value;
+            OnPropertyChanged();
+        }
+    }
+
     public DigitalFormsLibrary()
     {
         InitializeComponent();
+
+        Variables.Bind(IsEnabledProperty, this, x => x.DetailsEnabled, mode: BindingMode.OneWay);
+        Layouts.Bind(IsEnabledProperty, this, x => x.DetailsEnabled);
+        Reports.Bind(IsEnabledProperty, this, x => x.DetailsEnabled);
+        Documents.Bind(IsEnabledProperty, this, x => x.DetailsEnabled);
     }
 
+    private void DoLoadSettings()
+    {
+        _settings = new UserConfiguration<DigitalFormsLibrarySettings>().Load();
+
+        FormsSplitPanel.View = _settings.View;
+        FormsSplitPanel.AnchorWidth = _settings.AnchorWidth;
+    }
+    
+    private void DoSaveSettings()
+    {
+        _settings.View = FormsSplitPanel.View;
+        _settings.AnchorWidth = FormsSplitPanel.AnchorWidth;
+        new UserConfiguration<DigitalFormsLibrarySettings>().Save(_settings);
+    }
+        
+
     #region Panel Stuff
 
     public bool IsReady { get; set; }
@@ -66,7 +116,17 @@ public partial class DigitalFormsLibrary : UserControl, IPanel<DigitalForm>
 
     public void Setup()
     {
+        DoLoadSettings();
+
+        Layouts.VariableGrid = Variables;
+        Reports.VariableGrid = Variables;
+        Reports.LayoutGrid = Layouts;
+
         Forms.Refresh(true, false);
+        Variables.Refresh(true, false);
+        Layouts.Refresh(true, false);
+        Reports.Refresh(true, false);
+        Documents.Refresh(true, false);
 
         RolesTab.Visibility = Security.CanView<DigitalForm>()
             && Security.CanView<Role>()
@@ -125,6 +185,20 @@ public partial class DigitalFormsLibrary : UserControl, IPanel<DigitalForm>
 
     #endregion
 
+    private void Forms_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
+    {
+        var form = e.Rows?.FirstOrDefault()?.ToObject<DigitalForm>();
+        DetailsEnabled = form is not null;
+        Layouts.Form = form;
+        Layouts.Refresh(false, true);
+        Variables.Form = form;
+        Variables.Refresh(false, true);
+        Reports.Form = form;
+        Reports.Refresh(false, true);
+        Documents.Item = form;
+        Documents.Refresh(false, true);
+    }
+
     private void Groups_SelectionChanged(object sender, SelectionChangedEventArgs e)
     {
         if (_refreshing || e.OriginalSource != Groups)
@@ -207,4 +281,19 @@ public partial class DigitalFormsLibrary : UserControl, IPanel<DigitalForm>
     {
         return AllItems || Equals(row.Get<DigitalForm, string>(x => x.AppliesTo), CurrentGroup);
     }
+
+    private void DynamicSplitPanel_OnChanged(object sender, DynamicSplitPanelSettings e)
+    {
+        DoSaveSettings();
+        if (FormsSplitPanel.IsDetailVisible())
+        {
+            Layouts.Refresh(false, true);
+            Variables.Refresh(false, true);
+        }
+    }
+
+    private void OnPropertyChanged([CallerMemberName] string? property = null)
+    {
+        PropertyChanged?.Invoke(this, new(property));
+    }
 }

+ 224 - 225
prs.desktop/Panels/Employees/EmployeePanel.xaml.cs

@@ -13,277 +13,276 @@ using InABox.DynamicGrid;
 using InABox.WPF;
 using InABox.Wpf;
 
-namespace PRSDesktop
-{
+namespace PRSDesktop;
 
-    public class EmployeePanelSettings : IUserConfigurationSettings
-    {
-        public DynamicSplitPanelView View { get; set; }
-        public double AnchorWidth { get; set; }
-        
-        public double RoleHeight { get; set; }
-        public double RosterHeight { get; set; }
 
-        public EmployeePanelSettings()
-        {
-            View = DynamicSplitPanelView.Combined;
-            AnchorWidth = 250;
-            RoleHeight = 250;
-            RosterHeight = 400;
-        }
-    }
+public class EmployeePanelSettings : IUserConfigurationSettings
+{
+    public DynamicSplitPanelView View { get; set; }
+    public double AnchorWidth { get; set; }
     
-    /// <summary>
-    ///     Interaction logic for EmployeePanel.xaml
-    /// </summary>
-    public partial class EmployeePanel : UserControl, IPanel<Employee>
+    public double RoleHeight { get; set; }
+    public double RosterHeight { get; set; }
+
+    public EmployeePanelSettings()
     {
+        View = DynamicSplitPanelView.Combined;
+        AnchorWidth = 250;
+        RoleHeight = 250;
+        RosterHeight = 400;
+    }
+}
 
-        private enum Suppress
-        {
-            Events
-        }
+/// <summary>
+///     Interaction logic for EmployeePanel.xaml
+/// </summary>
+public partial class EmployeePanel : UserControl, IPanel<Employee>
+{
 
-        private EmployeePanelSettings _settings;
+    private enum Suppress
+    {
+        Events
+    }
 
-        private void DoLoadSettings()
-        {
-            using (new EventSuppressor(Suppress.Events))
-            {
-                _settings = new UserConfiguration<EmployeePanelSettings>().Load();
+    private EmployeePanelSettings _settings;
 
-                SplitPanel.View = _settings.View;
-                SplitPanel.AnchorWidth = _settings.AnchorWidth;
-                RoleGridRow.Height = new GridLength(_settings.RoleHeight, GridUnitType.Pixel);
-                RosterGridRow.Height = new GridLength(_settings.RosterHeight, GridUnitType.Pixel);
-             }
-        }
-        
-        private void DoSaveSettings()
-        {
-            _settings.View = SplitPanel.View;
-            _settings.AnchorWidth = SplitPanel.AnchorWidth;
-            _settings.RoleHeight = RoleGridRow.Height.Value;
-            _settings.RosterHeight = RosterGridRow.Height.Value;
-            new UserConfiguration<EmployeePanelSettings>().Save(_settings);
-        }
-        
-        public EmployeePanel()
+    private void DoLoadSettings()
+    {
+        using (new EventSuppressor(Suppress.Events))
         {
-            using (new EventSuppressor(Suppress.Events))
-                InitializeComponent();
-        }
+            _settings = new UserConfiguration<EmployeePanelSettings>().Load();
+
+            SplitPanel.View = _settings.View;
+            SplitPanel.AnchorWidth = _settings.AnchorWidth;
+            RoleGridRow.Height = new GridLength(_settings.RoleHeight, GridUnitType.Pixel);
+            RosterGridRow.Height = new GridLength(_settings.RosterHeight, GridUnitType.Pixel);
+         }
+    }
+    
+    private void DoSaveSettings()
+    {
+        _settings.View = SplitPanel.View;
+        _settings.AnchorWidth = SplitPanel.AnchorWidth;
+        _settings.RoleHeight = RoleGridRow.Height.Value;
+        _settings.RosterHeight = RosterGridRow.Height.Value;
+        new UserConfiguration<EmployeePanelSettings>().Save(_settings);
+    }
+    
+    public EmployeePanel()
+    {
+        using (new EventSuppressor(Suppress.Events))
+            InitializeComponent();
+    }
 
-        public bool IsReady { get; set; }
+    public bool IsReady { get; set; }
 
 
-        public event DataModelUpdateEvent? OnUpdateDataModel;
+    public event DataModelUpdateEvent? OnUpdateDataModel;
 
-        public Dictionary<string, object[]> Selected()
-        {
-            return new Dictionary<string, object[]> { { typeof(Employee).EntityName(), Employees.SelectedRows } };
-        }
+    public Dictionary<string, object[]> Selected()
+    {
+        return new Dictionary<string, object[]> { { typeof(Employee).EntityName(), Employees.SelectedRows } };
+    }
 
-        public void Setup()
+    public void Setup()
+    {
+        using (new EventSuppressor(Suppress.Events))
         {
-            using (new EventSuppressor(Suppress.Events))
+            DoLoadSettings();
+
+            Employees.HiddenColumns.Add(x => x.RosterTemplate.ID);
+            Employees.HiddenColumns.Add(x => x.RosterStart);
+
+            Employees.Refresh(true, false);
+            Rosters.Refresh(true, false);
+            Teams.Refresh(true, false);
+            Roles.Refresh(true, false);
+            Activities.Refresh(true, false);
+            Forms.Refresh(true, false);
+            Qualifications.Refresh(true, false);
+            Spreadsheets.Refresh(true, false);
+            Jobs.Refresh(true, false);
+
+            RoleCrossTab.Visibility = Security.CanView<Employee>()
+                && Security.CanView<Role>()
+                && Security.CanView<EmployeeRole>() ? Visibility.Visible : Visibility.Collapsed;
+            var visibleTabItems = Tab.Items.OfType<DynamicTabItem>().Where(x => x.Visibility == Visibility.Visible).ToList();
+            if(visibleTabItems.Count <= 1)
             {
-                DoLoadSettings();
-
-                Employees.HiddenColumns.Add(x => x.RosterTemplate.ID);
-                Employees.HiddenColumns.Add(x => x.RosterStart);
-
-                Employees.Refresh(true, false);
-                Rosters.Refresh(true, false);
-                Teams.Refresh(true, false);
-                Roles.Refresh(true, false);
-                Activities.Refresh(true, false);
-                Forms.Refresh(true, false);
-                Qualifications.Refresh(true, false);
-                Spreadsheets.Refresh(true, false);
-                Jobs.Refresh(true, false);
-
-                RoleCrossTab.Visibility = Security.CanView<Employee>()
-                    && Security.CanView<Role>()
-                    && Security.CanView<EmployeeRole>() ? Visibility.Visible : Visibility.Collapsed;
-                var visibleTabItems = Tab.Items.OfType<DynamicTabItem>().Where(x => x.Visibility == Visibility.Visible).ToList();
-                if(visibleTabItems.Count <= 1)
+                foreach(var tab in visibleTabItems)
                 {
-                    foreach(var tab in visibleTabItems)
-                    {
-                        tab.Visibility = Visibility.Collapsed;
-                        Tab.SelectedItem = tab;
-                    }
+                    tab.Visibility = Visibility.Collapsed;
+                    Tab.SelectedItem = tab;
                 }
             }
         }
+    }
 
-        public void Shutdown(CancelEventArgs? cancel)
-        {
-        }
+    public void Shutdown(CancelEventArgs? cancel)
+    {
+    }
 
-        public void CreateToolbarButtons(IPanelHost host)
-        {
-            HumanResourcesSetupActions.SecurityGroups(host);
-            host.CreateSetupSeparator();
-            HumanResourcesSetupActions.EmployeeGroups(host);
-            HumanResourcesSetupActions.EmployeePositions(host);
-            HumanResourcesSetupActions.EmployeeRoles(host);
-            HumanResourcesSetupActions.EmployeeTeams(host);
-            HumanResourcesSetupActions.EmployeeActivities(host);
-            HumanResourcesSetupActions.EmployeeQualifications(host);
-            HumanResourcesSetupActions.EmployeeRosters(host);
-            host.CreateSetupSeparator();
-            HumanResourcesSetupActions.EmployeeOvertimeRules(host);
-            HumanResourcesSetupActions.EmployeeOvertime(host);
-            HumanResourcesSetupActions.EmployeeStandardLeave(host);
-            host.CreateSetupSeparator();
-            HumanResourcesSetupActions.EmployeeSpreadsheetTemplates(host);
-        }
+    public void CreateToolbarButtons(IPanelHost host)
+    {
+        HumanResourcesSetupActions.SecurityGroups(host);
+        host.CreateSetupSeparator();
+        HumanResourcesSetupActions.EmployeeGroups(host);
+        HumanResourcesSetupActions.EmployeePositions(host);
+        HumanResourcesSetupActions.EmployeeRoles(host);
+        HumanResourcesSetupActions.EmployeeTeams(host);
+        HumanResourcesSetupActions.EmployeeActivities(host);
+        HumanResourcesSetupActions.EmployeeQualifications(host);
+        HumanResourcesSetupActions.EmployeeRosters(host);
+        host.CreateSetupSeparator();
+        HumanResourcesSetupActions.EmployeeOvertimeRules(host);
+        HumanResourcesSetupActions.EmployeeOvertime(host);
+        HumanResourcesSetupActions.EmployeeStandardLeave(host);
+        host.CreateSetupSeparator();
+        HumanResourcesSetupActions.EmployeeSpreadsheetTemplates(host);
+    }
 
-        private bool _loaded = false;
+    private bool _loaded = false;
 
-        private void Tab_SelectionChanged(object sender, SelectionChangedEventArgs e)
-        {
-            if (sender != Tab || !_loaded) return;
-            RefreshCurrentTab();
-        }
+    private void Tab_SelectionChanged(object sender, SelectionChangedEventArgs e)
+    {
+        if (sender != Tab || !_loaded) return;
+        RefreshCurrentTab();
+    }
 
-        private void RefreshCurrentTab()
+    private void RefreshCurrentTab()
+    {
+        if (Tab.SelectedTab == EmployeeTab)
         {
-            if (Tab.SelectedTab == EmployeeTab)
-            {
-                RefreshEmployeeTab();
-            }
-            else if (Tab.SelectedTab == RoleCrossTab)
-            {
-                RefreshRoleTab();
-            }
+            RefreshEmployeeTab();
         }
-
-        private void RefreshRoleTab()
+        else if (Tab.SelectedTab == RoleCrossTab)
         {
-            EmployeeRoles.Refresh(true, true);
+            RefreshRoleTab();
         }
+    }
 
-        private void RefreshEmployeeTab()
-        {
-            Employees.Refresh(false, true);
-            Rosters.Refresh(false, true);
-            Teams.Refresh(false, true);
-            Roles.Refresh(false, true);
-            Activities.Refresh(false, true);
-            Forms.Refresh(false, true);
-            Qualifications.Refresh(false, true);
-            Spreadsheets.Refresh(false, true);
-            Jobs.Refresh(false, true);
-        }
+    private void RefreshRoleTab()
+    {
+        EmployeeRoles.Refresh(true, true);
+    }
 
-        public void Refresh()
-        {
-            RefreshCurrentTab();
-            _loaded = true;
-        }
+    private void RefreshEmployeeTab()
+    {
+        Employees.Refresh(false, true);
+        Rosters.Refresh(false, true);
+        Teams.Refresh(false, true);
+        Roles.Refresh(false, true);
+        Activities.Refresh(false, true);
+        Forms.Refresh(false, true);
+        Qualifications.Refresh(false, true);
+        Spreadsheets.Refresh(false, true);
+        Jobs.Refresh(false, true);
+    }
 
-        public string SectionName => "Employees";
+    public void Refresh()
+    {
+        RefreshCurrentTab();
+        _loaded = true;
+    }
 
-        public DataModel DataModel(Selection selection)
-        {
-            var ids = Employees.ExtractValues(x => x.ID, selection).ToArray();
-            return new AutoDataModel<Employee>(Filter<Employee>.Where(x => x.ID).InList(ids));
-        }
+    public string SectionName => "Employees";
 
-        public void Heartbeat(TimeSpan time)
-        {
-        }
+    public DataModel DataModel(Selection selection)
+    {
+        var ids = Employees.ExtractValues(x => x.ID, selection).ToArray();
+        return new AutoDataModel<Employee>(Filter<Employee>.Where(x => x.ID).InList(ids));
+    }
 
-        private void Employees_OnOnSelectItem(object sender, DynamicGridSelectionEventArgs e)
-        {
-            var employee = e.Rows?.FirstOrDefault()?.ToObject<Employee>() ?? new Employee();
+    public void Heartbeat(TimeSpan time)
+    {
+    }
 
-            Rosters.Load(employee, null);
-            //Rosters.Refresh(false, true);
+    private void Employees_OnOnSelectItem(object sender, DynamicGridSelectionEventArgs e)
+    {
+        var employee = e.Rows?.FirstOrDefault()?.ToObject<Employee>() ?? new Employee();
 
-            Teams.EmployeeID = employee.ID;
-            Teams.Refresh(false, true);
+        Rosters.Load(employee, null);
+        //Rosters.Refresh(false, true);
 
-            //LoadEmployeeThumbnail(employee.Thumbnail.ID);
-            
-            Roles.EmployeeID = employee.ID;
-            Roles.Refresh(false, true);
+        Teams.EmployeeID = employee.ID;
+        Teams.Refresh(false, true);
 
-            Activities.Left = employee;
-            Activities.Refresh(false,true);
+        //LoadEmployeeThumbnail(employee.Thumbnail.ID);
+        
+        Roles.EmployeeID = employee.ID;
+        Roles.Refresh(false, true);
 
-            Forms.Left = employee;
-            Forms.Refresh(false, true);
-            
-            Qualifications.Load(employee, null);
+        Activities.Left = employee;
+        Activities.Refresh(false,true);
 
-            Spreadsheets.Master = employee;
-            Spreadsheets.Refresh(false,true);
+        Forms.Left = employee;
+        Forms.Refresh(false, true);
+        
+        Qualifications.Load(employee, null);
 
-            Jobs.Left = employee;
-            Jobs.Refresh(false, true);
-        }
+        Spreadsheets.Master = employee;
+        Spreadsheets.Refresh(false,true);
 
-        // private void LoadEmployeeThumbnail(Guid imageid)
-        // {
-        //     Thumbnail.Source = null;
-        //     if (imageid == Guid.Empty)
-        //         return;
-        //     Bitmap result = null;
-        //     new Client<Document>().Query(
-        //         Filter<Document>.Where(x => x.ID).IsEqualTo(imageid),
-        //         new Columns<Document>(x => x.ID, x => x.Data),
-        //         null,
-        //         (o, e) => Dispatcher.Invoke(() =>
-        //         {
-        //             if (o?.Rows.Any() == true)
-        //             {
-        //                 var ms = new MemoryStream(o.Rows.First().Get<Document, byte[]>(x => x.Data));
-        //                 Thumbnail.Source = new Bitmap(ms).AsBitmapImage();
-        //             }
-        //         })
-        //     );
-        // }
-
-        private void SplitPanel_OnChanged(object sender, DynamicSplitPanelSettings e)
-        {
-            if (EventSuppressor.IsSet(Suppress.Events))
-                return;
-            DoSaveSettings();
-        }
-        
-        private void Roles_OnSizeChanged(object sender, SizeChangedEventArgs e)
-        {
-            if (EventSuppressor.IsSet(Suppress.Events))
-                return;
-            DoSaveSettings();
-        }
-        
-        private void Roles_OnOnChanged(object sender, EventArgs args)
-        {
-            Activities.Refresh(false,true);
-            Forms.Refresh(false, true);
-        }
+        Jobs.Left = employee;
+        Jobs.Refresh(false, true);
+    }
 
+    // private void LoadEmployeeThumbnail(Guid imageid)
+    // {
+    //     Thumbnail.Source = null;
+    //     if (imageid == Guid.Empty)
+    //         return;
+    //     Bitmap result = null;
+    //     new Client<Document>().Query(
+    //         Filter<Document>.Where(x => x.ID).IsEqualTo(imageid),
+    //         new Columns<Document>(x => x.ID, x => x.Data),
+    //         null,
+    //         (o, e) => Dispatcher.Invoke(() =>
+    //         {
+    //             if (o?.Rows.Any() == true)
+    //             {
+    //                 var ms = new MemoryStream(o.Rows.First().Get<Document, byte[]>(x => x.Data));
+    //                 Thumbnail.Source = new Bitmap(ms).AsBitmapImage();
+    //             }
+    //         })
+    //     );
+    // }
+
+    private void SplitPanel_OnChanged(object sender, DynamicSplitPanelSettings e)
+    {
+        if (EventSuppressor.IsSet(Suppress.Events))
+            return;
+        DoSaveSettings();
+    }
+    
+    private void Roles_OnSizeChanged(object sender, SizeChangedEventArgs e)
+    {
+        if (EventSuppressor.IsSet(Suppress.Events))
+            return;
+        DoSaveSettings();
+    }
+    
+    private void Roles_OnOnChanged(object sender, EventArgs args)
+    {
+        Activities.Refresh(false,true);
+        Forms.Refresh(false, true);
+    }
 
-        private void Rosters_OnOnChanged(object sender, EventArgs args)
-        {
-            //Employees.Refresh(false, true);
-        }
 
-        private void Rosters_OnSizeChanged(object sender, SizeChangedEventArgs e)
-        {
-            if (EventSuppressor.IsSet(Suppress.Events))
-                return;
-            DoSaveSettings();
-        }
+    private void Rosters_OnOnChanged(object sender, EventArgs args)
+    {
+        //Employees.Refresh(false, true);
+    }
 
-        private void Rosters_EmployeeChanged()
-        {
-            Employees.Refresh(false, true);
-        }
+    private void Rosters_OnSizeChanged(object sender, SizeChangedEventArgs e)
+    {
+        if (EventSuppressor.IsSet(Suppress.Events))
+            return;
+        DoSaveSettings();
+    }
+
+    private void Rosters_EmployeeChanged()
+    {
+        Employees.Refresh(false, true);
     }
 }