1 /** 2 * Copyright 2008-Present actioncenters.org 3 * 4 * This file is part of actioncenters.org. 5 * 6 * Actioncenters.org is free software: you can redistribute it and/or modify 7 * it under the terms of the BSD License found in the LICENSE.txt file. 8 */ 9 10 /** 11 * @fileOverview Provides ActionCenters utility functions. 12 */ 13 14 /*global Ext, dojox, AC, workspaceUser, currentPSSWorkspaceId, workspaceUserId, acPSSUserId, acGlobalDelimiter, 15 actioncenter, actionCenterAPI, actionCenterJSON, ActionCenterListener, ActionCenterWorkspace */ 16 17 Ext.namespace('AC.util'); 18 Ext.namespace('AC.data'); 19 Ext.namespace('AC.server'); 20 Ext.namespace('AC.tree.grid'); 21 22 /** 23 * Default constructor. 24 * 25 * @class Defines standard icons and functions. 26 */ 27 AC.util.StandardIcons = { 28 29 /** 30 * Project icon. 31 * 32 * @constant 33 * @type String 34 * @default 'actioncenters/resources/images/icn-project_color_16x16.png' 35 */ 36 AC_Project_Definition: 'actioncenters/resources/images/icn-project_color_16x16.png', 37 38 /** 39 * Activity icon. 40 * 41 * @constant 42 * @type String 43 * @default 'actioncenters/resources/images/icn-activities_color_16x16.png' 44 */ 45 AC_Activity: 'actioncenters/resources/images/icn-activities_color_16x16.png', 46 47 /** 48 * Phase icon 49 * 50 * @constant 51 * @type String 52 * @default 'actioncenters/resources/images/icn_phase.gif' 53 */ 54 AC_Phase: 'actioncenters/resources/images/icn_phase.gif', 55 56 /** 57 * Role icon 58 * 59 * @constant 60 * @type String 61 * @default 'actioncenters/resources/images/icn_role.gif' 62 */ 63 AC_Role: 'actioncenters/resources/images/icn_role.gif', 64 65 /** 66 * Screen icon. 67 * 68 * @constant 69 * @type String 70 * @default 'actioncenters/resources/images/icn-Screen_color_16x16.png' 71 */ 72 AC_Screen: 'actioncenters/resources/images/icn-Screen_color_16x16.png', 73 74 /** 75 * Thinklet icon. 76 * 77 * @constant 78 * @type String 79 * @default 'actioncenters/resources/images/icn-ThinkLets_color_16x16.png' 80 */ 81 AC_Thinklet: 'actioncenters/resources/images/icn-ThinkLets_color_16x16.png', 82 83 /** 84 * Agenda category icon. 85 * 86 * @constant 87 * @type String 88 * @default 'actioncenters/resources/images/icn-category_gray_16x16.png' 89 */ 90 AC_Agenda_Category: 'actioncenters/resources/images/icn-category_gray_16x16.png', 91 92 /** 93 * Thinklet category icon. 94 * 95 * @constant 96 * @type String 97 * @default 'actioncenters/resources/images/icn-category_gray_16x16.png' 98 */ 99 AC_Thinklet_Category: 'actioncenters/resources/images/icn-category_gray_16x16.png', 100 101 /** 102 * Tool category icon. 103 * 104 * @constant 105 * @type String 106 * @default 'actioncenters/resources/images/icn-category_gray_16x16.png' 107 */ 108 AC_Tool_Category: 'actioncenters/resources/images/icn-category_gray_16x16.png', 109 110 /** 111 * Screen category icon. 112 * 113 * @constant 114 * @type String 115 * @default 'actioncenters/resources/images/icn-category_gray_16x16.png' 116 */ 117 AC_Screen_Category: 'actioncenters/resources/images/icn-category_gray_16x16.png', 118 119 /** 120 * Control category icon. 121 * 122 * @constant 123 * @type String 124 * @default 'actioncenters/resources/images/icn-category_gray_16x16.png' 125 */ 126 AC_Control_Category: 'actioncenters/resources/images/icn-category_gray_16x16.png', 127 128 /** 129 * Library icon. 130 * 131 * @constant 132 * @type String 133 * @default 'actioncenters/resources/images/icn-library_16x16.png' 134 */ 135 AC_Library_Type: 'actioncenters/resources/images/icn-library_16x16.png', 136 137 /** 138 * Workspace icon. 139 * 140 * @constant 141 * @type String 142 * @default 'actioncenters/resources/images/icn_ac-workspace_16x16.png' 143 */ 144 AC_Workspace: 'actioncenters/resources/images/icn_ac-workspace_16x16.png', 145 146 /** 147 * Info icon. 148 * 149 * @constant 150 * @type String 151 * @default 'actioncenters/resources/images/icn-info_16x16.png' 152 */ 153 AC_Info: 'actioncenters/resources/images/icn-info_16x16.png', 154 155 /** 156 * Orange info icon. 157 * 158 * @constant 159 * @type String 160 * @default 'actioncenters/resources/images/icn-info-orange_24x24.png' 161 */ 162 AC_Info_Orange: 'actioncenters/resources/images/icn-info-orange_24x24.png', 163 164 /** 165 * Edit icon. 166 * 167 * @constant 168 * @type String 169 * @default 'actioncenters/resources/images/pencil16x16.gif' 170 */ 171 AC_Edit: 'actioncenters/resources/images/pencil16x16.gif', 172 173 /** 174 * No-icon icon. 175 * 176 * @constant 177 * @type String 178 * @default 'actioncenters/resources/images/icn_no-icon_color_24x24.png' 179 */ 180 AC_No_Icon: 'actioncenters/resources/images/icn_no-icon_color_24x24.png', 181 182 /** 183 * Component icon. 184 * 185 * @constant 186 * @type String 187 * @default 'actioncenters/resources/images/icn-tools_color_16x16.png' 188 */ 189 AC_Component: 'actioncenters/resources/images/icn-tools_color_16x16.png', 190 191 /** 192 * Image icon. 193 * 194 * @constant 195 * @type String 196 * @default 'actioncenters/resources/images/image.png' 197 */ 198 AC_Image: 'actioncenters/resources/images/image.png', 199 200 /** 201 * Control icon. 202 * 203 * @constant 204 * @type String 205 * @default 'actioncenters/resources/images/image.png' 206 */ 207 AC_Control: 'actioncenters/resources/images/icn-settings_gray_16x16.png', 208 209 /** 210 * icon. 211 * 212 * @constant 213 * @type String 214 * @default 'actioncenters/resources/images/image.png' 215 */ 216 AC_Tool: 'actioncenters/resources/images/icn-settings_gray_16x16.png', 217 218 /** 219 * Gets the path to the icon specified by the argument. If no icon is found, an empty icon is returned. 220 * 221 * @param type 222 * the name of the icon 223 * @return the path to the icon or base64 encoding of an empty icon 224 */ 225 getIconSrc: function (type) { 226 try { 227 return eval('AC.util.StandardIcons.' + type); 228 } catch (err) { 229 return 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='; 230 } 231 }, 232 233 /** 234 * Gets the path to the image servlet. 235 * 236 * @return the path to the image servlet 237 */ 238 getImageServlet : function () { 239 return 'servlet/DisplayImageServlet?id='; 240 }, 241 242 /** 243 * Gets the path to the 1x1 px spacer image. 244 * 245 * @return the path to the 1x1 px spacer image 246 */ 247 getSpacerImage : function () { 248 return 'ext-3.3.1/resources/images/default/s.gif'; 249 }, 250 251 /** 252 * Gets the URL to the image specified by the argument id. 253 * 254 * @param id 255 * the id of the image 256 * @param returnBlankIcon 257 * the boolean flag to indicate whether to return a blank icon when the image id is null or empty 258 * @param scaleTo 259 * the scale of the returned image 260 * @return the URL path to the image 261 */ 262 getImageURL : function (id, returnBlankIcon, scaleTo) { 263 var imageURL = null; 264 if (id && id.length > 0) { 265 imageURL = this.getImageServlet() + id; 266 if (scaleTo) { 267 imageURL = imageURL + '&scale=' + scaleTo; 268 } 269 } else if (returnBlankIcon) { 270 imageURL = Ext.BLANK_IMAGE_URL; 271 } 272 return imageURL; 273 } 274 }; 275 /******************************* AC.util.FormatManager *************************************************/ 276 /** 277 * A hashmap that keeps track of the hierachical relationships between Component and Population Rule contributions 278 * along with their FIBU contributions. 279 * Hashmap key: the contributionId of the contribution 280 * Hashmap object includes: {contributionId: the contributionId of the contribution, 281 * type: the contribution type (e.g. AC_Component, AC_Population_Rule), 282 * superiorId: the contributionId of the higher level contribution (e.g. the higher level of AC_Population_Rule is AC_Component) 283 * FIBUs: a hashmap that keep track of the FIBU contributions that belong to this contribution 284 * (the key of the hashmap is fibuState(normal, selected, etc.), and the object is the contributionId) 285 * } 286 */ 287 AC.util.FormatManager = new Ext.util.MixedCollection(); 288 /******************************************************************************************************/ 289 // TODO: move the utility into AC namespace 290 /** 291 * Default constructor. 292 * 293 * @class A utility class 294 */ 295 var actionCenterUtility = { 296 /** 297 * Launches the FIBU editor. 298 * 299 * @param contributionId 300 * the contribution id 301 * @param states 302 * array of states for FIBU editing 303 * @return void 304 */ 305 FIBUEditor: function (contributionId, states) { 306 var stateEditors = []; 307 var editor = null; 308 var windowId = 'FFFIBUUDEditor' + acGlobalDelimiter + contributionId; 309 310 var FIBUEditorWindow = new actioncenter.FIBUEditorWindow({ 311 y : 25, 312 contributionId : contributionId, 313 states : states, 314 id: windowId, 315 layout: 'form', 316 width: 700, 317 autoScroll: true, 318 title: 'FIBU Editor', 319 autoHeight: true, 320 bodyStyle: 'padding:5px', 321 hideLabels: true, 322 frame: true, 323 modal: true, 324 constrainHeader: true, 325 buttons: [{ 326 text: 'DONE', 327 handler: function () { 328 Ext.getCmp('FFFIBUUDEditor' + acGlobalDelimiter + contributionId).close(); 329 } 330 }], 331 buttonAlign: 'center' 332 }); 333 actionCenterAPI.getSystemElementConfiguration("AC_Fibu", "Main", FIBUEditorWindow, FIBUEditorWindow.buildEditors); 334 }, 335 336 /** 337 * Launches the drop-event editor. 338 * 339 * @param popRuleContributionId 340 * the population rule contribution id 341 * @param componentContributionId 342 * the component contribution id 343 * @param states 344 * the array of states 345 * @return void 346 */ 347 DropEventsEditor: function (popRuleContributionId, componentContributionId, states) { 348 this.columns = states.length; 349 var editor = null; 350 var form = null; 351 var tree = null; 352 for (var i = 0; i < this.columns; i++) { 353 form = new actioncenter.DropEventEditorForm({ 354 superiorId: popRuleContributionId, 355 dropType: states[i], 356 layout: 'form', 357 width: 280, 358 border: false, 359 style: 'padding-top: 6px;' 360 }); 361 tree = new actioncenter.populationRuleSelector({ 362 superiorId: popRuleContributionId, 363 componentId: componentContributionId, 364 dropType: states[i], 365 layout: 'fit', 366 columnWidth: 1, 367 height: 250 368 }); 369 editor = { 370 xtype: 'panel', 371 layout: 'column', 372 id: 'editorPanel' + states[i] + acGlobalDelimiter + popRuleContributionId, 373 items: [form, tree], 374 border: false, 375 width: 500, 376 height: 250, 377 treePanel: tree 378 }; 379 } 380 381 var dropEventEditorWindow = new Ext.Window({ 382 y : 25, 383 id: 'DropEventEditor' + acGlobalDelimiter + popRuleContributionId, 384 layout: 'fit', 385 title: 'Drop Event Editor', 386 bodyStyle: 'padding:5px', 387 hideLabels: true, 388 frame: true, 389 modal: true, 390 constrainHeader: true, 391 items: [editor], 392 buttons: [{ 393 text: 'Close', 394 handler: function () { 395 Ext.getCmp('DropEventEditor' + acGlobalDelimiter + popRuleContributionId).close(); 396 } 397 }], 398 buttonAlign: 'center', 399 toolbars: [] 400 }); 401 tree.containingWindow = dropEventEditorWindow; 402 dropEventEditorWindow.show(); 403 }, 404 405 /** 406 * Starts the listeners for client messages. 407 * 408 * @return void 409 */ 410 startClientMessageListener : function () { 411 actionCenterAPI.startBatch(); 412 dojox.cometd.subscribe("/ActionCenters/message/error", actionCenterUtility, 'displayClientMessage'); 413 dojox.cometd.subscribe("/ActionCenters/message/info", actionCenterUtility, 'displayClientMessage'); 414 dojox.cometd.subscribe("/ActionCenters/message/debug", actionCenterUtility, 'displayClientMessage'); 415 dojox.cometd.subscribe("/ActionCenters/message/warning", actionCenterUtility, 'displayClientMessage'); 416 actionCenterAPI.endBatch(); 417 }, 418 419 /** 420 * Displays the specified message to the client. 421 * 422 * @param msg 423 * the message 424 * @return void 425 */ 426 displayClientMessage : function (msg) { 427 var messageLevel = actionCenterJSON.getMsgProperty(msg, 'data.userMessage.severity'); 428 var messageText = actionCenterJSON.getMsgProperty(msg, 'data.userMessage.text'); 429 var msgIconCls = null; 430 switch (messageLevel) { 431 case 'DEBUG': msgIconCls = Ext.MessageBox.QUESTION; 432 break; 433 case 'WARNING': msgIconCls = Ext.MessageBox.WARNING; 434 break; 435 case 'ERROR': msgIconCls = Ext.MessageBox.ERROR; 436 break; 437 case 'INFO': msgIconCls = Ext.MessageBox.INFO; 438 break; 439 default: msgIconCls = Ext.MessageBox.WARNING; 440 break; 441 } 442 Ext.MessageBox.show({ 443 title: 'Client Message', 444 maxWidth : 700, 445 msg: messageText, 446 buttons: Ext.MessageBox.OK, 447 icon: msgIconCls 448 }); 449 }, 450 451 /** 452 * Re-orders the specified new node as a child of the specified root node. 453 * 454 * @param rootNode 455 * the root node 456 * @param newNode 457 * the new node 458 * @param parentNode 459 * the parent node 460 * @return void 461 */ 462 reorder : function (rootNode, newNode, parentNode) { 463 if (!parentNode) { 464 parentNode = rootNode; 465 } 466 var desiredOrder = null; 467 if (parentNode.attributes && parentNode.attributes.order) { 468 desiredOrder = parentNode.attributes.order.split(','); 469 } 470 471 // var sm = rootNode.getOwnerTree().getSelectionModel(); 472 // //remember all the continuous selection pairs if this editOrder is not called rigth after a new node is created 473 // if(sm.markContinuousSelectionPairs){ 474 // sm.markContinuousSelectionPairs(); 475 // } 476 477 // Tracks whether a new node still needs to be placed 478 if (newNode) { 479 rootNode.appendChild(newNode); 480 } 481 //check whether the tree is in focus 482 var treeInFocus = false; 483 rootNode.cascade(function(n){ 484 if(n.ui.anchor === document.activeElement){ 485 treeInFocus = true; 486 } 487 }); 488 489 // sort when loadMonitor is not active and if there exists a desired order 490 if ((!parentNode.getOwnerTree().loadMonitor || 491 !parentNode.getOwnerTree().loadMonitor.isActive) && desiredOrder) { 492 rootNode.sort( 493 function (node1, node2) { 494 var contributionId1 = node1.contributionId; 495 var contributionId2 = node2.contributionId; 496 var index1 = desiredOrder.length + 1; 497 var i; 498 for (i = 0; i < desiredOrder.length; i++) { 499 if (contributionId1 === desiredOrder[i]) { 500 index1 = i; 501 break; 502 } 503 } 504 var index2 = desiredOrder.length + 1; 505 for (i = 0; i < desiredOrder.length; i++) { 506 if (contributionId2 === desiredOrder[i]) { 507 index2 = i; 508 break; 509 } 510 } 511 if (index1 < index2) { 512 return -1; 513 } else if (index1 > index2) { 514 return 1; 515 } else { 516 return 0; 517 } 518 } 519 ); 520 } 521 522 // //if there are visible nodes existing between the original continuous selected pairs, select them all 523 // if(sm.selectNodesBetweenPairs){ 524 // sm.selectNodesBetweenPairs(); 525 // } 526 527 if(treeInFocus){ 528 if (rootNode.firstChild && rootNode.ui && rootNode.firstChild.ui.anchor){ 529 rootNode.firstChild.ui.anchor.focus(); 530 } 531 } 532 533 if (rootNode.getOwnerTree().enableLineNumbering) { 534 this.reorderCounter(rootNode); 535 } 536 }, 537 538 /** 539 * Utility function to re-order line number counters. 540 * 541 * @param rootNode 542 * the root node whose child nodes need to be re-ordered 543 * @param isRootCounterChanged 544 * indicates whether the parent node's counter changed 545 * @return void 546 */ 547 reorderCounter: function (rootNode, isParentCounterChanged) { 548 for (var i = 0; i < rootNode.childNodes.length; i++) { 549 var currentNode = rootNode.childNodes[i]; 550 var uiCounter = null; 551 if (!currentNode.counter || currentNode.counter !== (i + 1) || isParentCounterChanged) { 552 // set the counters 553 currentNode.counter = i + 1; 554 if (rootNode.ui.counter) { 555 uiCounter = rootNode.ui.counter + currentNode.counter + '.'; 556 } else { 557 uiCounter = currentNode.counter + '.'; 558 } 559 currentNode.ui.counter = uiCounter; 560 if (!currentNode.ui.rendered) { 561 currentNode.ui.render(true); 562 } 563 564 if (currentNode.ui.counterNode) { 565 currentNode.ui.counterNode.firstChild.nodeValue = uiCounter; 566 currentNode.fireEvent('counterchange'); 567 } 568 // re-order children's counters as well 569 this.reorderCounter(currentNode, true); 570 } 571 } 572 }, 573 574 /** 575 * Re-orders the specified new node as a child of the specified root node. 576 * 577 * @param rootNode 578 * the root node 579 * @param newNode 580 * the new node 581 * @param parentNode 582 * the parent node 583 * @return void 584 */ 585 reorderGrid : function (rootNode, newNode, parentNode) { 586 if (!parentNode) { 587 parentNode = rootNode; 588 } 589 var desiredOrder = {}; 590 if (parentNode.order) { 591 desiredOrder = parentNode.order.split(','); 592 } 593 // Tracks whether a new node still needs to be placed 594 var newNodeNeedsPlaced = (newNode !== undefined && newNode !== null); 595 // Keep track of where we are in the rootNode's children 596 var childIndex = 0; 597 var nodeAtPoint = null; 598 // Iterate through the desired order list 599 for (var i = 0; i < desiredOrder.length; i++) { 600 // The id of the location we are in the parent's orderList 601 var currentId = desiredOrder[i]; 602 console.log("currentId is " + currentId); 603 // If we are past the end of the child node array 604 if (childIndex >= rootNode.childNodes.length) { 605 break; 606 // else if the current node matches the one in the order list 607 } else if (currentId === rootNode.item(childIndex).contributionId) { 608 childIndex++; 609 // else if the new node needs to be placed here 610 } else if (newNodeNeedsPlaced && (currentId === newNode.contributionId)) { 611 nodeAtPoint = rootNode.item(childIndex); 612 console.log("nodeAtPoint item(" + childIndex + ") " + nodeAtPoint.name + " and " + newNode.name + 613 "will be placed before it."); 614 //********************************************************** 615 rootNode.insertBefore(newNode, nodeAtPoint); 616 617 //********************************************************** 618 newNodeNeedsPlaced = false; 619 childIndex++; 620 } else { 621 var node = rootNode.findChild("contributionId", currentId); 622 // If the node that should be in this location is somewhere else in the child array 623 if (node) { 624 //************************************************************ 625 rootNode.removeChild(node); 626 console.log("removing node " + node.name); 627 nodeAtPoint = rootNode.item(childIndex); 628 node.rendered = false; 629 rootNode.insertBefore(node, nodeAtPoint); 630 console.log("nodeAtPoint item(" + childIndex + ") " + nodeAtPoint.name + " and " + node.name + 631 " will be placed before it."); 632 633 //*********************************************************** 634 childIndex++; 635 } 636 } 637 } 638 // If we have gone through the complete list of children and still not found a place for the new node 639 if (newNodeNeedsPlaced) { 640 console.log("no place found so appending " + newNode.name); 641 rootNode.appendChild(newNode); 642 } 643 rootNode.renderChildren(); 644 }, 645 646 /** 647 * Checks if the specified candidate is contained in the specified list. 648 * 649 * @param candidate 650 * the candidate 651 * @param list 652 * the list 653 * @return true if the candidate is in the list. 654 */ 655 isInList : function (candidate, list) { 656 var retVal = false; 657 for (var i = 0; i < list.length; i++) { 658 // The id of the location we are in the parent's orderList 659 var currentThing = list[i]; 660 if (candidate === currentThing) { 661 retVal = true; 662 } 663 } 664 return retVal; 665 }, 666 667 /** 668 * Re-orderes the specified new node in the list of child nodes of the specified parent node. 669 * 670 * @param parentNode 671 * the parent node 672 * @param newNode 673 * the new node 674 * @return void 675 */ 676 reorderInList : function (parentNode, newNode) { 677 var component; 678 var desiredOrder = {}; 679 if (parentNode.order) { 680 desiredOrder = parentNode.order.split(','); 681 } 682 // Tracks whether a new node still needs to be placed 683 var newNodeNeedsPlaced = (newNode !== undefined && newNode !== null); 684 // Keep track of where we are in the rootNode's children 685 var childIndex = 0; 686 if (parentNode.items) { 687 // Iterate through the desired order list 688 for (var i = 0; i < desiredOrder.length; i++) { 689 // The id of the location we are in the parent's orderList 690 var currentId = desiredOrder[i]; 691 // If we are past the end of the child node array 692 if (childIndex >= parentNode.items.length) { 693 break; 694 // else if the current node matches the one in the order list 695 } else if (currentId === parentNode.items.items[childIndex].contributionId) { 696 childIndex++; 697 // else if the new node needs to be placed here 698 } else if (newNodeNeedsPlaced && (currentId === newNode.contributionId)) { 699 var nodeAtPoint = parentNode.items.items[childIndex]; 700 component = parentNode.insert(childIndex, newNode); 701 newNodeNeedsPlaced = false; 702 childIndex++; 703 } else { 704 // The node that should be in this location is not here, look for it someplace else in the array 705 var object = null; 706 parentNode.items.each(function (o) { 707 if (currentId === o.contributionId) { 708 object = o; 709 } 710 }); 711 // if it is found someplace else in the array, remove it and put it here 712 if (object) { 713 this.remove(object); 714 component = parentNode.insert(childIndex, newNode); 715 childIndex++; 716 } 717 } 718 } 719 } 720 // If we have gone through the complete list of children and still not found a place for the new node 721 if (newNodeNeedsPlaced) { 722 component = parentNode.add(newNode); 723 } 724 parentNode.doLayout(); 725 726 return component; 727 }, 728 729 /** 730 * Converts a string array to a delimited string. 731 * 732 * @param stringArray 733 * an array of strings 734 * @return a delimitedString 735 */ 736 convertStringArrayToDelimitedString: function (stringArray) { 737 var returnValue = ''; 738 if (Ext.isArray(stringArray)) { 739 if (stringArray && stringArray.length > 0) { 740 returnValue = returnValue + stringArray[0]; 741 } 742 for (var index = 1; index < stringArray.length; index++) { 743 returnValue = returnValue + acGlobalDelimiter + stringArray[index]; 744 } 745 } else { 746 returnValue = stringArray; 747 } 748 return returnValue; 749 }, 750 751 /** 752 * Finds the node of the specified target type in the specified array of nodes to inspect. 753 * 754 * @param targetType 755 * the target node type 756 * @param nodesToInspect 757 * the array of nodes to inspect 758 * @return the found node or null otherwise 759 */ 760 findNodeType: function (targetType, nodesToInspect) { 761 var foundNode = null; 762 if (nodesToInspect.length) { 763 var index = 0; 764 while (index < nodesToInspect.length && !foundNode) { 765 // from the node find a node of 'targetType' 766 if (nodesToInspect[index].type === targetType) { 767 foundNode = nodesToInspect[index]; 768 } else { 769 foundNode = nodesToInspect[index].find('type', targetType); 770 if (foundNode && foundNode.length > 0) { 771 foundNode = foundNode[0]; //simply get the first node that pops up. 772 } else { 773 foundNode = null; //in case foundNode is an empty array, reset to null 774 } 775 } 776 index++; 777 } 778 } 779 return foundNode; 780 }, 781 performStandardTreeModeMove: function (e, typecast) { 782 for (var c = 0; c < e.dropNode.length; c++) { 783 var relationshipToSuperior = "childof"; 784 if (typecast && typecast.indexOf(acKeyValueSeperator) != -1) { 785 var temp = typecast.split(acKeyValueSeperator); 786 relationshipToSuperior = temp[1]; 787 typecast = temp[0]; 788 } 789 var moveMap = actionCenterUtility.getContributionTreeDropMap(e, c, typecast); 790 actionCenterUtility.executeStandardTreeNodeMove(moveMap, relationshipToSuperior); 791 } 792 }, 793 /** 794 * Gets a map specifying contribution info for tree node drops. 795 * 796 * @param e 797 * the drop event 798 * @param c 799 * the counter within drop nodes 800 * @param t 801 * the type to cast the contribution to 802 * 803 * @return the tree drop node map 804 */ 805 getContributionTreeDropMap: function (e, c, t) { 806 var parentNd = e.dropNode[c].parentNode; 807 var childNd = e.dropNode[c]; 808 switch (parentNd.type) { 809 case 'AC_Standard_Activity_Palette': 810 case 'AC_Agenda_Palette': 811 case 'AC_Thinklet_Palette': 812 case 'AC_Screen_Palette': 813 case 'AC_Tool_Palette': 814 case 'AC_Control_Palette': 815 case 'AC_Image_Palette': 816 parentNd = parentNd.parentNode; 817 break; 818 case 'AC_Activity': 819 if (childNd.type !== 'AC_User') { 820 while (parentNd.type !== 'AC_Project_Definition') { 821 parentNd = parentNd.parentNode; 822 } 823 } 824 break; 825 default:break; 826 } 827 828 var afterContributionId = null; 829 var beforeContributionId = null; 830 831 var ultimateParentNode = null; 832 switch (e.point) { 833 case "append" : ultimateParentNode = e.target; 834 break; 835 case "above" : ultimateParentNode = e.target.parentNode; 836 beforeContributionId = e.target.contributionId; 837 break; 838 case "below" : ultimateParentNode = e.target.parentNode; 839 afterContributionId = e.target.contributionId; 840 break; 841 case "parentAppend" : ultimateParentNode = e.target.parentNode; 842 break; 843 default : break; 844 } 845 switch (ultimateParentNode.type) { 846 case 'AC_Standard_Activity_Palette': 847 case 'AC_Agenda_Palette': 848 case 'AC_Thinklet_Palette': 849 case 'AC_Screen_Palette': 850 case 'AC_Tool_Palette': 851 case 'AC_Control_Palette': 852 case 'AC_Image_Palette': 853 ultimateParentNode = ultimateParentNode.parentNode; 854 break; 855 case 'AC_Activity': 856 if (childNd.type !== 'AC_User') { 857 while (ultimateParentNode.type !== 'AC_Project_Definition') { 858 ultimateParentNode = ultimateParentNode.parentNode; 859 } 860 } 861 default: break; 862 } 863 864 var treeDropMap = { 865 currentParentNode: parentNd, 866 ultimateParentNode: ultimateParentNode, 867 nodeBeingMoved: childNd, 868 afterContributionId: afterContributionId, 869 beforeContributionId: beforeContributionId, 870 typecast: t 871 }; 872 return treeDropMap; 873 }, 874 875 /** 876 * Executes a standard tree node move. 877 * 878 * @param moveMap 879 * the map specifying the node move info 880 * @param relationshipType 881 * the relationship type of the node after the move 882 * @return void 883 */ 884 executeStandardTreeNodeMove: function (moveMap, relationshipType) { 885 var currentParentNode = moveMap.currentParentNode; 886 var ultimateParentNode = moveMap.ultimateParentNode; 887 var nodeBeingMoved = moveMap.nodeBeingMoved; 888 var afterContributionId = moveMap.afterContributionId; 889 var beforeContributionId = moveMap.beforeContributionId; 890 var typecast = moveMap.typecast; 891 892 var currentParentNodeId = currentParentNode.contributionId; 893 var ultimateParentNodeId = ultimateParentNode.contributionId; 894 895 if (ultimateParentNode.type === 'AC_Role') { 896 // see if it is a move to a new Activity node if so, get the activity node id and concatenate it 897 var currentActivityNodeId = currentParentNode.parentNode.contributionId; 898 var ultimateActivityNodeId = ultimateParentNode.parentNode.contributionId; 899 if (currentActivityNodeId !== ultimateActivityNodeId) { 900 currentParentNodeId += acGlobalDelimiter + currentActivityNodeId; 901 ultimateParentNodeId += acGlobalDelimiter + ultimateActivityNodeId; 902 } 903 if (ultimateParentNode.hasChildNodes()) { 904 var otherScreenNode = ultimateParentNode.childNodes[0]; 905 var msg = 'A screen already exists here, do you wish to replace it?'; 906 var icon = Ext.MessageBox.QUESTION; 907 Ext.Msg.show({ 908 thisNode: this, 909 title: 'Add Screen', 910 msg: msg, 911 buttons: Ext.Msg.YESNO, 912 icon: icon, 913 fn: function (btn, text) { 914 if (btn === 'yes') { 915 actionCenterAPI.moveContributionToRecycleBin(otherScreenNode.contributionId); 916 actionCenterAPI.moveContribution2( 917 nodeBeingMoved.contributionId, 918 currentParentNodeId, 919 ultimateParentNodeId, 920 relationshipType, 921 afterContributionId, 922 beforeContributionId, 923 typecast, 924 nodeBeingMoved.addChannelRelationshipType); 925 } 926 } 927 }); 928 } else { 929 ultimateParentNode.attributes.dropTarget = true; 930 actionCenterAPI.moveContribution2( 931 nodeBeingMoved.contributionId, 932 currentParentNodeId, 933 ultimateParentNodeId, 934 relationshipType, 935 afterContributionId, 936 beforeContributionId, 937 typecast, 938 nodeBeingMoved.addChannelRelationshipType); 939 } 940 } else { 941 if (currentParentNodeId === ultimateParentNodeId) { 942 actionCenterAPI.moveContribution( 943 currentParentNodeId, 944 nodeBeingMoved.contributionId, 945 afterContributionId, 946 beforeContributionId); 947 } else { 948 if (!ultimateParentNode.hasChildNodes()) { 949 ultimateParentNode.attributes.dropTarget = true; 950 } 951 actionCenterAPI.moveContribution2( 952 nodeBeingMoved.contributionId, 953 currentParentNodeId, 954 ultimateParentNodeId, 955 relationshipType, 956 afterContributionId, 957 beforeContributionId, 958 typecast, 959 nodeBeingMoved.addChannelRelationshipType); 960 } 961 } 962 }, 963 964 /** 965 * Displays a choice dialog. 966 * 967 * @param choices 968 * the array of choices to be presented 969 * @param text 970 * the title of the dialog 971 * @param target 972 * the target id of the container of the dialog; if null, the dialog is a pop-up window 973 * @param passAlongData 974 * the data to be passed along in a callback 975 * @param callBackObject 976 * callback object 977 * @param callBackMethod 978 * callback method 979 * @return void 980 */ 981 choiceDialog: function (choices, text, target, passAlongData, callBackObject, callBackMethod) { 982 if (!target) { 983 target = Ext.id(); 984 } 985 var selectItemDialog = Ext.getCmp(target); 986 var choice = null; 987 var itemsList = []; 988 for (var i = 0; i < choices.length; i++) { 989 if (typeof choices[i] === "string") { 990 if (choices[i].indexOf(acKeyValueSeperator) != -1) { 991 var tempChoice = choices[i].split(acKeyValueSeperator); 992 choice = {label: tempChoice[0], value: choices[i]}; 993 } else { 994 choice = choices[i]; 995 } 996 } else { 997 choice = choices[i]; 998 } 999 var itemsListItem = { 1000 boxLabel: choice.label ? choice.label : choice, 1001 inputValue: choice.value ? choice.value : choice, 1002 name: 'chosenItem' 1003 }; 1004 itemsList.push(itemsListItem); 1005 } 1006 if (!selectItemDialog) { 1007 selectItemDialog = new Ext.Window({ 1008 id: target, 1009 layout: 'form', 1010 title: text, 1011 width: 370, 1012 autoHeight: true, 1013 bodyStyle: 'padding:5px', 1014 resizable: false, 1015 frame: true, 1016 modal: true, 1017 constrainHeader: true, 1018 items: [ 1019 { 1020 xtype: 'label', 1021 text: text, 1022 id: 'selectText', 1023 hideLabel: true, 1024 //cls: 'error-text-style', 1025 anchor: '100%' 1026 }, { 1027 xtype: 'radiogroup', 1028 columns: 1, 1029 items: itemsList, 1030 id: 'chosenItem', 1031 hideLabel: true 1032 } 1033 ], 1034 buttons: [{ 1035 text: 'Submit', 1036 callbackobject: callBackObject, 1037 callbackmethod: callBackMethod, 1038 target: target, 1039 handler: function () { 1040 var chosenItemObj = Ext.getCmp(target).findById('chosenItem'); 1041 var chosenItem = chosenItemObj.getValue().inputValue; 1042 this.callbackmethod.call(this.callbackobject, passAlongData, chosenItem); 1043 Ext.getCmp(target).close(); 1044 } 1045 }, { 1046 text: 'Cancel', 1047 handler: function () { 1048 Ext.getCmp(target).close(); 1049 } 1050 }], 1051 buttonAlign: 'center' 1052 }); 1053 } 1054 selectItemDialog.show(); 1055 }, 1056 getBrowserDimensions: function () { 1057 var myWidth = 0, myHeight = 0; 1058 if (typeof(window.innerWidth) === 'number') { 1059 // Non-IE 1060 myWidth = window.innerWidth; 1061 myHeight = window.innerHeight; 1062 } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) { 1063 // IE 6+ in 'standards compliant mode' 1064 myWidth = document.documentElement.clientWidth; 1065 myHeight = document.documentElement.clientHeight; 1066 } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) { 1067 // IE 4 compatible 1068 myWidth = document.body.clientWidth; 1069 myHeight = document.body.clientHeight; 1070 } 1071 return { 1072 width: myWidth, 1073 height: myHeight 1074 } 1075 } 1076 }; 1077 /** 1078 * Default constructor for ShallowSelectionNode 1079 * 1080 * 1081 * @class Data object for keeping track of what contributions need to be copied with a shallow copy 1082 */ 1083 1084 AC.data.ShallowSelectionNode = function(i, c) { 1085 this.contiguousIds = c || [i]; 1086 this.addContiguousId = function(i) { 1087 this.contiguousIds.push(i); 1088 }; 1089 }; 1090 /** 1091 * Default constructor for ShallowSelectionToken 1092 * 1093 * @class Data object used for processing a tree and determining what contributions will be copied 1094 * when a shallow copy is required. 1095 */ 1096 1097 AC.data.ShallowSelectionToken = function(a, c, i) { 1098 this.selectionArray = a || []; 1099 this.contiguousSelection = c; 1100 if (i) { 1101 this.index = i; 1102 } else { 1103 this.index = 0; 1104 } 1105 }; 1106 /** 1107 * Default constructor. 1108 * 1109 * @class Manages the clipboard. 1110 */ 1111 AC.data.Clipboard = { 1112 1113 /** 1114 * A property to store the current paste GUID 1115 * @field 1116 * @default null 1117 */ 1118 clientGUID : false, 1119 /** 1120 * A flag to indicate a copy/cut is in process 1121 * @field 1122 * @default false 1123 */ 1124 pendingCopy : false, 1125 /** 1126 * A list of items deep copied to the clipboard. 1127 * 1128 * @field 1129 * @default null 1130 */ 1131 copiedItemList : null, 1132 /** 1133 * 1134 */ 1135 /** 1136 * A list of items shallow copied to the clipboard. 1137 * 1138 * @field 1139 * @default null 1140 */ 1141 shallowCopiedItemList : null, 1142 /** 1143 * The id of the source of the data in the clipboard 1144 * @field 1145 * @default null 1146 */ 1147 sourceId : null, 1148 /** 1149 * ActionCenter listener. 1150 * 1151 * @field 1152 * @default null 1153 */ 1154 actionCenterListener : null, 1155 1156 /** 1157 * Gets a clipboard contribution and invokes subscribeToClipboard as a callback method. 1158 * 1159 * @return void 1160 */ 1161 initiateClipboard : function () { 1162 actionCenterAPI.getPersonalWorkspaceContribution( 1163 "AC_Clipboard", AC.data.Clipboard, AC.data.Clipboard.subscribeToClipboard); 1164 }, 1165 1166 /** 1167 * Copies clipboard items from the specified clipboard contribution and subscribes to the clipboard update channel. 1168 * 1169 * @param clipboard 1170 * the clipboard contribution 1171 * @return void 1172 */ 1173 subscribeToClipboard : function (clipboard) { 1174 if (clipboard && clipboard.getProperty('clipboardTypes')) { 1175 this.copiedItemList = clipboard.getProperty('clipboardTypes').getValue(); 1176 } 1177 if (clipboard && clipboard.getProperty('clipboardShallowTypes')) { 1178 this.shallowCopiedItemList = clipboard.getProperty('clipboardShallowTypes').getValue(); 1179 } 1180 if (clipboard && clipboard.getProperty('sourceId')) { 1181 this.sourceId = clipboard.getProperty('sourceId').getValue(); 1182 } 1183 if (!this.actionCenterListener) { 1184 this.actionCenterListener = new ActionCenterListener(); 1185 } 1186 this.actionCenterListener.getContributionUpdates(clipboard.getId(), AC.data.Clipboard, 'replaceClipboard'); 1187 }, 1188 1189 /** 1190 * Replaces contents of the clipboard with the contents of the clipboard specified in the message. 1191 * 1192 * @param msg 1193 * the message with the new clipboard contents 1194 * @return void 1195 */ 1196 replaceClipboard : function (msg) { 1197 AC.data.Clipboard.copiedItemList = msg.data.contribution.contributionProperties.clipboardTypes.value; 1198 AC.data.Clipboard.shallowCopiedItemList = msg.data.contribution.contributionProperties.clipboardShallowTypes.value; 1199 AC.data.Clipboard.sourceId = msg.data.contribution.contributionProperties.sourceId.value; 1200 AC.data.Clipboard.pendingCopy = false; 1201 }, 1202 /** 1203 * Sets the value of the pendingCopy flag 1204 * 1205 */ 1206 setPendingCopy : function (p) { 1207 AC.data.Clipboard.pendingCopy = p; 1208 }, 1209 1210 /** 1211 * Gets the value of the pendingCopy flag 1212 * @return boolean value 1213 */ 1214 isPendingCopy : function () { 1215 return AC.data.Clipboard.pendingCopy; 1216 }, 1217 /** 1218 * Displays a waiting message while pendingCopy flag is true 1219 * 1220 */ 1221 pasteToNode : function() { 1222 if (AC.data.Clipboard.node) { 1223 if (!AC.data.Clipboard.node.busyEl && AC.data.Clipboard.node.ui.elNode) { 1224 AC.data.Clipboard.node.busyEl = Ext.fly(AC.data.Clipboard.node.ui.elNode).createChild({ 1225 html: 'Waiting for previous clipboard copy...' 1226 }); 1227 AC.data.Clipboard.node.busyEl.addClass('loading-indicator'); 1228 AC.data.Clipboard.node.busyEl.setStyle('z-index', '15000'); 1229 AC.data.Clipboard.node.busyEl.setVisible(true); 1230 } 1231 AC.data.Clipboard.node.pasteToThisNode(AC.data.Clipboard.pasteInfo.position, AC.data.Clipboard.pasteInfo.relationshipType); 1232 } 1233 }, 1234 clearPendingInfo : function() { 1235 if (AC.data.Clipboard.node && AC.data.Clipboard.node.busyEl) { 1236 AC.data.Clipboard.node.busyEl.remove(); 1237 } 1238 AC.data.Clipboard.node = null; 1239 AC.data.Clipboard.pasteInfo = null; 1240 1241 }, 1242 /** 1243 * Gets the deep contents of the clipboard. 1244 * 1245 * @return the list of deep copied item types 1246 */ 1247 getClipboardTypes : function () { 1248 return AC.data.Clipboard.copiedItemList; 1249 }, 1250 /** 1251 * Gets the shallow contents of the clipboard. 1252 * 1253 * @return the list of shallow copied item types 1254 */ 1255 getShallowClipboardTypes : function () { 1256 return AC.data.Clipboard.shallowCopiedItemList; 1257 }, 1258 1259 /** 1260 * Gets the contents of the clipboard. 1261 * 1262 * @return the source component id of the clipboard contents 1263 */ 1264 getSourceId : function () { 1265 return AC.data.Clipboard.sourceId; 1266 }, 1267 1268 /** 1269 * Sets the clientGUID 1270 */ 1271 setClientGUID: function (clientGUID) { 1272 AC.data.Clipboard.clientGUID = clientGUID; 1273 }, 1274 1275 /** 1276 * gets the clientGUID 1277 * 1278 * @return (String) The clientGUID 1279 */ 1280 getClientGUID: function () { 1281 return AC.data.Clipboard.clientGUID; 1282 } 1283 }; 1284 1285 1286 // TODO: move the JSON utility into AC namespace 1287 /** 1288 * Default constructor. 1289 * 1290 * @class A utility class for manipulation of JSON messages. 1291 */ 1292 var actionCenterJSON = { 1293 1294 /** 1295 * A boolean constant denoting whether to log messages to the console. 1296 * 1297 * @field 1298 * @type bool 1299 * @default false 1300 */ 1301 logmsgs: false, 1302 1303 /** 1304 * Queries the specified JSON message using the specified path and returns message contents on the path or null 1305 * if the path is invalid. 1306 * 1307 * @param msg a JSON message 1308 * @param {String} path a dot-separated path to a message attribute 1309 * @returns null, if the message is null; or null, if the path is invalid; or the evaluated message on the path 1310 * contents. If the evaluated message has a value attribute, it's value is returned 1311 */ 1312 getMsgPropertyValue: function (msg, path) { 1313 var property = this.getMsgProperty(msg, path); 1314 if (property && property.value) { 1315 return property.value; 1316 } else { 1317 return property; 1318 } 1319 }, 1320 1321 /** 1322 * Queries the specified JSON message using the specified path and returns message contents on the path or null 1323 * if the path is invalid. 1324 * 1325 * @param msg a JSON message 1326 * @param {String} path a dot-separated path to a message attribute 1327 * @returns null, if the message is null; or null, if the path is invalid; or the evaluated message on the path 1328 * contents 1329 */ 1330 getMsgProperty: function (msg, path) { 1331 if (!msg) { 1332 return null; 1333 } 1334 var pathelements = path.split('.'); 1335 var builtpath = "msg."; 1336 var evaluatedProperty = null; 1337 for (var i = 0; i < pathelements.length; i++) { 1338 if (i === 0) { 1339 builtpath += pathelements[i]; 1340 } else { 1341 builtpath = builtpath + "." + pathelements[i]; 1342 } 1343 try { 1344 evaluatedProperty = eval(builtpath); 1345 } catch (error) { 1346 if (this.logmsgs) { 1347 console.log(path + " does not have a valid path in this message."); 1348 } 1349 } 1350 if (evaluatedProperty === null) { 1351 if (this.logmsgs) { 1352 console.log(path + " does not have a valid path in this message."); 1353 } 1354 return null; 1355 } 1356 } 1357 return evaluatedProperty; 1358 }, 1359 1360 /** 1361 * Sanitizes the specified string by replacing special characters by their string-safe equivalents. 1362 * 1363 * @param {String} inputString the string to make safe 1364 * @returns a string-safe equivalent 1365 */ 1366 makeStringSafe : function (inputString) { 1367 inputString = inputString.replace(/\n/g, " "); 1368 inputString = inputString.replace(/\r/g, " "); 1369 inputString = inputString.replace(/\\/g, "\\\\"); 1370 //inputString = inputString.replace(/\b/g, " "); 1371 //inputString = inputString.replace(/\t/g, " "); 1372 inputString = inputString.replace(/'/g, "\\'"); 1373 inputString = inputString.replace(/"/g, "\\\""); 1374 return inputString; 1375 } 1376 }; 1377 1378 /** 1379 * Default constructor. 1380 * 1381 * @class Defines standard ActionCenters constants 1382 */ 1383 AC.util.Constants = { 1384 1385 /** 1386 * The key to access the id attribute. 1387 * 1388 * @constant 1389 * @type String 1390 * @default "id" 1391 */ 1392 actionCenterIdKey: "id", 1393 1394 /** 1395 * The key to access the type attribute. 1396 * 1397 * @constant 1398 * @type String 1399 * @default "type" 1400 */ 1401 actionCenterTypeKey: "type", 1402 1403 /** 1404 * The key to access the user attribute. 1405 * 1406 * @constant 1407 * @type String 1408 * @default "user" 1409 */ 1410 actionCenterUserKey: "user", 1411 1412 /** 1413 * The key to access the workspace attribute. 1414 * 1415 * @constant 1416 * @type String 1417 * @default "workspace" 1418 */ 1419 actionCenterWorkspaceKey: "workspace", 1420 1421 /** 1422 * The key to access the fromDate attribute. 1423 * 1424 * @constant 1425 * @type String 1426 * @default "fromDate" 1427 */ 1428 actionCenterFromDateKey: "fromDate", 1429 1430 /** 1431 * The key to access the toDate attribute. 1432 * 1433 * @constant 1434 * @type String 1435 * @default "toDate" 1436 */ 1437 actionCenterToDateKey: "toDate", 1438 1439 /** 1440 * The key to access the relationships attribute. 1441 * 1442 * @constant 1443 * @type String 1444 * @default "relationships" 1445 */ 1446 actionCenterRelationshipsKey: "relationships", 1447 1448 /** 1449 * The key to access the contribution properties attribute. 1450 * 1451 * @constant 1452 * @type String 1453 * @default "contributionProperties" 1454 */ 1455 actionCenterContributionPropertiesKey: "contributionProperties", 1456 1457 /** 1458 * The key to access the add contribution properties attribute. 1459 * 1460 * @constant 1461 * @type String 1462 * @default "addContributionProperties" 1463 */ 1464 actionCenterAddContributionPropertiesKey: "addContributionProperties", 1465 1466 /** 1467 * The key to access the remove contribution properties attribute. 1468 * 1469 * @constant 1470 * @type String 1471 * @default "removeContributionProperties" 1472 */ 1473 actionCenterRemoveContributionPropertiesKey: "removeContributionProperties", 1474 1475 /** 1476 * The key to access the update contribution properties attribute. 1477 * 1478 * @constant 1479 * @type String 1480 * @default "updateContributionProperties" 1481 */ 1482 actionCenterUpdateContributionPropertiesKey: "updateContributionProperties", 1483 1484 /** 1485 * The key to access the value attribute. 1486 * 1487 * @constant 1488 * @type String 1489 * @default "value" 1490 */ 1491 actionCenterValueKey: "value", 1492 1493 /** 1494 * The key to access the locked by attribute. 1495 * 1496 * @constant 1497 * @type String 1498 * @default "lockedBy" 1499 */ 1500 actionCenterLockedByKey: "lockedBy", 1501 1502 /** 1503 * The key to access the contribution attribute. 1504 * 1505 * @constant 1506 * @type String 1507 * @default "Contribution" 1508 */ 1509 actionCenterContributionKey: "Contribution", 1510 1511 /** 1512 * The key to access the thumb prints attribute. 1513 * 1514 * @constant 1515 * @type String 1516 * @default "thumbprints" 1517 */ 1518 actionCenterThumbprintsKey: "thumbprints", 1519 1520 /** 1521 * The key to access the disabled flag attribute. 1522 * 1523 * @constant 1524 * @type String 1525 * @default "disabledFlag" 1526 */ 1527 actionCenterDisabledFlagKey: "disabledFlag", 1528 1529 /** 1530 * The key to access the email attribute. 1531 * 1532 * @constant 1533 * @type String 1534 * @default "email" 1535 */ 1536 actionCenterEmailKey: "email", 1537 1538 /** 1539 * The key to access the pending approval flag attribute. 1540 * 1541 * @constant 1542 * @type String 1543 * @default "pendingApprovalFlag" 1544 */ 1545 actionCenterPendingApprovalFlagKey: "pendingApprovalFlag", 1546 1547 /** 1548 * The key to access the first name attribute. 1549 * 1550 * @constant 1551 * @type String 1552 * @default "firstName" 1553 */ 1554 actionCenterFirstNameKey: "firstName", 1555 1556 /** 1557 * The key to access the last name attribute. 1558 * 1559 * @constant 1560 * @type String 1561 * @default "lastName" 1562 */ 1563 actionCenterLastNameKey: "lastName", 1564 1565 /** 1566 * The key to access the system roles attribute. 1567 * 1568 * @constant 1569 * @type String 1570 * @default "systemRoles" 1571 */ 1572 actionCenterSystemRolesKey: "systemRoles", 1573 1574 /** 1575 * The key to access the username attribute. 1576 * 1577 * @constant 1578 * @type String 1579 * @default "username" 1580 */ 1581 actionCenterUsernameKey: "username", 1582 1583 /** 1584 * The key to access the workspace roles attribute. 1585 * 1586 * @constant 1587 * @type String 1588 * @default "workspaceRoles" 1589 */ 1590 actionCenterWorkspaceRolesKey: "workspaceRoles", 1591 1592 /** 1593 * The key to access the response type attribute in a message. 1594 * 1595 * @constant 1596 * @type String 1597 * @default 'ResponseType' 1598 */ 1599 actionCenterResponseTypeKey: 'ResponseType', 1600 1601 /** 1602 * The key to access the contribution attribute in a response message from the server. 1603 * 1604 * @constant 1605 * @type String 1606 * @default 'Contribution' 1607 */ 1608 actionCenterResponseTypeContributionKey: 'Contribution', 1609 1610 /** 1611 * The key to access the user attribute in a response message from the server. 1612 * 1613 * @constant 1614 * @type String 1615 * @default 'User' 1616 */ 1617 actionCenterResponseTypeUserKey: 'User', 1618 1619 /** 1620 * The key to access the user list attribute in a response message from the server. 1621 * 1622 * @constant 1623 * @type String 1624 * @default 'UserList' 1625 */ 1626 actionCenterResponseTypeUserListKey: 'UserList' 1627 }; 1628 1629 /** 1630 * Creates a new contribution from the specified message. 1631 * 1632 * @class Represents a contribution. 1633 * @param msg a JSON message 1634 */ 1635 AC.data.Contribution = function (msg) { 1636 1637 /** 1638 * The contents of the JSON message. 1639 */ 1640 this._msg = msg; 1641 1642 /** 1643 * Gets an attribute's value from the message based on the specified attribute key. 1644 * 1645 * @param {String} key the key of the message attribute. 1646 * @return the value of the message attribute 1647 */ 1648 this.getAttribute = function (key) { 1649 return actionCenterJSON.getMsgProperty(this._msg, key); 1650 }; 1651 1652 /** 1653 * Gets the contribution id. 1654 * 1655 * @return the contribution id 1656 */ 1657 this.getId = function () { 1658 return this.getAttribute(AC.util.Constants.actionCenterIdKey); 1659 }; 1660 1661 /** 1662 * Gets the contribution type. 1663 * 1664 * @return the contribution type 1665 */ 1666 this.getType = function () { 1667 return this.getAttribute(AC.util.Constants.actionCenterTypeKey); 1668 }; 1669 1670 /** 1671 * Gets the contribution's user contents from the message and instantiates the user. 1672 * 1673 * @return the contribution's user 1674 */ 1675 this.getUser = function () { 1676 return new AC.data.User(this.getAttribute(AC.util.Constants.actionCenterUserKey)); 1677 }; 1678 1679 /** 1680 * Gets the contribution's workspace contents from the message and instantiates the workspace. 1681 * 1682 * @return the contribution's workspace 1683 */ 1684 this.getWorkspace = function () { 1685 // TODO: where is the definition of ActionCenterWorkspace? 1686 return new ActionCenterWorkspace(this.getAttribute(AC.util.Constants.actionCenterWorkspaceKey)); 1687 }; 1688 1689 /** 1690 * Gets the contribution's time stamp. 1691 * 1692 * @return the contribution's time stamp 1693 */ 1694 this.getFromDate = function () { 1695 return this.getAttribute(AC.util.Constants.actionCenterFromDateKey); 1696 }; 1697 1698 /** 1699 * Gets the contribution's relationships. 1700 * 1701 * @return the contribution's relationships 1702 */ 1703 this.getRelationships = function () { 1704 return this.getAttribute(AC.util.Constants.actionCenterRelationshipsKey); 1705 }; 1706 1707 /** 1708 * Gets the contribution's properties. 1709 * 1710 * @return the contribution's properties 1711 */ 1712 this.getProperties = function () { 1713 return this.getAttribute(AC.util.Constants.actionCenterContributionPropertiesKey); 1714 }; 1715 1716 /** 1717 * Gets an String with properties in format "{propertyKey:value, propertyKey:value}" 1718 * 1719 * @return a string that represents an object with all of the properties as elements 1720 */ 1721 this.getPropertiesObject = function () { 1722 var mixedCollection = new Ext.util.MixedCollection(); 1723 mixedCollection.addAll(this.getProperties()); 1724 mixedCollection.propertiestring = '{'; 1725 var buildPropertyString = function (item, index, length) { 1726 // this is a temporary fix to avoid a crash, need to figure out a better way to fix, trying to decode 1727 // the activityReportTemplate property causes an error 1728 if (item.propertyKey === 'activityReportTemplate' || item.propertyKey === 'undefined' || !item.propertyKey) { 1729 return true; 1730 } 1731 mixedCollection.propertiestring += '"' + item.propertyKey + '":"' + item.value + '"'; 1732 if (index + 1 < length) { 1733 mixedCollection.propertiestring += ","; 1734 } 1735 return true; 1736 }; 1737 1738 mixedCollection.each(buildPropertyString); 1739 mixedCollection.propertiestring += "}"; 1740 return mixedCollection.propertiestring; 1741 }; 1742 1743 /** 1744 * Gets a property object, where a property's value is indexed by the property's key. 1745 * 1746 * @return this contribution's properties wrapped as an object 1747 */ 1748 this.getParsedProperties = function () { 1749 var mixedCollection = new Ext.util.MixedCollection(); 1750 mixedCollection.addAll(this.getProperties()); 1751 mixedCollection.propertiestring = '{'; 1752 var buildPropertyString = function (item, index, length) { 1753 // this is a temporary fix to avoid a crash, need to figure out a better way to fix, trying to decode 1754 // the activityReportTemplate property causes an error 1755 if (item.propertyKey === 'activityReportTemplate' || item.propertyKey === 'undefined' || !item.propertyKey) { 1756 return true; 1757 } 1758 mixedCollection.propertiestring += '"' + item.propertyKey + '":"' + item.value + '"'; 1759 if (index + 1 < length) { 1760 mixedCollection.propertiestring += ","; 1761 } 1762 return true; 1763 }; 1764 1765 mixedCollection.each(buildPropertyString); 1766 mixedCollection.propertiestring += '}'; 1767 var parsedProperties = Ext.decode(mixedCollection.propertiestring); 1768 return parsedProperties; 1769 }; 1770 1771 /** 1772 * Gets the contribution's add-properties. 1773 * 1774 * @return the contribution's add-properties 1775 */ 1776 this.getAddedProperties = function () { 1777 return this.getAttribute(AC.util.Constants.actionCenterAddContributionPropertiesKey); 1778 }; 1779 1780 /** 1781 * Gets the contribution's remove-properties. 1782 * 1783 * @return the contribution's remove-properties 1784 */ 1785 this.getRemovedProperties = function () { 1786 return this.getAttribute(AC.util.Constants.actionCenterRemoveContributionPropertiesKey); 1787 }; 1788 1789 /** 1790 * Gets the contribution's update-properties. 1791 * 1792 * @return the contribution's update-properties 1793 */ 1794 this.getUpdatedProperties = function () { 1795 return this.getAttribute(AC.util.Constants.actionCenterUpdateContributionPropertiesKey); 1796 }; 1797 1798 /** 1799 * Gets the contribution's property object based on the specified property key. 1800 * 1801 * @param {String} propertyName the name of the property 1802 * @return the property object of the specified property 1803 */ 1804 this.getProperty = function (propertyName) { 1805 var returnValue = null; 1806 var property = actionCenterJSON.getMsgProperty(this.getProperties(), propertyName); 1807 if (property) { 1808 returnValue = new AC.data.ContributionProperty(property); 1809 } 1810 return returnValue; 1811 }; 1812 1813 /** 1814 * Gets the contribution's property value based on the specified property key. 1815 * 1816 * @param {String} propertyName the name of the property 1817 * @return the value of the specified property 1818 */ 1819 this.getPropertyValue = function (propertyName) { 1820 var returnValue = null; 1821 var property = actionCenterJSON.getMsgProperty(this.getProperties(), propertyName); 1822 if (property) { 1823 returnValue = new AC.data.ContributionProperty(property); 1824 returnValue = returnValue.getValue(); 1825 } 1826 return returnValue; 1827 }; 1828 } 1829 1830 /** 1831 * Creates a new contribution property from the specified message. 1832 * 1833 * @class Represents a contribution property. 1834 * @param msg a JSON message 1835 */ 1836 AC.data.ContributionProperty = function (msg) { 1837 1838 /** 1839 * The contents of the JSON message. 1840 */ 1841 this._msg = msg; 1842 1843 /** 1844 * Gets an attribute's value from the message based on the specified attribute key. 1845 * 1846 * @param {String} key the key of the message attribute. 1847 * @return the value of the message attribute 1848 */ 1849 this.getAttribute = function (key) { 1850 return actionCenterJSON.getMsgProperty(this._msg, key); 1851 }; 1852 1853 /** 1854 * Gets the property's value. 1855 * 1856 * @return the property's value 1857 */ 1858 this.getValue = function () { 1859 return this.getAttribute(AC.util.Constants.actionCenterValueKey); 1860 }; 1861 1862 /** 1863 * Gets the property's locking user. 1864 * 1865 * @return the property's locking user 1866 */ 1867 this.getLockedBy = function () { 1868 return new AC.data.User(this.getAttribute(AC.util.Constants.actionCenterLockedByKey)); 1869 }; 1870 1871 /** 1872 * Gets the property's thumbprints. 1873 * 1874 * @return the property's thumbprints 1875 */ 1876 this.getThumbprints = function () { 1877 return this.getAttribute(AC.util.Constants.actionCenterThumbprintsKey); 1878 }; 1879 1880 /** 1881 * Gets the property's user. 1882 * 1883 * @return the property's user 1884 */ 1885 this.getUser = function () { 1886 return new AC.data.User(this.getAttribute(AC.util.Constants.actionCenterUserKey)); 1887 }; 1888 } 1889 1890 /** 1891 * Creates a new user from the specified message. 1892 * 1893 * @class Represents a user. 1894 * @param msg a JSON message 1895 */ 1896 AC.data.User = function (msg) { 1897 1898 /** 1899 * The contents of the JSON message. 1900 */ 1901 this._msg = msg; 1902 1903 /** 1904 * Gets an attribute's value from the message based on the specified attribute key. 1905 * 1906 * @param {String} key the key of the message attribute. 1907 * @return the value of the message attribute 1908 */ 1909 this.getAttribute = function (key) { 1910 return actionCenterJSON.getMsgProperty(this._msg, key); 1911 }; 1912 1913 /** 1914 * Gets the user's id. 1915 * 1916 * @return the user's id 1917 */ 1918 this.getId = function () { 1919 return this.getAttribute(AC.util.Constants.actionCenterIdKey); 1920 }; 1921 1922 /** 1923 * Gets the user's disabled flag. 1924 * 1925 * @return the user's disabled flag 1926 */ 1927 this.getDisabledFlag = function () { 1928 return this.getAttribute(AC.util.Constants.actionCenterDisabledFlagKey); 1929 }; 1930 1931 /** 1932 * Gets the user's email. 1933 * 1934 * @return the user's email 1935 */ 1936 this.getEmail = function () { 1937 return this.getAttribute(AC.util.Constants.actionCenterEmailKey); 1938 }; 1939 1940 /** 1941 * Gets the user's fromDate. 1942 * 1943 * @return the user's fromDate 1944 */ 1945 this.getFromDate = function () { 1946 return this.getAttribute(AC.util.Constants.actionCenterFromDateKey); 1947 }; 1948 1949 /** 1950 * Gets the user's pending approval flag. 1951 * 1952 * @return the user's pending approval flag 1953 */ 1954 this.getPendingApprovalFlag = function () { 1955 return this.getAttribute(AC.util.Constants.actionCenterPendingApprovalFlagKey); 1956 }; 1957 1958 /** 1959 * Gets the user's first name. 1960 * 1961 * @return the user's first name 1962 */ 1963 this.getFirstName = function () { 1964 return this.getAttribute(AC.util.Constants.actionCenterFirstNameKey); 1965 }; 1966 1967 /** 1968 * Gets the user's last name. 1969 * 1970 * @return the user's last name 1971 */ 1972 this.getLastName = function () { 1973 return this.getAttribute(AC.util.Constants.actionCenterLastNameKey); 1974 }; 1975 1976 /** 1977 * Gets the user's system roles. 1978 * 1979 * @return the user's system roles 1980 */ 1981 this.getSystemRoles = function () { 1982 return this.getAttribute(AC.util.Constants.actionCenterSystemRolesKey); 1983 }; 1984 1985 /** 1986 * Gets the user's toDate. 1987 * 1988 * @return the user's toDate 1989 */ 1990 this.getToDate = function () { 1991 return this.getAttribute(AC.util.Constants.actionCenterToDateKey); 1992 }; 1993 1994 /** 1995 * Gets the user's user name. 1996 * 1997 * @return the user's user name 1998 */ 1999 this.getUsername = function () { 2000 return this.getAttribute(AC.util.Constants.actionCenterUsernameKey); 2001 }; 2002 2003 /** 2004 * Gets the user's workspace roles. 2005 * 2006 * @return the user's workspace roles 2007 */ 2008 this.getWorkspaceRoles = function () { 2009 return this.getAttribute(AC.util.Constants.actionCenterWorkspaceRolesKey); 2010 }; 2011 } 2012 2013 /** 2014 * Creates a user list from the specified message. 2015 * 2016 * @class Represents a user list. 2017 * @param msg a JSON message 2018 */ 2019 AC.data.UserList = function (msg) { 2020 2021 /** 2022 * The contents of the JSON message. 2023 */ 2024 this._msg = msg; 2025 2026 /** 2027 * Gets the length of the user list. 2028 * 2029 * @return the length of the user list 2030 */ 2031 this.getLength = function () { 2032 return this._msg.length; 2033 }; 2034 2035 /** 2036 * Gets the user from the user list based on the specified index. 2037 * 2038 * @param {int} index the index to use in getting the user 2039 * @return the user at the specified index 2040 */ 2041 this.getUser = function (index) { 2042 return new AC.data.User(this._msg[index]); 2043 }; 2044 } 2045 2046 /** 2047 * A counter used to create unique response channels. 2048 * 2049 * @type int 2050 * @default 0 2051 */ 2052 AC.server.callCounter = 0; 2053 2054 /** 2055 * Default constructor. 2056 * 2057 * @class Maintains callback information 2058 * @param callbackObject 2059 * the callback object 2060 * @param callbackmethod 2061 * the callback function 2062 */ 2063 AC.server.CallbackInfo = function (callbackObject, callbackmethod, passdata) { 2064 2065 /** 2066 * The object on which a callback should be invoked. 2067 */ 2068 this._callbackobject = callbackObject; 2069 2070 /** 2071 * The callback function. 2072 */ 2073 this._callbackmethod = callbackmethod; 2074 2075 /** 2076 * The object to pass along to the callback method. 2077 */ 2078 this._passdata = passdata; 2079 2080 } 2081 2082 /** 2083 * Default constructor. 2084 * 2085 * @class Defines functions for invoking server methods. 2086 */ 2087 AC.server.Callback = { 2088 2089 /** 2090 * Maps AC.server.callCounter to instances of AC.server.CallbackInfo for invocations of callbacks. 2091 */ 2092 _hashmap : new Ext.util.MixedCollection(), 2093 2094 /** 2095 * The channel for reply messages coming from the server. 2096 * 2097 * @default null 2098 */ 2099 _subscription : null, 2100 2101 /** 2102 * Invokes the specified method on the server in the read-only mode. 2103 * 2104 * @param message the message to pass to the server 2105 * @param methodName the name of the method to invoke on the server 2106 * @param callbackobject the callback object 2107 * @param callbackobject the callback method 2108 */ 2109 callServerReadOnly : function (message, methodName, callbackobject, callbackmethod, passdata) { 2110 this.callServer(message, methodName, "/service/requests", callbackobject, callbackmethod, passdata); 2111 }, 2112 2113 /** 2114 * Invokes the specified method on the server in the update mode. 2115 * 2116 * @param message the message to pass to the server 2117 * @param methodName the name of the method to invoke on the server 2118 * @param callbackobject the callback object 2119 * @param callbackobject the callback method 2120 */ 2121 callServerUpdate : function (message, methodName, callbackobject, callbackmethod, passdata) { 2122 this.callServer(message, methodName, "/service/requests", callbackobject, callbackmethod, passdata); 2123 }, 2124 2125 /** 2126 * Invokes the specified method on the server. 2127 * 2128 * @param message the message to pass to the server 2129 * @param methodName the name of the method to invoke on the server 2130 * @param channel the name of the channel on which to publish the message 2131 * @param callbackobject the callback object 2132 * @param callbackobject the callback method 2133 */ 2134 callServer : function (message, methodName, channel, callbackobject, callbackmethod, passdata) { 2135 actionCenterAPI.startBatch(); 2136 if (!message) { 2137 message = {}; 2138 } 2139 2140 // Only subscribe if there is a callback object and callback method provided 2141 if (callbackobject && callbackmethod) { 2142 var callCounter = AC.server.callCounter++; 2143 message.receivingchannel = "/response/service"; 2144 message.acMessageNumber = callCounter; 2145 this._hashmap.add(callCounter, new AC.server.CallbackInfo(callbackobject, callbackmethod, passdata)); 2146 if (!this._subscription) { 2147 this._subscription = dojox.cometd.subscribe(message.receivingchannel, this, 'setReturnMsg'); 2148 } 2149 } 2150 2151 message.action = methodName; 2152 message.user = workspaceUser; 2153 2154 dojox.cometd.publish(channel, message); 2155 actionCenterAPI.endBatch(); 2156 }, 2157 2158 /** 2159 * Handles server response messages by invoking callbacks passing server message as the argument. 2160 * 2161 * @param msg the server's reply 2162 */ 2163 setReturnMsg : function (msg) { 2164 var callbackInfo = this._hashmap.removeKey(msg.data.acMessageNumber); 2165 callbackInfo._callbackmethod.call(callbackInfo._callbackobject, this.translate(msg), callbackInfo._passdata); 2166 }, 2167 2168 /** 2169 * Translates the specified message into objects if the message's response type fits certain patterns:<br> 2170 * (Contribution -> AC.data.Contribution);<br> 2171 * (UserList -> AC.data.UserList);<br> 2172 * (anyOther -> the specified message). 2173 * 2174 * @param msg the message 2175 * @return the original message; or the objects as noted above 2176 */ 2177 translate : function (msg) { 2178 var responseType = actionCenterJSON.getMsgProperty( 2179 msg, "data." + AC.util.Constants.actionCenterResponseTypeKey); 2180 if (AC.util.Constants.actionCenterResponseTypeContributionKey === responseType) { 2181 return new AC.data.Contribution(actionCenterJSON.getMsgProperty( 2182 msg, "data." + AC.util.Constants.actionCenterResponseTypeContributionKey)); 2183 } else if (AC.util.Constants.actionCenterResponseTypeUserListKey === responseType) { 2184 return new AC.data.UserList(actionCenterJSON.getMsgProperty( 2185 msg, "data." + AC.util.Constants.actionCenterResponseTypeUserListKey)); 2186 } else { 2187 return msg; 2188 } 2189 } 2190 }; 2191 2192 // TODO: move the API into AC namespace 2193 /** 2194 * Default constructor. 2195 * 2196 * @class Defines the standard API of the ActionCenters. 2197 */ 2198 var actionCenterAPI = { 2199 2200 /** 2201 * The batch counter tracks the number of inner batches so that we can 2202 * end the batch when the counter gets back to 0. This way we can effectively have 2203 * nested batches. 2204 * @private 2205 * @default 0 2206 */ 2207 batchCounter : 0, 2208 2209 /** 2210 * Holds contribution id's for batched, as opposed to one-by-one, thumbprinting. 2211 */ 2212 thumbprints: "", 2213 /** 2214 * Holds the systemElementConfiguration 2215 */ 2216 systemElementConfiguration: null, 2217 /** 2218 * Initiates a batch connection to the server so that the multiple messages can be sent inside one http 2219 * request. There must be a matching call to endBatch. 2220 * 2221 * @return void 2222 */ 2223 startBatch : function () { 2224 if (this.batchCounter === 0) { 2225 dojox.cometd.startBatch(); 2226 } else { 2227 //console.log("batch depth = " + this.batchCounter); 2228 } 2229 this.batchCounter++; 2230 }, 2231 2232 /** 2233 * Terminates a batch connection to the server. 2234 * 2235 * @return void 2236 */ 2237 endBatch : function () { 2238 this.batchCounter--; 2239 if (this.batchCounter === 0) { 2240 dojox.cometd.endBatch(); 2241 } 2242 }, 2243 2244 /** 2245 * Creates a new project. 2246 * TODO: This function should be moved to a class for CACE functions because it is not intended for use by component developers. 2247 * 2248 * @param {Object} contributionProperties 2249 * the contribution properties 2250 * TODO: Remove this parameter because it is not used. 2251 * @param (String} projectType 2252 * the type of the project to create. 2253 * @return void 2254 */ 2255 createProject : function (contributionProperties, projectType) { 2256 AC.server.Callback.callServerUpdate( 2257 {contributionType: projectType, 2258 contributionProperties: contributionProperties 2259 }, 2260 "createProject", null, null); 2261 }, 2262 2263 /** 2264 * Adds a relationship of the specified type between the specified contributions. 2265 * 2266 * @param {String} superiorContributionId 2267 * The id of the superior contribution. 2268 * @param {String} subordinateContributionId 2269 * The id of the subordinate contribution. 2270 * @param {String} relationshipType 2271 * The type of the relationship. 2272 * @param {String} [afterContributionId] 2273 * The id of the preceding contribution. 2274 * @param {String} [beforeContributionId] 2275 * The id of the succeeding contribution. 2276 * @param {String} subordinateContributionType 2277 * The type of the subordinate contribution. 2278 * @param {Object} [contributionProperties] 2279 * The contribution properties. 2280 * @param {Object} [callbackObject] 2281 * The object to call back after the relationship is added. 2282 * @param {function} [callbackMethod] 2283 * The method to call back after the relationship is added. 2284 * @param {Object} [contributionBinObjProperties] 2285 * The binary contribution properties. 2286 * @return void 2287 */ 2288 addRelationship: function (superiorContributionId, subordinateContributionId, relationshipType, afterContributionId, 2289 beforeContributionId, subordinateContributionType, contributionProperties, callbackObject, callbackMethod, 2290 contributionBinObjProperties) { 2291 AC.server.Callback.callServerUpdate( 2292 {superiorContributionId: superiorContributionId, 2293 subordinateContributionId: subordinateContributionId, 2294 relationshipType: relationshipType, 2295 afterContributionId: afterContributionId, 2296 beforeContributionId: beforeContributionId, 2297 subordinateContributionType: subordinateContributionType, 2298 contributionProperties: contributionProperties, 2299 contributionBinObjProperties: contributionBinObjProperties}, 2300 "addRelationship", callbackObject, callbackMethod); 2301 }, 2302 2303 /** 2304 * Deletes a relationship of the specified type between the specified contributions. 2305 * 2306 * @param {String} superiorContributionId 2307 * The id of the superior contribution. 2308 * @param {String} subordinateContributionId 2309 * The id of the subordinate contribution. 2310 * @param {String} relationshipType 2311 * The type of the relationship. 2312 * @param {Boolean} [isDeleteAll] 2313 * Boolean flag to indicate whether all relationships to the superior should be deleted. Defalts to false. 2314 * TODO: remove this parameter because it is not used. 2315 * @return void 2316 */ 2317 deleteRelationship : function (superiorContributionId, subordinateContributionId, relationshipType, isDeleteAll) { 2318 AC.server.Callback.callServerUpdate( 2319 {superiorContributionId: superiorContributionId, 2320 subordinateContributionId: subordinateContributionId, 2321 relationshipType: relationshipType, 2322 isDeleteAll: isDeleteAll}, 2323 "deleteRelationship"); 2324 }, 2325 2326 /** 2327 * Deletes a contribution (remove from recycle bin). 2328 * 2329 * @param {String} contributionId 2330 * The id of the contribution to be deleted. 2331 * @return void 2332 */ 2333 deleteContribution : function (contributionId) { 2334 AC.server.Callback.callServerUpdate( 2335 {contributionId: contributionId}, 2336 "deleteContribution"); 2337 }, 2338 2339 /** 2340 * Moves the specified contribution, within the same superior, to be among subordinates 2341 * of the specified superior contribution between the 'after-' and 'before-' contributions 2342 * in the ordering of subordinates. 2343 * 2344 * @param {String} superiorContributionId 2345 * The id of the superior contribution. 2346 * @param {String} contributionToMoveId 2347 * The id of the contribution to move. 2348 * @param {String} [afterContributionId] 2349 * The id of the preceding contribution. If this parameter is not provided, the beforeContributionId must be provided. 2350 * @param {String} [beforeContributionId] 2351 * The id of the succeeding contribution. If this parameter is not provided, the afterContributionId must be provided. 2352 * @return void 2353 */ 2354 moveContribution : function (superiorContributionId, contributionToMoveId, 2355 afterContributionId, beforeContributionId) { 2356 AC.server.Callback.callServerUpdate( 2357 {superiorContributionId: superiorContributionId, 2358 contributionToMoveId: contributionToMoveId, 2359 afterContributionId: afterContributionId, 2360 beforeContributionId: beforeContributionId}, 2361 "moveContribution"); 2362 }, 2363 2364 /** 2365 * Moves the specified contribution, to a different superior, to be among subordinates 2366 * of the specified superior contribution between the 'after-' and 'before-' contributions 2367 * in the ordering of subordinates. 2368 * 2369 * @param {String} contributionToMoveId 2370 * The id of the contribution to move. 2371 * @param {String} oldSuperiorId 2372 * The id of the old superior contribution. 2373 * @param {String} newSuperiorId 2374 * The id of the new superior contribution. 2375 * @param {String} relationshipType 2376 * The type of the new relationship to the new superior. 2377 * @param {String} [afterContributionId] 2378 * The id of the preceding contribution. If this parameter is not provided, the beforeContributionId must be provided. 2379 * @param {String} [beforeContributionId] 2380 * The id of the succeeding contribution. If this parameter is not provided, the afterContributionId must be provided. 2381 * @param {String} [castToType] 2382 * The type of the contribution after the move. 2383 * @return void 2384 */ 2385 moveContribution2 : function (contributionToMoveId, oldSuperiorId, newSuperiorId, 2386 relationshipType, afterContributionId, beforeContributionId, castToType, oldRelationshipType) { 2387 AC.server.Callback.callServerUpdate( 2388 {contributionToMoveId: contributionToMoveId, 2389 oldSuperiorId: oldSuperiorId, 2390 newSuperiorId: newSuperiorId, 2391 relationshipType: relationshipType, 2392 afterContributionId: afterContributionId, 2393 beforeContributionId: beforeContributionId, 2394 type: castToType, 2395 oldRelationshipType: oldRelationshipType}, 2396 "moveContribution2"); 2397 }, 2398 2399 /** 2400 * Moves a project to the user's recyle bin. 2401 * 2402 * @param {String} projectId 2403 * the id of the project to put in the user's recycle bin 2404 * @return void 2405 */ 2406 moveProjectToRecycleBin : function (projectId) { 2407 AC.server.Callback.callServerUpdate( 2408 {projectId: projectId}, 2409 "moveProjectToRecycleBin"); 2410 }, 2411 2412 /** 2413 * Empties the user's project recyle bin. 2414 * 2415 * @param {String} contributionType 2416 * The type of project to remove from the user's project recycle bin. 2417 * @return void 2418 */ 2419 emptyProjectRecycleBin : function (contributionType) { 2420 AC.server.Callback.callServerUpdate( 2421 {contributionType: contributionType}, 2422 "emptyProjectRecycleBin"); 2423 }, 2424 2425 /** 2426 * Edits the properties of a contribution. 2427 * 2428 * @param {String} contributionId 2429 * The id of the contribution to be edited. 2430 * @param {Object} [properties] 2431 * A map of properties to modify. 2432 * @param {Object} [binaryObjectProperties] 2433 * A map of binary properties to modify. 2434 * @param {Object} [callbackObject] 2435 * The callback object. 2436 * @param {function} [callbackMethod] 2437 * The callback method. 2438 * @param {Boolean} [unlock] 2439 * Boolean flag indicating whether the contribution should be unlocked after the edit. 2440 * @param {String} [type] 2441 * The new contribution type if this is a cast. 2442 * @return void 2443 */ 2444 editContribution : function (contributionId, properties, binaryObjectProperties, callbackObject, callbackMethod, 2445 unlock, type) { 2446 AC.server.Callback.callServerUpdate( 2447 {id: contributionId, 2448 unlock: unlock, 2449 type: type, 2450 contributionProperties: properties, 2451 contributionBinObjProperties: binaryObjectProperties}, 2452 "editContribution", callbackObject, callbackMethod); 2453 }, 2454 2455 /** 2456 * Gets system demo dataset. This is only used for our COA demonstration. 2457 * 2458 * @param {Object} callbackObject 2459 * the callback object 2460 * @param {function} callbackMethod 2461 * the callback method 2462 * @return void 2463 */ 2464 getSystemDemoDataset : function (callbackObject, callbackMethod) { 2465 AC.server.Callback.callServerReadOnly( 2466 null, 2467 "getSystemDemoDataset", callbackObject, callbackMethod); 2468 }, 2469 2470 /** 2471 * Gets element configuration for a item in the ActionCenters system configuration. 2472 * 2473 * @param {String} elementConfigScope 2474 * The element configuration scope. Usually the contribution type for which the configuration is retrieved. 2475 * @param {String} [elementCategoryName] 2476 * The element category name. 2477 * @param {Object} callbackObject 2478 * The callback object. 2479 * @param {function} callbackMethod 2480 * The callback method. 2481 * @return void 2482 */ 2483 getSystemElementConfiguration : function (elementConfigScope, elementCategoryName, callbackObject, callbackMethod) { 2484 var passdata = { 2485 elementConfigScope: elementConfigScope, 2486 elementCategoryName: elementCategoryName, 2487 callbackObject: callbackObject, 2488 callbackMethod: callbackMethod}; 2489 if (!this.systemElementConfiguration) { 2490 AC.server.Callback.callServerReadOnly({},"getSystemElementConfiguration", this, this.getRequestedSystemElementConfig, passdata); 2491 } else { 2492 this.getRequestedSystemElementConfig(null, passdata); 2493 } 2494 }, 2495 /** 2496 * 2497 */ 2498 getRequestedSystemElementConfig : function (msg, passdata) { 2499 if (msg) { 2500 this.systemElementConfiguration = actionCenterJSON.getMsgProperty(msg, 'data.elementConfiguration'); 2501 } 2502 var returnVal = this.systemElementConfiguration; 2503 if (passdata.elementConfigScope) { 2504 returnVal = actionCenterJSON.getMsgProperty(returnVal, passdata.elementConfigScope); 2505 if (passdata.elementCategoryName) { 2506 var category = null; 2507 for (var i=0; i<returnVal.categories.length && !category; i++) { 2508 if (returnVal.categories[i].name === passdata.elementCategoryName) { 2509 category = returnVal.categories[i]; 2510 } 2511 } 2512 returnVal = category; 2513 } 2514 } 2515 passdata.callbackMethod.call(passdata.callbackObject, returnVal); 2516 }, 2517 2518 /** 2519 * Update new system element configuration to the server. 2520 * 2521 * @param {Object} systemElementConfiguration 2522 * The new system element configuration. 2523 * @param {Object} callbackObject 2524 * The callback object. 2525 * @param {function} callbackMethod 2526 * The callback method. 2527 * @return void 2528 */ 2529 updateSystemElementConfiguration: function(systemElementConfiguration, callbackObject, callbackMethod){ 2530 AC.server.Callback.callServerUpdate( 2531 systemElementConfiguration, 2532 "updateSystemElementConfiguration", callbackObject, callbackMethod); 2533 }, 2534 2535 /** 2536 * Gets a contribution grouping of the specified type from the personal workspace of the user. 2537 * 2538 * @param {String} contributionGroupingType 2539 * The contribution grouping type to lookup in the user's personal workspace. 2540 * @param {Object} callbackObject 2541 * The callback object. 2542 * @param {function} callbackMethod 2543 * The callback method. 2544 * @return void 2545 */ 2546 getPersonalWorkspaceContribution : function (contributionGroupingType, callbackObject, callbackMethod) { 2547 AC.server.Callback.callServerReadOnly( 2548 {contributionType: contributionGroupingType}, 2549 "getPersonalWorkspaceContribution", callbackObject, callbackMethod); 2550 }, 2551 2552 /** 2553 * Gets the properties of the specified contribution. 2554 * 2555 * @param {String} contributionId 2556 * The contribution id. 2557 * @param {Object} callbackObject 2558 * The callback object. 2559 * @param {function} callbackMethod 2560 * The callback method. 2561 * @return void 2562 */ 2563 getContributionProperties : function (contributionId, callbackObject, callbackMethod) { 2564 AC.server.Callback.callServerReadOnly( 2565 {contributionId: contributionId}, 2566 "getContributionProperties", callbackObject, callbackMethod); 2567 }, 2568 2569 /** 2570 * Tells the server to publish all the current contributions for a given channel. The server will parse the 2571 * channel name and retrive all existing contributions for that channel and publish them to this client only. 2572 * The server does not re-publish the matching contributions to all clients. 2573 * 2574 * @param {String} addChannel 2575 * The channel on which to publish all the existing matching contributions 2576 * @param {Boolean} createOneIfNoneExists 2577 * boolean flag indicating whether to create a subordinate contribution if none has been found 2578 * @param {Object} callbackObject 2579 * The callback object. 2580 * @param {function} callbackMethod 2581 * The callback method. 2582 * @return void 2583 */ 2584 publishRelatedContributions : function (addChannel, createOneIfNoneExists, createOneMode, miniMessage, callbackObject, callbackMethod) { 2585 AC.server.Callback.callServerUpdate( 2586 {AC_requestedchannel: addChannel, 2587 miniMessage: miniMessage, 2588 createOneIfNoneExists: createOneIfNoneExists, 2589 createOneMode: createOneMode}, 2590 "publishRelatedContributions", callbackObject, callbackMethod); 2591 }, 2592 2593 /** 2594 * Publishes a specified contribution if it has a specified relationship to the specified superiorid 2595 * 2596 * @param {String} addChannel 2597 * The channel that specifies the superiorId/relationshipType/subordinateId and for which to publish 2598 * the existing contribution if the matching relationship exists 2599 * @return void 2600 */ 2601 publishRelationship : function (addChannel) { 2602 AC.server.Callback.callServerReadOnly( 2603 {AC_requestedchannel: addChannel}, 2604 "publishRelationship"); 2605 }, 2606 2607 /** 2608 * Gets contributions that have a set of relationships and are of a specified type. The matching contributions 2609 * will be sent back to the callback object/method 2610 * in an array. The message key to the array in the message is "matchingContributions". 2611 * 2612 * @param {String[]} superiorIds 2613 * an array of superior ids 2614 * @param {String[]} relationshipTypes 2615 * an array of relationship types. The index of the relationship matches the index of the superior id in 2616 * the superiorIds array to which it is related. 2617 * @param {String} contributionType 2618 * the type of subordinate contributions 2619 * @param {Boolean} [createOneIfNoneExists] 2620 * boolean flag indicating whether to create a subordinate contribution if none is found 2621 * @param {Object} callbackObject 2622 * The callback object. 2623 * @param {function} callbackMethod 2624 * The callback method. 2625 * @return void 2626 */ 2627 getContributionsMatchingRelationships : function (superiorIds, relationshipTypes, contributionType, 2628 createOneIfNoneExists, callbackObject, callbackMethod) { 2629 AC.server.Callback.callServerUpdate( 2630 {superiorIds: actionCenterUtility.convertStringArrayToDelimitedString(superiorIds), 2631 relationshipTypes: actionCenterUtility.convertStringArrayToDelimitedString(relationshipTypes), 2632 contributionType: contributionType, 2633 createOneIfNoneExists: createOneIfNoneExists}, 2634 "getContributionsMatchingRelationships", callbackObject, callbackMethod); 2635 }, 2636 2637 /** 2638 * Gets a contribution that has the specified property and is related related to the specified superior contribution 2639 * via the specified relationship type and of the specified contribution type. If no such contribution is found, one 2640 * will be created if the createOneIfNoneExists boolean flag is set. 2641 * 2642 * @param {String} superiorId 2643 * The superior id 2644 * @param {String} [relationshipType] 2645 * The relationship type 2646 * @param {String} [subordinateType] 2647 * The subordinate type 2648 * @param {String} propertyKey 2649 * The property key 2650 * @param {String} propertyValue 2651 * The property value 2652 * @param {Boolean} [createOneIfNoneExists] 2653 * Boolean flag to indicate whether a new contribution should be created if no match is found. Default is false. 2654 * @param {Object} callbackObject 2655 * The callback object. 2656 * @param {function} callbackMethod 2657 * The callback method. 2658 * @return void 2659 */ 2660 getContributionByProperty : function (superiorId, relationshipType, subordinateType, propertyKey, propertyValue, 2661 createOneIfNoneExists, callbackObject, callbackMethod) { 2662 AC.server.Callback.callServerUpdate( 2663 {superiorId: superiorId, 2664 relationshipType: relationshipType, 2665 subordinateType: subordinateType, 2666 propertyKey: propertyKey, 2667 propertyValue: propertyValue, 2668 createOneIfNoneExists: createOneIfNoneExists}, 2669 "getContributionByProperty", callbackObject, callbackMethod); 2670 }, 2671 2672 /** 2673 * Gets users of the specified project. 2674 * 2675 * @param {String} projectID 2676 * The id of the project contribution. 2677 * @param {Object} callbackObject 2678 * The callback object. 2679 * @param {function} callbackMethod 2680 * The callback method. 2681 * @return void 2682 */ 2683 getUsersInProject : function (projectID, callbackObject, callbackMethod) { 2684 AC.server.Callback.callServerReadOnly({projectID: projectID}, "getUsersInProject", 2685 callbackObject, callbackMethod); 2686 }, 2687 2688 /** 2689 * Gets users having the specified systemrole(s). 2690 * 2691 * @param {String[]} systemRoles 2692 * An array of systemroles. 2693 * @param {Object} callbackObject 2694 * The callback object. 2695 * @param {function} callbackMethod 2696 * The callback method. 2697 * @return void 2698 */ 2699 getUsers : function (systemRoles, callbackObject, callbackMethod) { 2700 var systemRoleDelimitedString = actionCenterUtility.convertStringArrayToDelimitedString(systemRoles); 2701 AC.server.Callback.callServerReadOnly({systemRoles: systemRoleDelimitedString}, "getUsers", 2702 callbackObject, callbackMethod); 2703 }, 2704 2705 /** 2706 * Gets users having specified systemrole(s) and no role in the specified project. 2707 * 2708 * @param {String} workspaceProjectDefId 2709 * The id of the project contribution. 2710 * @param {String[]} systemRoles 2711 * an array of systemroles 2712 * @param {Object} callbackObject 2713 * The callback object. 2714 * @param {function} callbackMethod 2715 * The callback method. 2716 * @return void 2717 */ 2718 getUnassignedUsers : function (workspaceProjectDefId, systemRoles, callbackObject, callbackMethod) { 2719 var systemRoleDelimitedString = actionCenterUtility.convertStringArrayToDelimitedString(systemRoles); 2720 if (!workspaceProjectDefId) { 2721 workspaceProjectDefId = currentPSSWorkspaceId; 2722 } 2723 AC.server.Callback.callServerReadOnly( 2724 {projectID: workspaceProjectDefId, systemRoles: systemRoleDelimitedString}, 2725 "getUnassignedUsers", 2726 callbackObject, callbackMethod); 2727 }, 2728 2729 /** 2730 * Remove the specified user(s) from the specified project. 2731 * 2732 * @param {String[]} usernames 2733 * The array of user names to remove 2734 * @param {String} projectID 2735 * The id of the project contribution. 2736 * @return void 2737 */ 2738 removeUserFromProject : function (usernames, projectID) { 2739 this.startBatch(); 2740 for (var index = 0; index < usernames.length; index++) { 2741 AC.server.Callback.callServerReadOnly( 2742 {removeUser: usernames[index], projectID: projectID}, 2743 "removeUserFromProject"); 2744 } 2745 this.endBatch(); 2746 }, 2747 2748 /** 2749 * Grants the specified user(s) access to the specified project. 2750 * 2751 * @param {String[]} usernames 2752 * The array of user names. 2753 * @param {String} projectID 2754 * The id of the project. 2755 * @return void 2756 */ 2757 grantUserAccessToProject: function (usernames, projectID) { 2758 this.startBatch(); 2759 for (var index = 0; index < usernames.length; index++) { 2760 AC.server.Callback.callServerReadOnly( 2761 {grantUser: usernames[index], projectID: projectID}, "grantUserAccessToProject"); 2762 } 2763 this.endBatch(); 2764 }, 2765 2766 /** 2767 * Copies contributions and all the subordinates to the clipboard 2768 * 2769 * @param {String[]} contributionIds 2770 * Array of contributions which should be copied to the clipboard. 2771 * @return void 2772 */ 2773 copyToClipboard : function (componentId, deepCopyIds, shallowCopyIds) { 2774 AC.data.Clipboard.setPendingCopy(true); 2775 AC.server.Callback.callServerUpdate( 2776 {componentId: componentId, 2777 deepCopyIds: deepCopyIds, 2778 shallowCopyIds: shallowCopyIds}, 2779 "copyToClipboard", null, null); 2780 }, 2781 2782 /** 2783 * Cuts contributions and all the subordinates to the clipboard. 2784 * 2785 * @param {String[]} contributionIds 2786 * Array of contributions which should be cut to the clipboard. 2787 * @return void 2788 */ 2789 cutToClipboard : function (componentId, deepCopyIds) { 2790 AC.data.Clipboard.setPendingCopy(true); 2791 AC.server.Callback.callServerUpdate( 2792 {componentId: componentId, 2793 deepCopyIds: deepCopyIds}, 2794 "cutToClipboard", null, null); 2795 }, 2796 2797 /** 2798 * Pastes contributions from the clipboard in the selected superior, having this new relationship, 2799 * after a certain contribution. 2800 * 2801 * @param {String} superiorContributionId 2802 * The superior contribution for the contributions being pasted. 2803 * @param {String} relationshipType 2804 * The pasted contributions relationship to the new superior. 2805 * @param {String} afterContributionId 2806 * The pasted contributions should be after this contribution. 2807 * @return void 2808 */ 2809 pasteFromClipboard : function (superiorContributionId, relationshipType, afterContributionId, beforeContributionId, targetId, type) { 2810 var clientGUID = dojox.uuid.generateTimeBasedUuid(); 2811 AC.data.Clipboard.setClientGUID(clientGUID); 2812 AC.server.Callback.callServerUpdate( 2813 {superiorContributionId: superiorContributionId, 2814 relationshipType: relationshipType, 2815 afterContributionId: afterContributionId, 2816 beforeContributionId: beforeContributionId, 2817 targetId: targetId, 2818 type: type, 2819 clientGUID: clientGUID}, 2820 "pasteFromClipboard", null, null); 2821 }, 2822 2823 /** 2824 * Gets the recycle bin contributions for a project. 2825 * 2826 * @param {String} projectId 2827 * The project contribution id for which we are retrieving recycle bin contributions. 2828 * @param {Object} callbackObject 2829 * The callback object. 2830 * @param {function} callbackMethod 2831 * The callback method. 2832 * @return void 2833 */ 2834 getRecycleBinContributions : function (projectId, callbackObject, callbackMethod) { 2835 AC.server.Callback.callServerReadOnly( 2836 {projectId: projectId}, 2837 "getRecycleBinContributions", callbackObject, callbackMethod); 2838 }, 2839 2840 /** 2841 * Gets the recycle bin projects. 2842 * TODO: Move this to a CACE API. 2843 * 2844 * @param {String} [projectType] 2845 * The type of projects. Defaults to "AC_Project_Definition". 2846 * @param {Object} callbackObject 2847 * The callback object. 2848 * @param {function} callbackMethod 2849 * The callback method. 2850 * @return void 2851 */ 2852 getRecycleBinProjects : function (projectType, callbackObject, callbackMethod) { 2853 AC.server.Callback.callServerReadOnly( 2854 {contributionType: projectType}, 2855 "getRecycleBinProjects", callbackObject, callbackMethod); 2856 }, 2857 2858 /** 2859 * Gets the open CACE tool projects for a particular user. 2860 * 2861 * @param {Object} callbackObject 2862 * The callback object. 2863 * @param {function} callbackMethod 2864 * The callback method. 2865 * @return void 2866 */ 2867 getAvailableProjects : function (callbackObject, callbackMethod) { 2868 AC.server.Callback.callServerReadOnly( 2869 null, 2870 "getAvailableProjects", callbackObject, callbackMethod); 2871 }, 2872 2873 /** 2874 * Gets the available system widgets. 2875 * TODO: Move this to a CACE API. 2876 * 2877 * @param {String} widgetType 2878 * the widget type. 'AC_Control' or 'AC_Tool'. 2879 * @param {Object} callbackObject 2880 * The callback object. 2881 * @param {function} callbackMethod 2882 * The callback method. 2883 * @return void 2884 */ 2885 getAvailableWidgets: function (widgetType, callbackObject, callbackMethod) { 2886 AC.server.Callback.callServerReadOnly( 2887 {widgetType: widgetType}, 2888 "getAvailableWidgets", callbackObject, callbackMethod); 2889 }, 2890 2891 /** 2892 * Moves a contribution or collection of contributions to the recycle bin. 2893 * 2894 * @param {String|Object} contribution 2895 * The id of the contribution to move to the recycle bin 2896 * - or - 2897 * a collection of objects with property contributionId, each of the contributions will be moved to the recycle bin. 2898 * @return void 2899 */ 2900 moveContributionToRecycleBin : function (contribution) { 2901 if (Ext.isArray(contribution)) { 2902 var contributionIds = new Array(); 2903 for (var i=0; i<contribution.length; i++) { 2904 //for each contribution, check to see if it is a child of one already moved to contribution recycle bin 2905 var currentContribution = contribution[i]; 2906 var ancestorAlreadyMoved = false; 2907 for (var x=0; x<i && !ancestorAlreadyMoved; x++) { 2908 ancestorAlreadyMoved = currentContribution.isAncestor(contribution[x]); 2909 } 2910 if (!ancestorAlreadyMoved) { 2911 contributionIds.push(currentContribution.contributionId); 2912 } 2913 } 2914 AC.server.Callback.callServerUpdate( 2915 {contributionId: contributionIds}, 2916 "moveContributionToRecycleBin", null, null); 2917 } else { 2918 AC.server.Callback.callServerUpdate( 2919 {contributionId: [contribution]}, 2920 "moveContributionToRecycleBin", null, null); 2921 } 2922 }, 2923 2924 /** 2925 * Restores contributions from the recycle bin. 2926 * 2927 * @param {String[]} contributionIds 2928 * Array of contribution ids which should be restored. 2929 * @return void 2930 */ 2931 restoreContributionsFromRecycleBin : function (contributionIds) { 2932 AC.server.Callback.callServerUpdate( 2933 {contributionIds: contributionIds}, 2934 "restoreContributionsFromRecycleBin", null, null); 2935 }, 2936 2937 /** 2938 * Restores projects from a user's recycle bin. 2939 * TODO: Move this to a CACE API. 2940 * 2941 * @param {String} projectId 2942 * The id of the project contribution to restore. 2943 * @return void 2944 */ 2945 restoreProjectFromRecycleBin : function (projectId) { 2946 AC.server.Callback.callServerUpdate( 2947 {projectId: projectId}, 2948 "restoreProjectFromRecycleBin", null, null); 2949 }, 2950 2951 /** 2952 * Publishes an application to the "App Store". 2953 * TODO: Move this to a CACE API. 2954 * 2955 * @param {String} projectId 2956 * The id of the project contribution to publish. 2957 * @return void 2958 */ 2959 publishApplication : function (projectId) { 2960 Ext.MessageBox.show({ 2961 title: 'Publish Initiated', 2962 maxWidth : 700, 2963 msg: "Your request to Publish a Project is being processed.", 2964 buttons: Ext.MessageBox.OK, 2965 icon: Ext.MessageBox.INFO 2966 }); 2967 2968 AC.server.Callback.callServerUpdate( 2969 {projectId: projectId}, 2970 "publishApplication"); 2971 }, 2972 2973 /** 2974 * unpublishes an application to the "App Store". 2975 * TODO: Move this to a CACE API. 2976 * 2977 * @param {String} projectId 2978 * The id of the project contribution to publish. 2979 * @return void 2980 */ 2981 unPublishApplication : function (projectId) { 2982 Ext.MessageBox.show({ 2983 title: 'Unpublish Initiated', 2984 maxWidth : 700, 2985 msg: "Your request to Unpublish a Project is being processed.", 2986 buttons: Ext.MessageBox.OK, 2987 icon: Ext.MessageBox.INFO 2988 }); 2989 2990 AC.server.Callback.callServerUpdate( 2991 {projectId: projectId}, 2992 "unPublishApplication"); 2993 }, 2994 2995 /** 2996 * Creates a workspace from an application. 2997 * TODO: Move this to a CACE API. 2998 * 2999 * @param {String} projectId 3000 * The id of the project contribution to publish. 3001 * @param {Object} callbackObject 3002 * The callback object. 3003 * @param {function} callbackMethod 3004 * The callback method. 3005 * @return void 3006 */ 3007 createWorkspace : function (projectId, callbackObject, callbackMethod) { 3008 AC.server.Callback.callServerUpdate( 3009 {projectId: projectId}, 3010 "createWorkspace", 3011 callbackObject, 3012 callbackMethod); 3013 }, 3014 3015 /** 3016 * Get System Configuration for this user and for a particular configuration type. 3017 * TODO: Move this to a CACE API. 3018 * 3019 * @param {String}configurationType 3020 * A type of the system configuration you are looking for. 3021 * @param {Object} callbackObject 3022 * The callback object. 3023 * @param {function} callbackMethod 3024 * The callback method. 3025 * @return void 3026 */ 3027 getSystemConfiguration : function (configurationType, callbackObject, callbackMethod) { 3028 AC.server.Callback.callServerUpdate( 3029 {configurationType: configurationType}, 3030 "getSystemConfiguration", 3031 callbackObject, 3032 callbackMethod); 3033 }, 3034 3035 /** 3036 * Copies the specified contribution to the specified palette. 3037 * TODO: Move this to a CACE API. 3038 * 3039 * @param {String[]} contributionIds 3040 * The array of id's of the contributions to copy. 3041 * @param {String}paletteCategoryId 3042 * The id of the palette category where the contribution will be copied. 3043 * @param {String} [leaderRoleId] 3044 * The leader role id. This should be provided when copying an agenda item to the palette. 3045 * TODO: move this functionality to the back end. 3046 * @param {String} [participantRoleId] 3047 * The participant role id. This should be provided when copying an agenda item to the palette. 3048 * TODO: move this functionality to the back end. 3049 * @return void 3050 */ 3051 copyToPalette : function (contributionIds, paletteCategoryId, leaderRoleId, participantRoleId) { 3052 AC.server.Callback.callServerUpdate( 3053 {contributionIds: contributionIds, 3054 categoryId: paletteCategoryId, 3055 leaderRoleId: leaderRoleId, 3056 participantRoleId: participantRoleId}, 3057 "copyToPalette"); 3058 }, 3059 3060 /** 3061 * Pastes contributions from palette. 3062 * TODO: Move this to a CACE API. 3063 * 3064 * @param {String} superiorContributionId 3065 * The superior contribution for the contributions being pasted. 3066 * @param {String} contributionId 3067 * The id of the palette item being pasted/dropped. 3068 * @param {String} relationshipType 3069 * The pasted contributions relationship to the new superior. 3070 * @param {String} [afterContributionId] 3071 * The pasted contributions should be after this contribution. 3072 * @param {String} beforeContributionId. 3073 * The pasted contributions should be before this contribution. 3074 * @return void 3075 */ 3076 pasteFromPalette: function (superiorContributionId, 3077 contributionId, 3078 relationshipType, 3079 afterContributionId, 3080 beforeContributionId) { 3081 AC.server.Callback.callServerUpdate( 3082 {superiorContributionId: superiorContributionId, 3083 contributionId: contributionId, 3084 relationshipType: relationshipType, 3085 afterContributionId: afterContributionId, 3086 beforeContributionId: beforeContributionId}, 3087 "pasteFromPalette"); 3088 }, 3089 3090 /** 3091 * Performs a (shallow) copy of the contribution and relates it to the superior with the given relationship name. 3092 * 3093 * @param {String} contributionId 3094 * The contribution value object. 3095 * @param {String} superiorId 3096 * The superior contribution value object. 3097 * @param {String} relationshipType 3098 * The relationship to new superior. 3099 * @param {String} [beforeContributionId] 3100 * Place this new copy before the contribution with this id. 3101 * @param {String} [afterContributionId] 3102 * Place this new copy after the contribution with this id. 3103 * @return void 3104 */ 3105 copyContribution: function (contributionId, superiorId, relationshipType, afterContributionId, beforeContributionId, castToType) { 3106 AC.server.Callback.callServerUpdate( 3107 {contributionId: contributionId, 3108 superiorId: superiorId, 3109 relationshipType: relationshipType, 3110 afterContributionId: afterContributionId, 3111 beforeContributionId: beforeContributionId, 3112 type: castToType}, 3113 "copyContribution"); 3114 }, 3115 3116 /** 3117 * Performs a deep copy of the contribution and relates it to the superior with the given relationship name. 3118 * 3119 * @param {String} contributionId 3120 * The contribution value object. 3121 * @param {String} superiorId 3122 * The superior contribution value object. 3123 * @param {String} relationshipType 3124 * The relationship to new superior. 3125 * @param {String} [beforeContributionId] 3126 * Place this new copy before the contribution with this id. 3127 * @param {String} [afterContributionId] 3128 * Place this new copy after the contribution with this id. 3129 * @return void 3130 */ 3131 deepCopy: function (contributionId, superiorId, relationshipType, afterContributionId, beforeContributionId, castToType) { 3132 AC.server.Callback.callServerUpdate( 3133 {contributionId: contributionId, 3134 superiorId: superiorId, 3135 relationshipType: relationshipType, 3136 afterContributionId: afterContributionId, 3137 beforeContributionId: beforeContributionId, 3138 type: castToType, 3139 deepCopy: "true"}, 3140 "copyContribution"); 3141 }, 3142 /** 3143 * Copies a screen and adds superior relationship to activity and roled ids specified. 3144 * 3145 * @param {String} screenId 3146 * The screen id to be copied. 3147 * @param {String} activityId 3148 * The superior activity id. 3149 * @param {String} roleId 3150 * The superior role id. 3151 * @return void 3152 */ 3153 copyScreenToActivityRole: function (screenId, activityId, roleId) { 3154 AC.server.Callback.callServerUpdate( 3155 {screenId: screenId, 3156 activityId: activityId, 3157 roleId: roleId}, 3158 "copyScreenToActivityRole"); 3159 }, 3160 3161 /** 3162 * Copies a screen and replaces the specified screen 3163 * 3164 * @param {String} copyScreenId 3165 * The id of the screen to copy. 3166 * @param {String} replaceScreenId 3167 * The id of the screen to replace. 3168 * @return void 3169 */ 3170 copyReplaceScreen: function (copyScreenId, replaceScreenId) { 3171 AC.server.Callback.callServerUpdate( 3172 {screenId: copyScreenId, 3173 replaceId: replaceScreenId}, 3174 "copyScreenToActivityRole"); 3175 }, 3176 3177 /** 3178 * Moves a screen and adds superior relationship to activity and roled ids specified. 3179 * 3180 * @param {String} screenId 3181 * The screen id to be copied. 3182 * @param {String} activityId 3183 * The superior activity id. 3184 * @param {String} roleId 3185 * The superior role id. 3186 * @return void 3187 */ 3188 moveScreenToActivityRole: function (screenId, activityId, roleId) { 3189 AC.server.Callback.callServerUpdate( 3190 {screenId: screenId, 3191 activityId: activityId, 3192 roleId: roleId}, 3193 "moveScreenToActivityRole"); 3194 }, 3195 3196 /** 3197 * Move a user or group of users to a screen. 3198 * 3199 * @param {String} moveToId 3200 * This will indicate where to move the user(s). If it is the text "next" or "previous", the 3201 * contributon service will determine what that means. If the value is an id of a Role, then all users 3202 * specified will be moved to that role, if the id is an activity, all users specified will be moved to 3203 * that activity 3204 * @param (boolean) followTheLeader 3205 * Boolean indicator to tell whether all workspace users will get moved with the initiating user. 3206 * @param {String} workspaceProjectDefId 3207 * The id of the project definition contribution for the workspace the user is currently in 3208 * @param {Sting|String[]} contributionId 3209 * This is a single id or an Array of ids. The id(s) could be for contribution(s) of type AC_User, 3210 * so that specific users would be moved, it could be of type AC_Role, in which case all users having 3211 * that role would be moved, or of type AC_Activity so that all users on that activity would be moved. 3212 * @return void 3213 */ 3214 moveUser: function (moveToId, followTheLeader, workspaceProjectDefId, contributionId) { 3215 if (!workspaceProjectDefId) { 3216 workspaceProjectDefId = currentPSSWorkspaceId; 3217 } 3218 var contributionIds = null; 3219 if (contributionId) { 3220 contributionIds = actionCenterUtility.convertStringArrayToDelimitedString(contributionId); 3221 } 3222 AC.server.Callback.callServerUpdate( 3223 {contributionIds: contributionIds, 3224 followTheLeader: followTheLeader, 3225 moveToId: moveToId, 3226 workspaceProjectDefId: workspaceProjectDefId}, 3227 "moveUser"); 3228 }, 3229 3230 /** 3231 * Add a PSS user to a workspace. 3232 * 3233 * @param {String} roleId 3234 * The id of the role the user is being assigned. 3235 * @param {String|String[]} userid 3236 * This is a single userId or an Array of userIds. The userIds represent users in the user table 3237 * @param {String} workspaceProjectDefId 3238 * The id of the project definition contribution for the workspace to which the user is to be added. 3239 * @return void 3240 */ 3241 addUser: function (roleId, userId, workspaceProjectDefId) { 3242 if (!workspaceProjectDefId) { 3243 workspaceProjectDefId = currentPSSWorkspaceId; 3244 } 3245 var userIds = null; 3246 if (userId) { 3247 userIds = actionCenterUtility.convertStringArrayToDelimitedString(userId); 3248 } 3249 AC.server.Callback.callServerUpdate( 3250 {userIds: userIds, 3251 roleToId: roleId, 3252 workspaceProjectDefId: workspaceProjectDefId}, 3253 "addUser"); 3254 }, 3255 3256 /** 3257 * Remove a PSS user from a workspace 3258 * 3259 * @param {String|String[]} userid 3260 * This is a single contribution id or an Array of contribution id. The contribution ids represent contribution ids for user 3261 * contributions in contribution table. 3262 * @return void 3263 */ 3264 removeUserFromWorkspace: function (userId) { 3265 var userIds = null; 3266 if (userId) { 3267 userIds = actionCenterUtility.convertStringArrayToDelimitedString(userId); 3268 } 3269 AC.server.Callback.callServerUpdate( 3270 {userIds: userIds}, 3271 "removeUserFromWorkspace"); 3272 }, 3273 3274 /** 3275 * Get the workspace dataset based on the datasetName and workspaceId 3276 * 3277 * @param {String} datasetName 3278 * This is the datasetName 3279 * @param {Object} callbackObject 3280 * The callback object. 3281 * @param {function} callbackMethod 3282 * The callback method. 3283 * @param {String} workspaceId 3284 * The workspace ID. 3285 * @return void 3286 */ 3287 getWorkspaceDataset: function (datasetName, callbackObject, callbackMethod, workspaceId) { 3288 if (!workspaceId) { 3289 workspaceId = currentPSSWorkspaceId; 3290 } 3291 AC.server.Callback.callServerUpdate( 3292 {datasetName: datasetName, 3293 workspaceId: workspaceId}, 3294 "getWorkspaceDataset", 3295 callbackObject, 3296 callbackMethod); 3297 }, 3298 /** 3299 * Add an activity to a workspace, copying or linking datasets as specified, 3300 * 3301 * @param {String} activityId 3302 * This id of the activity to copy 3303 * @param {String} workspaceId 3304 * The id of the workspace project to add to 3305 * @param (String) parentId 3306 * The id of the superior contribution to the new activity 3307 * @param (String) afterId 3308 * The id of the sibling contribution to place the new activity after 3309 * @param (String) initialData 3310 * A value indicating whether to copy or link data 3311 * @param (String) dataSourceIncrementer 3312 * The incrementer of the activity being copied or linked to 3313 * @param (String) name 3314 * The name of the new Activity 3315 * @param (String) description 3316 * The description of the new Activity 3317 * @param (Object) callbackObject 3318 * The callback object 3319 * @param {function} callbackMethod 3320 * The callback method. 3321 * @return void 3322 */ 3323 addWorkspaceActivity: function (activityId, workspaceId, parentId, afterId, initialData, dataSourceIncrementer, name, description, callbackObject, callbackMethod) { 3324 AC.server.Callback.callServerUpdate( 3325 {workspaceId: workspaceId, 3326 parentId: parentId, 3327 afterId: afterId, 3328 activityId: activityId, 3329 initialData: initialData, 3330 dataSourceIncrementer: dataSourceIncrementer, 3331 name: name, 3332 description: description}, 3333 "addActivityToWorkspace", 3334 callbackObject, 3335 callbackMethod); 3336 }, 3337 /** 3338 * Gets the user id. 3339 * 3340 * @return CACE or PSS user id 3341 */ 3342 getUserId: function () { 3343 try { 3344 if (acPSSUserId) { 3345 return acPSSUserId; 3346 } 3347 } catch (err) { 3348 return workspaceUserId; 3349 } 3350 }, 3351 3352 /** 3353 * Thumb-prints the specified contribution with the current user's id. 3354 * 3355 * @param {String} contributionId 3356 * Contribution id. 3357 * @param {Boolean} [isCommit] 3358 * Boolean flag to indicate whether thumbprints should be submitted to the server. Defalut is false. 3359 * @return void 3360 */ 3361 thumbprint: function (contributionId, isCommit) { 3362 if (contributionId !== null) { 3363 if (this.thumbprints === "") { 3364 this.thumbprints += contributionId; 3365 } else { 3366 this.thumbprints += acGlobalDelimiter + contributionId; 3367 } 3368 } 3369 if (this.thumbprints !== "" && isCommit) { 3370 AC.server.Callback.callServerUpdate( 3371 {contributionId: this.thumbprints}, 3372 "thumbprint"); 3373 this.thumbprints = ""; 3374 } 3375 }, 3376 3377 /** 3378 * Thumb-prints the specified contribution when the window is closed. 3379 * 3380 * @param {String} contributionId 3381 * Contribution id. 3382 * @return void 3383 */ 3384 thumbprintContributionOnClose: function (contributionId) { 3385 if (typeof currentScreenId !== "undefined") { 3386 if (contributionId && currentScreenId && actionCenterAPI.getUserId()) { 3387 AC.server.Callback.callServerUpdate( 3388 {contributionId: contributionId, 3389 screenId: currentScreenId, 3390 userId: actionCenterAPI.getUserId()}, 3391 "thumbprintContributionOnClose"); 3392 } 3393 } 3394 }, 3395 3396 /** 3397 * Locks the specified contribution. 3398 * 3399 * @param {String} contributionId 3400 * The id of the contribution to lock. 3401 * @param {Object} callbackObject 3402 * The callback object. 3403 * @param {function} callbackMethod 3404 * The callback method. 3405 * @return void 3406 */ 3407 lockContribution: function (contributionId, callbackObject, callbackMethod) { 3408 AC.server.Callback.callServerUpdate( 3409 {contributionId: contributionId}, 3410 "lockContribution", 3411 callbackObject, 3412 callbackMethod); 3413 }, 3414 3415 /** 3416 * Unlocks the specified contribution. 3417 * 3418 * @param {String} contributionId 3419 * The id of the contribution to unlock. 3420 * @param {Object} callbackObject 3421 * The callback object. 3422 * @param {function} callbackMethod 3423 * The callback method. 3424 * @return void 3425 */ 3426 unlockContribution: function (contributionId, callbackObject, callbackMethod) { 3427 AC.server.Callback.callServerUpdate( 3428 {contributionId: contributionId}, 3429 "unlockContribution", 3430 callbackObject, 3431 callbackMethod); 3432 }, 3433 3434 /** 3435 * Edits the specified contribution property. 3436 * 3437 * @param {String} contributionId The id of the contribution, whose property to edit. 3438 * @param {String} key The property key. 3439 * @param {String} value The property value. 3440 * @param {Object} callbackObject The callback object. 3441 * @param {function} callbackMethod The callback method. 3442 * @return void 3443 */ 3444 editContributionProperty : function (contributionId, key, value, callbackObject, callbackMethod) { 3445 AC.server.Callback.callServerUpdate( 3446 {contributionId: contributionId, 3447 key: key, 3448 value: value}, 3449 "editContributionProperty", callbackObject, callbackMethod); 3450 }, 3451 3452 /** 3453 * Locks the specified contribution property. 3454 * 3455 * @param {String} contributionId The id of the contribution whose property to lock. 3456 * @param {String} propertyKey The property key. 3457 * @param {Object} callbackObject The callback object. 3458 * @param {function} callbackMethod The callback method. 3459 * @return void 3460 */ 3461 lockContributionProperty: function (contributionId, propertyKey, callbackObject, callbackMethod) { 3462 AC.server.Callback.callServerUpdate( 3463 {contributionId: contributionId, 3464 propertyKey: propertyKey}, 3465 "lockContributionProperty", 3466 callbackObject, 3467 callbackMethod); 3468 }, 3469 3470 /** 3471 * Unlocks the specified contribution property. 3472 * 3473 * @param {String} contributionId The id of the contribution whose property to unlock. 3474 * @param {String} propertyKey the property key 3475 * @param {Object} callbackObject The callback object. 3476 * @param {function} callbackMethod The callback method. 3477 * @return void 3478 */ 3479 unlockContributionProperty: function (contributionId, propertyKey, callbackObject, callbackMethod) { 3480 AC.server.Callback.callServerUpdate( 3481 {contributionId: contributionId, 3482 propertyKey: propertyKey}, 3483 "unlockContributionProperty", 3484 callbackObject, 3485 callbackMethod); 3486 }, 3487 3488 /** 3489 * Gets population rules for a component. 3490 * 3491 * @param {String} contributionId The component contribution id. 3492 * @param {Object} callbackObject The callback object. 3493 * @param {function} callbackMethod The callback method. 3494 * @return void 3495 */ 3496 getPopulationRules : function (contributionId, callbackObject, callbackMethod) { 3497 AC.server.Callback.callServerReadOnly( 3498 {contributionId: contributionId}, 3499 "getPopulationRules", callbackObject, callbackMethod); 3500 }, 3501 3502 /** 3503 * Gets sub-component configurations for the component. 3504 * 3505 * @param {String} superiorContributionId The superiorContributionId. 3506 * @param {String} componentId The component contribution id. 3507 * @param {Object} callbackObject The callback object. 3508 * @param {function} callbackMethod The callback method. 3509 * @return void 3510 */ 3511 getComponentConfiguration : function (superiorContributionId, componentId, callbackObject, callbackMethod) { 3512 if (superiorContributionId) { 3513 AC.server.Callback.callServerReadOnly( 3514 {superiorContributionId: superiorContributionId, 3515 componentId: componentId}, 3516 "getComponentConfiguration", callbackObject, callbackMethod); 3517 } else { 3518 AC.server.Callback.callServerReadOnly( 3519 {componentId: componentId}, 3520 "getComponentConfiguration", callbackObject, callbackMethod); 3521 } 3522 }, 3523 3524 /** 3525 * Gets a new swapper parent. 3526 * 3527 * @param {String} superiorRootContributionId The root contribution of the superior contribution. 3528 * @param {String} subordinateComponentId The subordinate component for which swapping is enabled. 3529 * @param {String} currentContributionId The current contribution id. 3530 * @param {String} shellSubcomponentId The shell subcomponent id. 3531 * @param {Object} callbackObject The callback object. 3532 * @param {function} callbackMethod The callback method. 3533 * @return void 3534 */ 3535 getSwapperParent : function (superiorRootContributionId, subordinateComponentId, currentContributionId, 3536 shellSubcomponentId, callbackObject, callbackMethod) { 3537 AC.server.Callback.callServerReadOnly( 3538 {superiorRootContributionId: superiorRootContributionId, 3539 subordinateComponentId: subordinateComponentId, 3540 currentContributionId: currentContributionId, 3541 shellSubcomponentId: shellSubcomponentId}, 3542 "getSwapperParent", callbackObject, callbackMethod); 3543 }, 3544 3545 /** 3546 * Gets the specified contribution. 3547 * 3548 * @param {String} contributionId The id of the contribution to retrieve. 3549 * @param {Object} callbackObject The callback object. 3550 * @param {function} callbackMethod The callback method. 3551 * @return void 3552 */ 3553 getContribution : function (contributionId, callbackObject, callbackMethod) { 3554 AC.server.Callback.callServerReadOnly( 3555 {contributionId: contributionId}, 3556 "getContribution", callbackObject, callbackMethod); 3557 }, 3558 3559 /** 3560 * Gets the Standard Activity Palette 3561 * 3562 * @return void 3563 */ 3564 getStandardActivityPalette : function (callbackObject, callbackMethod) { 3565 AC.server.Callback.callServerReadOnly( 3566 {}, 3567 "getStandardActivityPalette", callbackObject, callbackMethod); 3568 }, 3569 3570 /** 3571 * Deletes a widget from the system. 3572 * 3573 * @return void 3574 */ 3575 deleteWidget : function (contributionIds, isReadOnly, callbackObject, callbackMethod) { 3576 AC.server.Callback.callServerUpdate( 3577 {contributionIds: contributionIds, 3578 isReadOnly: isReadOnly}, 3579 "deleteWidget", callbackObject, callbackMethod); 3580 } 3581 }; 3582 3583 /** 3584 * Default constructor. 3585 * 3586 * @class Defines functions for manipulation of population rules. 3587 * @param {Object[]} populationRules 3588 * The array of population rules. 3589 */ 3590 AC.data.PopulationRulesParser = function (populationRules) { 3591 Ext.QuickTips.init(); 3592 /** 3593 * @private 3594 */ 3595 this.popRulesArray = populationRules; 3596 3597 /** 3598 * Gets the specified property matching superior and subordinate types starting at the specified index in the 3599 * population rules array. 3600 * 3601 * @param {String} subordinateType 3602 * The subordinate type. 3603 * @param {String} superiorType 3604 * The superior type. 3605 * @param {String} key 3606 * The key. 3607 * @param {String} index 3608 * The starting index into the population rules array 3609 * @return {String} 3610 * The matching property or null if no match is found. 3611 */ 3612 this.getRuleProperty = function (subordinateType, superiorType, key, index) { 3613 if (!index) { 3614 index = 0; 3615 } 3616 var property = null; 3617 for (var i = index; i < this.popRulesArray.length; i++) { 3618 if (subordinateType === this.popRulesArray[i].subordinate_type) { 3619 if (superiorType === this.popRulesArray[i].superior_type) { 3620 property = eval('this.popRulesArray[' + i + '].' + key); 3621 } else if (!property) { 3622 // in case of a node that is in an invalid location, match the first one matching 3623 // the subordinate type 3624 property = eval('this.popRulesArray[' + i + '].' + key); 3625 } 3626 } 3627 } 3628 return property; 3629 }; 3630 3631 /** 3632 * Gets the array of subordinates of the specified superior type starting at the specified index. 3633 * 3634 * @param {String} superiorType 3635 * The superior type. 3636 * @param {Integer} index 3637 * The starting index into the population rules array. 3638 * @return {Object[]} 3639 * The array of matching subordinates. 3640 */ 3641 this.getSubordinatesOfType = function (superiorType, index) { 3642 if (!index) { 3643 index = 0; 3644 } 3645 var subordinateTypes = []; 3646 for (var i = index; i < this.popRulesArray.length; i++) { 3647 if (superiorType === this.popRulesArray[i].superior_type) { 3648 subordinateTypes.push(this.popRulesArray[i]); 3649 } 3650 } 3651 return subordinateTypes; 3652 }; 3653 3654 /** 3655 * Checks if the specified superior has any subordinates. 3656 * 3657 * @param {String} superiorType 3658 * The superior type. 3659 * @param {Integer} index 3660 * The starting index into the population rules array. 3661 * @return {Boolean} 3662 * True if the superior has at least one subordinate or false otherwise. 3663 */ 3664 this.hasSubordinatesOfType = function (superiorType, index) { 3665 return (this.getSubordinatesOfType(superiorType, index).length > 0); 3666 }; 3667 3668 /** 3669 * Gets the relationship type for the specified superior and subordinate types. 3670 * 3671 * @param {String} subordinateType 3672 * The subordinate type. 3673 * @param {String} superiorType 3674 * The superior type. 3675 * @return {String} 3676 * The matching relationship type if one exists or null otherwise. 3677 */ 3678 this.getRelationshipTypeFor = function (subordinateType, superiorType) { 3679 var relationshipType = null; 3680 for (var i = 0; i < this.popRulesArray.length; i++) { 3681 if (subordinateType === this.popRulesArray[i].subordinate_type && 3682 superiorType === this.popRulesArray[i].superior_type) { 3683 relationshipType = this.popRulesArray[i].relationship_to_superior; 3684 break; 3685 } 3686 } 3687 return relationshipType; 3688 }; 3689 3690 /** 3691 * Gets all population rule types. 3692 * 3693 * @param {Integer} index 3694 * The starting index into the population rules array. 3695 * @return {String[]} 3696 * An array of rule types. 3697 */ 3698 this.getAllTypesList = function (index) { 3699 if (!index) { 3700 index = 0; 3701 } 3702 var subordinateTypes = []; 3703 for (var i = index; i < this.popRulesArray.length; i++) { 3704 subordinateTypes.push(this.popRulesArray[i].subordinate_type); 3705 } 3706 return subordinateTypes; 3707 3708 }; 3709 3710 /** 3711 * Gets a list of all child types. 3712 * 3713 * @param {Integer} index 3714 * The starting index into the population rules array. 3715 * @return {String[]} 3716 * An array of child types. 3717 */ 3718 this.getAllChildTypeList = function (index) { 3719 var childTypeList = []; 3720 if (this.popRulesArray) { 3721 for (var x = 0; x < this.popRulesArray.length; x++) { 3722 var childType = { 3723 type: this.popRulesArray[x].subordinate_type, 3724 relationship: this.popRulesArray[x].relationship_to_superior, 3725 createOne: false 3726 }; 3727 if (childTypeList.indexOf(childType < 0)) { 3728 childTypeList.push(childType); 3729 } 3730 } 3731 } 3732 return childTypeList; 3733 }; 3734 3735 /** 3736 * Gets a list of all valid child types of the specified superior. 3737 * 3738 * @param {String} superiorType 3739 * The superior type. 3740 * @param {Integer} index 3741 * The starting index into the population rules array. 3742 * @return {String[]} 3743 * An array of valid child types. 3744 */ 3745 this.getValidChildTypeList = function (superiorType, index) { 3746 var supType = superiorType; 3747 var children = this.getSubordinatesOfType(supType, index); 3748 var childTypeList = []; 3749 if (children) { 3750 for (var x = 0; x < children.length; x++) { 3751 var childType = { 3752 type: children[x].subordinate_type, 3753 relationship: children[x].relationship_to_superior, 3754 createOne: false 3755 }; 3756 childTypeList.push(childType); 3757 } 3758 } 3759 return childTypeList; 3760 }; 3761 3762 /** 3763 * Checks if the specified child is a valid child for the specified superior. 3764 * 3765 * @param {String} superiorType 3766 * The superior type. 3767 * @param {String} childType 3768 * The child type. 3769 * @return {Boolean} 3770 * True if the child is a valid child or false otherwise 3771 */ 3772 this.isValidChildType = function (superiorType, childType) { 3773 var validChildTypes = this.getSubordinatesOfType(superiorType); 3774 for (var i = 0; i < validChildTypes.length; i++) { 3775 if (validChildTypes[i].subordinate_type === childType) { 3776 return true; 3777 } 3778 } 3779 return false; 3780 }; 3781 3782 /** 3783 * Checks if the array of population rules has more than one occurrence of any given type. 3784 * 3785 * @return {Boolean} 3786 * True if there exists more than one rule with any given type or false otherwise. 3787 */ 3788 this.hasAmbiguities = function () { 3789 var isAmbiguous = false; 3790 var workingList = []; 3791 for (var x = 0; x < this.popRulesArray.length && !isAmbiguous; x++) { 3792 if (workingList.indexOf(this.popRulesArray[x].superior_type) === -1) { 3793 workingList.push(this.popRulesArray[x].superior_type); 3794 } else { 3795 isAmbiguous = true; 3796 } 3797 } 3798 return isAmbiguous; 3799 }; 3800 3801 /** 3802 * Gets valid cast types on trigger-drop by iterating through the population rule array and collecting all 3803 * population rule types that are valid casts. 3804 * 3805 * @return {Boolean} 3806 * The array of valid casts. 3807 */ 3808 this.getValidCastTypesOnTriggerDrop = function () { 3809 var validCastTypes = []; 3810 for (var x = 0; this.popRulesArray && x < this.popRulesArray.length; x++) { 3811 if (this.popRulesArray[x].isValidCastOnTriggerDrop && 3812 this.popRulesArray[x].isValidCastOnTriggerDrop === 'Y') { 3813 validCastTypes.push(this.popRulesArray[x].subordinate_type); 3814 } 3815 } 3816 if (validCastTypes.length > 0) { 3817 return validCastTypes; 3818 } else { 3819 return null; 3820 } 3821 }; 3822 3823 /** 3824 * Gets the drop rules properties for the specfied subordinate type and drop type 3825 * 3826 * @param {String} subordinateType 3827 * The contribution type of the drop target. 3828 * @param {String} dropType 3829 * A string representing the component drop type, expected values are: 'ctrlDropFromWithin', 'dropFromWithin', 'ctrlDropFromWithout' or 'dropFromWithout'. 3830 * @return {Object} 3831 * An object containing the properties of the matching drop event contribution 3832 */ 3833 this.getDropRules = function(subordinateType, dropType) { 3834 var popRule = null; 3835 for (var i = 0; i < this.popRulesArray.length; i++) { 3836 var rule = this.popRulesArray[i]; 3837 if (subordinateType === rule.subordinate_type) { 3838 popRule = rule; 3839 break; 3840 } 3841 } 3842 if (popRule && popRule[dropType]) { 3843 var dropRules = new AC.data.Contribution(popRule[dropType]).getParsedProperties(); 3844 dropRules.dropDisabled = dropRules.enabled !== 'Y'; 3845 dropRules.doMove = dropRules.action === 'MOVE'; 3846 dropRules.doCopyShallow = dropRules.action === 'COPY SHALLOW'; 3847 dropRules.doCopyDeep = dropRules.action === 'COPY DEEP'; 3848 dropRules.toSub = dropRules.location === 'SUB'; 3849 dropRules.toBefore = dropRules.location === 'BEFORE'; 3850 dropRules.toAfter = dropRules.location === 'AFTER'; 3851 dropRules.toAppend = dropRules.location === 'APPEND'; 3852 dropRules.toStandard = dropRules.location === 'STANDARD'; 3853 return dropRules; 3854 } 3855 }; 3856 }; 3857 3858 /** 3859 * Default constructor. 3860 * 3861 * @class Defines the contribution counter nodes. 3862 * @param contributionChildCounter 3863 * the child counter 3864 * @param contributionId 3865 * the contribution id 3866 * @param thumbprints 3867 * the thumbprints 3868 * @param superiorNode 3869 * the superior of this node 3870 */ 3871 AC.data.ContributionChildCounterNode = function (contributionChildCounter, contributionId, thumbprints, superiorNode) { 3872 /** 3873 * Indicates if this is a new contribution 3874 * 3875 * @default false 3876 */ 3877 this._isNew = false; 3878 3879 /** The child counter. */ 3880 this._contributionChildCounter = contributionChildCounter; 3881 3882 /** The contribution id. */ 3883 this._contributionId = contributionId; 3884 3885 /** The superior node. */ 3886 this._superiorNode = superiorNode; 3887 3888 /** The array of subordinates. */ 3889 this._subordinates = []; 3890 3891 /** The AC listener. */ 3892 this._actionCenterListener = new ActionCenterListener(); 3893 3894 /** The array of all child types. */ 3895 this._childTypeList = this._contributionChildCounter._populationRulesUtil.getAllChildTypeList(); 3896 3897 /** 3898 * Looks up a child node with the specified id in the list of subordinates. 3899 * 3900 * @param id 3901 * the contributon id 3902 * @return the subordinate node with the specified id or null if no such node is found 3903 */ 3904 this.findChildById = function (id) { 3905 for (var x = 0; x < this._subordinates.length; x++) { 3906 if (id === this._subordinates[x]._contributionId) { 3907 return this._subordinates[x]; 3908 } 3909 } 3910 return null; 3911 }; 3912 3913 /** 3914 * Creates a child contribution counter node with the configuration of the specified message. 3915 * 3916 * @param msg 3917 * the message 3918 * @return void 3919 */ 3920 this.createChild = function (msg) { 3921 var id = msg.data.contribution.id; 3922 if (id) { 3923 if (!this.findChildById(id)) { 3924 this._subordinates.push( 3925 new AC.data.ContributionChildCounterNode( 3926 this._contributionChildCounter, 3927 msg.data.contribution.id, 3928 msg.data.contribution.thumbprints, 3929 this 3930 ) 3931 ); 3932 } 3933 } 3934 }; 3935 3936 /** 3937 * Deletes the child node specified in the message by invoking the destroy function on the node. 3938 * 3939 * @param msg 3940 * the message 3941 * @return void 3942 */ 3943 this.deleteChild = function (msg) { 3944 if (!this.isMove(msg)) { 3945 var childNode = this.findChildById(msg.data.contribution.id); 3946 if (childNode) { 3947 childNode.destroy(); 3948 } 3949 } 3950 }; 3951 3952 /** 3953 * Destroys this node. 3954 * 3955 * @param msg 3956 * the message 3957 * @return void 3958 */ 3959 this.destroy = function (msg) { 3960 // destroy all subordinate nodes 3961 while (this._subordinates.length > 0) { 3962 this._subordinates[0].destroy(); 3963 } 3964 // unsubscribe 3965 this._actionCenterListener.destroy(); 3966 if (this._superiorNode) { 3967 // decrement counters 3968 if (this._isNew) { 3969 this._contributionChildCounter.decrementNewCount(); 3970 } 3971 this._contributionChildCounter.decrementCount(); 3972 // Remove this node from it's superior's collection of subordinates 3973 this._superiorNode._subordinates.remove(this); 3974 } 3975 }; 3976 3977 /** 3978 * Checks if the action specified by the message is a move, instead of a delete, message. 3979 * 3980 * @param msg 3981 * the message 3982 * @return true if the delete is part of a move or false otherwise 3983 */ 3984 this.isMove = function (msg) { 3985 return false; 3986 }; 3987 3988 /** 3989 * Thumbprints this node upon receipt of a thumbprint message. 3990 * 3991 * @param msg 3992 * the message 3993 * @return void 3994 */ 3995 this.thumbprinted = function (msg) { 3996 this._actionCenterListener.unsubscribeThumbprints(); 3997 this._contributionChildCounter.decrementNewCount(); 3998 this._isNew = false; 3999 }; 4000 4001 if (this._superiorNode) { 4002 // if this is not the top level node, increment appropriate counters 4003 this._contributionChildCounter.incrementCount(); 4004 4005 if (!thumbprints || thumbprints.indexOf(actionCenterAPI.getUserId()) === -1) { 4006 // if this user's thumbprint is not on this contribution, 4007 // mark as new 4008 this._isNew = true; 4009 // increment the new counter 4010 this._contributionChildCounter.incrementNewCount(); 4011 // and listen for thumbprint 4012 this._actionCenterListener.getThumbprints(this._contributionId, this, 'thumbprinted'); 4013 } 4014 } 4015 4016 for (var x = 0; x < this._childTypeList.length; x++) { 4017 this._actionCenterListener.getSubordinates( 4018 this._contributionId, 4019 this._childTypeList[x].relationship, 4020 this._childTypeList[x].type, 4021 this, 'createChild', 4022 false, 4023 this, 'deleteChild', 4024 null, true); 4025 } 4026 } 4027 4028 /** 4029 * Default constructor. 4030 * 4031 * @class Contribution counter. 4032 * @param superiorId 4033 * the superior counter node's contribution id 4034 * @param populationRules 4035 * the population rules 4036 * @param callbackobject 4037 * the callback object 4038 * @param callbackmethod 4039 * the callback method 4040 */ 4041 AC.data.ContributionChildCounter = function (superiorId, populationRules, callbackobject, callbackmethod) { 4042 4043 /** The population rule utility: i.e. an instance of AC.data.PopulationRulesParser. */ 4044 this._populationRulesUtil = populationRules; 4045 4046 this._callbackobject = callbackobject; 4047 4048 /** The callback method. */ 4049 this._callbackmethod = callbackmethod; 4050 4051 /** The count of all (both new and old) contributions. */ 4052 this.count = 0; 4053 4054 /** The count of new contributions. */ 4055 this.newCount = 0; 4056 4057 /** 4058 * Increments the count of all contributions. 4059 * 4060 * @return void 4061 */ 4062 this.incrementCount = function () { 4063 this.count++; 4064 this.doCallback(); 4065 }; 4066 4067 /** 4068 * Decrements the count of all contributions. 4069 * 4070 * @return void 4071 */ 4072 this.decrementCount = function () { 4073 this.count--; 4074 this.doCallback(); 4075 }; 4076 4077 /** 4078 * Increments the count of new contributions. 4079 * 4080 * @return void 4081 */ 4082 this.incrementNewCount = function () { 4083 this.newCount++; 4084 this.doCallback(); 4085 }; 4086 4087 /** 4088 * Decrements the count of new contributions. 4089 * 4090 * @return void 4091 */ 4092 this.decrementNewCount = function () { 4093 this.newCount--; 4094 this.doCallback(); 4095 }; 4096 4097 /** 4098 * Invokes the callback method on the callback object. 4099 * 4100 * @return void 4101 */ 4102 this.doCallback = function () { 4103 this._callbackmethod.call(this._callbackobject, this); 4104 }; 4105 4106 /** Contribution counter node. */ 4107 this._superiorContribution = new AC.data.ContributionChildCounterNode(this, superiorId); 4108 4109 /** 4110 * Destroys the contribution counter node. 4111 * 4112 * @return void 4113 */ 4114 this.destroy = function () { 4115 this._superiorContribution.destroy(); 4116 }; 4117 } 4118 4119 // TODO: move the listener into AC namespace 4120 /** 4121 * Default constructor. 4122 * 4123 * @class ActionCenters listener. 4124 */ 4125 function ActionCenterListener() { 4126 4127 /** 4128 * An array of channels on which this listener is registered. 4129 * 4130 * @private 4131 * @field 4132 * @type Array 4133 */ 4134 this.subscribedChannels = []; 4135 4136 /** 4137 * The subscription to listen for a thumbprint. 4138 * 4139 * @private 4140 * @field 4141 * @type Subscription 4142 */ 4143 this.thumbprintSubscription = null; 4144 4145 /** 4146 * Registers a callback function which will be invoked once for each contribution which matches the type and relationship to the superior contribution. The 4147 * callback function will also be called for each contribution which is added that matches the type and relationship to the superior contribution. If a remove 4148 * object and method is provided, a callback to that function will be invoked whenever a contribution matching the type and relationship to the superior contribution 4149 * is deleted. 4150 * 4151 * @param {String} contributionId 4152 * The id of the superior contribution. 4153 * @param {String} relationshipType 4154 * The type of the relationship. 4155 * @param {String} subordinateType 4156 * The type of the subordinate contribution. 4157 * @param {Object} addObjectToCall 4158 * Callback object to invoke after addition of the relationship. 4159 * @param {String} addMethodToCall 4160 * Callback method to invoke after addition of the relationship. 4161 * @param {Boolean} [createOneIfNoneExists] 4162 * Boolean flag to indicate whether to create a subordinate contribution if none has been found. 4163 * @param {Object} [removeObjectToCall] 4164 * Callback object to invoke after removal of the relationship. 4165 * @param {String} [removeMethodToCall] 4166 * Callback method to invoke after removal of the relationship. 4167 * @param {AC.data.LoadMonitor} [loadMonitor] 4168 * Load monitor to monitor the initial loading of a tree. 4169 * @param {Boolean} [miniMessage] 4170 * Exclude properties, dates, and locked by information from the callback message. This is useful for contribution counters. Default value is false. 4171 * @param {String} [createOneMode] 4172 * If this is 'project', then setting createOneIfNoneExists to true will create a subordinate project. 4173 * @return void 4174 */ 4175 this.getSubordinates = function (contributionId, relationshipType, subordinateType, 4176 addObjectToCall, addMethodToCall, 4177 createOneIfNoneExists, removeObjectToCall, removeMethodToCall, loadMonitor, miniMessage, createOneMode) { 4178 actionCenterAPI.startBatch(); 4179 var addChannel = 4180 "/contributions/relationship/" + contributionId + "/" + relationshipType + "/" + subordinateType + "/add"; 4181 this.subscribedChannels.push(dojox.cometd.subscribe(addChannel, addObjectToCall, addMethodToCall)); 4182 if (loadMonitor) { 4183 loadMonitor.increment(); 4184 } 4185 actionCenterAPI.publishRelatedContributions(addChannel, createOneIfNoneExists, createOneMode, miniMessage, addObjectToCall, 4186 function (msg) { 4187 var subordinates = msg.data.relatedContributions; 4188 this.childNodesLength = subordinates.length; 4189 for (var i = 0; i < subordinates.length; i++) { 4190 var subMsg = {data: {contribution: subordinates[i]}, channel: msg.data.AC_requestedchannel}; 4191 if (this.type && this.type === "AC_ComponentSuperior" && !this.childNodes) { 4192 // in this case processCreateChild throws exception 4193 } else { 4194 eval("this." + addMethodToCall + "(subMsg)"); // invoke the add method 4195 } 4196 } 4197 if (loadMonitor) { 4198 loadMonitor.decrement(); 4199 } 4200 } 4201 ); 4202 if (removeObjectToCall && removeMethodToCall) { 4203 var deleteChannel = "/contributions/relationship/" + contributionId + "/" + relationshipType + "/" + 4204 subordinateType + "/delete"; 4205 this.subscribedChannels.push(dojox.cometd.subscribe(deleteChannel, removeObjectToCall, removeMethodToCall)); 4206 } 4207 actionCenterAPI.endBatch(); 4208 }; 4209 4210 /** 4211 * Gets contributions of all types, which are subordinate to the specified contribution with the 4212 * specified relationship type. Registers a callback function which will be invoked once for each contribution of any type and the provided relationship 4213 * to the superior contribution. The callback function will also be called for each contribution which is added that matches the type and relationship 4214 * to the superior contribution. 4215 * 4216 * @param {String} contributionId 4217 * The id of the superior contribution. 4218 * @param {String} relationshipType 4219 * The type of the relationship. 4220 * @param {Object} objectToCall 4221 * Callback object to invoke after addition of the relationship. 4222 * @param {String} methodToCall 4223 * Callback method to invoke after addition of the relationship. 4224 * @param {AC.data.LoadMonitor} [loadMonitor] 4225 * Load monitor to monitor the initial loading of a tree. 4226 * @param {Boolean} [miniMessage] 4227 * Exclude properties, dates, and locked by information from the callback message. This is useful for contribution counters. Default value is false. 4228 * @return void 4229 */ 4230 this.getAllSubordinates = function (contributionId, relationshipType, objectToCall, methodToCall, loadMonitor, miniMessage) { 4231 actionCenterAPI.startBatch(); 4232 var actionChannel = "/contributions/relationship/" + contributionId + "/" + relationshipType + "/**"; 4233 this.subscribedChannels.push(dojox.cometd.subscribe(actionChannel, objectToCall, methodToCall)); 4234 if (loadMonitor) { 4235 loadMonitor.increment(); 4236 } 4237 actionCenterAPI.publishRelatedContributions(actionChannel, false, null, miniMessage, objectToCall, 4238 function (msg) { 4239 var subordinates = msg.data.relatedContributions; 4240 this.childNodesLength = subordinates.length; 4241 for (var i = 0; i < subordinates.length; i++) { 4242 var subMsg = {data: {contribution: subordinates[i]}, channel: msg.data.AC_requestedchannel}; 4243 if (this.type && this.type === "AC_ComponentSuperior" && !this.childNodes) { 4244 // in this case processCreateChild throws exception 4245 } else { 4246 eval("this." + methodToCall + "(subMsg)"); // invoke the add method 4247 } 4248 } 4249 if (loadMonitor) { 4250 loadMonitor.decrement(); 4251 } 4252 } 4253 ); 4254 actionCenterAPI.endBatch(); 4255 }; 4256 4257 /** 4258 * Monitors a relationship with the specified criteria. 4259 * 4260 * @param {String} superiorId 4261 * The id of the superior contribution. 4262 * @param {String} relationshipType 4263 * The type of the relationship. 4264 * @param {String} subordinateId 4265 * The subordinate id. 4266 * @param {Object} addObjectToCall 4267 * Callback object to invoke after addition of the relationship. 4268 * @param {String} addMethodToCall 4269 * Callback method to invoke after addition of the relationship. 4270 * @param {Object} [removeObjectToCall] 4271 * Callback object to invoke after removal of the relationship. 4272 * @param {String} [removeMethodToCall] 4273 * Callback method to invoke after removal of the relationship. 4274 * @return void 4275 */ 4276 this.monitorRelationship = function (superiorId, relationshipType, subordinateId, addObjectToCall, addMethodToCall, 4277 removeObjectToCall, removeMethodToCall) { 4278 actionCenterAPI.startBatch(); 4279 if (addObjectToCall && addMethodToCall) { 4280 var addChannel = 4281 "/contributions/relationship/" + superiorId + "/" + relationshipType + "/" + subordinateId + "/add"; 4282 this.subscribedChannels.push(dojox.cometd.subscribe(addChannel, addObjectToCall, addMethodToCall)); 4283 } 4284 if (removeObjectToCall && removeMethodToCall) { 4285 var deleteChannel = 4286 "/contributions/relationship/" + superiorId + "/" + relationshipType + "/" + subordinateId + "/delete"; 4287 this.subscribedChannels.push(dojox.cometd.subscribe(deleteChannel, removeObjectToCall, removeMethodToCall)); 4288 } 4289 if (addChannel) { 4290 actionCenterAPI.publishRelationship(addChannel); 4291 } 4292 actionCenterAPI.endBatch(); 4293 }; 4294 4295 /** 4296 * Subscribes to the channel of contribution updates for the specified contribution. 4297 * 4298 * @param {String} contributionId 4299 * The id of the contribution. 4300 * @param {Object} objectToCall 4301 * Callback object to invoke for each update to the contribution. 4302 * @param {String} methodToCall 4303 * Callback method to invoke for each update to the contribution. 4304 * @return void 4305 */ 4306 this.getContributionUpdates = function (contributionId, objectToCall, methodToCall) { 4307 var updateChannel = "/contributions/contribution/" + contributionId + "/update"; 4308 this.subscribedChannels.push(dojox.cometd.subscribe(updateChannel, objectToCall, methodToCall)); 4309 }; 4310 4311 /** 4312 * Subscribes to the channel of contribution property updates for the specified contribution and the specified 4313 * property. 4314 * 4315 * @param {String} contributionId 4316 * The id of the contribution. 4317 * @param {String} propertyName 4318 * the name of the property 4319 * @param {Object} objectToCall 4320 * Callback object to invoke for each update to the contribution. 4321 * @param {String} methodToCall 4322 * Callback method to invoke for each update to the contribution. 4323 * @return void 4324 */ 4325 this.getContributionPropertyUpdates = function (contributionId, propertyName, objectToCall, methodToCall) { 4326 var updateChannel = "/contributions/contribution/" + contributionId + "/property/" + propertyName + "/update"; 4327 this.subscribedChannels.push(dojox.cometd.subscribe(updateChannel, objectToCall, methodToCall)); 4328 }; 4329 4330 /** 4331 * Subscribes to the channel of contribution property deletion for the specified contribution and the specified 4332 * property. 4333 * 4334 * @param {String} contributionId 4335 * The id of the contribution. 4336 * @param {String} propertyName 4337 * the name of the property 4338 * @param {Object} objectToCall 4339 * Callback object to invoke for each update to the contribution. 4340 * @param {String} methodToCall 4341 * Callback method to invoke for each update to the contribution. 4342 * @return void 4343 */ 4344 this.getContributionPropertyDelete = function (contributionId, propertyName, objectToCall, methodToCall) { 4345 var deleteChannel = "/contributions/contribution/" + contributionId + "/property/" + propertyName + "/delete"; 4346 this.subscribedChannels.push(dojox.cometd.subscribe(deleteChannel, objectToCall, methodToCall)); 4347 }; 4348 4349 /** 4350 * Subscribes to the channel to listen for the delete of the specified contribution. 4351 * 4352 * @param {String} contributionId 4353 * The id of the contribution. 4354 * @param {Object} objectToCall 4355 * Callback object to invoke for each update to the contribution. 4356 * @param {String} methodToCall 4357 * Callback method to invoke for each update to the contribution. 4358 * @return void 4359 */ 4360 this.getContributionDelete = function (contributionId, objectToCall, methodToCall) { 4361 var deleteChannel = "/contributions/contribution/" + contributionId + "/delete"; 4362 this.subscribedChannels.push(dojox.cometd.subscribe(deleteChannel, objectToCall, methodToCall)); 4363 }; 4364 4365 /** 4366 * Subscribes to listen for users in a given system role. 4367 * 4368 * @param {String[]} systemRoles 4369 * The array of system roles. 4370 * @param {Object} objectToCall 4371 * Callback object to invoke for each update to the contribution. 4372 * @param {String} methodToCall 4373 * Callback method to invoke for each update to the contribution. 4374 * @return void 4375 */ 4376 this.getUserUpdates = function (systemRoles, 4377 addObjectToCall, addMethodToCall, removeObjectToCall, removeMethodToCall) { 4378 actionCenterAPI.startBatch(); 4379 for (var index = 0; index < systemRoles.length; index++) { 4380 if (addObjectToCall && addMethodToCall) { 4381 this.subscribedChannels.push(dojox.cometd.subscribe( 4382 "/contributions/relationship/systemuser/childof/" + systemRoles[index] + "/add", 4383 addObjectToCall, addMethodToCall 4384 )); 4385 } 4386 if (removeObjectToCall && removeMethodToCall) { 4387 this.subscribedChannels.push(dojox.cometd.subscribe( 4388 "/contributions/relationship/systemuser/childof/" + systemRoles[index] + "/delete", 4389 removeObjectToCall, removeMethodToCall 4390 )); 4391 } 4392 } 4393 actionCenterAPI.endBatch(); 4394 }; 4395 4396 /** 4397 * Subscribes to the channel to listen for thumbprints on the specified contribution. 4398 * 4399 * @param {String} contributionId 4400 * The id of the contribution. 4401 * @param {Object} objectToCall 4402 * Callback object to invoke for each update to the contribution. 4403 * @param {String} methodToCall 4404 * Callback method to invoke for each update to the contribution. 4405 * @return void 4406 */ 4407 this.getThumbprints = function (contributionId, objectToCall, methodToCall) { 4408 var userId = actionCenterAPI.getUserId(); 4409 var channel = "/contributions/contribution/" + contributionId + "/" + userId + "/thumbprints"; 4410 this.thumbprintSubscription = dojox.cometd.subscribe(channel, objectToCall, methodToCall); 4411 }; 4412 4413 /** 4414 * Unsubscribes from the thumbprint channel. 4415 * 4416 * @return void 4417 */ 4418 this.unsubscribeThumbprints = function () { 4419 if (this.thumbprintSubscription) { 4420 dojox.cometd.unsubscribe(this.thumbprintSubscription); 4421 this.thumbprintSubscription = null; 4422 } 4423 }; 4424 4425 /** 4426 * Unsubscribes from all channels on which this listener has been registered. This function should be called by 4427 * this ActionCenterListener's owning object destroy function. 4428 * 4429 * @return void 4430 */ 4431 this.destroy = function () { 4432 dojox.cometd.startBatch(); 4433 while (this.subscribedChannels.length > 0) { 4434 dojox.cometd.unsubscribe(this.subscribedChannels.pop()); 4435 } 4436 this.unsubscribeThumbprints(); 4437 dojox.cometd.endBatch(); 4438 }; 4439 } 4440 4441 /** 4442 * Default constructor. 4443 * 4444 * @class AC load monitor. 4445 * @extends Ext.util.Observable 4446 * @param owner 4447 * the owner of this load monitor 4448 */ 4449 AC.data.LoadMonitor = function (owner) { 4450 this.owner = owner; 4451 this.counter = 0; 4452 this.isActive = true; 4453 }; 4454 4455 Ext.extend(AC.data.LoadMonitor, Ext.util.Observable, 4456 /** 4457 * @lends AC.data.LoadMonitor 4458 */ 4459 { 4460 /** 4461 * Counter indicating the status of data loading. Zero means loading is done. 4462 * 4463 * @default 0 4464 */ 4465 counter: 0, 4466 4467 /** 4468 * Indicates if this monitor is active. 4469 * 4470 * @default false 4471 */ 4472 isActive: false, 4473 4474 /** 4475 * Owner of this monitor. 4476 * 4477 * @default null 4478 */ 4479 owner: null, 4480 4481 /** 4482 * Increments the load counter. 4483 * 4484 * @return void 4485 */ 4486 increment: function () { 4487 this.counter++; 4488 }, 4489 4490 /** 4491 * Decrements the load counter. 4492 * 4493 * @return void 4494 */ 4495 decrement: function () { 4496 this.counter--; 4497 if (this.isActive && this.counter === 0) { 4498 this.afterLoad(); 4499 } 4500 }, 4501 4502 /** 4503 * Invoked after the load counter reaches zero. 4504 * 4505 * @return void 4506 */ 4507 afterLoad : function () { 4508 //this.owner.fireEvent('afterload'); 4509 } 4510 }); 4511 4512 /** 4513 * Default constructor. 4514 * 4515 * @class AC tree load monitor. 4516 * @extends AC.data.LoadMonitor 4517 * @param owner 4518 * the owner of this monitor 4519 */ 4520 AC.data.TreeLoadMonitor = function (owner) { 4521 AC.data.TreeLoadMonitor.superclass.constructor.apply(this, arguments); 4522 }; 4523 4524 Ext.extend(AC.data.TreeLoadMonitor, AC.data.LoadMonitor, 4525 /** @lends AC.data.TreeLoadMonitor */ 4526 { 4527 /** 4528 * Fires the 'aftertreeload' event and disables the load monitor. 4529 * 4530 * @return void 4531 */ 4532 afterLoad : function () { 4533 AC.data.TreeLoadMonitor.superclass.afterLoad.apply(this, arguments); 4534 this.isActive = false; 4535 this.owner.fireEvent('aftertreeload'); 4536 } 4537 }); 4538 4539 /** 4540 * Default contructor. 4541 * 4542 * @class Defines the superior of a tree-grid cell. 4543 * @param superiorContributionType the superior contribution type. 4544 * @param superiorContributionType the superior contribution id. 4545 */ 4546 AC.tree.grid.Superior = function (superiorContributionType, superiorContributionId) { 4547 4548 /** 4549 * Superior contribution type. 4550 * 4551 * @field 4552 * @type String 4553 */ 4554 this._superiorContributionType = superiorContributionType; 4555 4556 /** 4557 * Superior contribution id. 4558 * 4559 * @field 4560 * @type String 4561 */ 4562 this._superiorContributionId = superiorContributionId; 4563 4564 /** 4565 * Gets the superior contribution type. 4566 * 4567 * @return the superior contribution type 4568 */ 4569 this.getSuperiorContributionType = function () { 4570 return this._superiorContributionType; 4571 }; 4572 4573 /** 4574 * Gets the superior contribution id. 4575 * 4576 * @return the superior contribution id 4577 */ 4578 this.getSuperiorContributionId = function () { 4579 return this._superiorContributionId; 4580 }; 4581 } 4582 4583 /** 4584 * Default constructor. 4585 * 4586 * @class A hash table for persisting widgets which have been instantiated (aka treegrid.objectManager). 4587 * @param factory the factory that will be used to create the widget if one does not already exist. 4588 * The factory must have a method with the signature getWidget(AC.tree.grid.Superior[]). 4589 */ 4590 AC.tree.grid.WidgetManager = function (factory) { 4591 /** 4592 * A factory that will be used to create the widget if one does not already exist. 4593 * The factory must have a method that with the signature getWidget(AC.tree.grid.Superior[]). 4594 * 4595 * @field 4596 * @type Factory 4597 */ 4598 this._factory = factory; 4599 4600 /** 4601 * A hashmap that will be used to hold the widgets that have been created. 4602 * 4603 * @field 4604 * @type Ext.util.MixedCollection 4605 */ 4606 this.hashMap = new Ext.util.MixedCollection(false); 4607 4608 /** 4609 * Get a Widget for the given relationship/s. 4610 * 4611 * @param arrayOfSuperiors 4612 * an array of AC.tree.grid.Superior objects which are the superiors 4613 * for the contribution which is represented by the widget that we are looking for. 4614 * @return the widget for the given superior combination. 4615 */ 4616 this.getWidgetForRelationship = function (arrayOfSuperiors, treegrid, config) { 4617 var idKey = this.getIdKey(arrayOfSuperiors); 4618 if (this.hashMap.containsKey(idKey)) { 4619 return this.hashMap.get(idKey); 4620 } else { 4621 var widget = this._factory.getWidget(arrayOfSuperiors, treegrid, config); 4622 return this.hashMap.add(idKey, widget); 4623 } 4624 }; 4625 4626 /** 4627 * Get a unique id based on the given superiors for storing and retrieving the widget in a hashtable. 4628 * 4629 * @param arrayOfSuperiors 4630 * an array of AC.tree.grid.Superior objects which are the superiors 4631 * for the contribution which is represented by the widget that we are looking for. 4632 * @return a unique string id 4633 */ 4634 this.getIdKey = function (arrayOfSuperiors) { 4635 var returnValue = ''; 4636 if (arrayOfSuperiors.length > 0) { 4637 returnValue += arrayOfSuperiors[0].getSuperiorContributionId(); 4638 } 4639 for (var index = 1; index < arrayOfSuperiors.length; index++) { 4640 returnValue += acGlobalDelimiter + arrayOfSuperiors[index].getSuperiorContributionId(); 4641 } 4642 return returnValue; 4643 }; 4644 4645 /** 4646 * Destroys the widget. This method is called for every widget in the hashtable upon destroy of this 4647 * hash table. 4648 * 4649 * @param widget 4650 * the widget to be destroyed 4651 * @return void 4652 */ 4653 this.destroyEach = function (widget) { 4654 widget.destroy(); 4655 }; 4656 4657 /** 4658 * Destroys this class and destroys every widget contained by this class. 4659 * 4660 * @return void 4661 */ 4662 this.destroy = function () { 4663 var hashdestroy; 4664 var items = [].concat(this.hashMap.items); // each safe for removal 4665 for(var i = 0, len = items.length; i < len; i++){ 4666 var widget = items[i]; 4667 if(widget != null){ 4668 this.destroyEach(widget); 4669 } 4670 } 4671 //this.hashMap.each(this.destroyEach); 4672 this.hashMap.clear(); 4673 }; 4674 } 4675 4676 /** 4677 * Default constructor. 4678 * 4679 * @class Factory of widgets corresponding to a given column and row. 4680 */ 4681 AC.tree.grid.CellObjectFactory = function () { 4682 4683 /** The hash map of widgets. */ 4684 this.hashMap = new Ext.util.MixedCollection(false); 4685 4686 /** 4687 * Gets a widget corresponding to the specified array of superiors. 4688 * 4689 * @param arrayOfSuperiors 4690 * the array of superiors 4691 * @param treegrid 4692 * the treegrid 4693 * @param config 4694 * the configuration of the widget 4695 * @return the corresponding widget 4696 */ 4697 this.getWidget = function (arrayOfSuperiors, treegrid, config) { 4698 var keyForObject = ''; 4699 var colid = null; 4700 var rowid = null; 4701 if (!config) { 4702 config = {}; 4703 } 4704 for (var i = 0; i < arrayOfSuperiors.length; i++) { 4705 var thisobj = arrayOfSuperiors[i]; 4706 if (i === 0) { 4707 colid = thisobj.getSuperiorContributionId(); 4708 } 4709 if (i === 1) { 4710 rowid = thisobj.getSuperiorContributionId(); 4711 } 4712 keyForObject += thisobj.getSuperiorContributionType(); 4713 } 4714 var objtype = null; 4715 if (this.hashMap.containsKey(keyForObject)) { 4716 objtype = this.hashMap.get(keyForObject); 4717 if (!objtype) { 4718 return null; 4719 } 4720 var cell = actioncenter.tgrCellCreate(objtype, rowid, colid, treegrid, config); 4721 return cell; 4722 } 4723 }; 4724 4725 /** 4726 * Adds the specified widget into the factory's hash map. 4727 * 4728 * @param arrayOfTypes 4729 * the array of types corresponding to the widget 4730 * @param objtype 4731 * the type of the widget 4732 * @param config 4733 * the configuration of the widget 4734 * @return void 4735 */ 4736 this.addWidget = function (arrayOfTypes, objtype, config) { 4737 var keyForObject = ''; 4738 for (var i = 0; i < arrayOfTypes.length; i++) { 4739 keyForObject += arrayOfTypes[i]; 4740 } 4741 this.hashMap.add(keyForObject, objtype); 4742 }; 4743 4744 this.destroy = function() { 4745 this.hashMap.clear(); 4746 this.hashMap = null; 4747 }; 4748 }