This commit is contained in:
zhujinyong
2021-09-08 15:35:04 +08:00
60 changed files with 264 additions and 212 deletions
+3 -4
View File
@@ -588,7 +588,7 @@ function selectAll(checker, scope, type)
{
if(type == 'button')
{
var check = $(checker).data('check');
var check = $('#' + scope + ' input:checkbox').length == $('#' + scope + ' input:checkbox:checked').length ? false : true;
$('#' + scope + ' input').each(function()
{
$(this).prop("checked", check)
@@ -607,12 +607,11 @@ function selectAll(checker, scope, type)
{
if(type == 'button')
{
var check = $(checker).data('check');
var check = $('input:checkbox').length == $('input:checkbox:checked').length ? false : true;
$('input:checkbox').each(function()
{
$(this).prop("checked", check)
});
$(checker).data('check', check == true ? false :true);
}
else if(type == 'checkbox')
{
@@ -632,7 +631,7 @@ EOT;
}
elseif($type == 'button')
{
$string .= "<input type='button' name='allchecker' id='allchecker' data-check=true class='btn btn-select-all $class' value='{$lang->selectAll}' onclick='selectAll(this, \"$scope\", \"$type\")' />";
$string .= "<input type='button' name='allchecker' id='allchecker' class='btn btn-select-all $class' value='{$lang->selectAll}' onclick='selectAll(this, \"$scope\", \"$type\")' />";
}
return $string;
+6 -5
View File
@@ -14,6 +14,7 @@
.table .c-progress {width: 60px;}
.table .c-estimate {width: 85px;}
.c-hours {text-align: right !important; padding-right: 24px !important;}
.table .c-burn {width: 150px;}
</style>
<?php if(empty($executionStats)): ?>
<div class='empty-tip'><?php common::printLink('execution', 'create', '', "<i class='icon-plus'></i> " . $lang->execution->create, '', "class='btn btn-primary'")?></div>
@@ -32,13 +33,13 @@
<?php endif;?>
<th class="c-progress"><?php echo $lang->execution->progress;?></th>
<?php if($longBlock):?>
<th><?php echo $lang->execution->burn;?></th>
<th class="c-burn"><?php echo $lang->execution->burn;?></th>
<?php endif;?>
</tr>
</thead>
<tbody class="text-center">
<?php $id = 0; ?>
<?php foreach($executionStats as $execution):?>
<?php $id = 0; ?>
<?php foreach($executionStats as $execution):?>
<?php
$appid = isset($_GET['entry']) ? "class='app-btn text-center' data-id='{$this->get->entry}'" : "class='text-center'";
$viewLink = $this->createLink('execution', 'task', 'executionID=' . $execution->id);
@@ -67,8 +68,8 @@
<?php if($longBlock):?>
<td id='spark-<?php echo $id++?>' class='no-padding text-left sparkline' values='<?php echo join(',', $execution->burns);?>'></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
+1
View File
@@ -39,6 +39,7 @@ $lang->report = new stdclass();
$lang->repo = new stdclass();
$lang->jenkins = new stdclass();
$lang->gitlab = new stdclass();
$lang->mr = new stdclass();
$lang->compile = new stdclass();
$lang->job = new stdclass();
$lang->svn = new stdclass();
+2 -7
View File
@@ -358,7 +358,7 @@ class commonModel extends model
$html .= "<i class='icon icon-plus-solid-circle text-secondary'></i>";
$html .= "</a><ul class='dropdown-menu pull-right create-list'>";
$showCreateList = $lastIsDivider = $needPrintDivider = false;
$showCreateList = $needPrintDivider = false;
$productID = isset($_SESSION['product']) ? $_SESSION['product'] : 0;
if(!$productID and $app->user->view->products) $productID = current(explode(',', $app->user->view->products));
@@ -379,16 +379,11 @@ class commonModel extends model
if(common::hasPriv($objectType, $createMethod))
{
/* Determines whether to print a divider. */
if(!$lastIsDivider and $needPrintDivider and $showCreateList)
if($needPrintDivider and $showCreateList)
{
$html .= '<li class="divider"></li>';
$lastIsDivider = true;
$needPrintDivider = false;
}
else
{
$lastIsDivider = false;
}
$showCreateList = true;
$isOnlyBody = $objectType == 'doc';
+45 -4
View File
@@ -42,8 +42,23 @@
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item {background-color: transparent; border: none; padding: 0; text-align: center;}
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item:hover {box-shadow: none;}
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item > .title {white-space: normal;}
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-item {text-align: center;}
#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: ellipsis; 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-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"] {box-shadow: 2px 0 0 #fff;}
#kanbanList .kanban-lane-col[data-type="doingProject"] + .kanban-lane-col {border-left: none;}
#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%; padding: 10px;}
#kanbanList .project-row > .project-col + .project-col {padding: 10px 9px 10px 11px;}
#kanbanList .project-row > .execution-item {position: absolute!important; left: 100%; top: 0}
</style>
<script>
/**
@@ -237,12 +252,13 @@ function renderReleaseItem(item, $item)
}
$title.appendTo($item);
}
$title.text(item.name).attr('title', item.name);
$title.html('<span class="text">' + item.name + '</span>')
.attr('title', item.name);
if(item.marker === '1')
{
if(!$title.find('.icon').length)
{
$title.append('&nbsp;<i class="icon icon-flag text-red"></i>');
$title.addClass('has-icon').append('<i class="icon icon-flag text-red"></i>');
}
}
else
@@ -253,6 +269,31 @@ function renderReleaseItem(item, $item)
return $item;
}
/**
* Render project item
* @param {Object} item Project item object
* @param {JQuery} $item Kanban item element
* @param {Object} col Column object
* @returns {JQuery} $item Kanban item element
*/
function renderDoingProjectItem(item, $item)
{
$item.removeClass('kanban-item').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);
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);
renderExecutionItem(item, $executionItem);
}
return $item;
}
/** All build-in columns renderers */
if(!window.columnRenderers) window.columnRenderers =
{
@@ -260,7 +301,7 @@ if(!window.columnRenderers) window.columnRenderers =
unexpiredPlan: renderPlanItem,
waitProject: renderProjectItem,
closedProject: renderProjectItem,
doingProject: renderProjectItem,
doingProject: renderDoingProjectItem,
doingExecution: renderExecutionItem,
normalRelease: renderReleaseItem,
};
+1
View File
@@ -23,3 +23,4 @@
.c-limited {width: 110px;}
.c-actions {width: 90px;}
.c-hours {width: 90px;}
+11 -7
View File
@@ -694,10 +694,10 @@ class executionModel extends model
public function start($executionID)
{
$oldExecution = $this->getById($executionID);
$now = helper::now();
$now = helper::now();
$execution = fixer::input('post')
->add('realBegan', $now)
->add('realBegan', helper::today())
->setDefault('status', 'doing')
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
@@ -718,7 +718,8 @@ class executionModel extends model
public function putoff($executionID)
{
$oldExecution = $this->getById($executionID);
$now = helper::now();
$now = helper::now();
$execution = fixer::input('post')
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
@@ -746,7 +747,8 @@ class executionModel extends model
public function suspend($executionID)
{
$oldExecution = $this->getById($executionID);
$now = helper::now();
$now = helper::now();
$execution = fixer::input('post')
->setDefault('status', 'suspended')
->setDefault('lastEditedBy', $this->app->user->account)
@@ -771,7 +773,8 @@ class executionModel extends model
public function activate($executionID)
{
$oldExecution = $this->getById($executionID);
$now = helper::now();
$now = helper::now();
$execution = fixer::input('post')
->setDefault('status', 'doing')
->setDefault('lastEditedBy', $this->app->user->account)
@@ -838,10 +841,11 @@ class executionModel extends model
public function close($executionID)
{
$oldExecution = $this->getById($executionID);
$now = helper::now();
$now = helper::now();
$execution = fixer::input('post')
->setDefault('status', 'closed')
->setDefault('realEnd', $now)
->setDefault('realEnd', helper::today())
->setDefault('closedBy', $this->app->user->account)
->setDefault('closedDate', $now)
->setDefault('lastEditedBy', $this->app->user->account)
+8 -6
View File
@@ -121,12 +121,13 @@ function setExportTPL()
/**
* Set whether part download.
*
* @param input target
* @access public
* @return void
*/
function setPart(t)
function setPart(target)
{
if($(t).prop("checked"))
if($(target).prop("checked"))
{
$("#submit").attr("onclick", 'setPartDownloading();');
}
@@ -147,10 +148,10 @@ var partQueue = new Array();
function setPartDownloading()
{
var partNum = 10000;
var total = $('.pager', window.parent.document).data('rec-total');
for(var i=0; i < total; i = i + partNum)
var total = $('.pager', window.parent.document).data('rec-total');
for(var i = 0; i < total; i = i + partNum)
{
partQueue.push(i+','+partNum);
partQueue.push(i + ',' + partNum);
}
$.cookie('downloading', 0);
$('#mainContent').addClass('loading');
@@ -170,7 +171,8 @@ function setPartDownloading()
*/
function startPartDownloading()
{
if($.cookie('downloading') == 1){
if($.cookie('downloading') == 1)
{
var limit = partQueue.shift();
if(limit)
{
+2 -1
View File
@@ -1171,7 +1171,8 @@ $lang->mr->methodOrder[10] = 'create';
$lang->mr->methodOrder[15] = 'browse';
$lang->mr->methodOrder[20] = 'edit';
$lang->mr->methodOrder[25] = 'delete';
$lang->mr->methodOrder[35] = 'settings';
$lang->mr->methodOrder[35] = 'view';
$lang->mr->methodOrder[45] = 'accept';
/* Git. */
$lang->resource->git = new stdclass();
+10 -8
View File
@@ -1,15 +1,17 @@
<?php
$lang->mr = new stdclass;
$lang->mr->common = "Merge Request";
$lang->mr->create = "create";
$lang->mr->browse = "browse";
$lang->mr->list = "list";
$lang->mr->edit = "edit";
$lang->mr->delete = "delete";
$lang->mr->view = "view";
$lang->mr->create = "Create";
$lang->mr->browse = "Browse";
$lang->mr->list = "List";
$lang->mr->edit = "Edit";
$lang->mr->delete = "Delete";
$lang->mr->view = "View";
$lang->mr->accept = "Accept";
$lang->mr->source = 'source';
$lang->mr->target = 'target';
$lang->mr->viewDiff = 'view diff';
$lang->mr->viewInGitlab = 'view in GitLab';
$lang->mr->viewDiff = 'View diff';
$lang->mr->viewInGitlab = 'View in GitLab';
$lang->mr->id = 'ID';
$lang->mr->mriid = "raw MR ID";
+2
View File
@@ -1,4 +1,5 @@
<?php
$lang->mr = new stdclass;
$lang->mr->common = "合并请求";
$lang->mr->create = "创建{$lang->mr->common}";
$lang->mr->browse = "浏览{$lang->mr->common}";
@@ -6,6 +7,7 @@ $lang->mr->list = $lang->mr->browse;
$lang->mr->edit = "编辑{$lang->mr->common}";
$lang->mr->delete = "删除{$lang->mr->common}";
$lang->mr->view = "{$lang->mr->common}详情";
$lang->mr->accept = "合并请求";
$lang->mr->source = '源项目分支';
$lang->mr->target = '目标项目分支';
$lang->mr->viewDiff = '比对代码';
+4 -4
View File
@@ -31,12 +31,12 @@
<tr>
<?php $vars = "objectID=$objectID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?>
<th class='w-60px text-left'><?php common::printOrderLink('id', $orderBy, $vars, $lang->mr->id); ?></th>
<th class='text-left'><?php common::printOrderLink('title', $orderBy, $vars, $lang->mr->title); ?></th>
<th class='w-200px text-left'><?php common::printOrderLink('title', $orderBy, $vars, $lang->mr->title); ?></th>
<th class='text-left'><?php common::printOrderLink('sourceProject', $orderBy, $vars, $lang->mr->sourceProject); ?></th>
<th class='w-100px text-left'><?php common::printOrderLink('sourceBranch', $orderBy, $vars, $lang->mr->sourceBranch); ?></th>
<th class='w-120px text-left'><?php common::printOrderLink('sourceBranch', $orderBy, $vars, $lang->mr->sourceBranch); ?></th>
<th class='text-left'><?php common::printOrderLink('targetProject', $orderBy, $vars, $lang->mr->targetProject); ?></th>
<th class='w-100px text-left'><?php common::printOrderLink('targetBranch', $orderBy, $vars, $lang->mr->targetBranch); ?></th>
<th class='w-100px text-left'><?php common::printOrderLink('mergeStatus', $orderBy, $vars, $lang->mr->mergeStatus); ?></th>
<th class='w-120px text-left'><?php common::printOrderLink('targetBranch', $orderBy, $vars, $lang->mr->targetBranch); ?></th>
<th class='w-120px text-left'><?php common::printOrderLink('mergeStatus', $orderBy, $vars, $lang->mr->mergeStatus); ?></th>
<th class='w-120px c-actions-4'><?php echo $lang->actions; ?></th>
</tr>
</thead>
+4 -3
View File
@@ -19,11 +19,12 @@
<table class='table table-form'>
<tr>
<th><?php echo $lang->gitlab->common;?></th>
<td class='required'><?php echo html::select('gitlabID', $gitlabHosts, '', "class='form-control'");?></td>
<!-- Use `array('') + $gitlabHosts` here because of this field must be changed when creating this MR. -->
<td class='required'><?php echo html::select('gitlabID', array('') + $gitlabHosts, '', "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->mr->sourceProject;?></th>
<td class='required'>
<td>
<div class='input-group'>
<?php echo html::select('sourceProject', array(''), '', "class='form-control chosen'");?>
<span class='input-group-addon fix-border'><?php echo $lang->mr->sourceBranch ?></span>
@@ -33,7 +34,7 @@
</tr>
<tr>
<th><?php echo $lang->mr->targetProject;?></th>
<td class='required'>
<td>
<div class='input-group'>
<?php echo html::select('targetProject', array(''), '', "class='form-control chosen'");?>
<span class='input-group-addon fix-border'><?php echo $lang->mr->targetBranch ?></span>
+1 -1
View File
@@ -34,7 +34,7 @@
</tr>
<tr>
<th><?php echo $lang->mr->targetProject;?></th>
<td class='required'>
<td>
<div class='input-group'>
<span class='input-group-addon fix-border'>
<?php echo $this->loadModel('gitlab')->apiGetSingleProject($MR->gitlabID, $MR->targetProject)->name_with_namespace;?>
+2 -4
View File
@@ -113,7 +113,7 @@ class myModel extends model
$product->releases = isset($releases[$product->id]) ? $releases[$product->id] : 0;
if(isset($executions[$product->id])) $product->executions = $executions[$product->id];
$product->storyEstimateCount = isset($stories[$product->id]) ? $stories[$product->id] : 0;
if($product->status != 'closed') $unclosedCount++;
if($product->status != 'closed') $unclosedCount ++;
if($product->status == 'closed') unset($products[$key]);
}
@@ -125,7 +125,6 @@ class myModel extends model
$data->allCount = $allCount;
$data->unclosedCount = $unclosedCount;
$data->products = array_values($products);
return $data;
}
@@ -143,7 +142,7 @@ class myModel extends model
$doingProjects = array();
$projects = $this->loadModel('project')->getOverviewList('byStatus', 'all', 'id_desc');
$projectsConsumed = $this->project->getProjectsConsumed(array_keys($projects), 'this_year');
$projectsConsumed = $this->project->getProjectsConsumed(array_keys($projects), 'THIS_YEAR');
$doingCount = 0;
foreach($projects as $key => $project)
{
@@ -167,7 +166,6 @@ class myModel extends model
$data->allConsumed = $allConsumed;
$data->thisYearConsumed = $thisYearConsumed;
$data->projects = $doingProjects;
return $data;
}
+3 -3
View File
@@ -1321,15 +1321,15 @@ class product extends control
$rowspan[$i]['rows']['program'] = 1;
$programI = $i;
}
else $rowspan[$programI]['rows']['program']++;
else $rowspan[$programI]['rows']['program'] ++;
if($lastLine == '' or $product->line != $lastLine)
{
$rowspan[$i]['rows']['line'] = 1;
$lineI = $i;
}
else $rowspan[$lineI]['rows']['line']++;
else $rowspan[$lineI]['rows']['line'] ++;
$lastProgram = $product->program;
$lastLine = $product->line;
$lastLine = $product->line;
if($this->post->exportType == 'selected')
{
-8
View File
@@ -1,8 +0,0 @@
#kanbanList .kanban-lane-col[data-type="doingProject"] {box-shadow: 2px 0 0 #fff;}
#kanbanList .kanban-lane-col[data-type="doingProject"] + .kanban-lane-col {border-left: none;}
#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); box-shadow: 0 2px 0 #fff;}
#kanbanList .project-row + .project-row {margin-top: 2px;}
#kanbanList .project-row > .project-col {float: left; width: 50%; padding: 10px;}
#kanbanList .project-row > .project-col + .project-col {padding: 10px 9px 10px 11px;}
#kanbanList .project-row > .execution-item {position: absolute!important; left: 100%; top: 0}
+3 -3
View File
@@ -41,9 +41,9 @@ $(function()
var $tbody = $('#productTableList');
$tbody.find('.program-checkbox').each(function()
{
var $checkbox = $(this);
var $tr = $checkbox.closest('tr');
var rowID = $tr.data('id');
var $checkbox = $(this);
var $tr = $checkbox.closest('tr');
var rowID = $tr.data('id');
var isAllRowChecked = !$tbody.find('tr[data-parent="' + rowID + '"] input:checkbox:not(:checked)').length;
$checkbox.toggleClass('checked', isAllRowChecked);
});
+5 -31
View File
@@ -71,10 +71,10 @@ function processKanbanData(key, programsData)
var productExecutions = classicExecution[productID];
if(productExecutions)
{
console.log(productExecutions);
$.each(productExecutions, function(executionID, execution)
$.each(productExecutions, function(_, execution)
{
if(!execution || !execution.id) return;
var executionID = execution.id;
var executionItem = $.extend({}, execution, {id: 'execution-' + executionID, _id: executionID});
items.doingExecution.push(executionItem);
});
@@ -106,41 +106,15 @@ function processKanbanData(key, programsData)
return {id: kanbanId, columns: columns, lanes: lanes};
}
/**
* Render project item
* @param {Object} item Project item object
* @param {JQuery} $item Kanban item element
* @param {Object} col Column object
* @returns {JQuery} $item Kanban item element
*/
function renderDoingProjectItem(item, $item)
{
$item.removeClass('kanban-item').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);
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);
renderExecutionItem(item, $executionItem);
}
return $item;
}
$(function()
{
/* Add custom renderer for doing project */
addColumnRenderer('doingProject', renderDoingProjectItem);
/* Init all kanbans */
$.each(kanbanList, function(key, programsData)
{
var $kanban = $('#kanban-' + key);
if(!$kanban.length) return;
var data = processKanbanData(key, programsData);
$('#kanban-' + key).kanban({data: data});
$kanban.kanban({data: data, noLaneName: isClassicMode});
});
});
+2
View File
@@ -18,6 +18,7 @@
<?php else:?>
<div id='kanbanList'>
<?php foreach($kanbanList as $type => $programs):?>
<?php if(empty($programs)) continue;?>
<div class='panel kanban-panel'>
<div class='panel-heading'>
<strong><?php echo $type == 'my' ? $lang->product->myProduct : $lang->product->otherProduct;?></strong>
@@ -48,6 +49,7 @@ $userPrivs['productplan'] = common::hasPriv('productplan', 'view');
$userPrivs['project'] = common::hasPriv('project', 'index');
$userPrivs['execution'] = common::hasPriv('execution', 'task');
$userPrivs['release'] = common::hasPriv('release', 'view');
js::set('isClassicMode', $config->systemMode != 'new');
js::set('kanbanColumns', $kanbanColumns);
js::set('userPrivs', $userPrivs);
js::set('kanbanList', $kanbanList);
+7
View File
@@ -75,6 +75,13 @@ function computeWorkDays(currentID)
{
beginDate = $('#begin').val();
endDate = $('#end').val();
var begin = new Date(beginDate.replace(/-/g,"/"));
var end = new Date(endDate.replace(/-/g,"/"));
var time = end.getTime() - begin.getTime();
var days = parseInt(time / (1000 * 60 * 60 * 24)) + 1;
if(days != $("input:radio[name='delta']:checked").val()) $("input:radio[name='delta']:checked").attr('checked', false);
if(endDate == longTime) $("#delta999").prop('checked', true);
}
if(beginDate && endDate)
+1 -3
View File
@@ -61,7 +61,6 @@ function processKanbanData(key, programsData)
/* doing projects and executions */
items.doingProject = [];
items.doingExecution = [];
var doingProjects = product.projects && product.projects.doing;
if(doingProjects)
{
@@ -73,8 +72,7 @@ function processKanbanData(key, programsData)
var execution = project.execution;
if(!execution || !execution.id) return;
var executionItem = $.extend({}, execution, {id: 'execution-' + execution.id, _id: execution.id});
items.doingExecution.push(executionItem);
projectItem.execution = execution;
});
}
+3 -1
View File
@@ -176,7 +176,7 @@ class programModel extends model
->andWhere('end')->gt(helper::today())
->fetchGroup('product');
/* Get all products linked projects and executions. */
/* Get all products linked projects. */
$projectGroup = $this->dao->select('t1.product, t2.id, t2.name, t2.status, t2.end')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')
->on('t1.project = t2.id')
@@ -184,6 +184,7 @@ class programModel extends model
->andWhere('t1.product')->in($productPairs)
->andWhere('t2.status')->ne('closed')
->andWhere('t2.type')->eq('project')
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->projects)->fi()
->fetchGroup('product');
$projectPairs = array();
@@ -201,6 +202,7 @@ class programModel extends model
->where('type')->in('sprint,stage')
->andWhere('status')->eq('doing')
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->orderBy('id_asc')
->fetchAll('project');
+1 -1
View File
@@ -87,7 +87,7 @@
<th><?php echo $lang->project->dateRange;?></th>
<td>
<div class='input-group'>
<?php echo html::input('begin', date('Y-m-d'), "class='form-control form-date' placeholder='" . $lang->project->begin . "' required");?>
<?php echo html::input('begin', date('Y-m-d'), "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->project->begin . "' required");?>
<span class='input-group-addon'><?php echo $lang->project->to;?></span>
<?php echo html::input('end', '', "class='form-control form-date' placeholder='" . $lang->project->end . "' required");?>
</div>
+1 -1
View File
@@ -33,7 +33,7 @@
$kanbanColumns = array();
$kanbanColumns['unclosedProduct'] = array('name' => $lang->program->kanban->openProducts, 'type' => 'unclosedProduct');
$kanbanColumns['unexpiredPlan'] = array('name' => $lang->program->kanban->unexpiredPlans, 'type' => 'unexpiredPlan');
$kanbanColumns['waitProject'] = array('name' => $lang->program->kanban->waitingProjects, 'type' => 'waitProject');
$kanbanColumns['waitProject'] = array('name' => $lang->program->kanban->waitingProjects, 'type' => 'waitProject');
$kanbanColumns['doingProject'] = array('name' => $lang->program->kanban->doingProjects, 'type' => 'doingProject');
$kanbanColumns['doingExecution'] = array('name' => $lang->program->kanban->doingExecutions, 'type' => 'doingExecution');
$kanbanColumns['normalRelease'] = array('name' => $lang->program->kanban->normalReleases, 'type' => 'normalRelease');
+2 -1
View File
@@ -80,7 +80,8 @@ function computeWorkDays(currentID)
var end = new Date(endDate.replace(/-/g,"/"));
var time = end.getTime() - begin.getTime();
var days = parseInt(time / (1000 * 60 * 60 * 24)) + 1;
if(days != $("input:radio[name='delta']:checked").val() && $("input:radio[name='delta']:checked").val() != 999) $("input:radio[name='delta']:checked").attr('checked',false);
if(days != $("input:radio[name='delta']:checked").val()) $("input:radio[name='delta']:checked").attr('checked', false);
if(endDate == longTime) $("#delta999").prop('checked', true);
}
if(beginDate && endDate)
+6 -4
View File
@@ -35,15 +35,15 @@ function processKanbanData(key, programGroup)
$.each(statusProjects, function(_, project)
{
var projectID = project.id;
itemsList.push($.extend({}, project, {id: 'project-' + projectID, _id: projectID}));
var projectItem = $.extend({}, project, {id: 'project-' + projectID, _id: projectID});
itemsList.push(projectItem);
if(status === 'doing')
{
var execution = latestExecutions[projectID];
if(execution && execution.id)
{
var executionItem = $.extend({}, execution, {id: 'execution-' + execution.id, _id: execution.id});
items.doingExecution = [executionItem];
projectItem.execution = $.extend({}, execution, {id: 'execution-' + execution.id, _id: execution.id});
}
}
});
@@ -62,6 +62,8 @@ $(function()
/* Init all kanbans */
$.each(kanbanGroup, function(key, programGroup)
{
$('#kanban-' + key).kanban({data: processKanbanData(key, programGroup)});
var $kanban = $('#kanban-' + key);
if(!$kanban.length) return;
$kanban.kanban({data: processKanbanData(key, programGroup)});
});
});
+6 -4
View File
@@ -411,7 +411,7 @@ class projectModel extends model
$totalConsumeds = $this->dao->select('project,ROUND(SUM(consumed), 1) AS totalConsumed')
->from(TABLE_TASK)
->where('project')->in($projectIdList)
->beginIF($time == 'this_year')->andWhere('realStarted')->ge(date("Y-01-01 00:00:00"))->fi()
->beginIF($time == 'THIS_YEAR')->andWhere('realStarted')->ge(date("Y-01-01 00:00:00"))->fi()
->andWhere('deleted')->eq(0)
->andWhere('parent')->lt(1)
->groupBy('project')
@@ -421,7 +421,7 @@ class projectModel extends model
{
$project = new stdClass();
$project->totalConsumed = isset($totalConsumeds[$projectID]->totalConsumed) ? $totalConsumeds[$projectID]->totalConsumed : 0;
$projects[$projectID] = $project;
$projects[$projectID] = $project;
}
return $projects;
@@ -1113,7 +1113,7 @@ class projectModel extends model
$now = helper::now();
$project = fixer::input('post')
->add('realBegan', $now)
->add('realBegan', helper::today())
->setDefault('status', 'doing')
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
@@ -1135,6 +1135,7 @@ class projectModel extends model
{
$oldProject = $this->getById($projectID);
$now = helper::now();
$project = fixer::input('post')
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
@@ -1185,6 +1186,7 @@ class projectModel extends model
{
$oldProject = $this->getById($projectID);
$now = helper::now();
$project = fixer::input('post')
->setDefault('status', 'doing')
->setDefault('lastEditedBy', $this->app->user->account)
@@ -1252,6 +1254,7 @@ class projectModel extends model
{
$oldProject = $this->getById($projectID);
$now = helper::now();
$project = fixer::input('post')
->setDefault('status', 'closed')
->setDefault('closedBy', $this->app->user->account)
@@ -1853,7 +1856,6 @@ class projectModel extends model
{
$otherProjects[$topProgram][$project->status][$project->id] = $project;
}
}
return array('kanbanGroup' => array('my' => $myProjects, 'other' => $otherProjects), 'latestExecutions' => $latestExecutions);
+4 -2
View File
@@ -17,9 +17,11 @@
#projectTableList .project-name {position: relative; display: flex; align-items: center;}
#projectTableList .project-name > span,
#projectTableList .project-name > span {flex: none;}
#projectTableList .project-name > a {color: #0c60e1; display: inline-block; max-width: calc(100% - 50px); padding: 0 5px;}
#projectTableList .project-name > a {color: #0c60e1; display: inline-block; max-width: calc(100% - 50px);}
#projectTableList .project-name.has-prefix > a,
#projectTableList .project-name.has-surfix > a {max-width: calc(100% - 100px);}
#projectTableList .project-name.has-suffix > a {max-width: calc(100% - 100px);}
#projectTableList .project-name.has-prefix > a {padding-left: 5px;}
#projectTableList .project-name.has-suffix > a {padding-right: 5px;}
</style>
<div id="mainMenu" class="clearfix">
<?php if($this->config->systemMode == 'new'):?>
+1
View File
@@ -18,6 +18,7 @@
<?php else:?>
<div id='kanbanList'>
<?php foreach($kanbanGroup as $type => $projectGroup):?>
<?php if(empty($projectGroup)) continue;?>
<div class='panel kanban-panel'>
<div class='panel-heading'>
<strong><?php echo $lang->project->typeList[$type];?></strong>
+2 -2
View File
@@ -40,8 +40,8 @@
<?php unset($users[$member->account]);?>
<tr>
<td><?php echo html::input("realnames[$i]", $member->realname, "class='form-control' readonly");?></td>
<td><?php echo html::input("roles[$i]", $member->role, "class='form-control'");?></td>
<td><?php echo html::input("days[$i]", $member->days, "class='form-control'");?></td>
<td><?php echo html::input("roles[$i]", $member->role, "class='form-control'");?></td>
<td><?php echo html::input("days[$i]", $member->days, "class='form-control'");?></td>
<td>
<?php echo html::input("hours[$i]", $member->hours, "class='form-control'");?>
<?php echo html::hidden("accounts[$i]", $member->account);?>
+1 -1
View File
@@ -116,7 +116,7 @@ class projectStory extends control
*/
public function batchUnlinkStory($projectID, $storyIdList = '')
{
$storyIdList = array_filter(explode(',', $storyIdList));
$storyIdList = if(empty($storyIdList)) ? array() : array_filter(explode(',', $storyIdList));
$executionStories = $this->projectstory->getExecutionStories($projectID, $storyIdList);
$html = '';
+1 -1
View File
@@ -943,7 +943,7 @@ class searchModel extends model
{
$words = explode(' ', trim($keywords, ' '));
$markedWords = array();
$leftMark = '|0000';
$leftMark = '|0000';
$rightMark = '0000|';
foreach($words as $key => $word)
+9 -10
View File
@@ -3953,17 +3953,16 @@ class storyModel extends model
if(count($tracks) < $pager->recPerPage)
{
/* Show of child story */
/* Show sub stories. */
$storiesCopy = array();
foreach($stories as $id => $story)
{
$storiesCopy[$id] = $story;
if(isset($story->children) and count($story->children) > 0)
if(!isset($story->children) or count($story->children) == 0) continue;
foreach($story->children as $childID => $children)
{
foreach($story->children as $childID => $children)
{
$storiesCopy[$childID] = $children;
}
$storiesCopy[$childID] = $children;
}
}
$stories = $storiesCopy;
@@ -3972,10 +3971,10 @@ class storyModel extends model
{
$stories[$id] = new stdclass();
$stories[$id]->parent = $story->parent;
$stories[$id]->title = $story->title;
$stories[$id]->cases = $this->loadModel('testcase')->getStoryCases($id);
$stories[$id]->bugs = $this->loadModel('bug')->getStoryBugs($id);
$stories[$id]->tasks = $this->loadModel('task')->getStoryTasks($id);
$stories[$id]->title = $story->title;
$stories[$id]->cases = $this->loadModel('testcase')->getStoryCases($id);
$stories[$id]->bugs = $this->loadModel('bug')->getStoryBugs($id);
$stories[$id]->tasks = $this->loadModel('task')->getStoryTasks($id);
if(isset($this->config->maxVersion))
{
$stories[$id]->designs = $this->dao->select('id, name')->from(TABLE_DESIGN)->where('story')->eq($id)->fetchAll('id');
+7
View File
@@ -1,7 +1,14 @@
/**
* Confirm left.
*
* @access public
* @return void
*/
function confirmLeft()
{
if($('#left').val() === '0') return confirm(confirmRecord);
}
$(function()
{
$('.form-date').datetimepicker('setEndDate', today);
+1
View File
@@ -223,6 +223,7 @@ $lang->task->error->realStartedEmpty = '"Real Started" should not be empty.';
$lang->task->error->finishedDateEmpty = '"Finished Date" should not be empty.';
$lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Started"';
$lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.';
$lang->task->error->date = 'The date should be >= today.';
/* Report. */
$lang->task->report = new stdclass();
+1
View File
@@ -226,6 +226,7 @@ $lang->task->error->realStartedEmpty = '"Real Started" should not be empty.';
$lang->task->error->finishedDateEmpty = '"Finished Date" should not be empty.';
$lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Started"';
$lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.';
$lang->task->error->date = 'The date should be >= today.';
/* Report. */
$lang->task->report = new stdclass();
+1
View File
@@ -223,6 +223,7 @@ $lang->task->error->realStartedEmpty = '"Real Started" should not be empty.';
$lang->task->error->finishedDateEmpty = '"Finished Date" should not be empty.';
$lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Started"';
$lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.';
$lang->task->error->date = 'The date should be >= today.';
/* Report. */
$lang->task->report = new stdclass();
+1
View File
@@ -223,6 +223,7 @@ $lang->task->error->realStartedEmpty = '"Real Started" should not be empty.';
$lang->task->error->finishedDateEmpty = '"Finished Date" should not be empty.';
$lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Started"';
$lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.';
$lang->task->error->date = 'The date should be >= today.';
/* Report. */
$lang->task->report = new stdclass();
+1
View File
@@ -226,6 +226,7 @@ $lang->task->error->realStartedEmpty = '实际开始不能为空';
$lang->task->error->finishedDateEmpty = '实际完成不能为空';
$lang->task->error->finishedDateSmall = '实际完成不能小于实际开始';
$lang->task->error->alreadyConsumed = '当前选中的父任务已有消耗。';
$lang->task->error->date = '日期不能大于今天';
/* Report. */
$lang->task->report = new stdclass();
+8 -1
View File
@@ -474,6 +474,7 @@ class taskModel extends model
$task->left = 0;
$task->pri = 3;
$task->type = 'devel';
$task->project = $this->dao->select('project')->from(TABLE_PROJECT)->where('id')->eq($executionID)->fetch('project');
$this->dao->insert(TABLE_TASK)->data($task, $skip = 'id,product')
->autoCheck()
@@ -1474,12 +1475,14 @@ class taskModel extends model
public function recordEstimate($taskID)
{
$record = fixer::input('post')->get();
$today = helper::today();
/* Fix bug#3036. */
foreach($record->consumed as $id => $item) $record->consumed[$id] = trim($item);
foreach($record->left as $id => $item) $record->left[$id] = trim($item);
foreach($record->consumed as $id => $item) if(!is_numeric($item) and !empty($item)) dao::$errors[] = 'ID #' . $id . ' ' . $this->lang->task->error->totalNumber;
foreach($record->left as $id => $item) if(!is_numeric($item) and !empty($item)) dao::$errors[] = 'ID #' . $id . ' ' . $this->lang->task->error->leftNumber;
foreach($record->dates as $id => $item) if($item > $today) dao::$errors[] = 'ID #' . $id . ' ' . $this->lang->task->error->date;
if(dao::isError()) return false;
$estimates = array();
@@ -2340,7 +2343,11 @@ class taskModel extends model
{
$oldEstimate = $this->getEstimateById($estimateID);
$estimate = fixer::input('post')->get();
$task = $this->getById($oldEstimate->task);
$today = helper::today();
if($estimate->date > $today) return dao::$errors[] = $this->lang->task->error->date;
$task = $this->getById($oldEstimate->task);
$this->dao->update(TABLE_TASKESTIMATE)->data($estimate)
->autoCheck()
->check('consumed', 'notempty')
+1 -1
View File
@@ -23,7 +23,7 @@
<table class='table table-form'>
<tr>
<th class='w-80px'><?php echo $lang->task->date;?></th>
<td class='w-p45'><?php echo html::input('date', $estimate->date, 'class="form-control form-date" readonly');?></td>
<td class='w-p45'><?php echo html::input('date', $estimate->date, 'class="form-control form-date"');?></td>
<td></td>
</tr>
<tr>
+1 -1
View File
@@ -86,7 +86,7 @@
<?php for($i = 1; $i <= 3; $i++):?>
<tr class="text-center">
<td><?php echo $i . html::hidden("id[$i]", $i);?></td>
<td><?php echo html::input("dates[$i]", helper::today(), "class='form-control text-center form-date' readonly");?></td>
<td><?php echo html::input("dates[$i]", helper::today(), "class='form-control text-center form-date'");?></td>
<td><?php echo html::input("consumed[$i]", '', "class='form-control text-center'");?></td>
<td><?php echo html::input("left[$i]", '', "class='form-control text-center left'");?></td>
<td class="text-left"><?php echo html::textarea("work[$i]", '', "class='form-control' style='height:50px;'");?></td>
+7 -6
View File
@@ -568,7 +568,8 @@ class testcaseModel extends model
->andWhere('deleted')->eq(0)
->beginIF($auto != 'skip' and $auto != 'unit')->andWhere('auto')->ne('unit')->fi()
->beginIF($auto == 'unit')->andWhere('auto')->eq('unit')->fi()
->orderBy($orderBy)->page($pager)->fetchAll('id');
->orderBy($orderBy)->page($pager)
->fetchAll('id');
}
/**
@@ -589,7 +590,7 @@ class testcaseModel extends model
{
$modules = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0';
$cases = $this->dao->select('t1.*, t2.title as storyTitlen')->from(TABLE_CASE)->alias('t1')
$cases = $this->dao->select('t1.*, t2.title as storyTitle')->from(TABLE_CASE)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
->beginIF($productID)->where('t1.product')->eq((int) $productID)->fi()
->beginIF($productID == 0)->where('t1.product')->in($this->app->user->view->products)->fi()
@@ -600,7 +601,8 @@ class testcaseModel extends model
->beginIF($auto == 'unit')->andWhere('t1.auto')->eq('unit')->fi()
->beginIF($auto != 'unit')->andWhere('t1.auto')->ne('unit')->fi()
->andWhere('t1.deleted')->eq('0')
->orderBy($orderBy)->page($pager)->fetchAll('id');
->orderBy($orderBy)->page($pager)
->fetchAll('id');
return $this->appendData($cases);
}
@@ -1006,10 +1008,9 @@ class testcaseModel extends model
$actions = array();
$this->loadModel('action');
$oldCases = $this->getByList($caseIdList);
foreach($caseIdList as $caseID)
{
$oldCase = $this->getById($caseID);
$case = new stdClass();
$case->lastEditedBy = $this->app->user->account;
$case->lastEditedDate = $now;
@@ -1017,7 +1018,7 @@ class testcaseModel extends model
$this->dao->update(TABLE_CASE)->data($case)->autoCheck()->where('id')->eq($caseID)->exec();
$actionID = $this->action->create('case', $caseID, 'Edited', '', ucfirst($result));
$changes = common::createChanges($oldCase, $case);
$changes = common::createChanges($oldCases[$caseID], $case);
$this->action->logHistory($actionID, $changes);
}
}
+1
View File
@@ -85,6 +85,7 @@ function loadExecutionRelated(executionID)
* Load execution builds.
*
* @param int $executionID
* @param int $selected
* @access public
* @return void
*/
+11 -11
View File
@@ -124,17 +124,17 @@ $lang->testtask->fail = 'Fehlgeschlagen';
$lang->testtask->showResult = 'Ausführungen <span class="text-info">%s</span>';
$lang->testtask->showFail = 'Fehlgeschlagen <span class="text-danger">%s</span>';
$lang->testtask->confirmDelete = 'Möchten Sie dieses Build löschen?';
$lang->testtask->confirmUnlinkCase = 'Möchten Sie die Verknüpfung zu dem Fall aufheben?';
$lang->testtask->noticeNoOther = 'Es existieren keine weiteren Testaufgaben für dieses Produkt';
$lang->testtask->noTesttask = 'Keine Testaufgaben. ';
$lang->testtask->checkLinked = "Please check whether the product that the test request is linked to has been linked to a {$lang->executionCommon}.";
$lang->testtask->noImportData = 'The imported XML does not parse the data.';
$lang->testtask->unitXMLFormat = 'Please select a file in JUnit XML format.';
$lang->testtask->titleOfAuto = "%s automated testing";
$lang->testtask->cannotBeParsed = 'The content of the imported XML file is in the wrong format and cannot be parsed.';
$lang->testtask->finishedDateError = 'Actual Finished Date cannot be <= Begin Date %s';
$lang->testtask->finishedDateError2 = 'Actual Finished Date cannot be > Today';
$lang->testtask->confirmDelete = 'Möchten Sie dieses Build löschen?';
$lang->testtask->confirmUnlinkCase = 'Möchten Sie die Verknüpfung zu dem Fall aufheben?';
$lang->testtask->noticeNoOther = 'Es existieren keine weiteren Testaufgaben für dieses Produkt';
$lang->testtask->noTesttask = 'Keine Testaufgaben. ';
$lang->testtask->checkLinked = "Please check whether the product that the test request is linked to has been linked to a {$lang->executionCommon}.";
$lang->testtask->noImportData = 'The imported XML does not parse the data.';
$lang->testtask->unitXMLFormat = 'Please select a file in JUnit XML format.';
$lang->testtask->titleOfAuto = "%s automated testing";
$lang->testtask->cannotBeParsed = 'The content of the imported XML file is in the wrong format and cannot be parsed.';
$lang->testtask->finishedDateLess = 'Actual Finished Date cannot be <= Begin Date %s';
$lang->testtask->finishedDateMore = 'Actual Finished Date cannot be > Today';
$lang->testtask->assignedToMe = 'Meine';
$lang->testtask->allCases = 'Alle Fälle';
+11 -11
View File
@@ -127,17 +127,17 @@ $lang->testtask->fail = 'Failed';
$lang->testtask->showResult = 'Run <span class="text-info">%s</span> times';
$lang->testtask->showFail = 'Failed <span class="text-danger">%s</span> times';
$lang->testtask->confirmDelete = 'Do you want to delete this build?';
$lang->testtask->confirmUnlinkCase = 'Do you want to unlink this case?';
$lang->testtask->noticeNoOther = 'No test builds for this product.';
$lang->testtask->noTesttask = 'No requests. ';
$lang->testtask->checkLinked = "Please check whether the product that the test request is linked to has been linked to a {$lang->executionCommon}.";
$lang->testtask->noImportData = 'The imported XML does not parse the data.';
$lang->testtask->unitXMLFormat = 'Please select a file in JUnit XML format.';
$lang->testtask->titleOfAuto = "%s automated testing";
$lang->testtask->cannotBeParsed = 'The content of the imported XML file is in the wrong format and cannot be parsed.';
$lang->testtask->finishedDateError = 'Actual Finished Date cannot be <= Begin Date %s';
$lang->testtask->finishedDateError2 = 'Actual Finished Date cannot be > Today';
$lang->testtask->confirmDelete = 'Do you want to delete this build?';
$lang->testtask->confirmUnlinkCase = 'Do you want to unlink this case?';
$lang->testtask->noticeNoOther = 'No test builds for this product.';
$lang->testtask->noTesttask = 'No requests. ';
$lang->testtask->checkLinked = "Please check whether the product that the test request is linked to has been linked to a {$lang->executionCommon}.";
$lang->testtask->noImportData = 'The imported XML does not parse the data.';
$lang->testtask->unitXMLFormat = 'Please select a file in JUnit XML format.';
$lang->testtask->titleOfAuto = "%s automated testing";
$lang->testtask->cannotBeParsed = 'The content of the imported XML file is in the wrong format and cannot be parsed.';
$lang->testtask->finishedDateLess = 'Actual Finished Date cannot be <= Begin Date %s';
$lang->testtask->finishedDateMore = 'Actual Finished Date cannot be > Today';
$lang->testtask->assignedToMe = 'AssignedToMe';
$lang->testtask->allCases = 'All Cases';
+11 -11
View File
@@ -124,17 +124,17 @@ $lang->testtask->fail = 'Echec';
$lang->testtask->showResult = 'Jouée <span class="text-info">%s</span> fois';
$lang->testtask->showFail = 'Echouée <span class="text-danger">%s</span> fois';
$lang->testtask->confirmDelete = 'Voulez-vous supprimer ce build ?';
$lang->testtask->confirmUnlinkCase = 'Voulez-vous détacher ce CasTest ?';
$lang->testtask->noticeNoOther = "Il n'y a pas de Campagnes de Recette pour ce product.";
$lang->testtask->noTesttask = 'Pas de campagne. ';
$lang->testtask->checkLinked = "Vérifiez si le product auquel la campagne de recette est associée est bien lié à un projet.";
$lang->testtask->noImportData = "Le XML importé ne parse pas les données.";
$lang->testtask->unitXMLFormat = 'Veuillez sélectionner un fichier au format XML JUnit.';
$lang->testtask->titleOfAuto = "%s tests automatisés";
$lang->testtask->cannotBeParsed = 'The content of the imported XML file is in the wrong format and cannot be parsed.';
$lang->testtask->finishedDateError = 'Actual Finished Date cannot be <= Begin Date %s';
$lang->testtask->finishedDateError2 = 'Actual Finished Date cannot be > Today';
$lang->testtask->confirmDelete = 'Voulez-vous supprimer ce build ?';
$lang->testtask->confirmUnlinkCase = 'Voulez-vous détacher ce CasTest ?';
$lang->testtask->noticeNoOther = "Il n'y a pas de Campagnes de Recette pour ce product.";
$lang->testtask->noTesttask = 'Pas de campagne. ';
$lang->testtask->checkLinked = "Vérifiez si le product auquel la campagne de recette est associée est bien lié à un projet.";
$lang->testtask->noImportData = "Le XML importé ne parse pas les données.";
$lang->testtask->unitXMLFormat = 'Veuillez sélectionner un fichier au format XML JUnit.';
$lang->testtask->titleOfAuto = "%s tests automatisés";
$lang->testtask->cannotBeParsed = 'The content of the imported XML file is in the wrong format and cannot be parsed.';
$lang->testtask->finishedDateLess = 'Actual Finished Date cannot be <= Begin Date %s';
$lang->testtask->finishedDateMore = 'Actual Finished Date cannot be > Today';
$lang->testtask->assignedToMe = 'Affecté à Moi';
$lang->testtask->allCases = 'Tous les CasTests';
+11 -11
View File
@@ -124,17 +124,17 @@ $lang->testtask->fail = 'Thất bại';
$lang->testtask->showResult = 'Chạy <span class="text-info">%s</span> lần';
$lang->testtask->showFail = 'Thất bại <span class="text-danger">%s</span> lần';
$lang->testtask->confirmDelete = 'Bạn có muốn xóa bản dựng này?';
$lang->testtask->confirmUnlinkCase = 'Bạn có muốn hủy liên kết tình huống này?';
$lang->testtask->noticeNoOther = 'Không có test builds cho sản phẩm này.';
$lang->testtask->noTesttask = 'Không có yêu cầu. ';
$lang->testtask->checkLinked = "Vui lòng kiểm tra sản phẩm đó mà yêu cầu test này là liên kết tới một dự án.";
$lang->testtask->noImportData = 'The imported XML does not parse the data.';
$lang->testtask->unitXMLFormat = 'Please select a file in JUnit XML format.';
$lang->testtask->titleOfAuto = "%s automated testing";
$lang->testtask->cannotBeParsed = 'The content of the imported XML file is in the wrong format and cannot be parsed.';
$lang->testtask->finishedDateError = 'Actual Finished Date cannot be <= Begin Date %s';
$lang->testtask->finishedDateError2 = 'Actual Finished Date cannot be > Today';
$lang->testtask->confirmDelete = 'Bạn có muốn xóa bản dựng này?';
$lang->testtask->confirmUnlinkCase = 'Bạn có muốn hủy liên kết tình huống này?';
$lang->testtask->noticeNoOther = 'Không có test builds cho sản phẩm này.';
$lang->testtask->noTesttask = 'Không có yêu cầu. ';
$lang->testtask->checkLinked = "Vui lòng kiểm tra sản phẩm đó mà yêu cầu test này là liên kết tới một dự án.";
$lang->testtask->noImportData = 'The imported XML does not parse the data.';
$lang->testtask->unitXMLFormat = 'Please select a file in JUnit XML format.';
$lang->testtask->titleOfAuto = "%s automated testing";
$lang->testtask->cannotBeParsed = 'The content of the imported XML file is in the wrong format and cannot be parsed.';
$lang->testtask->finishedDateLess = 'Actual Finished Date cannot be <= Begin Date %s';
$lang->testtask->finishedDateMore = 'Actual Finished Date cannot be > Today';
$lang->testtask->assignedToMe = 'Giao cho bạn';
$lang->testtask->allCases = 'Tất cả tình huống';
+11 -11
View File
@@ -127,17 +127,17 @@ $lang->testtask->fail = '失败';
$lang->testtask->showResult = '共执行<span class="text-info">%s</span>次';
$lang->testtask->showFail = '失败<span class="text-danger">%s</span>次';
$lang->testtask->confirmDelete = '您确认要删除该测试单吗?';
$lang->testtask->confirmUnlinkCase = '您确认要移除该用例吗?';
$lang->testtask->noticeNoOther = '该产品还没有其他测试单';
$lang->testtask->noTesttask = '暂时没有测试单。';
$lang->testtask->checkLinked = "请检查测试单的产品是否与{$lang->executionCommon}相关联";
$lang->testtask->noImportData = '导入的XML没有解析出数据。';
$lang->testtask->unitXMLFormat = '请选择Junit XML 格式的文件。';
$lang->testtask->titleOfAuto = "%s 自动化测试";
$lang->testtask->cannotBeParsed = '导入的XML文件内容格式错误,无法解析。';
$lang->testtask->finishedDateError = '实际完成日期不能小于开始日期%s';
$lang->testtask->finishedDateError2 = '实际完成日期不能大于今天';
$lang->testtask->confirmDelete = '您确认要删除该测试单吗?';
$lang->testtask->confirmUnlinkCase = '您确认要移除该用例吗?';
$lang->testtask->noticeNoOther = '该产品还没有其他测试单';
$lang->testtask->noTesttask = '暂时没有测试单。';
$lang->testtask->checkLinked = "请检查测试单的产品是否与{$lang->executionCommon}相关联";
$lang->testtask->noImportData = '导入的XML没有解析出数据。';
$lang->testtask->unitXMLFormat = '请选择Junit XML 格式的文件。';
$lang->testtask->titleOfAuto = "%s 自动化测试";
$lang->testtask->cannotBeParsed = '导入的XML文件内容格式错误,无法解析。';
$lang->testtask->finishedDateLess = '实际完成日期不能小于开始日期%s';
$lang->testtask->finishedDateMore = '实际完成日期不能大于今天';
$lang->testtask->assignedToMe = '指派给我';
$lang->testtask->allCases = '所有用例';
+2 -1
View File
@@ -136,7 +136,8 @@ $lang->testtask->noImportData = '導入的XML沒有解析出數據。';
$lang->testtask->unitXMLFormat = '請選擇Junit XML 格式的檔案。';
$lang->testtask->titleOfAuto = "%s 自動化測試";
$lang->testtask->cannotBeParsed = '導入的XML檔案內容格式錯誤,無法解析。';
$lang->testtask->finishedDateError = '實際完成日期不能小於開始日期%s';
$lang->testtask->finishedDateLess = '實際完成日期不能小於開始日期%s';
$lang->testtask->finishedDateMore = '實際完成日期不能大於今天';
$lang->testtask->assignedToMe = '指派給我';
$lang->testtask->allCases = '所有用例';
+2 -2
View File
@@ -803,12 +803,12 @@ class testtaskModel extends model
if($testtask->realFinishedDate <= $oldTesttask->begin)
{
dao::$errors[] = sprintf($this->lang->testtask->finishedDateError, $oldTesttask->begin);
dao::$errors[] = sprintf($this->lang->testtask->finishedDateLess, $oldTesttask->begin);
return false;
}
if($testtask->realFinishedDate > date("Y-m-d 00:00:00", strtotime("+1 day")))
{
dao::$errors[] = $this->lang->testtask->finishedDateError2;
dao::$errors[] = $this->lang->testtask->finishedDateMore;
return false;
}
+2 -2
View File
@@ -69,8 +69,8 @@ $lang->todo->closedBy = 'ClosedBy';
$lang->todo->closedDate = 'ClosedDate';
$lang->todo->deadline = 'Fällig';
$lang->todo->cycleDayTxt = 'Interval days';
$lang->todo->beforeDaysTxt = 'Days in advance';
$lang->todo->cycleDaysLabel = 'Interval days';
$lang->todo->beforeDaysLabel = 'Days in advance';
$lang->todo->every = 'Jeden';
$lang->todo->specify = 'ernennen';
+2 -2
View File
@@ -70,8 +70,8 @@ $lang->todo->closedDate = 'ClosedDate';
$lang->todo->deadline = 'Expiration';
$lang->todo->deleted = 'Deleted';
$lang->todo->cycleDayTxt = 'Interval days';
$lang->todo->beforeDaysTxt = 'Days in advance';
$lang->todo->cycleDaysLabel = 'Interval days';
$lang->todo->beforeDaysLabel = 'Days in advance';
$lang->todo->every = 'Every';
$lang->todo->specify = 'Specify';
+2 -2
View File
@@ -69,8 +69,8 @@ $lang->todo->closedBy = 'ClosedBy';
$lang->todo->closedDate = 'ClosedDate';
$lang->todo->deadline = 'Expiration';
$lang->todo->cycleDayTxt = 'Interval days';
$lang->todo->beforeDaysTxt = 'Days in advance';
$lang->todo->cycleDaysLabel = 'Interval days';
$lang->todo->beforeDaysLabel = 'Days in advance';
$lang->todo->every = 'Chaque';
$lang->todo->specify = 'Désigner';
+2 -2
View File
@@ -69,8 +69,8 @@ $lang->todo->closedBy = 'Người đóng';
$lang->todo->closedDate = 'Ngày đóng';
$lang->todo->deadline = 'Quá hạn';
$lang->todo->cycleDayTxt = 'Interval days';
$lang->todo->beforeDaysTxt = 'Days in advance';
$lang->todo->cycleDaysLabel = 'Interval days';
$lang->todo->beforeDaysLabel = 'Days in advance';
$lang->todo->every = 'Mọi';
$lang->todo->specify = 'bổ nhiệm';
+2 -2
View File
@@ -70,8 +70,8 @@ $lang->todo->closedDate = '关闭时间';
$lang->todo->deadline = '过期时间';
$lang->todo->deleted = '已删除';
$lang->todo->cycleDayTxt = '间隔天数';
$lang->todo->beforeDaysTxt = '提前天数';
$lang->todo->cycleDaysLabel = '间隔天数';
$lang->todo->beforeDaysLabel = '提前天数';
$lang->todo->every = '间隔';
$lang->todo->specify = '指定';
+3 -3
View File
@@ -77,12 +77,12 @@ class todoModel extends model
unset($todo->config['month']);
if(!$todo->config['day'])
{
dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->todo->cycleDayTxt);
dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->todo->cycleDaysLabel);
return false;
}
if(!validater::checkInt($todo->config['day']))
{
dao::$errors[] = sprintf($this->lang->error->int[0], $this->lang->todo->cycleDayTxt);
dao::$errors[] = sprintf($this->lang->error->int[0], $this->lang->todo->cycleDaysLabel);
return false;
}
}
@@ -101,7 +101,7 @@ class todoModel extends model
if($todo->config['beforeDays'] and !validater::checkInt($todo->config['beforeDays']))
{
dao::$errors[] = sprintf($this->lang->error->int[0], $this->lang->todo->beforeDaysTxt);
dao::$errors[] = sprintf($this->lang->error->int[0], $this->lang->todo->beforeDaysLabel);
return false;
}
$todo->config['beforeDays'] = (int)$todo->config['beforeDays'];
+1 -1
View File
@@ -3,4 +3,4 @@
* http://openzui.com
* GitHub: https://github.com/easysoft/zui.git
* Copyright (c) 2021 cnezsoft.com; Licensed MIT
*/.kanban{min-height:300px;overflow-x:auto}.kanban-header,.kanban-lane,.kanban-sub-lane{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;flex-direction:row;background-color:#f1f3f5;border-bottom:1px solid #d5d9de;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.no-flex .kanban-lane{padding-left:20px}.kanban-header{padding-left:20px;background-color:rgba(0,0,0,.07)}.kanban-col{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.not-use-flex .kanban-col{-webkit-box-flex:0;-webkit-flex:none;-ms-flex:none;flex:none}.no-flex .kanban-col{float:left}.kanban-col+.kanban-col{border-left:1px solid #d5d9de}.kanban-header-col{position:relative;height:32px}.kanban-header-col>.title{display:block;margin:6px 32px;line-height:20px;text-align:center}.kanban-header-col>.title>.text{display:inline-block;max-width:100px;margin:0 5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kanban-header-col>.title>.count,.kanban-header-col>.title>.icon{position:relative;top:-6px}.kanban-header-col[data-id=ADD]>.title{margin:6px;opacity:.7}.kanban-header-col[data-id=ADD]>.actions{display:none}.kanban-header-col>.actions{position:absolute;top:0;right:0}.kanban-header-col>.actions>.btn{min-width:32px}.kanban-header-col>.actions>.btn>.icon{opacity:.5}.kanban-lane{min-height:100px;margin-bottom:3px}.kanban-lane-name{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:20px;padding:10px 0;color:#fff;text-align:center;background-color:#3dc6fd;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-flex:0;-webkit-flex:none;-ms-flex:none;flex:none}.no-flex .kanban-lane-name{position:absolute;top:0;bottom:0;left:0}.kanban-header+.kanban-lane>.kanban-lane-name{margin-top:-33px}.kanban-lane-name .char{display:block;line-height:1;white-space:pre}.kanban-lane-name .char.rotate-90{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.kanban-lane-name.is-arab{font-size:12px;-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.kanban-lane-name.is-arab .char{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.kanban-sub-lanes{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;flex-direction:column;-webkit-box-flex:1;-webkit-flex:auto;-ms-flex:auto;flex:auto;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-pack:stretch;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column}.kanban-sub-lane{-webkit-box-flex:1;-webkit-flex:auto;-ms-flex:auto;flex:auto}.kanban-lane-col.drop-to{outline:3px solid rgba(255,190,57,.25);outline-offset:-3px}.kanban-lane-col.drop-to .kanban-lane-actions>.btn{background-color:rgba(255,190,57,.25);border:1px dotted #ff9800}.kanban-lane-col.drop-to .kanban-lane-actions>.btn>span{opacity:0}.kanban-lane-col[data-type=EMPTY]{background-color:#fff}.kanban-lane-items{max-height:300px;padding:0 15px;overflow:auto}.kanban-lane-actions{padding:10px 15px}.kanban-item{padding:10px;margin-top:10px;background:#fff;border:1px solid #fff;border-radius:4px;-webkit-transition:-webkit-box-shadow .2s,-webkit-transform .2s;-o-transition:box-shadow .2s,-o-transform .2s;transition:-webkit-box-shadow .2s,-webkit-transform .2s;transition:box-shadow .2s,transform .2s;transition:box-shadow .2s,transform .2s,-webkit-box-shadow .2s,-webkit-transform .2s,-o-transform .2s}.kanban-item.drag-from{background-color:#aaa;opacity:.2}.kanban-item:hover{border-color:rgba(0,0,0,.1);-webkit-box-shadow:0 4px 10px 0 rgba(0,0,0,.09);box-shadow:0 4px 10px 0 rgba(0,0,0,.09)}.kanban-item.drag-shadow{border-color:rgba(0,0,0,.2);-webkit-box-shadow:0 4px 10px 0 rgba(0,0,0,.09),0 4px 20px 0 rgba(0,0,0,.5);box-shadow:0 4px 10px 0 rgba(0,0,0,.09),0 4px 20px 0 rgba(0,0,0,.5);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}
*/.kanban{min-height:300px;overflow-x:auto}.kanban-header,.kanban-lane,.kanban-sub-lane{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;flex-direction:row;background-color:#f1f3f5;border-bottom:1px solid #d5d9de;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.no-flex .kanban-lane{padding-left:20px}.kanban-header{padding-left:20px;background-color:rgba(0,0,0,.07)}.kanban-no-lane-name .kanban-header{padding-left:0}.kanban-col{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.not-use-flex .kanban-col{-webkit-box-flex:0;-webkit-flex:none;-ms-flex:none;flex:none}.no-flex .kanban-col{float:left}.kanban-col+.kanban-col{border-left:1px solid #d5d9de}.kanban-header-col{position:relative;height:32px}.kanban-header-col>.title{display:block;margin:6px 32px;line-height:20px;text-align:center}.kanban-header-col>.title>.text{display:inline-block;max-width:100px;margin:0 5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kanban-header-col>.title>.count,.kanban-header-col>.title>.icon{position:relative;top:-6px}.kanban-header-col[data-id=ADD]>.title{margin:6px;opacity:.7}.kanban-header-col[data-id=ADD]>.actions{display:none}.kanban-header-col>.actions{position:absolute;top:0;right:0}.kanban-header-col>.actions>.btn{min-width:32px}.kanban-header-col>.actions>.btn>.icon{opacity:.5}.kanban-lane{min-height:100px;margin-bottom:3px}.kanban-lane-name{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:20px;padding:10px 0;color:#fff;text-align:center;background-color:#3dc6fd;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-flex:0;-webkit-flex:none;-ms-flex:none;flex:none}.no-flex .kanban-lane-name{position:absolute;top:0;bottom:0;left:0}.kanban-header+.kanban-lane>.kanban-lane-name{margin-top:-33px}.kanban-lane-name .char{display:block;line-height:1;white-space:pre}.kanban-lane-name .char.rotate-90{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.kanban-lane-name.is-arab{font-size:12px;-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.kanban-lane-name.is-arab .char{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.kanban-sub-lanes{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;flex-direction:column;-webkit-box-flex:1;-webkit-flex:auto;-ms-flex:auto;flex:auto;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-pack:stretch;-webkit-justify-content:stretch;-ms-flex-pack:stretch;justify-content:stretch;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column}.kanban-sub-lane{-webkit-box-flex:1;-webkit-flex:auto;-ms-flex:auto;flex:auto}.kanban-lane-col.drop-to{outline:3px solid rgba(255,190,57,.25);outline-offset:-3px}.kanban-lane-col.drop-to .kanban-lane-actions>.btn{background-color:rgba(255,190,57,.25);border:1px dotted #ff9800}.kanban-lane-col.drop-to .kanban-lane-actions>.btn>span{opacity:0}.kanban-lane-col[data-type=EMPTY]{background-color:#fff}.kanban-lane-items{max-height:300px;padding:0 15px;overflow:auto}.kanban-lane-actions{padding:10px 15px}.kanban-item{padding:10px;margin-top:10px;background:#fff;border:1px solid #fff;border-radius:4px;-webkit-transition:-webkit-box-shadow .2s,-webkit-transform .2s;-o-transition:box-shadow .2s,-o-transform .2s;transition:-webkit-box-shadow .2s,-webkit-transform .2s;transition:box-shadow .2s,transform .2s;transition:box-shadow .2s,transform .2s,-webkit-box-shadow .2s,-webkit-transform .2s,-o-transform .2s}.kanban-item.drag-from{background-color:#aaa;opacity:.2}.kanban-item:hover{border-color:rgba(0,0,0,.1);-webkit-box-shadow:0 4px 10px 0 rgba(0,0,0,.09);box-shadow:0 4px 10px 0 rgba(0,0,0,.09)}.kanban-item.drag-shadow{border-color:rgba(0,0,0,.2);-webkit-box-shadow:0 4px 10px 0 rgba(0,0,0,.09),0 4px 20px 0 rgba(0,0,0,.5);box-shadow:0 4px 10px 0 rgba(0,0,0,.09),0 4px 20px 0 rgba(0,0,0,.5);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}
File diff suppressed because one or more lines are too long