Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <title>Task Board</title>
- <link type="text/css" rel="stylesheet" href="__SERVER_URL__/js-lib/yui/2.6.0/build/reset-fonts-grids/reset-fonts-grids.css" />
- <link type="text/css" rel="stylesheet" href="__SERVER_URL__/css/toolkit/0.02/renderer.css" />
- <link type="text/css" rel="stylesheet" href="__SERVER_URL__/css/toolkit/0.02/grid.css" />
- <link type="text/css" rel="stylesheet" href="__SERVER_URL__/css/toolkit/0.02/editor.css" />
- <link type="text/css" rel="stylesheet" href="__SERVER_URL__/css/toolkit/0.02/toolkit.css" />
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/yui.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/toolkit.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/date.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/modal.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/html.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/connection.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/grid.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02.1/renderer/renderer.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/editor.js"></script>
- <script type="text/javascript" src="__SERVER_URL__/js/toolkit/0.02/datasource.js"></script>
- <script type="text/javascript" src="/apps/1.33/sdk.js?apiVersion=1.29"></script>
- <!-- <script type="text/javascript" src="/apps/2.0rc1/sdk.js"></script> -->
- <script type="text/javascript" src="/slm/js-lib/async/async.min.js"></script>
- <script type="text/javascript">
- // aqui tentamos preservar o scroll do iframe, para não perder de vista o objeto que modificamos
- // só funcionou com um delay bem grande... a tabela demora a carregar
- window.onload = function() {
- if(window.localStorage && localStorage.panelScrollTop) {
- setTimeout("document.body.scrollTop = localStorage.panelScrollTop;", 3000);
- }
- }
- window.onunload = function() {
- if(window.localStorage) {
- localStorage.panelScrollTop = document.body.scrollTop;
- }
- }
- var defaultTasks = [
- "Adicionar link ao documento da review",
- "Aplicar mudanças na JSP",
- "Analisar o problema",
- "Corrigir o problema",
- "Aplicar correção em produção via FIX",
- "Adicionar correção ao código",
- "Criar branch",
- "Criar cenários de testes",
- "Criar layout",
- "Montar mockup HTML",
- "Revisão de código",
- "Validação de HTML",
- "Validação de QA"
- ];
- function showDefaultTasks() {
- var w = parent.editorWindow;
- if(w.location === null) return false;
- _showDefaultTasksCounter = window._showDefaultTasksCounter || 0;
- try {
- var elem = w.document.getElementById('edit_header') || false;
- if(!elem) {
- if(++_showDefaultTasksCounter <= 10) setTimeout(showDefaultTasks, 1000);
- return false;
- }
- } catch(e) {
- if(++_showDefaultTasksCounter <= 10) setTimeout(showDefaultTasks, 1000);
- }
- var sel = w.document.createElement('select');
- sel.innerHTML = '<select id="default-tasks"><option>Tarefas comuns...</option><option>' + defaultTasks.join('</option><option>') + '</option></select>';
- sel.style.cssText = 'position: absolute; top: 2px; right: 45px;';
- sel.onchange = function() {
- var ind = this.selectedIndex, input = w.document.querySelector('#formContent tr:nth-child(3) input');
- if(ind == 0) return false;
- input.value = this.options[ind].innerHTML;
- sel.selectedIndex = 0;
- };
- elem.parentNode.insertBefore(sel, elem);
- _showDefaultTasksCounter = 0;
- }
- function showText(a) {
- closeText();
- var txt = a.nextSibling.innerHTML;
- var parent = a.parentNode.parentNode;
- var box = document.createElement('div');
- box.className = 'show-info';
- box.innerHTML = '<a class="closetxt" href="javascript://" onclick="closeText()"></a>'+txt;
- parent.appendChild(box);
- var links = box.getElementsByTagName('a');
- for(var i = 0; i < links.length; i++) {
- links[i].target = '_blank';
- }
- }
- function closeText() {
- var boxes = document.querySelectorAll('.show-info');
- for(var i = 0; i < boxes.length; i++) {
- boxes[i].parentNode.removeChild(boxes[i]);
- }
- }
- function deleteStory(ID, name, formatID) {
- if(!confirm('Tem certeza que quer excluir a User Story '+formatID+': '+name+'?\n\nNão será possível desfazer esta ação.')) return false;
- top.deleteAR({
- itemOid: ID,
- name: name,
- formattedID: formatID,
- msg: '',
- directChildrenCount: '0'
- });
- };
- function deleteTask(ID, name, formatID) {
- if(!confirm('Tem certeza que quer excluir a Task '+formatID+': '+name+'?\n\nNão será possível desfazer esta ação.')) return false;
- top.deleteAR({
- itemOid: ID,
- name: name,
- formattedID: formatID,
- msg: '',
- directChildrenCount: '0'
- });
- };
- function createStory() {
- top.Rally.nav.Manager.create('userstory',{Iteration:'/iteration/' + document.getElementById('change_iteration_control').value});
- };
- function createTask(objectID) {
- rally.sdk.util.Navigation.popupCreatePage('task', {workProduct: objectID});
- showDefaultTasks();
- };
- function editObject(objectType, objectID) {
- rally.sdk.util.Navigation.popupEditPage("/" + objectType + "/" + objectID);
- };
- function toggle(id) {
- var elem = Dom.get(id);
- elem.style.display = elem.style.display == 'none' ? 'block' : 'none';
- };
- function filterByType() {
- var types = document.getElementsByName('filter_product_type'), prefixes = [];
- for(var i = 0; i < types.length; i++) {
- if(types[i].checked) prefixes.push(types[i].value);
- }
- selectedTypes = '(' + prefixes.join('|') + ')';
- RALLY.toolkit.Cookie.add('selectedProductTypes', selectedTypes);
- var ths = document.querySelectorAll('.rally-grid-row-header');
- for(var i = 0; i < ths.length; i++) {
- var tr = Dom.getAncestorByTagName(ths[i], 'tr'),
- prefix = ths[i].querySelector('.id > a[target="_blank"]').innerHTML.substr(0,2);
- if(prefixes.length > 0) {
- if(new RegExp(selectedTypes).test(prefix)) tr.className = '';
- else tr.className = 'hidden';
- } else {
- tr.className = '';
- }
- if(tr.className == '' && Dom.get('hide_empty_lines').checked) {
- var tasks = tr.querySelectorAll('.rally-grid-cell .rally-task'), visible = 0;
- for(var it = 0; it < tasks.length; it++) {
- if(tasks[it].className.indexOf('hidden') < 0) visible++;
- }
- if(visible == 0) tr.className = 'hidden';
- }
- }
- }
- function filterTasksByOwner(owner) {
- var users = document.getElementsByName('filter_usernames'), usernames = [];
- for(var i = 0; i < users.length; i++) {
- if(users[i].checked) usernames.push(users[i].value);
- }
- selectedOwners = usernames.join('|');
- RALLY.toolkit.Cookie.add('selectedOwners', selectedOwners);
- var tasks = document.querySelectorAll('.rally-grid-cell .rally-task');
- for(var i = 0; i < tasks.length; i++) {
- var owner = tasks[i].querySelector('.owner').innerHTML;
- if(selectedOwners && selectedOwners.indexOf(owner) < 0) {
- Dom.addClass(tasks[i], 'hidden');
- } else {
- Dom.removeClass(tasks[i], 'hidden');
- }
- }
- filterByType();
- }
- function hideEmptyStories(show) {
- var ths = document.querySelectorAll('.rally-grid-row-header');
- for(var i = 0; i < ths.length; i++) {
- var tr = Dom.getAncestorByTagName(ths[i], 'tr');
- if(show) { Dom.removeClass(tr, 'hidden'); continue; }
- var tasks = tr.querySelectorAll('.rally-grid-cell .rally-task'), visible = 0;
- for(var it = 0; it < tasks.length; it++) {
- var cn = tasks[it].className;
- if(cn.indexOf('hidden') < 0) visible++;
- }
- if(visible == 0) {
- Dom.addClass(tr, 'hidden');
- }
- }
- filterByType();
- }
- // users selection
- function getHoveredUserIndex() {
- var labels = Dom.get('filter_user_list').querySelectorAll('li.visible label');
- //console.log(labels);
- for(var i = 0; i < labels.length; i++) {
- if(labels[i].className.indexOf('hover') >= 0) return Number(labels[i].parentNode.getAttribute('data-index'));
- }
- return -1;
- }
- function getVisibleIndexes() {
- var labels = Dom.get('filter_user_list').querySelectorAll('li.visible label'), ret = [];
- for(var i = 0; i < labels.length; i++) {
- var ind = Number(labels[i].parentNode.getAttribute('data-index'));
- ret[ret.length] = ind;
- }
- return ret;
- }
- function changeHoveredUser(dir) {
- var visible = getVisibleIndexes(),
- sel = getHoveredUserIndex(),
- index = inArray(visible, sel),
- nIndex;
- //console.log('visible, sel, index -> ', visible, sel, index);
- if(dir == 'up') {
- if(index <= 0) nIndex = visible.length - 1;
- else nIndex = index - 1;
- } else {
- if(1 + index >= visible.length) nIndex = 0;
- else nIndex = index + 1;
- }
- setHoveredUser(visible[nIndex]);
- }
- function inArray(arr, val) {
- for(var i = 0; i < arr.length; i++) {
- if(arr[i] == val) return i;
- }
- return -1;
- }
- function selectHoveredUser() {
- //console.log('selectHoveredUser');
- var sel = getHoveredUserIndex();
- if(sel < 0) return false;
- Dom.get('filter_user_list').getElementsByTagName('input')[sel].click();
- }
- function setHoveredUser(index) {
- //console.log('setHoveredUser: ', index);
- var labels = Dom.get('filter_user_list').getElementsByTagName('label');
- for(var i = 0; i < labels.length; i++) {
- Dom.removeClass(labels[i], 'hover');
- }
- if(index >= 0 && labels[index].parentNode.className.indexOf('hidden') >= 0) {
- }
- if(index >= 0 && labels[index].parentNode.className.indexOf('hidden') < 0) {
- Dom.addClass(labels[index], 'hover');
- labels[index].scrollIntoView();
- document.body.scrollTop = 0;
- }
- }
- function translateInfo() {
- var info = Dom.get('info').innerHTML.split('<br>'), timearr = info[1].split(/,* /);
- var months = {
- January: 'janeiro',
- February: 'fevereiro',
- March: 'março',
- April: 'abril',
- May: 'maio',
- June: 'junho',
- July: 'julho',
- August: 'agosto',
- September: 'setembro',
- October: 'outubro',
- November: 'novembro',
- December: 'dezembro'
- };
- var days = {
- Sunday: 'Domingo',
- Monday: 'Segunda',
- Tuesday: 'Terça',
- Wednesday: 'Quarta',
- Thursday: 'Quinta',
- Friday: 'Sexta',
- Saturday: 'Sábado',
- };
- Dom.get('info').innerHTML = info[0] + '<br>' + days[timearr[0]] + ', ' + timearr[2] + ' de ' + months[timearr[1]] + ' de ' + timearr[3];
- }
- function initTaskboard() {
- RALLY.toolkit.HTML.createMaskLayer();
- var statusDiv = null;
- var setStatus = function(msg) {
- if (!statusDiv) {
- statusDiv = Dom.get('status');
- }
- if (msg) {
- RALLY.toolkit.HTML.enableMask(null, 0);
- Dom.addClass(window.document.body, 'show-progress');
- } else {
- RALLY.toolkit.HTML.disableMask();
- Dom.removeClass(window.document.body, 'show-progress');
- }
- statusDiv.innerHTML = msg || '';
- }
- var insideRally = RALLY.toolkit.insideRally();
- var showActuals = false;
- var currentProjectOid = '__PROJECT_OID__';
- var projectScopeUp = '__PROJECT_SCOPING_UP__' == 'true';
- var projectScopeDown = '__PROJECT_SCOPING_DOWN__' == 'true';
- // use this to rebuild the full query, stitching in the
- // project scoping information from the top-level variables above
- function getQuery() {
- var scoping = "&project=${currentProject}&projectScopeUp=" + projectScopeUp + "&projectScopeDown=" + projectScopeDown;
- var paging = "&pagesize=100";
- return {
- "currentProject" : "/iteration:current/project",
- "#storyType" : "/typedefinition?query=(Name = \"Hierarchical Requirement\")",
- "taskUnit" : "${iteration/workspace/workspaceConfiguration/taskUnitName}",
- "storyStates" : "${#storyType/attributes[name=schedule state]/allowedvalues/stringvalue}",
- "iteration" : "/iteration:current?fetch=name,objectid&order=StartDate",
- "iterations" : "/iterations?fetch=name,objectid&order=StartDate,Name&project=${currentProject}&projectScopeUp=false&projectScopeDown=false" + paging,
- "users" : "/users?fetch=displayname,loginname,emailaddress,objectid" + paging,
- "tasks" : "/tasks?fetch=description,notes,taskindex,name,objectid,formattedid,owner,blocked,estimate,todo,actuals,state,workproduct&query=(Iteration = ${iteration})" + scoping + paging,
- "stories" : "/hierarchicalrequirement?fetch=description,notes,rank,blocked,formattedid,name,objectid,owner,project,schedulestate,taskestimatetotal,taskremainingtotal,taskactualtotal,PlanEstimate,tasks&order=Rank&query=(Iteration = ${iteration})" + scoping + paging,
- "defects" : "/defect?fetch=description,notes,rank,blocked,formattedid,name,objectid,owner,project,schedulestate,taskestimatetotal,taskremainingtotal,taskactualtotal&order=Rank&query=(Iteration = ${iteration})" + scoping + paging,
- "defectsuite" : "/defectsuite?fetch=rank,blocked,formattedid,name,objectid,owner,project,schedulestate,taskestimatetotal,taskremainingtotal,taskactualtotal&order=Rank&query=(Iteration = ${iteration})" + scoping + paging,
- "testsets" : "/testset?fetch=rank,blocked,formattedid,name,objectid,owner,project,schedulestate,taskestimatetotal,taskremainingtotal,taskactualtotal&query=(Iteration = ${iteration})" + scoping + paging
- };
- }
- var query = getQuery();
- var renderTimeCell = function(label, value, c) {
- var v = (Lang.isValue(value)) ? value : '-';
- return '<div class="' + c + '"><div>' + label + '</div><span>' + v + '</span></div>';
- };
- var projScopeUpControl = Dom.get('proj_scope_up_control');
- var projScopeDownControl = Dom.get('proj_scope_down_control');
- if (insideRally) {
- Dom.setStyle(Dom.get('project'), 'display', 'none');
- } else {
- projScopeUpControl.checked = projectScopeUp;
- projScopeDownControl.checked = projectScopeDown;
- var updateAfterScopeChange = function(e) {
- var src = Event.getTarget(e);
- if(src.id == 'proj_scope_up_control') {
- projectScopeUp = src.checked;
- }
- else if(src.id == 'proj_scope_down_control') {
- projectScopeDown = src.checked;
- }
- query = getQuery();
- RALLY.toolkit.showMessage('Refreshing iteration with selected project scoping');
- gridController.display();
- };
- Event.addListener(projScopeUpControl, 'click', updateAfterScopeChange);
- Event.addListener(projScopeDownControl, 'click', updateAfterScopeChange);
- }
- var viewConfig = {
- // configure columns
- columnAttribute: "State",
- columnValuesAccessor: function(model, modelSchema) {
- var stateOptions = modelSchema.Task.State.options;
- var stateNames = [];
- for(var i = 0, length = stateOptions.length; i < length; i++) {
- stateNames.push(stateOptions[i].Value);
- }
- return stateNames;
- },
- columnHeaderRenderer: function(container, value) {
- container.innerHTML = value;
- },
- // configure rows
- rowAttribute: "WorkProduct",
- rowKeyAccessor: function(workProduct) {return workProduct.ObjectID;},
- rowValuesAccessor: function(model, modelSchema) {
- return model.items[0].workProducts;
- },
- rowHeaderRenderer: function(container, value, modelSchema) {
- var state,
- html = [],
- schema = modelSchema.WorkProduct,
- owner,
- ownerClass = ['owner'],
- divId = 'rally-workprod-' + value.ObjectID,
- divClass = ['rally-workprod'],
- timeClass = ['rally-time'];
- // owner could be an object literal, or a string (if the user has been deleted in the app)
- if (!value.Owner) {
- ownerClass.push('de-emphasis');
- owner = gridController.noOwnerLabel;
- } else if (Lang.isObject(value.Owner)) {
- owner = value.Owner._refObjectName;
- } else {
- ownerClass.push('de-emphasis deleted-owner');
- owner = value.Owner;
- }
- if (value.ScheduleState == 'Accepted') {
- divClass.push('rally-workprod-accepted');
- divClass.push('de-emphasis');
- } else if (value.TaskRemainingTotal=='' || value.TaskRemainingTotal==0) {
- timeClass.push('de-emphasis');
- }
- html.push('<div class="' + divClass.join(' ') + '" id="' + divId + '">');
- state = new RALLY.toolkit.renderer.StateRenderer({
- schema: schema.State,
- state: value.ScheduleState,
- blocked: value.Blocked
- });
- html.push('<div class="state">' + state.display(false, value.ScheduleState=='Accepted') + '</div>');
- var detail_type = 'ar';
- if( /^DE/.test( value.FormattedID ) ) {
- detail_type = 'df';
- }
- var _type = value._type.toLowerCase();
- html.push('<div class="id">');
- html.push('<a href="/slm/detail/' + detail_type + '/' + value.ObjectID + '" title="Visualizar história" target="_blank">' + value.FormattedID + '</a> | ');
- html.push('<a href="javascript://" title="Editar história" onclick="editObject(\'' + _type + '\',' + value.ObjectID + '); return false;" class="edit-story"></a> | ');
- html.push('<a class="add-task" href="javascript://" title="Adicionar tarefa" onclick="createTask(' + value.ObjectID + '); return false;"></a>');
- html.push('</div>');
- html.push('<a class="delete-story" href="javascript://" title="Remover história" onclick="deleteStory(' +
- value.ObjectID + ', \'' + value.Name + '\', \'' + value.FormattedID + '\'); return false;"></a>');
- if(value.PlanEstimate) html.push('<div class="planestimate">' + value.PlanEstimate + '</div>');
- html.push('<div class="name">' + RALLY.toolkit.niceSubstring(value.Name, 100) + '</div>');
- html.push('<div class="' + ownerClass.join(' ') + '">' + owner + '</div>');
- if(value.Description) html.push('<div class="desc"><a onclick="showText(this)" href="javascript://">Description</a><div style="display:none">' + value.Description + '</div></div>');
- if(value.Notes) html.push('<div class="notes"><a onclick="showText(this)" href="javascript://">Notes</a><div style="display:none">' + value.Notes + '</div></div>');
- html.push( renderTimeCell((schema.TaskEstimateTotal) ? schema.TaskEstimateTotal.DisplayName : 'Est', value.TaskEstimateTotal, timeClass.join(' ')) );
- html.push( renderTimeCell((schema.TaskRemainingTotal) ? schema.TaskRemainingTotal.DisplayName : 'To Do', value.TaskRemainingTotal, timeClass.join(' ')) );
- if (showActuals) {
- html.push( renderTimeCell((schema.TaskActualTotal) ? schema.TaskActualTotal.DisplayName : 'Actuals', value.TaskActualTotal, timeClass.join(' ')) );
- }
- html.push('<div class="clear"></div>');
- html.push('</div>');
- container.innerHTML = html.join('');
- },
- // configure cells
- cellSortFunction: function(a,b) { return a - b; },
- // configure items
- itemRankAccessor: function(item) { return item.TaskIndex },
- itemKeyAccessor: function(item) { return item.ObjectID },
- itemsAccessor: function(model) {
- return model.items[0].tasks;
- },
- itemRenderer: function(container, item, modelSchema) {
- var html = [],
- owner,
- taskClass = ['rally-task'],
- ownerClass = ['owner'],
- estClass = ['rally-time'],
- todoClass = ['rally-time'],
- actClass = ['rally-time'],
- schema = modelSchema.Task,
- contentStyle = '',
- editIconId = 'edit-' + Dom.generateId(),
- deleteIconId = 'delete-' + Dom.generateId();
- // owner could be an object literal, or a string (if the user has been deleted in the app)
- if (!item.Owner) {
- ownerClass.push('de-emphasis');
- owner = gridController.noOwnerLabel;
- } else if (Lang.isObject(item.Owner)) {
- owner = item.Owner._refObjectName;
- } else {
- ownerClass.push('de-emphasis deleted-owner');
- owner = item.Owner;
- }
- if (item.Blocked) {
- taskClass.push('rally-task-blocked');
- }
- if (item.State == 'Defined') {
- todoClass.push('de-emphasis');
- actClass.push('de-emphasis');
- } else if (item.State == 'Completed') {
- todoClass.push('de-emphasis');
- }
- if (item.WorkProduct && item.WorkProduct.ScheduleState == 'Accepted') {
- taskClass.push('rally-task-accepted');
- taskClass.push('de-emphasis');
- }
- html.push('<div class="' + taskClass.join(' ') + '" id="rally-task-' + item.ObjectID + '">');
- if (item.Owner && Lang.isValue(item.Owner.ObjectID)) {
- // if there is an image, we need to pad the content to account for it
- contentStyle = 'margin-left: 70px';
- html.push('<div class="image">');
- html.push('<img id="edit-control" src="' + RALLY.toolkit.Connection.getServerURL() + '/profile/viewThumbnailImage.sp?tSize=60&uid=' + item.Owner.ObjectID + '" alt="" />');
- html.push('</div>');
- }
- html.push('<div style="' + contentStyle + '">');
- var _type = item._type.toLowerCase();
- html.push('<div class="id">');
- html.push('<a href="/slm/detail/tk/' + item.ObjectID + '" target="_blank" title="Visualizar tarefa">' + item.FormattedID + '</a>');
- html.push(' | <a href="javascript://" class="edit-task" title="Editar em nova janela" onclick="editObject(\'' + _type + '\',' + item.ObjectID + '); return false;"></a>');
- html.push(' | <a id="' + editIconId + '" href="javascript://" class="short-edit-task" title="Editar tarefa"></a>');
- html.push('</div>');
- html.push('<a href="javascript://" class="delete-task" title="Remover tarefa" onclick="deleteTask(' +
- item.ObjectID + ', \'' + item.Name + '\', \'' + item.FormattedID + '\'); return false;"></a>');
- html.push('<div class="name">' + RALLY.toolkit.niceSubstring(item.Name) + '</div>');
- if(item.Notes) {
- //html.push('<a href="javascript://" class="view-notes" title="Ver anotações" onclick="return false;">Notas</a>');
- html.push('<div class="notes"><a onclick="showText(this)" href="javascript://">Notes</a><div style="display:none">' + item.Notes + '</div></div>');
- }
- html.push('<div class="' + ownerClass.join(' ') + '">' + owner + '</div>');
- html.push('<div class="time">');
- html.push( renderTimeCell((schema.Estimate) ? schema.Estimate.ShortName : 'Est', item.Estimate, estClass.join(' ')) );
- html.push( renderTimeCell((schema.ToDo) ? schema.ToDo.ShortName : 'To Do', item.ToDo, todoClass.join(' ')) );
- if (showActuals) {
- html.push( renderTimeCell((schema.Actuals) ? schema.Actuals.ShortName : 'Actuals', item.Actuals, actClass.join(' ')) );
- }
- html.push('<div class="clear"></div>');
- html.push('</div>');
- html.push('</div>');
- if (item.Blocked) {
- html.push('<img class="blocked-icon" src="' + RALLY.toolkit.Connection.getServerURL() + '/images/icon_blocked.gif" alt="Blocked" />');
- html.push('<div class="clear"></div>');
- }
- html.push('</div>');
- container.innerHTML = html.join('');
- Event.purgeElement(editIconId);
- Event.addListener(editIconId, 'click', function(e) {
- gridController.showEditor(item, schema);
- });
- },
- // configure drag event
- dragDropCallback: function(item, value) {
- setStatus('Saving changes...');
- var cell = this.getRenderedItem(item);
- if (cell) {
- var anim = new YAHOO.util.ColorAnim(cell, { backgroundColor: { from: '#F5F4CD', to: '#fff' } });
- anim.animate();
- }
- gridController.saveChanges(item, { 'State': value }, 'taskboard', function() {
- setStatus();
- });
- }
- };
- RALLY.toolkit.Controller = function(query, viewConfig) {
- this.query = query;
- this.schemaConfig = {};
- this.viewConfig = viewConfig;
- this.dataSource = new RALLY.toolkit.TaskboardDataSource(query, '__SERVER_URL__');
- this.view = new RALLY.toolkit.Grid('taskboard', this.viewConfig);
- this.editor = new RALLY.toolkit.Editor();
- };
- RALLY.toolkit.Controller.prototype = {
- acceptedCookieKey: 'taskboard-hide-accepted',
- ownerCookieKey: 'taskboard-filter-by-owner',
- iterationCookieKey: 'taskboard-filter-by-iteration',
- projectOidCookieKey:'taskboard-current-project',
- noOwnerLabel: 'No Owner',
- allOwnersLabel: 'All Team Members',
- getIterationByOid: function(objectID) {
- for (var i = 0; i < this.iterations.length; i++) {
- if (this.iterations[i].ObjectID == objectID) {
- return this.iterations[i];
- }
- }
- return null;
- },
- display: function(iterationOid) {
- var len, iterations, selectedIteration,
- html = [],
- that = this,
- itr = (iterationOid) ? iterationOid : RALLY.toolkit.Cookie.get(this.iterationCookieKey) || '',
- projectOid = RALLY.toolkit.Cookie.get(this.projectOidCookieKey),
- curProjectOid = (currentProjectOid!='') ? currentProjectOid : null;
- // if our selcted project has changed, reset the iteration ObjectID in the cookie
- if (projectOid != curProjectOid) {
- itr = '';
- RALLY.toolkit.Cookie.remove(this.iterationCookieKey);
- }
- RALLY.toolkit.Cookie.add(this.projectOidCookieKey, curProjectOid);
- // re-write the query to scope to the specified iteration
- if (itr) {
- query.iteration = "/iterations?fetch=name,objectid&order=StartDate&query=(ObjectID = " + itr + ")";
- } else {
- query.iteration = "/iteration:current?fetch=name,objectid&order=StartDate";
- }
- setStatus('Loading...');
- if (this.dataSource) {
- this.dataSource.get(function(model) {
- var i;
- that.hideAcceptedControl = Dom.get('hide_accepted_control');
- that.iterationSelect = Dom.get('change_iteration_control');
- // clear out the grid container and any state-dependant vars
- YAHOO.util.Dom.get('taskboard').innerHTML = '';
- that.users = [];
- YAHOO.util.Event.removeListener(that.hideAcceptedControl, 'click');
- YAHOO.util.Event.removeListener(that.iterationSelect, 'change');
- if (model.errors.length > 0) {
- html.push('<ul>');
- for (i = 0, len = model.errors.length; i < len; i++) {
- html.push('<li>' + model.errors[i].message + '</li>');
- }
- html.push('</ul>');
- RALLY.toolkit.showError(html.join(''));
- setStatus();
- return;
- } else if (model.items.length == 0 || (model.items.length == 1 && model.items[0].iteration == null)) {
- RALLY.toolkit.showError('There are no stories to display in the selected project');
- setStatus();
- return;
- }
- // add in the header info
- Dom.get('proj_name').innerHTML = model.items[0].project.Name;
- Dom.get('info').innerHTML = (model.items[0].iteration.Name || '') + '<br/>' + (RALLY.Date.formatNow());
- // build the iteration select
- selectedIteration = RALLY.toolkit.Cookie.get(that.iterationCookieKey);
- iterations = model.items[0].iterations;
- that.iterations = model.items[0].iterations;
- RALLY.toolkit.HTML.clearSelect(that.iterationSelect);
- for (i = 0, len = iterations.length; i < len; i++) {
- that.iterationSelect.options[that.iterationSelect.options.length] = new Option(iterations[i].Name, iterations[i].ObjectID);
- if (iterations[i].ObjectID == selectedIteration || iterations[i].Name == model.items[0].iteration.Name) {
- RALLY.toolkit.Cookie.add(that.iterationCookieKey, iterations[i].ObjectID);
- that.iterationSelect.selectedIndex = i;
- }
- }
- Event.removeListener(that.iterationSelect, 'change');
- Event.addListener(that.iterationSelect, 'change', that.updateIteration, that, true);
- if (model.items[0].tasks.length == 0 && model.items[0].workProducts.length == 0) {
- RALLY.toolkit.showError('There are no stories to display for the given iteration');
- setStatus();
- return;
- }
- // filtrar por tipo
- var selectedTypes = RALLY.toolkit.Cookie.get('selectedProductTypes');
- var selectedOwners = RALLY.toolkit.Cookie.get('selectedOwners');
- var productTypes = {}, prods = model.items[0].workProducts;
- for(var curId in prods) {
- var curType = prods[curId]._type, curPrefix = prods[curId].FormattedID.substr(0,2);
- if(curType == 'HierarchicalRequirement') curType = 'UserStory'; // corrigindo o nome, que curiosamente é 'HierarchicalRequirement'
- if(typeof productTypes[curType] == 'undefined') productTypes[curType] = curPrefix;
- }
- var count = 0, cbwrap = Dom.get('filter_product');
- for(var ptName in productTypes) {
- var cleanName = ptName.replace(/([a-z])([A-Z])/, '$1 $2');
- var cbox = document.createElement('input');
- cbox.type = 'checkbox';
- cbox.name = 'filter_product_type';
- cbox.id = 'filter_product_type'+count;
- cbox.value = productTypes[ptName];
- if(selectedTypes && new RegExp(selectedTypes).test(productTypes[ptName])) {
- cbox.checked = true;
- }
- var label = document.createElement('label');
- label.appendChild(cbox);
- label.appendChild(document.createTextNode(' '+cleanName));
- cbwrap.appendChild(label);
- cbox.onclick = filterByType;//AndUser;
- count++;
- }
- // build the grid
- that.view.display(model);
- // should we hide accepted work?
- if (RALLY.toolkit.Cookie.get(that.acceptedCookieKey)=='true' || RALLY.toolkit.Cookie.get(that.acceptedCookieKey)==null) {
- that.hideAcceptedControl.checked = true;
- that.toggleAccepted();
- }
- Event.removeListener(that.hideAcceptedControl, 'click');
- Event.addListener(that.hideAcceptedControl, 'click', that.toggleAccepted, that, true);
- // add users into the select that were found during the rendering
- //that.refreshUserSelect();
- // colocar usuarios na lista
- that.refreshUserList();
- // atualiza os checkboxes
- filterByType();
- filterTasksByOwner();
- translateInfo();
- // select users
- Event.addListener(document.body, 'mousedown', function(ev) {
- var wrap = Dom.get('filter_users'), box = Dom.get('filter_users_wrap');
- if(wrap == ev.target || Dom.isAncestor(wrap, ev.target)) return true;
- box.style.display = 'none';
- });
- // select users
- Event.addListener(Dom.get('search_users'), 'keyup', function(ev) {
- if(ev.keyCode == 27) { // Esc
- toggle('filter_users_wrap');
- }
- if(ev.keyCode == 39) { // seta direita
- selectHoveredUser();
- return true;
- }
- if(ev.keyCode == 38 || ev.keyCode == 40) { // setas up / down
- var dir = ev.keyCode == 38 ? 'up' : 'down';
- changeHoveredUser(dir);
- return false;
- }
- var term = this.value.toLowerCase(), lis = Dom.get('filter_user_list').getElementsByTagName('li');
- for(var i = 0; i < lis.length; i++) {
- if(term == '') {
- Dom.removeClass(lis[i], 'hidden');
- Dom.addClass(lis[i], 'visible');
- continue;
- }
- var val = lis[i].getElementsByTagName('label')[0].innerHTML.replace(/<[^>]+>/g, '').replace(/^\s*|\s*$/g, '').toLowerCase();
- if(val.substr(0, term.length) == term) {
- Dom.removeClass(lis[i], 'hidden');
- Dom.addClass(lis[i], 'visible');
- } else {
- Dom.addClass(lis[i], 'hidden');
- Dom.removeClass(lis[i], 'visible');
- }
- }
- });
- Event.addListener(Dom.get('hide_empty_lines'), 'click', function() { hideEmptyStories(!this.checked); });
- // marcar todos os usuarios
- Event.addListener(Dom.get('checkall'), 'click', function() {
- if(this.checked) {
- var inputs = Dom.getAncestorByTagName(this, 'ul').getElementsByTagName('input');
- for(var i = 1; i < inputs.length; i++) {
- inputs[i].checked = false;
- inputs[i].parentNode.className = '';
- }
- filterTasksByOwner();
- }
- });
- setStatus();
- }, query);
- }
- },
- showEditor: function(item, schema) {
- var editorConfig = {
- props: (showActuals) ? ['Estimate', 'ToDo', 'Actuals', 'Owner', 'State'] : ['Estimate', 'ToDo', 'Owner', 'State'],
- propertyKeyAccessors: {
- Owner: function(prop) { return prop != null ? prop.LoginName : null; }
- },
- propertyValueAccessors: {
- Owner: function(prop) { return prop != null ? prop._refObjectName : null; }
- },
- titleAccessor: function(obj) { return obj.FormattedID + '<br/>' + obj.Name; },
- onErrorCallback: function() { gridController.display(); },
- onSaveCallback: function(changes) { gridController.saveChanges(item, changes, 'editor'); }
- };
- console.log(item, schema, editorConfig)
- this.editor.display(item, schema, editorConfig);
- },
- getParentRow: function(el) {
- while (el && el.tagName && el.tagName.toUpperCase()!='TR') { el = el.parentNode; }
- return el;
- },
- toggleAccepted: function() {
- var i, len, row,
- hideAcceptedControl = this.hideAcceptedControl || Dom.get('hide_accepted_control'),
- //userSelect = this.userSelect || Dom.get('filter_user_control'),
- hideAccepted = hideAcceptedControl.checked,
- workProds = Dom.getElementsByClassName('rally-workprod-accepted');
- RALLY.toolkit.Cookie.add(this.acceptedCookieKey, hideAccepted);
- for (i = 0, len = workProds.length; i < len; i++) {
- row = this.getParentRow(workProds[i]);
- if (hideAccepted) {
- Dom.addClass(row, 'accepted');
- } else {
- Dom.removeClass(row, 'accepted');
- }
- }
- /*if (hideAccepted && this.numItemsVisible() == 0) {
- if (userSelect.selectedIndex >= 0 && userSelect.options[userSelect.selectedIndex].value == this.allOwnersLabel) {
- RALLY.toolkit.showWarning('The selected iteration contains only accepted stories');
- } else {
- RALLY.toolkit.showWarning('The selected owner has only accepted stories and/or tasks');
- }
- }*/
- },
- refreshUserList: function() {
- var selectedOwners = (RALLY.toolkit.Cookie.get('selectedOwners') || ''),
- users = this.getOwnersOnTaskboard(),
- list = Dom.get('filter_user_list'),
- count = 0;
- list.innerHTML = '<li class="visible"><label><input id="checkall" type="checkbox" value="all" data-index="0"> Todos</label></li>';
- users.sort(function(a,b) { return (a.toLowerCase() < b.toLowerCase()) ? -1: 1; });
- for(var i = 0; i < users.length; i++) {
- var cleanName = users[i];
- var label = document.createElement('label');
- var cbox = document.createElement('input');
- cbox.type = 'checkbox';
- cbox.name = 'filter_usernames';
- cbox.id = 'filter_usernames'+count;
- cbox.value = cleanName;
- if(selectedOwners && selectedOwners.indexOf(cleanName) >= 0) {
- label.className = 'checked';
- cbox.checked = true;
- }
- label.appendChild(cbox);
- label.appendChild(document.createTextNode(' '+ cleanName));
- var li = document.createElement('li');
- li.className = 'visible';
- li.setAttribute('data-index', String(i+1));
- li.appendChild(label);
- list.appendChild(li);
- cbox.onclick = function() {
- Dom[this.checked ? 'addClass' : 'removeClass'](this.parentNode, 'checked'); Dom.get('checkall').checked = false;
- filterTasksByOwner();
- };
- label.onmouseover = function() {
- setHoveredUser(-1);
- };
- count++;
- }
- },
- saveChanges: function(item, changes, source, successCallback) {
- var that = this, i, len, html = [], error, isConcurrencyError;
- if (!Lang.isValue(source)) {
- source = 'taskboard';
- }
- // set to-do to 0
- if(changes.State == "Completed") { changes.ToDo = "0"; }
- // always include _objectVersion
- if (!changes._objectVersion) {
- changes._objectVersion = item._objectVersion;
- }
- if (this.dataSource) {
- this.dataSource.update(item, changes, function(model) {
- if (model.OperationResult.Errors.length == 0) {
- that.refreshItem(item);
- that.editor.close();
- if (successCallback) {
- successCallback();
- }
- } else {
- html.push('<ul>');
- for (i = 0, len = model.OperationResult.Errors.length; i < len; i++) {
- error = model.OperationResult.Errors[i];
- if (error.toLowerCase().indexOf('concurrency conflict') != -1 || error.toLowerCase().indexOf('could not read') != -1) {
- isConcurrencyError = true;
- }
- error = that.parseSaveErrorsIntoReadableString(error);
- if (error) {
- html.push('<li>' + error + '</li>');
- }
- }
- html.push('</ul>');
- if (source == 'editor') {
- that.editor.displayError(html.join(''), isConcurrencyError);
- } else {
- RALLY.toolkit.showWarning('The task you have drag-n-dropped has been modified by another user.<br/>Refreshing task board state.');
- that.display();
- }
- }
- });
- }
- },
- parseSaveErrorsIntoReadableString: function(error) {
- var matches, tmp;
- // what type of error did we get back?
- if (error.toLowerCase().indexOf('concurrency conflict') != -1) {
- error = 'Item was modified by another user';
- } else if (error.toLowerCase().indexOf('could not read') != -1) {
- error = 'Item was deleted by another user';
- } else if (error.toLowerCase().indexOf('could not convert') != -1) {
- // let's try and strip some of the nastyness out of this message
- matches = error.match(/could not convert: (.*)/i);
- if (matches && matches.length > 1) {
- error = matches[1];
- }
- error = error.replace('double', 'number');
- } else if (error.toLowerCase().indexOf('validation error') != -1) {
- matches = error.match(/validation error: .* ([a-z]+) >= 0 is an invalid numeric/i);
- if (matches && matches.length > 1) {
- tmp = matches[1].toLowerCase();
- // ignore these rollup fields
- if (tmp == 'taskestimatetotal' || tmp == 'taskremainingtotal') {
- return null;
- }
- error = '"' + tmp.substr(0,1).toUpperCase() + tmp.substr(1) + '" must be non-negative';
- }
- }
- return error;
- },
- deleteItem: function(task) {
- var that = this;
- if (task) {
- this.dataSource.remove(task, function(model) {
- if (model.OperationResult.Errors.length == 0) {
- that.view.removeItem(task);
- if(RALLY.toolkit.insideRally() && parent && parent.RALLY) {
- parent.RALLY.util.showDeleteFlair({
- oid: task.ObjectID,
- record: task,
- recordName : task.FormattedID + ': ' + task.Name,
- restorable : true
- });
- }
- that.dataSource.refreshWorkProduct(task.WorkProduct, function(newWorkProduct) {
- that.view.refreshRowHeader(newWorkProduct);
- // that.refreshUserSelect();
- that.refreshUserList();
- });
- } else {
- RALLY.toolkit.showError('There was an error deleting the task');
- // rebuild the task board to get back to a consistent state
- that.updateIteration();
- }
- });
- }
- },
- refreshItem: function(item) {
- var that = this;
- if (item) {
- this.dataSource.refreshTask(item, function(model) {
- that.view.refreshItem(model.items[0].tasks[0]);
- //that.refreshUserSelect();
- that.refreshUserList();
- that.view.refreshRowHeader(model.items[0].workProducts[0]);
- });
- }
- },
- getOwnersOnTaskboard: function() {
- var i, len, div, ownerMap = {}, owners = [], items = this.view.findItems();
- for (i = 0, len = items.length; i < len; i++) {
- div = Dom.getElementsByClassName('owner', 'div', items[i])[0];
- if (div && div.innerHTML != this.noOwnerLabel && !Dom.hasClass(div, 'deleted-owner')) {
- ownerMap[div.innerHTML] = 1;
- }
- }
- for (i in ownerMap) {
- owners.push(RALLY.toolkit.HTML.unescapeXMLEntities(i));
- }
- return owners;
- },
- numItemsVisible: function() {
- var i, len, items, num = 0;
- var comparator = function(el) {
- try { return Dom.hasClass(el, 'rally-task') || Dom.hasClass(el, 'rally-workprod'); } catch (e) {}
- return false;
- };
- items = this.view.findItems(comparator);
- for (i = 0, len = items.length; i < len; i++) {
- if ( !(Dom.hasClass(items[i], 'hidden') || Dom.hasClass(this.getParentRow(items[i]), 'accepted') || Dom.hasClass(this.getParentRow(items[i]), 'hidden')) ) {
- num++;
- }
- }
- return num;
- },
- filterByOwner: function() {
- var i, len, that = this, shown = 0, shownAccepted = 0, itemMap = {}, rows = [], items, item,
- sel = this.userSelect || Dom.get('filter_user_control'),
- selected = sel.options[sel.selectedIndex];
- RALLY.toolkit.Cookie.add(this.ownerCookieKey, selected.innerHTML);
- var buildComparator = function(owner) {
- return function(item) {
- try {
- return owner.innerHTML == that.allOwnersLabel || YAHOO.util.Dom.getElementsByClassName('owner', 'div', item)[0].innerHTML == owner.innerHTML;
- } catch (e) {}
- return false;
- };
- };
- var isTask = function(o) { return Dom.hasClass(o, 'rally-task'); };
- var isWorkProd = function(o) { return Dom.hasClass(o, 'rally-workprod'); };
- var isParentVisible = function(el) {
- for (var i = 0, len = rows.length; i < len; i++) {
- if (rows[i] == el) { return true; }
- }
- };
- items = this.view.findItems(buildComparator(selected));
- for (i = 0, len = items.length; i < len; i++) {
- item = items[i];
- if (isTask(item)) {
- itemMap[item.id] = 1;
- rows.push(this.getParentRow(item));
- } else if (isWorkProd(item)) {
- rows.push(this.getParentRow(item));
- }
- }
- items = this.view.findItems();
- for (i = 0, len = items.length; i < len; i++) {
- item = items[i];
- if (isTask(item)) {
- if (typeof itemMap[item.id] == 'undefined') {
- Dom.addClass(item, 'hidden');
- } else {
- if (this.hideAcceptedControl.checked && Dom.hasClass(item, 'rally-task-accepted')) {
- shownAccepted++;
- } else {
- shown++;
- }
- Dom.removeClass(item, 'hidden');
- }
- } else if (isWorkProd(item)) {
- item = this.getParentRow(item);
- if (isParentVisible(item)) {
- if (this.hideAcceptedControl.checked && Dom.hasClass(item, 'hidden')) {
- shownAccepted++;
- } else {
- shown++;
- }
- Dom.removeClass(item, 'hidden');
- } else {
- Dom.addClass(item, 'hidden');
- }
- }
- }
- if (shown == 0 && shownAccepted > 0) {
- RALLY.toolkit.showWarning('The selected owner has only accepted stories and/or tasks');
- }
- if ((shown+shownAccepted) == 0) {
- RALLY.toolkit.showWarning('The selected owner does not own any stories or tasks');
- }
- },
- updateIteration: function() {
- var sel = this.iterationSelect,
- selected = sel.options[sel.selectedIndex];
- RALLY.toolkit.Cookie.add(this.iterationCookieKey, selected.value);
- this.display(selected.value);
- }
- };
- var config = (query.adHocQuery) ? query : { adHocQuery: query };
- config.integrationInfo = {};
- config.integrationInfo.Name = "Mashup: Taskboard";
- config.integrationInfo.Version = "2009.5";
- config.integrationInfo.Vendor = "Rally Software";
- var gridController = new RALLY.toolkit.Controller(config, viewConfig);
- gridController.display();
- }
- YAHOO.util.Event.addListener(window, 'load', initTaskboard);
- </script>
- <style type="text/css">
- /** Customize the default grid styles **/
- body {
- font-family: tahoma,geneva,helvetica,arial,sans-serif;
- }
- .rally-grid-item {
- border: 0;
- }
- .rally-grid-item-content {
- margin: 0;
- }
- .rally-grid-column-header {
- padding: .2em;
- }
- /** Custom styles for this implementation **/
- #wrapper {
- margin: .8em;
- }
- #header {
- border-bottom: 2px solid #666;
- padding: .2em .3em;
- margin-bottom: .4em;
- }
- #header #title {
- float: left;
- text-align: left;
- }
- #header #title h3 {
- font-weight: bold;
- font-size: 1.6em;
- }
- #header #info {
- float: right;
- text-align: right;
- }
- .clear {
- clear: both;
- height: 0;
- }
- .hidden, .accepted {
- display: none;
- visibility: hidden;
- height: 0;
- }
- .de-emphasis {
- color: #999;
- }
- .rally-time {
- float: left;
- width: 58px;
- margin: .1em;
- padding: .1em;
- font-size: .8em;
- font-weight: normal;
- text-align: center;
- border: 1px solid #bbb;
- }
- .rally-time div {
- border-bottom: 1px solid #ccc;
- }
- /** work products **/
- .rally-workprod {
- margin: .5em;
- font-size: .9em;
- font-weight: normal;
- }
- .rally-workprod .id {
- clear: left;
- }
- .rally-workprod .name {
- font-size: 1.3em;
- padding-bottom: .5em;
- }
- .rally-workprod .owner {
- margin-bottom: .5em;
- }
- /** tasks **/
- .rally-task {
- padding: .8em;
- font-size: .9em;
- text-align: left;
- border: 1px solid #999;
- }
- .rally-task .name {
- font-size: 1.3em;
- margin-bottom: .5em;
- }
- .rally-task .owner {
- margin-bottom: .5em;
- }
- .rally-task .image {
- float: left;
- }
- .rally-task .actions {
- float: right;
- position: relative;
- top: -0.3em;
- right: -0.3em;
- }
- .rally-task .actions img {
- display: block;
- margin-bottom: .4em;
- cursor:pointer;
- }
- .rally-task .rally-time {
- width: 45px;
- }
- .rally-task-blocked {
- border: 1px solid #f00;
- }
- .rally-task-blocked img.blocked-icon {
- float: right;
- position: relative;
- bottom: -0.3em;
- right: -0.3em;
- }
- .rally-task-accepted {
- background-color: #ececec;
- border: 1px solid #cbcbcb;
- }
- /** filter bar **/
- #filter {
- width: 100%;
- background-color: #efefdf;
- text-align: left;
- font-size: .9em;
- padding: .2em 0;
- }
- #filter span {
- padding: 0 1em;
- }
- #filter #change_iteration, #filter #filter_user {
- border-right: 1px solid #ccc;
- }
- #filter #proj_scope_up, #filter #proj_scope_down {
- border-left: 1px solid #ccc;
- }
- #project {
- float: right;
- }
- /** status box - displays messages while loading **/
- #status {
- width: 50%;
- text-align: right;
- float: left;
- position: absolute;
- top: 0;
- left: 0;
- font-size: 11px;
- font-style: italic;
- font-weight: bold;
- }
- .show-progress{
- cursor:progress;
- }
- .rally-workprod .id {
- padding: 4px 0;
- }
- .rally-task img,
- .rally-workprod img {
- vertical-align: middle;
- }
- a.closetxt, a.add-task, a.edit-task, a.short-edit-task, a.delete-story, a.edit-story, a.delete-task {
- background: transparent url(https://rally1.rallydev.com/slm/images/sprites.gif) 0 0 no-repeat scroll;
- display: inline-block;
- height: 16px;
- line-height: 16px;
- width: 16px;
- vertical-align: middle;
- }
- a.add-task {
- background-position: 0 -1190px;
- }
- .short-edit-task {
- background-image: url(https://rally1.rallydev.com/slm/images/icon_pencil.gif) !important;
- background-position: 0 0;
- }
- .rally-workprod {
- position: relative;
- }
- a.edit-story,
- a.edit-task {
- background-position: 0 -595px;
- }
- .rally-workprod {
- position: relative;
- }
- a.closetxt {
- background-position: 0 -289px;
- float: right;
- margin: 0 0 5px 5px;
- }
- a.delete-task,
- a.delete-story {
- background-position: 0 -425px;
- position: absolute;
- top: 0;
- right: 0;
- }
- a.delete-task {
- top: 4px;
- right: 4px;
- }
- a.delete-task:hover,
- a.delete-story:hover {
- background-position: 0 -441px;
- }
- .show-info {
- position: absolute;
- top: 0;
- /*left: 101%;*/
- left: 106px;
- width: 450px;
- height: auto;
- border: 1px solid #CCC;
- border-radius: 6px;
- -moz-border-radius: 6px;
- -webkit-border-radius: 6px;
- background-color: #FFF;
- padding: 10px;
- z-index: 10;
- }
- .rally-task .show-info {
- left: -5px;
- top: -5px;
- width: 275px;
- }
- .show-info img {
- max-width: 98%;
- height: auto;
- }
- .appHeaderContainer {
- margin-top: 0px;
- }
- .rally-task {
- position: relative;
- }
- .rally-task-blocked img.blocked-icon {
- float: none;
- position: absolute;
- bottom: 6px;
- right: 6px;
- }
- .planestimate {
- position: absolute;
- top: 0px;
- right: 26px;
- font-size: 22px;
- font-weight: bold;
- }
- #filter label {
- display: inline-block;
- width: auto;
- margin: 0 6px 0 4px;
- }
- #filter input[type="checkbox"] {
- vertical-align: bottom;
- }
- #filter_users {
- position: relative;
- }
- #filter_users_wrap {
- padding: 4px;
- margin-top: 4px;
- border: 1px solid #DDD;
- border-top-width: 0px;
- position: absolute;
- top: 12px;
- left: 0;
- width: 200px;
- height: auto;
- max-height: 230px;
- padding: 0px;
- background-color: #efefdf;
- z-index: 999;
- }
- #search {
- }
- #search_users {
- width: 182px;
- margin: 5px;
- font-size: 12px;
- padding: 2px;
- }
- #filter_user_list_wrap {
- max-height: 190px;
- overflow: auto;
- }
- #filter_user_list {
- margin: 0;
- padding: 0;
- list-style: none;
- list-style-type: none;
- list-style-position: inside;
- }
- #filter_user_list li {
- list-style: none;
- list-style-type: none;
- list-style-position: inside;
- /*display: inline;*/
- }
- #filter_user_list li label {
- display: block;
- padding: 4px 6px;
- }
- #filter_user_list li label:hover,
- #filter_user_list li label.hover {
- background-color: #06F;
- color: #FFF;
- }
- #filter_user_list li label.checked {
- background-color: #95D1EE;
- color: #FFF;
- }
- #filter_user_list li label.checked:hover,
- #filter_user_list li label.checked.hover {
- background-color: #09F;
- color: #FFF;
- }
- #filter_user_list li input {
- }
- </style>
- </head>
- <body>
- <div id="wrapper">
- <div id="status"></div>
- <div id="header">
- <div id="title"><h3>Extra Full Task Board</h3></div>
- <div id="info"></div>
- <div class="clear"></div>
- </div>
- <div id="filter">
- <div id="project">
- <span id="proj_name"></span>
- <span id="proj_scope_up">
- Scope Up:
- <input type="checkbox" id="proj_scope_up_control" />
- </span>
- <span id="proj_scope_down">
- Scope Down:
- <input type="checkbox" id="proj_scope_down_control" />
- </span>
- </div>
- <span id="change_iteration">
- Mostrar sprint:
- <select id="change_iteration_control" size="1"></select>
- </span>
- <span id="hide_accepted">
- <label><input type="checkbox" id="hide_accepted_control" /> Esconder trabalhos finalizados</label>
- </span>
- <span id="hide_accepted">
- <label><input type="checkbox" id="hide_empty_lines" /> Esconder linhas sem tarefas</label>
- </span>
- <span id="filter_product">
- Filtrar por tipo:
- </span>
- <span id="filter_users">
- <a href="javascript://" class="toggle-owner-filter" accesskey="a" onclick="
- toggle('filter_users_wrap'); try { Dom.get('search_users').focus(); } catch(e) {}">Filtrar por autor</a>
- <div id="filter_users_wrap" style="display: none;">
- <div id="search">
- <input type="text" id="search_users" placeholder="Filtrar..." />
- </div>
- <div id="filter_user_list_wrap">
- <ul id="filter_user_list"></ul>
- </div>
- </div>
- </span>
- <span id="add_history">
- <a href="javascript://" onclick="createStory()">Adicionar história</a>
- </span>
- </div>
- <div id="taskboard"></div>
- </div>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement