Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into importExport
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
ALTER TABLE `zt_task` ADD `order` mediumint(8) NOT NULL DEFAULT 0 AFTER `activatedDate`;
|
||||
ALTER TABLE `zt_task` ADD INDEX `order` (`order`);
|
||||
ALTER TABLE `zt_story` ADD COLUMN `linkRequirements` varchar(255) NOT NULL AFTER `linkStories`;
|
||||
|
||||
ALTER TABLE `zt_searchindex` ADD FULLTEXT `title_content` (`title`, `content`);
|
||||
@@ -13,11 +15,16 @@ ALTER TABLE `zt_release` ADD `createdDate` datetime NOT NULL AFTER `createdBy`;
|
||||
ALTER TABLE `zt_testtask` ADD `createdBy` varchar(30) NOT NULL AFTER `subStatus`;
|
||||
ALTER TABLE `zt_testtask` ADD `createdDate` datetime NOT NULL AFTER `createdBy`;
|
||||
|
||||
ALTER TABLE `zt_build` ADD `createdBy` varchar(30) NOT NULL AFTER `desc`;
|
||||
ALTER TABLE `zt_build` ADD `createdDate` datetime NOT NULL AFTER `createdBy`;
|
||||
|
||||
INSERT IGNORE INTO `zt_workflowfield` (`module`, `field`, `type`, `length`, `name`, `control`, `expression`, `options`, `default`, `rules`, `placeholder`, `order`, `searchOrder`, `exportOrder`, `canExport`, `canSearch`, `isValue`, `readonly`, `buildin`, `role`, `desc`, `createdBy`, `createdDate`, `editedBy`, `editedDate`) VALUES
|
||||
('testtask', 'createdBy', 'varchar', '30', '由谁创建', 'select', '', 'user', '', '', '', 393, 0, 0, '0', '0', '0', '1', 1, 'buildin', '', '', '2022-08-02 14:49', '', '0000-00-00 00:00:00'),
|
||||
('testtask', 'createdDate', 'datetime', '', '创建时间', 'datetime', '', '', '', '', '', 394, 0, 0, '0', '0', '0', '1', 1, 'buildin', '', '', '2022-08-02 14:49', '', '0000-00-00 00:00:00'),
|
||||
('productplan', 'createdBy', 'varchar', '30', '由谁创建', 'select', '', 'user', '', '', '', 11, 0, 0, '0', '0', '0', '1', 1, 'buildin', '', '', '2022-08-02 14:49', '', '0000-00-00 00:00:00'),
|
||||
('productplan', 'createdDate', 'datetime', '', '创建时间', 'datetime', '', '', '', '', '', 12, 0, 0, '0', '0', '0', '1', 1, 'buildin', '', '', '2022-08-02 14:49', '', '0000-00-00 00:00:00'),
|
||||
('build', 'createdBy', 'varchar', '30', '由谁创建', 'select', '', 'user', '', '', '', 15, 0, 0, '0', '0', '0', '1', 1, 'buildin', '', '', '2022-08-02 14:49', '', '0000-00-00 00:00:00'),
|
||||
('build', 'createdDate', 'datetime', '', '创建时间', 'datetime', '', '', '', '', '', 16, 0, 0, '0', '0', '0', '1', 1, 'buildin', '', '', '2022-08-02 14:49', '', '0000-00-00 00:00:00'),
|
||||
('release', 'createdBy', 'varchar', '30', '由谁创建', 'select', '', 'user', '', '', '', 14, 0, 0, '0', '0', '0', '1', 1, 'buildin', '', '', '2022-08-02 14:49', '', '0000-00-00 00:00:00'),
|
||||
('release', 'createdDate', 'datetime', '', '创建时间', 'datetime', '', '', '', '', '', 15, 0, 0, '0', '0', '0', '1', 1, 'buildin', '', '', '2022-08-02 14:49', '', '0000-00-00 00:00:00');
|
||||
|
||||
|
||||
@@ -331,6 +331,8 @@ CREATE TABLE IF NOT EXISTS `zt_build` (
|
||||
`bugs` text NOT NULL,
|
||||
`builder` char(30) NOT NULL default '',
|
||||
`desc` mediumtext NOT NULL,
|
||||
`createdBy` varchar(30) NOT NULL,
|
||||
`createdDate` datetime NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `product` (`product`),
|
||||
@@ -1527,6 +1529,7 @@ CREATE TABLE IF NOT EXISTS `zt_task` (
|
||||
`lastEditedBy` varchar(30) NOT NULL,
|
||||
`lastEditedDate` datetime NOT NULL,
|
||||
`activatedDate` datetime NOT NULL,
|
||||
`order` mediumint(8) unsigned NOT NULL,
|
||||
`repo` mediumint(8) unsigned NOT NULL,
|
||||
`mr` mediumint(8) unsigned NOT NULL,
|
||||
`entry` varchar(255) NOT NULL,
|
||||
@@ -1540,6 +1543,7 @@ CREATE TABLE IF NOT EXISTS `zt_task` (
|
||||
KEY `story` (`story`),
|
||||
KEY `parent` (`parent`),
|
||||
KEY `assignedTo` (`assignedTo`)
|
||||
KEY `order` (`order`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_taskestimate`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_taskestimate` (
|
||||
|
||||
@@ -240,8 +240,8 @@ $lang->action->desc->linkrelatedcase = '$date, <strong>$actor</strong> hat ein
|
||||
$lang->action->desc->unlinkrelatedcase = '$date, <strong>$actor</strong> hate eine Fallverknüpfung aufgelöst <strong>$extra</strong>.' . "\n";
|
||||
|
||||
/* Used to describe the history of operations link story and bug to productplan. */
|
||||
$lang->action->desc->linkstory = '$date, <strong>$actor</strong> link stories <strong>$extra</strong> to plan.' . "\n";
|
||||
$lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <strong>$extra</strong> to plan.' . "\n";
|
||||
$lang->action->desc->linkstory = '$date, <strong>$actor</strong> link stories <strong>$extra</strong>.' . "\n";
|
||||
$lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <strong>$extra</strong>.' . "\n";
|
||||
$lang->action->desc->unlinkstory = '$date, <strong>$actor</strong> remove stories <strong>$extra</strong> from plan.' . "\n";
|
||||
$lang->action->desc->unlinkbug = '$date, <strong>$actor</strong> remove bugs <strong>$extra</strong> from plan.' . "\n";
|
||||
|
||||
|
||||
@@ -240,8 +240,8 @@ $lang->action->desc->linkrelatedcase = '$date, <strong>$actor</strong> linked
|
||||
$lang->action->desc->unlinkrelatedcase = '$date, <strong>$actor</strong> unlinked a case <strong>$extra</strong>.' . "\n";
|
||||
|
||||
/* Used to describe the history of operations link story and bug to productplan. */
|
||||
$lang->action->desc->linkstory = '$date, <strong>$actor</strong> link stories <strong>$extra</strong> to plan.' . "\n";
|
||||
$lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <strong>$extra</strong> to plan.' . "\n";
|
||||
$lang->action->desc->linkstory = '$date, <strong>$actor</strong> link stories <strong>$extra</strong>.' . "\n";
|
||||
$lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <strong>$extra</strong>.' . "\n";
|
||||
$lang->action->desc->unlinkstory = '$date, <strong>$actor</strong> remove stories <strong>$extra</strong> from plan.' . "\n";
|
||||
$lang->action->desc->unlinkbug = '$date, <strong>$actor</strong> remove bugs <strong>$extra</strong> from plan.' . "\n";
|
||||
|
||||
|
||||
@@ -240,8 +240,8 @@ $lang->action->desc->linkrelatedcase = '$date, <strong>$actor</strong> a fait
|
||||
$lang->action->desc->unlinkrelatedcase = '$date, <strong>$actor</strong> a délié le CasTest <strong>$extra</strong>.' . "\n";
|
||||
|
||||
/* Used to describe the history of operations link story and bug to productplan. */
|
||||
$lang->action->desc->linkstory = '$date, <strong>$actor</strong> link stories <strong>$extra</strong> to plan.' . "\n";
|
||||
$lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <strong>$extra</strong> to plan.' . "\n";
|
||||
$lang->action->desc->linkstory = '$date, <strong>$actor</strong> link stories <strong>$extra</strong>.' . "\n";
|
||||
$lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <strong>$extra</strong>.' . "\n";
|
||||
$lang->action->desc->unlinkstory = '$date, <strong>$actor</strong> remove stories <strong>$extra</strong> from plan.' . "\n";
|
||||
$lang->action->desc->unlinkbug = '$date, <strong>$actor</strong> remove bugs <strong>$extra</strong> from plan.' . "\n";
|
||||
|
||||
|
||||
@@ -240,8 +240,8 @@ $lang->action->desc->linkrelatedcase = '$date, 由 <strong>$actor</strong> 关
|
||||
$lang->action->desc->unlinkrelatedcase = '$date, 由 <strong>$actor</strong> 移除相关用例 <strong>$extra</strong>。' . "\n";
|
||||
|
||||
/* 用来描述计划关联和移除需求、bug时的历史操作记录。*/
|
||||
$lang->action->desc->linkstory = '$date, 由 <strong>$actor</strong> 关联需求 <strong>$extra</strong> 到计划。' . "\n";
|
||||
$lang->action->desc->linkbug = '$date, 由 <strong>$actor</strong> 关联BUG <strong>$extra</strong> 到计划。' . "\n";
|
||||
$lang->action->desc->linkstory = '$date, 由 <strong>$actor</strong> 关联需求 <strong>$extra</strong>。' . "\n";
|
||||
$lang->action->desc->linkbug = '$date, 由 <strong>$actor</strong> 关联BUG <strong>$extra</strong>。' . "\n";
|
||||
$lang->action->desc->unlinkstory = '$date, 由 <strong>$actor</strong> 从计划移除需求 <strong>$extra</strong>。' . "\n";
|
||||
$lang->action->desc->unlinkbug = '$date, 由 <strong>$actor</strong> 从计划移除BUG <strong>$extra</strong>。' . "\n";
|
||||
|
||||
|
||||
@@ -858,7 +858,7 @@ class actionModel extends model
|
||||
$this->app->loadLang('mr');
|
||||
$desc = sprintf($this->lang->mr->createAction, $mrCreatedDate, $mrActor, $mrLink);
|
||||
}
|
||||
elseif($this->config->edition == 'max' and strpos($this->config->action->assetType, $action->objectType) !== false and $action->action == 'approved')
|
||||
elseif($this->config->edition == 'max' and strpos($this->config->action->assetType, ",{$action->objectType},") !== false and $action->action == 'approved')
|
||||
{
|
||||
$desc = empty($this->lang->action->approve->{$action->extra}) ? '' : $this->lang->action->approve->{$action->extra};
|
||||
}
|
||||
@@ -1469,7 +1469,7 @@ class actionModel extends model
|
||||
}
|
||||
|
||||
if($this->config->edition == 'max'
|
||||
and strpos($this->config->action->assetType, $action->objectType) !== false
|
||||
and strpos($this->config->action->assetType, ",{$action->objectType},") !== false
|
||||
and empty($action->project) and empty($action->product) and empty($action->execution))
|
||||
{
|
||||
if($action->objectType == 'doc')
|
||||
|
||||
+10
-8
@@ -1146,13 +1146,15 @@ class bugModel extends model
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$buildData = new stdclass();
|
||||
$buildData->product = (int)$oldBug->product;
|
||||
$buildData->branch = (int)$oldBug->branch;
|
||||
$buildData->project = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($bug->buildExecution)->fetch('project');
|
||||
$buildData->execution = $bug->buildExecution;
|
||||
$buildData->name = $bug->buildName;
|
||||
$buildData->date = date('Y-m-d');
|
||||
$buildData->builder = $this->app->user->account;
|
||||
$buildData->product = (int)$oldBug->product;
|
||||
$buildData->branch = (int)$oldBug->branch;
|
||||
$buildData->project = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($bug->buildExecution)->fetch('project');
|
||||
$buildData->execution = $bug->buildExecution;
|
||||
$buildData->name = $bug->buildName;
|
||||
$buildData->date = date('Y-m-d');
|
||||
$buildData->builder = $this->app->user->account;
|
||||
$buildData->createdBy = $this->app->user->account;
|
||||
$buildData->createdDate = helper::now();
|
||||
$this->dao->insert(TABLE_BUILD)->data($buildData)->autoCheck()
|
||||
->check('name', 'unique', "product = {$buildData->product} AND branch = {$buildData->branch} AND deleted = '0'")
|
||||
->exec();
|
||||
@@ -1686,7 +1688,7 @@ class bugModel extends model
|
||||
$bugIDList = array();
|
||||
if($moduleName == 'contributeBug')
|
||||
{
|
||||
$bugsAssignedByMe = $this->loadModel('my')->getAssignedByMe($account, 0, $pager, $orderBy, 0, 'bug');
|
||||
$bugsAssignedByMe = $this->loadModel('my')->getAssignedByMe($account, 0, '', $orderBy, 'bug');
|
||||
foreach($bugsAssignedByMe as $bugID => $bug) $bugIDList[$bugID] = $bugID;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
#branch_chosen .chosen-single {border-left: 0px;}
|
||||
#noProduct {display: inline-block; width: 110%;}
|
||||
|
||||
@@ -313,6 +313,8 @@ class buildModel extends model
|
||||
->setDefault('branch', 0)
|
||||
->cleanInt('product,branch')
|
||||
->add('execution', (int)$executionID)
|
||||
->add('createdBy', $this->app->user->account)
|
||||
->add('createdDate', helper::now())
|
||||
->stripTags($this->config->build->editor->create['id'], $this->config->allowedTags)
|
||||
->remove('resolvedBy,allchecker,files,labels,uid')
|
||||
->get();
|
||||
|
||||
@@ -152,17 +152,19 @@ class caselibModel extends model
|
||||
/**
|
||||
* Get library list.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getList($orderBy = 'id_desc', $pager = null)
|
||||
public function getList($type = 'all', $orderBy = 'id_desc', $pager = null)
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_TESTSUITE)
|
||||
->where('product')->eq(0)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('type')->eq('library')
|
||||
->beginIF($type == 'review')->andWhere("FIND_IN_SET('{$this->app->user->account}', `reviewers`)")->fi()
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
|
||||
@@ -1521,10 +1521,12 @@ class commonModel extends model
|
||||
public static function printLink($module, $method, $vars = '', $label = '', $target = '', $misc = '', $newline = true, $onlyBody = false, $object = null)
|
||||
{
|
||||
/* Add data-app attribute. */
|
||||
global $app;
|
||||
global $app, $config;
|
||||
$currentModule = strtolower($module);
|
||||
$currentMethod = strtolower($method);
|
||||
if(strpos($misc, 'data-app') === false) $misc .= ' data-app="' . $app->tab . '"';
|
||||
|
||||
if(!commonModel::hasPriv($module, $method, $object)) return false;
|
||||
if(!commonModel::hasPriv($module, $method, $object) and !in_array("$currentModule.$currentMethod", $config->openMethods)) return false;
|
||||
echo html::a(helper::createLink($module, $method, $vars, '', $onlyBody), $label, $target, $misc, $newline);
|
||||
return true;
|
||||
}
|
||||
@@ -1966,7 +1968,7 @@ EOD;
|
||||
}
|
||||
}
|
||||
|
||||
$changes = array();
|
||||
$changes = array();
|
||||
foreach($new as $key => $value)
|
||||
{
|
||||
if(is_object($value) or is_array($value)) continue;
|
||||
|
||||
@@ -11,14 +11,18 @@
|
||||
*/
|
||||
css::import($jsRoot . 'dhtmlxgantt/min.css');
|
||||
js::import($jsRoot . 'dhtmlxgantt/min.js');
|
||||
js::import($jsRoot . 'dhtmlxgantt/ext/dhtmlxgantt_critical_path.js');
|
||||
js::import($jsRoot . 'dhtmlxgantt/ext/dhtmlxgantt_fullscreen.js');
|
||||
js::import($jsRoot . 'dhtmlxgantt/ext/dhtmlxgantt_smart_rendering.js');
|
||||
js::import($jsRoot . 'dhtmlxgantt/ext/dhtmlxgantt_marker.js');
|
||||
js::import($jsRoot . 'dhtmlxgantt/ext/dhtmlxgantt_tooltip.js');
|
||||
$currentLang = $app->getClientLang();
|
||||
if($currentLang != 'en') js::import($jsRoot . 'dhtmlxgantt/lang/' . $currentLang . '.js');
|
||||
?>
|
||||
<style>
|
||||
.gantt_message_area{display:none;}
|
||||
</style>
|
||||
<script>
|
||||
gantt.plugins({
|
||||
marker: true,
|
||||
critical_path: true,
|
||||
fullscreen: true,
|
||||
tooltip: true,
|
||||
click_drag: true
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -947,11 +947,13 @@ class convertModel extends model
|
||||
$productID = $projectProduct[$projectID];
|
||||
|
||||
$build = new stdclass();
|
||||
$build->product = $productID;
|
||||
$build->project = $projectID;
|
||||
$build->name = $data->vname;
|
||||
$build->date = substr($data->RELEASEDATE, 0, 10);
|
||||
$build->builder = $this->app->user->account;
|
||||
$build->product = $productID;
|
||||
$build->project = $projectID;
|
||||
$build->name = $data->vname;
|
||||
$build->date = substr($data->RELEASEDATE, 0, 10);
|
||||
$build->builder = $this->app->user->account;
|
||||
$build->createdBy = $this->app->user->account;
|
||||
$build->createdDate = helper::now();
|
||||
|
||||
$this->dao->dbh($this->dbh)->insert(TABLE_BUILD)->data($build)->exec();
|
||||
$buildID = $this->dao->dbh($this->dbh)->lastInsertID();
|
||||
|
||||
@@ -3675,7 +3675,6 @@ class execution extends control
|
||||
* All execution.
|
||||
*
|
||||
* @param string $status
|
||||
* @param int $projectID
|
||||
* @param string $orderBy
|
||||
* @param int $productID
|
||||
* @param string $param
|
||||
@@ -3685,7 +3684,7 @@ class execution extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function all($status = 'undone', $projectID = 0, $orderBy = 'order_asc', $productID = 0, $param = '', $recTotal = 0, $recPerPage = 100, $pageID = 1)
|
||||
public function all($status = 'undone', $orderBy = 'order_asc', $productID = 0, $param = '', $recTotal = 0, $recPerPage = 100, $pageID = 1)
|
||||
{
|
||||
$this->app->loadLang('my');
|
||||
$this->app->loadLang('product');
|
||||
@@ -3698,17 +3697,8 @@ class execution extends control
|
||||
|
||||
if($this->app->viewType == 'mhtml')
|
||||
{
|
||||
if($this->app->rawModule == 'project' and $this->app->rawMethod == 'execution')
|
||||
{
|
||||
$projects = $this->project->getPairsByProgram();
|
||||
$projectID = $this->project->saveState($projectID, $projects);
|
||||
$this->project->setMenu($projectID);
|
||||
}
|
||||
else
|
||||
{
|
||||
$executionID = $this->execution->saveState(0, $this->executions);
|
||||
$this->execution->setMenu($executionID);
|
||||
}
|
||||
$executionID = $this->execution->saveState(0, $this->executions);
|
||||
$this->execution->setMenu($executionID);
|
||||
}
|
||||
|
||||
/* Load pager and get tasks. */
|
||||
@@ -3716,13 +3706,13 @@ class execution extends control
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$queryID = ($status == 'bySearch') ? (int)$param : 0;
|
||||
$actionURL = $this->createLink('execution', 'all', "status=bySearch&projectID=$projectID&orderBy=$orderBy&productID=$productID¶m=myQueryID");
|
||||
$actionURL = $this->createLink('execution', 'all', "status=bySearch&orderBy=$orderBy&productID=$productID¶m=myQueryID");
|
||||
$this->execution->buildSearchFrom($queryID, $actionURL);
|
||||
|
||||
$this->view->title = $this->lang->execution->allExecutions;
|
||||
$this->view->position[] = $this->lang->execution->allExecutions;
|
||||
|
||||
$executionStats = $this->project->getStats($projectID, $status, $productID, 0, 30, $orderBy, $pager, false, $queryID);
|
||||
$executionStats = $this->project->getStats(0, $status, $productID, 0, 30, $orderBy, $pager, false, $queryID);
|
||||
|
||||
$parentIdList = array();
|
||||
foreach($executionStats as $execution)
|
||||
@@ -3733,15 +3723,13 @@ class execution extends control
|
||||
$parents = array();
|
||||
if($parentIdList) $parents = $this->execution->getByIdList($parentIdList);
|
||||
|
||||
$allExecutionsNum = $this->project->getStats($projectID, 'all');
|
||||
$allExecutionsNum = $this->project->getStats(0, 'all');
|
||||
$this->view->allExecutionsNum = count($allExecutionsNum);
|
||||
|
||||
$this->view->executionStats = $executionStats;
|
||||
$this->view->productList = $this->loadModel('product')->getProductPairsByProject($projectID);
|
||||
$this->view->productList = $this->loadModel('product')->getProductPairsByProject(0);
|
||||
$this->view->productID = $productID;
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->parents = $parents;
|
||||
$this->view->projects = array('') + $this->project->getPairsByProgram();
|
||||
$this->view->pager = $pager;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
|
||||
@@ -32,6 +32,8 @@ td.flex span.project-type-label {min-width: 40px;}
|
||||
.c-project{text-overflow: unset !important;}
|
||||
canvas {height: 28px;}
|
||||
.parent.has-child.c-name.flex, .table-child-bottom > .c-name.flex {border-bottom: 0px solid #cbd0db !important;}
|
||||
.parent.has-child.c-name.flex {margin-bottom: -2px !important;}
|
||||
#tableCustomBtn {padding-bottom: 5px;}
|
||||
#bysearchTab {margin-left: 5px;}
|
||||
#datatable-executionList .table-child-bottom > .c-name.flex {border-bottom: 1px solid #cbd0db !important;}
|
||||
#datatable-executionList .table-child-bottom.table-child-top > .c-name.flex {border-bottom: 2px solid #cbd0db !important;}
|
||||
#datatable-executionList .parent.has-child.c-name.flex {border-bottom: 1px solid #cbd0db !important;}
|
||||
#datatable-executionList tr:last-child .c-name.flex {margin-top: 1px !important;}
|
||||
|
||||
@@ -11,7 +11,7 @@ $(function()
|
||||
if(isCNLang && nameWidth < 150 && !useDatatable) $('#executionsForm thead th.c-name').css('width', '150px');
|
||||
if(!isCNLang && nameWidth < 200 && !useDatatable) $('#executionsForm thead th.c-name').css('width', '200px');
|
||||
|
||||
toggleFold('#executionsForm', unfoldExecutions, projectID, 'execution');
|
||||
toggleFold('#executionsForm', unfoldExecutions, 0, 'execution');
|
||||
|
||||
$('.table td.has-child > .plan-toggle').each(function()
|
||||
{
|
||||
|
||||
@@ -514,6 +514,9 @@ $lang->execution->featureBar['all']['doing'] = $lang->execution->statusList[
|
||||
$lang->execution->featureBar['all']['suspended'] = $lang->execution->statusList['suspended'];
|
||||
$lang->execution->featureBar['all']['closed'] = $lang->execution->statusList['closed'];
|
||||
|
||||
$lang->execution->featureBar['bug']['all'] = 'All';
|
||||
$lang->execution->featureBar['bug']['unresolved'] = 'Active';
|
||||
|
||||
$lang->execution->featureBar['build']['all'] = 'Build List';
|
||||
|
||||
$lang->execution->myExecutions = 'Ich bin beteiligt.';
|
||||
|
||||
@@ -514,6 +514,9 @@ $lang->execution->featureBar['all']['doing'] = $lang->execution->statusList[
|
||||
$lang->execution->featureBar['all']['suspended'] = $lang->execution->statusList['suspended'];
|
||||
$lang->execution->featureBar['all']['closed'] = $lang->execution->statusList['closed'];
|
||||
|
||||
$lang->execution->featureBar['bug']['all'] = 'All';
|
||||
$lang->execution->featureBar['bug']['unresolved'] = 'Active';
|
||||
|
||||
$lang->execution->featureBar['build']['all'] = 'Build List';
|
||||
|
||||
$lang->execution->myExecutions = 'Mine';
|
||||
|
||||
@@ -514,6 +514,9 @@ $lang->execution->featureBar['all']['doing'] = $lang->execution->statusList[
|
||||
$lang->execution->featureBar['all']['suspended'] = $lang->execution->statusList['suspended'];
|
||||
$lang->execution->featureBar['all']['closed'] = $lang->execution->statusList['closed'];
|
||||
|
||||
$lang->execution->featureBar['bug']['all'] = 'All';
|
||||
$lang->execution->featureBar['bug']['unresolved'] = 'Active';
|
||||
|
||||
$lang->execution->featureBar['build']['all'] = 'Build List';
|
||||
|
||||
$lang->execution->myExecutions = "J'étais impliqué";
|
||||
|
||||
@@ -418,6 +418,9 @@ $lang->execution->featureBar['all']['doing'] = $lang->execution->statusList[
|
||||
$lang->execution->featureBar['all']['suspended'] = $lang->execution->statusList['suspended'];
|
||||
$lang->execution->featureBar['all']['closed'] = $lang->execution->statusList['closed'];
|
||||
|
||||
$lang->execution->featureBar['bug']['all'] = 'All';
|
||||
$lang->execution->featureBar['bug']['unresolved'] = 'Active';
|
||||
|
||||
$lang->execution->featureBar['build']['all'] = 'Build List';
|
||||
|
||||
$lang->execution->myExecutions = 'Tôi tham gia';
|
||||
|
||||
@@ -514,6 +514,9 @@ $lang->execution->featureBar['all']['doing'] = $lang->execution->statusList[
|
||||
$lang->execution->featureBar['all']['suspended'] = $lang->execution->statusList['suspended'];
|
||||
$lang->execution->featureBar['all']['closed'] = $lang->execution->statusList['closed'];
|
||||
|
||||
$lang->execution->featureBar['bug']['all'] = '所有';
|
||||
$lang->execution->featureBar['bug']['unresolved'] = '未解决';
|
||||
|
||||
$lang->execution->featureBar['build']['all'] = '所有版本';
|
||||
|
||||
$lang->execution->myExecutions = '我参与的';
|
||||
|
||||
@@ -4361,6 +4361,8 @@ class executionModel extends model
|
||||
$this->loadModel('execution');
|
||||
$this->loadModel('programplan');
|
||||
|
||||
$today = helper::today();
|
||||
|
||||
if(!$isChild)
|
||||
{
|
||||
$trClass = 'is-top-level table-nest-child-hide';
|
||||
@@ -4385,8 +4387,22 @@ class executionModel extends model
|
||||
echo '<td>' . zget($users, $execution->PM) . '</td>';
|
||||
echo "<td class='status-{$execution->status}'>" . zget($this->lang->project->statusList, $execution->status) . '</td>';
|
||||
echo '<td>' . html::ring($execution->hours->progress) . '</td>';
|
||||
echo '<td>' . $execution->begin . '</td>';
|
||||
echo '<td>' . $execution->end . '</td>';
|
||||
echo helper::isZeroDate($execution->begin) ? '<td></td>' : '<td>' . $execution->begin . '</td>';
|
||||
if(!helper::isZeroDate($execution->end))
|
||||
{
|
||||
if($execution->status != 'closed')
|
||||
{
|
||||
echo strtotime($today) > strtotime($execution->end) ? '<td class="delayed" title="' . $this->lang->execution->delayed . '">' . $execution->end . '</td>' : '<td>' . $execution->end . '</td>';
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<td>' . $execution->end . '</td>';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<td></td>';
|
||||
}
|
||||
echo "<td class='hours' title='{$execution->hours->totalEstimate}{$this->lang->execution->workHour}'>" . $execution->hours->totalEstimate . $this->lang->execution->workHourUnit . '</td>';
|
||||
echo "<td class='hours' title='{$execution->hours->totalConsumed}{$this->lang->execution->workHour}'>" . $execution->hours->totalConsumed . $this->lang->execution->workHourUnit . '</td>';
|
||||
echo "<td class='hours' title='{$execution->hours->totalLeft}{$this->lang->execution->workHour}'>" . $execution->hours->totalLeft . $this->lang->execution->workHourUnit . '</td>';
|
||||
|
||||
@@ -16,14 +16,11 @@
|
||||
$datatableId = $this->moduleName . ucfirst($this->methodName);
|
||||
$useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable');
|
||||
?>
|
||||
<?php js::set('unfoldExecutions', array());?>
|
||||
<?php js::set('useDatatable', $useDatatable);?>
|
||||
<?php js::set('from', $from);?>
|
||||
<?php js::set('projectID', $projectID);?>
|
||||
<?php
|
||||
/* Set unfold parent executionID. */
|
||||
$unfoldExecutions = isset($config->execution->all->unfoldExecutions) ? json_decode($config->execution->all->unfoldExecutions, true) : array();
|
||||
$unfoldExecutions = zget($unfoldExecutions, $projectID, array());
|
||||
js::set('unfoldExecutions', $unfoldExecutions);
|
||||
js::set('unfoldAll', $lang->execution->treeLevel['all']);
|
||||
js::set('foldAll', $lang->execution->treeLevel['root']);
|
||||
js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
@@ -38,11 +35,11 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
<?php
|
||||
$class = '';
|
||||
if($productID == 0) $class = 'class="active"';
|
||||
echo "<li $class>" . html::a($this->createLink('project', 'execution', "status=$status&projectID=$projectID&orderby=$orderBy"), $lang->product->allProduct) . "</li>";
|
||||
echo "<li $class>" . html::a($this->createLink('project', 'execution', "status=$status&orderby=$orderBy"), $lang->product->allProduct) . "</li>";
|
||||
foreach($productList as $key => $product)
|
||||
{
|
||||
$class = $productID == $key ? 'class="active"' : '';
|
||||
echo "<li $class>" . html::a($this->createLink('project', 'execution', "status=$status&projectID=$projectID&orderby=$orderBy&productID=$key"), $product) . "</li>";
|
||||
echo "<li $class>" . html::a($this->createLink('project', 'execution', "status=$status&orderby=$orderBy&productID=$key"), $product) . "</li>";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
@@ -52,22 +49,13 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
<?php foreach($lang->execution->featureBar['all'] as $key => $label):?>
|
||||
<?php $label = "<span class='text'>$label</span>";?>
|
||||
<?php if($status == $key) $label .= " <span class='label label-light label-badge'>{$pager->recTotal}</span>";?>
|
||||
<?php echo html::a($this->createLink($this->app->rawModule, $this->app->rawMethod, "status=$key&projectID=$projectID&orderBy=$orderBy&productID=$productID"), $label, '', "class='btn btn-link' id='{$key}Tab' data-app='$from'");?>
|
||||
<?php echo html::a($this->createLink($this->app->rawModule, $this->app->rawMethod, "status=$key&orderBy=$orderBy&productID=$productID"), $label, '', "class='btn btn-link' id='{$key}Tab' data-app='$from'");?>
|
||||
<?php endforeach;?>
|
||||
<?php if($from == 'execution' and $this->config->systemMode == 'new'):?>
|
||||
<div class='input-control w-180px'>
|
||||
<?php echo html::select('project', $projects, $projectID, "class='form-control chosen' data-placeholder='{$lang->execution->selectProject}'");?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->execution->byQuery;?></a>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<?php common::printLink('execution', 'export', "status=$status&productID=$productID&orderBy=$orderBy&from=$from", "<i class='icon-export muted'> </i> " . $lang->export, '', "class='btn btn-link export'")?>
|
||||
<?php if(common::hasPriv('programplan', 'create') and $isStage):?>
|
||||
<?php echo html::a($this->createLink('programplan', 'create', "projectID=$projectID&productID=$productID"), "<i class='icon icon-plus'></i> " . $lang->programplan->create, '', "class='btn btn-primary'");?>
|
||||
<?php else: ?>
|
||||
<?php if(common::hasPriv('execution', 'create')) echo html::a($this->createLink('execution', 'create', "projectID=$projectID"), "<i class='icon icon-sm icon-plus'></i> " . ((($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-primary create-execution-btn' data-app='execution' onclick='$(this).removeAttr(\"data-toggle\")'");?>
|
||||
<?php endif;?>
|
||||
<?php if(common::hasPriv('execution', 'create')) echo html::a($this->createLink('execution', 'create'), "<i class='icon icon-sm icon-plus'></i> " . ((($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-primary create-execution-btn' data-app='execution' onclick='$(this).removeAttr(\"data-toggle\")'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div id='mainContent' class="main-row fade">
|
||||
@@ -77,12 +65,8 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $from == 'execution' ? $lang->execution->noExecutions : $lang->execution->noExecution;?></span>
|
||||
<?php if(empty($allExecutionsNum)):?>
|
||||
<?php if(common::hasPriv('programplan', 'create') and $isStage):?>
|
||||
<?php echo html::a($this->createLink('programplan', 'create', "projectID=$projectID&productID=$productID"), "<i class='icon icon-plus'></i> " . $lang->programplan->create, '', "class='btn btn-info'");?>
|
||||
<?php else: ?>
|
||||
<?php if(common::hasPriv('execution', 'create')):?>
|
||||
<?php echo html::a($this->createLink('execution', 'create', "projectID=$projectID"), "<i class='icon icon-plus'></i> " . (($from == 'execution' and $config->systemMode == 'new') ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-info' data-app='execution'");?>
|
||||
<?php endif;?>
|
||||
<?php if(common::hasPriv('execution', 'create')):?>
|
||||
<?php echo html::a($this->createLink('execution', 'create'), "<i class='icon icon-plus'></i> " . (($from == 'execution' and $config->systemMode == 'new') ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-info' data-app='execution'");?>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
</p>
|
||||
@@ -94,7 +78,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
<nav class="btn-toolbar pull-right setting"></nav>
|
||||
</div>
|
||||
<?php
|
||||
$vars = "status=$status&projectID=$projectID&orderBy=%s&productID=$productID¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";
|
||||
$vars = "status=$status&orderBy=%s&productID=$productID¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";
|
||||
if($useDatatable) include '../../common/view/datatable.html.php';
|
||||
else include '../../common/view/tablesorter.html.php';
|
||||
|
||||
@@ -167,12 +151,6 @@ $(document).on('click', '.plan-toggle', function(e)
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('#project').change(function()
|
||||
{
|
||||
var projectID = $('#project').val();
|
||||
location.href = createLink('execution', 'all', 'status=' + status + '&projectID=' + projectID);
|
||||
});
|
||||
</script>
|
||||
<?php js::set('orderBy', $orderBy)?>
|
||||
<?php js::set('status', $status)?>
|
||||
|
||||
@@ -31,12 +31,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php
|
||||
$buildName = $build ? " <span class='label label-danger'>Build:{$build->name}</span>" : '';
|
||||
$module = $type != 'bysearch' ? "¶m=$param" : '';
|
||||
echo html::a($this->inlink('bug', "executionID={$execution->id}&productID={$productID}&branch={$branchID}&orderBy=status,id_desc&build=$buildID&type=all$module"), "<span class='text'>{$lang->bug->allBugs}</span>" . ($type == 'all' ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>$buildName" : ''), '', "id='allTab' class='btn btn-link" . ('all' == $type ? ' btn-active-text' : '') . "'");
|
||||
echo html::a($this->inlink('bug', "executionID={$execution->id}&productID={$productID}&branch={$branchID}&orderBy=status,id_desc&build=$buildID&type=unresolved$module"), "<span class='text'>{$lang->bug->unResolved}</span>" . ($type == 'unresolved' ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>$buildName" : ''), '', "id='unresolvedTab' class='btn btn-link" . ('unresolved' == $type ? ' btn-active-text' : '') . "'");
|
||||
?>
|
||||
<?php common::sortFeatureMenu();?>
|
||||
<?php foreach($lang->execution->featureBar['bug'] as $featureType => $label):?>
|
||||
<?php $active = $type == $featureType ? 'btn-active-text' : '';?>
|
||||
<?php $label = "<span class='text'>$label</span>";?>
|
||||
<?php if($type == $featureType):?>
|
||||
<?php $label .= " <span class='label label-light label-badge'>{$pager->recTotal}</span>";?>
|
||||
<?php $label .= $build ? " <span class='label label-danger'>Build:{$build->name}</span>" : '';?>
|
||||
<?php endif;?>
|
||||
<?php $module = $type != 'bysearch' ? "¶m=$param" : '';?>
|
||||
<?php echo html::a(inlink('bug', "executionID=$execution->id&productID={$productID}&branch={$branchID}&orderBy=status,id_desc&build=$buildID&type={$featureType}$module"), $label, '', "class='btn btn-link $active' id='{$featureType}Tab'");?>
|
||||
<?php endforeach;?>
|
||||
<a class="btn btn-link querybox-toggle" id="bysearchTab"><i class="icon icon-search muted"></i> <?php echo $lang->bug->search;?></a>
|
||||
</div>
|
||||
<div class="btn-toolbar pull-right">
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
<th><?php echo $lang->execution->days;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input('days', (isset($plan) && !empty($plan->begin) ? helper::workDays($plan->begin, $plan->end) : ''), "class='form-control'");?>
|
||||
<?php echo html::input('days', (isset($plan) && !empty($plan->begin) ? (helper::workDays($plan->begin, $plan->end) + 1) : ''), "class='form-control'");?>
|
||||
<span class='input-group-addon'><?php echo $lang->execution->day;?></span>
|
||||
</div>
|
||||
</td><td></td><td></td>
|
||||
|
||||
@@ -754,8 +754,8 @@ $.extend(
|
||||
var searchModule = types[0];
|
||||
var searchMethod = typeof(types[1]) == 'undefined' ? 'view' : types[1];
|
||||
var searchLink = createLink(searchModule, searchMethod, "id=" + objectValue);
|
||||
var assetType = 'story,issue,risk,opportunity,doc';
|
||||
if(assetType.indexOf(searchModule) > -1)
|
||||
var assetType = ',story,issue,risk,opportunity,doc,';
|
||||
if(assetType.indexOf(',' + searchModule + ',') > -1)
|
||||
{
|
||||
var link = createLink('index', 'ajaxGetViewMethod' , 'objectID=' + objectValue + '&objectType=' + searchModule);
|
||||
$.get(link, function(data)
|
||||
|
||||
+26
-10
@@ -3345,7 +3345,7 @@ class kanbanModel extends model
|
||||
{
|
||||
$groupBy = ($this->session->execGroupBy and ($this->app->tab == 'execution' or $this->config->vision == 'lite')) ? $this->session->execGroupBy : '';
|
||||
|
||||
$fromCell = $this->dao->select('cards, lane')->from(TABLE_KANBANCELL)
|
||||
$fromCell = $this->dao->select('id,cards,lane')->from(TABLE_KANBANCELL)
|
||||
->where('`column`')->eq($fromColID)
|
||||
->beginIF(!$groupBy or $groupBy == 'default')->andWhere('lane')->eq($fromLaneID)->fi()
|
||||
->beginIF($groupBy and $groupBy != 'default')
|
||||
@@ -3355,20 +3355,36 @@ class kanbanModel extends model
|
||||
->fetch();
|
||||
|
||||
if($groupBy and $groupBy != 'default') $fromLaneID = $toLaneID = $fromCell->lane;
|
||||
$fromCells[$fromCell->id] = $fromCell;
|
||||
|
||||
$fromCellCards = $fromCell->cards;
|
||||
$toCell = $this->dao->select('*')->from(TABLE_KANBANCELL)->where('lane')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->fetch();
|
||||
$toCellCards = $this->dao->select('cards')->from(TABLE_KANBANCELL)->where('lane')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->fetch('cards');
|
||||
/* Remove all cells with cardID in fromCell. */
|
||||
$fromLane = $this->getLaneById($fromLaneID);
|
||||
$fromCells += $this->dao->select('t1.id as id,t1.cards,t1.lane')->from(TABLE_KANBANCELL)->alias('t1')
|
||||
->leftJoin(TABLE_KANBANLANE)->alias('t2')->on('t1.lane=t2.id')
|
||||
->where('t1.type')->eq($fromLane->type)
|
||||
->andWhere('t1.id')->ne($fromCell->id)
|
||||
->andWhere('t2.region')->eq($fromLane->region)
|
||||
->andWhere('t1.cards')->like("%,$cardID,%")
|
||||
->fetchAll('id');
|
||||
|
||||
$kanbanID = $kanbanID == 0 ? $toCell->kanban : $kanbanID;
|
||||
foreach($fromCells as $fromCell)
|
||||
{
|
||||
$fromCellCards = explode(',', $fromCell->cards);
|
||||
$fromCellCards = array_unique($fromCellCards);
|
||||
$fromCellCards = array_filter($fromCellCards);
|
||||
$fromCellCards = implode(',', $fromCellCards);
|
||||
$fromCardList = str_replace(",$cardID,", ',', ",$fromCellCards,");
|
||||
if($fromCardList == ',') $fromCardList = '';
|
||||
$this->dao->update(TABLE_KANBANCELL)->set('cards')->eq($fromCardList)->where('id')->eq($fromCell->id)->exec();
|
||||
}
|
||||
|
||||
/* Add cardID to toCell. */
|
||||
$toCell = $this->dao->select('*')->from(TABLE_KANBANCELL)->where('lane')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->fetch();
|
||||
$toCellCards = $this->dao->select('cards')->from(TABLE_KANBANCELL)->where('lane')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->fetch('cards');
|
||||
$kanbanID = $kanbanID == 0 ? $toCell->kanban : $kanbanID;
|
||||
if(!$toCell) $this->addKanbanCell($kanbanID, $toLaneID, $toColID, 'common');
|
||||
|
||||
$fromCardList = str_replace(",$cardID,", ',', $fromCellCards);
|
||||
$toCardList = rtrim($toCellCards, ',') . ",$cardID,";
|
||||
|
||||
if($fromCardList == ',') $fromCardList = '';
|
||||
$this->dao->update(TABLE_KANBANCELL)->set('cards')->eq($fromCardList)->where('`column`')->eq($fromColID)->andWhere('lane')->eq($fromLaneID)->exec();
|
||||
$toCardList = rtrim($toCellCards, ',') . ",$cardID,";
|
||||
$this->dao->update(TABLE_KANBANCELL)->set('cards')->eq($toCardList)->where('`column`')->eq($toColID)->andWhere('lane')->eq($toLaneID)->exec();
|
||||
}
|
||||
|
||||
|
||||
@@ -336,7 +336,7 @@ EOF;
|
||||
|
||||
if($type == 'assignedBy')
|
||||
{
|
||||
$stories = $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'story');
|
||||
$stories = $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, 'story');
|
||||
}
|
||||
elseif($type == 'bysearch')
|
||||
{
|
||||
@@ -400,7 +400,7 @@ EOF;
|
||||
|
||||
if($type == 'assignedBy')
|
||||
{
|
||||
$stories = $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'requirement');
|
||||
$stories = $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, 'requirement');
|
||||
}
|
||||
elseif($type == 'bysearch')
|
||||
{
|
||||
@@ -468,7 +468,7 @@ EOF;
|
||||
/* Get tasks. */
|
||||
if($type == 'assignedBy')
|
||||
{
|
||||
$tasks = $this->my->getAssignedByMe($this->app->user->account, 0, $pager, $sort, 0, 'task');
|
||||
$tasks = $this->my->getAssignedByMe($this->app->user->account, 0, $pager, $sort, 'task');
|
||||
}
|
||||
elseif($type == 'bySearch')
|
||||
{
|
||||
@@ -571,7 +571,7 @@ EOF;
|
||||
$sort = common::appendOrder($orderBy);
|
||||
if($type == 'assignedBy')
|
||||
{
|
||||
$bugs = $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'bug');
|
||||
$bugs = $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, 'bug');
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -877,7 +877,7 @@ EOF;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->type = $type;
|
||||
$this->view->param = $param;
|
||||
$this->view->issues = $type == 'assignedBy' ? $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'issue') : $this->loadModel('issue')->getUserIssues($type, $queryID, $this->app->user->account, $orderBy, $pager);
|
||||
$this->view->issues = $type == 'assignedBy' ? $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, 'issue') : $this->loadModel('issue')->getUserIssues($type, $queryID, $this->app->user->account, $orderBy, $pager);
|
||||
|
||||
$this->view->projectList = $this->loadModel('project')->getPairsByProgram();
|
||||
|
||||
@@ -911,7 +911,7 @@ EOF;
|
||||
/* Get risks by type*/
|
||||
if($type == 'assignedBy')
|
||||
{
|
||||
$risks = $this->my->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'risk');
|
||||
$risks = $this->my->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, 'risk');
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1002,7 +1002,7 @@ EOF;
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
$ncList = $browseType == 'assignedBy' ? $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'nc') : $this->my->getNcList($browseType, $orderBy, $pager, 'active');
|
||||
$ncList = $browseType == 'assignedBy' ? $this->loadModel('my')->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, 'nc') : $this->my->getNcList($browseType, $orderBy, $pager, 'active');
|
||||
|
||||
foreach($ncList as $nc) $ncIdList[] = $nc->id;
|
||||
$this->session->set('ncIdList', isset($ncIdList) ? $ncIdList : '');
|
||||
|
||||
@@ -21,3 +21,9 @@ td.delayed {background: #e84e0f !important; color: white;}
|
||||
|
||||
html[lang="en"] .c-date {width: 80px;}
|
||||
html[lang="en"] .c-user-short {width: 88px;}
|
||||
[lang^='de'] .c-user-short, [lang^='fr'] .c-user-short {width: 75px;}
|
||||
[lang^='de'] .c-date, [lang^='fr'] .c-date {width: 100px;}
|
||||
[lang^='de'] .c-user, [lang^='fr'] .c-user {width: 118px;}
|
||||
[lang^='de'] .c-hours.consumed {width: 70px;}
|
||||
[lang^='de'] .c-hours.estimate {width: 75px;}
|
||||
[lang^='de'] .c-project {width: 100px;}
|
||||
|
||||
+5
-5
@@ -322,7 +322,7 @@ class myModel extends model
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getAssignedByMe($account, $limit = 0, $pager = null, $orderBy = "id_desc", $projectID = 0, $objectType = '')
|
||||
public function getAssignedByMe($account, $limit = 0, $pager = null, $orderBy = "id_desc", $objectType = '')
|
||||
{
|
||||
$module = $objectType == 'requirement' ? 'story' : $objectType;
|
||||
$this->loadModel($module);
|
||||
@@ -550,7 +550,7 @@ class myModel extends model
|
||||
$taskIDList = array();
|
||||
if($moduleName == 'contributeTask')
|
||||
{
|
||||
$tasksAssignedByMe = $this->getAssignedByMe($account, 0, $pager, $orderBy, 0, 'task');
|
||||
$tasksAssignedByMe = $this->getAssignedByMe($account, 0, '', $orderBy, 'task');
|
||||
foreach($tasksAssignedByMe as $taskID => $task)
|
||||
{
|
||||
$taskIDList[$taskID] = $taskID;
|
||||
@@ -725,7 +725,7 @@ class myModel extends model
|
||||
|
||||
if($type == 'contribute')
|
||||
{
|
||||
$assignedByMe = $this->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'risk');
|
||||
$assignedByMe = $this->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, 'risk');
|
||||
|
||||
$risks = $this->dao->select('*')->from(TABLE_RISK)
|
||||
->where($riskQuery)
|
||||
@@ -822,7 +822,7 @@ class myModel extends model
|
||||
$storyIDList = array();
|
||||
if($type == 'contribute')
|
||||
{
|
||||
$storiesAssignedByMe = $this->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'story');
|
||||
$storiesAssignedByMe = $this->getAssignedByMe($this->app->user->account, '', '', $orderBy, 'story');
|
||||
foreach($storiesAssignedByMe as $storyID => $story)
|
||||
{
|
||||
$storyIDList[$storyID] = $storyID;
|
||||
@@ -941,7 +941,7 @@ class myModel extends model
|
||||
$requirementIDList = array();
|
||||
if($type == 'contribute')
|
||||
{
|
||||
$requirementsAssignedByMe = $this->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, '', 'requirement');
|
||||
$requirementsAssignedByMe = $this->getAssignedByMe($this->app->user->account, '', $pager, $orderBy, 'requirement');
|
||||
foreach($requirementsAssignedByMe as $requirementID => $requirement)
|
||||
{
|
||||
$requirementIDList[$requirementID] = $requirementID;
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<?php if($action->objectType == 'meeting') $tab = $action->project ? "data-app='project'" : "data-app='my'";?>
|
||||
<span class='label-name'>
|
||||
<?php
|
||||
if(($config->edition == 'max' and strpos($config->action->assetType, $action->objectType) !== false) and empty($action->objectName))
|
||||
if(($config->edition == 'max' and strpos($config->action->assetType, ",{$action->objectType},") !== false) and empty($action->objectName))
|
||||
{
|
||||
echo '#' . $action->objectID;
|
||||
}
|
||||
|
||||
@@ -78,8 +78,8 @@
|
||||
<?php if($type != 'finishedBy'): ?>
|
||||
<th class='c-user'><?php common::printOrderLink('finishedBy', $orderBy, $vars, $lang->task->finishedBy);?></th>
|
||||
<?php endif;?>
|
||||
<th class='c-hours'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->task->estimateAB);?></th>
|
||||
<th class='c-hours'><?php common::printOrderLink('consumed', $orderBy, $vars, $lang->task->consumedAB);?></th>
|
||||
<th class='c-hours estimate'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->task->estimateAB);?></th>
|
||||
<th class='c-hours consumed'><?php common::printOrderLink('consumed', $orderBy, $vars, $lang->task->consumedAB);?></th>
|
||||
<th class='c-hours'><?php common::printOrderLink('left', $orderBy, $vars, $lang->task->leftAB);?></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>
|
||||
|
||||
@@ -43,14 +43,12 @@
|
||||
<?php
|
||||
$vars = "mode=$mode&type=$type¶m=$param&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID";
|
||||
$this->app->loadLang('testtask');
|
||||
$canBatchRun = (common::hasPriv('testtask', 'batchRun') and $type == 'assigntome');
|
||||
$canBatchEdit = (common::hasPriv('testcase', 'batchEdit') and $type == 'assigntome');
|
||||
$canBatchAction = ($canBatchRun or $canBatchEdit);
|
||||
$canBatchEdit = (common::hasPriv('testcase', 'batchEdit') and $type == 'assigntome');
|
||||
?>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="<?php echo $canBatchAction ? 'w-100px' : 'w-50px';?>">
|
||||
<?php if($canBatchAction):?>
|
||||
<th class="<?php echo $canBatchEdit ? 'w-100px' : 'w-50px';?>">
|
||||
<?php if($canBatchEdit):?>
|
||||
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
|
||||
<label></label>
|
||||
</div>
|
||||
@@ -80,7 +78,7 @@
|
||||
?>
|
||||
<tr>
|
||||
<td class="c-id">
|
||||
<?php if($canBatchAction):?>
|
||||
<?php if($canBatchEdit):?>
|
||||
<div class="checkbox-primary">
|
||||
<input type='checkbox' name='caseIDList[]' value='<?php echo $case->id;?>' <?php if(!$canBeChanged) echo 'disabled';?> />
|
||||
<label></label>
|
||||
@@ -120,7 +118,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-footer">
|
||||
<?php if($canBatchAction):?>
|
||||
<?php if($canBatchEdit):?>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<?php endif;?>
|
||||
<div class="table-actions btn-toolbar">
|
||||
@@ -131,12 +129,6 @@
|
||||
$misc = "data-form-action='$actionLink'";
|
||||
echo html::commonButton($lang->edit, $misc);
|
||||
}
|
||||
if($canBatchRun)
|
||||
{
|
||||
$actionLink = $this->createLink('testtask', 'batchRun', 'productID=0');
|
||||
$misc = "data-form-action='$actionLink'";
|
||||
echo html::commonButton($lang->testtask->runCase, $misc);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
|
||||
@@ -32,7 +32,7 @@ $(function()
|
||||
}
|
||||
else
|
||||
{
|
||||
$.apps.open(createLink('execution', 'create', 'projectID=' + projectID + '&executionID=©ExecutionID=&planID=' + planID + '&confirm=&productID=' + productID), 'project')
|
||||
$.apps.open(createLink('execution', 'create', 'projectID=' + projectID + '&executionID=©ExecutionID=&planID=' + planID + '&confirm=&productID=' + productID), 'execution')
|
||||
}
|
||||
$('#projects').modal('hide');
|
||||
});
|
||||
|
||||
@@ -86,6 +86,18 @@ class programplan extends control
|
||||
$plans = $this->programplan->getDataForGantt($projectID, $this->productID, $baselineID, $selectCustom, false);
|
||||
}
|
||||
|
||||
if($type == 'assignedTo')
|
||||
{
|
||||
$owner = $this->app->user->account;
|
||||
$module = 'programplan';
|
||||
$section = 'browse';
|
||||
$object = 'stageCustom';
|
||||
$selectCustom = $this->loadModel('setting')->getItem("owner={$owner}&module={$module}§ion={$section}&key={$object}");
|
||||
if(strpos($selectCustom, 'date') !== false) $dateDetails = 0;
|
||||
|
||||
$plans = $this->programplan->getDataForGanttGroupByAssignedTo($projectID, $this->productID, $baselineID, $selectCustom, false);
|
||||
}
|
||||
|
||||
if($type == 'lists')
|
||||
{
|
||||
$sort = common::appendOrder($orderBy);
|
||||
@@ -103,6 +115,7 @@ class programplan extends control
|
||||
$this->view->selectCustom = $selectCustom;
|
||||
$this->view->dateDetails = $dateDetails;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->ganttType = $type;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -237,4 +250,42 @@ class programplan extends control
|
||||
$response['message'] = '';
|
||||
return $this->send($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save task drag position.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxSaveTaskDrag()
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
if(!isset($_POST['id']) or empty($_POST['id'])) return $this->send(array('result' => 'fail', 'message' => ''));
|
||||
$objectID = $_POST['id'];
|
||||
|
||||
$this->loadModel('task')->saveTaskDrag($objectID, $_POST['type']);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
return $this->send(array('result' => 'success'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save task drag action.
|
||||
*
|
||||
* @param int $productID
|
||||
*
|
||||
* @access public
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxSaveGanttMove($productID = 0)
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$this->loadModel('task')->saveTaskMove($productID);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
return $this->send(array('result' => 'success'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
$lang->programplan->common = 'Program Plan';
|
||||
$lang->programplan->browse = 'Program Plan';
|
||||
$lang->programplan->gantt = 'Gantt Chart';
|
||||
$lang->programplan->ganttEdit = 'Gantt Edit';
|
||||
$lang->programplan->list = 'Stage List';
|
||||
$lang->programplan->create = 'Create';
|
||||
$lang->programplan->edit = 'Edit';
|
||||
@@ -84,3 +85,4 @@ $lang->programplan->error->createdTask = 'The task has been decomposed. Sub
|
||||
$lang->programplan->error->parentWorkload = 'The sum of the workload of the child phase cannot be greater than that of the parent phase: %s.';
|
||||
$lang->programplan->error->parentDuration = 'The planned start and planned completion of the child phase cannot exceed the parent phase.';
|
||||
$lang->programplan->error->sameName = 'Stage name cannot be the same!';
|
||||
$lang->programplan->error->taskDrag = 'The %s task cannot be dragged';
|
||||
@@ -12,6 +12,7 @@
|
||||
$lang->programplan->common = 'Program Plan';
|
||||
$lang->programplan->browse = 'Gantt Chart';
|
||||
$lang->programplan->gantt = 'Gantt Chart';
|
||||
$lang->programplan->ganttEdit = 'Gantt Edit';
|
||||
$lang->programplan->list = 'Stage List';
|
||||
$lang->programplan->create = 'Create';
|
||||
$lang->programplan->edit = 'Edit';
|
||||
@@ -84,3 +85,4 @@ $lang->programplan->error->createdTask = 'The task is decomposed. Sub stages
|
||||
$lang->programplan->error->parentWorkload = 'The sum of the workload in the sub stage cannot be > that in the parent stage: %s.';
|
||||
$lang->programplan->error->parentDuration = 'The planned start and planned completion of the child phase cannot exceed the parent phase.';
|
||||
$lang->programplan->error->sameName = 'Stage name cannot be the same!';
|
||||
$lang->programplan->error->taskDrag = 'The %s task cannot be dragged';
|
||||
@@ -12,6 +12,7 @@
|
||||
$lang->programplan->common = 'Program Plan';
|
||||
$lang->programplan->browse = 'Program Plan';
|
||||
$lang->programplan->gantt = 'Gantt Chart';
|
||||
$lang->programplan->ganttEdit = 'Gantt Edit';
|
||||
$lang->programplan->list = 'Stage List';
|
||||
$lang->programplan->create = 'Create';
|
||||
$lang->programplan->edit = 'Edit';
|
||||
@@ -84,3 +85,4 @@ $lang->programplan->error->createdTask = 'The task has been decomposed. Sub
|
||||
$lang->programplan->error->parentWorkload = 'The sum of the workload of the child phase cannot be greater than that of the parent phase: %s.';
|
||||
$lang->programplan->error->parentDuration = 'The planned start and planned completion of the child phase cannot exceed the parent phase.';
|
||||
$lang->programplan->error->sameName = 'Stage name cannot be the same!';
|
||||
$lang->programplan->error->taskDrag = 'The %s task cannot be dragged';
|
||||
@@ -12,6 +12,7 @@
|
||||
$lang->programplan->common = '项目阶段';
|
||||
$lang->programplan->browse = '浏览甘特图';
|
||||
$lang->programplan->gantt = '甘特图';
|
||||
$lang->programplan->ganttEdit = '甘特图编辑';
|
||||
$lang->programplan->list = '阶段列表';
|
||||
$lang->programplan->create = '设置阶段';
|
||||
$lang->programplan->edit = '编辑';
|
||||
@@ -84,3 +85,9 @@ $lang->programplan->error->createdTask = '已分解任务,不可添加子
|
||||
$lang->programplan->error->parentWorkload = '子阶段的工作量之和不能大于父阶段的工作量:%s';
|
||||
$lang->programplan->error->parentDuration = '子阶段计划开始、计划完成不能超过父阶段';
|
||||
$lang->programplan->error->sameName = '阶段名称不能相同!';
|
||||
$lang->programplan->error->taskDrag = '%s的任务不可以拖动';
|
||||
$lang->programplan->error->planDrag = '%s的阶段不可以拖动';
|
||||
|
||||
|
||||
$lang->programplan->ganttBrowseType['gantt'] = '按阶段分组';
|
||||
$lang->programplan->ganttBrowseType['assignedTo'] = '按指派给分组';
|
||||
|
||||
@@ -191,17 +191,17 @@ class programplanModel extends model
|
||||
$data->status = $this->processStatus('execution', $plan);
|
||||
$data->begin = $start;
|
||||
$data->deadline = $end;
|
||||
$data->realBegan = helper::isZeroDate($plan->realBegan) ? '' : substr($plan->realBegan, 0, 10);
|
||||
$data->realEnd = helper::isZeroDate($plan->realEnd) ? '' : substr($plan->realEnd, 0, 10);
|
||||
$data->realBegan = helper::isZeroDate($plan->realBegan) ? '' : $plan->realBegan;
|
||||
$data->realEnd = helper::isZeroDate($plan->realEnd) ? '' : $plan->realEnd;
|
||||
$data->parent = $plan->grade == 1 ? 0 :$plan->parent;
|
||||
$data->open = true;
|
||||
$data->start_date = $data->realBegan ? $data->realBegan : $data->begin;
|
||||
$data->endDate = $data->realEnd ? $data->realEnd : $data->deadline;
|
||||
$data->duration = 0;
|
||||
$data->duration = 1;
|
||||
|
||||
if($data->endDate > $data->start_date) $data->duration = helper::diffDate($data->endDate, $data->start_date) + 1;
|
||||
if($data->start_date) $data->start_date = date('d-m-Y', strtotime($data->start_date));
|
||||
if($data->start_date == '' or $data->endDate == '') $data->duration = 0;
|
||||
if($data->start_date == '' or $data->endDate == '') $data->duration = 1;
|
||||
|
||||
$datas['data'][$plan->id] = $data;
|
||||
$stageIndex[$plan->id] = array('planID' => $plan->id, 'parent' => $plan->parent, 'progress' => array('totalConsumed' => 0, 'totalReal' => 0));
|
||||
@@ -218,7 +218,7 @@ class programplanModel extends model
|
||||
|
||||
if(empty($selectCustom)) $selectCustom = $this->loadModel('setting')->getItem("owner={$owner}&module={$module}§ion={$section}&key={$object}");
|
||||
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)->where('deleted')->eq(0)->andWhere('execution')->in($planIdList)->fetchAll('id');
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)->where('deleted')->eq(0)->andWhere('execution')->in($planIdList)->orderBy('execution_asc, order_asc, id_desc')->fetchAll('id');
|
||||
$taskTeams = $this->dao->select('root,account')->from(TABLE_TEAM)->where('type')->eq('task')->andWhere('root')->in(array_keys($tasks))->fetchGroup('root', 'account');
|
||||
$users = $this->loadModel('user')->getPairs('noletter');
|
||||
|
||||
@@ -242,8 +242,8 @@ class programplanModel extends model
|
||||
|
||||
$estStart = helper::isZeroDate($task->estStarted) ? '' : $task->estStarted;
|
||||
$estEnd = helper::isZeroDate($task->deadline) ? '' : $task->deadline;
|
||||
$realBegan = helper::isZeroDate($task->realStarted) ? '' : substr($task->realStarted, 0, 10);
|
||||
$realEnd = (in_array($task->status, array('done', 'closed')) and !helper::isZeroDate($task->finishedDate)) ? substr($task->finishedDate, 0, 10) : '';
|
||||
$realBegan = helper::isZeroDate($task->realStarted) ? '' : $task->realStarted;
|
||||
$realEnd = (in_array($task->status, array('done', 'closed')) and !helper::isZeroDate($task->finishedDate)) ? $task->finishedDate : '';
|
||||
|
||||
$start = $realBegan ? $realBegan : $estStart;
|
||||
$end = $realEnd ? $realEnd : $estEnd;
|
||||
@@ -272,7 +272,7 @@ class programplanModel extends model
|
||||
$data->taskProgress = ($progress * 100) . '%';
|
||||
$data->start_date = $start;
|
||||
$data->endDate = $end;
|
||||
$data->duration = 0;
|
||||
$data->duration = 1;
|
||||
|
||||
/* If multi task then show the teams. */
|
||||
if($task->mode == 'multi' and !empty($taskTeams[$task->id]))
|
||||
@@ -285,7 +285,7 @@ class programplanModel extends model
|
||||
|
||||
if($data->endDate > $data->start_date) $data->duration = helper::diffDate($data->endDate, $data->start_date) + 1;
|
||||
if($data->start_date) $data->start_date = date('d-m-Y', strtotime($data->start_date));
|
||||
if($data->start_date == '' or $data->endDate == '') $data->duration = 0;
|
||||
if($data->start_date == '' or $data->endDate == '') $data->duration = 1;
|
||||
|
||||
if(strpos($selectCustom, 'task') !== false) $datas['data'][$data->id] = $data;
|
||||
foreach($stageIndex as $index => $stage)
|
||||
@@ -333,6 +333,193 @@ class programplanModel extends model
|
||||
return $returnJson ? json_encode($datas) : $datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gantt data group by assigned.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param int $productID
|
||||
* @param int $baselineID
|
||||
* @param string $selectCustom
|
||||
* @param bool $returnJson
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDataForGanttGroupByAssignedTo($executionID, $productID, $baselineID = 0, $selectCustom = '', $returnJson = true)
|
||||
{
|
||||
$plans = $this->getStage($executionID, $productID);
|
||||
|
||||
$datas = array();
|
||||
$planIdList = array();
|
||||
$isMilestone = "<icon class='icon icon-flag icon-sm red'></icon> ";
|
||||
$stageIndex = array();
|
||||
|
||||
foreach($plans as $plan) $planIdList[$plan->id] = $plan->id;
|
||||
|
||||
$taskSign = "<span class='task-label'>[ T ] </span>";
|
||||
$taskPri = "<span class='label-pri label-pri-%s' title='%s'>%s</span> ";
|
||||
|
||||
/* Judge whether to display tasks under the stage. */
|
||||
$owner = $this->app->user->account;
|
||||
$module = 'programplan';
|
||||
$section = 'browse';
|
||||
$object = 'stageCustom';
|
||||
if(empty($selectCustom)) $selectCustom = $this->loadModel('setting')->getItem("owner={$owner}&module={$module}§ion={$section}&key={$object}");
|
||||
|
||||
$tasksGroup = $this->dao->select('*')->from(TABLE_TASK)->where('deleted')->eq(0)->andWhere('execution')->in($planIdList)->fetchGroup('assignedTo','id');
|
||||
$users = $this->loadModel('user')->getPairs('noletter');
|
||||
|
||||
$tasksMap = array();
|
||||
foreach($tasksGroup as $group => $tasks)
|
||||
{
|
||||
foreach($tasks as $id => $task)
|
||||
{
|
||||
if($task->mode == 'multi')
|
||||
{
|
||||
$team = $this->dao->select('t1.*,t2.realname')->from(TABLE_TEAM)->alias('t1')
|
||||
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account = t2.account')
|
||||
->where('t1.root')->eq($id)->andWhere('t1.type')->eq('task')->orderBy('t1.order')->fetchAll('account');
|
||||
foreach($team as $account => $member)
|
||||
{
|
||||
if($account == $group) continue;
|
||||
if(!isset($taskGroups[$account])) $taskGroups[$account] = array();
|
||||
|
||||
$taskGroups[$account][$id] = clone $task;
|
||||
$taskGroups[$account][$id]->id = $id . '_' . $account;
|
||||
$taskGroups[$account][$id]->realID = $id;
|
||||
$taskGroups[$account][$id]->assignedTo = $account;
|
||||
$taskGroups[$account][$id]->realname = $member->realname;
|
||||
}
|
||||
}
|
||||
|
||||
$tasksMap[$task->id] = $task;
|
||||
}
|
||||
}
|
||||
|
||||
$groupID = 0;
|
||||
foreach($tasksGroup as $group => $tasks)
|
||||
{
|
||||
$groupID --;
|
||||
$groupName = $group;
|
||||
$groupName = zget($users, $group);
|
||||
$dataGroup = new stdclass();
|
||||
$dataGroup->id = $groupID;
|
||||
$dataGroup->type = 'group';
|
||||
$dataGroup->text = $groupName;
|
||||
$dataGroup->percent = '';
|
||||
$dataGroup->attribute = '';
|
||||
$dataGroup->milestone = '';
|
||||
$dataGroup->owner_id = $group;
|
||||
$dataGroup->status = '';
|
||||
$dataGroup->begin = '';
|
||||
$dataGroup->deadline = '';
|
||||
$dataGroup->realBegan = '';
|
||||
$dataGroup->realEnd = '';
|
||||
$dataGroup->parent = 0;
|
||||
$dataGroup->open = true;
|
||||
$dataGroup->progress = '';
|
||||
$dataGroup->taskProgress = '';
|
||||
|
||||
$groupKey = $groupID . $group;
|
||||
$datas['data'][$groupKey] = $dataGroup;
|
||||
|
||||
$realStartDate = array();
|
||||
$realEndDate = array();
|
||||
$totalTask = count($tasks);
|
||||
foreach($tasks as $taskID => $task)
|
||||
{
|
||||
$execution = zget($plans, $task->execution, array());
|
||||
|
||||
$priIcon = sprintf($taskPri, $task->pri, $task->pri, $task->pri);
|
||||
|
||||
$estStart = helper::isZeroDate($task->estStarted) ? '' : $task->estStarted;
|
||||
$estEnd = helper::isZeroDate($task->deadline) ? '' : $task->deadline;
|
||||
$realBegan = helper::isZeroDate($task->realStarted) ? '' : $task->realStarted;
|
||||
$realEnd = (in_array($task->status, array('done', 'closed')) and !helper::isZeroDate($task->finishedDate)) ? $task->finishedDate : '';
|
||||
|
||||
$start = $realBegan ? $realBegan : $estStart;
|
||||
$end = $realEnd ? $realEnd : $estEnd;
|
||||
if(empty($start) and $execution) $start = $execution->begin;
|
||||
if(empty($end) and $execution) $end = $execution->end;
|
||||
if($start > $end) $end = $start;
|
||||
|
||||
$data = new stdclass();
|
||||
$data->id = $task->id;
|
||||
$data->type = 'task';
|
||||
$data->text = $taskSign . $priIcon . $task->name;
|
||||
$data->percent = '';
|
||||
$data->status = $this->processStatus('task', $task);
|
||||
$data->owner_id = $task->assignedTo;
|
||||
$data->attribute = '';
|
||||
$data->milestone = '';
|
||||
$data->begin = $start;
|
||||
$data->deadline = $end;
|
||||
$data->realBegan = $realBegan;
|
||||
$data->realEnd = $realEnd;
|
||||
$data->pri = $task->pri;
|
||||
$data->parent = ($task->parent > 0 and $task->assignedTo != '' and !empty($tasksMap[$task->parent]->assignedTo)) ? $task->parent : $groupID;
|
||||
$data->open = true;
|
||||
$progress = $task->consumed ? round($task->consumed / ($task->left + $task->consumed), 3) : 0;
|
||||
$data->progress = $progress;
|
||||
$data->taskProgress = ($progress * 100) . '%';
|
||||
$data->start_date = $start;
|
||||
$data->endDate = $end;
|
||||
$data->duration = 1;
|
||||
|
||||
if($data->endDate > $data->start_date) $data->duration = helper::diffDate($data->endDate, $data->start_date) + 1;
|
||||
|
||||
if($data->start_date) $data->start_date = date('d-m-Y', strtotime($data->start_date));
|
||||
if($data->start_date == '' or $data->endDate == '') $data->duration = 1;
|
||||
|
||||
if(strpos($selectCustom, 'task') !== false) $datas['data'][$data->id] = $data;
|
||||
|
||||
if(!empty($start)) $realStartDate[] = strtotime($start);
|
||||
if(!empty($end)) $realEndDate[] = strtotime($end);
|
||||
|
||||
if(isset($stageIndex[$groupKey]['totalConsumed']))
|
||||
{
|
||||
$stageIndex[$groupKey]['totalConsumed'] += $task->consumed;
|
||||
$stageIndex[$groupKey]['totalReal'] += $task->left + $task->consumed;
|
||||
}
|
||||
else
|
||||
{
|
||||
$stageIndex[$groupKey]['totalConsumed'] = $task->consumed;
|
||||
$stageIndex[$groupKey]['totalReal'] = $task->left + $task->consumed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate group realBegan and realEnd. */
|
||||
if(!empty($realStartDate)) $datas['data'][$groupKey]->realBegan = date('Y-m-d H:i:s', min($realStartDate));
|
||||
if(!empty($realEndDate) and (count($realEndDate) == $totalTask)) $datas['data'][$groupKey]->realEnd = date('Y-m-d H:i:s', max($realEndDate));
|
||||
}
|
||||
|
||||
/* Calculate the progress of the phase. */
|
||||
foreach($stageIndex as $index => $stage)
|
||||
{
|
||||
$progress = empty($stage['totalReal']) ? 0 : round($stage['totalConsumed'] / $stage['totalReal'], 3);
|
||||
$datas['data'][$index]->progress = $progress;
|
||||
|
||||
$progress = ($progress * 100) . '%';
|
||||
$datas['data'][$index]->taskProgress = $progress;
|
||||
}
|
||||
|
||||
$datas['links'] = array();
|
||||
if($this->config->edition != 'open')
|
||||
{
|
||||
$relations = $this->dao->select('*')->from(TABLE_RELATIONOFTASKS)->where('execution')->in($planIdList)->orderBy('task,pretask')->fetchAll();
|
||||
foreach($relations as $relation)
|
||||
{
|
||||
$link['source'] = $relation->execution . '-' . $relation->pretask;
|
||||
$link['target'] = $relation->execution . '-' . $relation->task;
|
||||
$link['type'] = $this->config->execution->gantt->linkType[$relation->condition][$relation->action];
|
||||
$datas['links'][] = $link;
|
||||
}
|
||||
}
|
||||
|
||||
$datas['data'] = isset($datas['data']) ? array_values($datas['data']) : array();
|
||||
|
||||
return $returnJson ? json_encode($datas) : $datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total percent.
|
||||
*
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<?php if($type == 'gantt') include './gantt.html.php';?>
|
||||
<?php if($type == 'gantt' or $type == 'assignedTo') include './gantt.html.php';?>
|
||||
<?php if($type == 'lists') include './list.html.php';?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
|
||||
@@ -60,16 +60,19 @@ form {display: block; margin-top: 0em; margin-block-end: 1em;}
|
||||
#mainContent.loading #ganttContainer {padding: 40px;}
|
||||
#mainContent.loading .scrollVer_cell,
|
||||
#mainContent.loading .scrollVer_cell {display: none;}
|
||||
#
|
||||
.gantt-fullscreen #header,
|
||||
.gantt-fullscreen #mainMenu,
|
||||
.gantt-fullscreen #footer {display: none!important;}
|
||||
.gantt-fullscreen #mainContent {position: fixed; top: 0; right: 0; bottom: 0; left: 0}
|
||||
.gantt_grid_head_cell.gantt_grid_head_text{overflow:visible;}
|
||||
|
||||
</style>
|
||||
<?php js::set('customUrl', $this->createLink('programplan', 'ajaxCustom'));?>
|
||||
<?php js::set('dateDetails', $dateDetails);?>
|
||||
<?php js::set('module', $app->rawModule);?>
|
||||
<?php js::set('method', $app->rawMethod);?>
|
||||
<?php js::set('ganttType', $ganttType);?>
|
||||
<?php js::set('canGanttEdit', common::hasPriv('programplan', 'ganttEdit'));?>
|
||||
<div id='mainContent' class='main-content load-indicator' data-loading='<?php echo $lang->programplan->exporting;?>'>
|
||||
<form class="main-form form-ajax not-watch">
|
||||
<div class="example">
|
||||
@@ -93,6 +96,16 @@ form {display: block; margin-top: 0em; margin-block-end: 1em;}
|
||||
</div>
|
||||
<?php $fileName = "gantt-export-{$projectID}";?>
|
||||
<a id='ganttDownload' target='hiddenwin' download='<?php echo "{$fileName}.png";?>'></a>
|
||||
<?php
|
||||
$typeHtml = '<div class="btn-group">';
|
||||
$typeHtml .= '<button class="btn btn-link" data-toggle="dropdown"><span class="text">' . $lang->programplan->ganttBrowseType[$ganttType] . '</span> <span class="caret"></span></button>';
|
||||
$typeHtml .= '<ul class="dropdown-menu">';
|
||||
foreach($lang->programplan->ganttBrowseType as $browseType => $typeName)
|
||||
{
|
||||
$typeHtml .= '<li ' . ($ganttType == $browseType ? "class='active'" : '') . '>' . html::a($this->createLink('programplan', 'browse', "projectID=$projectID&productID=$productID&type=$browseType"), $typeName) . '</li>';
|
||||
}
|
||||
$typeHtml .= '</ul></div>';
|
||||
?>
|
||||
</div>
|
||||
<script>
|
||||
var scriptLoadedMap = {};
|
||||
@@ -381,6 +394,67 @@ function exitHandler()
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate task drag. */
|
||||
function validateResources(id)
|
||||
{
|
||||
var task = gantt.getTask(id);
|
||||
var from = new Date(task.start_date),
|
||||
to = new Date(task.end_date);
|
||||
var status = task.status;
|
||||
var type = task.type;
|
||||
var statusLang = "<?php echo $lang->task->statusList['wait'];?>";
|
||||
flag = true;
|
||||
|
||||
/* Check status. */
|
||||
if(status !== statusLang)
|
||||
{
|
||||
if(type == 'task')
|
||||
{
|
||||
tipMsg = "<?php echo $lang->programplan->error->taskDrag;?>";
|
||||
}
|
||||
else
|
||||
{
|
||||
tipMsg = "<?php echo $lang->programplan->error->planDrag;?>";
|
||||
}
|
||||
new $.zui.Messager(tipMsg.replace('%s', status), {
|
||||
type: 'danger',
|
||||
icon: 'exclamation-sign'
|
||||
}).show();
|
||||
gantt.refreshData();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check data. */
|
||||
var postData = {
|
||||
'id' : type == 'task' ? task.id.split("-")[1] : task.id,
|
||||
'start_date': from.toLocaleDateString('en-CA'),
|
||||
'end_date' : to.toLocaleDateString('en-CA'),
|
||||
'type' : type
|
||||
};
|
||||
var link = createLink('programplan', 'ajaxSaveTaskDrag');
|
||||
/* Sync Close. */
|
||||
$.ajax({
|
||||
url: link,
|
||||
dataType: "json",
|
||||
async: false,
|
||||
data: postData,
|
||||
type: "post",
|
||||
success: function(response)
|
||||
{
|
||||
if(response.result == 'fail' && response.message)
|
||||
{
|
||||
new $.zui.Messager(response.message, {
|
||||
type: 'danger',
|
||||
icon: 'exclamation-sign'
|
||||
}).show();
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
$(function()
|
||||
{
|
||||
document.addEventListener('fullscreenchange', exitHandler);
|
||||
@@ -409,40 +483,46 @@ $(function()
|
||||
?>
|
||||
gantt.serverList("userList", <?php echo json_encode($userList);?>);
|
||||
|
||||
gantt.config.readonly = true;
|
||||
gantt.config.smart_rendering = true;
|
||||
gantt.config.smart_scales = true;
|
||||
gantt.config.static_background = true;
|
||||
gantt.config.show_task_cells = false;
|
||||
gantt.config.row_height = 25;
|
||||
gantt.config.min_column_width = 40;
|
||||
gantt.config.details_on_create = false;
|
||||
gantt.config.scales = [{unit: "year", step: 1, format: "%Y"}, {unit: 'day', step: 1, format: '%m-%d'}];
|
||||
gantt.config.scale_height = 22 * gantt.config.scales.length;
|
||||
gantt.config.duration_unit = "day";
|
||||
gantt.config.readonly = canGanttEdit ? false : true;
|
||||
gantt.config.details_on_dblclick = false;
|
||||
gantt.config.order_branch = ganttType == 'assignedTo' ? false : 'marker';
|
||||
gantt.config.drag_progress = false;
|
||||
gantt.config.drag_links = false;
|
||||
gantt.config.drag_move = ganttType == 'assignedTo' ? false : true;
|
||||
gantt.config.drag_resize = ganttType == 'assignedTo' ? false : true;
|
||||
gantt.config.smart_rendering = true;
|
||||
gantt.config.smart_scales = true;
|
||||
gantt.config.static_background = true;
|
||||
gantt.config.show_task_cells = false;
|
||||
gantt.config.row_height = 25;
|
||||
gantt.config.min_column_width = 40;
|
||||
gantt.config.details_on_create = false;
|
||||
gantt.config.scales = [{unit: "year", step: 1, format: "%Y"}, {unit: 'day', step: 1, format: '%m-%d'}];
|
||||
gantt.config.scale_height = 22 * gantt.config.scales.length;
|
||||
gantt.config.duration_unit = "day";
|
||||
|
||||
gantt.config.columns = [
|
||||
{name: 'text', width: '*', tree: true, resize: true, width:200},
|
||||
{name: 'status', align: 'center', resize: true, width: 80},
|
||||
{name: 'begin', align: 'center', resize: true, width: 80},
|
||||
{name: 'deadline', align: 'center', resize: true, width: 80},
|
||||
{name: 'duration', align: 'center', resize: true, width: 60},
|
||||
{name: 'percent', align: 'center', resize: true, width:70, template: function(plan)
|
||||
{name: 'text', width: '*', tree: true, resize: true, width:200},
|
||||
{name: 'status', align: 'center', resize: true, width: 80},
|
||||
{name: 'start_date', align: 'center', resize: true, width: 80},
|
||||
{name: 'end_date', align: 'center', resize: true, width: 80},
|
||||
{name: 'duration', align: 'center', resize: true, width: 60},
|
||||
{name: 'percent', align: 'center', resize: true, width:70, template: function(plan)
|
||||
{
|
||||
if(plan.percent) return Math.round(plan.percent) + '%';
|
||||
}
|
||||
},
|
||||
{name: 'taskProgress', align: 'center', resize: true, width: 60},
|
||||
{name: 'realBegan', align: 'center', resize: true, width: 80},
|
||||
{name: 'realEnd', align: 'center', width: 80}
|
||||
{name: 'realBegan', align: 'center', resize: true, width: 150},
|
||||
{name: 'realEnd', align: 'center', width: 150}
|
||||
];
|
||||
|
||||
gantt.locale.labels.column_text = "<?php echo $lang->programplan->name;?>";
|
||||
gantt.locale.labels.column_text = <?php echo json_encode($typeHtml);?>;
|
||||
gantt.locale.labels.column_status = "<?php echo $lang->statusAB;?>";
|
||||
gantt.locale.labels.column_percent = "<?php echo $lang->programplan->percentAB;?>";
|
||||
gantt.locale.labels.column_taskProgress = "<?php echo $lang->programplan->taskProgress;?>";
|
||||
gantt.locale.labels.column_begin = "<?php echo $lang->programplan->begin;?>";
|
||||
gantt.locale.labels.column_deadline = "<?php echo $lang->programplan->end;?>";
|
||||
gantt.locale.labels.column_start_date = "<?php echo $lang->programplan->begin;?>";
|
||||
gantt.locale.labels.column_end_date = "<?php echo $lang->programplan->end;?>";
|
||||
gantt.locale.labels.column_realBegan = "<?php echo $lang->programplan->realBegan;?>";
|
||||
gantt.locale.labels.column_realEnd = "<?php echo $lang->programplan->realEnd;?>";
|
||||
gantt.locale.labels.column_duration = "<?php echo $lang->programplan->duration;?>";
|
||||
@@ -488,7 +568,7 @@ $(function()
|
||||
{
|
||||
if(module == 'review' && method == 'assess')
|
||||
{
|
||||
gantt.config.layout = layout;
|
||||
gantt.config.layout = layout;
|
||||
gantt.init('ganttView');
|
||||
}
|
||||
gantt.expand();
|
||||
@@ -552,16 +632,45 @@ $(function()
|
||||
gantt.attachEvent('onTaskClick', function(id, e)
|
||||
{
|
||||
if($(e.srcElement).hasClass('gantt_close') || $(e.srcElement).hasClass('gantt_open')) return false;
|
||||
|
||||
/* The id of task item is like executionID-taskID. e.g. 1507-37829, 37829 is task id. */
|
||||
var position = id.indexOf('-');
|
||||
if(position < 0) return;
|
||||
|
||||
var taskID = parseInt(id.substring(position + 1));
|
||||
if(ganttType == 'assignedTo')
|
||||
{
|
||||
taskID = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The id of task item is like executionID-taskID. e.g. 1507-37829, 37829 is task id. */
|
||||
var position = id.indexOf('-');
|
||||
if(position < 0) return;
|
||||
var taskID = parseInt(id.substring(position + 1));
|
||||
}
|
||||
|
||||
if(!isNaN(taskID) && taskID > 0) taskModalTrigger.show({url: createLink('task', 'view', 'taskID=' + taskID, 'html', true)});
|
||||
});
|
||||
|
||||
gantt.attachEvent("onBeforeRowDragEnd", function(id, parent, tindex)
|
||||
{
|
||||
var task = gantt.getTask(id);
|
||||
var link = createLink('programplan', 'ajaxSaveGanttMove');
|
||||
|
||||
//prevent moving to another position.
|
||||
if(task.parent != parent || id.indexOf('-') == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$.ajax({
|
||||
url: link,
|
||||
dataType: "json",
|
||||
data: {id: id, type: task.type, index: tindex},
|
||||
type: "post",
|
||||
success: function(result){}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Make folder can open or close by click
|
||||
$('#ganttView').on('click', '.gantt_close,.gantt_open', function()
|
||||
{
|
||||
@@ -596,5 +705,11 @@ $(function()
|
||||
{
|
||||
setTimeout(function(){$('.gantt_tooltip').remove()}, 100);
|
||||
});
|
||||
|
||||
/* Link attachEvent onAfterTaskDrag */
|
||||
gantt.attachEvent("onBeforeTaskChanged", function(id, mode, task)
|
||||
{
|
||||
return validateResources(id);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
.future {display: inline-block;}
|
||||
.c-number {overflow: hidden; text-align: right !important; text-overflow: ellipsis; white-space: nowrap;}
|
||||
.text-remind {color: #ffa34d;}
|
||||
td.delayed {color: #fff; background: #e84e0f !important;}
|
||||
|
||||
@@ -192,7 +192,7 @@ class projectModel extends model
|
||||
|
||||
$project = $this->dao->select('*')->from(TABLE_PROJECT)
|
||||
->where('id')->eq($projectID)
|
||||
->beginIF($this->config->system == 'new')->andWhere('`type`')->in($type)->fi()
|
||||
->beginIF($this->config->systemMode == 'new')->andWhere('`type`')->in($type)->fi()
|
||||
->fetch();
|
||||
|
||||
if(!$project) return false;
|
||||
@@ -437,7 +437,7 @@ class projectModel extends model
|
||||
$progressList[$projectID] = $progress;
|
||||
}
|
||||
|
||||
return is_numeric($projectIDList) ? $progressList[$projectIDList] : $progressList;
|
||||
return is_numeric($projectIDList) ? (empty($progressList) ? 0 : $progressList[$projectIDList]) : $progressList;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -169,14 +169,16 @@ class releaseModel extends model
|
||||
else
|
||||
{
|
||||
$build = new stdclass();
|
||||
$build->project = $projectID;
|
||||
$build->product = (int)$productID;
|
||||
$build->branch = (int)$branch;
|
||||
$build->name = $release->name;
|
||||
$build->date = $release->date;
|
||||
$build->builder = $this->app->user->account;
|
||||
$build->desc = $release->desc;
|
||||
$build->execution = 0;
|
||||
$build->project = $projectID;
|
||||
$build->product = (int)$productID;
|
||||
$build->branch = (int)$branch;
|
||||
$build->name = $release->name;
|
||||
$build->date = $release->date;
|
||||
$build->builder = $this->app->user->account;
|
||||
$build->desc = $release->desc;
|
||||
$build->execution = 0;
|
||||
$build->createdBy = $this->app->user->account;
|
||||
$build->createdDate = helper::now();
|
||||
|
||||
$build = $this->loadModel('file')->processImgURL($build, $this->config->release->editor->create['id']);
|
||||
$this->app->loadLang('build');
|
||||
|
||||
@@ -4,3 +4,5 @@
|
||||
.main-actions .btn-toolbar .btn {padding-right: 6px; padding-left: 6px;}
|
||||
.btn-edit-comment {z-index: 100;}
|
||||
#legendRelated .table-data tbody>tr>th {width: 90px;}
|
||||
#legendStories .list-unstyled li a {padding: 6px;}
|
||||
[lang^='zh'] #legendStories .list-unstyled li a {padding: 6px 12px;}
|
||||
|
||||
@@ -794,7 +794,7 @@ class storyModel extends model
|
||||
->cleanFloat('estimate')
|
||||
->setDefault('assignedDate', $oldStory->assignedDate)
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('reviewedBy', '')
|
||||
->setDefault('reviewedBy', $oldStory->reviewedBy)
|
||||
->setDefault('mailto', '')
|
||||
->add('id', $storyID)
|
||||
->add('lastEditedDate', $now)
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<?php if(count($track) != 0):?>
|
||||
<?php $i = 1;?>
|
||||
<?php $i = 0;?>
|
||||
<?php foreach($track as $storyID => $story):?>
|
||||
<?php if($i != 1) echo '<tr>';?>
|
||||
<td>
|
||||
|
||||
@@ -19,4 +19,4 @@
|
||||
.c-leftAB {width: 60px;}
|
||||
.c-actions {width: 175px;}
|
||||
|
||||
#mainContent .main-actions .btn-toolbar .btn {padding-left: 7px; padding-right: 6px;}
|
||||
[lang^='de'] #mainContent .main-actions .btn-toolbar .btn {padding-left: 3px; padding-right: 3px;}
|
||||
|
||||
@@ -349,6 +349,8 @@ function toggleSelectTestStory()
|
||||
$('#testStoryBox').removeClass('hidden');
|
||||
$('#copyButton').addClass('hidden');
|
||||
$('.colorpicker').css('right', '0');
|
||||
$('#dataform .table-form>tbody>tr>th').css('width', '130px');
|
||||
$('[lang^="zh-"] #dataform .table-form>tbody>tr>th').css('width', '120px');
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -358,6 +360,7 @@ function toggleSelectTestStory()
|
||||
$('#estStarted').closest('tr').removeClass('hidden');
|
||||
$('#estimate').closest('.table-col').removeClass('hidden');
|
||||
$('#testStoryBox').addClass('hidden');
|
||||
$('#dataform .table-form>tbody>tr>th').css('width', '100px');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -352,3 +352,5 @@ $lang->task->report->finishedTasksPerDay->graph->xAxisName = 'Datum';
|
||||
|
||||
$lang->taskestimate = new stdclass();
|
||||
$lang->taskestimate->consumed = 'Schätzung';
|
||||
|
||||
$lang->task->overTime = 'The %s scheduled time has been exceeded, please modify the %s time first';
|
||||
@@ -352,3 +352,5 @@ $lang->task->report->finishedTasksPerDay->graph->xAxisName = 'Date';
|
||||
|
||||
$lang->taskestimate = new stdclass();
|
||||
$lang->taskestimate->consumed = 'Estimates';
|
||||
|
||||
$lang->task->overTime = 'The %s scheduled time has been exceeded, please modify the %s time first';
|
||||
@@ -352,3 +352,5 @@ $lang->task->report->finishedTasksPerDay->graph->xAxisName = 'Date';
|
||||
|
||||
$lang->taskestimate = new stdclass();
|
||||
$lang->taskestimate->consumed = 'Estimés';
|
||||
|
||||
$lang->task->overTime = 'The %s scheduled time has been exceeded, please modify the %s time first';
|
||||
@@ -352,3 +352,5 @@ $lang->task->report->finishedTasksPerDay->graph->xAxisName = '日期';
|
||||
|
||||
$lang->taskestimate = new stdclass();
|
||||
$lang->taskestimate->consumed = '工时';
|
||||
|
||||
$lang->task->overTime = '已超出%s计划时间,请先修改%s时间';
|
||||
+177
-2
@@ -3782,6 +3782,9 @@ class taskModel extends model
|
||||
*/
|
||||
public function buildNestedList($execution, $task, $isChild = false, $showmore = false, $users = array())
|
||||
{
|
||||
$this->app->loadLang('execution');
|
||||
|
||||
$today = helper::today();
|
||||
$showmore = $showmore ? 'showmore' : '';
|
||||
$trAttrs = "data-id='t$task->id'";
|
||||
if(!$isChild)
|
||||
@@ -3806,8 +3809,22 @@ class taskModel extends model
|
||||
$list .= '<td>' . zget($users, $task->assignedTo, '') . '</td>';
|
||||
$list .= "<td class='status-{$task->status}'>" . $this->processStatus('task', $task) . '</td>';
|
||||
$list .= '<td></td>';
|
||||
$list .= '<td>' . $task->estStarted . '</td>';
|
||||
$list .= '<td>' . $task->deadline . '</td>';
|
||||
$list .= helper::isZeroDate($task->estStarted) ? '<td></td>' : '<td>' . $task->estStarted . '</td>';
|
||||
if(!helper::isZeroDate($task->deadline))
|
||||
{
|
||||
if($task->status != 'done')
|
||||
{
|
||||
$list .= strtotime($today) > strtotime($task->deadline) ? '<td class="delayed" ' . 'title="' . $this->lang->execution->delayed . '">' . $task->deadline . '</td>' : '<td>' . $task->deadline . '</td>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$list .= '<td>' . $task->deadline . '</td>';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$list .= '<td></td>';
|
||||
}
|
||||
$list .= '<td>' . $task->estimate . $this->lang->execution->workHourUnit . '</td>';
|
||||
$list .= '<td>' . $task->consumed . $this->lang->execution->workHourUnit . '</td>';
|
||||
$list .= '<td>' . $task->left . $this->lang->execution->workHourUnit . '</td>';
|
||||
@@ -3912,4 +3929,162 @@ class taskModel extends model
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Task Drag.
|
||||
*
|
||||
* @param int $objectID
|
||||
* @param string $objectType
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function saveTaskDrag($objectID, $objectType)
|
||||
{
|
||||
$post = fixer::input('post')->get();
|
||||
$post->end_date = date('Y-m-d', strtotime('-1 day', strtotime($post->end_date)));
|
||||
if($objectType == 'task')
|
||||
{
|
||||
$objectData = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($objectID)->fetch();
|
||||
$parent = $objectData->parent;
|
||||
$project = $objectData->project;
|
||||
$execution = $objectData->execution;
|
||||
$stage = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($execution)->andWhere('project')->eq($project)->fetch();
|
||||
|
||||
if($parent <= 0)
|
||||
{
|
||||
$parentData = $stage;
|
||||
|
||||
$start = $parentData->begin;
|
||||
$end = $parentData->end;
|
||||
}
|
||||
else
|
||||
{
|
||||
$parentData = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($parent)->fetch();
|
||||
|
||||
$start = helper::isZeroDate($parentData->estStarted) ? '' : $parentData->estStarted;
|
||||
$end = helper::isZeroDate($parentData->deadline) ? '' : $parentData->deadline;
|
||||
}
|
||||
|
||||
if(helper::diffDate($start, $post->start_date) > 0)
|
||||
{
|
||||
$arg = !empty($parent) ? $this->lang->task->parent : $this->lang->project->stage;
|
||||
return dao::$errors = sprintf($this->lang->task->overTime, $arg, $arg);
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_TASK)
|
||||
->set('estStarted')->eq($post->start_date)
|
||||
->set('deadline')->eq($post->end_date)
|
||||
->set('lastEditedBy')->eq($this->app->user->account)
|
||||
->where('id')->eq($objectID)
|
||||
->exec();
|
||||
}
|
||||
elseif($objectType == 'plan')
|
||||
{
|
||||
$objectData = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($objectID)->fetch();
|
||||
$parent = $objectData->parent;
|
||||
$project = $objectData->project;
|
||||
|
||||
if(empty($parent))
|
||||
{
|
||||
$parentData = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($project)->fetch();
|
||||
}
|
||||
else
|
||||
{
|
||||
$parentData = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($parent)->fetch();
|
||||
}
|
||||
|
||||
$start = helper::isZeroDate($parentData->begin) ? '' : $parentData->begin;
|
||||
$end = helper::isZeroDate($parentData->end) ? '' : $parentData->end;
|
||||
|
||||
if(helper::diffDate($start, $post->start_date) > 0)
|
||||
{
|
||||
$arg = !empty($parent) ? $this->lang->programplan->parent : $this->lang->project->common;
|
||||
return dao::$errors = sprintf($this->lang->task->overTime, $arg, $arg);
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_PROJECT)
|
||||
->set('begin')->eq($post->start_date)
|
||||
->set('end')->eq($post->end_date)
|
||||
->set('lastEditedBy')->eq($this->app->user->account)
|
||||
->where('id')->eq($objectID)
|
||||
->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save task order.
|
||||
*
|
||||
* @param int $productID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function saveTaskMove($productID = 0)
|
||||
{
|
||||
$data = fixer::input('post')->get();
|
||||
$IdList = explode('-', $data->id);
|
||||
$executionID = $IdList[0];
|
||||
$taskID = $IdList[1];
|
||||
$oldTask = $this->loadModel('task')->getByID($taskID);
|
||||
$index = (int)$data->index;
|
||||
|
||||
$hasZeroOrder = $this->dao->select('id')->from(TABLE_TASK)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('execution')->eq($executionID)
|
||||
->andWhere('`order`')->eq(0)
|
||||
->beginIF($oldTask->parent <= 0)->andWhere('parent')->le(0)->fi()
|
||||
->beginIF($oldTask->parent > 0)->andWhere('parent')->eq($oldTask->parent)->fi()
|
||||
->limit(1)
|
||||
->fetch('id');
|
||||
|
||||
if($hasZeroOrder)
|
||||
{
|
||||
$tasks = $this->dao->select('id')->from(TABLE_TASK)
|
||||
->where('execution')->eq($executionID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->beginIF($oldTask->parent <= 0)->andWhere('parent')->le(0)->fi()
|
||||
->beginIF($oldTask->parent > 0)->andWhere('parent')->eq($oldTask->parent)->fi()
|
||||
->orderBy('order_asc, id_desc')
|
||||
->fetchPairs('id');
|
||||
|
||||
$order = 1;
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
$this->dao->update(TABLE_TASK)->set('`order`')->eq($order)->where('id')->eq($task)->exec();
|
||||
$order ++;
|
||||
}
|
||||
|
||||
$oldTask = $this->loadModel('task')->getByID($taskID);
|
||||
}
|
||||
|
||||
$order = ++ $index;
|
||||
$oldOrder = (int)$oldTask->order;
|
||||
if($order > $oldOrder)
|
||||
{
|
||||
$this->dao->update(TABLE_TASK)->set('`order`=`order`-1')
|
||||
->where('execution')->eq($executionID)
|
||||
->andWhere('`order`')->le($order)
|
||||
->andWhere('`order`')->gt($oldOrder)
|
||||
->beginIF($oldTask->parent <= 0)->andWhere('parent')->le(0)->fi()
|
||||
->beginIF($oldTask->parent > 0)->andWhere('parent')->eq($oldTask->parent)->fi()
|
||||
->exec();
|
||||
}
|
||||
else if($order < $oldOrder)
|
||||
{
|
||||
$this->dao->update(TABLE_TASK)->set('`order`=`order`+1')
|
||||
->where('execution')->eq($executionID)
|
||||
->andWhere('`order`')->lt($oldOrder)
|
||||
->andWhere('`order`')->ge($order)
|
||||
->beginIF($oldTask->parent <= 0)->andWhere('parent')->le(0)->fi()
|
||||
->beginIF($oldTask->parent > 0)->andWhere('parent')->eq($oldTask->parent)->fi()
|
||||
->exec();
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_TASK)->set('`order`')->eq($order)->where('id')->eq($taskID)->exec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1377,6 +1377,7 @@ class testtask extends control
|
||||
$this->view->title = $this->lang->testtask->batchRun;
|
||||
$this->view->position[] = $this->lang->testtask->common;
|
||||
$this->view->position[] = $this->lang->testtask->batchRun;
|
||||
$this->view->from = $from;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#mailtoGroup .chosen-container-single a {border-left-width: 0px;}
|
||||
#ownerAndPriBox .picker .picker-selections .picker-selection {width: 158px;}
|
||||
.table tbody>tr>td {width: 400px;}
|
||||
[lang^='en'] .table tbody>tr>td, [lang^='de'].table tbody>tr>td {width: 460px;}
|
||||
[lang^='en'] .table tbody>tr>td, [lang^='de'] .table tbody>tr>td {width: 460px;}
|
||||
[lang^='fr'] .table tbody>tr>td {width: 480px;}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#mailtoGroup .chosen-container-single a {border-left-width: 0px;}
|
||||
#ownerAndPriBox .picker .picker-selections .picker-selection {width: 158px;}
|
||||
.table tbody>tr>td {width: 400px;}
|
||||
[lang^='en'] .table tbody>tr>td, [lang^='de'].table tbody>tr>td {width: 460px;}
|
||||
[lang^='en'] .table tbody>tr>td, [lang^='de'] .table tbody>tr>td {width: 460px;}
|
||||
[lang^='fr'] .table tbody>tr>td {width: 480px;}
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
$(function()
|
||||
{
|
||||
if(from == 'testcase')
|
||||
{
|
||||
$("#navbar li[data-id='testtask']").toggleClass('active');
|
||||
$("#navbar li[data-id='testcase']").toggleClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('keyup', 'form input:text', function()
|
||||
{
|
||||
var preSelect = $(this).parent().prev().find('select');
|
||||
|
||||
@@ -11,10 +11,11 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php js::set('from', $from);?>
|
||||
<?php $this->app->loadLang('testcase'); unset($this->lang->testcase->resultList['n/a']); ?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->testtask->common . $lang->colon . $lang->testtask->batchRun;?></h2>
|
||||
<h2><?php echo ($from == 'testtask' ? ($lang->testtask->common . $lang->colon) : ''). $lang->testtask->batchRun;?></h2>
|
||||
</div>
|
||||
<form class='main-form' method='post' target='hiddenwin'>
|
||||
<table class='table table-fixed table-form table-bordered'>
|
||||
|
||||
@@ -534,8 +534,8 @@ class upgradeModel extends model
|
||||
case '17_4':
|
||||
$this->changeTableEngine();
|
||||
$this->processCreatedInfo();
|
||||
$this->updateApproval();
|
||||
$this->processCreatedBy();
|
||||
$this->updateApproval();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6777,8 +6777,8 @@ class upgradeModel extends model
|
||||
*/
|
||||
public function processCreatedInfo()
|
||||
{
|
||||
$objectTypes = array('productplan', 'release', 'testtask');
|
||||
$tables = array('productplan' => TABLE_PRODUCTPLAN, 'release' => TABLE_RELEASE, 'testtask' => TABLE_TESTTASK);
|
||||
$objectTypes = array('productplan', 'release', 'testtask', 'build');
|
||||
$tables = array('productplan' => TABLE_PRODUCTPLAN, 'release' => TABLE_RELEASE, 'testtask' => TABLE_TESTTASK, 'build' => TABLE_BUILD);
|
||||
|
||||
$actions = $this->dao->select('objectType, objectID, actor, date')->from(TABLE_ACTION)->where('objectType')->in($objectTypes)->andWhere('action')->eq('opened')->fetchGroup('objectType');
|
||||
foreach($actions as $objectType => $objectActions)
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
class gitlabTest
|
||||
{
|
||||
public $tester;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
global $tester;
|
||||
$this->tester = $tester;
|
||||
$this->gitlab = $this->tester->loadModel('gitlab');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get by id.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getByID($id)
|
||||
{
|
||||
$gitlab = $this->gitlab->getByID($id);
|
||||
if(empty($gitlab)) return 0;
|
||||
return $gitlab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gitlab list.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getList($orderBy = 'id_desc')
|
||||
{
|
||||
$gitlab = $this->gitlab->getList($orderBy);
|
||||
if(empty($gitlab)) return 0;
|
||||
return array_shift($gitlab);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gitlab pairs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPairs()
|
||||
{
|
||||
$pairs = $this->gitlab->getPairs();
|
||||
return key($pairs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a gitlab.
|
||||
*
|
||||
* @access public
|
||||
* @return object|string
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$gitlabID = $this->gitlab->create();
|
||||
if(dao::isError())
|
||||
{
|
||||
$errors = dao::getError();
|
||||
return key($errors);
|
||||
}
|
||||
|
||||
return $this->gitlab->getById($gitlabID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a gitlab.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return object|string
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
$this->gitlab->update($id);
|
||||
if(dao::isError())
|
||||
{
|
||||
$errors = dao::getError();
|
||||
return key($errors);
|
||||
}
|
||||
|
||||
return $this->gitlab->getById($id);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@ version: "1.0"
|
||||
fields:
|
||||
- field: id
|
||||
range: 1
|
||||
- field: gitlabID
|
||||
- field: hostID
|
||||
range: 1
|
||||
- field: sourceProject
|
||||
range: 42
|
||||
|
||||
@@ -14,6 +14,10 @@ fields:
|
||||
range: Gitlab
|
||||
- field: client
|
||||
range: 1
|
||||
- field: serviceHost
|
||||
range: 1
|
||||
- field: serviceProject
|
||||
range: 42
|
||||
- field: extra
|
||||
range: 42
|
||||
- field: preMerge
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/gitlab.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试gitlabModel->create();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
GitLab名称为空 >> name
|
||||
服务器地址为空 >> url
|
||||
正确GitLab数据 >> GitLab,http://10.0.1.161:58080,1196c85ba525a268570df9da627e3a7b2d
|
||||
|
||||
*/
|
||||
|
||||
$gitlab = new gitlabTest();
|
||||
|
||||
$_POST = array();
|
||||
$_POST['name'] = '';
|
||||
$_POST['url'] = 'http://10.0.1.161:51080';
|
||||
$_POST['token'] = 'y2UBqwPPzaLxsniy8R6A';
|
||||
$_POST['password'] = '';
|
||||
|
||||
r($gitlab->create()) && p() && e('name'); // GitLab名称为空
|
||||
|
||||
$_POST['name'] = 'GitLab';
|
||||
$_POST['url'] = '';
|
||||
r($gitlab->create()) && p() && e('url'); // 服务器地址为空
|
||||
|
||||
$_POST['url'] = 'http://10.0.1.161:51080';
|
||||
r($gitlab->create()) && p('name,url,token') && e('GitLab,http://10.0.1.161:51080,y2UBqwPPzaLxsniy8R6A'); // 正确GitLab数据
|
||||
|
||||
system("./ztest init");
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/gitlab.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试gitlabModel->gitById();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
使用存在的ID >> 3
|
||||
使用空的ID >> 0
|
||||
使用不存在的ID >> 0
|
||||
|
||||
*/
|
||||
|
||||
$gitlab = new gitlabTest();
|
||||
|
||||
$gitlabID = 1;
|
||||
r($gitlab->getById($gitlabID)) && p('id') && e('1'); // 使用存在的ID
|
||||
|
||||
$gitlabID = 0;
|
||||
r($gitlab->getById($gitlabID)) && p() && e(0); // 使用空的ID
|
||||
|
||||
$gitlabID = 111;
|
||||
r($gitlab->getById($gitlabID)) && p() && e(0); // 使用不存在的ID
|
||||
|
||||
system("./ztest init");
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/gitlab.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试gitlabModel->gitList();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
获取GiLlab列表 >> 1
|
||||
|
||||
*/
|
||||
|
||||
$gitlab = new gitlabTest();
|
||||
|
||||
$orderBy = 'id_desc';
|
||||
r($gitlab->getList($orderBy)) && p('id') && e('1'); // 获取GitLab列表
|
||||
|
||||
system("./ztest init");
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/gitlab.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试gitlabModel->gitPairs();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
获取GitLab >> 1
|
||||
|
||||
*/
|
||||
|
||||
$gitlab = new gitlabTest();
|
||||
|
||||
r($gitlab->getPairs()) && p() && e('1'); // 获取GitLab
|
||||
|
||||
system("./ztest init");
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/gitlab.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试gitlabModel->update();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
GitLab名称为空 >> name
|
||||
服务器地址为空 >> url
|
||||
正确GitLab数据 >> Changed GitLab
|
||||
|
||||
*/
|
||||
|
||||
$gitlab = new gitlabTest();
|
||||
|
||||
$gitlabID = 3;
|
||||
|
||||
$_POST = array();
|
||||
$_POST['name'] = '';
|
||||
$_POST['url'] = 'http://10.0.1.161:51080';
|
||||
$_POST['account'] = 'admin';
|
||||
$_POST['token'] = 'y2UBqwPPzaLxsniy8R6A';
|
||||
$_POST['password'] = '';
|
||||
|
||||
r($gitlab->update($gitlabID)) && p() && e('name'); // GitLab名称为空
|
||||
|
||||
$_POST['name'] = 'Changed GitLab';
|
||||
$_POST['url'] = '';
|
||||
r($gitlab->update($gitlabID)) && p() && e('url'); // 服务器地址为空
|
||||
|
||||
$_POST['url'] = 'http://10.0.1.161:51080';
|
||||
r($gitlab->update($gitlabID)) && p('name') && e('Changed GitLab'); // 正确GitLab数据
|
||||
|
||||
system("./ztest init");
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.6.2.4 Professional
|
||||
|
||||
This software is covered by DHTMLX Commercial License. Usage without proper license is prohibited.
|
||||
|
||||
(c) XB Software Ltd.
|
||||
|
||||
*/
|
||||
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}(window,function(){return function(e){var t={};function n(o){if(t[o])return t[o].exports;var l=t[o]={i:o,l:!1,exports:{}};return e[o].call(l.exports,l,l.exports,n),l.l=!0,l.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)n.d(o,l,function(t){return e[t]}.bind(null,l));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/codebase/",n(n.s=245)}({245:function(e,t){!function(){var e=gantt.getState;function t(){var e=document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement;return e&&e===document.body}gantt.getState=function(){var n=e.apply(this,arguments);return n.fullscreen=t(),n};var n=!1,o={width:null,height:null,top:null,position:null,modified:!1};function l(e){e?(!function(){var e=gantt.$root;o.width=e.style.width,o.height=e.style.height,o.top=e.style.top,o.position=e.style.position,e.style.width="100vw",e.style.height="100vh",e.style.top="0",e.style.position="absolute",o.modified=!0}(),setTimeout(function(){gantt.render()})):(!function(){var e=gantt.$root;o.modified&&(e.style.width=o.width,e.style.height=o.height,e.style.top=o.top,e.style.position=o.position,o.modified=!1)}(),gantt.render())}function u(){if(gantt.$container){var e=t();l(e),e?(n=!0,setTimeout(function(){gantt.callEvent("onExpand")})):n&&(n=!1,setTimeout(function(){gantt.callEvent("onCollapse")}))}}function r(){return!gantt.$container||!(document.fullscreenEnabled||document.webkitFullscreenEnabled||document.mozFullScreenEnabled||document.msFullscreenEnabled)&&((console.warning||console.log)("The `fullscreen` feature not being allowed, or full-screen mode not being supported"),!0)}gantt.attachEvent("onGanttReady",function(){gantt.event(document,"webkitfullscreenchange",u),gantt.event(document,"mozfullscreenchange",u),gantt.event(document,"MSFullscreenChange",u),gantt.event(document,"fullscreenChange",u),gantt.event(document,"fullscreenchange",u)}),gantt.expand=function(){if(!r()&&gantt.callEvent("onBeforeExpand",[])){var e=document.body;e.requestFullscreen?e.requestFullscreen():e.msRequestFullscreen?e.msRequestFullscreen():e.mozRequestFullScreen?e.mozRequestFullScreen():e.webkitRequestFullscreen&&e.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}},gantt.collapse=function(){r()||t()&&gantt.callEvent("onBeforeCollapse",[])&&(document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&&document.webkitExitFullscreen())}}()}})});
|
||||
//# sourceMappingURL=dhtmlxgantt_fullscreen.js.map
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.6.1.1 Professional
|
||||
This software is covered by DHTMLX Commercial License. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
|
||||
*/
|
||||
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r=e();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(window,function(){return function(t){var e={};function r(a){if(e[a])return e[a].exports;var n=e[a]={i:a,l:!1,exports:{}};return t[a].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=t,r.c=e,r.d=function(t,e,a){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:a})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var a=Object.create(null);if(r.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)r.d(a,n,function(e){return t[e]}.bind(null,n));return a},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="/codebase/",r(r.s=216)}({216:function(t,e){!function(){function t(t){if(!gantt.config.show_markers)return!1;if(!t.start_date)return!1;var e=gantt.getState();if(!(+t.start_date>+e.max_date||+t.end_date&&+t.end_date<+e.min_date||+t.start_date<+e.min_date)){var r=document.createElement("div");r.setAttribute("data-marker-id",t.id);var a="gantt_marker";gantt.templates.marker_class&&(a+=" "+gantt.templates.marker_class(t)),t.css&&(a+=" "+t.css),t.title&&(r.title=t.title),r.className=a;var n=gantt.posFromDate(t.start_date);if(r.style.left=n+"px",r.style.height=Math.max(gantt.getRowTop(gantt.getVisibleTaskCount()),0)+"px",t.end_date){var i=gantt.posFromDate(t.end_date);r.style.width=Math.max(i-n,0)+"px"}return t.text&&(r.innerHTML="<div class='gantt_marker_content' >"+t.text+"</div>"),r}}function e(){if(gantt.$task_data){var t=document.createElement("div");t.className="gantt_marker_area",gantt.$task_data.appendChild(t),gantt.$marker_area=t}}gantt._markers||(gantt._markers=gantt.createDatastore({name:"marker",initItem:function(t){return t.id=t.id||gantt.uid(),t}})),gantt.config.show_markers=!0,gantt.attachEvent("onBeforeGanttRender",function(){gantt.$marker_area||e()}),gantt.attachEvent("onGanttReady",function(){e(),gantt.$services.getService("layers").createDataRender({name:"marker",defaultContainer:function(){return gantt.$marker_area}}).addLayer(t)}),gantt.getMarker=function(t){return this._markers?this._markers.getItem(t):null},gantt.addMarker=function(t){return this._markers.addItem(t)},gantt.deleteMarker=function(t){return!!this._markers.exists(t)&&(this._markers.removeItem(t),!0)},gantt.updateMarker=function(t){this._markers.refresh(t)},gantt._getMarkers=function(){return this._markers.getItems()},gantt.renderMarkers=function(){this._markers.refresh()}}()}})});
|
||||
//# sourceMappingURL=dhtmlxgantt_marker.js.map
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -82,13 +82,14 @@ a.showMoreImage:hover {opacity: 1;}
|
||||
|
||||
.fixed-head-table{z-index:1000;}
|
||||
|
||||
#headerActions {position: absolute; top: 9px; right: 230px; border-right: 2px solid rgba(255, 255, 255, 0.3);}
|
||||
#headerActions {position: absolute; top: 9px; right: 175px; border-right: 2px solid rgba(255, 255, 255, 0.3);}
|
||||
#headerActions .btn-group > .btn{ color: #fff; margin-right: 8px; border-radius: 4px !important;}
|
||||
#headerActions .btn-group > .btn.active, #headerActions .btn:active, #headerActions .open .dropdown-toggle.btn {background: rgba(0,0,0,0.15) !important;}
|
||||
#headerActions #kanbanActionMenu {left: 55px}
|
||||
#headerActions .setting {border-color: transparent;}
|
||||
#headerActions .dropdown-menu {top: 35px; z-index: 2000;}
|
||||
#headerActions .dropdown-menu:before, #headerActions .dropdown-menu:hover:before {position: absolute; top: -9px; right: 50%; width: 0; height: 0; content: ' '; border-color: transparent transparent #fff transparent; border-style: solid; border-width: 0 10px 10px 10px;}
|
||||
[lang^='zh'] #headerActions {width: 230px;}
|
||||
|
||||
.icon-size-width:before {content: "\e9c5"; transform: rotate(90deg); -ms-transform: rotate(90deg); -moz-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg);}
|
||||
.checkbox-primary > label{overflow: hidden;}
|
||||
|
||||
Reference in New Issue
Block a user