const executionDropdownMap = new Map();
/**
* 计算表格计划信息的统计。
* Set plan summary for table footer.
*
* @param element element
* @param array checkedIDList
* @access public
* @return object
*/
window.setStatistics = function(element, checkedIDList, pageSummary)
{
if(!checkedIDList.length) return {html: pageSummary, className: 'text-dark'};
let total = checkedIDList.length;
let totalParent = 0;
let totalChild = 0;
let totalIndependent = 0;
const rows = element.layout.allRows;
rows.forEach((row) => {
if(checkedIDList.length == 0 || checkedIDList.includes(row.id))
{
const plan = row.data;
if(plan.parent > 0) totalChild ++;
if(plan.parent == 0 && plan.isParent) totalParent ++;
}
});
totalIndependent = total - totalParent - totalChild;
let summary = checkedSummary.replace('%total%', total);
summary = summary.replace('%parent%', totalParent);
summary = summary.replace('%child%', totalChild);
summary = summary.replace('%independent%', totalIndependent);
return {html: summary};
}
window.showExecution = function(target, executionList)
{
if(executionDropdownMap.has(target)) return;
let executionItems = new Array();
executionList.forEach(function(execution, index)
{
const link = $.createLink('execution', 'task', `executionID=${execution.id}`);
executionItems.push({text: execution.name, url: link});
});
const dropdown = new zui.Dropdown($(target), {
arrow: true,
placement: 'right',
menu: {items: executionItems},
});
executionDropdownMap.set(target, dropdown);
}
window.renderProductPlanList = function(result, {col, row, value})
{
if(col.name === 'execution')
{
if(result[0].length === 0) return [];
if(result[0].length === 1)
{
const link = $.createLink('execution', 'task', `executionID=${result[0][0].id}`);
result[0] = {html: ''};
return result;
}
result[0] = {html: ``};
}
return result;
}
window.startProductPlan = function(planID)
{
zui.Modal.confirm({message: confirmStart, icon:'icon-exclamation-sign', iconClass: 'warning-pale rounded-full icon-2x'}).then((res) =>
{
if(res) $.ajaxSubmit({url: $.createLink('productplan', 'start', 'planID=' + planID)});
});
}
window.finishProductPlan = function(planID)
{
zui.Modal.confirm({message: confirmFinish, icon:'icon-exclamation-sign', iconClass: 'warning-pale rounded-full icon-2x'}).then((res) =>
{
if(res) $.ajaxSubmit({url: $.createLink('productplan', 'finish', 'planID=' + planID)});
});
}
window.activateProductPlan = function(planID)
{
zui.Modal.confirm({message: confirmActivate, icon:'icon-exclamation-sign', iconClass: 'warning-pale rounded-full icon-2x'}).then((res) =>
{
if(res) $.ajaxSubmit({url: $.createLink('productplan', 'activate', 'planID=' + planID)});
});
}
window.deleteProductPlan = function(planID)
{
zui.Modal.confirm({message: confirmDelete, icon:'icon-exclamation-sign', iconClass: 'warning-pale rounded-full icon-2x'}).then((res) =>
{
if(res) $.ajaxSubmit({url: $.createLink('productplan', 'delete', 'planID=' + planID)});
});
}
$(document).off('click', '.batch-btn').on('click', '.batch-btn', function()
{
const dtable = zui.DTable.query($(this).target);
const checkedList = dtable.$.getChecks();
if(!checkedList.length) return;
const url = $(this).data('url');
const form = new FormData();
checkedList.forEach((id) => form.append('planIdList[]', id));
if($(this).hasClass('ajax-btn'))
{
$.ajaxSubmit({url, data: form});
}
else
{
postAndLoadPage(url, form);
}
});
$(document).on('click', '[data-target="#createExecutionModal"]', function()
{
const planID = $(this).data('plan') ? $(this).data('plan') : $(this).closest('.dtable-cell').data('row');
$('#createExecutionModal [name=planID]').val(planID);
const productID = plans[planID].product;
const branch = plans[planID].branch;
const link = $.createLink('productplan', 'ajaxGetProjects', `productID=${productID}&branch=${branch}`);
$.getJSON(link, function(projects)
{
const $projectPicker = $('#createExecutionModal [name=project]').zui('picker');
$projectPicker.render({items: projects, disabled: projects.length == 0});
$('.projectTips').toggleClass('hidden', projects.length != 0);
$projectPicker.$.setValue('');
if(projects.length > 0)
{
$('#createExecutionModal .createExecutionBtn').attr('id', 'createExecutionButton');
$('#createExecutionModal .createExecutionBtn').attr('href', '###');
$('#createExecutionModal .createExecutionBtn').text(nextStep);
}
else
{
$('#createExecutionModal .createExecutionBtn').attr('id', '');
$('#createExecutionModal .createExecutionBtn').attr('href', $.createLink('product', 'project', `status=all&productID=${productID}&branch=${branch}`));
$('#createExecutionModal .createExecutionBtn').text(enterProjectList);
}
})
});
$(document).on('click', '#createExecutionButton', function()
{
const projectID = $('input[name=project]').val();
const planID = $('input[name=planID]').val();
openUrl($.createLink('execution', 'create', 'projectID=' + projectID + '&executionID=©ExecutionID=&planID=' + planID + '&confirm=&productID=' + productID), {'app': 'execution'});
zui.Modal.hide('#createExecutionModal');
});
/**
* 对部分列进行重定义。
* Redefine the partial column.
*
* @param array result
* @param array info
* @access public
* @return string|array
*/
window.renderCell = function(result, info)
{
if(info.col.name == 'execution')
{
const projects = info.row.data.projects;
const projectCount = projects.length;
if(projectCount == 0) return result;
if(projectCount == 1)
{
result[0] = {html: ''};
}
else
{
let contentHtml = "
";
projects.forEach((project) => {
contentHtml += `- ${project.name}
`;
});
contentHtml += "
";
let content = {html: contentHtml};
content = JSON.stringify(content);
content = content.replace(/"/g, '"');
const buttonHtml = ``;
result[0] = {html: buttonHtml};
}
}
if(info.col.name == 'title')
{
html = '';
if(info.row.data.parent > 0) html += "" + childrenAB + "";
if(html) result.unshift({html});
html = '';
if(info.row.data.expired && ['wait', 'doing'].includes(info.row.data.status)) html += '' + expiredLang + '';
if(html) result.push({html});
}
return result;
}
$(document).on('click', '.switchButton', function()
{
const type = $(this).data('type');
$.cookie.set('viewType', type, {expires:config.cookieLife, path:config.webRoot});
loadCurrentPage();
})
window.getCol = function(col)
{
col.subtitle = {html: "" + col.cards + ""};
}
window.getItem = function(info)
{
if(info.item.delay && ['wait', 'doing'].includes(info.item.status))
{
info.item.suffix = productplanLang.expired;
info.item.suffixClass = 'label danger rounded-xl' + (info.item.status == 'doing' ? ' mr-8' : '');
}
info.item.icon = 'delay';
info.item.titleAttrs = {'class': 'text-black clip', 'title' : info.item.title, 'data-app': currentTab};
info.item.content = {html: info.item.desc};
info.item.contentClass = 'text-gray';
info.item.footer = {html: "" + info.item.statusLabel + "" + info.item.dateLine + "
"};
if(privs.canViewPlan) info.item.titleUrl = $.createLink('productplan', 'view', `id=${info.item.id}`);
}
window.canDrop = function(dragInfo, dropInfo)
{
if(!dragInfo) return false;
const column = this.getCol(dropInfo.col);
const lane = this.getLane(dropInfo.lane);
if(!column || !lane) return false;
if(dropInfo.type == 'item') return false;
if(dragInfo.item.lane != lane.name) return false;
if(dragInfo.item.status == 'wait' && dropInfo.col == 'doing') return privs.canStartPlan;
if(dragInfo.item.status == 'wait' && dropInfo.col == 'closed') return privs.canClosePlan;
if(dragInfo.item.status == 'doing' && dropInfo.col == 'done') return privs.canFinishPlan;
if(dragInfo.item.status == 'doing' && dropInfo.col == 'closed') return privs.canClosePlan;
if(dragInfo.item.status == 'done' && dropInfo.col == 'doing') return privs.canActivatePlan;
if(dragInfo.item.status == 'done' && dropInfo.col == 'closed') return privs.canClosePlan;
if(dragInfo.item.status == 'closed' && dropInfo.col == 'doing') return privs.canActivatePlan;
return false;
}
window.onDrop = function(changes, dropInfo)
{
const item = dropInfo['drag']['item'];
const toCol = dropInfo['drop']['col'];
if(item.status == 'wait' && toCol == 'doing')
{
zui.Modal.confirm(productplanLang.confirmStart).then(result =>
{
if(result)
{
const url = $.createLink('productplan', 'start', 'planID=' + item.id)
$.ajaxSubmit({url});
this.update(changes);
}
});
return false;
}
else if(item.status == 'doing' && toCol == 'done')
{
zui.Modal.confirm(productplanLang.confirmFinish).then(result =>
{
if(result)
{
const url = $.createLink('productplan', 'finish', 'planID=' + item.id)
$.ajaxSubmit({url});
this.update(changes);
}
});
return false;
}
else if((item.status == 'done' || item.status == 'closed') && toCol == 'doing')
{
zui.Modal.confirm(productplanLang.confirmActivate).then(result =>
{
if(result)
{
const url = $.createLink('productplan', 'activate', 'planID=' + item.id)
$.ajaxSubmit({url});
this.update(changes);
}
});
return false;
}
zui.Modal.open({url: $.createLink('productplan', 'close', 'planID=' + item.id), size: 'lg'});
return false;
}
window.getItemActions = function(item)
{
return [{
type: 'dropdown',
icon: 'ellipsis-v',
caret: false,
items: buildCardActions(item),
}];
}
window.buildCardActions = function(item)
{
let actions = [];
if(item.actionList.includes('createExecution')) actions.push({text: productplanLang.createExecution, icon: 'plus', url: '#createExecutionModal', 'data-target': '#createExecutionModal', 'data-toggle': 'modal', 'data-on': 'click', 'data-call': 'getPlanID', 'data-params': 'event', 'data-branch': item.branch, 'data-plan': item.id});
if(item.actionList.includes('linkStory')) actions.push({text: productplanLang.linkStory, icon: 'link', url: $.createLink(rawModule, 'view', "planID=" + item.id + "&type=story&orderBy=id_desc&link=true")});
if(item.actionList.includes('linkBug')) actions.push({text: productplanLang.linkBug, icon: 'bug', url: $.createLink(rawModule, 'view', "planID=" + item.id + "&type=bug&orderBy=id_desc&link=true")});
if(item.actionList.includes('edit')) actions.push({text: productplanLang.edit, icon: 'edit', url: $.createLink(rawModule, 'edit', "planID=" + item.id)});
if(item.actionList.includes('start')) actions.push({text: productplanLang.start, icon: 'start', url: $.createLink('productplan', 'start', "planID=" + item.id), 'data-confirm': productplanLang.confirmStart});
if(item.actionList.includes('finish')) actions.push({text: productplanLang.finish, icon: 'checked', url: $.createLink('productplan', 'finish', "planID=" + item.id), 'data-confirm': productplanLang.confirmFinish});
if(item.actionList.includes('close')) actions.push({text: productplanLang.close, icon: 'off', url: $.createLink('productplan', 'close', "planID=" + item.id), 'data-toggle': 'modal'});
if(item.actionList.includes('activate')) actions.push({text: productplanLang.activate, icon: 'magic', url: $.createLink('productplan', 'activate', "planID=" + item.id), 'data-confirm': productplanLang.confirmActivate});
if(item.actionList.includes('delete')) actions.push({text: productplanLang.delete, icon: 'trash', url: $.createLink('productplan', 'delete', "planID=" + item.id), 'data-confirm': productplanLang.confirmDelete});
return actions;
}
window.getPlanID = function(event)
{
const planID = $(event.target).closest('a').data('plan');
$('[name=planID]').val(planID);
}
window.firstRendered = false;
window.toggleCheckRows = function(idList)
{
if(!idList?.length || firstRendered) return;
firstRendered = true;
this._rendered = true;
const dtable = zui.DTable.query($('#productPlans'));
dtable.$.toggleCheckRows(idList.split(','), true);
}