| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673 |
- $('#kanbanList').on('enterFullscreen', () => {$('#kanbanList > div').css('height', '100%'); window.hideAllAction();});
- $('#kanbanList').on('exitFullscreen', () => {$('#kanbanList > div').css('height', 'calc(100vh - 120px)')});
- searchValue = '';
- const kanbanDropRules =
- {
- story:
- {
- backlog: ['ready', 'backlog'],
- ready: ['backlog', 'ready'],
- tested: ['verified', 'rejected'],
- verified: ['tested', 'pending', 'released'],
- pending: ['verified', 'released'],
- released: ['verified', 'closed'],
- closed: ['released']
- },
- bug:
- {
- 'unconfirmed': ['confirmed', 'fixing', 'fixed'],
- 'confirmed': ['fixing', 'fixed'],
- 'fixing': ['fixed'],
- 'fixed': ['testing', 'tested', 'fixing'],
- 'testing': ['tested', 'closed', 'fixing'],
- 'tested': ['closed', 'fixing'],
- 'closed': ['fixing'],
- },
- task:
- {
- 'wait': ['developing', 'developed', 'canceled'],
- 'developing': ['developed', 'pause', 'canceled'],
- 'developed': ['developing', 'closed'],
- 'pause': ['developing'],
- 'canceled': ['developing', 'closed'],
- 'closed': ['developing'],
- },
- risk:
- {
- 'active': ['track', 'hangup', 'canceled', 'closed'],
- 'track': ['active', 'hangup', 'canceled', 'closed'],
- 'hangup': ['active', 'track', 'canceled', 'closed'],
- 'canceled': ['active', 'track', 'closed'],
- 'closed': ['active', 'track'],
- }
- };
- window.changeBrowseType = function()
- {
- const type = $('.c-type [name=type]').val();
- loadPage($.createLink('execution', 'taskKanban', "executionID=" + executionID + '&type=' + type));
- };
- window.changeGroupBy = function()
- {
- const group = $('.c-group [name=group]').val();
- const type = $('.c-type [name=type]').val();
- loadPage($.createLink('execution', 'taskKanban', 'executionID=' + executionID + '&type=' + type + '&orderBy=order_asc' + '&groupBy=' + group));
- };
- window.changeBugProduct = function()
- {
- const productID = $('[name=productName]').val();
- if(productID) $('#batchCreateBugButton').attr('href', $.createLink('bug', 'batchCreate', 'productID=' + productID + '&branch=&executionID=' + executionID));
- };
- window.changeShowParent = function()
- {
- const showParent = $('[name=showParent]').prop('checked') ? 1 : 0;
- $.cookie.set('showParent', showParent, {expires:config.cookieLife, path:config.webRoot});
- const type = $('.c-type [name=type]').val();
- const group = $('.c-group [name=group]').val();
- let link = $.createLink('execution', 'taskKanban', 'executionID=' + executionID + '&type=' + type);
- if(typeof group != 'undefined') link = $.createLink('execution', 'taskKanban', 'executionID=' + executionID + '&type=' + type + '&orderBy=order_asc' + '&groupBy=' + group);
- loadPage(link);
- };
- window.linkPlanStory = function()
- {
- const planID = $('[name=plan]').val();
- if(planID)
- {
- var param = "¶m=executionID=" + executionID + ",browseType=" + browseType + ",orderBy=id_asc,groupBy=" + groupBy;
- $.ajaxSubmit({url: $.createLink('execution', 'importPlanStories', 'executionID=' + executionID + '&planID=' + planID + '&productID=0&fromMethod=taskKanban&extra=' + param)});
- }
- };
- window.toggleSearchBox = function()
- {
- $('#taskKanbanSearch').toggle();
- if($('#taskKanbanSearch').css('display') == 'block')
- {
- $(".querybox-toggle").css("color", "#0c64eb");
- }
- else
- {
- $(".querybox-toggle").css("color", "#3c495c");
- $('#taskKanbanSearchInput').attr('value', '');
- searchCards('');
- }
- };
- window.getLane = function(lane)
- {
- /* 看板只有一个泳道时,铺满全屏。 */
- if(laneCount < 2) lane.minHeight = window.innerHeight - 235;
- }
- /*
- * 构造看板泳道上的操作按钮。
- * Build action buttons on the kanban lane.
- */
- window.getLaneActions = function(lane)
- {
- return [{
- type: 'dropdown',
- icon: 'ellipsis-v',
- caret: false,
- }];
- }
- window.getCol = function(col)
- {
- /* 计算WIP。*/
- if(['story', 'epic', 'requirement', 'parentStory'].includes(col.group) && ERURColumn.includes(col.type)) return;
- const limit = col.limit == -1 ? "<i class='icon icon-md icon-infinite'></i>" : col.limit;
- const cards = col.cards;
- col.subtitleClass = 'ml-1';
- let wip = `(${cards}/${limit})`;
- if(col.limit != -1 && cards > col.limit)
- {
- col.subtitleClass += ' text-danger';
- wip += ' <i class="icon icon-exclamation-sign" data-toggle="tooltip" data-title="' + kanbanLang.limitExceeded + '"></i>';
- }
- col.subtitle = {html: wip};
- }
- window.getColActions = function(col)
- {
- let actionList = [];
- /* 父列不需要创建卡片相关的操作按钮。 */
- if(col.parent != '-1' && (['backlog', 'unconfirmed', 'wait', 'active'].includes(col.type)))
- {
- let cardActions = buildColCardActions(col);
- if(cardActions.length > 0) actionList.push({type:'dropdown', icon:'expand-alt text-primary', caret:false, items:cardActions});
- if(cardActions.length == 0 && ((col.type == 'backlog' && !priv.canCreateStory && productID == '0') || (col.type == 'unconfirmed' && !priv.canCreateBug && productID == '0'))) actionList.push({icon:'expand-alt text-primary', 'data-on': 'click', 'data-do': "zui.Modal.alert('" + needLinkProducts + "')"});
- }
- actionList.push({type:'dropdown', icon:'ellipsis-v', caret:false, items:buildColActions(col)});
- return actionList;
- }
- /*
- * 构造看板上的创建卡片相关操作按钮。
- * Build create card related action buttons on the kanban.
- */
- window.buildColCardActions = function(col)
- {
- let actions = [];
- if(col.group == 'parentStory') return actions;
- if(col.type == 'backlog')
- {
- if(priv.canCreateStory) actions.push({text: storyLang.create, url:$.createLink('story', 'create', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&objectID=' + executionID), 'data-toggle': 'modal', 'data-size': 'lg'});
- if(priv.canBatchCreateStory) actions.push({text: executionLang.batchCreateStory, url: $.createLink('story', 'batchcreate', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&executionID=' + executionID), 'data-toggle': 'modal', 'data-size': 'lg'});
- if(priv.canLinkStory) actions.push({text: executionLang.linkStory, url: $.createLink('execution', 'linkStory', 'executionID=' + executionID), 'data-toggle': 'modal', 'data-size': 'lg'});
- if(priv.canLinkStoryByPlan) actions.push({text: executionLang.linkStoryByPlan, url: '#linkStoryByPlan', 'data-toggle': 'modal', 'data-size': 'sm'});
- }
- else if(col.type == 'unconfirmed')
- {
- if(priv.canCreateBug) actions.push({text: bugLang.create, url: $.createLink('bug', 'create', 'productID=' + productID + '&moduleID=0&extra=executionID=' + executionID), 'data-toggle': 'modal', 'data-size': 'lg'});
- if(priv.canBatchCreateBug)
- {
- if(productNum > 1) actions.push({text: bugLang.batchCreate, url: '#batchCreateBug', 'data-toggle': 'modal', 'data-size': 'lg'});
- else actions.push({text: bugLang.batchCreate, url: $.createLink('bug', 'batchcreate', 'productID=' + productID + '&moduleID=0&executionID=' + executionID), 'data-toggle': 'modal', 'data-size': 'lg'});
- }
- }
- else if(col.type == 'wait')
- {
- if(priv.canCreateTask) actions.push({text: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID), 'data-toggle': 'modal', 'data-size': 'lg'});
- if(priv.canBatchCreateTask) actions.push({text: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID), 'data-toggle': 'modal', 'data-size': 'lg'});
- if(priv.canImportBug && canImportBug) actions.push({text: executionLang.importBug, url: $.createLink('execution', 'importBug', 'executionID=' + executionID), 'data-toggle': 'modal', 'data-size': 'lg'});
- }
- else if(col.type == 'active')
- {
- if(priv.canCreateRisk) actions.push({text: riskLang.create, url: $.createLink('risk', 'create', 'executionID=' + executionID + '&from=execution'), 'data-toggle': 'modal', 'data-size': 'lg'});
- if(priv.canBatchCreateRisk) actions.push({text: riskLang.batchCreateRisk, url: $.createLink('risk', 'batchcreate', 'executionID=' + executionID + '&from=execution'), 'data-toggle': 'modal', 'data-size': 'lg'});
- }
- return actions;
- }
- /*
- * 构造看板上的创建列、拆分列等操作按钮。
- * Build create column, split column and other action buttons on the kanban.
- */
- window.buildColActions = function(col)
- {
- let actions = [];
- if(priv.canEditName && col.actionList && col.actionList.includes('setColumn')) actions.push({text: kanbanLang.setColumn, url: $.createLink('kanban', 'setColumn', `columnID=${col.id}&executionID=${executionID}&from=RDKanban`), 'data-toggle': 'modal', 'icon': 'edit'});
- if(priv.canSetWIP && col.actionList && col.actionList.includes('setWIP') && !(['story', 'epic', 'requirement', 'parentStory'].includes(col.group) && ERURColumn.includes(col.type))) actions.push({text: kanbanLang.setWIP, url: $.createLink('kanban', 'setWIP', `columnID=${col.id}&executionID=${executionID}&from=RDKanban`), 'data-toggle': 'modal', 'icon': 'alert'});
- return actions;
- }
- /**
- * 渲染卡片内容。
- * Render card content.
- */
- window.getItem = function(info)
- {
- let begin = info.item.begin;
- let end = info.item.end;
- let beginAndEnd = '';
- let assignLink = '';
- let assignedTo = '';
- let avatar = "<span class='avatar rounded-full size-xs ml-1 bg-gray-100 text-canvas' title='" + noAssigned + "'><i class='icon icon-person'></i></span>";
- info.item.originalTitle = info.item.title;
- if(begin < '1970-01-01' && end > '1970-01-01')
- {
- beginAndEnd = end + ' ' + cardLang.deadlineAB;
- }
- else if(end < '1970-01-01' && begin > '1970-01-01')
- {
- beginAndEnd = begin + ' ' + cardLang.beginAB;
- }
- else if(begin > '1970-01-01' && end > '1970-01-01')
- {
- beginAndEnd = formatDate(begin) + ' ~ ' + formatDate(end);
- }
- if(info.item.assignedTo && typeof userList[info.item.assignedTo] != 'undefined')
- {
- user = userList[info.item.assignedTo];
- assignedTo = user.realname;
- userAvatar = user.avatar ? "<img src='" + user.avatar + "' />" : assignedTo.slice(-2).toUpperCase();
- avatar = "<span class='avatar rounded-full size-xs ml-1 primary nowrap' title=" + assignedTo + '>' + userAvatar + '</span>';
- }
- if(info.laneInfo.type == 'story' && priv.canAssignStory) assignLink = $.createLink('story', 'assignto', 'id=' + info.item.id + '&kanbanGroup=default&from=taskkanban');
- if(info.laneInfo.type == 'bug' && priv.canAssignBug) assignLink = $.createLink('bug', 'assignto', 'id=' + info.item.id + '&kanbanGroup=default&from=taskkanban');
- if(info.laneInfo.type == 'risk' && priv.canAssignRisk) assignLink = $.createLink('risk', 'assignto', 'id=' + info.item.id + '&kanbanGroup=default&from=taskkanban');
- if(info.laneInfo.type == 'task' && priv.canAssignTask && info.item.canAssignTo) assignLink = $.createLink('task', 'assignto', 'executionID=' + executionID + '&id=' + info.item.id + '&kanbanGroup=default&from=taskkanban');
- if(assignLink)
- {
- avatar = "<a href='" + assignLink + "' data-toggle='modal'>" + avatar + "</a>";
- }
- else if(['parentStory', 'requirement', 'epic'].includes(info.laneInfo.type))
- {
- avatar = '<div class="avatar child-item rounded-full size-xs ml-1" title="' + storyLang.children + '" style="background: #ccc; color: #fff; cursor: pointer;"><i class="icon icon-split"></i></div>';
- }
- if(info.laneInfo.type == 'risk')
- {
- var content = `
- <div class='flex items-center'>
- <span class='text-gray mr-1'>#${info.item.id}</span>
- <span class='pri-${info.item.priLevel}'>${info.item.pri}</span>
- <span class='ml-1'>${info.item.strategy}</span>
- <span class='date ml-1'>${beginAndEnd}</span>
- <div class='flex-1 flex justify-end'>${avatar}</div>
- </div>
- `;
- }
- else
- {
- var content = `
- <div class='flex items-center'>
- <span class='text-gray mr-1'>#${info.item.id}</span>
- <span class='pri-${info.item.pri}'>${info.item.pri}</span>
- <span class='date ml-1'>${beginAndEnd}</span>
- <div class='flex-1 flex justify-end'>${avatar}</div>
- </div>
- `;
- }
- if(searchValue != '')
- {
- info.item.title = info.item.title.replaceAll(searchValue, "<span class='text-danger'>" + searchValue + "</span>");
- info.item.title = {html: info.item.title};
- }
- if(info.laneInfo.type == 'task')
- {
- let label = '';
- if(info.item.isParent == '1')
- {
- label = "<span class='label gray-pale rounded p-0 size-sm whitespace-nowrap'>" + parentAB + "</span> ";
- }
- else if(info.item.parent > 0)
- {
- label = "<span class='label gray-pale rounded p-0 size-sm whitespace-nowrap'>" + childrenAB + "</span> ";
- }
- if(typeof info.item.title == 'string') info.item.title = {html: info.item.title};
- if(label && typeof info.item.title == 'object') info.item.title.html = label + info.item.title.html;
- }
- if(['story', 'epic', 'requirement', 'parentStory'].includes(info.laneInfo.type))
- {
- info.item.titleUrl = $.createLink('execution', 'storyView', `id=${info.item.id}&executionID=${executionID}`);
- }
- else if(info.laneInfo.type == 'task' || info.laneInfo.type == 'bug')
- {
- info.item.titleUrl = $.createLink(info.laneInfo.type, 'view', `id=${info.item.id}`);
- }
- else if(info.laneInfo.type == 'risk')
- {
- info.item.titleUrl = $.createLink(info.laneInfo.type, 'view', `id=${info.item.id}&from=execution`);
- }
- info.item.titleAttrs = {'data-toggle': 'modal', 'data-size': 'lg', 'title': info.item.originalTitle, 'class': 'card-title clip'};
- info.item.content = {html: content};
- if(info.item.color && info.item.color != '#fff') info.item.className = 'color-' + info.item.color.replace('#', '');
- }
- window.getItemActions = function(item)
- {
- const actionList = typeof item.actionList == 'object' ? Object.values(item.actionList) : item.actionList;
- if(actionList.length)
- {
- return [{
- type: 'dropdown',
- icon: 'ellipsis-v',
- caret: false,
- items: buildCardActions(item),
- }];
- }
- }
- window.buildCardActions = function(item)
- {
- let actions = [];
- const actionList = typeof item.actionList == 'object' ? Object.values(item.actionList) : item.actionList;
- actionList.forEach(action =>
- {
- actionMap = {'text': action.label, 'icon': action.icon, 'url': action.url};
- if(typeof(action.confirm) != 'undefined') actionMap['data-confirm'] = action.confirm;
- if(typeof(action.modal) != 'undefined') actionMap['data-toggle'] = 'modal';
- if(typeof(action.size) != 'undefined') actionMap['data-size'] = action.size;
- if(typeof(action.modal) == 'undefined') actionMap['innerClass'] = 'ajax-submit';
- actions.push(actionMap);
- });
- return actions;
- }
- window.canDrop = function(dragInfo, dropInfo)
- {
- if(!dragInfo || $.getFullscreenElement()) return false;
- const fromColumn = this.getCol(dragInfo.col);
- const toColumn = this.getCol(dropInfo.col);
- const lane = this.getLane(dropInfo.lane);
- const laneType = lanePairs[lane.id];
- const fromColType = colPairs[fromColumn.id];
- const toColType = colPairs[toColumn.id];
- if(!fromColumn || !lane) return false;
- if(dragInfo.type == 'item' && dragInfo.item.group == 'task' && dragInfo.item.isParent == '1') return false; // 父任务不可拖动。
- if(priv.canSortCards && dropInfo.type == 'item' && (dropInfo.col != dragInfo.item.col || dropInfo.lane != dragInfo.item.lane)) return false;
- if(!priv.canSortCards && dropInfo.type == 'item') return false;
- /* 卡片可在同组内拖动。 */
- if(dragInfo.lane != dropInfo.lane) return false;
- if(dragInfo.item.group != toColumn.group) return false;
- if(dropInfo.type != 'item')
- {
- if(!canChangeObject) return false;
- let kanbanRules = kanbanDropRules[laneType];
- let colRules = typeof kanbanRules[fromColType] == 'undefined' ? null : kanbanRules[fromColType];
- if(!colRules) return false;
- if(!colRules.includes(toColType)) return false;
- }
- }
- window.onDrop = function(changes, dropInfo)
- {
- if(!dropInfo) return false;
- const toLaneID = dropInfo.drop.lane;
- const toColumn = this.getCol(dropInfo.drop.col);
- const laneType = lanePairs[dropInfo.drag.lane];
- const fromColID = dropInfo.drag.col;
- const toColID = dropInfo.drop.col;
- const fromColType = colPairs[fromColID];
- const toColType = colPairs[toColID];
- const item = dropInfo.drag.item;
- const objectID = item.id;
- let link = '';
- let moveCard = false;
- let laneID = toLaneID;
- if(typeof toColumn.laneName != 'undefined') laneID = toColumn.laneName;
- if(item.col == toColID && item.lane == toLaneID && priv.canSortCards)
- {
- link = $.createLink('kanban', 'sortCard', 'kanbanID=' + executionID + '&laneID=' + laneID + '&columnID=' + toColID + '&cards=' + dropInfo['data']['list'].join(','));
- $.get(link, function(){refreshKanban()})
- return true;
- }
- /* Task lane. */
- if(laneType == 'task')
- {
- if(toColType == 'developed' && (fromColType == 'developing' || fromColType == 'wait') && priv.canFinishTask && typeof item.actionList.finish != 'undefined') link = $.createLink('task', 'finish', 'taskID=' + objectID + '&extra=from=taskkanban');
- if(toColType == 'pause' && fromColType == 'developing' && priv.canPauseTask && typeof item.actionList.pause != 'undefined') link = $.createLink('task', 'pause', 'taskID=' + objectID + '&extra=from=taskkanban');
- if(toColType == 'canceled' && (fromColType == 'developing' || fromColType == 'wait' || fromColType == 'pause') && priv.canCancelTask && typeof item.actionList.cancel != 'undefined') link = $.createLink('task', 'cancel', 'taskID=' + objectID + '&cardPosition=&from=taskkanban');
- if(toColType == 'closed' && (fromColType == 'developed' || fromColType == 'canceled') && priv.canCloseTask) link = $.createLink('task', 'close', 'taskID=' + objectID + '&extra=from=taskkanban');
- if(toColType == 'developing')
- {
- if((fromColType == 'canceled' || fromColType == 'closed' || fromColType == 'developed') && priv.canActivateTask && typeof item.actionList.activate != 'undefined') link = $.createLink('task', 'activate', 'taskID=' + objectID + '&extra=&from=taskkanban');
- if(fromColType == 'pause' && priv.canActivateTask && typeof item.actionList.restart != 'undefined') link = $.createLink('task', 'restart', 'taskID=' + objectID + '&from=taskkanban');
- if(fromColType == 'wait' && priv.canStartTask && typeof item.actionList.start != 'undefined') link = $.createLink('task', 'start', 'taskID=' + objectID + '&extra=from=taskkanban');
- }
- }
- if(laneType == 'bug')
- {
- if(toColType == 'confirmed' && fromColType == 'unconfirmed' && priv.canConfirmBug) link = $.createLink('bug', 'confirm', 'bugID=' + objectID + '&extra=&from=taskkanban');
- if(toColType == 'fixed' && (fromColType == 'fixing' || fromColType == 'confirmed' || fromColType == 'unconfirmed') && priv.canResolveBug) link = $.createLink('bug', 'resolve', 'bugID=' + objectID + '&extra=&from=taskkanban');
- if(toColType == 'closed' && (fromColType == 'testing' || fromColType == 'tested') && priv.canCloseBug) link = $.createLink('bug', 'close', 'bugID=' + objectID + '&extra=&from=taskkanban');
- if(toColType == 'testing' && fromColType == 'fixed') moveCard = true;
- if(toColType == 'tested' && (fromColType == 'fixed' || fromColType == 'testing')) moveCard = true;
- if(toColType == 'fixing')
- {
- if(fromColType == 'confirmed' || fromColType == 'unconfirmed') moveCard = true;
- if((fromColType == 'closed' || fromColType == 'fixed' || fromColType == 'testing' || fromColType == 'tested') && priv.canActivateBug) link = $.createLink('bug', 'activate', 'bugID=' + objectID);
- }
- if(moveCard)
- {
- link = $.createLink('kanban', 'ajaxMoveCard', 'cardID=' + objectID + '&fromColID=' + fromColID + '&toColID=' + toColID + '&fromLaneID=' + laneID + '&toLaneID=' + laneID + '&execitionID=' + executionID + '&browseType=' + browseType + '&groupBy=' + groupBy);
- refreshKanban(link);
- return true;
- }
- }
- if(laneType == 'story')
- {
- if(toColType == 'closed' && priv.canCloseStory) link = $.createLink('story', 'close', 'storyID=' + objectID + '&from=taskkanban');
- if(toColType == 'ready')
- {
- if(item.status == 'draft' || item.status == 'changing' || item.status == 'reviewing')
- {
- zui.Modal.alert(executionLang.storyDragError);
- return false;
- }
- }
- if(!link)
- {
- ajaxMoveCard(objectID, fromColID, toColID, laneID, laneID);
- return true;
- }
- }
- if(laneType == 'risk')
- {
- let params = window.btoa('module=kanban&method=moveRiskCard&objectID=' + objectID + '&fromColID=' + fromColID + '&toColID=' + toColID + '&laneID=' + laneID + '&execution=' + executionID + '&browseType=' + browseType + '&groupBy=' + groupBy);
- if(toColType == 'active' && fromColType == 'track')
- {
- ajaxMoveCard(objectID, fromColID, toColID, laneID, laneID);
- return true;
- }
- if(toColType == 'active' && (fromColType == 'hangup' || fromColType == 'canceled' || fromColType == 'closed') && priv.canActivateRisk) link = $.createLink('risk', 'activate', 'riskID=' + objectID);
- if(toColType == 'track' && fromColType == 'active' && priv.canTrackRisk) link = $.createLink('risk', 'track', 'riskID=' + objectID + '¶ms=' + params);
- if(toColType == 'track' && (fromColType == 'hangup' || fromColType == 'canceled' || fromColType == 'closed') && priv.canTrackRisk) link = $.createLink('risk', 'activate', 'riskID=' + objectID + '¶ms=' + params);
- if(toColType == 'hangup' && (fromColType == 'active' || fromColType == 'track') && priv.canHangupRisk) link = $.createLink('risk', 'hangup', 'riskID=' + objectID);
- if(toColType == 'canceled' && (fromColType == 'active' || fromColType == 'track' || fromColType == 'hangup') && priv.canCancelRisk) link = $.createLink('risk', 'cancel', 'riskID=' + objectID);
- if(toColType == 'closed' && (fromColType == 'active' || fromColType == 'track' || fromColType == 'hangup' || fromColType == 'canceled') && priv.canCancelRisk) link = $.createLink('risk', 'close', 'riskID=' + objectID);
- }
- if(link) zui.Modal.open({url: link});
- return false;
- }
- function formatDate(inputDate)
- {
- const date = new Date(inputDate);
- const formattedDate = `${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getDate().toString().padStart(2, '0')}`;
- return formattedDate;
- }
- window.fullScreen = function()
- {
- var element = document.getElementById('kanbanList');
- var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullscreen;
- if(requestMethod)
- {
- var afterEnterFullscreen = function()
- {
- $('#kanbanList').addClass('fullscreen').css('background', '#fff');
- window.hideAllAction();
- $.cookie.set('isFullScreen', 1, {expires:config.cookieLife, path:config.webRoot});
- };
- var whenFailEnterFullscreen = function()
- {
- exitFullScreen();
- };
- try
- {
- var result = requestMethod.call(element);
- if(result && (typeof result.then === 'function' || result instanceof window.Promise))
- {
- result.then(afterEnterFullscreen).catch(whenFailEnterFullscreen);
- }
- else
- {
- afterEnterFullscreen();
- }
- }
- catch (error)
- {
- whenFailEnterFullscreen(error);
- }
- }
- }
- /**
- * Exit full screen.
- *
- * @access public
- * @return void
- */
- function exitFullScreen()
- {
- $('.btn').show();
- $.cookie.set('isFullScreen', 0, {expires:config.cookieLife, path:config.webRoot});
- $('#kanbanList .card-heading a').each(function(){restoreDiv($(this));});
- $('#kanbanList .avatar').closest('a').each(function(){restoreDiv($(this));});
- }
- function restoreDiv(obj)
- {
- const $this = $(obj);
- const relatedDiv = $this.data('relatedDiv');
- if(relatedDiv)
- {
- relatedDiv.remove();
- $this.show().removeData('relatedDiv');
- }
- }
- document.addEventListener('fullscreenchange', function (e)
- {
- if(!document.fullscreenElement) exitFullScreen();
- });
- document.addEventListener('webkitfullscreenchange', function (e)
- {
- if(!document.webkitFullscreenElement) exitFullScreen();
- });
- document.addEventListener('mozfullscreenchange', function (e)
- {
- if(!document.mozFullScreenElement) exitFullScreen();
- });
- document.addEventListener('msfullscreenChange', function (e)
- {
- if(!document.msfullscreenElement) exitFullScreen();
- });
- window.hideAllAction = function()
- {
- $('.btn').hide();
- $('#kanbanList .card-heading a').each(function(){replaceDiv($(this));});
- $('#kanbanList .avatar').closest('a').each(function(){replaceDiv($(this));});
- }
- function replaceDiv(obj)
- {
- var $this = $(obj);
- var newDiv = $('<div></div>').addClass($this.attr('class')).html($this.html());
- $this.data('relatedDiv', newDiv).before(newDiv).hide();
- }
- /**
- * AJAX: move card.
- *
- * @param int $objectID
- * @param int $fromColID
- * @param int $toColID
- * @param int $fromLaneID
- * @param int $toLaneID
- * @access public
- * @return void
- */
- window.ajaxMoveCard = function(objectID, fromColID, toColID, fromLaneID, toLaneID)
- {
- var link = $.createLink('kanban', 'ajaxMoveCard', 'cardID=' + objectID + '&fromColID=' + fromColID + '&toColID=' + toColID + '&fromLaneID=' + fromLaneID + '&toLaneID=' + toLaneID + '&execitionID=' + executionID + '&browseType=' + browseType + '&groupBy=' + groupBy);
- refreshKanban(link);
- };
- window.debounce = function (callback, delay)
- {
- let timer;
- return function() {
- const context = this;
- const args = arguments;
- clearTimeout(timer);
- timer = setTimeout(function () {
- callback.apply(context, args);
- }, delay);
- };
- };
- $('#taskKanbanSearchInput').on('input', debounce(function(){
- searchCards($(this).val());
- }, 500));
- window.searchCards = function(value, order)
- {
- searchValue = value;
- if(typeof order == 'undefined') order = orderBy;
- refreshKanban($.createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=taskkanban&searchValue=' + value + '&orderBy=' + order));
- };
- window.refreshKanban = function(url)
- {
- if(typeof url == 'undefined') url = $.createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=taskkanban&searchValue=' + searchValue + '&orderBy=' + orderBy);
- const $kanbanList = $('[data-zui-kanbanlist]').zui('kanbanList');
- let options = $kanbanList.options;
- $.getJSON(url, function(data)
- {
- for(const group of data)
- {
- group.getLane = window.getLane;
- group.getCol = window.getCol;
- group.getItem = window.getItem;
- group.canDrop = window.canDrop;
- group.onDrop = window.onDrop;
- group.minColWidth = minColWidth;
- group.maxColWidth = maxColWidth;
- group.colProps = {'actions': window.getColActions};
- group.itemProps = {'actions': window.getItemActions};
- }
- options.items = data;
- $kanbanList.render(options);
- });
- };
- waitDom('.c-group .picker-box .picker-single-selection', function(){this.html(kanbanLang.laneGroup + ': ' + this.attr('title'));});
- $(document).off('click', '#linkStoryByPlan button[type="submit"]').on('click', '#linkStoryByPlan button[type="submit"]', function()
- {
- const planID = $('[name=plan]').val();
- if(planID)
- {
- var param = "¶m=executionID=" + executionID + ",browseType=" + browseType + ",orderBy=id_asc,groupBy=" + groupBy;
- $.ajaxSubmit({url: $.createLink('execution', 'importPlanStories', 'executionID=' + executionID + '&planID=' + planID + '&productID=0&fromMethod=taskKanban&extra=' + param)});
- }
- return false;
- })
|