Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
-
trunk/HeuristicLab.Clients.Hive.Administrator
- Property svn:mergeinfo changed
-
trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.cs
r15760 r16117 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-201 7Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 37 37 private const int slaveImageIndex = 0; 38 38 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]"; 41 47 42 48 private readonly HashSet<Resource> assignedResources = new HashSet<Resource>(); 43 49 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>(); 51 52 52 53 private readonly Color addedAssignmentColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1 … … 54 55 private readonly Color addedIncludeColor = Color.FromArgb(25, 169, 221, 221); // #a9dddd 55 56 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; 56 63 57 64 public new Project Content { … … 73 80 assignedResources.Clear(); 74 81 newAssignedResources.Clear(); 75 inheritedResources.Clear(); 76 resourceAncestors.Clear(); 82 includedResources.Clear(); 77 83 treeView.Nodes.Clear(); 78 84 detailsViewHost.Content = null; 79 85 } else { 80 UpdateProjectGenealogy();81 86 UpdateAssignedResources(); 82 Update ResourceGenealogy();83 var top = BuildResourceTree( HiveAdminClient.Instance.Resources);87 UpdateIncludedResources(); 88 var top = BuildResourceTree(); 84 89 detailsViewHost.Content = top; 90 detailsViewHost.Locked = true; 85 91 } 86 92 } … … 102 108 103 109 private void refreshButton_Click(object sender, EventArgs e) { 104 UpdateProjectGenealogy();110 HiveAdminClient.Instance.Refresh(); 105 111 UpdateAssignedResources(); 106 Update ResourceGenealogy();107 var top = BuildResourceTree( HiveAdminClient.Instance.Resources);112 UpdateIncludedResources(); 113 var top = BuildResourceTree(); 108 114 detailsViewHost.Content = top; 109 115 } … … 114 120 SetAssignedProjectResources(Content.Id, newAssignedResources.Select(x => x.Id), false, true, false); 115 121 }); 122 HiveAdminClient.Instance.Refresh(); 116 123 UpdateResourceTree(); 117 124 } … … 122 129 SetAssignedProjectResources(Content.Id, newAssignedResources.Select(x => x.Id), false, false, false); 123 130 }); 131 HiveAdminClient.Instance.Refresh(); 124 132 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; 125 142 } 126 143 … … 131 148 132 149 private void treeView_BeforeCheck(object sender, TreeViewCancelEventArgs e) { 150 if (e.Node == null || e.Node == ungroupedGroupNode) { 151 e.Cancel = true; 152 return; 153 } 154 133 155 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)) { 135 160 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)) { 138 165 e.Cancel = true; 139 166 } … … 157 184 private void UpdateResourceTree() { 158 185 UpdateAssignedResources(); 159 UpdateResourceGenealogy(); 160 var top = BuildResourceTree(HiveAdminClient.Instance.Resources); 186 UpdateIncludedResources(); 187 188 var top = BuildResourceTree(); 161 189 detailsViewHost.Content = top; 162 190 } … … 164 192 private void UpdateNewResourceTree() { 165 193 UpdateNewAssignedResources(); 166 UpdateNewIn heritedResources();167 var top = BuildResourceTree( HiveAdminClient.Instance.Resources);194 UpdateNewIncludedResources(); 195 var top = BuildResourceTree(); 168 196 detailsViewHost.Content = top; 169 197 } 170 198 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)); 174 256 } 175 257 … … 183 265 private void UpdateNewAssignedResources() { 184 266 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()) { 186 268 newAssignedResources.Remove(newAssignedResources.ElementAt(i)); 187 269 } … … 198 280 } 199 281 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(); 202 295 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() { 255 303 treeView.Nodes.Clear(); 256 if (!resources.Any()) return null;257 304 258 305 treeView.BeforeCheck -= treeView_BeforeCheck; 259 306 treeView.AfterCheck -= treeView_AfterCheck; 260 307 261 resources = resources.Where(x => x.Id != Guid.Empty); 308 var resources = GetAvailableResourcesForProjectAdministration(Content.Id); 309 310 var disabledParentResources = HiveAdminClient.Instance.DisabledParentResources; 262 311 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)); 267 318 268 319 var stack = new Stack<Resource>(mainResources.OrderByDescending(x => x.Name)); 320 269 321 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 270 328 271 329 TreeNode currentNode = null; 272 330 Resource currentResource = null; 273 331 274 275 332 var addedAssignments = newAssignedResources.Except(assignedResources); 276 333 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); 284 336 285 337 while (stack.Any()) { 286 if(top == null) top = stack.Peek();287 338 var newResource = stack.Pop(); 288 339 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 //} 289 350 290 351 // search for parent node of newNode and save in currentNode … … 302 363 } 303 364 304 if (newAssignedResources.Contains(newResource)) { 365 if (disabledParentResources.Contains(newResource)) { 366 newNode.Checked = false; 367 newNode.ForeColor = grayTextColor; 368 } else if (newAssignedResources.Contains(newResource)) { 305 369 newNode.Checked = true; 306 370 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)) { 308 374 newNode.ForeColor = SystemColors.GrayText; 309 newNode.Text += " [immutable]";375 newNode.Text += IMMUTABLE_TAG; 310 376 } 311 377 } 312 378 313 } else if (newIn heritedResources.Contains(newResource)) {379 } else if (newIncludedResources.Contains(newResource)) { 314 380 newNode.Checked = true; 315 381 newNode.ForeColor = SystemColors.GrayText; 316 382 } 317 383 318 if (in heritedResources.Contains(newResource) && newInheritedResources.Contains(newResource)) {319 newNode.Text += " [included]";384 if (includedResources.Contains(newResource) && newIncludedResources.Contains(newResource)) { 385 newNode.Text += INCLUDED_TAG; 320 386 } else if (addedIncludes.Contains(newResource)) { 321 387 newNode.BackColor = addedIncludeColor; 322 388 newNode.ForeColor = SystemColors.GrayText; 323 newNode.Text += " [added include]";389 newNode.Text += ADDED_INCLUDE_TAG; 324 390 } else if (removedIncludes.Contains(newResource)) { 325 391 newNode.BackColor = removedIncludeColor; 326 newNode.Text += " [removed include]";392 newNode.Text += REMOVED_INCLUDE_TAG; 327 393 } 328 394 … … 330 396 newNode.BackColor = addedAssignmentColor; 331 397 newNode.ForeColor = SystemColors.ControlText; 332 newNode.Text += " [added assignment]";398 newNode.Text += ADDED_ASSIGNMENT_TAG; 333 399 } else if (removedAssignments.Contains(newResource)) { 334 400 newNode.BackColor = removedAssignmentColor; 335 401 newNode.ForeColor = SystemColors.ControlText; 336 newNode.Text += " [removed assignment]";402 newNode.Text += REMOVED_ASSIGNMENT_TAG; 337 403 } 338 404 … … 353 419 } 354 420 newNode.SelectedImageIndex = newNode.ImageIndex; 355 //if (newResource.OwnerUserId == UserInformation.Instance.User.Id)356 // newNode.BackColor = ownedResourceColor;357 421 } 358 422 359 423 var ungroupedSlaves = subResources.OfType<Slave>().OrderBy(x => x.Name); 360 424 if(ungroupedSlaves.Any()) { 361 var ungroupedNode = new TreeNode(ungroupedGroupName) {425 ungroupedGroupNode = new TreeNode(UNGROUPED_GROUP_NAME) { 362 426 ForeColor = SystemColors.GrayText, 363 427 Tag = new SlaveGroup() { 364 Name = ungroupedGroupName,365 Description = ungroupedGroupDescription428 Name = UNGROUPED_GROUP_NAME, 429 Description = UNGROUPED_GROUP_DESCRIPTION 366 430 } 367 431 }; … … 369 433 foreach (var slave in ungroupedSlaves) { 370 434 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(); 374 440 } 375 441 376 442 treeView.BeforeCheck += treeView_BeforeCheck; 377 443 treeView.AfterCheck += treeView_AfterCheck; 378 treeView.ExpandAll(); 444 445 ExpandResourceNodesOfInterest(treeView.Nodes); 379 446 380 447 return top; 381 448 } 382 449 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); 401 457 } else { 402 parentProjectId = null;458 n.Collapse(); 403 459 } 404 } 405 } 460 } else { 461 n.Collapse(); 462 } 463 } 464 } 465 466 private bool IsAdmin() { 467 return HiveRoles.CheckAdminUserPermissions(); 406 468 } 407 469
Note: See TracChangeset
for help on using the changeset viewer.