Merge branch 'master' into 'liyuchun_59430'
# Conflicts: # module/repo/control.php
This commit is contained in:
@@ -9,3 +9,5 @@ CREATE TABLE `zt_cfd` (
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('30', '23', '*', '*', '*', 'moduleName=execution&methodName=computecfd', '更新累积流图', 'zentao', 1, 'normal', '0000-00-00 00:00:00');
|
||||
|
||||
ALTER TABLE `zt_doc` CHANGE `assignedDate` `assignedDate` datetime NOT NULL AFTER `assignedTo`;
|
||||
|
||||
+1
-1
@@ -8963,7 +8963,7 @@ ALTER TABLE `zt_doc` ADD `assetLibType` varchar(30) NOT NULL default '' after `a
|
||||
ALTER TABLE `zt_doc` ADD `from` mediumint(8) unsigned NOT NULL default 0 after `assetLibType`;
|
||||
ALTER TABLE `zt_doc` ADD `fromVersion` smallint(6) NOT NULL default 1 after `from`;
|
||||
ALTER TABLE `zt_doc` ADD `assignedTo` varchar(30) NOT NULL after `addedDate`;
|
||||
ALTER TABLE `zt_doc` ADD `assignedDate` date NOT NULL after `assignedTo`;
|
||||
ALTER TABLE `zt_doc` ADD `assignedDate` datetime NOT NULL after `assignedTo`;
|
||||
ALTER TABLE `zt_doc` ADD `approvedDate` date NOT NULL after `assignedDate`;
|
||||
ALTER TABLE `zt_doc` ADD `status` varchar(30) NOT NULL after `type`;
|
||||
|
||||
|
||||
@@ -3233,7 +3233,8 @@ class ztSessionHandler
|
||||
public function destroy($id)
|
||||
{
|
||||
$sessFile = $this->getSessionFile($id);
|
||||
@unlink($sessFile);
|
||||
unlink($sessFile);
|
||||
unlink($this->rawFile);
|
||||
touch($sessFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ class actionModel extends model
|
||||
$name = $this->dao->select('name')->from(TABLE_TESTTASK)->where('id')->eq($action->extra)->fetch('name');
|
||||
if($name) $action->extra = common::hasPriv('testtask', 'view') ? html::a(helper::createLink('testtask', 'view', "taskID=$action->extra"), $name) : $name;
|
||||
}
|
||||
elseif($actionName == 'moved')
|
||||
elseif($actionName == 'moved' and $action->objectType != 'module')
|
||||
{
|
||||
$name = $this->dao->select('name')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch('name');
|
||||
if($name) $action->extra = common::hasPriv('execution', 'task') ? html::a(helper::createLink('execution', 'task', "executionID=$action->extra"), "#$action->extra " . $name) : "#$action->extra " . $name;
|
||||
|
||||
@@ -1802,7 +1802,7 @@ class block extends control
|
||||
{
|
||||
$this->app->loadLang('feedback');
|
||||
$this->view->users = $this->loadModel('user')->getPairs('all,noletter');
|
||||
$this->view->products = $this->loadModel('product')->getPairs();
|
||||
$this->view->products = $this->dao->select('id, name')->from(TABLE_PRODUCT)->where('deleted')->eq('0')->fetchPairs('id', 'name');
|
||||
}
|
||||
|
||||
$count[$objectType] = count($objects);
|
||||
|
||||
+40
-10
@@ -395,6 +395,12 @@ class bug extends control
|
||||
{
|
||||
$this->dao->update(TABLE_TODO)->set('status')->eq('done')->where('id')->eq($output['todoID'])->exec();
|
||||
$this->action->create('todo', $output['todoID'], 'finished', '', "BUG:$bugID");
|
||||
|
||||
if($this->config->edition == 'biz' || $this->config->edition == 'max')
|
||||
{
|
||||
$todo = $this->dao->select('type, idvalue')->from(TABLE_TODO)->where('id')->eq($output['todoID'])->fetch();
|
||||
if($todo->type == 'feedback' && $todo->idvalue) $this->loadModel('feedback')->updateStatus('todo', $todo->idvalue, 'done');
|
||||
}
|
||||
}
|
||||
|
||||
$message = $this->executeHooks($bugID);
|
||||
@@ -404,18 +410,31 @@ class bug extends control
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $bugID));
|
||||
|
||||
/* If link from no head then reload. */
|
||||
if(isset($output['executionID']) and isonlybody())
|
||||
if(isonlybody())
|
||||
{
|
||||
$executionID = $this->post->execution ? $this->post->execution : $output['executionID'];
|
||||
$executionID = isset($output['executionID']) ? $output['executionID'] : $this->session->execution;
|
||||
$executionID = $this->post->execution ? $this->post->execution : $executionID;
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
if($executionID == $output['executionID'] and $this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, 0)"));
|
||||
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, 0)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -705,15 +724,26 @@ class bug extends control
|
||||
if(isonlybody() and $executionID)
|
||||
{
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
if($execution->type == 'kanban' and $this->app->tab == 'execution')
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -13,69 +13,11 @@ $(function()
|
||||
/* Implement a custom form without feeling refresh. */
|
||||
$('#formSettingForm .btn-primary').click(function()
|
||||
{
|
||||
var fields = '';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input:checked').each(function()
|
||||
{
|
||||
fields += ',' + $(this).val();
|
||||
});
|
||||
|
||||
var link = createLink('custom', 'ajaxSaveCustomFields', 'module=bug§ion=custom&key=batchCreateFields');
|
||||
$.post(link, {'fields' : fields}, function()
|
||||
{
|
||||
showFields = fields;
|
||||
showCheckedFields(fields);
|
||||
$('#formSetting').parent().removeClass('open');
|
||||
|
||||
if($('#batchCreateForm table thead tr th.c-title').width() < 150) $titleCol.width(150);
|
||||
|
||||
var fieldCount = $('#batchCreateForm .table thead>tr>th:visible').length;
|
||||
$('.form-actions').attr('colspan', fieldCount);
|
||||
|
||||
if(fieldCount > 10)
|
||||
{
|
||||
$('#batchCreateForm > .table-responsive').removeClass('scroll-none');
|
||||
$('#batchCreateForm > .table-responsive').css('overflow', 'auto');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#batchCreateForm > .table-responsive').addClass('scroll-none');
|
||||
$('#batchCreateForm > .table-responsive').css('overflow', 'visible');
|
||||
}
|
||||
});
|
||||
|
||||
saveCustomFields('batchCreateFields', 10, $titleCol, 150);
|
||||
return false;
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
* Show checked fields.
|
||||
*
|
||||
* @param string fields
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function showCheckedFields(fields)
|
||||
{
|
||||
var fieldList = ',' + fields + ',';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var $field = $('[name^=' + $(this).val() + ']');
|
||||
var required = ',' + requiredFields + ',';
|
||||
var $fieldBox = $('.' + $(this).val() + 'Box' );
|
||||
if(fieldList.indexOf(field) >= 0 || required.indexOf(field) >= 0)
|
||||
{
|
||||
$fieldBox.removeClass('hidden');
|
||||
$field.removeAttr('disabled');
|
||||
}
|
||||
else if(!$fieldBox.hasClass('hidden'))
|
||||
{
|
||||
$fieldBox.addClass('hidden');
|
||||
$field.attr('disabled', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set opened builds.
|
||||
*
|
||||
@@ -219,35 +161,3 @@ $(document).keydown(function(event)
|
||||
inputFocusJump('down');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Add item.
|
||||
*
|
||||
* @param object $obj
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function addItem(obj)
|
||||
{
|
||||
var item = $('#addItem').html().replace(/%i%/g, itemIndex + 1);
|
||||
$('<tr class="addedItem">' + item + '</tr>').insertAfter($(obj).closest('tr'));
|
||||
|
||||
$(obj).closest('tr').next().find(".form-date").datepicker();
|
||||
$(obj).closest('tr').next().find('div[id$=_chosen]').remove();
|
||||
$(obj).closest('tr').next().find('.chosen').next('.picker').remove();
|
||||
$(obj).closest('tr').next().find('.chosen').chosen();
|
||||
|
||||
itemIndex ++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete item.
|
||||
*
|
||||
* @param object $obj
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function deleteItem(obj)
|
||||
{
|
||||
$(obj).closest('tr').remove();
|
||||
}
|
||||
|
||||
@@ -886,19 +886,3 @@ function setBranchRelated(branchID, productID, num)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden require field.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function hiddenRequireFields()
|
||||
{
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var required = ',' + requiredFields + ',';
|
||||
if(required.indexOf(field) >= 0) $(this).closest('div').addClass('hidden');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -147,9 +147,9 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<?php if($i != 1):?>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -207,9 +207,9 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<?php if($i != 1):?>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -227,7 +227,7 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php js::set('itemIndex', -- $i);?>
|
||||
<?php js::set('rowIndex', -- $i);?>
|
||||
<table class='template' id='trTemp'>
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -266,8 +266,8 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[%s]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -275,7 +275,7 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
<div>
|
||||
<?php $i = '%i%';?>
|
||||
<table class='hidden'>
|
||||
<tr id='addItem' class='hidden'>
|
||||
<tr id='addRow' class='hidden'>
|
||||
<td><?php echo $i;?></td>
|
||||
<td class='<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox' style='overflow:visible'><?php echo html::select("branches[$i]", $branches, $branch, "class='form-control chosen' onchange='setBranchRelated(this.value, $productID, $i)'");?></td>
|
||||
<td><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
|
||||
@@ -315,8 +315,8 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -43,6 +43,7 @@ $lang->report = new stdclass();
|
||||
$lang->repo = new stdclass();
|
||||
$lang->jenkins = new stdclass();
|
||||
$lang->gitlab = new stdclass();
|
||||
$lang->gitea = new stdclass();
|
||||
$lang->mr = new stdclass();
|
||||
$lang->compile = new stdclass();
|
||||
$lang->job = new stdclass();
|
||||
@@ -175,8 +176,7 @@ $lang->createIcons['program'] = 'program';
|
||||
$lang->createIcons['kanbanspace'] = 'cube';
|
||||
$lang->createIcons['kanban'] = 'kanban';
|
||||
|
||||
$lang->refreshIcon = "<i class='icon icon-refresh'></i>";
|
||||
|
||||
$lang->noMenuModule = array('report', 'my', 'todo', 'effort', 'program', 'product', 'execution', 'task', 'build', 'productplan', 'project', 'projectrelease', 'projectstory', 'story', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'pssp', 'sms', 'message', 'webhook', 'search', 'score', 'stage', 'entry', 'jenkins', 'gitlab');
|
||||
$lang->refreshIcon = "<i class='icon icon-refresh'></i>";
|
||||
$lang->noMenuModule = array('report', 'my', 'todo', 'effort', 'program', 'product', 'execution', 'task', 'build', 'productplan', 'project', 'projectrelease', 'projectstory', 'story', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'pssp', 'sms', 'message', 'webhook', 'search', 'score', 'stage', 'entry', 'jenkins', 'gitlab', 'gitea');
|
||||
|
||||
if(isset($_SESSION['tutorialMode']) and $_SESSION['tutorialMode'] and !defined('TUTORIAL')) define('TUTORIAL', true);
|
||||
|
||||
@@ -399,7 +399,7 @@ $lang->devops->menu->code = array('link' => "{$lang->repo->common}|repo|brows
|
||||
$lang->devops->menu->mr = array('link' => "{$lang->devops->mr}|mr|browse|repoID=%s");
|
||||
$lang->devops->menu->compile = array('link' => "{$lang->devops->compile}|job|browse|repoID=%s", 'subModule' => 'compile,job');
|
||||
$lang->devops->menu->app = array('link' => "{$lang->app->common}|app|serverlink|%s");
|
||||
$lang->devops->menu->set = array('link' => "{$lang->devops->set}|repo|maintain", 'subModule' => 'gitlab,jenkins,sonarqube', 'alias' => 'setrules,create,edit');
|
||||
$lang->devops->menu->set = array('link' => "{$lang->devops->set}|repo|maintain", 'subModule' => 'gitlab,jenkins,sonarqube,gitea', 'alias' => 'setrules,create,edit');
|
||||
|
||||
$lang->devops->menuOrder[5] = 'code';
|
||||
$lang->devops->menuOrder[10] = 'mr';
|
||||
@@ -412,6 +412,7 @@ $lang->devops->dividerMenu = ',set,';
|
||||
$lang->devops->menu->set['subMenu'] = new stdclass();
|
||||
$lang->devops->menu->set['subMenu']->repo = array('link' => "{$lang->devops->repo}|repo|maintain", 'alias' => 'create,edit');
|
||||
$lang->devops->menu->set['subMenu']->gitlab = array('link' => 'GitLab|gitlab|browse', 'subModule' => 'gitlab');
|
||||
$lang->devops->menu->set['subMenu']->gitea = array('link' => 'Gitea|gitea|browse', 'subModule' => 'gitea');
|
||||
$lang->devops->menu->set['subMenu']->jenkins = array('link' => 'Jenkins|jenkins|browse', 'subModule' => '');
|
||||
$lang->devops->menu->set['subMenu']->sonarqube = array('link' => 'SonarQube|sonarqube|browse', 'subModule' => 'sonarqube');
|
||||
$lang->devops->menu->set['subMenu']->setrules = array('link' => "{$lang->devops->rules}|repo|setrules");
|
||||
@@ -645,6 +646,7 @@ $lang->navGroup->job = 'devops';
|
||||
$lang->navGroup->jenkins = 'devops';
|
||||
$lang->navGroup->mr = 'devops';
|
||||
$lang->navGroup->gitlab = 'devops';
|
||||
$lang->navGroup->gitea = 'devops';
|
||||
$lang->navGroup->sonarqube = 'devops';
|
||||
$lang->navGroup->sonarqubeproject = 'devops';
|
||||
$lang->navGroup->compile = 'devops';
|
||||
|
||||
@@ -2460,16 +2460,16 @@ EOD;
|
||||
/* If is the program/project/product/execution admin, have all program privs. */
|
||||
if($app->config->vision != 'lite')
|
||||
{
|
||||
$inProject = isset($lang->navGroup->$module) and $lang->navGroup->$module == 'project';
|
||||
$inProject = (isset($lang->navGroup->$module) and $lang->navGroup->$module == 'project');
|
||||
if($inProject and $app->session->project and (strpos(",{$app->user->rights['projects']},", ",{$app->session->project},") !== false or strpos(",{$app->user->rights['projects']},", ',all,') !== false)) return true;
|
||||
|
||||
$inProduct = isset($lang->navGroup->$module) and $lang->navGroup->$module == 'product';
|
||||
$inProduct = (isset($lang->navGroup->$module) and $lang->navGroup->$module == 'product');
|
||||
if($inProduct and $app->session->product and (strpos(",{$app->user->rights['products']},", ",{$app->session->product},") !== false or strpos(",{$app->user->rights['products']},", ',all,') !== false)) return true;
|
||||
|
||||
$inProgram = isset($lang->navGroup->$module) and $lang->navGroup->$module == 'program';
|
||||
$inProgram = (isset($lang->navGroup->$module) and $lang->navGroup->$module == 'program');
|
||||
if($inProgram and $app->session->program and (strpos(",{$app->user->rights['programs']},", ",{$app->session->program},") !== false or strpos(",{$app->user->rights['programs']},", ',all,') !== false)) return true;
|
||||
|
||||
$inExecution = isset($lang->navGroup->$module) and $lang->navGroup->$module == 'execution';
|
||||
$inExecution = (isset($lang->navGroup->$module) and $lang->navGroup->$module == 'execution');
|
||||
if($inExecution and $app->session->execution and (strpos(",{$app->user->rights['executions']},", ",{$app->session->execution},") !== false or strpos(",{$app->user->rights['executions']},", ',all,') !== false)) return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ $(function()
|
||||
var moduleArr = ['task', 'story', 'bug', 'testcase'];
|
||||
if($.inArray(config.currentModule, moduleArr) >= 0 && config.currentMethod == 'batchcreate')
|
||||
{
|
||||
lastIndex = itemIndex;
|
||||
itemIndex ++;
|
||||
lastIndex = rowIndex;
|
||||
rowIndex ++;
|
||||
}
|
||||
|
||||
var $newRow = $(rowTpl.replace(/%s/g, lastIndex + 1));
|
||||
|
||||
@@ -125,7 +125,7 @@ class custom extends control
|
||||
foreach($postArray->data->keys as $key)
|
||||
{
|
||||
if($module == 'testtask' and $field == 'typeList' and empty($key)) continue;
|
||||
if(in_array($key, $keys)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->custom->notice->repeatKey, $key)));;
|
||||
if($key && in_array($key, $keys)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->custom->notice->repeatKey, $key)));;
|
||||
$keys[] = $key;
|
||||
}
|
||||
}
|
||||
@@ -243,9 +243,12 @@ class custom extends control
|
||||
}
|
||||
|
||||
$this->custom->deleteItems("lang=$lang&module=$module§ion=$field&vision={$this->config->vision}");
|
||||
$data = fixer::input('post')->get();
|
||||
$data = fixer::input('post')->get();
|
||||
$emptyKey = false;
|
||||
foreach($data->keys as $index => $key)
|
||||
{
|
||||
if(!$key && $emptyKey) continue;
|
||||
|
||||
//if(!$system and (!$value or !$key)) continue; //Fix bug #951.
|
||||
|
||||
$value = $data->values[$index];
|
||||
@@ -253,6 +256,8 @@ class custom extends control
|
||||
if($key and trim($value) === '') return $this->send(array('result' => 'fail', 'message' => $this->lang->custom->notice->valueEmpty)); // Fix bug #23538.
|
||||
|
||||
$this->custom->setItem("{$lang}.{$module}.{$field}.{$key}.{$system}", $value);
|
||||
|
||||
if(!$key) $emptyKey = true;
|
||||
}
|
||||
}
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
@@ -21,7 +21,7 @@ $itemRow = <<<EOT
|
||||
<td>
|
||||
<input type='text' class="form-control" value="" autocomplete="off" name="values[]">
|
||||
</td>
|
||||
<td class='c-actions'>
|
||||
<td class='c-actions text-left'>
|
||||
<a href="javascript:void(0)" class='btn btn-link' onclick="addItem(this)"><i class='icon-plus'></i></a>
|
||||
<a href="javascript:void(0)" class='btn btn-link' onclick="delItem(this)"><i class='icon-close'></i></a>
|
||||
</td>
|
||||
@@ -249,7 +249,7 @@ EOT;
|
||||
<?php echo html::input("values[]", isset($dbFields[$key]) ? $dbFields[$key]->value : $value, "class='form-control' " . (empty($key) ? 'readonly' : ''));?>
|
||||
</td>
|
||||
<?php if($canAdd):?>
|
||||
<td class='c-actions'>
|
||||
<td class='c-actions text-left'>
|
||||
<a href="javascript:void(0)" onclick="addItem(this)" class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href="javascript:void(0)" onclick="delItem(this)" class='btn btn-link'><i class='icon-close'></i></a>
|
||||
</td>
|
||||
|
||||
@@ -409,6 +409,7 @@ class deptModel extends model
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF(strpos($params, 'all') === false)->andWhere('type')->eq($type)->fi()
|
||||
->beginIF($childDepts)->andWhere('dept')->in($childDepts)->fi()
|
||||
->beginIF($deptID === '0')->andWhere('dept')->eq($deptID)->fi()
|
||||
->beginIF($this->config->vision)->andWhere("CONCAT(',', visions, ',')")->like("%,{$this->config->vision},%")->fi()
|
||||
->orderBy('account')
|
||||
->fetchPairs();
|
||||
|
||||
@@ -1042,7 +1042,9 @@ class execution extends control
|
||||
* Execution case list.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param int $productID
|
||||
* @param string $type
|
||||
* @param int $moduleID
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
@@ -1050,28 +1052,45 @@ class execution extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function testcase($executionID = 0, $type = 'all', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
public function testcase($executionID = 0, $productID = 0, $type = 'all', $moduleID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
$this->loadModel('testtask');
|
||||
$this->loadModel('tree');
|
||||
$this->commonAction($executionID);
|
||||
$uri = $this->app->getURI(true);
|
||||
$this->session->set('caseList', $uri, 'execution');
|
||||
$this->session->set('bugList', $uri, 'execution');
|
||||
|
||||
$products = $this->product->getProducts($executionID);
|
||||
$productID = key($products); // Get the first product for creating testcase.
|
||||
$products = $this->product->getProducts($executionID, 'all', '', false);
|
||||
if(count($products) == 1) $productID = key($products);
|
||||
|
||||
$extra = $executionID;
|
||||
$this->lang->modulePageNav = $this->product->select(array('0' => $this->lang->product->all) + $products, $productID, 'execution', 'testcase', $extra, 0, 0, '', false);
|
||||
|
||||
/* Load pager. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$cases = $this->loadModel('testcase')->getExecutionCases($executionID, $orderBy, $pager, $type);
|
||||
$cases = $this->loadModel('testcase')->getExecutionCases($executionID, $productID, $moduleID, $orderBy, $pager, $type);
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', false);
|
||||
|
||||
$cases = $this->testcase->appendData($cases, 'case');
|
||||
$cases = $this->loadModel('story')->checkNeedConfirm($cases);
|
||||
|
||||
$modules = $this->tree->getAllModulePairs('case');
|
||||
|
||||
/* Get module tree.*/
|
||||
if($executionID and empty($productID))
|
||||
{
|
||||
$moduleTree = $this->tree->getCaseTreeMenu($executionID, $productID, 0, array('treeModel', 'createCaseLink'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$moduleTree = $this->tree->getTreeMenu($productID, 'case', 0, array('treeModel', 'createCaseLink'), array('executionID' => $executionID, 'productID' => $productID), 'all');
|
||||
}
|
||||
$tree = $moduleID ? $this->tree->getByID($moduleID) : '';
|
||||
|
||||
$this->view->title = $this->lang->execution->testcase;
|
||||
$this->view->executionID = $executionID;
|
||||
$this->view->productID = $productID;
|
||||
@@ -1081,6 +1100,10 @@ class execution extends control
|
||||
$this->view->type = $type;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->execution = $this->execution->getByID($executionID);
|
||||
$this->view->moduleTree = $moduleTree;
|
||||
$this->view->modules = $modules;
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->moduleName = $moduleID ? $tree->name : $this->lang->tree->all;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -2271,7 +2294,6 @@ class execution extends control
|
||||
public function kanban($executionID, $browseType = 'all', $orderBy = 'id_asc', $groupBy = 'default')
|
||||
{
|
||||
$this->app->loadLang('bug');
|
||||
$this->loadModel('story');
|
||||
|
||||
if(empty($groupBy)) $groupBy = 'default';
|
||||
|
||||
@@ -2345,7 +2367,6 @@ class execution extends control
|
||||
$this->view->kanbanData = $kanbanData;
|
||||
$this->view->executionActions = $executionActions;
|
||||
$this->view->kanban = $this->lang->execution->kanban;
|
||||
$this->view->reviewStoryParis = $this->story->getExecutionStoryPairs($execution->id, 0, 'all', 0, 'full', 'review');
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -2374,7 +2395,6 @@ class execution extends control
|
||||
/* Load language. */
|
||||
$this->app->loadLang('task');
|
||||
$this->app->loadLang('bug');
|
||||
$this->loadModel('story');
|
||||
$this->loadModel('kanban');
|
||||
|
||||
/* Compatibility IE8. */
|
||||
@@ -2435,7 +2455,6 @@ class execution extends control
|
||||
$this->view->groupBy = $groupBy;
|
||||
$this->view->canBeChanged = $canBeChanged;
|
||||
$this->view->userList = $userList;
|
||||
$this->view->reviewStoryParis = $this->story->getExecutionStoryPairs($execution->id, 0, 'all', 0, 'full', 'review');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -3162,6 +3181,19 @@ class execution extends control
|
||||
}
|
||||
return $this->send($response);
|
||||
}
|
||||
|
||||
$execution = $this->execution->getByID($executionID);
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent', '', "parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
.main-content > h2 {font-size: 16px;}
|
||||
.container {max-width: 1700px !important}
|
||||
|
||||
.pull-left .input-control {margin-right: 10px;}
|
||||
|
||||
#cfdWrapper {max-width: 1450px; padding: 25px 0px 10px; position: relative}
|
||||
@media screen and (max-width: 1920px)
|
||||
{
|
||||
#cfdWrapper {max-width: 1400px; padding: 25px 0px 10px; position: relative}
|
||||
#cfdChart {width:1400px !important; height:600px !important}
|
||||
#cfdYUnit {position: absolute; color: #CBD0DB; top: 40px; left: 30px}
|
||||
#cfdXUnit {position: absolute; color: #CBD0DB; bottom: 20px; right: 0px}
|
||||
#mainContent {min-width: 1550px !important;}
|
||||
#burnStatistics {left: 1400px !important;}
|
||||
}
|
||||
@media screen and (max-width: 1680px)
|
||||
{
|
||||
#cfdChart {width:1100px !important; height:400px !important}
|
||||
#mainContent {min-width: 1300px !important;}
|
||||
#burnStatistics {left: 1100px !important;}
|
||||
#cfdChart {width:1150px !important; height:500px !important}
|
||||
#mainContent {min-width: 1350px !important;}
|
||||
#burnStatistics {left: 1150px !important;}
|
||||
}
|
||||
@media screen and (max-width: 1366px)
|
||||
{
|
||||
#cfdChart {width:1000px !important; height:400px !important}
|
||||
#mainContent {min-width: 1200px !important;}
|
||||
#burnStatistics {left: 1000px !important;}
|
||||
}
|
||||
|
||||
#mainContent {min-width: 1400px;}
|
||||
#burnStatistics {position: absolute; width: 180px; left: 1250px; height: 200px; top: 20%; margin-top: -30px; line-height: 30px; color: #838A9D; font-size: 12px; border: 1px solid #dcdcdc; background-color: #F8F8F8; padding: 15px 20px; color: #3c4353; border-radius: 8px;}
|
||||
#burnStatistics {position: absolute; width: 180px; left: 1200px; height: 200px; top: 20%; margin-top: -30px; line-height: 30px; color: #838A9D; font-size: 12px; border: 1px solid #dcdcdc; background-color: #F8F8F8; padding: 15px 20px; color: #3c4353; border-radius: 8px;}
|
||||
#burnStatistics .bg-primary {margin-right: 5px;}
|
||||
#burnStatistics .icon-help {color: black;}
|
||||
#burnStatistics h3 {margin-top: 10px; text-indent: 10px; margin-bottom: 30px;}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#dateRange {vertical-align: top; padding-top: 13px;}
|
||||
#dateRangeOption {vertical-align: top; padding-top: 13px;}
|
||||
#beginLabel {white-space: nowrap;}
|
||||
#endLabel {white-space: nowrap;}
|
||||
#copyProjectModal .projectSelect {display: inline-block; margin-left: 10px; width: 20%;}
|
||||
#copyProjectModal .titleBox{position: relative; bottom: 3px; display: inline-block;}
|
||||
a.chosen-single > div > b {top: -4px !important;}
|
||||
a.chosen-single > div > b {top: -4px !important;}
|
||||
@@ -1,2 +1,3 @@
|
||||
.c-id, .c-pri {width: 50px;}
|
||||
.c-result {width: 80px;}
|
||||
#pageNav #dropMenu .col-left {padding-bottom: 0px;}
|
||||
|
||||
@@ -2,7 +2,7 @@ $(function()
|
||||
{
|
||||
$('[data-toggle=tooltip]').tooltip();
|
||||
|
||||
if(chartData)
|
||||
if(Object.keys(chartData).length || 1)
|
||||
{
|
||||
var i = 0;
|
||||
var series = [];
|
||||
@@ -56,6 +56,7 @@ $(function()
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: chartData['labels'],
|
||||
name: XUnit,
|
||||
axisLine:
|
||||
{
|
||||
show: true,
|
||||
@@ -70,6 +71,19 @@ $(function()
|
||||
{
|
||||
type: 'value',
|
||||
minInterval: 1,
|
||||
name: YUnit,
|
||||
nameTextStyle:
|
||||
{
|
||||
fontWeight: 'normal'
|
||||
},
|
||||
axisPointer:
|
||||
{
|
||||
label:
|
||||
{
|
||||
show: true,
|
||||
precision: 0
|
||||
},
|
||||
},
|
||||
axisLine:
|
||||
{
|
||||
show: true,
|
||||
|
||||
@@ -1092,28 +1092,29 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
|
||||
}
|
||||
else
|
||||
{
|
||||
if(toColType == 'ready' && typeof(reviewStoryParis[objectID]) != 'undefined')
|
||||
if(toColType == 'ready')
|
||||
{
|
||||
bootbox.alert(executionLang.storyDragError);
|
||||
return false;
|
||||
$.get(createLink('story', 'ajaxGetInfo', "storyID=" + cardID), function(data)
|
||||
{
|
||||
if(data)
|
||||
{
|
||||
data = $.parseJSON(data);
|
||||
if(data.status == 'draft' || data.status == 'changed')
|
||||
{
|
||||
bootbox.alert(executionLang.storyDragError);
|
||||
}
|
||||
else
|
||||
{
|
||||
ajaxMoveCard(objectID, fromColID, toColID, fromLaneID, toLaneID, regionID);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ajaxMoveCard(objectID, fromColID, toColID, fromLaneID, toLaneID, regionID);
|
||||
}
|
||||
|
||||
var link = createLink('kanban', 'ajaxMoveCard', 'cardID=' + objectID + '&fromColID=' + fromColID + '&toColID=' + toColID + '&fromLaneID=' + fromLaneID + '&toLaneID=' + toLaneID + '&execitionID=' + executionID + '&browseType=' + browseType + '&groupBy=' + groupBy + '®ionID=' + regionID+ '&orderBy=' + orderBy );
|
||||
$.ajax(
|
||||
{
|
||||
method: 'post',
|
||||
dataType: 'json',
|
||||
url: link,
|
||||
success: function(data)
|
||||
{
|
||||
data = groupBy == 'default' ? data[regionID] : data[groupBy];
|
||||
updateRegion(regionID, data);
|
||||
},
|
||||
error: function(xhr, status, error)
|
||||
{
|
||||
showErrorMessager(error || lang.timeout);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1124,6 +1125,38 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: move card.
|
||||
*
|
||||
* @param int $objectID
|
||||
* @param int $fromColID
|
||||
* @param int $toColID
|
||||
* @param int $fromLaneID
|
||||
* @param int $toLaneID
|
||||
* @param int $regionID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function ajaxMoveCard(objectID, fromColID, toColID, fromLaneID, toLaneID, regionID)
|
||||
{
|
||||
var link = createLink('kanban', 'ajaxMoveCard', 'cardID=' + objectID + '&fromColID=' + fromColID + '&toColID=' + toColID + '&fromLaneID=' + fromLaneID + '&toLaneID=' + toLaneID + '&execitionID=' + executionID + '&browseType=' + browseType + '&groupBy=' + groupBy + '®ionID=' + regionID+ '&orderBy=' + orderBy );
|
||||
$.ajax(
|
||||
{
|
||||
method: 'post',
|
||||
dataType: 'json',
|
||||
url: link,
|
||||
success: function(data)
|
||||
{
|
||||
data = groupBy == 'default' ? data[regionID] : data[groupBy];
|
||||
updateRegion(regionID, data);
|
||||
},
|
||||
error: function(xhr, status, error)
|
||||
{
|
||||
showErrorMessager(error || lang.timeout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a card.
|
||||
*
|
||||
|
||||
@@ -774,28 +774,28 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
|
||||
}
|
||||
else
|
||||
{
|
||||
if(toColType == 'ready' && typeof(reviewStoryParis[objectID]) != 'undefined')
|
||||
if(toColType == 'ready')
|
||||
{
|
||||
bootbox.alert(executionLang.storyDragError);
|
||||
return false;
|
||||
}
|
||||
|
||||
var link = createLink('kanban', 'ajaxMoveCard', 'cardID=' + objectID + '&fromColID=' + fromColID + '&toColID=' + toColID + '&fromLaneID=' + fromLaneID + '&toLaneID=' + toLaneID + '&execitionID=' + executionID + '&browseType=' + browseType + '&groupBy=' + groupBy);
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(data)
|
||||
$.get(createLink('story', 'ajaxGetInfo', "storyID=" + cardID), function(data)
|
||||
{
|
||||
kanbanGroup = $.parseJSON(data);
|
||||
if(groupBy == 'default')
|
||||
if(data)
|
||||
{
|
||||
updateKanban('story', kanbanGroup.story);
|
||||
data = $.parseJSON(data);
|
||||
if(data.status == 'draft' || data.status == 'changed')
|
||||
{
|
||||
bootbox.alert(executionLang.storyDragError);
|
||||
}
|
||||
else
|
||||
{
|
||||
ajaxMoveCard(objectID, fromColID, toColID, fromLaneID, toLaneID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
updateKanban(browseType, kanbanGroup[groupBy]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ajaxMoveCard(objectID, fromColID, toColID, fromLaneID, toLaneID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,6 +806,37 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: move card.
|
||||
*
|
||||
* @param int $objectID
|
||||
* @param int $fromColID
|
||||
* @param int $toColID
|
||||
* @param int $fromLaneID
|
||||
* @param int $toLaneID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function ajaxMoveCard(objectID, fromColID, toColID, fromLaneID, toLaneID)
|
||||
{
|
||||
var link = createLink('kanban', 'ajaxMoveCard', 'cardID=' + objectID + '&fromColID=' + fromColID + '&toColID=' + toColID + '&fromLaneID=' + fromLaneID + '&toLaneID=' + toLaneID + '&execitionID=' + executionID + '&browseType=' + browseType + '&groupBy=' + groupBy);
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(data)
|
||||
{
|
||||
kanbanGroup = $.parseJSON(data);
|
||||
if(groupBy == 'default')
|
||||
{
|
||||
updateKanban('story', kanbanGroup.story);
|
||||
}
|
||||
else
|
||||
{
|
||||
updateKanban(browseType, kanbanGroup[groupBy]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle drop task.
|
||||
*
|
||||
|
||||
@@ -76,8 +76,9 @@ foreach($executions as $projectID => $projectExecutions)
|
||||
foreach($projectExecutions as $index => $execution)
|
||||
{
|
||||
$kanbanLink = $this->createLink('execution', 'kanban', "executionID=%s");
|
||||
$cfdLink = $this->createLink('execution', 'cfd', "executionID=%s");
|
||||
$taskLink = $this->createLink('execution', 'task', "executionID=%s");
|
||||
if($execution->type != 'kanban' and $link == $kanbanLink) $link = $taskLink;
|
||||
if($execution->type != 'kanban' and ($link == $kanbanLink or $link == $cfdLink)) $link = $taskLink;
|
||||
if($execution->type == 'kanban' and $link != $kanbanLink) $link = $kanbanLink;
|
||||
|
||||
$selected = $execution->id == $executionID ? 'selected' : '';
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
<?php js::import($jsRoot . 'html2canvas/min.js'); ?>
|
||||
<?php js::set('executionID', $executionID); ?>
|
||||
<?php js::set('chartData', $chartData); ?>
|
||||
<?php js::set('YUnit', $lang->execution->count); ?>
|
||||
<?php js::set('XUnit', $lang->execution->burnXUnit); ?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<?php
|
||||
@@ -33,8 +35,6 @@
|
||||
<h2 class='text-center'><?php echo $executionName . ' - ' . zget($lang->execution->cfdTypeList, $type) . $lang->execution->CFD;?></h2>
|
||||
<div id="cfdWrapper">
|
||||
<div id="cfdChart" style="width: 1200px; height: 600px"></div>
|
||||
<div id="cfdYUnit"><?php echo $lang->execution->count;?></div>
|
||||
<div id="cfdXUnit"><?php echo $lang->execution->burnXUnit;?></div>
|
||||
<div id="burnStatistics">
|
||||
<div class="stat-title"><span class="bg-primary"> </span> <?php echo $lang->execution->charts->cfd->cycleTime;?> <i class="icon icon-help" data-toggle="tooltip" data-tip-class="tooltip-help" data-placement="bottom" title="<?php echo $lang->execution->charts->cfd->cycleTimeTip;?>"></i></div>
|
||||
<h3><?php echo $cycleTimeAvg ? ($cycleTimeAvg . $lang->day) : $lang->noData;?></h3>
|
||||
|
||||
@@ -53,7 +53,6 @@ js::set('projectID', $projectID);
|
||||
js::set('vision', $this->config->vision);
|
||||
js::set('productCount', count($productNames));
|
||||
js::set('executionID', $execution->id);
|
||||
js::set('reviewStoryParis', $reviewStoryParis);
|
||||
js::set('needLinkProducts', $lang->execution->needLinkProducts);
|
||||
js::set('lastUpdateData', '');
|
||||
js::set('rdSearchValue', '');
|
||||
|
||||
@@ -218,7 +218,6 @@ js::set('priv',
|
||||
<?php js::set('entertime', time());?>
|
||||
<?php js::set('fluidBoard', $execution->fluidBoard);?>
|
||||
<?php js::set('displayCards', $execution->displayCards);?>
|
||||
<?php js::set('reviewStoryParis', $reviewStoryParis);?>
|
||||
<?php js::set('needLinkProducts', $lang->execution->needLinkProducts);?>
|
||||
<?php js::set('hourUnit', $config->hourUnit);?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -1,87 +1,120 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div id="mainMenu" class="clearfix main-row fade in">
|
||||
<div id="sidebarHeader">
|
||||
<div class="title" title="<?php echo $moduleName;?>">
|
||||
<?php
|
||||
echo $moduleName;
|
||||
if(!empty($moduleID))
|
||||
{
|
||||
$removeLink = $this->createLink('execution', 'testcase', "executionID=$executionID&productID=$productID&type=all&moduleID=0&orderBy=$orderBy&recTotal=0&recPerPage={$pager->recPerPage}");
|
||||
echo html::a($removeLink, "<i class='icon icon-sm icon-close'></i>", '', "class='text-muted' data-app='{$this->app->tab}'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php echo html::a(inlink('testcase', "executionID=$executionID&type=$type&orderBy=$orderBy"), "<span class='text'>{$lang->execution->all}</span>", '', "class='btn btn-link btn-active-text'");?>
|
||||
<?php echo html::a(inlink('testcase', "executionID=$executionID&productID=$productID&type=$type&moduleID=$moduleID&orderBy=$orderBy"), "<span class='text'>{$lang->execution->all}</span>", '', "class='btn btn-link btn-active-text'");?>
|
||||
</div>
|
||||
<div class="btn-toolbar pull-right">
|
||||
<?php if(common::canModify('execution', $execution)) echo html::a(helper::createLink('testcase', 'create', "productID=$productID&branch=0&moduleID=0&from=execution¶m=$execution->id", '', '', '', true), "<i class='icon icon-plus'></i> " . $lang->testcase->create, '', "class='btn btn-primary' data-app='{$this->app->tab}'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mainContent">
|
||||
<?php if(empty($cases)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->testcase->noCase;?></span>
|
||||
<?php if(common::canModify('execution', $execution) and common::hasPriv('testcase', 'create')):?>
|
||||
<?php echo html::a(helper::createLink('testcase', 'create', "productID=$productID&branch=0&moduleID=0&from=execution¶m=$execution->id", '', '', '', true), "<i class='icon icon-plus'></i> " . $lang->testcase->create, '', "class='btn btn-info' data-app='{$this->app->tab}'");?>
|
||||
<div id="mainContent" class='main-row split-row fade'>
|
||||
<div class="side-col" id='sidebar' data-min-width='235'>
|
||||
<div class="sidebar-toggle"><i class="icon icon-angle-left"></i></div>
|
||||
<div class='cell'>
|
||||
<?php if(empty($moduleTree) or empty($lang->modulePageNav)):?>
|
||||
<hr class="space">
|
||||
<div class="text-center text-muted"><?php echo $lang->testcase->noModule;?></div>
|
||||
<hr class="space">
|
||||
<?php else:?>
|
||||
<?php echo $moduleTree;?>
|
||||
<?php endif;?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<form class='main-table' method='post' id='executionBugForm' data-ride="table">
|
||||
<table class='table has-sort-head' id='bugList'>
|
||||
<?php $vars = "executionID=$executionID&type=$type&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th class='c-pri' title=<?php echo $lang->execution->pri;?>> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
|
||||
<th> <?php common::printOrderLink('title', $orderBy, $vars, $lang->testcase->title);?></th>
|
||||
<th class='c-type'> <?php common::printOrderLink('type', $orderBy, $vars, $lang->typeAB);?></th>
|
||||
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
|
||||
<th class='c-user'> <?php common::printOrderLink('lastRunner', $orderBy, $vars, $lang->testtask->lastRunAccount);?></th>
|
||||
<th class='c-date'> <?php common::printOrderLink('lastRunDate', $orderBy, $vars, $lang->testtask->lastRunTime);?></th>
|
||||
<th class='c-result'><?php common::printOrderLink('lastRunResult', $orderBy, $vars, $lang->testtask->lastRunResult);?></th>
|
||||
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
|
||||
<th class='c-actions-6 text-center'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($cases as $case):?>
|
||||
<?php
|
||||
$caseID = $type == 'assigntome' ? $case->case : $case->id;
|
||||
$runID = $type == 'assigntome' ? $case->id : 0;
|
||||
?>
|
||||
<tr>
|
||||
<td class="c-id">
|
||||
<?php echo sprintf('%03d', $case->id); ?>
|
||||
</td>
|
||||
<td><span class='label-pri <?php echo 'label-pri-' . $case->pri?>' title='<?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?>'><?php echo zget($lang->testcase->priList, $case->pri, $case->pri)?></span></td>
|
||||
<?php $params = "testcaseID=$caseID&version=$case->version";?>
|
||||
<?php if($type == 'assigntome') $params .= "&from=testtask&taskID=$case->task";?>
|
||||
<td class='c-title text-left' title="<?php echo $case->title?>"><?php echo html::a($this->createLink('testcase', 'view', $params, '', '', $case->project), $case->title, null, "style='color: $case->color' data-app='{$this->app->tab}'");?></td>
|
||||
<td><?php echo zget($lang->testcase->typeList, $case->type);?></td>
|
||||
<td><?php echo zget($users, $case->openedBy);?></td>
|
||||
<td><?php echo zget($users, $case->lastRunner);?></td>
|
||||
<td><?php if(!helper::isZeroDate($case->lastRunDate)) echo substr($case->lastRunDate, 5, 11);?></td>
|
||||
<td class='<?php echo $case->lastRunResult;?>'><?php if($case->lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?></td>
|
||||
<td>
|
||||
<div class='main-col' data-min-width='400'>
|
||||
<?php if(empty($cases)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->testcase->noCase;?></span>
|
||||
<?php if(common::canModify('execution', $execution) and common::hasPriv('testcase', 'create')):?>
|
||||
<?php echo html::a(helper::createLink('testcase', 'create', "productID=$productID&branch=0&moduleID=0&from=execution¶m=$execution->id", '', '', '', true), "<i class='icon icon-plus'></i> " . $lang->testcase->create, '', "class='btn btn-info' data-app='{$this->app->tab}'");?>
|
||||
<?php endif;?>
|
||||
</p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<form class='main-table' method='post' id='executionBugForm' data-ride="table">
|
||||
<table class='table has-sort-head' id='bugList'>
|
||||
<?php $vars = "executionID=$executionID&productID=$productID&type=$type&moduleID=$moduleID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th class='c-pri' title=<?php echo $lang->execution->pri;?>> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
|
||||
<th> <?php common::printOrderLink('title', $orderBy, $vars, $lang->testcase->title);?></th>
|
||||
<th class='c-type'> <?php common::printOrderLink('type', $orderBy, $vars, $lang->typeAB);?></th>
|
||||
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
|
||||
<th class='c-user'> <?php common::printOrderLink('lastRunner', $orderBy, $vars, $lang->testtask->lastRunAccount);?></th>
|
||||
<th class='c-date'> <?php common::printOrderLink('lastRunDate', $orderBy, $vars, $lang->testtask->lastRunTime);?></th>
|
||||
<th class='c-result'><?php common::printOrderLink('lastRunResult', $orderBy, $vars, $lang->testtask->lastRunResult);?></th>
|
||||
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
|
||||
<th class='c-actions-6 text-center'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($cases as $case):?>
|
||||
<?php
|
||||
if($case->needconfirm)
|
||||
{
|
||||
echo "<span class='status-story status-changed' title='{$this->lang->story->changed}'>{$this->lang->story->changed}</span>";
|
||||
}
|
||||
elseif(isset($case->fromCaseVersion) and $case->fromCaseVersion > $case->version and !$case->needconfirm)
|
||||
{
|
||||
echo "<span class='status-story status-changed' title='{$this->lang->testcase->changed}'>{$this->lang->testcase->changed}</span>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<span class='status-testcase status-{$case->status}'>" . $this->processStatus('testcase', $case) . "</span>";
|
||||
}
|
||||
$caseID = $type == 'assigntome' ? $case->case : $case->id;
|
||||
$runID = $type == 'assigntome' ? $case->id : 0;
|
||||
?>
|
||||
</td>
|
||||
<td class='c-actions'>
|
||||
<tr>
|
||||
<td class="c-id">
|
||||
<?php echo sprintf('%03d', $case->id); ?>
|
||||
</td>
|
||||
<td><span class='label-pri <?php echo 'label-pri-' . $case->pri?>' title='<?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?>'><?php echo zget($lang->testcase->priList, $case->pri, $case->pri)?></span></td>
|
||||
<?php $params = "testcaseID=$caseID&version=$case->version";?>
|
||||
<?php if($type == 'assigntome') $params .= "&from=testtask&taskID=$case->task";?>
|
||||
<td class='c-title text-left' title="<?php echo $case->title?>"><?php echo html::a($this->createLink('testcase', 'view', $params, '', '', $case->project), $case->title, null, "style='color: $case->color' data-app='{$this->app->tab}'");?></td>
|
||||
<td><?php echo zget($lang->testcase->typeList, $case->type);?></td>
|
||||
<td><?php echo zget($users, $case->openedBy);?></td>
|
||||
<td><?php echo zget($users, $case->lastRunner);?></td>
|
||||
<td><?php if(!helper::isZeroDate($case->lastRunDate)) echo substr($case->lastRunDate, 5, 11);?></td>
|
||||
<td class='<?php echo $case->lastRunResult;?>'><?php if($case->lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?></td>
|
||||
<td>
|
||||
<?php
|
||||
$case->browseType = $type;
|
||||
echo $this->testcase->buildOperateMenu($case, 'browse');
|
||||
if($case->needconfirm)
|
||||
{
|
||||
echo "<span class='status-story status-changed' title='{$this->lang->story->changed}'>{$this->lang->story->changed}</span>";
|
||||
}
|
||||
elseif(isset($case->fromCaseVersion) and $case->fromCaseVersion > $case->version and !$case->needconfirm)
|
||||
{
|
||||
echo "<span class='status-story status-changed' title='{$this->lang->testcase->changed}'>{$this->lang->testcase->changed}</span>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<span class='status-testcase status-{$case->status}'>" . $this->processStatus('testcase', $case) . "</span>";
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-footer"><?php $pager->show('right', 'pagerjs');?></div>
|
||||
</form>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
<td class='c-actions'>
|
||||
<?php
|
||||
$case->browseType = $type;
|
||||
echo $this->testcase->buildOperateMenu($case, 'browse');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-footer"><?php $pager->show('right', 'pagerjs');?></div>
|
||||
</form>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<?php js::set('moduleID', $moduleID);?>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
$('#module' + moduleID).closest('li').addClass('active');
|
||||
});
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
$config->gitea->create = new stdclass;
|
||||
$config->gitea->create->requiredFields = 'name,url,token';
|
||||
|
||||
$config->gitea->edit = new stdclass;
|
||||
$config->gitea->edit->requiredFields = 'name,url,token';
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* The control file of gitea module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: ${FILE_NAME} 5144 2020/1/8 8:10 下午 chenqi@cnezsoft.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class gitea extends control
|
||||
{
|
||||
/**
|
||||
* The gitea constructor.
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
*/
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct($moduleName, $methodName);
|
||||
|
||||
/* This is essential when changing tab(menu) from gitea to repo. */
|
||||
/* Optional: common::setMenuVars('devops', $this->session->repoID); */
|
||||
$this->loadModel('ci')->setMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse gitea.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
/* Admin user don't need bind. */
|
||||
$giteaList = $this->gitea->getList($orderBy, $pager);
|
||||
|
||||
$this->view->title = $this->lang->gitea->common . $this->lang->colon . $this->lang->gitea->browse;
|
||||
$this->view->giteaList = $giteaList;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->pager = $pager;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a gitea.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$this->checkToken();
|
||||
$giteaID = $this->gitea->create();
|
||||
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$actionID = $this->loadModel('action')->create('gitea', $giteaID, 'created');
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->gitea->common . $this->lang->colon . $this->lang->gitea->lblCreate;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* View a gitea.
|
||||
* @param int $giteaID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function view($giteaID)
|
||||
{
|
||||
$gitea = $this->gitea->getByID($giteaID);
|
||||
|
||||
$this->view->title = $this->lang->gitea->common . $this->lang->colon . $this->lang->gitea->view;
|
||||
$this->view->gitea = $gitea;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
|
||||
$this->view->actions = $this->loadModel('action')->getList('gitea', $giteaID);
|
||||
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('pipeline', $giteaID);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a gitea.
|
||||
*
|
||||
* @param int $giteaID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($giteaID)
|
||||
{
|
||||
$oldGitea = $this->gitea->getByID($giteaID);
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
$this->checkToken();
|
||||
$this->gitea->update($giteaID);
|
||||
$gitea = $this->gitea->getByID($giteaID);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->loadModel('action');
|
||||
$actionID = $this->action->create('gitea', $giteaID, 'edited');
|
||||
$changes = common::createChanges($oldGitea, $gitea);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->gitea->common . $this->lang->colon . $this->lang->gitea->edit;
|
||||
$this->view->gitea = $oldGitea;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a gitea.
|
||||
*
|
||||
* @param int $giteaID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($giteaID, $confirm = 'no')
|
||||
{
|
||||
if($confirm != 'yes') return print(js::confirm($this->lang->gitea->confirmDelete, inlink('delete', "id=$giteaID&confirm=yes")));
|
||||
|
||||
$oldGitea = $this->gitea->getByID($giteaID);
|
||||
$this->gitea->delete(TABLE_PIPELINE, $giteaID);
|
||||
|
||||
$actionID = $this->dao->lastInsertID();
|
||||
$gitea = $this->gitea->getByID($giteaID);
|
||||
$changes = common::createChanges($oldGitea, $gitea);
|
||||
$this->loadModel('action')->logHistory($actionID, $changes);
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check post token has admin permissions.
|
||||
*
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function checkToken()
|
||||
{
|
||||
$gitea = fixer::input('post')->trim('url,token')->get();
|
||||
$this->dao->update('gitea')->data($gitea)->batchCheck($this->config->gitea->create->requiredFields, 'notempty');
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$result = $this->gitea->checkTokenAccess($gitea->url, $gitea->token);
|
||||
|
||||
if($result === false) return $this->send(array('result' => 'fail', 'message' => array('url' => array($this->lang->gitea->hostError))));
|
||||
if(!$result) return $this->send(array('result' => 'fail', 'message' => array('token' => array($this->lang->gitea->tokenLimit))));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
.c-id {width: 60px;}
|
||||
.c-name {width: 200px;}
|
||||
@@ -0,0 +1,2 @@
|
||||
#publicTip {padding-left: 10px;}
|
||||
.table-form>tbody>tr>th {width: 110px;}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
$lang->gitea = new stdclass;
|
||||
$lang->gitea->common = 'Gitea';
|
||||
$lang->gitea->browse = 'Gitea Browse';
|
||||
$lang->gitea->search = 'Search';
|
||||
$lang->gitea->create = 'Create Gitea';
|
||||
$lang->gitea->edit = 'Edit Gitea';
|
||||
$lang->gitea->view = 'View Gitea';
|
||||
$lang->gitea->delete = 'Delete Gitea';
|
||||
$lang->gitea->confirmDelete = 'Do you want to delete this Gitea server?';
|
||||
|
||||
$lang->gitea->browseAction = 'Gitea List';
|
||||
$lang->gitea->deleteAction = 'Delete Gitea';
|
||||
|
||||
$lang->gitea->id = 'ID';
|
||||
$lang->gitea->name = "Server Name";
|
||||
$lang->gitea->url = 'Server URL';
|
||||
$lang->gitea->token = 'Token';
|
||||
|
||||
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
|
||||
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
|
||||
|
||||
$lang->gitea->server = "Server List";
|
||||
$lang->gitea->lblCreate = 'Create Gitea Server';
|
||||
$lang->gitea->emptyError = " cannot be empty";
|
||||
$lang->gitea->createSuccess = "Create success";
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
$lang->gitea = new stdclass;
|
||||
$lang->gitea->common = 'Gitea';
|
||||
$lang->gitea->browse = 'Gitea Browse';
|
||||
$lang->gitea->search = 'Search';
|
||||
$lang->gitea->create = 'Create Gitea';
|
||||
$lang->gitea->edit = 'Edit Gitea';
|
||||
$lang->gitea->view = 'View Gitea';
|
||||
$lang->gitea->delete = 'Delete Gitea';
|
||||
$lang->gitea->confirmDelete = 'Do you want to delete this Gitea server?';
|
||||
|
||||
$lang->gitea->browseAction = 'Gitea List';
|
||||
$lang->gitea->deleteAction = 'Delete Gitea';
|
||||
|
||||
$lang->gitea->id = 'ID';
|
||||
$lang->gitea->name = "Server Name";
|
||||
$lang->gitea->url = 'Server URL';
|
||||
$lang->gitea->token = 'Token';
|
||||
|
||||
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
|
||||
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
|
||||
|
||||
$lang->gitea->server = "Server List";
|
||||
$lang->gitea->lblCreate = 'Create Gitea Server';
|
||||
$lang->gitea->emptyError = " cannot be empty";
|
||||
$lang->gitea->createSuccess = "Create success";
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
$lang->gitea = new stdclass;
|
||||
$lang->gitea->common = 'Gitea';
|
||||
$lang->gitea->browse = 'Gitea Browse';
|
||||
$lang->gitea->search = 'Search';
|
||||
$lang->gitea->create = 'Create Gitea';
|
||||
$lang->gitea->edit = 'Edit Gitea';
|
||||
$lang->gitea->view = 'View Gitea';
|
||||
$lang->gitea->delete = 'Delete Gitea';
|
||||
$lang->gitea->confirmDelete = 'Do you want to delete this Gitea server?';
|
||||
|
||||
$lang->gitea->browseAction = 'Gitea List';
|
||||
$lang->gitea->deleteAction = 'Delete Gitea';
|
||||
|
||||
$lang->gitea->id = 'ID';
|
||||
$lang->gitea->name = "Server Name";
|
||||
$lang->gitea->url = 'Server URL';
|
||||
$lang->gitea->token = 'Token';
|
||||
|
||||
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
|
||||
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
|
||||
|
||||
$lang->gitea->server = "Server List";
|
||||
$lang->gitea->lblCreate = 'Create Gitea Server';
|
||||
$lang->gitea->emptyError = " cannot be empty";
|
||||
$lang->gitea->createSuccess = "Create success";
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
$lang->gitea = new stdclass;
|
||||
$lang->gitea->common = 'Gitea';
|
||||
$lang->gitea->browse = 'Gitea Browse';
|
||||
$lang->gitea->search = 'Search';
|
||||
$lang->gitea->create = 'Create Gitea';
|
||||
$lang->gitea->edit = 'Edit Gitea';
|
||||
$lang->gitea->view = 'View Gitea';
|
||||
$lang->gitea->delete = 'Delete Gitea';
|
||||
$lang->gitea->confirmDelete = 'Do you want to delete this Gitea server?';
|
||||
|
||||
$lang->gitea->browseAction = 'Gitea List';
|
||||
$lang->gitea->deleteAction = 'Delete Gitea';
|
||||
|
||||
$lang->gitea->id = 'ID';
|
||||
$lang->gitea->name = "Server Name";
|
||||
$lang->gitea->url = 'Server URL';
|
||||
$lang->gitea->token = 'Token';
|
||||
|
||||
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
|
||||
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
|
||||
|
||||
$lang->gitea->server = "Server List";
|
||||
$lang->gitea->lblCreate = 'Create Gitea Server';
|
||||
$lang->gitea->emptyError = " cannot be empty";
|
||||
$lang->gitea->createSuccess = "Create success";
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
$lang->gitea = new stdclass;
|
||||
$lang->gitea->common = 'Gitea';
|
||||
$lang->gitea->browse = '浏览Gitea';
|
||||
$lang->gitea->search = '搜索';
|
||||
$lang->gitea->create = '添加Gitea';
|
||||
$lang->gitea->edit = '编辑Gitea';
|
||||
$lang->gitea->view = '查看Gitea';
|
||||
$lang->gitea->delete = '删除Gitea';
|
||||
$lang->gitea->confirmDelete = '确认删除该Gitea吗?';
|
||||
|
||||
$lang->gitea->browseAction = 'Gitea列表';
|
||||
$lang->gitea->deleteAction = '删除Gitea';
|
||||
|
||||
$lang->gitea->id = 'ID';
|
||||
$lang->gitea->name = "服务器名称";
|
||||
$lang->gitea->url = '服务器地址';
|
||||
$lang->gitea->token = 'Token';
|
||||
|
||||
$lang->gitea->tokenLimit = "Gitea Token权限不足。";
|
||||
$lang->gitea->hostError = "当前Gitea服务器地址无效,请确认当前服务器可被访问";
|
||||
|
||||
$lang->gitea->server = "服务器列表";
|
||||
$lang->gitea->lblCreate = '添加Gitea服务器';
|
||||
$lang->gitea->emptyError = "不能为空";
|
||||
$lang->gitea->createSuccess = "创建成功";
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
$lang->gitea = new stdclass;
|
||||
$lang->gitea->common = 'Gitea';
|
||||
$lang->gitea->browse = '浏览Gitea';
|
||||
$lang->gitea->search = '搜索';
|
||||
$lang->gitea->create = '添加Gitea';
|
||||
$lang->gitea->edit = '编辑Gitea';
|
||||
$lang->gitea->view = '查看Gitea';
|
||||
$lang->gitea->delete = '删除Gitea';
|
||||
$lang->gitea->confirmDelete = '确认删除该Gitea吗?';
|
||||
|
||||
$lang->gitea->browseAction = 'Gitea列表';
|
||||
$lang->gitea->deleteAction = '删除Gitea';
|
||||
|
||||
$lang->gitea->id = 'ID';
|
||||
$lang->gitea->name = "服务器名称";
|
||||
$lang->gitea->url = '服务器地址';
|
||||
$lang->gitea->token = 'Token';
|
||||
|
||||
$lang->gitea->tokenLimit = "Gitea Token权限不足。";
|
||||
$lang->gitea->hostError = "当前Gitea服务器地址无效,请确认当前服务器可被访问";
|
||||
|
||||
$lang->gitea->server = "服务器列表";
|
||||
$lang->gitea->lblCreate = '添加Gitea服务器';
|
||||
$lang->gitea->emptyError = "不能为空";
|
||||
$lang->gitea->createSuccess = "创建成功";
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
/**
|
||||
* The model file of gitea module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Chenqi <chenqi@cnezsoft.com>
|
||||
* @package product
|
||||
* @version $Id: $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
|
||||
class giteaModel extends model
|
||||
{
|
||||
|
||||
const HOOK_PUSH_EVENT = 'Push Hook';
|
||||
|
||||
/* Gitlab access level. */
|
||||
public $noAccess = 0;
|
||||
public $developerAccess = 30;
|
||||
public $maintainerAccess = 40;
|
||||
|
||||
/**
|
||||
* Get a gitea by id.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getByID($id)
|
||||
{
|
||||
return $this->loadModel('pipeline')->getByID($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gitea list.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getList($orderBy = 'id_desc', $pager = null)
|
||||
{
|
||||
$giteaList = $this->loadModel('pipeline')->getList('gitea', $orderBy, $pager);
|
||||
|
||||
return $giteaList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gitea pairs.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getPairs()
|
||||
{
|
||||
return $this->loadModel('pipeline')->getPairs('gitea');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gitea api base url by gitea id.
|
||||
*
|
||||
* @param int $giteaID
|
||||
* @param bool $sudo
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getApiRoot($giteaID, $sudo = true)
|
||||
{
|
||||
$gitea = $this->getByID($giteaID);
|
||||
if(!$gitea) return '';
|
||||
|
||||
$sudoParam = '';
|
||||
if($sudo == true and !$this->app->user->admin)
|
||||
{
|
||||
$openID = $this->getUserIDByZentaoAccount($giteaID, $this->app->user->account);
|
||||
if($openID) $sudoParam = "&sudo={$openID}";
|
||||
}
|
||||
|
||||
return rtrim($gitea->url, '/') . '/api/v1%s' . "?token={$gitea->token}" . $sudoParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a gitea.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return $this->loadModel('pipeline')->create('gitea');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a gitea.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
return $this->loadModel('pipeline')->update($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Api error handling.
|
||||
*
|
||||
* @param object $response
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function apiErrorHandling($response)
|
||||
{
|
||||
if(!empty($response->error))
|
||||
{
|
||||
dao::$errors[] = $response->error;
|
||||
return false;
|
||||
}
|
||||
if(!empty($response->message))
|
||||
{
|
||||
if(is_string($response->message))
|
||||
{
|
||||
$errorKey = array_search($response->message, $this->lang->gitea->apiError);
|
||||
dao::$errors[] = $errorKey === false ? $response->message : zget($this->lang->gitea->errorLang, $errorKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($response->message as $field => $fieldErrors)
|
||||
{
|
||||
if(is_string($fieldErrors))
|
||||
{
|
||||
$errorKey = array_search($fieldErrors, $this->lang->gitea->apiError);
|
||||
if($fieldErrors) dao::$errors[$field][] = $errorKey === false ? $fieldErrors : zget($this->lang->gitea->errorLang, $errorKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($fieldErrors as $error)
|
||||
{
|
||||
$errorKey = array_search($error, $this->lang->gitea->apiError);
|
||||
if($error) dao::$errors[$field][] = $errorKey === false ? $error : zget($this->lang->gitea->errorLang, $errorKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$response) dao::$errors[] = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user access.
|
||||
*
|
||||
* @param int $giteaID
|
||||
* @param int $projectID
|
||||
* @param object $project
|
||||
* @param string $maxRole
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkUserAccess($giteaID, $projectID = 0, $project = null, $groupIDList = array(), $maxRole = 'maintainer')
|
||||
{
|
||||
if($this->app->user->admin) return true;
|
||||
|
||||
if($project == null) $project = $this->apiGetSingleProject($giteaID, $projectID);
|
||||
if(!isset($project->id)) return false;
|
||||
|
||||
$accessLevel = $this->config->gitea->accessLevel[$maxRole];
|
||||
|
||||
if(isset($project->permissions->project_access->access_level) and $project->permissions->project_access->access_level >= $accessLevel) return true;
|
||||
if(isset($project->permissions->group_access->access_level) and $project->permissions->group_access->access_level >= $accessLevel) return true;
|
||||
if(!empty($project->shared_with_groups))
|
||||
{
|
||||
if(empty($groupIDList))
|
||||
{
|
||||
$groups = $this->apiGetGroups($giteaID, 'name_asc', $maxRole);
|
||||
foreach($groups as $group) $groupIDList[] = $group->id;
|
||||
}
|
||||
|
||||
foreach($project->shared_with_groups as $group)
|
||||
{
|
||||
if($group->group_access_level < $accessLevel) continue;
|
||||
if(in_array($group->group_id, $groupIDList)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check token access.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $token
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkTokenAccess($url = '', $token = '')
|
||||
{
|
||||
$apiRoot = rtrim($url, '/') . '/api/v1%s' . "?token={$token}";
|
||||
$url = sprintf($apiRoot, "/admin/users") . "&limit=1";
|
||||
$httpData = commonModel::httpWithHeader($url);
|
||||
$users = json_decode($httpData['body']);
|
||||
if(empty($users)) return false;
|
||||
if(isset($users->message) or isset($users->error)) return null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Gitea id list by user account.
|
||||
*
|
||||
* @param string $account
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getGiteaListByAccount($account = '')
|
||||
{
|
||||
if(!$account) $account = $this->app->user->account;
|
||||
|
||||
return $this->dao->select('providerID,openID')->from(TABLE_OAUTH)
|
||||
->where('providerType')->eq('gitea')
|
||||
->andWhere('account')->eq($account)
|
||||
->fetchPairs('providerID');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* The browse view file of gitea module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package gitea
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php echo html::a($this->createLink('gitea', 'browse'), "<span class='text'>{$lang->gitea->server}</span>", '', "class='btn btn-link btn-active-text'");?>
|
||||
</div>
|
||||
<div class="btn-toolbar pull-right">
|
||||
<?php if(common::hasPriv('gitea', 'create')) common::printLink('gitea', 'create', "", "<i class='icon icon-plus'></i> " . $lang->gitea->create, '', "class='btn btn-primary'");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if(empty($giteaList)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->noData;?></span>
|
||||
<?php if(common::hasPriv('gitea', 'create')):?>
|
||||
<?php echo html::a($this->createLink('gitea', 'create'), "<i class='icon icon-plus'></i> " . $lang->gitea->create, '', "class='btn btn-info'");?>
|
||||
<?php endif;?>
|
||||
</p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div id='mainContent' class='main-row'>
|
||||
<form class='main-table' id='ajaxForm' method='post'>
|
||||
<table id='giteaList' class='table has-sort-head table-fixed'>
|
||||
<thead>
|
||||
<tr>
|
||||
<?php $vars = "orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
|
||||
<th class='c-id text-center'><?php common::printOrderLink('id', $orderBy, $vars, $lang->gitea->id);?></th>
|
||||
<th class='c-name text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->gitea->name);?></th>
|
||||
<th class='text-left'><?php common::printOrderLink('url', $orderBy, $vars, $lang->gitea->url);?></th>
|
||||
<th class='c-actions-3'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($giteaList as $id => $gitea): ?>
|
||||
<tr class='text'>
|
||||
<td class='text-center'><?php echo $id;?></td>
|
||||
<td class='text-c-name' title='<?php echo $gitea->name;?>'>
|
||||
<?php if(common::hasPriv('gitea', 'view')):?>
|
||||
<a class="iframe" href="<?php echo $this->createLink('gitea', 'view', "giteaID=$id", '', true); ?>"><?php echo $gitea->name;?></a>
|
||||
<?php else:?>
|
||||
<?php echo $gitea->name;?>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
<td class='text' title='<?php echo $gitea->url;?>'><?php echo html::a($gitea->url, $gitea->url, '_target');?></td>
|
||||
<td class='c-actions text-left'>
|
||||
<?php
|
||||
common::printIcon('gitea', 'edit', "giteaID=$id", '', 'list', 'edit');
|
||||
common::printIcon('gitea', 'delete', "giteaID=$id", '', 'list', 'trash', 'hiddenwin');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php if($giteaList):?>
|
||||
<div class='table-footer'><?php $pager->show('right', 'pagerjs');?></div>
|
||||
<?php endif;?>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* The create view file of gitea module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package gitea
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='main-col main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->gitea->lblCreate;?></h2>
|
||||
</div>
|
||||
<form id='giteaForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th><?php echo $lang->gitea->name;?></th>
|
||||
<td class='required'><?php echo html::input('name', '', "class='form-control'");?></td>
|
||||
<td class="tips-git"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->gitea->url;?></th>
|
||||
<td class='required'><?php echo html::input('url', '', "class='form-control'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->gitea->token;?></th>
|
||||
<td><?php echo html::input('token', '', "class='form-control'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td class='text-center form-actions'>
|
||||
<?php echo html::submitButton();?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* The edit view file of gitea module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2017 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Gang Liu <liugang@cnezsoft.com>
|
||||
* @package gitea
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='mainContent' class='main-row'>
|
||||
<div class='main-col main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->gitea->edit;?></h2>
|
||||
</div>
|
||||
<form id='giteaForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th><?php echo $lang->gitea->name;?></th>
|
||||
<td class='required'><?php echo html::input('name', isset($gitea->name) ? $gitea->name : '', "class='form-control'");?></td>
|
||||
<td class="tips-git"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->gitea->url;?></th>
|
||||
<td class='required'><?php echo html::input('url', isset($gitea->url) ? $gitea->url : '', "class='form-control'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->gitea->token;?></th>
|
||||
<td><?php echo html::input('token', isset($gitea->token) ? $gitea->token : '', "class='form-control'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td class='text-center form-actions'>
|
||||
<?php echo html::submitButton();?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* The view file of GitLab module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author dave.li <lichengjun@cnezsoft.com>
|
||||
* @package GitLab
|
||||
* @version $Id: view.html.php 4728 2013-05-03 06:14:34Z david18810279601@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
* */
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<style>.action-cell {margin-bottom: 10px;}</style>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class="btn-toolbar pull-left">
|
||||
<div class="page-title">
|
||||
<span class="label label-id"><?php echo $gitea->id?></span>
|
||||
<span class="text" title="<?php echo $gitea->name;?>" style='color: #3c4354'><?php echo $gitea->name;?></span>
|
||||
<?php if($gitea->deleted):?>
|
||||
<span class='label label-danger'><?php echo $lang->gitea->deleted;?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mainContent" class="main-row">
|
||||
<div class="main-col col-8">
|
||||
<div class="cell">
|
||||
<div class="detail">
|
||||
<div class="detail-title"><?php echo $lang->gitea->url;?></div>
|
||||
<div class="detail-content article-content"><?php echo html::a($gitea->url, $gitea->url, '_target');?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='cell action-cell'><?php include '../../common/view/action.html.php';?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -62,7 +62,7 @@ class gitlab extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* create a gitlab.
|
||||
* Create a gitlab.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -86,7 +86,7 @@ class gitlab extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* view a gitlab.
|
||||
* View a gitlab.
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -642,7 +642,7 @@ class gitlab extends control
|
||||
$userPairs = array('' => '');
|
||||
foreach($users as $user)
|
||||
{
|
||||
if(!isset($bindedUsers[$user->account]) or $u->account == $zentaoBindAccount) $userPairs[$user->account] = $user->realname;
|
||||
if(!isset($bindedUsers[$user->account]) or $user->account == $zentaoBindAccount) $userPairs[$user->account] = $user->realname;
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->user->edit;
|
||||
|
||||
@@ -2896,4 +2896,23 @@ class gitlabModel extends model
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download zip code.
|
||||
*
|
||||
* @param int $gitlabID
|
||||
* @param int $projectID
|
||||
* @param string $branch
|
||||
* @param string $ext tar.gz|tar.bz2|tbz|tbz2|tb2|bz2|tar|zip
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function downloadCode($gitlabID = 0, $projectID = 0, $branch = '', $ext = 'zip')
|
||||
{
|
||||
if(empty($gitlabID) or empty($projectID)) return false;
|
||||
|
||||
$url = sprintf($this->getApiRoot($gitlabID), "/projects/$projectID/repository/archive." . $ext);
|
||||
if($branch) $url .= '&sha=' . $branch;
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<h2><?php echo $lang->gitlab->importIssue;?></h2>
|
||||
<?php if(!isonlybody() and empty($importable)):?>
|
||||
<div class='pull-right'>
|
||||
<?php echo html::linkButton($lang->goback, $this->createLink('repo', 'maintain'), 'self', '', 'btn btn-primary');?>
|
||||
<?php echo html::backButton($lang->goback, "data-app='{$app->tab}'", 'btn btn-primary');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
@@ -51,7 +51,7 @@
|
||||
<tr>
|
||||
<td class='text-center form-actions' colspan='4'>
|
||||
<?php echo html::submitButton($lang->save);?>
|
||||
<?php if(!isonlybody()) echo html::a($this->createLink('repo', 'maintain', ""), $lang->goback, '', 'class="btn btn-wide"');?>
|
||||
<?php if(!isonlybody()) echo html::backButton($lang->goback, "data-app='{$app->tab}'", 'btn btn-wide');?>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
|
||||
@@ -69,6 +69,7 @@ $lang->moduleOrder[215] = 'message';
|
||||
$lang->moduleOrder[220] = 'gitlab';
|
||||
$lang->moduleOrder[225] = 'mr';
|
||||
$lang->moduleOrder[230] = 'app';
|
||||
$lang->moduleOrder[235] = 'gitea';
|
||||
|
||||
$lang->resource = new stdclass();
|
||||
|
||||
@@ -1384,6 +1385,20 @@ $lang->gitlab->methodOrder[135] = 'browseTag';
|
||||
$lang->gitlab->methodOrder[140] = 'browseTagPriv';
|
||||
$lang->gitlab->methodOrder[145] = 'deleteTagPriv';
|
||||
|
||||
/* Gitea. */
|
||||
$lang->resource->gitea = new stdclass();
|
||||
$lang->resource->gitea->browse = 'browse';
|
||||
$lang->resource->gitea->create = 'create';
|
||||
$lang->resource->gitea->edit = 'edit';
|
||||
$lang->resource->gitea->view = 'view';
|
||||
$lang->resource->gitea->delete = 'delete';
|
||||
|
||||
$lang->gitea->methodOrder[5] = 'browse';
|
||||
$lang->gitea->methodOrder[10] = 'create';
|
||||
$lang->gitea->methodOrder[15] = 'edit';
|
||||
$lang->gitea->methodOrder[20] = 'view';
|
||||
$lang->gitea->methodOrder[25] = 'delete';
|
||||
|
||||
/* SonarQube. */
|
||||
$lang->resource->sonarqube = new stdclass();
|
||||
$lang->resource->sonarqube->browse = 'browse';
|
||||
|
||||
@@ -10,7 +10,7 @@ $lang->jenkins->browseAction = 'Jenkins List';
|
||||
$lang->jenkins->deleteAction = 'Delete Jenkins';
|
||||
|
||||
$lang->jenkins->id = 'ID';
|
||||
$lang->jenkins->name = 'Name';
|
||||
$lang->jenkins->name = 'Server Name';
|
||||
$lang->jenkins->url = 'Server URL';
|
||||
$lang->jenkins->token = 'Token';
|
||||
$lang->jenkins->account = 'Username';
|
||||
|
||||
@@ -10,7 +10,7 @@ $lang->jenkins->browseAction = 'Jenkins列表';
|
||||
$lang->jenkins->deleteAction = '删除Jenkins';
|
||||
|
||||
$lang->jenkins->id = 'ID';
|
||||
$lang->jenkins->name = '名称';
|
||||
$lang->jenkins->name = '服务器名称';
|
||||
$lang->jenkins->url = '服务器地址';
|
||||
$lang->jenkins->token = 'Token';
|
||||
$lang->jenkins->account = '用户名';
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
$lang->pipeline->id = 'ID';
|
||||
$lang->pipeline->name = 'Server Name';
|
||||
$lang->pipeline->url = 'Server URL';
|
||||
$lang->pipeline->token = 'Token';
|
||||
$lang->pipeline->account = 'Username';
|
||||
$lang->pipeline->password = 'Password';
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
$lang->pipeline->id = 'ID';
|
||||
$lang->pipeline->name = 'Server Name';
|
||||
$lang->pipeline->url = 'Server URL';
|
||||
$lang->pipeline->token = 'Token';
|
||||
$lang->pipeline->account = 'Username';
|
||||
$lang->pipeline->password = 'Password';
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
$lang->pipeline->id = 'ID';
|
||||
$lang->pipeline->name = 'Server Name';
|
||||
$lang->pipeline->url = 'Server URL';
|
||||
$lang->pipeline->token = 'Token';
|
||||
$lang->pipeline->account = 'Username';
|
||||
$lang->pipeline->password = 'Password';
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
$lang->pipeline->id = 'ID';
|
||||
$lang->pipeline->name = 'Server Name';
|
||||
$lang->pipeline->url = 'Server URL';
|
||||
$lang->pipeline->token = 'Token';
|
||||
$lang->pipeline->account = 'Username';
|
||||
$lang->pipeline->password = 'Password';
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
$lang->pipeline->id = 'ID';
|
||||
$lang->pipeline->name = '名称';
|
||||
$lang->pipeline->url = '服务地址';
|
||||
$lang->pipeline->name = '服务器名称';
|
||||
$lang->pipeline->url = '服务器地址';
|
||||
$lang->pipeline->token = 'Token';
|
||||
$lang->pipeline->account = '用户名';
|
||||
$lang->pipeline->password = '密码';
|
||||
|
||||
@@ -93,6 +93,7 @@ class productModel extends model
|
||||
}
|
||||
$isMobile = $this->app->viewType == 'mhtml';
|
||||
|
||||
$productID = $productID == 'all' ? 0 : $productID;
|
||||
setcookie("lastProduct", $productID, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true);
|
||||
if($productID) $currentProduct = $this->getById($productID);
|
||||
|
||||
|
||||
@@ -1314,9 +1314,10 @@ class repo extends control
|
||||
mkdir($savePath, 0777, true);
|
||||
}
|
||||
|
||||
$repo = $this->repo->getRepoByID($repoID);
|
||||
if($repo->SCM == 'Gitlab')
|
||||
{
|
||||
return '';
|
||||
$url = $this->loadModel('gitlab')->downloadCode($repo->gitlab, $repo->project, $branch);
|
||||
}
|
||||
elseif($repo->SCM == 'Git')
|
||||
{
|
||||
@@ -1344,5 +1345,7 @@ class repo extends control
|
||||
|
||||
$url = DS . 'data' . DS . 'repo' . DS . $repo->name . '.zip';
|
||||
}
|
||||
|
||||
$this->locate($url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,13 @@ $(function()
|
||||
{
|
||||
$('#downloadCode').popover('show');
|
||||
|
||||
$('.copy-btn').tooltip({
|
||||
trigger: 'click',
|
||||
placement: 'bottom',
|
||||
title: lang.copied,
|
||||
tipClass: 'tooltip-success'
|
||||
});
|
||||
|
||||
/* Set popover area. */
|
||||
var left = parseFloat($('.download-popover').css('left')) - 155;
|
||||
$('.download-popover').css('left', left + 'px')
|
||||
@@ -80,12 +87,18 @@ $(function()
|
||||
var copyText = $(this).parent().parent().find('input');
|
||||
copyText .select();
|
||||
document.execCommand("Copy");
|
||||
alert(lang.copied);
|
||||
|
||||
$(this).tooltip('show');
|
||||
var that = this;
|
||||
setTimeout(function()
|
||||
{
|
||||
$(that).tooltip('hide')
|
||||
}, 2000)
|
||||
})
|
||||
|
||||
$('.download-btn').live('click', function()
|
||||
{
|
||||
var link = createLink('repo', 'downloadCode', 'repoID=' + repoID);
|
||||
var link = createLink('repo', 'downloadCode', 'repoID=' + repoID + '&branch=' + branch);
|
||||
window.open(link);
|
||||
})
|
||||
})
|
||||
|
||||
+14
-16
@@ -315,6 +315,20 @@ class report extends control
|
||||
$users[''] = $this->lang->report->annualData->allUser;
|
||||
|
||||
$depts = $this->loadModel('dept')->getOptionMenu();
|
||||
$accounts = array();
|
||||
if($userID)
|
||||
{
|
||||
$user = $this->loadModel('user')->getById($userID, 'id');
|
||||
$dept = $user->dept;
|
||||
$users = $this->loadModel('dept')->getDeptUserPairs($dept, 'id');
|
||||
$accounts = array($user->account => ($user->realname ? $user->realname : $user->account));
|
||||
}
|
||||
else
|
||||
{
|
||||
$users = $this->loadModel('dept')->getDeptUserPairs($dept, 'id');
|
||||
$users = array('' => $this->lang->report->annualData->allUser) + $users;
|
||||
$accounts = $this->loadModel('dept')->getDeptUserPairs($dept);
|
||||
}
|
||||
if(!$this->app->user->admin)
|
||||
{
|
||||
foreach($depts as $id => $name) if($id != $this->app->user->dept) unset($depts[$id]);
|
||||
@@ -323,25 +337,9 @@ class report extends control
|
||||
{
|
||||
$depts = array('' => $this->lang->report->annualData->allDept) + $depts;
|
||||
}
|
||||
if(empty($userID)) unset($depts[0]);
|
||||
|
||||
$accounts = array();
|
||||
if($dept) $accounts = $this->loadModel('dept')->getDeptUserPairs($dept);
|
||||
if($userID)
|
||||
{
|
||||
$user = $this->loadModel('user')->getById($userID, 'id');
|
||||
$dept = $user->dept;
|
||||
$accounts = array($user->account => ($user->realname ? $user->realname : $user->account));
|
||||
}
|
||||
if(empty($accounts)) $accounts = $this->user->getPairs('noletter|noclosed');
|
||||
if($accounts) $accounts = array_keys($accounts);
|
||||
|
||||
if($dept)
|
||||
{
|
||||
$users = $this->loadModel('dept')->getDeptUserPairs($dept, 'id');
|
||||
$users = array('' => $this->lang->report->annualData->allUser) + $users;
|
||||
}
|
||||
|
||||
/* Get annual data. */
|
||||
$data = array();
|
||||
if(!$userID)
|
||||
|
||||
@@ -30,6 +30,7 @@ $lang->search->noQuery = 'Keine Suche gespeichert';
|
||||
$lang->search->onMenuBar = 'In Menü anzeigen';
|
||||
$lang->search->custom = 'Eigene';
|
||||
$lang->search->setCommon = 'Set as public query criteria';
|
||||
$lang->search->saveCondition = 'Save search options';
|
||||
|
||||
$lang->search->account = 'Konto';
|
||||
$lang->search->module = 'Module';
|
||||
|
||||
@@ -30,6 +30,7 @@ $lang->search->noQuery = 'No query is saved yet!';
|
||||
$lang->search->onMenuBar = 'Show in Menu';
|
||||
$lang->search->custom = 'Custom';
|
||||
$lang->search->setCommon = 'Set as public query criteria';
|
||||
$lang->search->saveCondition = 'Save search options';
|
||||
|
||||
$lang->search->account = 'Account';
|
||||
$lang->search->module = 'Module';
|
||||
|
||||
@@ -30,6 +30,7 @@ $lang->search->noQuery = 'Aucune query de sauvegardée !';
|
||||
$lang->search->onMenuBar = 'Montrer dans le Menu';
|
||||
$lang->search->custom = 'Personnalisation';
|
||||
$lang->search->setCommon = 'Set as public query criteria';
|
||||
$lang->search->saveCondition = 'Save search options';
|
||||
|
||||
$lang->search->account = 'Compte';
|
||||
$lang->search->module = 'Module';
|
||||
|
||||
@@ -30,6 +30,7 @@ $lang->search->noQuery = '还没有保存查询!';
|
||||
$lang->search->onMenuBar = '显示在菜单栏';
|
||||
$lang->search->custom = '自定义';
|
||||
$lang->search->setCommon = '设为公共查询条件';
|
||||
$lang->search->saveCondition = '保存搜索条件';
|
||||
|
||||
$lang->search->account = '用户名';
|
||||
$lang->search->module = '模块';
|
||||
|
||||
@@ -64,6 +64,7 @@ $formId = 'searchForm-' . uniqid('');
|
||||
html[lang^='zh-'] .fieldWidth {width: 110px !important;}
|
||||
html[lang^='zh-'] .operatorWidth {width: 90px !important;}
|
||||
.table tbody tr td input {display: block !important;}
|
||||
#save-query {color: #0061f2;}
|
||||
</style>
|
||||
<?php if($style != 'simple'):?>
|
||||
<div id='toggle-queries'>
|
||||
@@ -242,12 +243,9 @@ foreach($fieldParams as $fieldName => $param)
|
||||
echo html::hidden('actionURL', $actionURL);
|
||||
echo html::hidden('groupItems', $groupItems);
|
||||
echo html::submitButton($lang->search->common, '', 'btn btn-primary') . " ";
|
||||
if($style != 'simple')
|
||||
{
|
||||
if(common::hasPriv('search', 'saveQuery')) echo html::a($this->createLink('search', 'saveQuery', "module=$module&onMenuBar=$onMenuBar"), $lang->save, '', "class='btn-save-form btn btn-secondary iframe' id='save-query'") . " ";
|
||||
echo html::commonButton($lang->search->reset, '', 'btn-reset-form btn');
|
||||
}
|
||||
if($style != 'simple') echo html::commonButton($lang->search->reset, '', 'btn-reset-form btn');
|
||||
echo html::commonButton('<i class="icon icon-chevron-double-down"></i>', '', 'btn-expand-form btn btn-info pull-right');
|
||||
if($style != 'simple' and common::hasPriv('search', 'saveQuery')) echo html::a($this->createLink('search', 'saveQuery', "module=$module&onMenuBar=$onMenuBar"), '<i class="icon-bug-confirmBug icon-ok"></i> ' . $lang->search->saveCondition, '', "class='btn-save-form btn btn-link iframe pull-right' id='save-query'");
|
||||
echo html::hidden('formType', zget($formSession, 'formType', 'lite'));
|
||||
?>
|
||||
</td>
|
||||
@@ -306,9 +304,11 @@ $(function()
|
||||
$select.picker(pickerOptions);
|
||||
});
|
||||
|
||||
$('#queryBox select, #queryBox input').change(function(){
|
||||
$('#save-query').attr("disabled","disabled");
|
||||
$('#queryBox select, #queryBox input').change(function()
|
||||
{
|
||||
$('#save-query').attr("disabled", "disabled");
|
||||
})
|
||||
|
||||
/* Toggle user queries action. */
|
||||
$('#toggle-queries').click(function()
|
||||
{
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="text-center">
|
||||
<td><?php echo $measures['bugs'];?></td>
|
||||
<td><?php echo $measures['vulnerabilities'];?></td>
|
||||
<td><?php echo $measures['security_hotspots_reviewed'];?></td>
|
||||
<td><?php echo $measures['code_smells'];?></td>
|
||||
<td><?php echo $measures['coverage'];?></td>
|
||||
<td><?php echo $measures['duplicated_lines_density'];?></td>
|
||||
<td><?php echo $measures['ncloc'];?></td>
|
||||
<td><?php echo zget($measures, 'bugs', 0);?></td>
|
||||
<td><?php echo zget($measures, 'vulnerabilities', 0);?></td>
|
||||
<td><?php echo zget($measures, 'security_hotspots_reviewed', '0.0%');?></td>
|
||||
<td><?php echo zget($measures, 'code_smells', 0);?></td>
|
||||
<td><?php echo zget($measures, 'coverage', '0.0%');?></td>
|
||||
<td><?php echo zget($measures, 'duplicated_lines_density', '0.0%');?></td>
|
||||
<td><?php echo zget($measures, 'ncloc', 0);?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -175,6 +175,12 @@ class story extends control
|
||||
{
|
||||
$this->dao->update(TABLE_TODO)->set('status')->eq('done')->where('id')->eq($todoID)->exec();
|
||||
$this->action->create('todo', $todoID, 'finished', '', "STORY:$storyID");
|
||||
|
||||
if($this->config->edition == 'biz' || $this->config->edition == 'max')
|
||||
{
|
||||
$todo = $this->dao->select('type, idvalue')->from(TABLE_TODO)->where('id')->eq($todoID)->fetch();
|
||||
if($todo->type == 'feedback' && $todo->idvalue) $this->loadModel('feedback')->updateStatus('todo', $todo->idvalue, 'done');
|
||||
}
|
||||
}
|
||||
|
||||
$message = $this->executeHooks($storyID);
|
||||
@@ -184,7 +190,24 @@ class story extends control
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $storyID));
|
||||
|
||||
/* If link from no head then reload. */
|
||||
if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, 0)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
|
||||
}
|
||||
}
|
||||
|
||||
if($this->post->newStory)
|
||||
{
|
||||
@@ -477,7 +500,25 @@ class story extends control
|
||||
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'idList' => $stories));
|
||||
|
||||
if(isonlybody()) return print(js::closeModal('parent.parent', 'this'));
|
||||
if(isonlybody())
|
||||
{
|
||||
$executionID = $executionID ? $executionID : $this->session->execution;
|
||||
$execution = $this->execution->getByID($executionID);
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return print(js::reload('parent.parent'));
|
||||
}
|
||||
}
|
||||
|
||||
if($storyID)
|
||||
{
|
||||
@@ -999,7 +1040,24 @@ class story extends control
|
||||
|
||||
$module = $this->app->tab == 'project' ? 'projectstory' : 'story';
|
||||
|
||||
if(isonlybody()) return print(js::reload('parent.parent'));
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return print(js::reload('parent.parent'));
|
||||
}
|
||||
}
|
||||
|
||||
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success'));
|
||||
return print(js::locate($this->createLink($module, 'view', "storyID=$storyID"), 'parent'));
|
||||
@@ -2187,6 +2245,7 @@ class story extends control
|
||||
$storyInfo['estimate'] = $story->estimate;
|
||||
$storyInfo['pri'] = $story->pri;
|
||||
$storyInfo['spec'] = html_entity_decode($story->spec, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8');
|
||||
$storyInfo['status'] = $story->status;
|
||||
|
||||
echo json_encode($storyInfo);
|
||||
}
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
#batchCreateForm .c-verify {width: 140px;}
|
||||
#batchCreateForm .c-keywords {width: 140px;}
|
||||
.body-modal .main-header > h2 {max-width: 80%;}
|
||||
#batchCreateForm .reviewBox{width: 200px !important;}
|
||||
|
||||
@@ -7,3 +7,6 @@
|
||||
#source_chosen {min-width: 50px !important;}
|
||||
#feedbackBox > .input-group + #notifyEmailLabel {position: relative; width: 50%; left: 48%}
|
||||
#product + .picker{min-width: 400px}
|
||||
#dataform .priBox, #dataform .estimateBox {width: 120px;}
|
||||
#dataform .categoryBox {width: 150px;}
|
||||
#dataform .needNotReviewBox {width: 130px;}
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
$(function()
|
||||
{
|
||||
if($('#batchCreateForm table thead tr th.col-name').width() < 200) $('#batchCreateForm table thead tr th.col-name').width(200);
|
||||
$name = $('#batchCreateForm table thead tr th.col-name');
|
||||
if($name.width() < 200) $name.width(200);
|
||||
|
||||
$('#customField').click(function()
|
||||
{
|
||||
hiddenRequireFields();
|
||||
});
|
||||
|
||||
/* Implement a custom form without feeling refresh. */
|
||||
$('#formSettingForm .btn-primary').click(function()
|
||||
{
|
||||
saveCustomFields('batchCreateFields', 8, $name, 200);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.chosen-with-drop', function()
|
||||
{
|
||||
var select = $(this).prev('select');
|
||||
|
||||
@@ -46,6 +46,11 @@ $(function()
|
||||
|
||||
// Init bactch action form
|
||||
$('#batchEditForm').batchActionForm();
|
||||
|
||||
$('#customField').click(function()
|
||||
{
|
||||
hiddenRequireFields();
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.chosen-with-drop', function(){oldValue = $(this).prev('select').val();})//Save old value.
|
||||
|
||||
@@ -13,6 +13,14 @@ $(function()
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Get status.
|
||||
*
|
||||
* @param method $method
|
||||
* @param params $params
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function getStatus(method, params)
|
||||
{
|
||||
$.get(createLink('story', 'ajaxGetStatus', "method=" + method + '¶ms=' + params), function(status)
|
||||
|
||||
@@ -46,6 +46,18 @@ $(function()
|
||||
$('#assignedToBox').attr('colspan', 2);
|
||||
}
|
||||
});
|
||||
|
||||
$('#customField').click(function()
|
||||
{
|
||||
hiddenRequireFields();
|
||||
});
|
||||
|
||||
/* Implement a custom form without feeling refresh. */
|
||||
$('#formSettingForm .btn-primary').click(function()
|
||||
{
|
||||
saveCustomFields('createFields');
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -344,6 +344,8 @@ class storyModel extends model
|
||||
|
||||
if($bugID > 0)
|
||||
{
|
||||
if(($this->config->edition == 'biz' || $this->config->edition == 'max')) $oldBug = $this->dao->select('feedback, status')->from(TABLE_BUG)->where('id')->eq($bugID)->fetch();
|
||||
|
||||
$bug = new stdclass();
|
||||
$bug->toStory = $storyID;
|
||||
$bug->status = 'closed';
|
||||
@@ -359,6 +361,8 @@ class storyModel extends model
|
||||
$this->loadModel('action')->create('bug', $bugID, 'ToStory', '', $storyID);
|
||||
$this->action->create('bug', $bugID, 'Closed');
|
||||
|
||||
if(($this->config->edition == 'biz' || $this->config->edition == 'max') && !dao::isError() && $oldBug->feedback) $this->loadModel('feedback')->updateStatus('bug', $oldBug->feedback, 'closed', $oldBug->status);
|
||||
|
||||
/* add files to story from bug. */
|
||||
$files = $this->dao->select('*')->from(TABLE_FILE)
|
||||
->where('objectType')->eq('bug')
|
||||
@@ -4086,15 +4090,14 @@ class storyModel extends model
|
||||
|
||||
$group = array();
|
||||
foreach($relations as $relation) $group[$relation->AID][] = $relation->BID;
|
||||
|
||||
foreach($stories as $story)
|
||||
{
|
||||
if(!isset($group[$story->id]))
|
||||
{
|
||||
unset($stories[$story->id]);
|
||||
continue;
|
||||
}
|
||||
if(!isset($group[$story->id])) continue;
|
||||
$story->children = $this->getByList($group[$story->id]);
|
||||
array_map(function($storyID) use(&$stories)
|
||||
{
|
||||
unset($stories[$storyID]);
|
||||
}, $group[$story->id]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
*/
|
||||
?>
|
||||
<?php include './header.html.php';?>
|
||||
<?php js::set('showFields', $showFields);?>
|
||||
<?php js::set('requiredFields', $config->story->create->requiredFields);?>
|
||||
<div id="mainContent" class="main-content">
|
||||
<div class="main-header">
|
||||
<h2><?php echo $storyID ? $storyTitle . ' - ' . $this->lang->story->subdivide : $this->lang->story->batchCreate;?></h2>
|
||||
@@ -47,23 +49,23 @@
|
||||
<table class="table table-form">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='c-branch<?php echo zget($visibleFields, $product->type, ' hidden')?>'><?php echo $lang->product->branch;?></th>
|
||||
<th class='c-branch<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox'><?php echo $lang->product->branch;?></th>
|
||||
<th class='c-module<?php echo zget($requiredFields, 'module', '', ' required');?>'><?php echo $lang->story->module;?></th>
|
||||
<th class='c-plan<?php echo zget($visibleFields, 'plan', ' hidden') . zget($requiredFields, 'plan', '', ' required');?>'><?php echo $lang->story->plan;?></th>
|
||||
<th class='c-plan<?php echo zget($visibleFields, 'plan', ' hidden') . zget($requiredFields, 'plan', '', ' required');?> planBox'><?php echo $lang->story->plan;?></th>
|
||||
<?php if(isset($execution) and $execution->type == 'kanban'):?>
|
||||
<th class='c-branch'><?php echo $lang->kanbancard->region;?></th>
|
||||
<th class='c-branch'><?php echo $lang->kanbancard->lane;?></th>
|
||||
<?php endif;?>
|
||||
<th class='c-name required has-btn'><?php echo $lang->story->title;?></th>
|
||||
<th class='c-spec<?php echo zget($visibleFields, 'spec', ' hidden') . zget($requiredFields, 'spec', '', ' required');?>'><?php echo $lang->story->spec;?></th>
|
||||
<th class='c-source<?php echo zget($visibleFields, 'source', ' hidden') . zget($requiredFields, 'source', '', ' required');?>'><?php echo $lang->story->source;?></th>
|
||||
<th class='c-note<?php echo zget($visibleFields, 'source', ' hidden') . zget($requiredFields, 'sourceNote', '', ' required');?>'><?php echo $lang->story->sourceNote;?></th>
|
||||
<th class='c-verify<?php echo zget($visibleFields, 'verify', ' hidden') . zget($requiredFields, 'verify', '', ' required');?>'><?php echo $lang->story->verify;?></th>
|
||||
<th class='c-spec<?php echo zget($visibleFields, 'spec', ' hidden') . zget($requiredFields, 'spec', '', ' required');?> specBox'><?php echo $lang->story->spec;?></th>
|
||||
<th class='c-source<?php echo zget($visibleFields, 'source', ' hidden') . zget($requiredFields, 'source', '', ' required');?> sourceBox'><?php echo $lang->story->source;?></th>
|
||||
<th class='c-note<?php echo zget($visibleFields, 'source', ' hidden') . zget($requiredFields, 'sourceNote', '', ' required');?> sourceBox'><?php echo $lang->story->sourceNote;?></th>
|
||||
<th class='c-verify<?php echo zget($visibleFields, 'verify', ' hidden') . zget($requiredFields, 'verify', '', ' required');?> verifyBox'><?php echo $lang->story->verify;?></th>
|
||||
<th class='c-category'><?php echo $lang->story->category;?></th>
|
||||
<th class='c-pri<?php echo zget($visibleFields, 'pri', ' hidden') . zget($requiredFields, 'pri', '', ' required');?>'><?php echo $lang->story->pri;?></th>
|
||||
<th class='c-estimate<?php echo zget($visibleFields, 'estimate', ' hidden') . zget($requiredFields, 'estimate', '', ' required');?>'><?php echo $lang->story->estimate;?></th>
|
||||
<th class='<?php echo zget($visibleFields, 'review', ' hidden');?><?php if($forceReview) echo ' required'?>' style="width: 200px !important"><?php echo $lang->story->reviewedBy;?></th>
|
||||
<th class='c-keywords<?php echo zget($visibleFields, 'keywords', ' hidden') . zget($requiredFields, 'keywords', '', ' required');?>'><?php echo $lang->story->keywords;?></th>
|
||||
<th class='c-pri<?php echo zget($visibleFields, 'pri', ' hidden') . zget($requiredFields, 'pri', '', ' required');?> priBox'><?php echo $lang->story->pri;?></th>
|
||||
<th class='c-estimate<?php echo zget($visibleFields, 'estimate', ' hidden') . zget($requiredFields, 'estimate', '', ' required');?> estimateBox'><?php echo $lang->story->estimate;?></th>
|
||||
<th class='<?php echo zget($visibleFields, 'review', ' hidden');?><?php if($forceReview) echo ' required'?> reviewBox'><?php echo $lang->story->reviewedBy;?></th>
|
||||
<th class='c-keywords<?php echo zget($visibleFields, 'keywords', ' hidden') . zget($requiredFields, 'keywords', '', ' required');?> keywordsBox'><?php echo $lang->story->keywords;?></th>
|
||||
<?php
|
||||
$extendFields = $this->story->getFlowExtendFields();
|
||||
foreach($extendFields as $extendField)
|
||||
@@ -72,13 +74,14 @@
|
||||
echo "<th class='c-extend $required'>{$extendField->name}</th>";
|
||||
}
|
||||
?>
|
||||
<th class='c-actions'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="template">
|
||||
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?>'><?php echo html::select('branch[$id]', $branches, $branch, "class='form-control chosen' onchange='setModuleAndPlan(this.value, $productID, \$id)'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox'><?php echo html::select('branch[$id]', $branches, $branch, "class='form-control chosen' onchange='setModuleAndPlan(this.value, $productID, \$id)'");?></td>
|
||||
<td class='text-left' style='overflow:visible'><?php echo html::select('module[$id]', $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?>' style='overflow:visible'><?php echo html::select('plan[$id]', $plans, $planID, "class='form-control chosen'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?> planBox' style='overflow:visible'><?php echo html::select('plan[$id]', $plans, $planID, "class='form-control chosen'");?></td>
|
||||
<?php if(isset($execution) and $execution->type == 'kanban'):?>
|
||||
<td class='text-left'><?php echo html::select('regions[$id]', $regionPairs, $regionID, "class='form-control chosen' onchange='setLane(this.value, \$id)'");?>
|
||||
<td class='text-left'><?php echo html::select('lanes[$id]', $lanePairs, $laneID, "class='form-control chosen'");?>
|
||||
@@ -100,24 +103,28 @@
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class='<?php echo zget($visibleFields, 'spec', 'hidden')?>'><textarea name="spec[$id]" id="spec$id" rows="1" class="form-control autosize"></textarea></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'source', ' hidden')?>'><?php echo html::select('source[$id]', $sourceList, '', "class='form-control chosen' id='source_\$id'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'source', 'hidden')?>'><?php echo html::input('sourceNote[$id]', '', "class='form-control' id='sourceNote_\$id'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'verify', 'hidden')?>'><textarea name="verify[$id]" id="verify$id" rows="1" class="form-control autosize"></textarea></td>
|
||||
<td class='<?php echo zget($visibleFields, 'spec', 'hidden')?> specBox'><textarea name="spec[$id]" id="spec$id" rows="1" class="form-control autosize"></textarea></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'source', ' hidden')?> sourceBox'><?php echo html::select('source[$id]', $sourceList, '', "class='form-control chosen' id='source_\$id'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'source', 'hidden')?> sourceBox'><?php echo html::input('sourceNote[$id]', '', "class='form-control' id='sourceNote_\$id'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'verify', 'hidden')?> verifyBox'><textarea name="verify[$id]" id="verify$id" rows="1" class="form-control autosize"></textarea></td>
|
||||
<td class='text-left' style='overflow:visible'><?php echo html::select('category[$id]', $lang->story->categoryList, 'feature', "class='form-control chosen'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'pri', ' hidden')?>' style='overflow:visible'><?php echo html::select('pri[$id]', $priList, $pri, "class='form-control chosen'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'estimate', 'hidden')?>'><?php echo html::input('estimate[$id]', $estimate, "class='form-control'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'review', 'hidden')?>'>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'pri', ' hidden')?> priBox' style='overflow:visible'><?php echo html::select('pri[$id]', $priList, $pri, "class='form-control chosen'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'estimate', 'hidden')?> estimateBox'><?php echo html::input('estimate[$id]', $estimate, "class='form-control'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'review', 'hidden')?> reviewBox'>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('reviewer[$id][]', $reviewers, '', "class='form-control picker-select' multiple");?>
|
||||
<span class='input-group-addon reviewerDitto'><input type='checkbox' name='reviewDitto[$id]' value='ditto' checked='checked' id='dittocheck$id'/> <?php echo $lang->story->ditto;?></span>
|
||||
</div>
|
||||
</td>
|
||||
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input('keywords[$id]', '', "class='form-control'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?> keywordsBox'><?php echo html::input('keywords[$id]', '', "class='form-control'");?></td>
|
||||
<?php
|
||||
$this->loadModel('flow');
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . '[$id]') . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
@@ -132,6 +139,59 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<?php $i = '%i%';?>
|
||||
<table class='hidden'>
|
||||
<tr id='addRow' class='hidden'>
|
||||
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox'><?php echo html::select("branch[$i]", $branches, $branch, "class='form-control chosen' onchange='setModuleAndPlan(this.value, $productID, $i)'");?></td>
|
||||
<td class='text-left' style='overflow:visible'><?php echo html::select("module[$i]", $moduleOptionMenu, 'ditto', "class='form-control chosen'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?> planBox' style='overflow:visible'><?php echo html::select("plan[$i]", $plans, 'ditto', "class='form-control chosen'");?></td>
|
||||
<?php if(isset($execution) and $execution->type == 'kanban'):?>
|
||||
<td class='text-left'><?php echo html::select("regions[$i]", $regionPairs, $regionID, "class='form-control chosen' onchange='setLane(this.value, $i)'");?>
|
||||
<td class='text-left'><?php echo html::select("lanes[$i]", $lanePairs, $laneID, "class='form-control chosen'");?>
|
||||
<?php endif;?>
|
||||
<td style='overflow:visible'>
|
||||
<div class="input-group">
|
||||
<div class="input-control has-icon-right">
|
||||
<input type="text" name="title[<?php echo $i?>]" id="title<?php echo $i?>" value="" class="form-control title-import input-story-title" autocomplete="off">
|
||||
<div class="colorpicker">
|
||||
<button type="button" class="btn btn-link dropdown-toggle" data-toggle="dropdown"><span class="cp-title"></span><span class="color-bar"></span><i class="ic"></i></button>
|
||||
<ul class="dropdown-menu clearfix">
|
||||
<li class="heading"><?php echo $lang->story->colorTag;?><i class="icon icon-close"></i></li>
|
||||
</ul>
|
||||
<input type="hidden" class="colorpicker" id="color<?php echo $i?>" name="color[<?php echo $i?>]" value="" data-icon="color" data-wrapper="input-control-icon-right" data-update-color="#title<?php echo $i?>">
|
||||
</div>
|
||||
</div>
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-link btn-icon btn-copy" data-copy-from="#title<?php echo $i?>" data-copy-to="#spec<?php echo $i?>" title="<?php echo $lang->story->copyTitle;?>"><i class="icon icon-arrow-right"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class='<?php echo zget($visibleFields, 'spec', 'hidden')?> specBox'><textarea name="spec[<?php echo $i?>]" id="spec<?php echo $i;?>" rows="1" class="form-control autosize"></textarea></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'source', ' hidden')?> sourceBox'><?php echo html::select("source[$i]", $sourceList, 'ditto', "class='form-control chosen' id='source_$i'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'source', 'hidden')?> sourceBox'><?php echo html::input("sourceNote[$i]", '', "class='form-control' id='sourceNote_$i'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'verify', 'hidden')?> verifyBox'><textarea name="verify[<?php echo $i?>]" id="verify<?php echo $i?>" rows="1" class="form-control autosize"></textarea></td>
|
||||
<td class='text-left' style='overflow:visible'><?php echo html::select("category[$i]", $lang->story->categoryList, 'feature', "class='form-control chosen'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'pri', ' hidden')?> priBox' style='overflow:visible'><?php echo html::select("pri[$i]", $priList, 'ditto', "class='form-control chosen'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'estimate', 'hidden')?> estimateBox'><?php echo html::input("estimate[$i]", $estimate, "class='form-control'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'review', 'hidden')?> reviewBox'>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select("reviewer[$i][]", $reviewers, '', "class='form-control picker-select' multiple");?>
|
||||
<span class='input-group-addon reviewerDitto'><input type='checkbox' name="reviewDitto[<?php echo $i?>]" value='ditto' checked='checked' id="dittocheck<?php echo $i?>"/> <?php echo $lang->story->ditto;?></span>
|
||||
</div>
|
||||
</td>
|
||||
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?> keywordsBox'><?php echo html::input("keywords[$i]", '', "class='form-control'");?></td>
|
||||
<?php
|
||||
$this->loadModel('flow');
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
@@ -144,6 +204,7 @@ $(function()
|
||||
idEnd: <?php echo max((empty($titles) ? 1 : count($titles)), 10)?>,
|
||||
rowCreator: function($row, index)
|
||||
{
|
||||
rowIndex = index; // Set the index for the add element operation
|
||||
$row.find('select.chosen,select.picker-select').each(function()
|
||||
{
|
||||
var $select = $(this);
|
||||
@@ -156,12 +217,35 @@ $(function()
|
||||
{
|
||||
$select.next('.chosen-container').find('.chosen-drop').width($select.closest('td').width() + 50);
|
||||
}, 200);
|
||||
});
|
||||
var storyTitle = storyTitles && storyTitles[index - 1];
|
||||
if (storyTitle !== undefined && storyTitle !== null)
|
||||
{
|
||||
$row.find('.input-story-title').val(storyTitle).after('<input type="hidden" name="uploadImage[' + index + ']" id="uploadImage[' + index + ']" value="' + imageTitles[storyTitle] + '">');
|
||||
}
|
||||
});
|
||||
|
||||
var storyTitle = storyTitles && storyTitles[index - 1];
|
||||
if (storyTitle !== undefined && storyTitle !== null)
|
||||
{
|
||||
$row.find('.input-story-title').val(storyTitle).after('<input type="hidden" name="uploadImage[' + index + ']" id="uploadImage[' + index + ']" value="' + imageTitles[storyTitle] + '">');
|
||||
}
|
||||
|
||||
if(index == 1) $row.find('td.c-actions > a:last').remove();
|
||||
|
||||
/* Implement a custom form without feeling refresh. */
|
||||
var fieldList = ',' + showFields + ',';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var $field = $row.find('[name^=' + $(this).val() + ']');
|
||||
var required = ',' + requiredFields + ',';
|
||||
var $fieldBox = $row.find('.' + $(this).val() + 'Box' );
|
||||
if(fieldList.indexOf(field) >= 0 || required.indexOf(field) >= 0)
|
||||
{
|
||||
$fieldBox.removeClass('hidden');
|
||||
$field.removeAttr('disabled');
|
||||
}
|
||||
else if(!$fieldBox.hasClass('hidden'))
|
||||
{
|
||||
$fieldBox.addClass('hidden');
|
||||
$field.attr('disabled', true);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<?php js::set('storyType', $storyType);?>
|
||||
<?php js::set('app', $this->app->tab);?>
|
||||
<?php if(isset($resetActive)) js::set('resetActive', true);?>
|
||||
<?php js::set('showFields', $showFields);?>
|
||||
<div class='main-content' id='mainContent'>
|
||||
<div class='main-header'>
|
||||
<h2>
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
<?php js::set('blockID', $blockID); ?>
|
||||
<?php js::set('feedbackSource', $config->story->feedbackSource); ?>
|
||||
<?php js::set('storyType', $type);?>
|
||||
<?php js::set('requiredFields', $config->story->create->requiredFields);?>
|
||||
<?php
|
||||
foreach(explode(',', $config->story->create->requiredFields) as $field)
|
||||
{
|
||||
if($field and strpos($showFields, $field) === false) $showFields .= ',' . $field;
|
||||
}
|
||||
?>
|
||||
<?php js::set('showFields', $showFields);?>
|
||||
<?php if(common::checkNotCN()):?>
|
||||
<style> .sourceTd > .input-group > .input-group > .input-group-addon:first-child{padding: 5px 18px} </style>
|
||||
<?php endif;?>
|
||||
@@ -32,12 +40,6 @@
|
||||
<?php include '../../common/view/customfield.html.php';?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
foreach(explode(',', $config->story->create->requiredFields) as $field)
|
||||
{
|
||||
if($field and strpos($showFields, $field) === false) $showFields .= ',' . $field;
|
||||
}
|
||||
?>
|
||||
<form class="load-indicator main-form form-ajax" method='post' enctype='multipart/form-data' id='dataform'>
|
||||
<table class="table table-form">
|
||||
<tbody>
|
||||
@@ -67,6 +69,7 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $hiddenSource = strpos(",$showFields,", ',source,') !== false ? '' : 'hidden';?>
|
||||
<?php if($type == 'story'):?>
|
||||
<tr>
|
||||
<th class='planTh'><?php echo $lang->story->planAB;?></th>
|
||||
@@ -86,8 +89,7 @@
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
<?php if(strpos(",$showFields,", ',source,') !== false):?>
|
||||
<td colspan="2" class='sourceTd'>
|
||||
<td colspan="2" class="sourceTd <?php echo $hiddenSource?> sourceBox">
|
||||
<div class="input-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon" style="min-width: 77px;"><?php echo $lang->story->source;?></div>
|
||||
@@ -98,7 +100,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
@@ -109,7 +110,7 @@
|
||||
<div class="table-col">
|
||||
<?php echo html::select('reviewer[]', $reviewers, empty($needReview) ? $product->PO : '', "class='form-control picker-select' multiple");?>
|
||||
</div>
|
||||
<div class="table-col w-130px">
|
||||
<div class="table-col needNotReviewBox">
|
||||
<span class="input-group-addon" style="border: 1px solid #dcdcdc; border-left-width: 0px;">
|
||||
<div class='checkbox-primary'>
|
||||
<input id='needNotReview' name='needNotReview' value='1' type='checkbox' class='no-margin' <?php echo $needReview;?>/>
|
||||
@@ -131,8 +132,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<?php if($type == 'requirement'):?>
|
||||
<?php if(strpos(",$showFields,", ',source,') !== false):?>
|
||||
<td colspan="2" class='sourceTd'>
|
||||
<td colspan="2" class="sourceTd <?php echo $hiddenSource?> sourceBox">
|
||||
<div class="input-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon" style="min-width: 77px;"><?php echo $lang->story->source;?></div>
|
||||
@@ -142,7 +142,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<?php else:?>
|
||||
<td colspan="2" id='feedbackBox' class='hidden'>
|
||||
<div class="input-group">
|
||||
@@ -203,14 +202,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if(strpos(",$showFields,", ',pri,') !== false): // begin print pri selector?>
|
||||
<div class='table-col w-150px'>
|
||||
<?php $hiddenPri = strpos(",$showFields,", ',pri,') !== false ? '' : 'hidden';?>
|
||||
<div class="table-col categoryBox">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon fix-border br-0"><?php echo $lang->story->category;?></span>
|
||||
<?php echo html::select('category', $lang->story->categoryList, 'feature', "class='form-control chosen'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div class='table-col w-120px'>
|
||||
<div class="table-col <?php echo $hiddenPri?> priBox">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon fix-border br-0"><?php echo $lang->story->pri;?></span>
|
||||
<?php
|
||||
@@ -246,15 +245,13 @@
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if(strpos(",$showFields,", ',estimate,') !== false):?>
|
||||
<div class='table-col w-120px'>
|
||||
<?php $hiddenEstimate = strpos(",$showFields,", ',estimate,') !== false ? '' : 'hidden';?>
|
||||
<div class="table-col <?php echo $hiddenEstimate?> estimateBox">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon fix-border br-0"><?php echo $lang->story->estimateAB;?></span>
|
||||
<input type="text" name="estimate" id="estimate" value="<?php echo $estimate;?>" class="form-control" autocomplete="off" placeholder='<?php echo $lang->story->hour;?>' />
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -265,12 +262,11 @@
|
||||
<?php echo html::textarea('spec', $spec, "rows='9' class='form-control kindeditor disabled-ie-placeholder' hidefocus='true' placeholder='" . htmlSpecialString($lang->story->specTemplate . "\n" . $lang->noticePasteImg) . "'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if(strpos(",$showFields,", ',verify,') !== false):?>
|
||||
<tr>
|
||||
<?php $hiddenVerify = strpos(",$showFields,", ',verify,') !== false ? '' : 'hidden';?>
|
||||
<tr class="<?php echo $hiddenVerify;?> verifyBox">
|
||||
<th><?php echo $lang->story->verify;?></th>
|
||||
<td colspan="4"><?php echo html::textarea('verify', $verify, "rows='6' class='form-control kindeditor' hidefocus='true'");?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr class='hide'>
|
||||
<th><?php echo $lang->story->status;?></th>
|
||||
<td><?php echo html::hidden('status', 'draft');?></td>
|
||||
@@ -280,8 +276,8 @@
|
||||
<th><?php echo $lang->story->legendAttatch;?></th>
|
||||
<td colspan='4'><?php echo $this->fetch('file', 'buildform');?></td>
|
||||
</tr>
|
||||
<?php if(strpos(",$showFields,", ',mailto,') !== false):?>
|
||||
<tr>
|
||||
<?php $hiddenMailto = strpos(",$showFields,", ',mailto,') !== false ? '' : 'hidden';?>
|
||||
<tr class="<?php echo $hiddenMailto?> mailtoBox">
|
||||
<th><?php echo $lang->story->mailto;?></th>
|
||||
<td colspan="4">
|
||||
<div class="input-group">
|
||||
@@ -290,15 +286,13 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php if(strpos(",$showFields,", ',keywords,') !== false):?>
|
||||
<tr>
|
||||
<?php $hiddenKeyWords = strpos(",$showFields,", ',keywords,') !== false ? '' : 'hidden';?>
|
||||
<tr class="<?php echo $hiddenKeyWords?> keywordsBox">
|
||||
<th><?php echo $lang->story->keywords;?></th>
|
||||
<td colspan="4">
|
||||
<?php echo html::input('keywords', $keywords, 'class="form-control"');?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
|
||||
@@ -168,6 +168,8 @@ class task extends control
|
||||
{
|
||||
$this->dao->update(TABLE_TODO)->set('status')->eq('done')->where('id')->eq($todoID)->exec();
|
||||
$this->action->create('todo', $todoID, 'finished', '', "TASK:$taskID");
|
||||
|
||||
if(($this->config->edition == 'biz' || $this->config->edition == 'max') && $todo->type == 'feedback' && $todo->idvalue) $this->loadModel('feedback')->updateStatus('todo', $todo->idvalue, 'done');
|
||||
}
|
||||
|
||||
$message = $this->executeHooks($taskID);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
$(function()
|
||||
{
|
||||
removeDitto();
|
||||
if($('th.c-name').width() < 165) $('th.c-name').width(165);
|
||||
$name = $('th.c-name');
|
||||
if($name.width() < 165) $name.width(165);
|
||||
if(taskConsumed > 0) bootbox.alert(addChildTask);
|
||||
$('#customField').on('click', function(){$('#tableBody .chosen-with-drop').removeClass('chosen-with-drop chosen-container-active')});
|
||||
|
||||
@@ -14,36 +15,7 @@ $(function()
|
||||
/* Implement a custom form without feeling refresh. */
|
||||
$('#formSettingForm .btn-primary').click(function()
|
||||
{
|
||||
var fields = '';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input:checked').each(function()
|
||||
{
|
||||
fields += ',' + $(this).val();
|
||||
});
|
||||
|
||||
var link = createLink('custom', 'ajaxSaveCustomFields', 'module=task§ion=custom&key=batchCreateFields');
|
||||
$.post(link, {'fields' : fields}, function()
|
||||
{
|
||||
showFields = fields;
|
||||
showCheckedFields(fields);
|
||||
$('#formSetting').parent().removeClass('open');
|
||||
|
||||
var fieldCount = $('#batchCreateForm .table thead>tr>th:visible').length;
|
||||
$('.form-actions').attr('colspan', fieldCount);
|
||||
|
||||
if(fieldCount > 9)
|
||||
{
|
||||
$('#batchCreateForm > .table-responsive').removeClass('scroll-none');
|
||||
$('#batchCreateForm > .table-responsive').css('overflow', 'auto');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#batchCreateForm > .table-responsive').addClass('scroll-none');
|
||||
$('#batchCreateForm > .table-responsive').css('overflow', 'visible');
|
||||
}
|
||||
|
||||
if($('th.c-name').width() < 165) $('th.c-name').width(165);
|
||||
});
|
||||
|
||||
saveCustomFields('batchCreateFields', 9, $name, 165);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
@@ -356,35 +328,3 @@ $(function()
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Add item.
|
||||
*
|
||||
* @param object $obj
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function addItem(obj)
|
||||
{
|
||||
var item = $('#addItem').html().replace(/%i%/g, itemIndex + 1);
|
||||
$('<tr class="addedItem">' + item + '</tr>').insertAfter($(obj).closest('tr'));
|
||||
|
||||
$(obj).closest('tr').next().find(".form-date").datepicker();
|
||||
$(obj).closest('tr').next().find('div[id$=_chosen]').remove();
|
||||
$(obj).closest('tr').next().find('.chosen').next('.picker').remove();
|
||||
$(obj).closest('tr').next().find('.chosen').chosen();
|
||||
|
||||
itemIndex ++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete item.
|
||||
*
|
||||
* @param object $obj
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function deleteItem(obj)
|
||||
{
|
||||
$(obj).closest('tr').remove();
|
||||
}
|
||||
|
||||
@@ -19,65 +19,3 @@ function setStoryModule()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show checked fields.
|
||||
*
|
||||
* @param string fields
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function showCheckedFields(fields)
|
||||
{
|
||||
var fieldList = ',' + fields + ',';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var $field = config.currentMethod == 'create' ? $('#' + $(this).val()) : $('[name^=' + $(this).val() + ']');
|
||||
var $fieldBox = $('.' + $(this).val() + 'Box' );
|
||||
if(fieldList.indexOf(field) >= 0)
|
||||
{
|
||||
$fieldBox.removeClass('hidden');
|
||||
$field.removeAttr('disabled');
|
||||
}
|
||||
else if(!$fieldBox.hasClass('hidden'))
|
||||
{
|
||||
$fieldBox.addClass('hidden');
|
||||
$field.attr('disabled', true);
|
||||
}
|
||||
});
|
||||
|
||||
if(config.currentMethod == 'create');
|
||||
{
|
||||
if(fieldList.indexOf(',estStarted,') >= 0 && fieldList.indexOf(',deadline,') >= 0)
|
||||
{
|
||||
$('.borderBox').removeClass('hidden');
|
||||
}
|
||||
else if(fieldList.indexOf(',estStarted,') >= 0 || fieldList.indexOf(',deadline,') >= 0)
|
||||
{
|
||||
$('.datePlanBox').removeClass('hidden');
|
||||
if(!$('.borderBox').hasClass('hidden')) $('.borderBox').addClass('hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!$('.borderBox').hasClass('hidden')) $('.borderBox').addClass('hidden');
|
||||
if(!$('.datePlanBox').hasClass('hidden')) $('.datePlanBox').addClass('hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden require field.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function hiddenRequireFields()
|
||||
{
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var required = ',' + requiredFields + ',';
|
||||
if(required.indexOf(field) >= 0) $(this).closest('div').addClass('hidden');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,19 +8,7 @@ $(function()
|
||||
/* Implement a custom form without feeling refresh. */
|
||||
$('#formSettingForm .btn-primary').click(function()
|
||||
{
|
||||
var fields = '';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input:checked').each(function()
|
||||
{
|
||||
fields += ',' + $(this).val();
|
||||
});
|
||||
|
||||
var link = createLink('custom', 'ajaxSaveCustomFields', 'module=task§ion=custom&key=createFields');
|
||||
$.post(link, {'fields' : fields}, function()
|
||||
{
|
||||
showCheckedFields(fields);
|
||||
$('#formSetting').parent().removeClass('open');
|
||||
});
|
||||
|
||||
saveCustomFields('createFields');
|
||||
return false;
|
||||
});
|
||||
})
|
||||
|
||||
@@ -640,8 +640,8 @@ class taskModel extends model
|
||||
if($oldParentTask->parent != '-1') $this->dao->update(TABLE_TASK)->set('parent')->eq('-1')->where('id')->eq($parentID)->exec();
|
||||
$this->computeWorkingHours($parentID);
|
||||
|
||||
$childrenStatus = $this->dao->select('id,status')->from(TABLE_TASK)->where('parent')->eq($parentID)->andWhere('deleted')->eq(0)->fetchPairs('status', 'status');
|
||||
$childrenClosedReason = $this->dao->select('closedReason')->from(TABLE_TASK)->where('parent')->eq($parentID)->andWhere('deleted')->eq(0)->fetchPairs('closedReason');
|
||||
$childrenStatus = $this->dao->select('id,status')->from(TABLE_TASK)->where('parent')->eq($parentID)->andWhere('deleted')->eq('0')->fetchPairs('status', 'status');
|
||||
$childrenClosedReason = $this->dao->select('closedReason')->from(TABLE_TASK)->where('parent')->eq($parentID)->andWhere('deleted')->eq('0')->fetchPairs('closedReason');
|
||||
if(empty($childrenStatus)) return $this->dao->update(TABLE_TASK)->set('parent')->eq('0')->where('id')->eq($parentID)->exec();
|
||||
|
||||
$status = '';
|
||||
@@ -755,7 +755,7 @@ class taskModel extends model
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
if(($this->config->edition == 'biz' || $this->config->edition == 'max') && $parentTask->feedback) $this->loadModel('feedback')->udpateStatus('task', $parentTask->feedback, $status, $parentTask->status);
|
||||
if(($this->config->edition == 'biz' || $this->config->edition == 'max') && $oldParentTask->feedback) $this->loadModel('feedback')->updateStatus('task', $oldParentTask->feedback, $newParentTask->status, $oldParentTask->status);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -175,9 +175,9 @@ $colspan = count($visibleFields) + 3;
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<?php if($i != 1):?>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -195,7 +195,7 @@ $colspan = count($visibleFields) + 3;
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php js::set('itemIndex', -- $i);?>
|
||||
<?php js::set('rowIndex', -- $i);?>
|
||||
<table class='template' id='trTemp'>
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -251,8 +251,8 @@ $colspan = count($visibleFields) + 3;
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[%s]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -260,7 +260,7 @@ $colspan = count($visibleFields) + 3;
|
||||
<div>
|
||||
<?php $i = '%i%';?>
|
||||
<table class='hidden'>
|
||||
<tr id='addItem' class='hidden'>
|
||||
<tr id='addRow' class='hidden'>
|
||||
<td class='text-left c-id'><?php echo $i;?></td>
|
||||
<td class="<?php echo zget($visibleFields, 'module', 'hidden')?> moduleBox" style='overflow:visible'>
|
||||
<?php echo html::select("module[$i]", $modules, $moduleID, "class='form-control chosen'")?>
|
||||
@@ -320,8 +320,8 @@ $colspan = count($visibleFields) + 3;
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
removeDitto();//Remove 'ditto' in first row.
|
||||
if($('#batchCreateForm table thead tr th.c-title').width() < 170) $('#batchCreateForm table thead tr th.c-title').width('170');
|
||||
var $title = $('#batchCreateForm table thead tr th.c-title');
|
||||
if($title.width() < 170) $title.width('170');
|
||||
|
||||
$(document).keydown(function(event)
|
||||
{
|
||||
@@ -35,67 +36,7 @@ $(document).ready(function()
|
||||
/* Implement a custom form without feeling refresh. */
|
||||
$('#formSettingForm .btn-primary').click(function()
|
||||
{
|
||||
var fields = '';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input:checked').each(function()
|
||||
{
|
||||
fields += ',' + $(this).val();
|
||||
});
|
||||
|
||||
var link = createLink('custom', 'ajaxSaveCustomFields', 'module=testcase§ion=custom&key=batchCreateFields');
|
||||
$.post(link, {'fields' : fields}, function()
|
||||
{
|
||||
showCheckedFields(fields);
|
||||
$('#formSetting').parent().removeClass('open');
|
||||
|
||||
var fieldCount = $('#batchCreateForm .table thead>tr>th:visible').length;
|
||||
$('.form-actions').attr('colspan', fieldCount);
|
||||
|
||||
if(fieldCount > 8)
|
||||
{
|
||||
$('#batchCreateForm > .table-responsive').removeClass('scroll-none');
|
||||
$('#batchCreateForm > .table-responsive').css('overflow', 'auto');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#batchCreateForm > .table-responsive').addClass('scroll-none');
|
||||
$('#batchCreateForm > .table-responsive').css('overflow', 'visible');
|
||||
}
|
||||
|
||||
if($('#batchCreateForm table thead tr th.c-title').width() < 170) $('#batchCreateForm table thead tr th.c-title').width('170');
|
||||
});
|
||||
|
||||
saveCustomFields('batchCreateFields', 8, $title, 170);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Add item.
|
||||
*
|
||||
* @param object $obj
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function addItem(obj)
|
||||
{
|
||||
var item = $('#addItem').html().replace(/%i%/g, itemIndex + 1);
|
||||
$('<tr class="addedItem">' + item + '</tr>').insertAfter($(obj).closest('tr'));
|
||||
|
||||
$(obj).closest('tr').next().find('div[id$=_chosen]').remove();
|
||||
$(obj).closest('tr').next().find('.picker').remove();
|
||||
$(obj).closest('tr').next().find('.chosen').chosen();
|
||||
$(obj).closest('tr').next().find('.picker-select').picker();
|
||||
|
||||
itemIndex ++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete item.
|
||||
*
|
||||
* @param object $obj
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function deleteItem(obj)
|
||||
{
|
||||
$(obj).closest('tr').remove();
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ function loadStories(productID, moduleID, num)
|
||||
if(!stories) stories = '<select id="story' + num + '" name="story[' + num + ']" class="form-control"></select>';
|
||||
if(config.currentMethod == 'batchcreate')
|
||||
{
|
||||
for(var i = num; i <= itemIndex ; i ++)
|
||||
for(var i = num; i <= rowIndex ; i ++)
|
||||
{
|
||||
if(i != num && $('#module' + i).val() != 'ditto') break;
|
||||
var nowStories = stories.replaceAll('story' + num, 'story' + i);
|
||||
@@ -426,50 +426,3 @@ function setModules(branchID, productID, num)
|
||||
$('#plan' + (num + 1)).trigger("chosen:updated");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show checked fields.
|
||||
*
|
||||
* @param string fields
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function showCheckedFields(fields)
|
||||
{
|
||||
showFields = fields;
|
||||
|
||||
var fieldList = ',' + fields + ',';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var $field = config.currentMethod == 'create' ? $('#' + $(this).val()) : $('[name^=' + $(this).val() + ']');
|
||||
var required = ',' + requiredFields + ',';
|
||||
var $fieldBox = $('.' + $(this).val() + 'Box' );
|
||||
if(fieldList.indexOf(field) >= 0 || required.indexOf(field) >= 0)
|
||||
{
|
||||
$fieldBox.removeClass('hidden');
|
||||
$field.removeAttr('disabled');
|
||||
}
|
||||
else if(!$fieldBox.hasClass('hidden'))
|
||||
{
|
||||
$fieldBox.addClass('hidden');
|
||||
$field.attr('disabled', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden require field.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function hiddenRequireFields()
|
||||
{
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var required = ',' + requiredFields + ',';
|
||||
if(required.indexOf(field) >= 0) $(this).closest('div').addClass('hidden');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -165,19 +165,7 @@ $(function()
|
||||
/* Implement a custom form without feeling refresh. */
|
||||
$('#formSettingForm .btn-primary').click(function()
|
||||
{
|
||||
var fields = '';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input:checked').each(function()
|
||||
{
|
||||
fields += ',' + $(this).val();
|
||||
});
|
||||
|
||||
var link = createLink('custom', 'ajaxSaveCustomFields', 'module=testcase§ion=custom&key=createFields');
|
||||
$.post(link, {'fields' : fields}, function()
|
||||
{
|
||||
showCheckedFields(fields);
|
||||
$('#formSetting').parent().removeClass('open');
|
||||
});
|
||||
|
||||
saveCustomFields('createFields');
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -322,20 +322,25 @@ class testcaseModel extends model
|
||||
* Get execution cases.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param int $productID
|
||||
* @param int $moduleID
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param string $browseType all|wait|needconfirm
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getExecutionCases($executionID, $orderBy = 'id_desc', $pager = null, $browseType = '')
|
||||
public function getExecutionCases($executionID, $productID = 0, $moduleID = 0, $orderBy = 'id_desc', $pager = null, $browseType = '')
|
||||
{
|
||||
if($browseType == 'needconfirm')
|
||||
{
|
||||
return $this->dao->select('distinct t1.*, t2.*')->from(TABLE_PROJECTCASE)->alias('t1')
|
||||
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case=t2.id')
|
||||
->leftJoin(TABLE_STORY)->alias('t3')->on('t2.story = t3.id')
|
||||
->leftJoin(TABLE_MODULE)->alias('t4')->on('t2.module=t4.id')
|
||||
->where('t1.project')->eq((int)$executionID)
|
||||
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi()
|
||||
->beginIF(!empty($moduleID))->andWhere('t4.path')->like("%,$moduleID,%")->fi()
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->andWhere('t3.version > t2.storyVersion')
|
||||
->andWhere("t3.status")->eq('active')
|
||||
@@ -346,8 +351,11 @@ class testcaseModel extends model
|
||||
|
||||
return $this->dao->select('distinct t1.*, t2.*')->from(TABLE_PROJECTCASE)->alias('t1')
|
||||
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case=t2.id')
|
||||
->leftJoin(TABLE_MODULE)->alias('t3')->on('t2.module=t3.id')
|
||||
->where('t1.project')->eq((int)$executionID)
|
||||
->beginIF($browseType != 'all')->andWhere('t2.status')->eq($browseType)->fi()
|
||||
->beginIF($browseType != 'all' and $browseType != 'byModule')->andWhere('t2.status')->eq($browseType)->fi()
|
||||
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi()
|
||||
->beginIF(!empty($moduleID))->andWhere('t3.path')->like("%,$moduleID,%")->fi()
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
|
||||
@@ -114,9 +114,9 @@
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<?php if($i != 1):?>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -134,7 +134,7 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php js::set('itemIndex', -- $i);?>
|
||||
<?php js::set('rowIndex', -- $i);?>
|
||||
<table class='template' id='trTemp'>
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -165,9 +165,9 @@
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[%s]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<?php if($i != 1):?>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -176,7 +176,7 @@
|
||||
<div>
|
||||
<?php $i = '%i%';?>
|
||||
<table class='hidden'>
|
||||
<tr id='addItem' class='hidden'>
|
||||
<tr id='addRow' class='hidden'>
|
||||
<td class="text-center"><?php echo $i;?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox'><?php echo html::select("branch[$i]", $branches, $branch, "class='form-control' onchange='setModules(this.value, $productID, $i)'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?> moduleBox' style='overflow:visible'><?php echo html::select("module[$i]", $moduleOptionMenu, $currentModuleID, "class='form-control chosen' onchange='loadStories($productID, this.value, $i)' data-drop_direction='down'");?></td>
|
||||
@@ -204,8 +204,8 @@
|
||||
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
|
||||
?>
|
||||
<td class='c-actions text-left'>
|
||||
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
<a href='javascript:;' onclick='addRow(this)' class='btn btn-link'><i class='icon-plus'></i></a>
|
||||
<a href='javascript:;' onclick='deleteRow(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
+24
-15
@@ -404,9 +404,10 @@ class treeModel extends model
|
||||
|
||||
$this->loadModel('branch');
|
||||
$projectID = zget($extra, 'projectID', 0);
|
||||
$executionID = zget($extra, 'executionID', 0);
|
||||
$branches = array($branch => '');
|
||||
$executionModules = array();
|
||||
if($branch and empty($projectID))
|
||||
if($branch and empty($projectID) and empty($extra['executionID']))
|
||||
{
|
||||
$branchName = $this->branch->getById($branch);
|
||||
$branches = array($branch => $branchName);
|
||||
@@ -416,11 +417,16 @@ class treeModel extends model
|
||||
$manage = $userFunc[1] == 'createManageLink' ? true : false;
|
||||
$product = $this->loadModel('product')->getById($rootID);
|
||||
|
||||
$onlyGetLinked = ($projectID and $this->config->vision != 'lite');
|
||||
if(strpos('story|bug|case', $type) !== false and $branch === 'all' and empty($projectID))
|
||||
$onlyGetLinked = (($projectID or $executionID) and $this->config->vision != 'lite');
|
||||
if(strpos('story|bug|case', $type) !== false and $branch === 'all' and empty($projectID) and empty($executionID))
|
||||
{
|
||||
if($product->type != 'normal') $branches = array(BRANCH_MAIN => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($rootID, 'noempty');
|
||||
}
|
||||
elseif($type == 'case' and $this->app->tab == 'execution')
|
||||
{
|
||||
if($product->type != 'normal' and $executionID) $branches += $this->branch->getPairs($product->id, 'noempty', $executionID);
|
||||
if($onlyGetLinked) $executionModules = $this->getTaskTreeModules($executionID, true, $type);
|
||||
}
|
||||
elseif(($type == 'story' and $this->app->rawModule == 'projectstory') or ($type == 'case' and $this->app->tab == 'project'))
|
||||
{
|
||||
if($product->type != 'normal' and $projectID) $branches += $this->branch->getPairs($product->id, 'noempty', $projectID);
|
||||
@@ -721,10 +727,10 @@ class treeModel extends model
|
||||
*/
|
||||
public function getCaseTreeMenu($rootID, $productID = 0, $startModule = 0, $userFunc = '', $extra = '')
|
||||
{
|
||||
$extra = array('projectID' => $rootID, 'productID' => $productID, 'tip' => true, 'extra' => $extra);
|
||||
$extra = array('projectID' => $rootID, 'executionID' => $rootID, 'productID' => $productID, 'tip' => true, 'extra' => $extra);
|
||||
|
||||
/* If createdVersion <= 4.1, go to getTreeMenu(). */
|
||||
$products = $this->loadModel('product')->getProductPairsByProject($rootID);
|
||||
$products = $this->app->tab != 'execution' ? $this->loadModel('product')->getProductPairsByProject($rootID) : $this->loadModel('product')->getProducts($rootID);
|
||||
$branchGroups = $this->dao->select('t1.product as product,branch,t3.name')->from(TABLE_PROJECTPRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id')
|
||||
->leftJoin(TABLE_BRANCH)->alias('t3')->on('t1.branch=t3.id')
|
||||
@@ -734,6 +740,7 @@ class treeModel extends model
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->fetchGroup('product', 'branch');
|
||||
|
||||
$this->app->loadLang('branch');
|
||||
foreach($branchGroups as $productID => $branches)
|
||||
{
|
||||
foreach($branches as $branchID => $branchInfo)
|
||||
@@ -756,15 +763,16 @@ class treeModel extends model
|
||||
$executionModules = $this->getTaskTreeModules($rootID, true, 'case');
|
||||
|
||||
/* Get module according to product. */
|
||||
$productNum = count($products);
|
||||
$moduleName = $this->app->tab == 'project' ? 'project' : 'testcase';
|
||||
$methodName = $this->app->tab == 'project' ? 'testcase' : 'browse';
|
||||
$projectParam = $this->app->tab == 'project' ? "projectID={$this->session->project}&" : '';
|
||||
$productNum = count($products);
|
||||
$moduleName = strpos(',project,execution,', ",{$this->app->tab},") !== false ? $this->app->tab : 'testcase';
|
||||
$methodName = strpos(',project,execution,', ",{$this->app->tab},") !== false ? 'testcase' : 'browse';
|
||||
$param = $this->app->tab == 'project' ? "projectID={$this->session->project}&" : '';
|
||||
$param = $this->app->tab == 'execution' ? "executionID={$rootID}&" : $param;
|
||||
foreach($products as $id => $product)
|
||||
{
|
||||
$extra['productID'] = $id;
|
||||
$link = helper::createLink($moduleName, $methodName, $projectParam . "productID=$id");
|
||||
$menu .= "<li>" . html::a($link, $product, '_self', "id='product$id' data-app='project'");
|
||||
$link = helper::createLink($moduleName, $methodName, $param . "productID=$id");
|
||||
$menu .= "<li>" . html::a($link, is_object($product) ? $product->name : $product, '_self', "id='product$id' data-app='{$this->app->tab}'");
|
||||
|
||||
/* tree menu. */
|
||||
$tree = '';
|
||||
@@ -1202,10 +1210,11 @@ class treeModel extends model
|
||||
*/
|
||||
public function createCaseLink($type, $module, $extra = array())
|
||||
{
|
||||
$moduleName = $this->app->tab == 'project' ? 'project' : 'testcase';
|
||||
$methodName = $this->app->tab == 'project' ? 'testcase' : 'browse';
|
||||
$projectParam = $this->app->tab == 'project' ? "projectID={$this->session->project}&" : '';
|
||||
return html::a(helper::createLink($moduleName, $methodName, $projectParam . "root={$module->root}&branch={$extra['branchID']}&type=byModule¶m={$module->id}"), $module->name, '_self', "id='module{$module->id}' data-app='{$this->app->tab}' title='{$module->name}'");
|
||||
$moduleName = strpos(',project,execution,', ",{$this->app->tab},") !== false ? $this->app->tab : 'testcase';
|
||||
$methodName = strpos(',project,execution,', ",{$this->app->tab},") !== false ? 'testcase' : 'browse';
|
||||
$param = $this->app->tab == 'project' ? "projectID={$this->session->project}&root={$module->root}&branch={$extra['branchID']}&" : "root={$module->root}&branch={$extra['branchID']}&";
|
||||
$param = $this->app->tab == 'execution' ? "executionID={$extra['executionID']}&root={$module->root}&" : $param;
|
||||
return html::a(helper::createLink($moduleName, $methodName, $param . "&type=byModule¶m={$module->id}"), $module->name, '_self', "id='module{$module->id}' data-app='{$this->app->tab}' title='{$module->name}'");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -95,9 +95,11 @@ if($viewType == 'doc' or $viewType == 'api')
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title"><?php echo $childTitle;?></div>
|
||||
<?php if($app->tab == 'product'):?>
|
||||
<div class="panel-actions btn-toolbar">
|
||||
<?php echo html::a($this->createLink('tree', 'viewHistory', "productID=$rootID", '', true), $lang->history, '', "class='btn btn-sm btn-primary iframe'");?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul id='modulesTree' data-name='tree-<?php echo $viewType;?>'></ul>
|
||||
|
||||
@@ -1032,3 +1032,171 @@ $(document).ready(function()
|
||||
$(this).removeClass('dropdown-hover');
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Add row.
|
||||
*
|
||||
* @param object $obj
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function addRow(obj)
|
||||
{
|
||||
var row = $('#addRow').html().replace(/%i%/g, rowIndex + 1);
|
||||
$('<tr class="addedRow">' + row + '</tr>').insertAfter($(obj).closest('tr'));
|
||||
|
||||
var $row = $(obj).closest('tr').next();
|
||||
|
||||
$row.find(".form-date").datepicker();
|
||||
$row.find("input[name^=color]").colorPicker();
|
||||
$row.find('div[id$=_chosen]').remove();
|
||||
$row.find('.picker').remove();
|
||||
$row.find('.chosen').chosen();
|
||||
$row.find('.picker-select').picker();
|
||||
|
||||
rowIndex ++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete row.
|
||||
*
|
||||
* @param object $obj
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function deleteRow(obj)
|
||||
{
|
||||
$(obj).closest('tr').remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show checked fields.
|
||||
*
|
||||
* @param string fields
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function showCheckedFields(fields)
|
||||
{
|
||||
var fieldList = ',' + fields + ',';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var $field = config.currentMethod == 'create' ? $('#' + $(this).val()) : $('[name^=' + $(this).val() + ']');
|
||||
var $fieldBox = $('.' + $(this).val() + 'Box' );
|
||||
|
||||
var required = '';
|
||||
if(typeof requiredFields != 'undefined') var required = ',' + requiredFields + ',';
|
||||
if(fieldList.indexOf(field) >= 0 || (required && required.indexOf(field) >= 0))
|
||||
{
|
||||
$fieldBox.removeClass('hidden');
|
||||
$field.removeAttr('disabled');
|
||||
}
|
||||
else if(!$fieldBox.hasClass('hidden'))
|
||||
{
|
||||
$fieldBox.addClass('hidden');
|
||||
$field.attr('disabled', true);
|
||||
}
|
||||
|
||||
if(config.currentModule == 'story' && $(this).val() == 'source')
|
||||
{
|
||||
var $sourceNote = config.currentMethod == 'create' ? $('#sourceNote') : $('[name^=sourceNote]');
|
||||
$sourceNote.attr('disabled', $fieldBox.hasClass('hidden'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if(config.currentModule == 'task' && config.currentMethod == 'create');
|
||||
{
|
||||
if(fieldList.indexOf(',estStarted,') >= 0 && fieldList.indexOf(',deadline,') >= 0)
|
||||
{
|
||||
$('.borderBox').removeClass('hidden');
|
||||
}
|
||||
else if(fieldList.indexOf(',estStarted,') >= 0 || fieldList.indexOf(',deadline,') >= 0)
|
||||
{
|
||||
$('.datePlanBox').removeClass('hidden');
|
||||
if(!$('.borderBox').hasClass('hidden')) $('.borderBox').addClass('hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!$('.borderBox').hasClass('hidden')) $('.borderBox').addClass('hidden');
|
||||
if(!$('.datePlanBox').hasClass('hidden')) $('.datePlanBox').addClass('hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden require field.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function hiddenRequireFields()
|
||||
{
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
|
||||
{
|
||||
var field = ',' + $(this).val() + ',';
|
||||
var required = ',' + requiredFields + ',';
|
||||
if(required.indexOf(field) >= 0) $(this).closest('div').addClass('hidden');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Save custom fields.
|
||||
*
|
||||
* @param stirng $key
|
||||
* @param int $maxFieldCount
|
||||
* @param object $name
|
||||
* @param int $nameMinWidth
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function saveCustomFields(key, maxFieldCount, $name, nameMinWidth)
|
||||
{
|
||||
var fields = '';
|
||||
$('#formSettingForm > .checkboxes > .checkbox-primary > input:checked').each(function()
|
||||
{
|
||||
fields += ',' + $(this).val();
|
||||
});
|
||||
|
||||
var module = config.currentModule;
|
||||
var link = createLink('custom', 'ajaxSaveCustomFields', 'module=' + module + '§ion=custom&key=' + key);
|
||||
$.post(link, {'fields' : fields}, function()
|
||||
{
|
||||
showFields = fields;
|
||||
|
||||
showCheckedFields(fields);
|
||||
$('#formSetting').parent().removeClass('open');
|
||||
|
||||
if(key == 'batchCreateFields') setCustomFieldsStyle(maxFieldCount, $name, nameMinWidth);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom fields style.
|
||||
*
|
||||
* @param int $maxFieldCount
|
||||
* @param object $name
|
||||
* @param int $nameMinWidth
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setCustomFieldsStyle(maxFieldCount, $name, nameMinWidth)
|
||||
{
|
||||
var fieldCount = $('#batchCreateForm .table thead>tr>th:visible').length;
|
||||
$('.form-actions').attr('colspan', fieldCount);
|
||||
|
||||
var $table = $('#batchCreateForm > .table-responsive');
|
||||
if(fieldCount > maxFieldCount)
|
||||
{
|
||||
$table.removeClass('scroll-none');
|
||||
$table.css('overflow', 'auto');
|
||||
}
|
||||
else
|
||||
{
|
||||
$table.addClass('scroll-none');
|
||||
$table.css('overflow', 'visible');
|
||||
}
|
||||
|
||||
if($name.width() < nameMinWidth) $name.width(200);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user