/******************************************************************************************************************************** * Licensed Materials - Property of IBM * * * * IBM Cognos Products: AGS * * * * (C) Copyright IBM Corp. 2005, 2021 * * * * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * *********************************************************************************************************************************/ /* **************************************** TO DO - TO DO - TO DO - TO DO - TO DO - TO DO - TO DO - getFolderChild() instead of _.ref+"_Child" **************************************** */ var agentItemsTree = null; var agentParameterTree = null; function initDataItems() { if (agentItemsTree == null) { if (browserCheck.isNav6Up()) { document.getElementById("agentItemsTreeContainer").addEventListener("mouseup", function(e) {if(e.target.toString().indexOf("XULElement") > -1){e.cancelBubble = true;return false;}}, true); document.getElementById("agentItemsTreeContainer").addEventListener("dragover", function(e) {cancelBub(e);}, true); document.getElementById("agentItemsTreeContainer").addEventListener("dragdrop", function(e) {cancelBub(e);}, true); } var agentItemsTreeNode = document.getElementById("agentItemsTreeContainer"); // at this point - this is the only node with this id agentItemsTreeNode.setAttribute("container", "true"); agentItemsTreeNode.setAttribute("tabindex", "-1"); // now create and render the tree agentItemsTree = new CTree (agentItemsTreeNode, "", false, true, "agentItemsTree"); agentItemsTree.setSelectionMode(CONTIGUOUS_TREE_SELECTION); agentItemsTree.setSelectTreeUI(NORMAL_TREE); agentItemsTree.setAllowDragDrop(true); agentItemsTree.setOnDragStart(onDragStartF); agentItemsTree.setOnDrag(onDragF); agentItemsTree.setOnDragEnd(onDragEndF); agentItemsTree.setContextMenu(showContextMenu); agentItemsTree.setTrackSelectionOrder(true); agentItemsTree.setDoubleClickFunc(processDoubleClick); agentItemsTree.setSingleClickFunc(singleClickedDataItemsTree); agentItemsTree.setHideOuterTable(true); agentItemsTree.setAllowSelectionToggle(true); // define the root of the tree agentItemsTree.getRootNode().setName(agentItemsRoot_string); agentItemsTree.getRootNode().setCanHaveChildren(true); agentItemsTree.setRootNodeType(tntAgentRoot); agentItemsTree.drawAll(); agentItemsTree.checkData(); } } function initParameterItems() { if (agentParameterTree == null) { if (browserCheck.isNav6Up()) { document.getElementById("agentParameterTreeContainer").addEventListener("mouseup", function(e) {if(e.target.toString().indexOf("XULElement") > -1){e.cancelBubble = true;return false;}}, true); document.getElementById("agentParameterTreeContainer").addEventListener("dragover", function(e) {e.preventBubble();}, true); document.getElementById("agentParameterTreeContainer").addEventListener("dragdrop", function(e) {e.preventBubble();}, true); } var agentParameterTreeNode = document.getElementById("agentParameterTreeContainer"); // at this point - this is the only node with this id agentParameterTreeNode.setAttribute("container", "true"); agentParameterTreeNode.setAttribute("tabindex", "-1"); // now create and render the tree agentParameterTree = new CTree (agentParameterTreeNode, "", false, true, "agentParameterTree"); agentParameterTree.setSelectionMode(CONTIGUOUS_TREE_SELECTION); agentParameterTree.setSelectTreeUI(NORMAL_TREE); agentParameterTree.setAllowDragDrop(true); agentParameterTree.setOnDragStart(onDragStartF); agentParameterTree.setOnDrag(onDragF); agentParameterTree.setOnDragEnd(onDragEndF); agentParameterTree.setContextMenu(showContextMenu); agentParameterTree.setTrackSelectionOrder(true); agentParameterTree.setDoubleClickFunc(processDoubleClick); agentParameterTree.setSingleClickFunc(singleClickedParametersTree); agentParameterTree.setHideOuterTable(true); agentParameterTree.setAllowSelectionToggle(true); // define the root of the tree agentParameterTree.getRootNode().setName(agentItemsParameters_string); agentParameterTree.getRootNode().setCanHaveChildren(true); agentParameterTree.setRootNodeType(tntAgentRoot); agentParameterTree.drawAll(); agentParameterTree.checkData(); } } function processDoubleClick(){ addSelectedDblClick(); } function singleClickedDataItemsTree() { parent.deletionCandidateManager.setCandidate("deleteAgentItems()",K_sFunctionCandidate); } function singleClickedParametersTree(){ parent.deletionCandidateManager.setCandidate("deleteParameters()",K_sFunctionCandidate); } function resetAgentItems() { resetDataItems(); resetParameterItems(); } function resetDataItems() { if (agentItemsTree != null) { // we have to remove the tree agentItemsTree = null; // remove the rendering of the tree removeTreeRendering("agentItemsTreeContainer"); } // re-init the agent Items tree initDataItems(); } function resetParameterItems() { if (agentParameterTree != null) { // we have to remove the tree agentParameterTree = null; // remove the rendering of the tree removeTreeRendering("agentParameterTreeContainer"); } // re-init the agent Items tree initParameterItems(); } /* * Delete selected agent parameters from the tree */ function deleteParameters() { if(confirm(parameterDeleteWarning)) { deleteFromTree(getParametersTree()); } } /* * Delete selected agent items from the tree */ function deleteAgentItems() { if(confirm(agentItemsDeleteWarning)) { deleteFromTree(getDataItemsTree()); } } function deleteDataItem(dataItemDropValue,undo) { var tree = getDataItemsTree(); var deleteNode = getNodeFromTreeWithValue(dataItemDropValue,'getDropValue()',getTreeChildNodes(tree)); return deleteDataItemNode(deleteNode,undo); } function deleteDataItemNode(deleteNode,undo) { var tree = getDataItemsTree(); if (deleteNode) { deleteNode.detach(); //redraw the parent redrawTreeNode(tree.getRootNode(),false); if(!undo){ //store the ref obj in case we need to undo the delete getRedoUndoManager().getActionHistory().push(new DeleteItemEditAction(deleteNode)); } parent.deletionCandidateManager.clearCandidate(); } return deleteNode; } function redrawTreeNode(node,isSelected){ //UnSelect all. node.getTree().deSelectAll(); //This doing it the ahrd way to update the name. //redraw the whole caboudle node.getTree().drawAll(); if (isSelected) { //Now we set it to selected node.setSelected(true); node.updateParent(); //And need to redraw again node.getTree().redraw(); } //validate the result node.getTree().checkData(); } /* takes a string and searches it for agent items and returns the agent items that it found */ function findTopicsInContent(content, excludeCalculations){ var topic_map = new Object(); var topics = new Array(); var items = getTreeValues(getDataItemsTree()); for(var i = 0; i < items.length; i++){ if(!topic_map[items[i].getDropValue()] && content.indexOf(items[i].getDropValue()) != -1){ if(!excludeCalculations){ topic_map[items[i].getDropValue()]; topics.push(items[i].getDropValue()); } } } return topics; } /* * Create a ref obj agent item. Called when loading an agent from load_agent.xts */ function generateAgentItem(name, ref, aggregate, displayType) { var obj = null; var newTreeNode = null; var displayTypeCode = null; if (displayType.match(/textItem/)) { displayTypeCode = "0"; } else if (displayType.match(/image/)) { displayTypeCode = "1"; } else if (displayType.match(/hyperlink/)) { displayTypeCode = "2"; } else { displayTypeCode = "0"; } // we have an agent item obj = new aiDataItem(name, ref, aggregate, displayType); // add this to the tree - we can call addAgentItem - which will actually make a copy // but the addAgentItem call will make sure that names are unique. addAgentItem(obj); return obj; } function updateParameter(obj, node) { var itemNode = node; if (!node || node == 'undefined') { itemNode = getNodeFromTree(obj,"name",getParametersTree()); } if (itemNode) { var item = itemNode.getValue(); item.name = obj.name; item.acceptRange = obj.acceptRange; itemNode.setName(obj.name); itemNode.setValue(item); } else { //Ok smarty. Item is not in the tree add it. itemNode = addParameter(obj); } //UnSelect all. //itemNode.getTree().deSelectAll(); //itemNode.setSelected(true); redrawTreeNode(itemNode,true); //update the agent changed state, we have added/updated a data item cf.agentHasChanged(true); return itemNode; } function updateDataItem(obj, node) { var dataItemNode = node; if (!node || node == 'undefined') { dataItemNode = getNodeFromTree(obj,"name",getDataItemsTree()); } if (dataItemNode) { var dataItem = dataItemNode.getValue(); dataItem.name = obj.name; dataItem.ref = obj.ref; dataItemNode.setName(obj.name); dataItemNode.setValue(dataItem); if (obj.isIndicator()) { dataItemNode.setIndicator(obj.getIndicator()); } } else { //Ok smarty. Item is not in the tree add it. dataItemNode = addAgentItem(obj); } redrawTreeNode(dataItemNode,true); //update the agent changed state, we have added/updated a data item cf.agentHasChanged(true); return dataItemNode; } /* * Generate the name for the agentItem. Algorith is to see if the name is used - * if it is - add a numeric onto the end - continue doing so until you get to a name which isn't used */ function generateName(obj) { var i = 1; var currentName = obj.name; //Check if Item is there with this name. while (getNodeFromTreeWithValue(currentName,"name",getTreeChildNodes(getDataItemsTree()))) { // generate a new name currentName = obj.name + i; // up the index i++; } // return the generated name return currentName; } function createDataItemObj(name,value,aggregate) { if (!aggregate || aggregate == 'undefined') { aggregate = 'automatic'; } var obj = new aiDataItem(name, value, aggregate, '0'); return obj; } function createParameterObj(name,acceptRange) { // create the new object var obj = new aiParameter(name, acceptRange); return obj; } /* * Add an agent item * obj - the object that we want to add */ function addAgentItem(obj, undo) { //check if item already there, and get the Node. var ret_value = getNodeFromTree(obj,"name",getDataItemsTree()); //We found it. Now check if the ref is the same if (ret_value) { //We have the node so use it. This is a bit faster and straight. ret_value = getNodeFromTreeWithValue(obj.ref,"ref",new Array(ret_value)); } // create the agentItem if the ref is not there if (!ret_value || ret_value == "undefined") { if (obj.usage && !obj.usage.match(/fact/i)) { //This is to work around the problem where //the usage is an 'attribute' and not a 'fact', //hence you want to set aggregate as 'none' //Because this is what ReportServer would //expect it to be for an 'attribute' type usage. //Bug obj.regularAggregate = 'none'; } // may have to rename them though var itemName = generateName(obj); // get the agentItemObject var agentItemObj = new aiDataItem(itemName, obj.ref, obj.regularAggregate, obj.displayType); // get the type for the tree var agentItemTreeType = generateAgentItemTreeType(obj.regularAggregate); // build a new tree node var newTreeNode = new cf.CTreeNode(getDataItemsTree().getRootNode(), agentItemTreeType, false, itemName, agentItemObj, false); //Set the tree location of this item. A bit nasty that we have to toString the integer value. //CTree should deal with this and set the treeref to a string value always and not int in one case //and strign in another especially if it is the top level of the tree. agentItemObj.treeRef = newTreeNode.getTreeRef().toString(); // check to see what sort of node we're adding - folder nodes don't want toggles. newTreeNode.setCanHaveChildren(false); // update the tree if(newTreeNode.getTree() != null) newTreeNode.getTree().redraw(); // return the aiDataItem created ret_value = newTreeNode; if(!undo){ if(getRedoUndoManager().isEditActionBatching()){ getRedoUndoManager().getEditActionBatch().push(new AddItemEditAction(newTreeNode)); }else{ getRedoUndoManager().getActionHistory().push(new AddItemEditAction(newTreeNode)); } //adding a new item, clears the redo cache getRedoUndoManager().getUndoneHistory().clear(); } } return ret_value; } function addParameter(obj, undo) { var newTreeNode = getNodeFromTree(obj,"name",getParametersTree()); //guard clause to check if we can add this item if (!newTreeNode) { // build a new tree node newTreeNode = new CTreeNode(getParametersTree().getRootNode(), tntParameter, false, obj.name, obj, false); // update the tree newTreeNode.getTree().redraw(); if(!undo){ getRedoUndoManager().getActionHistory().push(new AddItemEditAction(newTreeNode)); //adding a new item, clears the redo cache getRedoUndoManager().getUndoneHistory().clear(); } } return newTreeNode; } /** * This is used by agentItemListener.js to add items back to the tree * during undo/redo. */ function addUnknownItem(obj, undo){ var added; if (obj instanceof aiParameter){ added = addParameter(obj, undo); }else if (obj instanceof aiDataItem){ added = addAgentItem(obj, undo); } return added; } function setIndicator(name) { var node = getNodeFromTreeWithValue(name,"getDropValue()", getTreeChildNodes(getDataItemsTree())); if (node && node != 'undefined') { var obj = node.getValue(); node.setIndicator(obj.getIndicator()); redrawTreeNode(getDataItemsTree().getRootNode()); } } function removeIndicator(name) { var node = getNodeFromTreeWithValue(name,"getDropValue()", getTreeChildNodes(getDataItemsTree())); if (node && node != 'undefined') { node.setIndicator(null); redrawTreeNode(getDataItemsTree().getRootNode()); } } /** * Get the values for a particular tree. * optionally you can pass an object with a "match" function that * takes a tree node as an argument */ function getTreeValues(tree, searcher) { var items = new Array(); //Default to agentItems var children = getTreeChildNodes(tree); for(var i=0; i < children.length;i++) { if((searcher && searcher.match(children[i].getValue())) || !searcher){ //only add the item if you dont have a searcher, or the searcher matches the item items.push(children[i].getValue()); } } return items; } /** * Get the values for a particular tree. */ function getTreeChildNodes(tree) { return tree.getRootNode().getChildren(); } /** * For a given aiDataITem or aiPArameter get the correpsonding * Node from the tree. */ function getNodeFromTree(obj,property, tree) { return getItemFromTreeWithObject(obj,property,getTreeChildNodes(tree)); } /** * Get item from tree when you have an object such as aiDataItem or aiParameter. */ function getItemFromTreeWithObject(obj,property, children) { return getNodeFromTreeWithValue(obj[property],property,children); } /** * Get a Node from tree with a given value like name, ref etc... */ function getNodeFromTreeWithValue(value,property, children) { for(var i=0; i < children.length;i++) { var treeObj = children[i].getValue(); if (treeObj && eval("treeObj" + "." + property) == value) { //We found the object in the tree so we //return it. return children[i]; } } return null; } function getDataItemsTree() { return agentItemsTree; } function getParametersTree() { return agentParameterTree; } function deleteFromTree(tree) { var rootNode = tree.getRootNode(); var selectedNodes = tree.getSelectedLeafNodes(rootNode); //remove the ui nodes if(selectedNodes.length > 0) { rootNode.removeChildren(selectedNodes); var delete_stack = new Array(); var agentDef = parent.getAgentDefinition(); for(var i = 0; i < selectedNodes.length; i++){ delete_stack.push(new DeleteItemEditAction(selectedNodes[i])); // delete any extra topic from summry event keys if(agentDef!=null && agentDef.summaryEventKey!=null && agentDef.summaryEventKey.containsItem('['+selectedNodes[i].getName()+'];')) { agentDef.summaryEventKey.removeItem('['+selectedNodes[i].getName()+'];'); } } getRedoUndoManager().getActionHistory().push(new EditActionBundle(delete_stack)); //re write the tree... I dont know, I have to do everything round here redrawTreeNode(rootNode,false); // delete any extra topic from summry event keys if(agentDef!=null){ agentDef.removeInvalidFilterTopics(); } //getActionTopicFilterElementProcessor().updateList(); //update the agent changed state, we have added/updated a data item cf.agentHasChanged(true); } } // get the property from the given object function getObjProp(obj, prop) { return obj[prop]; } // get the name for the object - this is mutated to give a unique name function getObjPropName(obj) { return getObjProp(obj, "name"); } function generateAgentItemTreeType(aggregate) { // this is an integer value - have found the following values defined in FM - // where all the other values are defined I don't know // any = 10 --> "none" // average = 5 --> "average" // averageNonZero = 11 --> "none" // automatic = 18 --> "none" // calculated = 12 --> "none" // count = 6 --> "count" // countDistinct = 13 --> "none" // countNonZero = 14 --> "none" // external = 0 --> "none" // maximum = 4 --> "maximum" // median = 17 --> "none" // minimum = 3 --> "minimum" // standardDeviation= 15 --> "none" // sum = 2 --> "total" // variance = 16 --> "none" var type = tntDataItem; switch ( aggregate ) { case "total": type = tntDataItemTotal; break; case "count": type = tntDataItemCount; break; case "average": type = tntDataItemAverage; break; case "minimum": type = tntDataItemMinimum; break; case "maximum": type = tntDataItemMaximum; break; case "countDistinct": type = tntDataItemCntDistinct; break; case "median": type = tntDataItemMedian; break; case "standardDeviation": type = tntDataItemStdDeviation; break; case "variance": type = tntDataItemVariance; break; case "calculated": type = tntDataItemCalc; break; case "automatic": type = tntDataItemAutomatic; break; case "aggregate": type = tntDataItemAggregate; break; case "none": type = tntDataItemNone; break; case "notApplicable": type = tntDataItemNotApplicable; break; default: type = tntDataItem; break; } // default case return type; } function encode(text) { // seeing as this is destined for XML - and it could hold anything - escape // any dodgy characters var amp_re = /&/g; var lt_re = //g; var ap_re = /\'/g; var qu_re = /\"/g; text = text.replace(amp_re, "&"); text = text.replace(lt_re, "<"); text = text.replace(gt_re, ">"); text = text.replace(ap_re, "'"); text = text.replace(qu_re, """); return text; } function stripSpaces(text) { return text.replace(/^\s+/,'').replace(/\s+$/,''); } function buildFilterExpressions(detailFilterValue,summaryFilterValue) { var detailFilter = generateFilter(new Array(detailFilterValue), "detail"); var summaryFilter = generateFilter(new Array(summaryFilterValue), "summary"); return detailFilter + summaryFilter; } function generateFilter(filters,filterType) { var builtFilter = ""; var builtFilterFlag = false; // add the filter condition if we have one if (filters!= null && filters.length > 0) { builtFilter += "<" + filterType + "Filters>"; // loop over the filters for (var i = 0; i < filters.length; ++i) { // get the filter var filter = filters[i]; // add if we have a filter if (filter != null && stripSpaces(filter).length > 0) { if (filterType=="detail") { builtFilter += "<" + filterType + "Filter use=\"required\" postAutoAggregation=\"false\">"; } else { builtFilter += "<" + filterType + "Filter use=\"required\">"; } builtFilter += "" + encode(filter) + ""; builtFilter += ""; builtFilterFlag = true; } } builtFilter += ""; //If we have built at least one filter then we keep filter as is //otherwise if flag is false then we should remove the wrapping tags // or if (!builtFilterFlag) { builtFilter = ""; } } return builtFilter; } function buildFilterCondition() { //The AgentTask-condition holds an XML encoded blob of the summary and details //filter. We have a hidden input in the defineCondtion.xts that is always updated //when the summary and detail filter changes. var filters = ""; var msgFrame = getMessageIFrame(); var msgDoc = getFrameDocument(msgFrame); // get the task condition element var conditionElement = msgDoc.pform.elements['AgentTask-condition']; // if we have an element - get it's value if (conditionElement != null && conditionElement.value != "") { //ensure single quotes are encoded, these are generate when a value is inserted into the condition using the selectValues dialog var filterValue = ""; var aposRegEx = /\'/g; filterValue = conditionElement.value.replace(aposRegEx, "'"); // condition element MIGHT be 2 elements if we have both summary and detail filters, so create a dummy root node. var filters_xml = new XMLParser(""+filterValue+""); if (filters_xml != null && filters_xml.childNodes != null && filters_xml.childNodes.length > 0) { //shouldnt have any attributes.. they are probably xts ones which cause report server validation death filters_xml.attributes = new Array(); // handle the filters and combine as one string for (var i = 0; i < filters_xml.childNodes.length; i++) { filters_xml.childNodes[i].attributes = new Array(); filters = filters + filters_xml.childNodes[i].toString(); } } } // return the filters return filters; } function noDataItems() { var dataItemsTree = getTreeValues(getDataItemsTree()); if (dataItemsTree.length < 1) { return true; } else return false; }