#set ($START_DATE = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.startdate"))) #set ($END_DATE = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.enddate"))) #set ($PLANNED_CAPACITY = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.plannedcapacity"))) #set ($ASSIGNED_CAPACITY = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.assignedcapacity"))) #set ($REMAINING_CAPACITY = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.remainingcapacity"))) #set ($LOAD_ERROR = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.loaderror"))) #set ($RELEASE_LOAD_ERROR = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.releaseloaderror"))) #set ($STORY = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.story"))) #set ($STORIES = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.stories"))) #set ($DECOMMIT_STORY_MSG = $CommonFunctions.encodeJavaScriptString($CommonFunctions.getTermFromResourceBundle($currentUserId, "gSprintplanningrhs", "sprintplanningrhs.decommitStoryMsg", "{0}", "{1}"))) #set ($LocaleDateFormat = $CommonFunctions.localeDateFormat()) #set ($ReleaseLocaleDateFormat = $CommonFunctions.localeDateFormat("m","Y")) var SPRHSLabels = { START_DATE: '$START_DATE:', END_DATE: '$END_DATE:', PLANNED_CAPACITY: '$PLANNED_CAPACITY:', ASSIGNED_CAPACITY: '$ASSIGNED_CAPACITY:', REMAINING_CAPACITY: '$REMAINING_CAPACITY:', LOAD_ERROR: '$LOAD_ERROR', RELEASE_LOAD_ERROR: '$RELEASE_LOAD_ERROR', STORY: '$STORY', STORIES: '$STORIES' }; Bxt.GroupingView = function(config) { Ext.apply(this, config); Bxt.GroupingView.superclass.constructor.call(this); }; Ext.extend(Bxt.GroupingView, Ext.grid.GroupingView, {}); Ext.override(Bxt.GroupingView, { interceptMouse : function(e){ e.stopEvent(); var hd = e.getTarget('.x-grid-group-hd', this.mainBody); if(hd){ // var hd1 = e.getTarget(); // var hdcls = hd1.parentNode.className; // if (hdcls != 'tbHover' && hdcls != '') { // this.toggleGroup(hd.parentNode); // } var hdp = e.getTarget('.tbName'); if(hdp == null) { this.toggleGroup(hd.parentNode); } } } }); /* * RHS of sprintplanning tab. Currently this object using the local data * from this file and does not access the server to retreive or persist data. */ var sprintplanningrhs = { gridCtrl : null, gridView:null, ddTarget : null, storyRec : null, releaseCombobox : null, releaseComboDS : null, sprintreqDS : null, selectedItem : null, sprintMetricsMap:null, headercontextmenu:null, loadMask:null, init: function(el) { Ext.QuickTips.init(); sprintplanningrhs.createReleaseCombobox(); sprintplanningrhs.createAddMenu(); sprintplanningrhs.createGrid(); releaseDialog.init(); sprintDialog.init(); // fix for displaying 'Choose...' sprintplanningrhs.releaseCombobox.setValue(); }, setLoadMask : function (loadMask) { sprintplanningrhs.loadMask = loadMask; }, createReleaseCombobox : function () { var releaseComboRec = Ext.data.Record.create( [ { name:'id' }, { name:'name', sortType:'asUCString' } ]); sprintplanningrhs.releaseComboDS = new Ext.data.Store({ id : 0, proxy: new Ext.data.HttpProxy({url:'pbv/PBVAsyncHandler?action=RELEASELIST'}), reader: new Ext.data.JsonReader({id: 'id'}, releaseComboRec), sortInfo:{field: 'name', direction: "ASC"} }); // backlog toolbar combo box sprintplanningrhs.releaseCombobox = new Ext.form.ComboBox({ id: 'spx_releaseCombobox', tpl: '
{name}
', store : sprintplanningrhs.releaseComboDS, displayField :'name', valueField :'id', forceSelection : true, mode : 'local', emptyText :'$CHOOSE', selectOnFocus :true, width : 220, editable : false, triggerAction : 'all', listClass :'x-combo-list-small' , listeners : { select : onReleaseSelect, loadexception: BxtUtil.lexHandler } }); function onReleaseSelect(combo, rec, index) { sprintplanningrhs.loadSprintRequirements(); } sprintplanningrhs.releaseCombobox.setValue(); }, createAddMenu : function() { sprintplanningrhs.addMenu = new Ext.menu.Menu ({ items: [ { text: '$MENU_RELEASE', handler: sprintplanningrhs.addRelease}, { text: '$MENU_SPRINT', handler: sprintplanningrhs.addSprint} ] }); sprintplanningrhs.addMenu.on('beforeshow', sprintplanningrhs.enableAddMenu); }, createGrid : function() { sprintplanningrhs.storyRec = Ext.data.Record.create([ {name: 'id'}, {name: 'name'}, {name: 'rank', type: 'float', sortType: BxtUtil.rankSort}, {name: 'size', type: 'float'}, {name: 'acceptedby' }, {name: 'sprint'}, {name: 'sprintid'}, {name: 'dummy'}, {name: 'enddate'}, {name: 'status'}, {name: 'startdate'}, {name: 'enddate'}, {name: 'plannedcapacity'}, {name: 'actualcapacity'}, {name: 'remainingcapacity'} ]); var proxy = new Ext.data.HttpProxy({url:'ajax2/Gemini?action=focus.web.ajax.LoadSPxSprintTableAction&userid=$currentUserId'}); var reader = new Ext.data.JsonReader({}, sprintplanningrhs.storyRec); var s = new Ext.data.GroupingStore({ proxy : proxy, reader : reader, sortInfo:{field: 'rank', direction: "ASC"}, groupField:'sprint' }); var sprintid = "{[values.rs[0].data.sprintid]}"; var tmpl = ""+ "" + ""+ "
"+ "" + "{text}" + '{[values.rs[0].data.id.length > 1 ? " (" + values.rs.length + [ values.rs.length > 1 ? " ' + SPRHSLabels.STORIES + '" + ")" : " ' + SPRHSLabels.STORY + '" + ")" ] : ""]}' + ""+ "" + "
"; var v = new Bxt.GroupingView({ forceFit:true, enableGroupingMenu : false, enableNoGroups : false, hideGroupedColumn : true, showGroupName : false, enableRowBody : true, groupTextTpl: tmpl }); var g = new Ext.grid.GridPanel({ id: 'sprintplanningrhsGrid', store : s, columns : [ {header:'ID', width:8, sortable:false, dataIndex: 'id', renderer: TBLRender.Id}, {id:'name',header: '$COL_STORY', width: 55, sortable: false, dataIndex: 'name', renderer: sprintplanningrhs.renderName}, {header: "Rank", width: 10, hidden: true, sortable: false, dataIndex: 'rank', renderer:TBLRender.Number}, {header: "$COL_SIZE", width: 7, sortable: false, dataIndex: 'size', renderer:TBLRender.Number}, {header: "$COL_ACCPTBY", width: 20, sortable: false, dataIndex: 'acceptedby' }, {header: "Sprint", width: 20, hidden:true, dataIndex: 'sprint'}, {header: "enddate", width: 20, hidden:true, sortable: true, dattaIndex: 'enddate'} ], view : v, frame : false, header : false, border : false, loadMask: true, collapsible : true, animCollapse : false, iconCls : 'icon-grid', renderTo : document.body, enableDragDrop : true, //bbar :[], tbar :[ new Ext.Toolbar.TextItem(' $RELEASE_LBL :'), new Ext.Toolbar.Spacer(), new Ext.Toolbar.Spacer(), new Ext.Toolbar.Spacer(), new Ext.Toolbar.Spacer(), sprintplanningrhs.releaseCombobox, new Ext.Toolbar.Button( { iconCls: 'edit', #if (!$canManageReleases) disabled: true, #end handler: sprintplanningrhs.editRelease, tooltip: '$TT_EDITREL'}), '->', { text: '$MENU_ADD', iconCls: 'Add', #if (!$canManageReleases && !$canManageSprints) disabled: true, #end menu : sprintplanningrhs.addMenu }, new Ext.Toolbar.Spacer() ] }); sprintplanningrhs.gridCtrl = g; sprintplanningrhs.sprintreqDS = s; sprintplanningrhs.gridView = v; // set dragdrop g.getDragDropText = function() { var count = this.selModel.getCount(); var selections = this.selModel.selections; var result = ''; for(i = 0; i < count; i ++) { var rec = selections.get(i); if(i>0) result += ", "; result += rec.data.name; } return result; } sprintplanningrhs.ddTarget = new Ext.dd.DropTarget(g.getEl(), { ddGroup : 'GridDD', copy:false, containerScroll : true, notifyDrop : sprintplanningrhs.notifyDropRR, notifyOver : sprintplanningrhs.notifyOver } ); // For row drag and drop scrolling . Ext.dd.ScrollManager.register(g.view.scroller); // context menu sprintplanningrhs.addContextMenu(); }, renderName : function(value, p, record, rowindex, colindex, store) { // p.attr = 'ext:qtip="' + value + '"'; var tip = 'qtip="' + value + '"'; var reqId = sprintplanningrhs.gridCtrl.getStore().getAt(rowindex).get('id'); var sprintId = sprintplanningrhs.gridCtrl.getStore().getAt(rowindex).get('sprintid'); if(reqId == '-') { return ''; } var r = "" + value + ""; return r; }, addContextMenu : function() { sprintplanningrhs.contextMenu = new Ext.menu.Menu(); sprintplanningrhs.headercontextmenu = new Ext.menu.Menu(); // handler for context menu items function contextMenuHandler(item, e) { var sprintId = sprintplanningrhs.selectedItem['sprintid']; switch (item.id) { case 'decommitstory': sprintplanningrhs.decommitStory(sprintplanningrhs.selectedItem); break; case 'editsprint': case 'editsprint1': sprintplanningrhs.editSprint(sprintId); break; case 'copystory': var storyId = sprintplanningrhs.selectedItem['id']; sprintplanningrhs.editStory(storyId, true, item.getEl(),sprintId); break; case 'editstory': var storyId = sprintplanningrhs.selectedItem['id']; sprintplanningrhs.editStory(storyId, false, item.getEl(),sprintId); break; case 'addstory': case 'addstory1': sprintplanningrhs.addNewRequirement(item.getEl(),sprintId); break; case 'refreshsprint': case 'refreshsprint1': sprintplanningrhs.refreshSprint(); break; case 'collapseall': case 'collapseall1': sprintplanningrhs.gridView.collapseAllGroups(); break; case 'expandall': case 'expandall1': sprintplanningrhs.gridView.expandAllGroups(); break; } } sprintplanningrhs.editstory = new Ext.menu.Item({ id: 'editstory', text: '$EDIT_STORY_MENU', handler: contextMenuHandler }); sprintplanningrhs.copystorymenu = new Ext.menu.Item({ id: 'copystory', text: '$COPY_STORY_MENU', handler: contextMenuHandler }); sprintplanningrhs.decommitmenu = new Ext.menu.Item({ id: 'decommitstory', text: '$DECOMMIT_STORY_MENU', handler: contextMenuHandler }); sprintplanningrhs.editsprint = new Ext.menu.Item({ id: 'editsprint', text: '$EDIT_SPRINT_MENU', handler: contextMenuHandler }); sprintplanningrhs.addstorymenu = new Ext.menu.Item({ id: 'addstory', text: '$ADD_STORY_MENU', handler: contextMenuHandler }); sprintplanningrhs.refreshsprints = new Ext.menu.Item({ id: 'refreshsprint', text: '$REFRESH_SPRINTS_MENU', handler: contextMenuHandler }); sprintplanningrhs.collapseallmenu = new Ext.menu.Item({ id: 'collapseall', text: '$COLLAPSE_ALL_SPRINTS_MENU', handler: contextMenuHandler }); sprintplanningrhs.expandallmenu= new Ext.menu.Item({ id: 'expandall', text: '$EXPAND_ALL_SPRINTS_MENU', handler: contextMenuHandler }); sprintplanningrhs.contextMenu.add(sprintplanningrhs.editstory); sprintplanningrhs.contextMenu.add(sprintplanningrhs.copystorymenu); sprintplanningrhs.contextMenu.add(sprintplanningrhs.decommitmenu); sprintplanningrhs.contextMenu.add('-'); sprintplanningrhs.contextMenu.add(sprintplanningrhs.editsprint); sprintplanningrhs.contextMenu.add(sprintplanningrhs.addstorymenu); sprintplanningrhs.contextMenu.add('-'); sprintplanningrhs.contextMenu.add(sprintplanningrhs.refreshsprints); sprintplanningrhs.contextMenu.add(sprintplanningrhs.collapseallmenu); sprintplanningrhs.contextMenu.add(sprintplanningrhs.expandallmenu); sprintplanningrhs.editsprint1 = new Ext.menu.Item({ id: 'editsprint1', text: '$EDIT_SPRINT_MENU', handler: contextMenuHandler }); sprintplanningrhs.addstorymenu1 = new Ext.menu.Item({ id: 'addstory1', text: '$ADD_STORY_MENU', handler: contextMenuHandler }); sprintplanningrhs.refreshsprints1 = new Ext.menu.Item({ id: 'refreshsprint1', text: '$REFRESH_SPRINTS_MENU', handler: contextMenuHandler }); sprintplanningrhs.collapseallmenu1 = new Ext.menu.Item({ id: 'collapseall1', text: '$COLLAPSE_ALL_SPRINTS_MENU', handler: contextMenuHandler }); sprintplanningrhs.expandallmenu1= new Ext.menu.Item({ id: 'expandall1', text: '$EXPAND_ALL_SPRINTS_MENU', handler: contextMenuHandler }); sprintplanningrhs.headercontextmenu.add(sprintplanningrhs.editsprint1); sprintplanningrhs.headercontextmenu.add(sprintplanningrhs.addstorymenu1); sprintplanningrhs.headercontextmenu.add('-'); sprintplanningrhs.headercontextmenu.add(sprintplanningrhs.refreshsprints1); sprintplanningrhs.headercontextmenu.add(sprintplanningrhs.collapseallmenu1); sprintplanningrhs.headercontextmenu.add(sprintplanningrhs.expandallmenu1); sprintplanningrhs.refreshstorytablemenu = new Ext.menu.Item({ id: 'refreshstory', text: '$REFRESH_STORY_MENU', handler: contextMenuHandler }); sprintplanningrhs.gridCtrl.addListener('rowcontextmenu', function (grid, rowIndex, e) { e.stopEvent(); var mitems = sprintplanningrhs.contextMenu.items; var sel = grid.getSelectionModel().getSelections(); if(sel.length <= 1) { mitems.get(0).enable(); sprintplanningrhs.selectedItem = grid.getStore().getAt(rowIndex).data; //enable/disable var id = sprintplanningrhs.selectedItem['id']; if (id != '-') { sprintplanningrhs.editstory.enable(); sprintplanningrhs.copystorymenu.enable(); sprintplanningrhs.decommitmenu.enable(); }else { sprintplanningrhs.editstory.disable(); sprintplanningrhs.copystorymenu.disable(); sprintplanningrhs.decommitmenu.disable(); } sprintplanningrhs.refreshstorytablemenu.enable(); } else { mitems.get(0).disable(); sprintplanningrhs.editstory.disable(); sprintplanningrhs.copystorymenu.disable(); sprintplanningrhs.decommitmenu.disable(); sprintplanningrhs.refreshstorytablemenu.disable(); } #if (!$canManageStories || !$canManageSprints) sprintplanningrhs.copystorymenu.disable(); #end #if (!$canManageSprints) sprintplanningrhs.decommitmenu.disable(); sprintplanningrhs.editsprint.disable(); #end #if (!$canManageStories) sprintplanningrhs.addstorymenu.disable(); #end var coords = e.getXY(); sprintplanningrhs.contextMenu.showAt([coords[0], coords[1]]); } ); }, OnSprintMenu: function(event,el,sprintid,rowIndex) { var event_var = (event) ? event: window.event; sprintplanningrhs.selectedItem = sprintplanningrhs.gridCtrl.getStore().getAt(rowIndex).data; if(window.event) window.event.returnValue = false; else event.preventDefault(); #if (!$canManageSprints) sprintplanningrhs.editsprint1.disable(); #end #if (!$canManageStories) sprintplanningrhs.addstorymenu1.disable(); #end sprintplanningrhs.headercontextmenu.showAt([event_var.clientX,event_var.clientY]); return false; }, enableAddMenu : function (menu) { var mitem = menu.items; if(sprintplanning.projectCombobox.getValue() == '') { mitem.get(0).disable(); mitem.get(1).disable(); } else if( sprintplanningrhs.releaseCombobox.getValue() == '') { #if ($canManageReleases) mitem.get(0).enable(); #else mitem.get(0).disable(); #end mitem.get(1).disable(); } else { #if ($canManageReleases) mitem.get(0).enable(); #else mitem.get(0).disable(); #end #if ($canManageSprints) mitem.get(1).enable(); #else mitem.get(1).disable(); #end } }, groupHeaderRenderer : function(v,unused,rec,rowIndex,colIndex,ds) { return rec.get('name'); }, // ---------- DragDrop Handlers ---------- notifyDropRR : function (dd, e, data) { if(!$canManageSprints) { return false; } var ddat = dd.getDragData(e); var g = ddat.grid; if(g == undefined) { return false; } var ds = g.getStore(); if(ds != sprintplanningrhs.gridCtrl.getStore()) { return sprintplanningrhs.notifyDropLR(dd, e, data, ddat.rowIndex); } var rows = data.selections; var dstidx = ddat.rowIndex; if(dstidx == undefined) { return false; } BxtRanks.buildSPxRankString(sprintplanningrhs.updateRankPositionRR, dstidx, rows, ds); }, notifyOver: function(dd,e,data) { // CHANGE DRAG IMAGE TO THE DROP ALLOWED IMAGE if(!$canManageSprints) { return dd.dropNotAllowed; } var ddat = dd.getDragData(e); var g = ddat.grid; if(g == undefined ) { return dd.dropNotAllowed; } var dstidx = ddat.rowIndex; if(dstidx == undefined) { return dd.dropNotAllowed; } return dd.dropAllowed; }, updateRankPositionRR : function(indexArray, rankArray, destIndex, paramString, destRecord) { //sprintplanningrhs.loadMask.show(); Ext.Ajax.request({ url: 'pbv/PBVAsyncHandler?action=SAVE-RANKS', success: sprintplanningrhs.reqReinsertHandlerRR, failure: function(response, options) { //sprintplanningrhs.loadMask.hide(); ErrorHandlerLib.onAjaxFailure(response, options); }, settings: {show: true, msg:'$UPDATERANK_ERROR'}, localvars: { indexArray: indexArray, rankArray: rankArray, destindex: destIndex, destRecord: destRecord }, params: { start: 0, limit: 25, paramString: paramString, reqsprintid: destRecord.get('sprintid'), releaseid : sprintplanningrhs.releaseCombobox.getValue() } }); }, reqReinsertHandlerRR : function(response, options) { //sprintplanningrhs.loadMask.hide(); if (response.responseText != undefined) { if(BxtUtil.checkErrorInResponse(response)) { return; } // get params passed from requesting method var indexArray = options.localvars.indexArray; var rankArray = options.localvars.rankArray; var destIndex = options.localvars.destindex; var destRecord = options.localvars.destRecord; if (indexArray.length == rankArray.length) { var ds = sprintplanningrhs.sprintreqDS; var removeDummy = null; var addDummy = null; var addDummyIdx = null; var dummyidx = 0; var removedDummy = false; for (i = 0; i < indexArray.length; i++) { var index = indexArray[i]; if (index < ds.indexOf(destRecord)) { index -= i; } var v = ds.getAt(index); var srcidx = ds.indexOf(v); if(v.get('dummy') == '1') { continue; } var vsp = v.get('sprint'); var tsp = destRecord.get('sprint'); var tspid = destRecord.get('sprintid'); var tstatus = destRecord.get('status'); var tstartdate = destRecord.get('startdate'); var tenddate = destRecord.get('enddate'); var tplannedcapacity = destRecord.get('plannedcapacity'); var tactualcapacity = destRecord.get('actualcapacity'); var tremainingcapacity = destRecord.get('remainingcapacity'); var vInsp = ds.query('sprint', vsp); var tInsp = ds.query('sprint', tsp); // remove story from source if (vInsp.getCount() == 1) { // create a dummy record if there are no more records for the sprint after the move. // this dummy record is a place holder and cannot be drag-dropped. addDummy = new sprintplanningrhs.storyRec({ id : '-', name: '', rank: '', size: '', owner: '', sprint: vsp, dummy: '1', sprintid : v.get('sprintid'), status: v.get('status'), startdate: v.get('startdate'), enddate: v.get('enddate'), plannedcapacity: v.get('plannedcapacity'), actualcapacity: v.get('actualcapacity'), remainingcapacity: v.get('remainingcapacity') }); addDummyIdx = srcidx; if (srcidx >= ds.indexOf(destRecord)) { addDummyIdx++; } } ds.remove(v); // insert story to destination if(tInsp.getCount() == 1) { if(null != destRecord && destRecord.get('dummy') == '1') { // It the sprint has a dummy record, remove it before insertion a real one. removeDummy = destRecord; } } ds.insert(ds.indexOf(destRecord),v); // update story attributes v.set('sprint', tsp); v.set('sprintid', tspid); v.set('rank', rankArray[i]); v.set('status', tstatus); v.set('startdate', tstartdate); v.set('enddate', tenddate); v.set('plannedcapacity', tplannedcapacity); v.set('actualcapacity', tactualcapacity); v.set('remainingcapacity', tremainingcapacity); } if (null != addDummy && null != addDummyIdx) { ds.insert(addDummyIdx, addDummy); } if (null != removeDummy) { ds.remove(removeDummy); } ds.commitChanges(); //restore the sorted state var state = ds.getSortState(); ds.sort(state.field ,state.direction); sprintplanningrhs.gridCtrl.view.refresh(); sprintplanningrhs.drawSprintInfoBars(); } else { BxtUtil.showErrorMsg('$ERROR_SPRINT_UPDATE'); } } return true; }, notifyDropLR : function (dd, e, data, dstidx) { if(!$canManageSprints) { return false; } var ddat = dd.dragData; //dd.getDragData(e); var srcGrid = ddat.grid; if(srcGrid == undefined) { return false; } var srcDS = srcGrid.getStore(); var dstDS = sprintplanningrhs.gridCtrl.getStore(); var state = dstDS.getSortState(); var sdir = (state.direction == 'ASC'); var rows = data.selections; if(dstidx == undefined) { return false; } var destRecord = dstDS.getAt(dstidx); var recordCount = dstDS.getCount(); var lastRecord = destRecord; // if the destination record is not the last record in the sprint // find the last record in the sprint to get the greatest rank var index = dstidx; if (index < recordCount-1) { var destSprintId = destRecord.get('sprintid'); while (index < recordCount-1) { var record = dstDS.getAt(index+1); if (destSprintId == record.get('sprintid')) { lastRecord = record; } else { break; } index++; } } var lastRankInt = parseInt(lastRecord.get('rank')); if (isNaN(lastRankInt)) { lastRankInt = 0; } // build backlog storyRec array and // build sprint storyRec array and // build reqid,newrank string var srcRecArray = new Array(rows.length); var dstRecArray = new Array(rows.length); var paramString = ""; // This first pass is done so the paramString is formatted properly // paramString = "v1,v2|v1,v2|v1,v2" src = srcDS.getById(rows[0].id); srcRecArray[0] = src; newStoryRec = new sprintplanningrhs.storyRec({ id: src.get('id'), name: src.get('name'), rank: ++lastRankInt, size: src.get('size'), acceptedby: src.get('acceptedby'), owner: '', sprint: destRecord.get('sprint'), sprintid: destRecord.get('sprintid'), dummy: '0', status: destRecord.get('status'), startdate: destRecord.get('startdate'), enddate: destRecord.get('enddate'), plannedcapacity: destRecord.get('plannedcapacity'), actualcapacity: destRecord.get('actualcapacity'), remainingcapacity: destRecord.get('remainingcapacity') }); dstRecArray[0] = newStoryRec; paramString += newStoryRec.get('id') + "," + newStoryRec.get('rank'); for (i = 1; i < rows.length; i++) { src = srcDS.getById(rows[i].id); srcRecArray[i] = src; newStoryRec = new sprintplanningrhs.storyRec({ id: src.get('id'), name: src.get('name'), rank: ++lastRankInt, size: src.get('size'), acceptedby: src.get('acceptedby'), owner: '', sprint: destRecord.get('sprint'), sprintid: destRecord.get('sprintid'), dummy: '0', status: destRecord.get('status'), startdate: destRecord.get('startdate'), enddate: destRecord.get('enddate'), plannedcapacity: destRecord.get('plannedcapacity'), actualcapacity: destRecord.get('actualcapacity'), remainingcapacity: destRecord.get('remainingcapacity') }); dstRecArray[i] = newStoryRec; paramString += "|" + newStoryRec.get('id') + "," + newStoryRec.get('rank'); } sprintplanningrhs.commitStoriesLR(srcRecArray, dstRecArray, paramString, dstidx, dstDS.getAt(dstidx)); }, commitStoriesLR : function(srcRecArray, dstRecArray, paramString, destIndex, destRecord) { //sprintplanningrhs.loadMask.show(); Ext.Ajax.request({ url: 'pbv/PBVAsyncHandler?action=SAVE-RANKS', success: sprintplanningrhs.reqReinsertHandlerLR, failure: function(response, options){ //sprintplanningrhs.loadMask.hide(); ErrorHandlerLib.onAjaxFailure(response, options); }, settings: {show: true, msg:'$UPDATERANK_ERROR'}, localvars: { srcRecArray: srcRecArray, dstRecArray: dstRecArray, destindex: destIndex }, params: { start: 0, limit: 25, paramString: paramString, reqsprintid: destRecord.get('sprintid'), releaseid : sprintplanningrhs.releaseCombobox.getValue() } }); }, reqReinsertHandlerLR : function(response, options) { //sprintplanningrhs.loadMask.hide(); if (response.responseText != undefined) { if (BxtUtil.checkErrorInResponse(response)) { return; } // get params passed from requesting method var srcRecArray = options.localvars.srcRecArray; var dstRecArray = options.localvars.dstRecArray; var destIndex = options.localvars.destindex; var dstDS = sprintplanningrhs.sprintreqDS; var srcDS = sprintplanning.gridDS; for (i = dstRecArray.length-1; i >= 0; i--) { var v = dstRecArray[i]; var tgt = dstDS.getAt(destIndex); if (tgt.get('dummy') == '1') { // It the sprint has a dummy record, remove it before insertion a real one. dstDS.remove(tgt); } srcDS.remove(srcRecArray[i]); dstDS.insert(destIndex, dstRecArray[i]); } dstDS.commitChanges(); srcDS.commitChanges(); //restore the sorted state var state = dstDS.getSortState(); dstDS.sort(state.field ,state.direction); sprintplanningrhs.gridCtrl.view.refresh(); sprintplanningrhs.drawSprintInfoBars(); } }, calcSprintRank : function( dstDS, srcidx, dstidx, sdir ) { var row1 = (dstidx > 0) ? dstDS.getAt(dstidx-1) : null; var row2 = dstDS.getAt(dstidx); if(row2.get('dummy') == '1') { var r = (row1 != null) ? row1.get('rank') : ''; return (r == null || r == '') ? 10.0 : parseFloat(r);; } var sp2 = row2.get('sprint'); var sp1 = (row1 == null) ? sp2: row1.get('sprint'); if(sp1 != sp2) { row1 = null; } var r1 = (row1 == null || (row1.get('rank') == '')) ? 0.0 : parseFloat(row1.get('rank')); var r2 = (row2.get('rank') == '') ? 0.0 : parseFloat(row2.get('rank')); return BxtRanks.calcNewRank(r1, r2, sdir); }, // ---------- Add/Edit Release, Add/Edit/Decommit Sprint ---------- addRelease : function() { if (sprintplanning.projectCombobox.getValue() != '') { releaseDialog.addNewRelease(sprintplanningrhs.addMenu.getEl()); } }, editRelease : function() { var selRelId = sprintplanningrhs.releaseCombobox.getValue(); if (selRelId != '') { releaseDialog.editRelease(selRelId); } }, addSprint : function() { if (sprintplanningrhs.releaseCombobox.getValue() != '') { sprintDialog.addNewSprint(sprintplanningrhs.addMenu.getEl()); } }, editSprint : function (sprintId) { if(sprintId != undefined) { sprintDialog.editSprint(sprintId); } }, editSprintByRow : function (rowId) { var row = sprintplanningrhs.sprintreqDS.getAt(rowId); var sprintId = row.get('sprintid'); sprintDialog.editSprint(sprintId); }, loadSprintInfo: function( el,rowIndex) { if (rowIndex >= 0) { var current_record = sprintplanningrhs.sprintreqDS.getAt(rowIndex); var sprintId = current_record.get('sprintid'); var sprintName = current_record.get('sprint'); var status = current_record.get('status'); var startdate = current_record.get('startdate'); var enddate = current_record.get('enddate'); var planned = current_record.get('plannedcapacity'); //calculate metrics in the UI var ds = sprintplanningrhs.sprintreqDS; var actual = 0; for (i = 0; i < ds.getCount(); i++) { var rec = ds.getAt(i); var spid = rec.get('sprintid'); var isReqRow = (rec.get('dummy') == '0') ? 1 : 0; if (isReqRow && spid == sprintId) { if (rec.get('size') != undefined && rec.get('size') != null && rec.get('size') != "") { var act = 0; act = rec.get('size'); actual = actual + act; } } } var remain = (planned != undefined && planned != null) ? (planned - actual):''; status = (status != undefined && status != null) ? status:''; startdate = (startdate != undefined && startdate != null) ? startdate:''; enddate = (enddate != undefined && enddate != null) ? enddate:''; planned = (planned != undefined && planned != null) ? planned:''; return sprintplanningrhs.createSprintToolTip(sprintName, status, startdate, enddate, planned, actual, remain, el); } }, createSprintToolTip: function(sprintName,status,startdate,enddate,planned,actual,remain,el) { var font_dark_blue = ""; var font_dark_gray = ""; var font_green = ""; var font_dark_black = ""; var font_end = ""; var tab_space = "    "; var statusStr = ''; if (SprintStatus.PLANNING.value == status) { statusStr = SprintStatus.PLANNING.status; } else if (SprintStatus.ACTIVE.value == status) { statusStr = SprintStatus.ACTIVE.status; } else if (SprintStatus.COMPLETED.value == status) { statusStr = font_green + SprintStatus.COMPLETED.status + font_end; } var buff = ""; buff = buff + ""; buff = buff + ""; buff = buff + ""; buff = buff + "
" + sprintName + "" + statusStr + "
"; buff = buff + ""; buff = buff + ""; buff = buff + font_dark_gray + tab_space + SPRHSLabels.START_DATE + "  " + font_end + font_dark_blue + startdate + font_end; buff = buff + "
"; buff = buff + font_dark_gray + tab_space + SPRHSLabels.END_DATE + "  " + font_end + font_dark_blue + enddate + font_end; buff = buff + "
"; buff = buff + font_dark_gray + tab_space + SPRHSLabels.PLANNED_CAPACITY + "  " + font_end + font_dark_blue + planned + font_end; buff = buff + "
"; buff = buff + font_dark_gray + tab_space + SPRHSLabels.ASSIGNED_CAPACITY + "  " + font_end + font_dark_blue + actual + font_end; buff = buff + "
"; buff = buff + font_dark_gray + tab_space + SPRHSLabels.REMAINING_CAPACITY + "  " + font_end + font_dark_blue + remain + font_end; buff = buff + "

