This commit is contained in:
liugang
2018-06-15 14:11:38 +08:00
18 changed files with 161 additions and 89 deletions
-3
View File
@@ -6,6 +6,3 @@
#batchCreateForm .input-group .form-control, #batchEditForm .input-group .form-control {position: static;}
#batchCreateForm .input-group .colorpicker, #batchEditForm .input-group .colorpicker {z-index: 2;}
#batchCreateForm .input-group .colorpicker.open, #batchEditForm .input-group .colorpicker.open {z-index: 5;}
.table td {overflow:hidden;}
+1 -1
View File
@@ -300,7 +300,7 @@ class commonModel extends model
echo "<li class='dropdown'>";
echo "<a data-toggle='dropdown'>" . $lang->help . " <span class='caret'></span></a>";
echo "<ul class='dropdown-menu'>";
if(!commonModel::isTutorialMode() and $app->user->account != 'guest') echo '<li>' . html::a(helper::createLink('tutorial', 'start'), $lang->tutorial, '', "class='iframe' data-width='800' data-headerless='true' data-backdrop='true' data-keyboard='true'") . "</li>";
if(!commonModel::isTutorialMode() and $app->user->account != 'guest') echo '<li>' . html::a(helper::createLink('tutorial', 'start'), $lang->tutorial, '', "class='iframe' data-class-name='modal-inverse' data-width='800' data-headerless='true' data-backdrop='true' data-keyboard='true'") . "</li>";
echo '<li>' . html::a($lang->manualUrl, $lang->manual, '_blank', "class='open-help-tab'") . '</li>';
echo '<li>' . html::a(helper::createLink('misc', 'changeLog'), $lang->changeLog, '', "class='iframe' data-width='800' data-headerless='true' data-backdrop='true' data-keyboard='true'") . '</li>';
echo "</ul></li>\n";
+1 -1
View File
@@ -1,2 +1,2 @@
#whitelistBox .checkbox-primary, #whitelistBox .radio-inline{margin-left: 10px; display: inline-block; padding-left: 0px; padding-right: 10px;}
.table td {overflow:hidden;}
.c-pri {overflow:hidden;}
+3 -1
View File
@@ -1,4 +1,4 @@
.boards {display: table; table-layout: fixed; width: 100%; }
.boards {display: table; table-layout: fixed; width: auto; }
.board {display: table-cell; width: 16.666666667%; padding: 10px; border: 1px solid transparent; transition: background-color .2s, opacity .2s; vertical-align: top;}
.board-item {border: 1px solid #EBEBEB; padding: 5px 10px; cursor: move; border-radius: 2px; background-color: #fff; transition: border .2s, opacity .2s; overflow: hidden;}
.board-item.disabled {cursor: not-allowed;}
@@ -17,6 +17,8 @@
.board-item.dragging {opacity: .35;}
.board-item .btn {padding: 2px 10px 2px 23px; font-size: 12px; position: relative; left: -2px;}
.board-item .btn-icon-left > .icon {width: 22px; height: 22px; line-height: 20px; font-size: 14px;}
#kanban {overflow-y: auto}
#kanban > .table {min-width: 1100px;}
#kanban.dragging .boards.dragging .board {background: #eee; opacity: .35; border-color: #f1f1f1}
#kanban thead .c-side {padding: 5px;}
#kanban .label-pri {width: 16px; height: 16px; line-height: 16px; min-width: 16px; font-size: 12px;}
+3
View File
@@ -1 +1,4 @@
tbody > tr > td > .btn-icon {margin-right: 4px}
@media (max-width: 1200px) {#storyList .c-user, #storyList .c-estimate {display: none!important;}}
@media (max-width: 1000px) {#storyList .c-status, #storyList .c-pri {display: none!important;}}
@media (max-width: 820px) {#storyList .c-sort, #storyList .c-stage {display: none!important;}}
+3 -1
View File
@@ -1,4 +1,4 @@
.boards {display: table; table-layout: fixed; width: 100%; }
.boards {display: table; table-layout: fixed; width: auto; }
.board {display: table-cell; width: 16.666666667%; padding: 10px; border: 1px solid transparent; transition: background-color .2s, opacity .2s; vertical-align: top;}
.board-item {border: 1px solid #EBEBEB; padding: 5px 10px; cursor: move; border-radius: 2px; background-color: #fff; transition: border .2s, opacity .2s; overflow: hidden;}
.board-item.disabled {cursor: not-allowed;}
@@ -17,6 +17,8 @@
.board-item .btn {padding: 2px 10px 2px 30px; font-size: 12px;}
.board-item .btn-icon-left > .icon {width: 22px; height: 22px; line-height: 20px; font-size: 14px;}
.board-item .status {line-height: 20px; display: inline-block; vertical-align: middle;}
#kanban {overflow-y: auto}
#kanban > .table {min-width: 1100px;}
#kanban.dragging .boards.dragging .board {background: #eee; opacity: .35; border-color: #f1f1f1}
#kanban thead .c-side {padding: 5px;}
#kanban .label-pri {width: 16px; height: 16px; line-height: 16px; min-width: 16px; font-size: 12px;}
+55 -32
View File
@@ -26,6 +26,58 @@ $(function()
}
};
// Get scrollbar width
var getScrollbarWidth = function ()
{
var outer = document.createElement("div");
outer.style.visibility = "hidden";
outer.style.width = "100px";
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
document.body.appendChild(outer);
var widthNoScroll = outer.offsetWidth;
// force scrollbars
outer.style.overflow = "scroll";
// add innerdiv
var inner = document.createElement("div");
inner.style.width = "100%";
outer.appendChild(inner);
var widthWithScroll = inner.offsetWidth;
// remove divs
outer.parentNode.removeChild(outer);
return widthNoScroll - widthWithScroll;
};
var scrollbarWidth = getScrollbarWidth();
var fixBoardWidth = function()
{
var $table = $kanban.find('.table');
var kanbanWidth = $table.width();
var $cBoards = $table.find('thead>tr>th.c-board:not(.c-side)');
var boardCount = $cBoards.length;
var $cSide = $table.find('thead>tr>th.c-board.c-side');
var totalWidth = kanbanWidth - scrollbarWidth;
if ($cSide.length) totalWidth = totalWidth - ($cSide.outerWidth() + 5);
var cBoardWidth = Math.floor(totalWidth/boardCount) - 16;
$cBoards.not(':last').width(cBoardWidth);
$cBoards.first().width(cBoardWidth + 5);
$kanban.find('.boards > .board').width(cBoardWidth + 16 - 22);
};
fixBoardWidth();
$(window).on('resize', fixBoardWidth);
var refresh = function()
{
var selfClose = $.cookie('selfClose');
$.cookie('selfClose', 0, {expires:config.cookieLife, path:config.webRoot});
if(selfClose == 1) $kanban.load(location.href + ' #kanban', fixBoardWidth);
};
var kanbanModalTrigger = new $.zui.ModalTrigger({type: 'iframe', width:800});
var lastOperation;
var dropTo = function(id, from, to, type)
@@ -37,29 +89,7 @@ $(function()
{
url: $.createLink(type, statusMap[type][from][to], 'id=' + id) + onlybody,
shown: function(){$('.modal-iframe').addClass('with-titlebar').data('cancel-reload', true)},
hidden: function()
{
var selfClose = $.cookie('selfClose');
$.cookie('selfClose', 0, {expires: config.cookieLife, path: config.webRoot});
$item = $('#' + type + '-' + id);
$item.removeClass('board-' + type + '-' + lastOperation.to).removeClass('drop-in');
if(selfClose != 1 && lastOperation)
{
$item.appendTo($item.closest('.boards').find('.board[data-type="'+ lastOperation.from + '"]'));
}
else
{
$.get($.createLink(type, 'ajaxGetByID', 'id=' + id), function(data)
{
$('#' + type + '-' + id).find('.' + type + '-assignedTo .text').html(data.assignedTo);
if(type == 'task')
{
$('#task-' + id).find('.task-left').html(data.left + 'h');
if(data.story) $('div.board-story[data-id="' + data.story + '"]').find('.story-stage').html(data.storyStage);
}
}, 'json');
}
}
hidden: refresh
});
return true;
}
@@ -113,13 +143,6 @@ $(function()
}
});
var refresh = function()
{
var selfClose = $.cookie('selfClose');
$.cookie('selfClose', 0, {expires:config.cookieLife, path:config.webRoot});
if(selfClose == 1) $kanban.load(location.href + ' #kanban');
}
$kanban.on('click', '.kanbaniframe', function(e)
{
var $link = $(this);
@@ -130,8 +153,8 @@ $(function()
width: '80%',
}, $link.data())).show(
{
shown: function(){$('.modal-iframe').addClass('with-titlebar').data('cancel-reload', true)},
hidden: function(){refresh();}
shown: function(){$('.modal-iframe').data('cancel-reload', true)},
hidden: refresh
});
return false;
});
+60 -18
View File
@@ -4,6 +4,7 @@ $(function()
var onlybody = config.requestType == 'GET' ? "&onlybody=yes" : "?onlybody=yes";
$.cookie('selfClose', 0, {expires:config.cookieLife, path:config.webRoot});
var $kanban = $('#kanban');
var kanbanModalTrigger = new $.zui.ModalTrigger({type: 'iframe', width:800});
var stageMap =
{
@@ -17,14 +18,68 @@ $(function()
}
};
// Get scrollbar width
var getScrollbarWidth = function ()
{
var outer = document.createElement("div");
outer.style.visibility = "hidden";
outer.style.width = "100px";
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
document.body.appendChild(outer);
var widthNoScroll = outer.offsetWidth;
// force scrollbars
outer.style.overflow = "scroll";
// add innerdiv
var inner = document.createElement("div");
inner.style.width = "100%";
outer.appendChild(inner);
var widthWithScroll = inner.offsetWidth;
// remove divs
outer.parentNode.removeChild(outer);
return widthNoScroll - widthWithScroll;
};
var scrollbarWidth = getScrollbarWidth();
var fixBoardWidth = function()
{
var $table = $kanban.find('.table');
var kanbanWidth = $table.width();
var $cBoards = $table.find('thead>tr>th.c-board:not(.c-side)');
var boardCount = $cBoards.length;
var $cSide = $table.find('thead>tr>th.c-board.c-side');
var totalWidth = kanbanWidth - scrollbarWidth;
if ($cSide.length) totalWidth = totalWidth - ($cSide.outerWidth() + 5);
var cBoardWidth = Math.floor(totalWidth/boardCount) - 16;
$cBoards.not(':last').width(cBoardWidth);
$cBoards.first().width(cBoardWidth + 5);
$kanban.find('.boards > .board').width(cBoardWidth + 16 - 22);
};
fixBoardWidth();
$(window).on('resize', fixBoardWidth);
var refresh = function()
{
var selfClose = $.cookie('selfClose');
$.cookie('selfClose', 0, {expires:config.cookieLife, path:config.webRoot});
if(selfClose == 1) $kanban.load(location.href + ' #kanban', fixBoardWidth);
};
var lastOperation;
var dropTo = function(id, from, to, type)
{
console.log(id);
if(stageMap[type][from] && stageMap[type][from][to])
{
lastOperation = {id: id, from: from, to: to};
$.post(createLink(type, stageMap[type][from][to], 'stage=' + to), {'storyIDList[]':[id]});
$.post(createLink(type, stageMap[type][from][to], 'stage=' + to), {'storyIDList[]':[id]}, function()
{
refresh();
});
return true;
}
return false;
@@ -77,13 +132,6 @@ $(function()
}
});
var refresh = function()
{
var selfClose = $.cookie('selfClose');
$.cookie('selfClose', 0, {expires:config.cookieLife, path:config.webRoot});
if(selfClose == 1) $kanban.load(location.href + ' #kanban');
}
$kanban.on('click', '.kanbaniframe', function(e)
{
var $link = $(this);
@@ -94,15 +142,9 @@ $(function()
width: '80%',
}, $link.data())).show(
{
shown: function(){$('.modal-iframe').addClass('with-titlebar').data('cancel-reload', true)},
hidden: function(){refresh();}
shown: function(){$('.modal-iframe').data('cancel-reload', true)},
hidden: refresh
});
return false;
return false;
});
$.extend({'closeModal':function(callback, location)
{
kanbanModalTrigger.close();
if(callback && $.isFunction(callback)) callback();
}});
});
+1 -1
View File
@@ -2748,7 +2748,7 @@ class projectModel extends model
$productPlans = array();
foreach($products as $productID => $product)
{
$productPlans[$productID] = $this->productplan->getPairs($product->id, $product->branch);
$productPlans[$productID] = $this->productplan->getPairs($product->id, isset($product->branch) ? $product->branch : '');
}
return $productPlans;
}
+15 -15
View File
@@ -100,15 +100,15 @@
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<?php if($canOrder):?>
<th class='w-80px'> <?php common::printOrderLink('order', $orderBy, $vars, $lang->project->updateOrder);?></th>
<th class='w-80px c-sort'> <?php common::printOrderLink('order', $orderBy, $vars, $lang->project->updateOrder);?></th>
<?php endif;?>
<th class='c-pri'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<th class='w-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='w-80px'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
<th class='w-80px'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='w-80px'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='w-70px'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='c-name'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='c-user'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
<th class='c-estimate w-80px'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-stage w-70px'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th title='<?php echo $lang->story->taskCount?>' class='w-30px'><?php echo $lang->story->taskCountAB;?></th>
<th title='<?php echo $lang->story->bugCount?>' class='w-30px'><?php echo $lang->story->bugCountAB;?></th>
<th title='<?php echo $lang->story->caseCount?>' class='w-30px'><?php echo $lang->story->caseCountAB;?></th>
@@ -130,23 +130,23 @@
<?php endif;?>
</td>
<?php if($canOrder):?>
<td class='sort-handler'><i class='icon-move'></i></td>
<td class='sort-handler c-sort'><i class='icon-move'></i></td>
<?php endif;?>
<td><span class='label-pri <?php echo 'label-pri-' . $story->pri?>' title='<?php echo zget($lang->story->priList, $story->pri, $story->pri);?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri);?></span></td>
<td class='text-left' title="<?php echo $story->title?>">
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $story->pri?>' title='<?php echo zget($lang->story->priList, $story->pri, $story->pri);?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri);?></span></td>
<td class='c-name' title="<?php echo $story->title?>">
<?php if(isset($branchGroups[$story->product][$story->branch])) echo "<span class='label label-info label-badge'>" . $branchGroups[$story->product][$story->branch] . '</span>';?>
<?php echo html::a($storyLink,$story->title, null, "style='color: $story->color'");?>
</td>
<td><?php echo $users[$story->openedBy];?></td>
<td><?php echo $users[$story->assignedTo];?></td>
<td><?php echo $story->estimate;?></td>
<td title='<?php echo zget($lang->story->statusList, $story->status);?>'>
<td class='c-user'><?php echo $users[$story->openedBy];?></td>
<td class='c-user'><?php echo $users[$story->assignedTo];?></td>
<td class='c-estimate'><?php echo $story->estimate;?></td>
<td class='c-status' title='<?php echo zget($lang->story->statusList, $story->status);?>'>
<span class='status-<?php echo $story->status;?>'>
<span class='label label-dot'></span>
<span class='status-text'><?php echo zget($lang->story->statusList, $story->status);?></span>
</span>
</td>
<td><?php echo $lang->story->stageList[$story->stage];?></td>
<td class='c-stage'><?php echo $lang->story->stageList[$story->stage];?></td>
<td class='linkbox'>
<?php
$tasksLink = $this->createLink('story', 'tasks', "storyID=$story->id&projectID=$project->id");
+1
View File
@@ -42,6 +42,7 @@ $formId = 'searchForm-' . uniqid('');
#userQueries .label:hover {background-color: #aaa; color: #fff;}
#userQueries .label > .icon-close {position: absolute; top: 2px; right: 2px; border-radius: 9px; font-size: 12px; line-height: 18px; width: 18px; display: inline-block;}
#userQueries .label > .icon-close:hover {background-color: #ff5d5d; color: #fff;}
@media (max-width: 1150px) {#userQueries {display: none}}
</style>
<form method='post' action='<?php echo $this->createLink('search', 'buildQuery');?>' target='hiddenwin' id='<?php echo $formId;?>' class='search-form'>
<div class='hidden'>
+5 -3
View File
@@ -2,9 +2,11 @@
function copyStoryTitle()
{
var storyTitle = $('#story option:selected').text();
startPosition = storyTitle.indexOf(':') + 1;
endPosition = storyTitle.lastIndexOf('(');
storyTitle = storyTitle.substr(startPosition, endPosition - startPosition);
var startPosition = storyTitle.indexOf(':') + 1;
if (startPosition > 0) {
var endPosition = storyTitle.lastIndexOf('(');
storyTitle = storyTitle.substr(startPosition, endPosition - startPosition);
}
$('#name').attr('value', storyTitle);
$('#estimate').val($('#storyEstimate').val());
+2 -2
View File
@@ -11,7 +11,7 @@
*/
$lang->tutorial = new stdclass();
$lang->tutorial->common = '新手教程';
$lang->tutorial->desc = '通过完成一系列任务,快速了解禅道的基本使用方法。这可能会花费您10分钟,你可以随时退出任务。';
$lang->tutorial->desc = '通过完成一系列任务,快速了解禅道的基本使用方法。这可能会花费你10分钟,你可以随时退出任务。';
$lang->tutorial->start = '立即开始';
$lang->tutorial->exit = '退出教程';
$lang->tutorial->congratulation = '恭喜,你已完成了所有任务!';
@@ -29,7 +29,7 @@ $lang->tutorial->requiredTip = '【%s】为必填项';
$lang->tutorial->congratulateTask = '恭喜,你完成了任务 【<span class="task-name-current"></span>】!';
$lang->tutorial->serverErrorTip = '发生了一些错误。';
$lang->tutorial->ajaxSetError = '必须指定已完成的任务,如果要重置任务,请设置值为空。';
$lang->tutorial->novice = "您可能初次使用禅道,是否进入新手教程";
$lang->tutorial->novice = "你可能初次使用禅道,是否进入新手教程";
$lang->tutorial->dataNotSave = "教程任务中,数据不会保存。";
$lang->tutorial->tasks = array();
+2 -2
View File
@@ -11,7 +11,7 @@
*/
$lang->tutorial = new stdclass();
$lang->tutorial->common = '新手教程';
$lang->tutorial->desc = '通過完成一系列任務,快速瞭解禪道的基本使用方法。這可能會花費您10分鐘,你可以隨時退出任務。';
$lang->tutorial->desc = '通過完成一系列任務,快速瞭解禪道的基本使用方法。這可能會花費你10分鐘,你可以隨時退出任務。';
$lang->tutorial->start = '立即開始';
$lang->tutorial->exit = '退出教程';
$lang->tutorial->congratulation = '恭喜,你已完成了所有任務!';
@@ -29,7 +29,7 @@ $lang->tutorial->requiredTip = '【%s】為必填項';
$lang->tutorial->congratulateTask = '恭喜,你完成了任務 【<span class="task-name-current"></span>】!';
$lang->tutorial->serverErrorTip = '發生了一些錯誤。';
$lang->tutorial->ajaxSetError = '必須指定已完成的任務,如果要重置任務,請設置值為空。';
$lang->tutorial->novice = "您可能初次使用禪道,是否進入新手教程";
$lang->tutorial->novice = "你可能初次使用禪道,是否進入新手教程";
$lang->tutorial->dataNotSave = "教程任務中,數據不會保存。";
$lang->tutorial->tasks = array();
+2 -2
View File
@@ -291,7 +291,7 @@ $(function()
if($required.length)
{
var val = $required.val();
if(val === undefined || val === null || val === '')
if(val === undefined || val === null || val === '' || val === '0')
{
targetStatus.form = false;
if(!targetStatus.waitFeild) targetStatus.waitFeild = $required;
@@ -340,7 +340,7 @@ $(function()
if(targetStatus.form)
{
$submitTarget.addClass('active');
if(task.nav.submit) showToolTip($form.find(task.nav.submit), $submitTarget.text());
if(task.nav.submit) showToolTip($form.find(task.nav.submit), $submitTarget.text(), {placement: 'top'});
}
else
{
+3 -3
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long