Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/30/18 11:32:56 (6 years ago)
Author:
jkarder
Message:

#2839: merged [15377-16116/branches/2839_HiveProjectManagement] into trunk

Location:
trunk
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/HeuristicLab.Clients.Hive.Administrator

  • trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.cs

    r15760 r16117  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    3737    private const int slaveImageIndex = 0;
    3838    private const int slaveGroupImageIndex = 1;
    39     public const string ungroupedGroupName = "UNGROUPED";
    40     public const string ungroupedGroupDescription = "Contains slaves that are not assigned to any group.";
     39    public const string UNGROUPED_GROUP_NAME = "UNGROUPED";
     40    public const string UNGROUPED_GROUP_DESCRIPTION = "Contains slaves that are not assigned to any group.";
     41    public const string IMMUTABLE_TAG = " [assigned, immutable]";
     42    public const string INCLUDED_TAG = " [included]";
     43    public const string ADDED_ASSIGNMENT_TAG = " [added assignment]";
     44    public const string REMOVED_ASSIGNMENT_TAG = " [removed assignment]";
     45    public const string ADDED_INCLUDE_TAG = " [added include]";
     46    public const string REMOVED_INCLUDE_TAG = " [removed include]";
    4147
    4248    private readonly HashSet<Resource> assignedResources = new HashSet<Resource>();
    4349    private readonly HashSet<Resource> newAssignedResources = new HashSet<Resource>();
    44     private readonly HashSet<Resource> inheritedResources = new HashSet<Resource>();
    45     private readonly HashSet<Resource> newInheritedResources = new HashSet<Resource>();
    46 
    47     private readonly Dictionary<Guid, HashSet<Project>> projectAncestors = new Dictionary<Guid, HashSet<Project>>();
    48     private readonly Dictionary<Guid, HashSet<Project>> projectDescendants = new Dictionary<Guid, HashSet<Project>>();
    49     private readonly Dictionary<Guid, HashSet<Resource>> resourceAncestors = new Dictionary<Guid, HashSet<Resource>>();
    50     private readonly Dictionary<Guid, HashSet<Resource>> resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
     50    private readonly HashSet<Resource> includedResources = new HashSet<Resource>();
     51    private readonly HashSet<Resource> newIncludedResources = new HashSet<Resource>();
    5152
    5253    private readonly Color addedAssignmentColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
     
    5455    private readonly Color addedIncludeColor = Color.FromArgb(25, 169, 221, 221); // #a9dddd
    5556    private readonly Color removedIncludeColor = Color.FromArgb(25, 249, 210, 145); // #f9d291
     57    private readonly Color selectedBackColor = Color.DodgerBlue;
     58    private readonly Color selectedForeColor = Color.White;
     59    private readonly Color grayTextColor = SystemColors.GrayText;
     60
     61    private HashSet<Resource> projectExclusiveResources = new HashSet<Resource>();
     62    private TreeNode ungroupedGroupNode;
    5663
    5764    public new Project Content {
     
    7380        assignedResources.Clear();
    7481        newAssignedResources.Clear();
    75         inheritedResources.Clear();
    76         resourceAncestors.Clear();
     82        includedResources.Clear();
    7783        treeView.Nodes.Clear();
    7884        detailsViewHost.Content = null;
    7985      } else {
    80         UpdateProjectGenealogy();
    8186        UpdateAssignedResources();
    82         UpdateResourceGenealogy();
    83         var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
     87        UpdateIncludedResources();
     88        var top = BuildResourceTree();
    8489        detailsViewHost.Content = top;
     90        detailsViewHost.Locked = true;
    8591      }
    8692    }
     
    102108
    103109    private void refreshButton_Click(object sender, EventArgs e) {
    104       UpdateProjectGenealogy();
     110      HiveAdminClient.Instance.Refresh();
    105111      UpdateAssignedResources();
    106       UpdateResourceGenealogy();
    107       var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
     112      UpdateIncludedResources();
     113      var top = BuildResourceTree();
    108114      detailsViewHost.Content = top;
    109115    }
     
    114120          SetAssignedProjectResources(Content.Id, newAssignedResources.Select(x => x.Id), false, true, false);
    115121        });
     122      HiveAdminClient.Instance.Refresh();
    116123      UpdateResourceTree();
    117124    }
     
    122129          SetAssignedProjectResources(Content.Id, newAssignedResources.Select(x => x.Id), false, false, false);
    123130        });
     131      HiveAdminClient.Instance.Refresh();
    124132      UpdateResourceTree();
     133    }
     134
     135    private void treeView_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
     136      if (e.Node == null || e.Node == ungroupedGroupNode)
     137        e.Cancel = true;
     138
     139      var selectedResource = (Resource)e.Node.Tag;
     140      if(HiveAdminClient.Instance.DisabledParentResources.Contains(selectedResource))
     141        e.Cancel = true;
    125142    }
    126143
     
    131148
    132149    private void treeView_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
     150      if (e.Node == null || e.Node == ungroupedGroupNode) {
     151        e.Cancel = true;
     152        return;
     153      }
     154       
    133155      var checkedResource = (Resource)e.Node.Tag;
    134       if (newInheritedResources.Contains(checkedResource) || checkedResource.Id == Guid.Empty) {
     156      if (checkedResource == null
     157        || checkedResource.Id == Guid.Empty
     158        || HiveAdminClient.Instance.DisabledParentResources.Contains(checkedResource)
     159        || newIncludedResources.Contains(checkedResource)) {
    135160        e.Cancel = true;
    136       } else if (!HiveRoles.CheckAdminUserPermissions()) {
    137           if (!projectAncestors[Content.Id].Any()) {
     161      } else if (!IsAdmin()) {
     162          if (!HiveAdminClient.Instance.CheckOwnershipOfParentProject(Content, UserInformation.Instance.User.Id)
     163            || !HiveAdminClient.Instance.GetAvailableProjectAncestors(Content.Id).Any()
     164            || projectExclusiveResources.Contains(checkedResource)) {
    138165            e.Cancel = true;
    139166          }
     
    157184    private void UpdateResourceTree() {
    158185      UpdateAssignedResources();
    159       UpdateResourceGenealogy();
    160       var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
     186      UpdateIncludedResources();
     187
     188      var top = BuildResourceTree();
    161189      detailsViewHost.Content = top;
    162190    }
     
    164192    private void UpdateNewResourceTree() {
    165193      UpdateNewAssignedResources();
    166       UpdateNewInheritedResources();
    167       var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
     194      UpdateNewIncludedResources();
     195      var top = BuildResourceTree();
    168196      detailsViewHost.Content = top;
    169197    }
    170198
    171     private static IEnumerable<Resource> GetAssignedResourcesForProject(Guid projectId) {
    172       var assignedProjectResources = HiveServiceLocator.Instance.CallHiveService(s => s.GetAssignedResourcesForProjectAdministration(projectId));
    173       return HiveAdminClient.Instance.Resources.Where(x => assignedProjectResources.Select(y => y.ResourceId).Contains(x.Id));
     199    private IEnumerable<Resource> GetAvailableResourcesForProjectAdministration(Guid projectId) {
     200      projectExclusiveResources.Clear();
     201      if (projectId == Guid.Empty) return Enumerable.Empty<Resource>();
     202      var resources = HiveAdminClient.Instance.Resources.Where(x => x.Id != Guid.Empty);
     203      if (!resources.Any()) return resources;
     204      if (IsAdmin()) return resources;
     205
     206      // get project specific assigned resources
     207      var projectResources = resources.Where(x =>
     208        HiveAdminClient.Instance.ProjectResourceAssignments
     209          .Where(a => a.ProjectId == projectId)
     210          .Select(a => a.ResourceId)
     211        .Contains(x.Id));
     212
     213      // look up for assignments of ancestor projects
     214      var projectIds = new HashSet<Guid>();
     215      HiveAdminClient.Instance.GetAvailableProjectAncestors(projectId).ToList().ForEach(x => projectIds.Add(x.Id));
     216
     217      var ancestorProjectResources = resources.Where(x =>
     218        HiveAdminClient.Instance.ProjectResourceAssignments
     219          .Where(a => projectIds.Contains(a.ProjectId))
     220          .Select(a => a.ResourceId)
     221        .Contains(x.Id));
     222
     223      // look down for included resources of ancestor projects
     224      HashSet<Resource> availableResources = new HashSet<Resource>(ancestorProjectResources);
     225      foreach (var r in ancestorProjectResources) {
     226        foreach(var d in HiveAdminClient.Instance.GetAvailableResourceDescendants(r.Id)) {
     227          availableResources.Add(d);
     228        }
     229      }
     230
     231      // determine resources, which are exclusively assigned to the currently selected project
     232      projectResources
     233        .Except(availableResources)
     234        .ToList()
     235        .ForEach(x => projectExclusiveResources.Add(x));
     236
     237      // look down for included resources of currently selected project
     238      if (projectExclusiveResources.Any()) {
     239        foreach (var r in projectExclusiveResources.ToArray()) {
     240          foreach (var d in HiveAdminClient.Instance.GetAvailableResourceDescendants(r.Id)) {
     241            projectExclusiveResources.Add(d);
     242          } 
     243        }
     244      }
     245
     246      return availableResources.Union(projectExclusiveResources);
     247    }
     248
     249    private IEnumerable<Resource> GetAssignedResourcesForProject(Guid projectId) {
     250      if (projectId == Guid.Empty) return Enumerable.Empty<Resource>();
     251      return HiveAdminClient.Instance.Resources.Where(x =>
     252        HiveAdminClient.Instance.ProjectResourceAssignments
     253          .Where(a => a.ProjectId == projectId)
     254          .Select(a => a.ResourceId)
     255        .Contains(x.Id));
    174256    }
    175257
     
    183265    private void UpdateNewAssignedResources() {
    184266      for(int i = newAssignedResources.Count -1; i >= 0; i--) {
    185         if(newAssignedResources.Intersect(resourceAncestors[newAssignedResources.ElementAt(i).Id]).Any()) {
     267        if(newAssignedResources.Intersect(HiveAdminClient.Instance.GetAvailableResourceAncestors(newAssignedResources.ElementAt(i).Id)).Any()) {
    186268          newAssignedResources.Remove(newAssignedResources.ElementAt(i));
    187269        }
     
    198280    }
    199281
    200     private void UpdateNewInheritedResources() {
    201       newInheritedResources.Clear();
     282    private void UpdateIncludedResources() {
     283      includedResources.Clear();
     284      newIncludedResources.Clear();
     285      foreach (var a in assignedResources) {
     286        foreach (var r in HiveAdminClient.Instance.GetAvailableResourceDescendants(a.Id)) {
     287          includedResources.Add(r);
     288          newIncludedResources.Add(r);
     289        }
     290      }
     291    }
     292
     293    private void UpdateNewIncludedResources() {
     294      newIncludedResources.Clear();
    202295      foreach (var a in newAssignedResources) {
    203         if (resourceDescendants.ContainsKey(a.Id)) {
    204           foreach (var r in resourceDescendants[a.Id]) {
    205             newInheritedResources.Add(r);
    206           }
    207         }
    208       }
    209     }
    210 
    211     private void UpdateResourceGenealogy() {
    212       resourceAncestors.Clear();
    213       resourceDescendants.Clear();
    214       var resources = HiveAdminClient.Instance.Resources;
    215 
    216       foreach(var r in resources.Where(x => x.Id != Guid.Empty)) {
    217         resourceAncestors.Add(r.Id, new HashSet<Resource>());
    218         resourceDescendants.Add(r.Id, new HashSet<Resource>());
    219       }
    220 
    221       foreach(var r in resources.Where(x => x.Id != Guid.Empty)) {
    222         var parentResourceId = r.ParentResourceId;
    223         while(parentResourceId != null) {
    224           var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
    225           if(parent != null) {
    226             resourceAncestors[r.Id].Add(parent);
    227             resourceDescendants[parent.Id].Add(r);
    228             parentResourceId = parent.ParentResourceId;
    229           } else {
    230             parentResourceId = null;
    231           }
    232         }
    233       }
    234 
    235       inheritedResources.Clear();
    236       newInheritedResources.Clear();
    237       foreach(var a in assignedResources) {
    238         if (resourceDescendants.ContainsKey(a.Id)) {
    239           foreach(var r in resourceDescendants[a.Id]) {
    240             inheritedResources.Add(r);
    241             newInheritedResources.Add(r);
    242           }
    243         }
    244       }
    245 
    246       //foreach(var r in resources) {
    247       //  if (resourceAncestors.ContainsKey(r.Id)
    248       //    && resourceAncestors[r.Id].Intersect(assignedResources.Select(x => x.Id)).Any()) {
    249       //    inheritedResources.Add(r);
    250       //  }
    251       //}
    252     }
    253 
    254     private Resource BuildResourceTree(IEnumerable<Resource> resources) {
     296        foreach (var r in HiveAdminClient.Instance.GetAvailableResourceDescendants(a.Id)) {
     297          newIncludedResources.Add(r);
     298        }
     299      }
     300    }
     301
     302    private Resource BuildResourceTree() {
    255303      treeView.Nodes.Clear();
    256       if (!resources.Any()) return null;
    257304
    258305      treeView.BeforeCheck -= treeView_BeforeCheck;
    259306      treeView.AfterCheck -= treeView_AfterCheck;
    260307
    261       resources = resources.Where(x => x.Id != Guid.Empty);
     308      var resources = GetAvailableResourcesForProjectAdministration(Content.Id);
     309
     310      var disabledParentResources = HiveAdminClient.Instance.DisabledParentResources;
    262311      var mainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>().Where(x => x.ParentResourceId == null));
    263       var parentedMainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
    264         .Where(x => x.ParentResourceId.HasValue && !resources.Select(y => y.Id).Contains(x.ParentResourceId.Value)));
    265       mainResources.UnionWith(parentedMainResources);
    266       var subResources = new HashSet<Resource>(resources.Except(mainResources));
     312      //var parentedMainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
     313      //  .Where(x => x.ParentResourceId.HasValue && !resources.Select(y => y.Id).Contains(x.ParentResourceId.Value)));
     314      //mainResources.UnionWith(parentedMainResources);
     315      var mainDisabledParentResources = new HashSet<Resource>(disabledParentResources.Where(x => x.ParentResourceId == null || x.ParentResourceId == Guid.Empty));
     316      mainResources.UnionWith(mainDisabledParentResources);
     317      var subResources = new HashSet<Resource>(resources.Union(disabledParentResources).Except(mainResources).OrderByDescending(x => x.Name));
    267318
    268319      var stack = new Stack<Resource>(mainResources.OrderByDescending(x => x.Name));
     320     
    269321      Resource top = null;
     322      //bool nodeSelected = false;
     323      if (detailsViewHost != null && detailsViewHost.Content != null && detailsViewHost.Content is Resource) {
     324        var resourceId = ((Resource)detailsViewHost.Content).Id;
     325        top = resources.Where(x => x.Id == resourceId).FirstOrDefault();
     326      }
     327     
    270328
    271329      TreeNode currentNode = null;
    272330      Resource currentResource = null;
    273331
    274 
    275332      var addedAssignments = newAssignedResources.Except(assignedResources);
    276333      var removedAssignments = assignedResources.Except(newAssignedResources);
    277       var addedIncludes = newInheritedResources.Except(inheritedResources);
    278       var removedIncludes = inheritedResources.Except(newInheritedResources);
    279 
    280       //var assignmentDiff = new HashSet<Resource>(newAssignedResources);
    281       //assignmentDiff.SymmetricExceptWith(assignedResources);
    282       //var inheritanceDiff = new HashSet<Resource>(newInheritedResources);
    283       //inheritanceDiff.SymmetricExceptWith(inheritedResources);
     334      var addedIncludes = newIncludedResources.Except(includedResources);
     335      var removedIncludes = includedResources.Except(newIncludedResources);
    284336
    285337      while (stack.Any()) {
    286         if(top == null)  top = stack.Peek();
    287338        var newResource = stack.Pop();
    288339        var newNode = new TreeNode(newResource.Name) { Tag = newResource };
     340
     341        if(top == null && !disabledParentResources.Contains(newResource)) {
     342          top = newResource;
     343        }
     344
     345        //if(!nodeSelected && top != null && newResource.Id == top.Id) {
     346        //  newNode.BackColor = selectedBackColor;
     347        //  newNode.ForeColor = selectedForeColor;
     348        //  nodeSelected = true;
     349        //}
    289350
    290351        // search for parent node of newNode and save in currentNode
     
    302363        }
    303364
    304         if (newAssignedResources.Contains(newResource)) {
     365        if (disabledParentResources.Contains(newResource)) {
     366          newNode.Checked = false;
     367          newNode.ForeColor = grayTextColor;
     368        } else if (newAssignedResources.Contains(newResource)) {
    305369          newNode.Checked = true;
    306370          if(!HiveRoles.CheckAdminUserPermissions()) {
    307             if(!projectAncestors[Content.Id].Any()) {
     371            if (!HiveAdminClient.Instance.CheckOwnershipOfParentProject(Content, UserInformation.Instance.User.Id)
     372              || !HiveAdminClient.Instance.GetAvailableProjectAncestors(Content.Id).Any()
     373              || projectExclusiveResources.Contains(newResource)) {
    308374              newNode.ForeColor = SystemColors.GrayText;
    309               newNode.Text += " [immutable]";
     375              newNode.Text += IMMUTABLE_TAG;
    310376            }
    311377          }
    312378
    313         } else if (newInheritedResources.Contains(newResource)) {
     379        } else if (newIncludedResources.Contains(newResource)) {
    314380          newNode.Checked = true;
    315381          newNode.ForeColor = SystemColors.GrayText;
    316382        }
    317383
    318           if (inheritedResources.Contains(newResource) && newInheritedResources.Contains(newResource)) {
    319           newNode.Text += " [included]";
     384          if (includedResources.Contains(newResource) && newIncludedResources.Contains(newResource)) {
     385          newNode.Text += INCLUDED_TAG;
    320386        } else if (addedIncludes.Contains(newResource)) {
    321387          newNode.BackColor = addedIncludeColor;
    322388          newNode.ForeColor = SystemColors.GrayText;
    323           newNode.Text += " [added include]";
     389          newNode.Text += ADDED_INCLUDE_TAG;
    324390        } else if (removedIncludes.Contains(newResource)) {
    325391          newNode.BackColor = removedIncludeColor;
    326           newNode.Text += " [removed include]";
     392          newNode.Text += REMOVED_INCLUDE_TAG;
    327393        }
    328394
     
    330396          newNode.BackColor = addedAssignmentColor;
    331397          newNode.ForeColor = SystemColors.ControlText;
    332           newNode.Text += " [added assignment]";
     398          newNode.Text += ADDED_ASSIGNMENT_TAG;
    333399        } else if (removedAssignments.Contains(newResource)) {
    334400          newNode.BackColor = removedAssignmentColor;
    335401          newNode.ForeColor = SystemColors.ControlText;
    336           newNode.Text += " [removed assignment]";
     402          newNode.Text += REMOVED_ASSIGNMENT_TAG;
    337403        }
    338404
     
    353419        }
    354420        newNode.SelectedImageIndex = newNode.ImageIndex;
    355         //if (newResource.OwnerUserId == UserInformation.Instance.User.Id)
    356         //  newNode.BackColor = ownedResourceColor;
    357421      }
    358422
    359423      var ungroupedSlaves = subResources.OfType<Slave>().OrderBy(x => x.Name);
    360424      if(ungroupedSlaves.Any()) {
    361         var ungroupedNode = new TreeNode(ungroupedGroupName) {
     425        ungroupedGroupNode = new TreeNode(UNGROUPED_GROUP_NAME) {
    362426          ForeColor = SystemColors.GrayText,
    363427          Tag = new SlaveGroup() {
    364             Name = ungroupedGroupName,
    365             Description = ungroupedGroupDescription
     428            Name = UNGROUPED_GROUP_NAME,
     429            Description = UNGROUPED_GROUP_DESCRIPTION
    366430          }
    367431        };
     
    369433        foreach (var slave in ungroupedSlaves) {
    370434          var slaveNode = new TreeNode(slave.Name) { Tag = slave };
    371           ungroupedNode.Nodes.Add(slaveNode);
    372         }
    373         treeView.Nodes.Add(ungroupedNode);
     435          ungroupedGroupNode.Nodes.Add(slaveNode);
     436        }
     437        treeView.Nodes.Add(ungroupedGroupNode);
     438      } else if (ungroupedGroupNode != null) {
     439        ungroupedGroupNode.Nodes.Clear();
    374440      }
    375441
    376442      treeView.BeforeCheck += treeView_BeforeCheck;
    377443      treeView.AfterCheck += treeView_AfterCheck;
    378       treeView.ExpandAll();
     444     
     445      ExpandResourceNodesOfInterest(treeView.Nodes);
    379446
    380447      return top;
    381448    }
    382449
    383     private void UpdateProjectGenealogy() {
    384       projectAncestors.Clear();
    385       projectDescendants.Clear();
    386       var projects = HiveAdminClient.Instance.Projects;
    387 
    388       foreach(var p in projects.Where(x => x.Id != Guid.Empty)) {
    389         projectAncestors.Add(p.Id, new HashSet<Project>());
    390         projectDescendants.Add(p.Id, new HashSet<Project>());
    391       }
    392 
    393       foreach (var p in projects.Where(x => x.Id != Guid.Empty)) {
    394         var parentProjectId = p.ParentProjectId;
    395         while (parentProjectId != null) {
    396           var parent = projects.SingleOrDefault(x => x.Id == parentProjectId);
    397           if (parent != null) {
    398             projectAncestors[p.Id].Add(parent);
    399             projectDescendants[parent.Id].Add(p);
    400             parentProjectId = parent.ParentProjectId;
     450    private void ExpandResourceNodesOfInterest(TreeNodeCollection nodes) {
     451      foreach (TreeNode n in nodes) {
     452        Resource r = (Resource)n.Tag;
     453        if (n.Nodes.Count > 0) {
     454          if (HiveAdminClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()) {
     455            n.Expand();
     456            ExpandResourceNodesOfInterest(n.Nodes);
    401457          } else {
    402             parentProjectId = null;
     458            n.Collapse();
    403459          }
    404         }
    405       }
     460        } else {
     461          n.Collapse();
     462        }
     463      }
     464    }
     465
     466    private bool IsAdmin() {
     467      return HiveRoles.CheckAdminUserPermissions();
    406468    }
    407469
Note: See TracChangeset for help on using the changeset viewer.