Name

global.ScrumAjaxTaskBoardDetailsProvider

Description

ScrumAjaxTaskBoardDetailsProvider

Script

var ScrumAjaxTaskBoardDetailsProvider = Class.create();
  ScrumAjaxTaskBoardDetailsProvider.prototype = Object.extendsObject(AbstractAjaxProcessor, {
     belongsToUser: function(user){
        return gs.getUser().getID() == user;
     },
  
     isActiveTaskState: function(state){
        var states = gs.getProperty("com.snc.sdlc.scrum.pp.progress.task.state").split(",");
        for (var i = 0; i < states.length; i++)
           if (states[i] == state)
              return true;
        return false;
     },
  
     createStoryNode: function(gr, userLanguage, parentOnly){
        var id = gr["sys_id"];
        var name = gr["short_description"];
        var assignedTo = gr["assigned_to"];
        var assignedToName = this._getUserName(assignedTo);
        var stateName = this._getChoiceName("rm_story", gr["state"], userLanguage, "state");
        var points = gr["story_points"];
        var pointsTabIndex = JSUtil.nil(points)?-1:0;
        var displayName = name;
        if (displayName.trim().length == 0)
           displayName = gs.getMessage("-- Empty --");
  
        var type = gr["type"];
        var typeLabel = this._getChoiceName("rm_story", type, userLanguage, "type");
        var classification = gr["classification"];
        var classificationLabel = this._getChoiceName("rm_story", classification, userLanguage, "classification");
        
        var item = this.newItem("story");
        if (parentOnly){
           var tasks = new GlideRecordSecure("rm_scrum_task");
           tasks.addQuery("parent", id);
           tasks.query();
           item.setAttribute('has_tasks', 'false');
           while(tasks.next()){
              var taskState = tasks["state"];
              if (!this.taskStateActiveMap || !this.taskStateActiveMap[taskState]){
                 if (!this.taskStateActiveMap)
                    this.taskStateActiveMap = {};
                 if (this.isActiveTaskState(taskState))
                    this.taskStateActiveMap[taskState] = "true";
                 else
                    this.taskStateActiveMap[taskState] = "false";
              }
              if (this.taskStateActiveMap[taskState] == "true"){
                 item.setAttribute('has_tasks', 'true');
                 break;
              }
           }   
        }
  
        item.setAttribute('belongs_to', this.belongsToUser(gr["assigned_to"]));
        item.setAttribute('blocked', gr["blocked"]);
        item.setAttribute('blocked_reason', escape(gr["blocked_reason"]));
        item.setAttribute('id', gr["sys_id"]);
        item.setAttribute('number', gr["number"]);
        item.setAttribute('points', points);
        item.setAttribute('assigned_to', gr["assigned_to"]);
        item.setAttribute('assigned_to_name', assignedToName);
        item.setAttribute('short_description', escape(gr["short_description"]));
        item.setAttribute('acceptance_criteria', escape(gr["acceptance_criteria"]));
        item.setAttribute('state', escape(gr["state"]));
        item.setAttribute('type', type);
        item.setAttribute("type_label", typeLabel);
        item.setAttribute('classification', classification);
        item.setAttribute("classification_label", classificationLabel);
  
        item.setAttribute('index', gr["sprint_index"]);
  
        var markup = '<table class="elemTable" style="margin-right:5px;">';
           markup +=     '<tr>';
           markup +=         '<td colspan="2" title="'+gs.getMessage("Short Description")+'" id="short_descriptionCell_'+id+'" class="itemNameCell" tabindex="0" style="width: 100%;padding-bottom:5px;" role="link" aria-haspopup="true">';
           markup +=             GlideStringUtil.escapeHTML(displayName);
           markup +=         '</td>';
           markup +=     '</tr>';
  
  	   if (!parentOnly) {
             markup += '<tr class="toggleItem">';
             markup +=     '<td style="text-align:right;white-space: nowrap; vertical-align: top;">';
             markup +=         '<span class="itemStateTitleCell" id="stateTitleCell_'+id+'">';
             markup +=             gs.getMessage("Story State");
             markup +=         '</span>';
             markup +=     '</td>';
             markup +=     '<td style="white-space: nowrap; vertical-align: top;padding-left:20px;">';
             markup +=         '<span id="stateCell_'+id+'" class="itemStateCell" tabindex="0" role="link" aria-haspopup="true" aria-labelledby="stateTitleCell_'+id+'">';
             markup +=             GlideStringUtil.escapeHTML(stateName);
             markup +=         '</span>';
             markup +=     '</td>';
             markup += '</tr>';
  	   }
  
  	   markup += '<tr class="toggleItem">';
  	   markup +=     '<td style="text-align:right;vertical-align: top; white-space: nowrap;padding-top:5px;">';
  	   markup +=         '<span class="itemAssignedTitleCell" id="assigned_to_titleCell_'+id+'">';
  	   markup +=             gs.getMessage("Assigned To");
  	   markup +=         '</span>';
  	   markup +=     '</td>';
  	   markup +=     '<td style="vertical-align: top; width: 100%;padding-left:20px;padding-top:5px;">';
  	   markup +=         '<span id="assigned_to_nameCell_'+id+'" class="itemAssignedCell" tabindex="0" role="link" aria-haspopup="true" aria-labelledby="assigned_to_titleCell_'+id+'">';
  	   markup +=             GlideStringUtil.escapeHTML(assignedToName);
  	   markup +=         '</span>';
  	   markup +=     '</td>';
  	   markup += '</tr>';
  	   markup += '<tr class="toggleItem">';
  	   markup +=     '<td style="text-align:right;white-space: nowrap; vertical-align: top;padding-top:5px;">';
  	   markup +=         '<span class="itemTypeCell" id="type_titleCell_'+id+'">';
  	   markup +=             gs.getMessage("Story Type");
  	   markup +=         '</span>';
  	   markup +=     '</td>';
  	   markup +=     '<td style="width: 100%; white-space: nowrap; vertical-align: top;padding-top:5px;padding-left:20px;">';
  	   markup +=         '<span class="itemTypeLabelCell" id="type_labelCell_'+id+'" tabindex="0" role="link" aria-haspopup="true" aria-labelledby="type_titleCell_'+id+'">';
  	   markup +=             GlideStringUtil.escapeHTML(typeLabel);
  	   markup +=         '</span>';
  	   markup +=     '</td>';
  	   markup += '</tr>';
  	   markup += '<tr class="toggleItem">';
  	   markup +=     '<td style="text-align:right;white-space: nowrap; vertical-align: top;padding-top:5px;">';
  	   markup +=         '<span class="itemClassificationCell" id="classification_titleCell_'+id+'">';
  	   markup +=             gs.getMessage("Classification");
  	   markup +=         '</span>';
  	   markup +=     '</td>';
  	   markup +=     '<td style="width: 100%; white-space: nowrap; vertical-align: top;padding-top:5px;padding-left:20px;">';
  	   markup +=         '<span class="itemClassificationLabelCell" id="classification_labelCell_'+id+'" tabindex="0" role="link" aria-haspopup="true" aria-labelledby="classification_titleCell_'+id+'">';
  	   markup +=             GlideStringUtil.escapeHTML(classificationLabel);
  	   markup +=         '</span>';
  	   markup +=     '</td>';
  	   markup += '</tr>';
  
  	   if(parentOnly) {
  		   markup += '<tr class="toggleItem">';
  		   markup +=     '<td style="text-align:right;white-space: nowrap; vertical-align: top;padding-top:5px;">';
  		   markup +=         '<span class="itemHasTasksCell" id="itemHasTasksCell_'+id+'">';
  		   markup +=             gs.getMessage("Has Tasks");
  		   markup +=         '</span>';
  		   markup +=     '</td>';
  		   markup +=     '<td class="itemChildCell" style="width: 100%; white-space: nowrap; vertical-align: top;padding-top:5px;padding-left:20px;" aria-labelledby="itemHasTasksCell_'+id+'" tabindex="0" aria-disabled="true">';
  		   markup +=     '</td>';
  		   markup += '</tr>';
  	   }
  	   markup += '</table>';
        item.setAttribute('markup', escape(markup));
  
        var controlsMarkup = '<td colspan="2" style="text-align:right;background:none;padding-bottom:5px;">';
   	    controlsMarkup +=     '<div class="itemCreateChildCell">';
  	     controlsMarkup +=     '</div>';
  	     controlsMarkup +=     '<div>';
  	     controlsMarkup +=         '<span id="pointsCell_'+id+'" class="input_span" tabindex="'+pointsTabIndex+'" role="link" aria-haspopup="true" aria-label="Points">';
  	     controlsMarkup +=             GlideStringUtil.escapeHTML(points);
  	     controlsMarkup +=         '</span>';
  	     controlsMarkup +=         '<span> pts</span>';
  	     controlsMarkup +=     '</div>';
  	     controlsMarkup +=     '<div class="itemBlockedCell"></div>';
  	     controlsMarkup += '</td>';
  
        item.setAttribute("controls_markup", escape(controlsMarkup));
        item.setAttribute('mod_count', escape(gr["sys_mod_count"]));
        return item;
     },
  
     createTaskNode: function(gr, userLanguage, createTop, showActual){
        
        var type = gr["type"];
        var id = gr["sys_id"];
        var name = gr["short_description"];
        var displayName = name;
        if (displayName.trim().length == 0)
           displayName = gs.getMessage("-- Empty --");
        var assignedTo = gr["assigned_to"];
        var assignedToName = this._getUserName(assignedTo);
        var typeLabel = this._getChoiceName("rm_scrum_task", type, userLanguage, "type");
        var testResult = gr["test_result"];
        var testResultLabel = this._getChoiceName("rm_scrum_task", testResult,userLanguage , "test_result");
        var planned = gr["planned_hours"];
        var remaining = gr["remaining_hours"];
        var hours = gr["hours"];
        var plannedTabIndex = JSUtil.nil(planned)?-1:0;
        var remainingTabIndex = JSUtil.nil(remaining)?-1:0;
        var hoursTabIndex = JSUtil.nil(hours)?-1:0; 
  
        var item;
        if (createTop)
           item = this.newItem("task");
        else
           item = this.getDocument().createElement("task");
        item.setAttribute("belongs_to", this.belongsToUser(gr["assigned_to"]));
        item.setAttribute("blocked", gr["blocked"]);
        item.setAttribute("blocked_reason", escape(gr["blocked_reason"]));
        item.setAttribute("id", id);
        item.setAttribute("number", gr["number"]);
        item.setAttribute("hours", hours);
        item.setAttribute("planned_hours", planned);
        item.setAttribute("remaining_hours", remaining);
        item.setAttribute("assigned_to", assignedTo);
        item.setAttribute("assigned_to_name", assignedToName);
        item.setAttribute("type_label", typeLabel);
        item.setAttribute("short_description", escape(name));
        item.setAttribute("test_result_label", testResultLabel);
        item.setAttribute("test_result", testResult);
        item.setAttribute("type", type);
        item.setAttribute("state", gr["state"]);
        item.setAttribute('mod_count', escape(gr["sys_mod_count"]));
  
  
        var resultRowDisplay = "";
        if (type != "4")
           resultRowDisplay = ' style="display: none;"';
        var markup = '<table class="elemTable">';
  	     markup += '<tr>';
  	     markup +=     '<td colspan="2" id="short_descriptionCell_'+id+'" class="itemNameCell" style="width: 100%;padding-bottom:10px;" title="'+gs.getMessage("Short Description")+'" tabindex="0" role="link" aria-haspopup="true">';
  	     markup +=         GlideStringUtil.escapeHTML(displayName);
  	     markup +=     '</td>';
  	     markup += '</tr>';
  		 markup += '<tr class="toggleItem">';
  	     markup +=     '<td style="white-space: nowrap; vertical-align: top;text-align:right;">';
  	     markup +=         '<span class="itemAssignedTitleCell" id="taskAssigned_to_titleCell_'+id+'">';
  	     markup +=             gs.getMessage("Assigned To");
  	     markup +=         '</span>';
  	     markup +=     '</td>';
  	     markup +=     '<td style="width: 100%; vertical-align: top;padding-left:20px;">';
  	     markup +=         '<span class="itemAssignedCell" id="assigned_to_nameCell_'+id+'" tabindex="0" role="link" aria-haspopup="true" aria-labelledby="taskAssigned_to_titleCell_'+id+'">';
  	     markup +=             GlideStringUtil.escapeHTML(assignedToName);
  	     markup +=         '</span>';
  	     markup +=     '</td>';
  	     markup += '</tr>';
  		 markup += '<tr class="toggleItem">';
  	     markup +=     '<td style="white-space: nowrap; vertical-align: top;text-align:right;padding-top:5px;">';
  	     markup +=         '<span class="itemTypeCell" id="taskTypetitleCell_'+id+'">';
  	     markup +=             gs.getMessage("Task Type");
  	     markup +=         '</span>';
  	     markup +=     '</td>';
  	     markup +=     '<td style="width: 100%; white-space: nowrap; vertical-align: top;padding-top:5px;padding-left:20px;">';
  	     markup +=         '<span class="itemTypeLabelCell" id="type_labelCell_'+id+'" tabindex="0" role="link" aria-haspopup="true" aria-labelledby="taskTypetitleCell_'+id+'">';
  	     markup +=             GlideStringUtil.escapeHTML(typeLabel);
  	     markup +=         '</span>';
  	     markup +=     '</td>';
  	     markup += '</tr>';
  		 markup += '<tr class="toggleItem" class="itemTestResultRow" id="test_result_labelRow_'+id+'"'+resultRowDisplay+'>';
  	     markup +=     '<td style="white-space: nowrap; vertical-align: top;text-align:right;padding-top:5px;">';
  	     markup +=         '<span class="itemTestResultCell" id="test_result_titleCell_'+id+'">';
  	     markup +=             gs.getMessage("Test Result");
  	     markup +=         '</span>';
  	     markup +=     '</td>';
  	     markup +=     '<td style="width: 100%; white-space: nowrap; vertical-align: top;text-align:left;padding-top:5px;padding-left:20px;">';
  	     markup +=         '<span class="itemTestResultLabelCell" id="test_result_labelCell_'+id+'" tabindex="0" role="link" aria-haspopup="true" aria-labelledby="test_result_titleCell_'+id+'">';
  	     markup +=             GlideStringUtil.escapeHTML(testResultLabel);
  	     markup +=         '</span>';
  	     markup +=     '</td>';
  	     markup += '</tr>';
  	     markup += '</table>';
  
        item.setAttribute("markup", escape(markup));
  
        var actualStyle = '';
        if (!showActual)
           actualStyle = ' style="display: none;"';
        var controlsMarkup = '<td colspan="2" style="text-align:right;padding-bottom:5px;padding-top:5px;">';
  	     controlsMarkup +=     '<div nowrap="nowrap" title="'+gs.getMessage("Planned hours")+'" style="white-space: nowrap; padding-top: 5px;" class="itemHoursPlannedCell">';
  	     controlsMarkup +=         '<span style="white-space: nowrap;">P ';
   	    controlsMarkup +=             '<span title="'+gs.getMessage("Planned hours")+'" id="planned_hoursCell_'+id+'" class="input_span" tabindex="'+plannedTabIndex+'" role="link" aria-haspopup="true" aria-label="'+gs.getMessage("Planned hours")+'">';
  	     controlsMarkup +=                 GlideStringUtil.escapeHTML(planned);
  	     controlsMarkup +=             '</span>';
  	     controlsMarkup +=         '</span>';
  	     controlsMarkup +=     '</div>';
           controlsMarkup +=     '<div nowrap="nowrap" title="'+gs.getMessage("Remaining hours")+'" style="white-space: nowrap; padding-top: 5px;" class="itemHoursRemainingCell">';
  	     controlsMarkup +=         '<span style="white-space: nowrap;">R ';
  	     controlsMarkup +=             '<span title="'+gs.getMessage("Remaining hours")+'" id="remaining_hoursCell_'+id+'" class="input_span" tabindex="'+remainingTabIndex+'" role="link" aria-haspopup="true" aria-label="'+gs.getMessage("Remaining hours")+'">';
  	     controlsMarkup +=                 GlideStringUtil.escapeHTML(remaining);
  	     controlsMarkup +=             '</span>';
  	     controlsMarkup +=         '</span>';
  	     controlsMarkup +=     '</div>';
           controlsMarkup +=     '<div nowrap="nowrap" title="'+gs.getMessage("Actual hours")+'" style="white-space: nowrap; padding-top: 5px;" class="itemHoursCell">';
  	     controlsMarkup +=         '<span style="white-space: nowrap;">A ';
  	     controlsMarkup +=             '<span title="'+gs.getMessage("Actual hours")+'" id="hoursCell_'+id+'" class="input_span" tabindex="'+hoursTabIndex+'" role="link" aria-haspopup="true" aria-label="'+gs.getMessage("Actual hours")+'">';
  	     controlsMarkup +=                 GlideStringUtil.escapeHTML(hours);
  	     controlsMarkup +=             '</span>';
  	     controlsMarkup +=         '</span>';
  	     controlsMarkup +=     '</div>';
  	     controlsMarkup +=     '<div nowrap="nowrap" class="itemBlockedCell"></div>';
  	     controlsMarkup += '</td>';
        item.setAttribute("controls_markup", escape(controlsMarkup));
  
        return item;
     },
  
     getStringDate: function(str){
        return new GlideDateTime(str);
     },
  
  
     getLongDate: function(lng){
        return new GlideDateTime(new Packages.java.util.Date(lng));
     },
  
     updateTaskBoardData: function() {
        var rootID = this.getParameter('sysparm_root_id');
        var parentOnly = this.getParameter('sysparm_parent_only') == "true";
        var userLanguage = this.getParameter('sysparm_user_language');
        var lastUpdated  = this.getLongDate(Packages.java.lang.Long.parseLong(this.getParameter('sysparm_last_updated')));
        var showActual = gs.getProperty('com.snc.sdlc.scrum.pp.task_uses_actual_hours') == "true";
        var timeItem = this.newItem("time");
        timeItem.setAttribute("time", new Packages.java.util.Date().getTime());
  
        var idsStr = "";
        if (parentOnly){
           var gr = new GlideRecordSecure("rm_story");
           gr.addQuery("sprint", rootID);
           gr.orderBy("sprint_index");
           gr.orderBy("number");
           gr.query();
           while(gr.next()) { 
              if (this.getStringDate(gr["sys_updated_on"]).compareTo(lastUpdated) > 0)
                 this.createStoryNode(gr, userLanguage, parentOnly);
              else{
                 var gr2 = new GlideRecordSecure("rm_scrum_task");
                 gr2.addQuery("parent", gr["sys_id"]);
                 gr2.query();
                 while(gr2.next())
                    if (this.getStringDate(gr2["sys_updated_on"]).compareTo(lastUpdated) > 0){
                       this.createStoryNode(gr, userLanguage, parentOnly);
                       break;
                    }
              }
              idsStr += "|"+gr["sys_id"];
           }
        }else{
           var gr = new GlideRecordSecure("rm_story");
           gr.addQuery("sprint", rootID);
           gr.orderBy("sprint_index");
           gr.orderBy("number");
           gr.query();
           var item = null;
           while(gr.next()) { 
              var gr2 = new GlideRecordSecure("rm_scrum_task");
              gr2.addQuery("parent", gr["sys_id"]);
              gr2.query();
              var item = null;
              while(gr2.next()) {
                 var childUpdated  = this.getStringDate(gr2["sys_updated_on"]);
                 if (childUpdated.compareTo(lastUpdated) > 0){
                    if (!item || item == null)
                       item = this.createStoryNode(gr, userLanguage, parentOnly);
                    item.appendChild(this.createTaskNode(gr2, userLanguage, false, showActual));
                 }
                 idsStr += "|"+gr2["sys_id"];
              }
              if (!item || item == null)
                 if (this.getStringDate(gr["sys_updated_on"]).compareTo(lastUpdated) > 0)
                    this.createStoryNode(gr, userLanguage, parentOnly);
              idsStr += "|"+gr["sys_id"];
           }
        }
        var idsItem = this.newItem("ids");
        idsItem.setAttribute("ids", idsStr);
     },
  
     getTaskBoardData: function() {
        var rootID = this.getParameter('sysparm_root_id');
        var parentOnly = this.getParameter('sysparm_parent_only') == "true";
        var userLanguage = this.getParameter('sysparm_user_language');
        var showActual = gs.getProperty('com.snc.sdlc.scrum.pp.task_uses_actual_hours') == "true";
  
        var timeItem = this.newItem("time");
        timeItem.setAttribute("time", new Packages.java.util.Date().getTime());
  	  if (JSUtil.nil(rootID) || rootID == 'null')
  		return;
  
        var gr = new GlideRecordSecure("rm_story");
        gr.addQuery("sprint", rootID);
        gr.orderBy("sprint_index");
        gr.orderBy("number");
        gr.query();
        while (gr.next()){
           var item = this.createStoryNode(gr, userLanguage, parentOnly);
           if (!parentOnly){
              var gr2 = new GlideRecordSecure("rm_scrum_task");
              gr2.addQuery("parent", gr["sys_id"]);
              gr2.query();
              while (gr2.next())
                 item.appendChild(this.createTaskNode(gr2, userLanguage, false, showActual));
           }
        }
     },
  
     getTaskData: function() {
        var sysID = this.getParameter('sysparm_sys_id');
        var userLanguage = this.getParameter('sysparm_user_language');
        var showActual = gs.getProperty('com.snc.sdlc.scrum.pp.task_uses_actual_hours') == "true";
        var result = "";
        var gr = new GlideRecordSecure("rm_scrum_task");
        gr.addQuery("sys_id", sysID);
        gr.query();
        if (gr.next())
           this.createTaskNode(gr, userLanguage, true, showActual);
     },
  
     _getUserName: function(userID){
  
        if (userID && userID != ''){
           if (this.userNameMap && this.userNameMap[userID]){
              return this.userNameMap[userID];
           }else{
              var gr = new GlideRecordSecure("sys_user");
              gr.addQuery("sys_id", userID);
              gr.query();
              if (gr.next()){
                 if (!this.userNameMap)
                    this.userNameMap = {};
                 this.userNameMap[userID] = gr.name;
                 return gr.name;
              }
           }
        }
        return "None";
     },
  
     _getChoiceName: function(table, typeID, userLanguage, element){
        var key = table + "|" + typeID + "|" + userLanguage + "|" + element;
        if (this.choiceNameMap && this.choiceNameMap[key]){
           return this.choiceNameMap[key];
        }else{
           if (!this.choiceNameMap)
              this.choiceNameMap = {};
           if (!typeID || typeID == ''){
              this.choiceNameMap[key] = "None";
              return "None";
           }
           var gr = new GlideRecordSecure("sys_choice");
           gr.addQuery("name", table);
           gr.addQuery("element", element);
           gr.addQuery("language", "en");
           gr.addQuery("value", typeID);
           gr.query();
           var label = "None";
           if (gr.next()){
              label = gr["label"];
              var value = gr["value"];
              if (userLanguage != "en"){
                 var gr2 = new GlideRecordSecure("sys_choice");
                 gr2.addQuery("name", table);
                 gr2.addQuery("element", element);
                 gr2.addQuery("language", userLanguage);
                 gr2.addQuery("value", typeID);
                 gr2.query();
                 if (gr2.next())
                    label = gr2["label"];
              }
           }
           this.choiceNameMap[key] = label;
           return label;
        }
     },
  	
  	/**
  	 * Prevent public access to this processor
  	 */
  	isPublic: function() {
  		return false;
  	}    
  });

Sys ID

a4018f0537201000dadaa3549dbe5d08

Offical Documentation

Official Docs: