2023-05-16 10:47:08 +08:00

217 lines
6.6 KiB
JavaScript

/**
* Process kanban data
* @param {string} key Kanban key, used as kanban id
* @param {Object} programGroup Group data
* @returns {Object} kanban data
*/
function processKanbanData(key, programGroup)
{
var kanbanId = key;
/* Generate columns */
var columns = [];
var executionsCol;
$.each(kanbanColumns, function(_, column)
{
var colType = column.type;
column = $.extend({}, column,
{
kanban: kanbanId,
id: kanbanId + '-' + column.type,
parentType: (colType === 'doingProject' || colType === 'doingExecution') ? 'doing' : false,
});
if(colType === 'doingProject')
{
columns.push(
{
kanban: kanbanId,
id: kanbanId + '-doing',
type: 'doing',
asParent: true,
name: doingText,
count: ''
});
}
else if(colType === 'doingExecution')
{
executionsCol = column;
executionsCol.count = 0;
}
columns.push(column);
});
/* Format lanes data */
var lanes = [];
$.each(programGroup, function(programId, statusMap)
{
var programName = programPairs[programId];
var items = {doingExecution: []};
/* Projects and executions */
['wait', 'doing', 'closed'].forEach(function(status)
{
var itemsList = [];
var statusProjects = statusMap[status];
if(statusProjects)
{
$.each(statusProjects, function(_, project)
{
var projectID = project.id;
var projectItem = $.extend({}, project, {id: 'project-' + projectID, _id: projectID});
itemsList.push(projectItem);
if(status === 'doing')
{
var execution = latestExecutions[projectID];
if(execution && execution.id)
{
if(typeof(executionsCol) == 'object') executionsCol.count++;
projectItem.execution = $.extend({}, execution, {id: 'execution-' + execution.id, _id: execution.id});
}
}
});
}
items[status + 'Project'] = itemsList;
});
lanes.push({id: programId, kanban: kanbanId, name: programName, items: items});
});
return {id: kanbanId, columns: columns, lanes: lanes};
}
/** Define kanban d-n-d rules */
var projectDropRules =
{
waitProject: ['doingProject', 'closedProject'],
doingProject: ['closedProject'],
closedProject: ['doingProject'],
};
window.kanbanDropRules = {my: projectDropRules, other: projectDropRules};
/*
* Find drop columns
* @param {JQuery} $element Drag element
* @param {JQuery} $root Dnd root element
*/
function findDropColumns($element, $root)
{
var $col = $element.closest('.kanban-col');
var col = $col.data();
var lane = $col.closest('.kanban-lane').data();
var kanbanID = $root.data('id');
var kanbanRules = window.kanbanDropRules ? window.kanbanDropRules[kanbanID] : null;
if(!kanbanRules) return $root.find('.kanban-lane[data-id="' + lane.id + '"] .kanban-lane-col:not([data-type="doingExecution"],[data-type="' + col.type + '"])');
var colRules = kanbanRules[col.type];
var lane = $col.closest('.kanban-lane').data('lane');
return $root.find('.kanban-lane-col').filter(function()
{
if(!colRules) return false;
if(colRules === true) return true;
var $newCol = $(this);
var newCol = $newCol.data();
if(newCol.id === col.id) return false;
var $newLane = $newCol.closest('.kanban-lane');
var newLane = $newLane.data('lane');
return colRules.indexOf(newCol.type) > -1 && newLane.id === lane.id;
});
}
/**
* Change column type for a card
* @param {Object} card Card object
* @param {String} fromColType The column type before change
* @param {String} toColType The column type after change
* @param {String} kanbanID Kanban ID
*/
function changeCardColType(card, fromColType, toColType, kanbanID)
{
if(typeof card == 'undefined') return false;
var cardID = card.id;
var projectID = cardID.substr(cardID.indexOf("-") + 1);;
var showIframe = false;
if(toColType == 'doingProject')
{
if(fromColType == 'waitProject' && priv.canStart)
{
var link = createLink('project', 'start', 'project=' + projectID, '', true);
showIframe = true;
}
if(fromColType == 'closedProject' && priv.canActivate)
{
var link = createLink('project', 'activate', 'projectID=' + projectID, '', true);
showIframe = true;
}
}
else if(toColType == 'closedProject')
{
if(priv.canClose)
{
var link = createLink('project', 'close', 'projectID=' + projectID, '', true);
showIframe = true;
}
}
if(showIframe)
{
var modalTrigger = new $.zui.ModalTrigger({type: 'iframe', width: '80%', url: link});
modalTrigger.show();
}
}
/**
* Handle finish drop task
* @param {Object} event Event object
* @returns {void}
*/
function handleFinishDrop(event)
{
var $card = $(event.element).closest('.kanban-item'); // The drag card
var $dragCol = $card.closest('.kanban-lane-col');
var $dropCol = $(event.target);
/* Get d-n-d(drag and drop) infos. */
var card = $card.data('item');
var fromColType = $dragCol.data('type');
var toColType = $dropCol.data('type');
var kanbanID = $card.closest('.kanban').data('id');
changeCardColType(card, fromColType, toColType, kanbanID);
}
/** Calculate column height */
function calcColHeight(col, lane, colCards, colHeight)
{
if (col.type !== 'doingProject') return colHeight;
return colCards.length * 62;
}
$(function()
{
/* Init all kanbans */
$.each(kanbanGroup, function(key, programGroup)
{
var $kanban = $('#kanban-' + key);
if(!$kanban.length) return;
$kanban.kanban(
{
data: processKanbanData(key, programGroup),
calcColHeight: calcColHeight,
virtualize: true,
virtualCardList: true,
droppable:
{
selector: '.kanban-card:not(.execution-item)',
target: findDropColumns,
finish: handleFinishDrop
},
});
});
});