"; return new Ext.ToolTip({ target: el, autoDestroy: true, title: '', autoHide: true, showDelay: 60, hideDelay: 0, autoHeight: true, width: 250, trackMouse: true, html: buff, mouseOffset : [10,-50] //without the offset, the last sprint had display issues }); }, decommitStory : function (item) { var selections = sprintplanningrhs.gridCtrl.selModel.getSelections(); var selectlen = selections.length; if (selectlen <= 1) { msg = '$DECOMMIT_STORY_MSG'; msg = msg.replace(/\{0\}/, BxtUtil.formatId(item['id'])); msg = msg.replace(/\{1\}/, item['name']); Ext.Msg.show({ title: '$DECOMMIT_STORY', msg: '' + msg + '', buttons: Ext.Msg.OKCANCEL, localvars: item, fn: sprintplanningrhs.onDecommit, icon: Ext.MessageBox.QUESTION, animEl: sprintplanningrhs.gridCtrl.getEl() }); } }, editStory : function(reqId, copy, el,sprintId) { storyDialog.resetDialog(); storyDialog.projectId = sprintplanning.projectCombobox.getValue(); storyDialog.sprintId = sprintId; storyDialog.saveSuccessHandlerFn = sprintplanningrhs.loadSprintRequirements; storyDialog.tabx = 'spx'; storyDialog.showRequirementDetails(reqId, copy, el, sprintplanningrhs.loadMask); }, onDecommit : function(val, options) { if(val == 'ok'){ var item = sprintplanningrhs.selectedItem; var paramString = item['id'] + "," + item['sprintid']; sprintplanning.loadMask.show(); Ext.Ajax.request({ url: 'pbv/PBVAsyncHandler?action=SAVE-REQ', success: sprintplanningrhs.decommitReload, failure: ErrorHandlerLib.onAjaxFailure, settings: {show: true, msg:'$UPDATERANK_ERROR'}, params: { start: 0, limit: 25, subaction: 'DECOMMIT', paramString: paramString } }); } }, decommitReload : function(response, options) { sprintplanning.loadMask.hide(); sprintplanningrhs.loadSprintRequirements(); sprintplanning.reloadRequirements(); }, // ---------- Add Requirement ---------- getDefaultBacklogId:function() { sprintplanning.blCombods var count =sprintplanning.blCombods.getCount(); var ds = sprintplanning.blCombods; for (i = 0; i < count; i++) { var backlogId = ds.getAt(i).get('id'); var master = ds.getAt(i).get('master'); if(master){ return backlogId; } } return ''; }, setupStoryDialog : function(sprintId) { storyDialog.resetDialog(); storyDialog.productBacklog = null;//there is no backlog context on the sprint side storyDialog.projectId = sprintplanning.projectCombobox.getValue(); storyDialog.sprintId = sprintId; storyDialog.tabx = 'spx'; storyDialog.saveSuccessHandlerFn = sprintplanningrhs.loadSprintRequirements; }, addNewRequirement : function(el,sprintId) { sprintplanningrhs.setupStoryDialog(sprintId); storyDialog.addNewRequirement(el, sprintplanningrhs.loadMask); }, // ---------- Misc Handlers ---------- onProjectChange : function() { sprintplanningrhs.releaseCombobox.clearValue(); sprintplanningrhs.loadReleaseList(); }, // ---------- Combo/Table loaders --------- loadReleaseList : function() { var projectId = sprintplanning.projectCombobox.getValue(); if (projectId != '' && projectId != undefined) { sprintplanningrhs.releaseComboDS.reload({ waitMsg: '$LOADING', params: {start: 0, limit: 30, projectid: projectId }, callback : sprintplanningrhs.loadedReleases }); } }, loadedReleases : function ( rec, option, success) { if (success) { if (rec.length == 1) { sprintplanningrhs.setReleaseValue(rec[0].get('id')); } else { sprintplanningrhs.loadUserSettingsRelease(); } } else { BxtUtil.showErrorMsg(SPRHSLabels.RELEASE_LOAD_ERROR); } }, loadUserSettingsRelease : function() { BxtUserSettings.load('$_FOCUS_SPRINT_PLANNING_VIEW', '$_FOCUS_RELEASE_SELECTION', sprintplanningrhs.setReleaseSettingValue, null); }, setReleaseSettingValue : function(response, options) { var r = Ext.decode(response.responseText); sprintplanningrhs.setReleaseValue(r.selection); }, setReleaseValue : function(selection) { var cb = sprintplanningrhs.releaseCombobox; var ret = BxtUserSettings.setComboboxValue( cb, selection); if( (ret == BxtUserSettings.cbNEW)) { if( selection == null || selection == "") { cb.setValue(); sprintplanningrhs.sprintreqDS.removeAll(); } else { sprintplanningrhs.loadSprintRequirements(); } } else if( ret == BxtUserSettings.cbNONE ) { cb.setValue(); sprintplanningrhs.sprintreqDS.removeAll(); } else { cb.setValue(selection); } }, reloadSprintStories : function(sprintId) { sprintplanningrhs.loadSprintRequirements(); sprintplanning.reloadRequirements(); }, loadSPxReleaseTable : function(cbFunction) { if (!cbFunction) cbFunction = null; var projectCtrlId = sprintplanning.projectCombobox.getValue(); var releaseCtrlId = sprintplanningrhs.releaseCombobox.getValue(); sprintplanningrhs.sprintreqDS.load({ waitMsg:'$LOADING', params:{ start:0, limit:50, userid:'$currentUserId', releaseid : releaseCtrlId, spxprojectid: projectCtrlId, spxreleaseid: releaseCtrlId }, callback: cbFunction }); }, loadSprintRequirements : function() { var releaseId = sprintplanningrhs.releaseCombobox.getValue(); sprintplanningrhs.loadSPxReleaseTable(sprintplanningrhs.onLoadSprints); }, onLoadSprints : function(rec, option, success) { if(!success) { BxtUtil.showErrorMsg(SPRHSLabels.LOAD_ERROR); sprintplanningrhs.sprintreqDS.removeAll(); } else { sprintplanningrhs.drawSprintInfoBars(); } }, drawSprintInfoBars: function() { sprintplanningrhs.calculateSprintMetrics();//first calculate var light_green_color = '#E1F5D0'; var green_color = '#39A340'; var green_image = '../common/system/images/CapacityGradientStretch.jpg'; var light_red_color = '#F4B6B6'; var red_color = '#FF0000'; var red_image = '../common/system/images/CapacityGradientRedStretch.jpg'; var black_color = '#000000'; var template = "" + "" + "" + "
" + ""+ " "+ ""+ ""+ ""+ " "+ //""+ ""+ ""+ ""+ " "+ ""+ ""+ ""+ "
" + " REMAIN SP" + "
"; var arr = sprintplanningrhs.sprintMetricsMap; for (i = 0; i < arr.length; i++) { var sprintid = arr[i].sprintid ; var actual = 0; actual = arr[i].actual ; var planned = arr[i].planned ; var remain = arr[i].remain ; var actual_percent = 0; if(planned != null && planned != undefined && planned != "") { actual_percent = (actual / planned) * 100.0; } else { actual_percent = 100; remain = 0 - actual; } var remain_percent = 100.0 - actual_percent; var sprintbar = template.replace(/REMAIN/,remain); if (remain < 0) { sprintbar = sprintbar.replace(/BAR_IMAGE/g, red_image); sprintbar = sprintbar.replace(/BACKGROUND_COLOR/g, light_red_color); sprintbar = sprintbar.replace(/TEXT_COLOR/g, red_color); } else{ sprintbar = sprintbar.replace(/BAR_IMAGE/g, green_image); sprintbar = sprintbar.replace(/BACKGROUND_COLOR/g, light_green_color); sprintbar = sprintbar.replace(/TEXT_COLOR/g, green_color); } sprintbar = sprintbar.replace(/A_PERCENT/g,actual_percent); sprintbar = sprintbar.replace(/R_PERCENT/g,remain_percent); document.getElementById(sprintid).innerHTML = sprintbar; } }, calculateSprintMetrics: function(){ sprintplanningrhs.sprintMetricsMap = new Array(); var ds = sprintplanningrhs.sprintreqDS; var arr = sprintplanningrhs.sprintMetricsMap; for (i = 0; i < ds.getCount(); i++) { var rec = ds.getAt(i); var sprintid = rec.get('sprintid'); var index = -1; for (j = 0; j < arr.length; j++) { if(arr[j].sprintid == sprintid) { index = j; break; } } index = (index == -1) ? arr.length: index; if (arr[index] == null) { arr[index]= new Array(); arr[index].actual = 0; arr[index].remain = 0; } arr[index].sprintid = sprintid; arr[index].status = rec.get('status'); arr[index].startdate = rec.get('startdate'); arr[index].enddate = rec.get('enddate'); arr[index].planned = rec.get('plannedcapacity'); //calculate actual and remaining var actual = arr[index].actual; var isReqRow = (rec.get('dummy') == '0') ? 1 : 0; if (isReqRow) { if (rec.get('size') != undefined && rec.get('size') != null && rec.get('size') != "") { var act = 0; act = rec.get('size'); actual = actual + act; } } //actual arr[index].actual = actual; //remain var planned = arr[index].planned; var remain = (planned != undefined && planned != null) ? (planned - actual):0; arr[index].remain = remain; } }, refreshSprint : function() { sprintplanningrhs.loadSprintRequirements(); }, //used by watir commitStory : function(storyid,sprintid) { var sourceds = sprintplanning.gridCtrl.getStore(); var destds = sprintplanningrhs.gridCtrl.getStore(); var paramString = ''; var rankArray = new Array(1); var indexArray = new Array(1); rankArray[0] = '9999'; var destIndex = 0; var destRecord; var bSrcfound = false; var bDestfound = false; for(var i=0; i < sourceds.getCount(); i++) { var rec = sourceds.getAt(i); var story_id = rec.get('id'); if(storyid == story_id ) { indexArray[0] = i; paramString = story_id + "," + rankArray[0]; bSrcfound = true; } } for(var i=0; i < destds.getCount(); i++) { var rec = destds.getAt(i); var sprint_id = rec.get('sprintid'); var isReqRow = (rec.get('dummy') == '0') ? 1 : 0; var reqId = rec.get('id'); if(sprintid == sprint_id ) { if(reqId == '-' || isReqRow) { destIndex = i; destRecord = rec; bDestfound = true; } } } if(bSrcfound && bDestfound ) { sprintplanningrhs.updateRankPositionRR(indexArray, rankArray, destIndex, paramString, destRecord) ; } return; } };