* task #45145, support to change scale size for execution kanban.
This commit is contained in:
@@ -5,8 +5,8 @@
|
||||
#kanbanList .panel-heading {padding: 10px;}
|
||||
#kanbanList .panel-body {padding: 0 10px 10px;}
|
||||
#kanbanList .kanban {min-height: 120px; overflow: visible;}
|
||||
#kanbanList .kanban-item {border-radius: 2px;}
|
||||
#kanbanList .kanban-item:hover {border: 1px solid #ccc;}
|
||||
#kanbanList .kanban-card {border-radius: 2px; padding: 10px;}
|
||||
#kanbanList .kanban-card:hover {border: 1px solid #ccc;}
|
||||
#kanbanList .kanban-header,
|
||||
#kanbanList .kanban-lane {border-bottom: none; margin-bottom: 0;}
|
||||
#kanbanList .kanban-sub-lane {border-bottom: 0;}
|
||||
@@ -18,45 +18,44 @@
|
||||
#kanbanList .kanban-header + .kanban-lane > .kanban-lane-name {margin-top: 0;}
|
||||
#kanbanList .kanban-header {position: relative;}
|
||||
#kanbanList .kanban-item.link-block {padding: 0;}
|
||||
#kanbanList .kanban-item.link-block > a {padding: 10px; display: block;}
|
||||
#kanbanList .kanban-item > .title {white-space: nowrap; overflow: hidden; text-overflow: clip;}
|
||||
#kanbanList .kanban-item.link-block > a {padding: 10px; display: block;}
|
||||
#kanbanList .kanban-item.has-progress {padding-right: 40px; position: relative;}
|
||||
#kanbanList .kanban-item.has-progress > .progress-pie {position: absolute; right: 7px; top: 7px}
|
||||
#kanbanList .kanban-item.has-left-border {border-left: 2px solid #838a9d;}
|
||||
#kanbanList .kanban-item.has-left-border.border-left-green {border-left-color: #0bd986;}
|
||||
#kanbanList .kanban-item.has-left-border.border-left-red {border-left-color: #ff5d5d;}
|
||||
#kanbanList .kanban-item.has-left-border.border-left-blue {border-left-color: #0991ff;}
|
||||
#kanbanList .kanban-item.link-block a {padding: 10px; display: block;}
|
||||
#kanbanList .kanban-card > .title {white-space: nowrap; overflow: hidden; text-overflow: clip;}
|
||||
#kanbanList .kanban-card.has-progress {padding-right: 40px; position: relative;}
|
||||
#kanbanList .kanban-card.has-progress > .progress-pie {position: absolute; right: 7px; top: 7px}
|
||||
#kanbanList .kanban-card.has-left-border {border-left: 2px solid #838a9d;}
|
||||
#kanbanList .kanban-card.has-left-border.border-left-green {border-left-color: #0bd986;}
|
||||
#kanbanList .kanban-card.has-left-border.border-left-red {border-left-color: #ff5d5d;}
|
||||
#kanbanList .kanban-card.has-left-border.border-left-blue {border-left-color: #0991ff;}
|
||||
#kanbanList .no-flex .kanban-lane > .kanban-sub-lanes[data-sub-lanes-count="1"] > .kanban-sub-lane {min-height: 90px;}
|
||||
#kanbanList .no-flex .kanban-lane > .kanban-sub-lanes[data-sub-lanes-count="2"] > .kanban-sub-lane {min-height: 45px;}
|
||||
|
||||
.kanban-affixed {padding-top: 72px;}
|
||||
.kanban-affixed > .kanban-header {position: fixed!important; top: 0; background: rgba(80,80,80,.9); color: #fff; z-index: 100;}
|
||||
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item {padding: 0;}
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-lane-items {height: 100%; display: flex; flex-direction: column; justify-content: center; padding: 0; overflow: hidden;}
|
||||
#kanbanList .kanban-card.kanban-card-span,
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-card {background-color: transparent; border: none; padding: 0; text-align: center; box-shadow: none!important; margin: 0; height: auto!important;}
|
||||
#kanbanList .kanban-card.kanban-card-span:hover,
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-card:hover {box-shadow: none;}
|
||||
#kanbanList .kanban-card.kanban-card-span > .title,
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-card > .title {white-space: normal; line-height: 1;}
|
||||
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-lane-items {height: 100%; display: flex; flex-direction: column; justify-content: center;}
|
||||
#kanbanList .kanban-item.kanban-item-span,
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item {background-color: transparent; border: none; padding: 0; text-align: center; box-shadow: none!important; margin: 0 10px;}
|
||||
#kanbanList .kanban-item.kanban-item-span:hover,
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item:hover {box-shadow: none;}
|
||||
#kanbanList .kanban-item.kanban-item-span > .title,
|
||||
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item > .title {white-space: normal;}
|
||||
|
||||
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-item > .title {display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center; height: 38px;}
|
||||
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-item > .title > .text {display: block; white-space: nowrap; text-overflow: clip; overflow: hidden;}
|
||||
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-item > .title.has-icon > .text {margin-right: 5px; max-width: calc(100% - 20px);}
|
||||
#kanbanList .no-flex .kanban-col[data-type="normalRelease"] .kanban-item > .title {display: block; height: 38px;}
|
||||
#kanbanList .no-flex .kanban-col[data-type="normalRelease"] .kanban-item > .title > .text {display: inline-block;}
|
||||
#kanbanList .no-flex .kanban-col[data-type="normalRelease"] .kanban-item > .title > .icon {position: relative; top: -5px}
|
||||
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-card > .title {display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;}
|
||||
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-card > .title > .text {display: block; white-space: nowrap; text-overflow: clip; overflow: hidden;}
|
||||
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-card > .title.has-icon > .text {margin-right: 5px; max-width: calc(100% - 20px);}
|
||||
#kanbanList .no-flex .kanban-col[data-type="normalRelease"] .kanban-card > .title {display: block; height: 38px;}
|
||||
#kanbanList .no-flex .kanban-col[data-type="normalRelease"] .kanban-card > .title > .text {display: inline-block;}
|
||||
#kanbanList .no-flex .kanban-col[data-type="normalRelease"] .kanban-card > .title > .icon {position: relative; top: -5px}
|
||||
#kanbanList .kanban-affixed .kanban-header-col[data-type="doingProject"]:after {background-color: #606060;}
|
||||
|
||||
/* Show project and execution in one row */
|
||||
#kanbanList .kanban-lane-col[data-type="doingProject"] + .kanban-lane-col {border-left: none; box-shadow: inset 2px 0 0 #fff;}
|
||||
#kanbanList .kanban-lane-col[data-type="doingProject"] > .kanban-lane-items {padding: 0; overflow: visible; max-height: none!important;}
|
||||
#kanbanList .project-row {position: relative; width: 200%; width: calc(200% + 2px);}
|
||||
#kanbanList .project-row + .project-row {border-top: 2px solid #fff;}
|
||||
#kanbanList .project-row > .project-col {float: left; width: 50%;}
|
||||
/* #kanbanList .project-row > .project-col + .project-col {padding: 10px 9px 10px 11px;} */
|
||||
#kanbanList .kanban-lane-col[data-type="doingProject"] > .kanban-lane-items {padding: 0!important; overflow: visible; max-height: none!important;}
|
||||
#kanbanList .kanban-item-span {padding: 0!important;}
|
||||
#kanbanList .project-row {position: relative; width: 200%; width: calc(200% + 2px); height: 62px!important;}
|
||||
#kanbanList .kanban-item-span + .kanban-item-span > .project-row {border-top: 2px solid #fff;}
|
||||
#kanbanList .project-row > .project-col {float: left; width: 50%; padding: 10px;}
|
||||
#kanbanList .project-row > .execution-item {position: absolute!important; left: 100%; top: 0}
|
||||
</style>
|
||||
<script>
|
||||
@@ -94,7 +93,7 @@ function renderSpanItem(item, $item)
|
||||
$title = $('<div class="title" />').appendTo($item);
|
||||
}
|
||||
$title.text(item.name).attr('title', item.name);
|
||||
return $item.addClass('kanban-item-span');
|
||||
return $item.addClass('kanban-card-span');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,16 +299,17 @@ function renderReleaseItem(item, $item)
|
||||
*/
|
||||
function renderDoingProjectItem(item, $item)
|
||||
{
|
||||
$item.removeClass('kanban-item').addClass('project-row clearfix').empty();
|
||||
$item.closest('.kanban-item').addClass('kanban-item-span');
|
||||
$item.removeClass('kanban-card').addClass('project-row clearfix').empty();
|
||||
|
||||
var $projectCol = $('<div class="project-col"></div>').appendTo($item);
|
||||
var $projectItem = $('<div class="kanban-item project-item"></div>').appendTo($projectCol);
|
||||
var $projectItem = $('<div class="kanban-card project-item"></div>').appendTo($projectCol);
|
||||
renderProjectItem(item, $projectItem);
|
||||
|
||||
var $executionCol = $('<div class="project-col"></div>').appendTo($item);
|
||||
if(item.execution)
|
||||
{
|
||||
var $executionItem = $('<div class="kanban-item execution-item"></div>').appendTo($executionCol);
|
||||
var $executionItem = $('<div class="kanban-card execution-item"></div>').appendTo($executionCol);
|
||||
renderExecutionItem(item.execution, $executionItem);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,20 +2,19 @@
|
||||
#main > .container {max-width: 1960px!important; padding: 0 10px}
|
||||
|
||||
.kanban + .kanban {margin-top: 15px}
|
||||
.kanban-item {position: relative;}
|
||||
.kanban-item > .title { display: block;white-space: nowrap; overflow: hidden; text-overflow: ellipsis}
|
||||
.kanban-item > .infos {position: relative; margin-top: 5px}
|
||||
.kanban-item > .infos > .info + .info {margin-left: 8px}
|
||||
.kanban-item > .infos > .info-id,
|
||||
.kanban-item > .infos > .info-deadline,
|
||||
.kanban-item > .infos > .info-estimate {font-size: 12px; position: relative; top: 2px}
|
||||
.kanban-item > .infos > .label-pri {min-width: 16px; line-height: 14px; height: 16px; padding: 0}
|
||||
.kanban-item > .infos > .label-severity {transform: scale(.75)}
|
||||
.kanban-item > .infos > .avatar {position: absolute; right: 0; top: 0}
|
||||
.kanban-item > .actions {position: absolute; top: 4px; right: 4px; opacity: 0;}
|
||||
.kanban-item:hover > .actions {opacity: 1;}
|
||||
.kanban-item > .actions > a {display: block; float: left; width: 20px; height: 20px; line-height: 20px; text-align: center; border-radius: 4px; opacity: .7;}
|
||||
.kanban-item > .actions > a:hover {background-color: rgba(0,0,0,.075); opacity: 1;}
|
||||
.kanban-card > .title {display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis}
|
||||
.kanban-card > .infos {position: relative; margin-top: 5px}
|
||||
.kanban-card > .infos > .info + .info {margin-left: 8px}
|
||||
.kanban-card > .infos > .info-id,
|
||||
.kanban-card > .infos > .info-deadline,
|
||||
.kanban-card > .infos > .info-estimate {font-size: 12px; position: relative; top: 2px}
|
||||
.kanban-card > .infos > .label-pri {min-width: 16px; line-height: 14px; height: 16px; padding: 0}
|
||||
.kanban-card > .infos > .label-severity {transform: scale(.75)}
|
||||
.kanban-card > .infos > .avatar {position: absolute; right: 0; top: 0}
|
||||
.kanban-card > .actions {position: absolute; top: 4px; right: 4px; opacity: 0;}
|
||||
.kanban-card:hover > .actions {opacity: 1;}
|
||||
.kanban-card > .actions > a {display: block; float: left; width: 20px; height: 20px; line-height: 20px; text-align: center; border-radius: 4px; opacity: .7;}
|
||||
.kanban-card > .actions > a:hover {background-color: rgba(0,0,0,.075); opacity: 1;}
|
||||
|
||||
.kanban-header-col > .actions {padding-top: 22px}
|
||||
.kanban-header-parent-col .kanban-header-col > .actions {padding-top: 6px; padding-right: 2px;}
|
||||
@@ -35,6 +34,20 @@
|
||||
#kanbans .kanban {min-height: initial;}
|
||||
#kanbans .kanban-lane {min-height: 150px;}
|
||||
#kanbans .kanban-affixed > .kanban-header {top: 100px;}
|
||||
#kanbans .kanban-card[data-scale-size="4"] {padding: 8px;}
|
||||
#kanbans .kanban-card[data-scale-size="3"] {padding: 3px 4px;}
|
||||
#kanbans .kanban-card[data-scale-size="3"] > .title {white-space: normal; max-height: 100%;}
|
||||
#kanbans .kanban-card[data-scale-size="2"] {padding: 3px 4px;}
|
||||
#kanbans .kanban-card[data-scale-size="2"] > .title {line-height: 18px; white-space: normal; max-height: 100%;}
|
||||
#kanbans .kanban-card[data-scale-size="2"] > .title > .infos {display: inline-block; height: 18px; vertical-align: top;}
|
||||
#kanbans .kanban-card[data-scale-size="2"] > .title > .infos > .info-pri {transform: scale(.8); vertical-align: top;}
|
||||
#kanbans .kanban-card[data-scale-size="2"] > .title > .infos > .avatar {display: inline-block; transform: scale(.8); position: relative; top: -1px; vertical-align: top; margin-right: -1px;}
|
||||
|
||||
#kanbanScaleControl {width: 100px;}
|
||||
#kanbanScaleControl .input-group-addon {background: #fff; padding: 5px;}
|
||||
#kanbanScaleControl > .input-group-btn:first-child > .btn {border-radius: 16px 0 0 16px; border-right-color: transparent;}
|
||||
#kanbanScaleControl > .input-group-btn:last-child > .btn {border-radius: 0 16px 16px 0; border-left-color: transparent;}
|
||||
#kanbanScaleControl > .input-group-btn > .btn:hover {border-color: #b8bfce;}
|
||||
|
||||
#type_chosen .icon-kanban {padding-right: 10px; font-size: 15px;}
|
||||
|
||||
|
||||
+191
-104
@@ -9,9 +9,10 @@ function changeView(view)
|
||||
* @param {String|{account: string, avatar: string}} user User account or user object
|
||||
* @returns {string}
|
||||
*/
|
||||
function renderUserAvatar(user, objectType, objectID)
|
||||
function renderUserAvatar(user, objectType, objectID, size)
|
||||
{
|
||||
var $noPrivAndNoAssigned = $('<div class="avatar has-text avatar-sm avatar-circle" title="' + noAssigned + '" style="background: #ccc"><i class="icon icon-account"></i></div>');
|
||||
var avatarSizeClass = 'avatar-' + (size || 'sm');
|
||||
var $noPrivAndNoAssigned = $('<div class="avatar has-text ' + avatarSizeClass + ' avatar-circle" title="' + noAssigned + '" style="background: #ccc"><i class="icon icon-person"></i></div>');
|
||||
if(objectType == 'task')
|
||||
{
|
||||
if(!priv.canAssignTask && !user) return $noPrivAndNoAssigned;
|
||||
@@ -28,17 +29,17 @@ function renderUserAvatar(user, objectType, objectID)
|
||||
var link = createLink('bug', 'assignto', 'id=' + objectID, '', true);
|
||||
}
|
||||
|
||||
if(!user) return $('<a class="avatar has-text avatar-sm avatar-circle iframe" title="' + noAssigned + '" style="background: #ccc" href="' + link + '"><i class="icon icon-account"></i></a>');
|
||||
if(!user) return $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + noAssigned + '" style="background: #ccc" href="' + link + '"><i class="icon icon-person"></i></a>');
|
||||
|
||||
if(typeof user === 'string') user = {account: user};
|
||||
if(!user.avatar && window.userList && window.userList[user.account]) user = window.userList[user.account];
|
||||
|
||||
var $noPrivAvatar = $('<div class="avatar has-text avatar-sm avatar-circle" />').avatar({user: user});
|
||||
var $noPrivAvatar = $('<div class="avatar has-text ' + avatarSizeClass + ' avatar-circle" />').avatar({user: user});
|
||||
if(objectType == 'task' && !priv.canAssignTask) return $noPrivAvatar;
|
||||
if(objectType == 'story' && !priv.canAssignStory) return $noPrivAvatar;
|
||||
if(objectType == 'bug' && !priv.canAssignBug) return $noPrivAvatar;
|
||||
|
||||
return $('<a class="avatar has-text avatar-sm avatar-circle iframe" href="' + link + '"/>').avatar({user: user});
|
||||
return $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" href="' + link + '"/>').avatar({user: user});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,43 +72,56 @@ function renderDeadline(deadline)
|
||||
*/
|
||||
function renderStoryItem(item, $item, col)
|
||||
{
|
||||
var $title = $item.find('.title');
|
||||
if(!$title.length)
|
||||
{
|
||||
$title = $('<a class="title iframe" data-width="95%"><i class="icon icon-lightbulb text-muted"></i> <span class="text"></span></a>')
|
||||
.attr('href', $.createLink('story', 'view', 'storyID=' + item.id, '', true));
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.title).find('.text').text(item.title);
|
||||
var scaleSize = window.kanbanScaleSize;
|
||||
if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
|
||||
|
||||
var $infos = $item.find('.infos');
|
||||
if(!$infos.length)
|
||||
if(scaleSize <= 3)
|
||||
{
|
||||
$infos = $('<div class="infos"></div>').appendTo($item);
|
||||
}
|
||||
$infos.html(
|
||||
[
|
||||
'<span class="info info-id text-muted">#' + item.id + '</span>',
|
||||
'<span class="info info-pri label-pri label-pri-' + item.pri + '" title="' + item.pri + '">' + item.pri + '</span>',
|
||||
item.estimate ? '<span class="info info-estimate text-muted">' + item.estimate + 'h</span>' : '',
|
||||
].join(''));
|
||||
$infos.append(renderUserAvatar(item.assignedTo, 'story', item.id));
|
||||
|
||||
var $actions = $item.find('.actions');
|
||||
if(!$actions.length && item.menus.length)
|
||||
{
|
||||
$actions = $([
|
||||
'<div class="actions">',
|
||||
'<a data-contextmenu="story" data-col="' + col.type + '">',
|
||||
'<i class="icon icon-ellipsis-v"></i>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join('')).appendTo($item);
|
||||
var $title = $item.find('.title');
|
||||
if(!$title.length)
|
||||
{
|
||||
$title = $('<a class="title iframe" data-width="95%">' + (scaleSize <= 1 ? '<i class="icon icon-lightbulb text-muted"></i> ' : '') + '<span class="text"></span></a>')
|
||||
.attr('href', $.createLink('story', 'view', 'storyID=' + item.id, '', true));
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.title).find('.text').text(item.title);
|
||||
}
|
||||
|
||||
$item.attr('data-type', 'story').addClass('kanban-item-story');
|
||||
if(scaleSize <= 2)
|
||||
{
|
||||
var idHtml = scaleSize <= 1 ? ('<span class="info info-id text-muted">#' + item.id + '</span>') : '';
|
||||
var priHtml = '<span class="info info-pri label-pri label-pri-' + item.pri + '" title="' + item.pri + '">' + item.pri + '</span>';
|
||||
var hoursHtml = (item.estimate && scaleSize <= 1) ? ('<span class="info info-estimate text-muted">' + item.estimate + 'h</span>') : '';
|
||||
var avatarHtml = renderUserAvatar(item.assignedTo, 'story', item.id);
|
||||
var $infos = $item.find('.infos');
|
||||
if(!$infos.length) $infos = $('<div class="infos"></div>');
|
||||
$infos.html([idHtml, priHtml, hoursHtml].join(''));
|
||||
|
||||
return $item;
|
||||
$infos[scaleSize <= 1 ? 'append' : 'prepend'](avatarHtml);
|
||||
if(scaleSize <= 1) $infos.appendTo($item);
|
||||
else $infos.prependTo($item.find('.title'));
|
||||
}
|
||||
else if(scaleSize === 4)
|
||||
{
|
||||
$item.html(renderUserAvatar(item.assignedTo, 'story', item.id, 'md'));
|
||||
}
|
||||
|
||||
if(scaleSize <= 1)
|
||||
{
|
||||
var $actions = $item.find('.actions');
|
||||
if(!$actions.length && item.menus.length)
|
||||
{
|
||||
$actions = $([
|
||||
'<div class="actions">',
|
||||
'<a data-contextmenu="story" data-col="' + col.type + '">',
|
||||
'<i class="icon icon-ellipsis-v"></i>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join('')).appendTo($item);
|
||||
}
|
||||
}
|
||||
|
||||
return $item.attr('data-type', 'story').addClass('kanban-item-story');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,44 +133,58 @@ function renderStoryItem(item, $item, col)
|
||||
*/
|
||||
function renderBugItem(item, $item, col)
|
||||
{
|
||||
var $title = $item.find('.title');
|
||||
if(!$title.length)
|
||||
{
|
||||
$title = $('<a class="title iframe" data-width="95%"><i class="icon icon-bug text-muted"></i> <span class="text"></span></a>')
|
||||
.attr('href', $.createLink('bug', 'view', 'bugID=' + item.id, '', true));
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.title).find('.text').text(item.title);
|
||||
var scaleSize = window.kanbanScaleSize;
|
||||
if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
|
||||
|
||||
var $infos = $item.find('.infos');
|
||||
if(!$infos.length)
|
||||
if(scaleSize <= 3)
|
||||
{
|
||||
$infos = $('<div class="infos"></div>').appendTo($item);
|
||||
}
|
||||
$infos.html(
|
||||
[
|
||||
'<span class="info info-id text-muted">#' + item.id + '</span>',
|
||||
'<span class="info info-severity label-severity" data-severity="' + item.severity + '" title="' + item.severity + '"></span>',
|
||||
'<span class="info info-pri label-pri label-pri-' + item.pri + '" title="' + item.pri + '">' + item.pri + '</span>',
|
||||
].join(''));
|
||||
if(item.deadline) $infos.append(renderDeadline(item.deadline));
|
||||
$infos.append(renderUserAvatar(item.assignedTo, 'bug', item.id));
|
||||
|
||||
var $actions = $item.find('.actions');
|
||||
if(!$actions.length && item.menus.length)
|
||||
{
|
||||
$actions = $([
|
||||
'<div class="actions">',
|
||||
'<a data-contextmenu="bug" data-col="' + col.type + '">',
|
||||
'<i class="icon icon-ellipsis-v"></i>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join('')).appendTo($item);
|
||||
var $title = $item.find('.title');
|
||||
if(!$title.length)
|
||||
{
|
||||
$title = $('<a class="title iframe" data-width="95%">' + (scaleSize <= 1 ? '<i class="icon icon-bug text-muted"></i> ' : '') + '<span class="text"></span></a>')
|
||||
.attr('href', $.createLink('bug', 'view', 'bugID=' + item.id, '', true));
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.title).find('.text').text(item.title);
|
||||
}
|
||||
|
||||
$item.attr('data-type', 'bug').addClass('kanban-item-bug');
|
||||
if(scaleSize <= 2)
|
||||
{
|
||||
var idHtml = scaleSize <= 1 ? ('<span class="info info-id text-muted">#' + item.id + '</span>') : '';
|
||||
var severityHtml = scaleSize <= 1 ? ('<span class="info info-severity label-severity" data-severity="' + item.severity + '" title="' + item.severity + '"></span>') : '';
|
||||
var priHtml = '<span class="info info-pri label-pri label-pri-' + item.pri + '" title="' + item.pri + '">' + item.pri + '</span>';
|
||||
var avatarHtml = renderUserAvatar(item.assignedTo, 'bug', item.id);
|
||||
|
||||
return $item;
|
||||
var $infos = $item.find('.infos');
|
||||
if(!$infos.length) $infos = $('<div class="infos"></div>');
|
||||
$infos.html([idHtml, severityHtml, priHtml].join(''));
|
||||
if(item.deadline && scaleSize <= 1) $infos.append(renderDeadline(item.deadline));
|
||||
$infos[scaleSize <= 1 ? 'append' : 'prepend'](avatarHtml);
|
||||
|
||||
if(scaleSize <= 1) $infos.appendTo($item);
|
||||
else $infos.prependTo($item.find('.title'));
|
||||
}
|
||||
else if(scaleSize === 4)
|
||||
{
|
||||
$item.html(renderUserAvatar(item.assignedTo, 'bug', item.id, 'md'));
|
||||
}
|
||||
|
||||
if(scaleSize <= 1)
|
||||
{
|
||||
var $actions = $item.find('.actions');
|
||||
if(!$actions.length && item.menus.length)
|
||||
{
|
||||
$actions = $([
|
||||
'<div class="actions">',
|
||||
'<a data-contextmenu="bug" data-col="' + col.type + '">',
|
||||
'<i class="icon icon-ellipsis-v"></i>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join('')).appendTo($item);
|
||||
}
|
||||
}
|
||||
|
||||
return $item.attr('data-type', 'bug').addClass('kanban-item-bug');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,39 +196,55 @@ function renderBugItem(item, $item, col)
|
||||
*/
|
||||
function renderTaskItem(item, $item, col)
|
||||
{
|
||||
var $title = $item.find('.title');
|
||||
if(!$title.length)
|
||||
{
|
||||
$title = $('<a class="title iframe" data-width="95%"><i class="icon icon-checked text-muted"></i> <span class="text"></span></a>')
|
||||
.attr('href', $.createLink('task', 'view', 'taskID=' + item.id, '', true));
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.name).find('.text').text(item.name);
|
||||
var scaleSize = window.kanbanScaleSize;
|
||||
if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
|
||||
|
||||
var $infos = $item.find('.infos');
|
||||
if(!$infos.length)
|
||||
if(scaleSize <= 3)
|
||||
{
|
||||
$infos = $('<div class="infos"></div>').appendTo($item);
|
||||
var $title = $item.find('.title');
|
||||
if(!$title.length)
|
||||
{
|
||||
$title = $('<a class="title iframe" data-width="95%">' + (scaleSize <= 1 ? '<i class="icon icon-checked text-muted"></i> ' : '') + '<span class="text"></span></a>')
|
||||
.attr('href', $.createLink('task', 'view', 'taskID=' + item.id, '', true));
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.name).find('.text').text(item.name);
|
||||
}
|
||||
$infos.html(
|
||||
[
|
||||
'<span class="info info-id text-muted">#' + item.id + '</span>',
|
||||
'<span class="info i nfo-pri label-pri label-pri-' + item.pri + '" title="' + item.pri + '">' + item.pri + '</span>',
|
||||
item.estimate ? '<span class="info info-estimate text-muted">' + item.estimate + 'h</span>' : '',
|
||||
].join(''));
|
||||
if(item.deadline) $infos.append(renderDeadline(item.deadline));
|
||||
$infos.append(renderUserAvatar(item.assignedTo, 'task', item.id));
|
||||
|
||||
var $actions = $item.find('.actions');
|
||||
if(!$actions.length && item.menus.length)
|
||||
if(scaleSize <= 2)
|
||||
{
|
||||
$actions = $([
|
||||
'<div class="actions">',
|
||||
'<a data-contextmenu="task" data-col="' + col.type + '">',
|
||||
'<i class="icon icon-ellipsis-v"></i>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join('')).appendTo($item);
|
||||
var idHtml = scaleSize <= 1 ? ('<span class="info info-id text-muted">#' + item.id + '</span>') : '';
|
||||
var priHtml = '<span class="info info-pri label-pri label-pri-' + item.pri + '" title="' + item.pri + '">' + item.pri + '</span>';
|
||||
var hoursHtml = (item.estimate && scaleSize <= 1) ? ('<span class="info info-estimate text-muted">' + item.estimate + 'h</span>') : '';
|
||||
var avatarHtml = renderUserAvatar(item.assignedTo, 'task', item.id);
|
||||
|
||||
var $infos = $item.find('.infos');
|
||||
if(!$infos.length) $infos = $('<div class="infos"></div>');
|
||||
$infos.html([idHtml, priHtml, hoursHtml].join(''));
|
||||
if(item.deadline && scaleSize <= 1) $infos.append(renderDeadline(item.deadline));
|
||||
$infos[scaleSize <= 1 ? 'append' : 'prepend'](avatarHtml);
|
||||
|
||||
if(scaleSize <= 1) $infos.appendTo($item);
|
||||
else $infos.prependTo($item.find('.title'));
|
||||
}
|
||||
else if(scaleSize === 4)
|
||||
{
|
||||
$item.html(renderUserAvatar(item.assignedTo, 'task', item.id, 'md'));
|
||||
}
|
||||
|
||||
if(scaleSize <= 1)
|
||||
{
|
||||
var $actions = $item.find('.actions');
|
||||
if(!$actions.length && item.menus.length)
|
||||
{
|
||||
$actions = $([
|
||||
'<div class="actions">',
|
||||
'<a data-contextmenu="task" data-col="' + col.type + '">',
|
||||
'<i class="icon icon-ellipsis-v"></i>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join('')).appendTo($item);
|
||||
}
|
||||
}
|
||||
|
||||
$item.attr('data-type', 'task').addClass('kanban-item-task');
|
||||
@@ -737,20 +781,57 @@ $.extend($.fn.kanban.Constructor.DEFAULTS,
|
||||
}
|
||||
});
|
||||
|
||||
/** Get card height */
|
||||
function getCardHeight()
|
||||
{
|
||||
return [59, 59, 62, 62, 47][window.kanbanScaleSize];
|
||||
}
|
||||
|
||||
/** Change kanban scale size */
|
||||
function changeKanbanScaleSize(newScaleSize)
|
||||
{
|
||||
var newScaleSize = Math.max(1, Math.min(4, newScaleSize));
|
||||
if(newScaleSize === window.kanbanScaleSize) return;
|
||||
|
||||
window.kanbanScaleSize = newScaleSize;
|
||||
$.zui.store.set('executionKanbanScaleSize', newScaleSize);
|
||||
$('#kanbanScaleSize').text(newScaleSize);
|
||||
$('#kanbanScaleControl .btn[data-type="+"]').attr('disabled', newScaleSize >= 4 ? 'disabled' : null);
|
||||
$('#kanbanScaleControl .btn[data-type="-"]').attr('disabled', newScaleSize <= 1 ? 'disabled' : null);
|
||||
|
||||
$('#kanbans').children('.kanban').each(function()
|
||||
{
|
||||
var kanban = $(this).data('zui.kanban');
|
||||
if(!kanban) return;
|
||||
kanban.setOptions({cardsPerRow: newScaleSize, cardHeight: getCardHeight()});
|
||||
});
|
||||
|
||||
return newScaleSize;
|
||||
}
|
||||
|
||||
/* Example code: */
|
||||
$(function()
|
||||
{
|
||||
$.cookie('isFullScreen', 0);
|
||||
|
||||
window.kanbanScaleSize = +$.zui.store.get('executionKanbanScaleSize', 1);
|
||||
$('#kanbanScaleSize').text(window.kanbanScaleSize);
|
||||
$('#kanbanScaleControl .btn[data-type="+"]').attr('disabled', window.kanbanScaleSize >= 4 ? 'disabled' : null);
|
||||
$('#kanbanScaleControl .btn[data-type="-"]').attr('disabled', window.kanbanScaleSize <= 1 ? 'disabled' : null);
|
||||
|
||||
/* Common options 用于初始化看板的通用选项 */
|
||||
var commonOptions =
|
||||
{
|
||||
maxColHeight: 'auto',
|
||||
minColWidth: 240,
|
||||
maxColWidth: 240,
|
||||
showCount: true,
|
||||
showZeroCount: true,
|
||||
fluidBoardWidth: false,
|
||||
maxColHeight: 'auto',
|
||||
minColWidth: 240,
|
||||
maxColWidth: 240,
|
||||
cardHeight: getCardHeight(),
|
||||
showCount: true,
|
||||
showZeroCount: true,
|
||||
fluidBoardWidth: false,
|
||||
cardsPerRow: window.kanbanScaleSize,
|
||||
virtualize: true,
|
||||
virtualRenderOptions: {container: '#kanbanContainer>.panel-body'},
|
||||
droppable:
|
||||
{
|
||||
target: findDropColumns,
|
||||
@@ -806,6 +887,12 @@ $(function()
|
||||
$.zui.ContextMenu.show(items, items.$options || {event: event});
|
||||
});
|
||||
|
||||
/* Make kanbanScaleControl works */
|
||||
$('#kanbanScaleControl').on('click', '.btn', function()
|
||||
{
|
||||
changeKanbanScaleSize(window.kanbanScaleSize + ($(this).data('type') === '+' ? 1 : -1));
|
||||
});
|
||||
|
||||
/* Resize kanban container on window resize */
|
||||
resizeKanbanContainer();
|
||||
$(window).on('resize', resizeKanbanContainer);
|
||||
|
||||
@@ -397,6 +397,7 @@ $lang->execution->bugList = "Bugs";
|
||||
$lang->execution->kanbanHideCols = 'Closed & Cancelled Columns';
|
||||
$lang->execution->kanbanShowOption = 'Unfold';
|
||||
$lang->execution->kanbanColsColor = 'Customize Column Color';
|
||||
$lang->execution->kanbanCardsUnit = 'X';
|
||||
|
||||
$lang->execution->kanbanViewList['all'] = 'All';
|
||||
$lang->execution->kanbanViewList['story'] = "{$lang->SRCommon}";
|
||||
|
||||
@@ -398,6 +398,7 @@ $lang->execution->bugList = "Bug列表";
|
||||
$lang->execution->kanbanHideCols = '看板隐藏已关闭、已取消列';
|
||||
$lang->execution->kanbanShowOption = '显示折叠信息';
|
||||
$lang->execution->kanbanColsColor = '看板列自定义颜色';
|
||||
$lang->execution->kanbanCardsUnit = '个';
|
||||
|
||||
$lang->execution->kanbanViewList['all'] = '综合看板';
|
||||
$lang->execution->kanbanViewList['story'] = "{$lang->SRCommon}看板";
|
||||
|
||||
@@ -21,6 +21,17 @@
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<div class='input-group pull-left not-fix-input-group' id='kanbanScaleControl'>
|
||||
<span class='input-group-btn'>
|
||||
<button class='btn btn-icon' type='button' data-type='-'><i class='icon icon-minuse-solid-circle text-muted'></i></button>
|
||||
</span>
|
||||
<span class='input-group-addon'>
|
||||
<span id='kanbanScaleSize'>1</span><?php echo $lang->execution->kanbanCardsUnit; ?>
|
||||
</span>
|
||||
<span class='input-group-btn'>
|
||||
<button class='btn btn-icon' type='button' data-type='+'><i class='icon icon-plus-solid-circle text-muted'></i></button>
|
||||
</span>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<?php
|
||||
$link = $this->createLink('task', 'export', "execution=$executionID&orderBy=$orderBy&type=kanban");
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user