* task #45145, support to change scale size for execution kanban.

This commit is contained in:
Hao Sun
2021-12-01 08:30:57 +08:00
parent 81f69855be
commit 5424c131dc
9 changed files with 268 additions and 155 deletions
+34 -34
View File
@@ -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);
}
+27 -14
View File
@@ -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
View File
@@ -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);
+1
View File
@@ -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}";
+1
View File
@@ -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}看板";
+11
View File
@@ -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
View File
File diff suppressed because one or more lines are too long