Merge branch 'master' into tanghucheng_feedback_module

This commit is contained in:
tanghucheng
2022-10-18 15:33:45 +08:00
139 changed files with 1382 additions and 399 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ class executionsEntry extends entry
{
foreach($execution->hours as $field => $value) $execution->$field = $value;
$execution = $this->filterFields($execution, 'id,name,project,code,type,parent,begin,end,status,openedBy,openedDate,delay,progress,' . $appendFields);
$execution = $this->filterFields($execution, 'id,name,project,code,type,parent,begin,end,status,openedBy,openedDate,delay,progress,children,' . $appendFields);
$result[] = $this->format($execution, 'openedBy:user,openedDate:time,lastEditedBy:user,lastEditedDate:time,closedBy:user,closedDate:time,canceledBy:user,canceledDate:time,PM:user,PO:user,RD:user,QD:user,whitelist:userList,begin:date,end:date,realBegan:date,realEnd:date,deleted:bool');
}
+1 -1
View File
@@ -36,7 +36,7 @@ class taskRecordEstimateEntry extends Entry
if(!$data) return $this->error('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$effort = array();
$effort = new stdclass();
if($issetEffort and $data->data->efforts) $effort = $data->data->efforts;
if(!$issetEffort and $data->data->estimates) $effort = $data->data->estimates;
$this->send(200, array('effort' => $effort));
+39
View File
@@ -66,4 +66,43 @@ class testtasksEntry extends entry
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'testtasks' => $result));
}
/**
* POST method.
*
* @access public
* @param int $projectID
* @return void
*/
public function post($projectID = 0)
{
if(!$projectID) $projectID = $this->param('project', 0);
$productID = $this->request('product', 0);
$executionID = $this->request('execution', 0);
$buildID = $this->request('build', 0);
if(empty($projectID)) return $this->sendError(400, 'need project id!');
if(empty($productID)) return $this->sendError(400, 'need product id!');
if(empty($executionID)) return $this->sendError(400, 'need execution id!');
if(empty($buildID)) return $this->sendError(400, 'need build id!');
/* Check whether executionID and buildID is valid. */
$executions = $this->loadModel('product')->getExecutionPairsByProduct($productID, '', 'id_desc', $projectID);
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk');
if(!isset($executions[$executionID])) return $this->sendError(400, 'error execution id!');
if(!isset($builds[$buildID])) return $this->sendError(400, 'error build id!');
$fields = 'product,execution,build,name,begin,end,owner,type,pri,status,desc';
$this->batchSetPost($fields);
$control = $this->loadController('testtask', 'create');
$this->requireFields('name,begin,end');
$control->create($productID, $executionID, $build, $projectID);
$data = $this->getData();
if(!isset($data->id)) return $this->sendError(400, $data->message);
$testtask = $this->loadModel('testtask')->getByID($data->id);
$this->send(201, $testtask);
}
}
+1
View File
@@ -62,6 +62,7 @@ class userEntry extends Entry
$info->profile->role = array('code' => $info->profile->role, 'name' => $this->lang->user->roleList[$info->profile->role]);
$info->profile->admin = strpos($this->app->company->admins, ",{$profile->account},") !== false;
$info->profile->superReviewer = isset($this->config->story) ? strpos(',' . trim(zget($this->config->story, 'superReviewers', ''), ',') . ',', ',' . $this->app->user->account . ',') : false;
$info->profile->view = $this->app->user->view;
if(!$fields) return $this->send(200, $info);
+2 -1
View File
@@ -216,6 +216,7 @@ $config->openMethods[] = 'kanban.importplan';
$config->openMethods[] = 'kanban.importrelease';
$config->openMethods[] = 'kanban.importexecution';
$config->openMethods[] = 'kanban.importbuild';
$config->openMethods[] = 'kanban.importticket';
$config->openMethods[] = 'kanban.activatecard';
$config->openMethods[] = 'kanban.finishcard';
$config->openMethods[] = 'kanban.deleteobjectcard';
@@ -403,4 +404,4 @@ $config->waterfallModules = array('workestimation', 'durationestimation', 'budge
$config->showMainMenu = true;
$config->maxPriValue = '256';
$config->importWhiteList = array('user', 'task', 'story', 'bug', 'testcase', 'feedback');
$config->importWhiteList = array('user', 'task', 'story', 'bug', 'testcase', 'feedback', 'ticket');
+65
View File
@@ -1,7 +1,72 @@
CREATE TABLE IF NOT EXISTS `zt_ticket` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`module` mediumint(8) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL,
`desc` text NOT NULL,
`openedBuild` varchar(255) NOT NULL,
`feedback` mediumint(8) NOT NULL,
`assignedTo` varchar(255) NOT NULL,
`assignedDate` datetime NOT NULL,
`realStarted` datetime NOT NULL,
`startedBy` varchar(255) NOT NULL,
`startedDate` datetime NOT NULL,
`deadline` date NOT NULL,
`pri` tinyint unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`consumed` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`status` varchar(30) NOT NULL,
`openedBy` varchar(30) NOT NULL,
`openedDate` datetime NOT NULL,
`activatedCount` int(10) NOT NULL,
`activatedBy` varchar(30) NOT NULL,
`activatedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL,
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`finishedBy` varchar(30) NOT NULL,
`finishedDate` datetime NOT NULL,
`resolvedBy` varchar(30) NOT NULL,
`resolvedDate` datetime NOT NULL,
`resolution` varchar(1000) NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`keywords` varchar(255) NOT NULL,
`repeatTicket` mediumint(8) NOT NULL DEFAULT '0',
`mailto` varchar(255) NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
key `product` (`product`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zt_ticketsource` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`ticketId` mediumint(8) unsigned NOT NULL,
`customer` varchar(100) NOT NULL,
`contact` varchar(100) NOT NULL,
`notifyEmail` varchar(100) NOT NULL,
`createdDate` datetime NOT NULL,
PRIMARY KEY (`id`),
key `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `zt_ticketrelation` (
`id` mediumint unsigned NOT NULL AUTO_INCREMENT,
`ticketId` mediumint unsigned NOT NULL,
`objectId` mediumint NOT NULL,
`objectType` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_product` ADD `ticket` varchar(30) NOT NULL AFTER `feedback`;
ALTER TABLE `zt_kanban` ADD `colWidth` smallint(4) NOT NULL DEFAULT '264' AFTER `fluidBoard`;
ALTER TABLE `zt_kanban` ADD `minColWidth` smallint(4) NOT NULL DEFAULT '180' AFTER `colWidth`;
ALTER TABLE `zt_kanban` ADD `maxColWidth` smallint(4) NOT NULL DEFAULT '384' AFTER `minColWidth`;
ALTER TABLE `zt_project` ADD `colWidth` smallint(4) NOT NULL DEFAULT '264' AFTER `fluidBoard`;
ALTER TABLE `zt_project` ADD `minColWidth` smallint(4) NOT NULL DEFAULT '180' AFTER `colWidth`;
ALTER TABLE `zt_project` ADD `maxColWidth` smallint(4) NOT NULL DEFAULT '384' AFTER `minColWidth`;
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', 'global', 'syncProductFeedback', '{}');
+65
View File
@@ -7121,6 +7121,70 @@ CREATE TABLE IF NOT EXISTS `zt_feedback` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_ticket`;
CREATE TABLE IF NOT EXISTS `zt_ticket` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`module` mediumint(8) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL,
`desc` text NOT NULL,
`openedBuild` varchar(255) NOT NULL,
`feedback` mediumint(8) NOT NULL,
`assignedTo` varchar(255) NOT NULL,
`assignedDate` datetime NOT NULL,
`realStarted` datetime NOT NULL,
`startedBy` varchar(255) NOT NULL,
`startedDate` datetime NOT NULL,
`deadline` date NOT NULL,
`pri` tinyint unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`consumed` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`status` varchar(30) NOT NULL,
`openedBy` varchar(30) NOT NULL,
`openedDate` datetime NOT NULL,
`activatedCount` int(10) NOT NULL,
`activatedBy` varchar(30) NOT NULL,
`activatedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL,
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`finishedBy` varchar(30) NOT NULL,
`finishedDate` datetime NOT NULL,
`resolvedBy` varchar(30) NOT NULL,
`resolvedDate` datetime NOT NULL,
`resolution` varchar(1000) NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`keywords` varchar(255) NOT NULL,
`repeatTicket` mediumint(8) NOT NULL DEFAULT '0',
`mailto` varchar(255) NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
key `product` (`product`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zt_ticketsource` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`ticketId` mediumint(8) unsigned NOT NULL,
`customer` varchar(100) NOT NULL,
`contact` varchar(100) NOT NULL,
`notifyEmail` varchar(100) NOT NULL,
`createdDate` datetime NOT NULL,
PRIMARY KEY (`id`),
key `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `zt_ticketrelation` (
`id` mediumint unsigned NOT NULL AUTO_INCREMENT,
`ticketId` mediumint unsigned NOT NULL,
`objectId` mediumint NOT NULL,
`objectType` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_bug` ADD `feedback` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `caseVersion`;
ALTER TABLE `zt_story` ADD `feedback` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `fromBug`;
ALTER TABLE `zt_user` ADD `feedback` enum('0', '1') NOT NULL DEFAULT '0' AFTER `locked`;
@@ -7626,6 +7690,7 @@ ADD `grade` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `path`,
ADD `order` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `grade`;
ALTER TABLE `zt_product` ADD `feedback` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `RD`;
ALTER TABLE `zt_product` ADD `ticket` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `feedback`;
ALTER TABLE `zt_leave` ADD `level` tinyint(3) NOT NULL;
ALTER TABLE `zt_leave` ADD `assignedTo` varchar(30) NOT NULL;
+1 -1
View File
@@ -291,7 +291,7 @@
</tbody>
<tfoot>
<tr>
<td colspan='3' class='text-center'><?php echo html::a('javascript:void(0)', $lang->confirm, '', "class='btn btn-primary'");?></td>
<td colspan='4' class='text-center'><?php echo html::a('javascript:void(0)', $lang->confirm, '', "class='btn btn-primary'");?></td>
</tr>
</tfoot>
</table>
+2 -2
View File
@@ -504,8 +504,8 @@ class baseHTML
/* If the link of the referer is not the link of the current page or the link of the index, the cookie and gobackLink will be updated. */
if(!preg_match("/(m=|\/)(index|search|$currentModule)(&f=|-)(index|buildquery|$currentMethod)(&|-|\.)?/", strtolower($refererLink)))
{
$gobackList[$tab] = $referer;
$gobackLink = $referer;
$gobackList[$tab] = $referer . "#app=$tab";
$gobackLink = $referer . "#app=$tab";
setcookie('goback', json_encode($gobackList), $config->cookieLife, $config->webRoot, '', $config->cookieSecure, false);
}
+1
View File
@@ -215,6 +215,7 @@ $lang->action->desc->importedproductplan = '$date, imported to <strong>$extra</
$lang->action->desc->importedrelease = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedexecution = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedbuild = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedticket = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</strong> from <strong>SonarQube Issue</strong>.' . "\n";
$lang->action->desc->tolib = '$date, imported by <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, updated to ' . $lang->testcase->common . ' by <strong>$actor</strong>.' . "\n";
+1
View File
@@ -215,6 +215,7 @@ $lang->action->desc->importedproductplan = '$date, imported to <strong>$extra</
$lang->action->desc->importedrelease = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedexecution = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedbuild = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedticket = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</strong> from <strong>SonarQube Issue</strong>.' . "\n";
$lang->action->desc->tolib = '$date, imported by <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, updated to ' . $lang->testcase->common . ' by <strong>$actor</strong>.' . "\n";
+1
View File
@@ -215,6 +215,7 @@ $lang->action->desc->importedproductplan = '$date, imported to <strong>$extra</
$lang->action->desc->importedrelease = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedexecution = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedbuild = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedticket = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</strong> from <strong>SonarQube Issue</strong>.' . "\n";
$lang->action->desc->tolib = '$date, Importé par <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, MàJ de ' . $lang->testcase->common . ' par <strong>$actor</strong>.' . "\n";
+2
View File
@@ -215,6 +215,7 @@ $lang->action->desc->importedproductplan = '$date, 由 <strong>$actor</strong>
$lang->action->desc->importedrelease = '$date, 由 <strong>$actor</strong> 从产品发布 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedexecution = '$date, 由 <strong>$actor</strong> 从项目执行 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedbuild = '$date, 由 <strong>$actor</strong> 从项目版本 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedticket = '$date, 由 <strong>$actor</strong> 从反馈工单 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->fromsonarqube = '$date, 由 <strong>$actor</strong> 从<strong>SonarQube问题</strong>转化而来。' . "\n";
$lang->action->desc->tolib = '$date, 由 <strong>$actor</strong> 导入。' . "\n";
$lang->action->desc->updatetolib = '$date, 由 <strong>$actor</strong> 从' . $lang->testcase->common . '更新。' . "\n";
@@ -717,6 +718,7 @@ $lang->action->label->mr = '合并请求|mr|view|id=%s';
$lang->action->label->gitlab = 'GitLab服务器|gitlab|view|id=%s';
$lang->action->label->stage = '瀑布模型的阶段|stage|browse|';
$lang->action->label->module = '模块|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
$lang->action->label->ticket = '工单|ticket|view|id=%s';
/* Object type. */
$lang->action->search = new stdclass();
+3 -1
View File
@@ -787,7 +787,9 @@ EOT;
*/
public function debug($filePath, $action)
{
$filePath = helper::safe64Decode($filePath);
$filePath = helper::safe64Decode($filePath);
$fileDirPath = realpath(dirname($filePath));
if(strpos($fileDirPath, $this->app->getModuleRoot()) !== 0 and strpos($fileDirPath, $this->app->getExtensionRoot()) !== 0) return;
if($action == 'extendModel')
{
$method = $this->api->getMethod($filePath, 'Model');
+14 -9
View File
@@ -488,7 +488,8 @@ class block extends control
return true;
}
$blocks = json_decode($blocks, true);
$blocks = json_decode($blocks, true);
if(empty($blocks)) $blocks = array();
$blockPairs = array('' => '') + $blocks;
echo '<div class="form-group">';
@@ -1734,10 +1735,11 @@ class block extends control
if(common::hasPriv('bug', 'view') and $this->config->vision != 'lite') $hasViewPriv['bug'] = true;
if($this->config->URAndSR and common::hasPriv('story', 'view') and $this->config->vision != 'lite') $hasViewPriv['requirement'] = true;
if(common::hasPriv('story', 'view') and $this->config->vision != 'lite') $hasViewPriv['story'] = true;
if(common::hasPriv('risk', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['risk'] = true;
if(common::hasPriv('issue', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['issue'] = true;
if(common::hasPriv('meeting', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['meeting'] = true;
if(common::hasPriv('risk', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['risk'] = true;
if(common::hasPriv('issue', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['issue'] = true;
if(common::hasPriv('meeting', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['meeting'] = true;
if(common::hasPriv('feedback', 'view') and in_array($this->config->edition, array('max', 'biz'))) $hasViewPriv['feedback'] = true;
if(common::hasPriv('ticket', 'view') and in_array($this->config->edition, array('max', 'biz'))) $hasViewPriv['ticket'] = true;
$params = $this->get->param;
$params = json_decode(base64_decode($params));
@@ -1746,14 +1748,14 @@ class block extends control
$objectCountList = array('todo' => 'todoCount', 'task' => 'taskCount', 'bug' => 'bugCount', 'story' => 'storyCount', 'requirement' => 'requirementCount');
if($this->config->edition == 'max')
{
$objectList += array('risk' => 'risks', 'issue' => 'issues', 'feedback' => 'feedbacks');
$objectCountList += array('risk' => 'riskCount', 'issue' => 'issueCount', 'feedback' => 'feedbackCount');
$objectList += array('risk' => 'risks', 'issue' => 'issues', 'feedback' => 'feedbacks', 'ticket' => 'tickets');
$objectCountList += array('risk' => 'riskCount', 'issue' => 'issueCount', 'feedback' => 'feedbackCount', 'ticket' => 'ticketCount');
}
if($this->config->edition == 'biz')
{
$objectList += array('feedback' => 'feedbacks');
$objectCountList += array('feedback' => 'feedbackCount');
$objectList += array('feedback' => 'feedbacks', 'ticket' => 'tickets');
$objectCountList += array('feedback' => 'feedbackCount', 'ticket' => 'ticketCount');
}
$tasks = $this->loadModel('task')->getUserSuspendedTasks($this->app->user->account);
@@ -1769,6 +1771,7 @@ class block extends control
->beginIF($objectType == 'bug')->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id')->fi()
->beginIF($objectType == 'task')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id')->fi()
->beginIF($objectType == 'issue' or $objectType == 'risk')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')->fi()
->beginIF($objectType == 'ticket')->leftJoin(TABLE_USER)->alias('t2')->on('t1.openedBy = t2.account')->fi()
->where('t1.deleted')->eq(0)
->andWhere('t1.assignedTo')->eq($this->app->user->account)->fi()
->beginIF($objectType == 'story')->andWhere('t1.type')->eq('story')->andWhere('t2.deleted')->eq('0')->fi()
@@ -1779,6 +1782,7 @@ class block extends control
->beginIF($objectType != 'todo')->andWhere('t1.status')->ne('closed')->fi()
->beginIF($objectType == 'feedback')->andWhere('t1.status')->in('wait, noreview')->fi()
->beginIF($objectType == 'issue' or $objectType == 'risk')->andWhere('t2.deleted')->eq(0)->fi()
->beginIF($objectType == 'ticket')->andWhere('t1.status')->in('wait,doing,done')->fi()
->orderBy($orderBy)
->beginIF($limitCount)->limit($limitCount)->fi()
->fetchAll();
@@ -1823,9 +1827,10 @@ class block extends control
if($objectType == 'risk') $this->app->loadLang('risk');
if($objectType == 'issue') $this->app->loadLang('issue');
if($objectType == 'feedback')
if($objectType == 'feedback' or $objectType == 'ticket')
{
$this->app->loadLang('feedback');
$this->app->loadLang('ticket');
$this->view->users = $this->loadModel('user')->getPairs('all,noletter');
$this->view->products = $this->dao->select('id, name')->from(TABLE_PRODUCT)->where('deleted')->eq('0')->fetchPairs('id', 'name');
}
+1
View File
@@ -358,6 +358,7 @@ $lang->block->availableBlocks->risk = 'My Risks';
$lang->block->availableBlocks->issue = 'My Issues';
$lang->block->availableBlocks->meeting = 'My Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
$lang->block->availableBlocks->ticket = 'Ticket';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = 'Project';
$lang->block->moduleList['product'] = $lang->productCommon;
+1
View File
@@ -358,6 +358,7 @@ $lang->block->availableBlocks->risk = 'Risks';
$lang->block->availableBlocks->issue = 'Issues';
$lang->block->availableBlocks->meeting = 'Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
$lang->block->availableBlocks->ticket = 'Ticket';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = 'Project';
$lang->block->moduleList['product'] = $lang->productCommon;
+1
View File
@@ -358,6 +358,7 @@ $lang->block->availableBlocks->risk = 'My Risks';
$lang->block->availableBlocks->issue = 'My Issues';
$lang->block->availableBlocks->meeting = 'My Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
$lang->block->availableBlocks->ticket = 'Ticket';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = 'Project';
$lang->block->moduleList['product'] = $lang->productCommon;
+2
View File
@@ -358,6 +358,7 @@ $lang->block->availableBlocks->risk = '风险';
$lang->block->availableBlocks->issue = '问题';
$lang->block->availableBlocks->meeting = '会议';
$lang->block->availableBlocks->feedback = '反馈';
$lang->block->availableBlocks->ticket = '工单';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = '项目';
$lang->block->moduleList['product'] = $lang->productCommon;
@@ -478,6 +479,7 @@ $lang->block->issueCount = '问题数';
$lang->block->storyCount = '需求数';
$lang->block->meetingCount = '会议数';
$lang->block->feedbackCount = '反馈数';
$lang->block->ticketCount = '工单数';
$lang->block->typeList = new stdclass();
+2 -2
View File
@@ -18,10 +18,10 @@
<thead>
<tr>
<th class='c-id text-center'><?php echo $lang->idAB?></th>
<th><?php echo $lang->build->name;?></th>
<?php if($longBlock):?>
<th><?php echo $lang->build->product;?></th>
<?php endif;?>
<th><?php echo $lang->build->name;?></th>
<th class='c-date'><?php echo $lang->build->date;?></th>
</tr>
</thead>
@@ -34,10 +34,10 @@
?>
<tr <?php echo $appid?>>
<td class='text-center'><?php echo sprintf('%03d', $build->id);?></td>
<td title='<?php echo $build->name?>'><?php echo html::a($buildViewLink, $build->name);?></td>
<?php if($longBlock):?>
<td title='<?php echo $build->productName?>'><?php echo html::a($productViewLink, $build->productName);?></td>
<?php endif;?>
<td title='<?php echo $build->name?>'><?php echo html::a($buildViewLink, $build->name);?></td>
<td><?php echo $build->date?></td>
</tr>
<?php endforeach;?>
@@ -102,11 +102,11 @@ $(function()
e.preventDefault();
});
var $projectLi = $('#activeProject');
if($projectLi.length)
var $projectList = $('#activeProject');
if($projectList.length)
{
var projectLi = $projectLi[0];
$(".col ul.nav").animate({scrollTop: projectLi.offsetTop}, "slow");
var projectList = $projectList[0];
$(".col ul.nav").animate({scrollTop: projectList.offsetTop}, "slow");
}
});
</script>
@@ -123,7 +123,7 @@ $(function()
<?php $selected = key($projects);?>
<?php foreach($projects as $project):?>
<li <?php if($project->id == $selected) echo "class='active' id='activeProject'";?> projectID='<?php echo $project->id;?>'>
<a href="###" title="<?php echo $project->name?>" data-target="#tab3Content<?php echo $project->id;?>" data-toggle="tab"><?php echo $project->name;?></a>
<a href="###" title="<?php echo $project->name?>" data-target='<?php echo "#tab3{$blockNavId}Content{$project->id}";?>' data-toggle="tab"><?php echo $project->name;?></a>
<?php echo html::a(helper::createLink('project', 'index', "projectID=$project->id"), "<i class='icon-arrow-right text-primary'></i>", '', "class='btn-view' title={$lang->project->index}");?>
</li>
<?php endforeach;?>
@@ -132,7 +132,7 @@ $(function()
</div>
<div class="col tab-content">
<?php foreach($projects as $project):?>
<div class="tab-pane fade<?php if($project->id == $selected) echo ' active in';?>" id="tab3Content<?php echo $project->id;?>">
<div class="tab-pane fade<?php if($project->id == $selected) echo ' active in';?>" id='<?php echo "tab3{$blockNavId}Content{$project->id}";?>'>
<div class="table-row">
<?php if($project->model == 'scrum' or $project->model == 'kanban'):?>
<div class='table-row'>
+36
View File
@@ -0,0 +1,36 @@
<?php if(empty($tickets)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-tickets .c-id {width: 50px;}
</style>
<div class='panel-body has-table scrollbar-hover'>
<table class='table table-borderless table-fixed table-fixed-head table-hover tablesorter block-tickets <?php if(!$longBlock) echo 'block-sm'?>'>
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB?></th>
<th class='c-product'><?php echo $lang->ticket->product;?></th>
<th class='c-title'><?php echo $lang->ticket->title?></th>
<th class='c-type'><?php echo $lang->ticket->type;?></th>
<th class='c-openedBy'><?php echo $lang->ticket->createdBy;?></th>
<th class='c-openedDate'><?php echo $lang->ticket->createdDate;?></th>
</tr>
</thead>
<tbody>
<?php foreach($tickets as $ticket):?>
<?php
$appid = isset($_GET['entry']) ? "class='app-btn' data-id='{$this->get->entry}'" : '';
?>
<tr>
<td><?php echo sprintf('%03d', $ticket->id);?></td>
<td><?php echo zget($products, $ticket->product);?></td>
<td class='c-title' title='<?php echo $ticket->title?>'><?php echo html::a($this->createLink('ticket', 'view', "ticketID=$ticket->id"), $ticket->title, '', "data-app='my'")?></td>
<td><?php echo zget($lang->ticket->typeList, $ticket->type)?></td>
<td><?php echo zget($users, $ticket->openedBy)?></td>
<td><?php echo $ticket->openedDate;?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
+2 -1
View File
@@ -78,7 +78,7 @@ class bugModel extends model
->join('mailto', ',')
->join('os', ',')
->join('browser', ',')
->remove('files,labels,uid,oldTaskID,contactListMenu,region,lane')
->remove('files,labels,uid,oldTaskID,contactListMenu,region,lane,ticket')
->get();
if($bug->execution != 0) $bug->project = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($bug->execution)->fetch('project');
@@ -2214,6 +2214,7 @@ class bugModel extends model
if(!empty($run->task)) $testtask = $this->loadModel('testtask')->getById($run->task);
$executionID = isset($testtask->execution) ? $testtask->execution : 0;
if(!$executionID and $caseID > 0) $executionID = isset($run->case->execution) ? $run->case->execution : 0; // Fix feedback #1043.
if(!$executionID and $this->app->tab == 'execution') $executionID = $this->session->execution;
return array('title' => $title, 'steps' => $bugSteps, 'storyID' => $run->case->story, 'moduleID' => $run->case->module, 'version' => $run->case->version, 'executionID' => $executionID);
+2 -2
View File
@@ -160,11 +160,11 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
<?php if($showNoticefeedbackBy):?>
<tr>
<th><nobr><?php echo $lang->bug->feedbackBy;?></nobr></th>
<td><?php echo html::input('feedbackBy', $feedbackBy, "class='form-control'");?></td>
<td><?php echo html::input('feedbackBy', isset($feedbackBy) ? $feedbackBy : '', "class='form-control'");?></td>
<td id='notifyEmailTd'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->bug->notifyEmail?></span>
<span><?php echo html::input('notifyEmail', $notifyEmail, "class='form-control'");?></span>
<span><?php echo html::input('notifyEmail', isset($notifyEmail) ? $notifyEmail : '', "class='form-control'");?></span>
</div>
</td>
</tr>
+4 -4
View File
@@ -126,11 +126,11 @@ js::set('flow', $config->global->flow);
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='c-pri' title=<?php echo $lang->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='text-left'><?php common::printOrderLink('title', $orderBy, $vars, $lang->testcase->title);?></th>
<th class='c-pri' title=<?php echo $lang->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-type'> <?php common::printOrderLink('type', $orderBy, $vars, $lang->typeAB);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<?php
$extendFields = $this->caselib->getFlowExtendFields();
foreach($extendFields as $extendField) echo "<th>{$extendField->name}</th>";
@@ -148,15 +148,15 @@ js::set('flow', $config->global->flow);
<?php echo sprintf('%03d', $case->id);?>
<?php endif;?>
</td>
<td><span class='label-pri label-pri-<?php echo $case->pri;?>' title='<?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?>'><?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?></span></td>
<td class='text-left' title="<?php echo $case->title?>">
<?php if($modulePairs and $case->module) echo "<span title='{$lang->testcase->module}' class='label label-info label-badge'>{$modulePairs[$case->module]}</span> ";?>
<?php $viewLink = $this->createLink('testcase', 'view', "caseID=$case->id&version=$case->version");?>
<?php echo html::a($viewLink, $case->title, null, "style='color: $case->color'");?>
</td>
<td><span class='label-pri label-pri-<?php echo $case->pri;?>' title='<?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?>'><?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?></span></td>
<td><?php echo $lang->testcase->typeList[$case->type];?></td>
<td title="<?php echo zget($users, $case->openedBy);?>"><?php echo zget($users, $case->openedBy);?></td>
<td class='<?php if(isset($run)) echo $run->status;?> testcase-<?php echo $case->status?>'> <?php echo $this->processStatus('testcase', $case);?></td>
<td title="<?php echo zget($users, $case->openedBy);?>"><?php echo zget($users, $case->openedBy);?></td>
<?php foreach($extendFields as $extendField) echo "<td>" . $this->loadModel('flow')->getFieldValue($extendField, $case) . "</td>";?>
<td class='c-actions'>
<?php echo $this->caselib->buildOperateMenu($case, 'browse');?>
+1 -1
View File
@@ -261,7 +261,7 @@ class custom extends control
}
}
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('custom', 'set', "module=$module&field=$field&lang=" . str_replace('-', '_', isset($this->config->langs[$lang]) ? $lang : 'all'))));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('custom', 'set', "module=$module&field=$field&lang=" . ($lang == 'all' ? $lang : ''))));
}
/* Check whether the current language has been customized. */
+1
View File
@@ -33,6 +33,7 @@ $lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdByAB = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
+1
View File
@@ -33,6 +33,7 @@ $lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdByAB = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
+1
View File
@@ -33,6 +33,7 @@ $lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdByAB = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
+1
View File
@@ -33,6 +33,7 @@ $lang->design->affectedStory = "影响{$lang->SRCommon}";
$lang->design->affectedTasks = '影响任务';
$lang->design->reviewObject = '评审对象';
$lang->design->createdBy = '由谁创建';
$lang->design->createdByAB = '创建者';
$lang->design->createdDate = '创建时间';
$lang->design->basicInfo = '基本信息';
$lang->design->noAssigned = '未指派';
+6 -6
View File
@@ -32,12 +32,12 @@
<?php $vars = "projectID=$projectID&productID=$productID&type=$type&param=$param&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<thead>
<tr>
<th class="text-left w-60px"> <?php common::printOrderLink('id', $orderBy, $vars, $lang->design->id);?></th>
<th class="text-left w-100px"> <?php common::printOrderLink('type', $orderBy, $vars, $lang->design->type);?></th>
<th class="text-left w-60px"> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class="text-left"> <?php common::printOrderLink('name', $orderBy, $vars, $lang->design->name);?></th>
<th class="text-left w-120px"> <?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->design->createdBy);?></th>
<th class="text-left w-150px"> <?php common::printOrderLink('createdDate', $orderBy, $vars, $lang->design->createdDate);?></th>
<th class="text-left w-100px"> <?php common::printOrderLink('type', $orderBy, $vars, $lang->design->type);?></th>
<th class="c-assignedTo w-120px"><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->design->assignedTo);?></th>
<th class="text-left w-120px"> <?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->design->createdByAB);?></th>
<th class="text-left w-150px"> <?php common::printOrderLink('createdDate', $orderBy, $vars, $lang->design->createdDate);?></th>
<th class="text-center w-100px"> <?php echo $lang->design->actions;?></th>
</tr>
</thead>
@@ -45,11 +45,11 @@
<?php foreach($designs as $design):?>
<tr>
<td calss="c-id"> <?php printf('%03d', $design->id);?></td>
<td class="c-type"> <?php echo zget($lang->design->typeList, $design->type);?></td>
<td class="c-name" title="<?php echo $design->name;?>"><?php echo common::hasPriv('design', 'view') ? html::a($this->createLink('design', 'view', "id={$design->id}"), $design->name) : $design->name;?></td>
<td class="c-type"> <?php echo zget($lang->design->typeList, $design->type);?></td>
<td class="c-assignedTo"> <?php echo $this->design->printAssignedHtml($design, $users);?></td>
<td class="c-createdBy"> <?php echo zget($users, $design->createdBy);?></td>
<td class="c-createdDate"><?php echo substr($design->createdDate, 0, 11);?></td>
<td class="c-assignedTo"> <?php echo $this->design->printAssignedHtml($design, $users);?></td>
<td class='c-actions text-center'>
<?php
$vars = "design={$design->id}";
+2
View File
@@ -61,9 +61,11 @@ $lang->doc->keywords = 'Tags';
$lang->doc->url = 'URL';
$lang->doc->files = 'Datei';
$lang->doc->addedBy = 'Angelegt von';
$lang->doc->addedByAB = 'Added';
$lang->doc->addedDate = 'Angelegt am';
$lang->doc->editedBy = 'Bearbeitet von';
$lang->doc->editedDate = 'Bearbeitet am';
$lang->doc->lastEditedBy = 'Last Editor';
$lang->doc->version = 'Version';
$lang->doc->basicInfo = 'Basis Info';
$lang->doc->deleted = 'Gelöscht';
+2
View File
@@ -61,9 +61,11 @@ $lang->doc->keywords = 'Tags';
$lang->doc->url = 'URL';
$lang->doc->files = 'Files';
$lang->doc->addedBy = 'Author';
$lang->doc->addedByAB = 'Added';
$lang->doc->addedDate = 'Added';
$lang->doc->editedBy = 'UpdatedBy';
$lang->doc->editedDate = 'Updated';
$lang->doc->lastEditedBy = 'Last Editor';
$lang->doc->version = 'Version';
$lang->doc->basicInfo = 'Basic Information';
$lang->doc->deleted = 'Deleted';
+2
View File
@@ -61,9 +61,11 @@ $lang->doc->keywords = 'Tags';
$lang->doc->url = 'URL';
$lang->doc->files = 'Fichiers';
$lang->doc->addedBy = 'Auteur';
$lang->doc->addedByAB = 'Added';
$lang->doc->addedDate = 'Ajouté le';
$lang->doc->editedBy = 'Màj par';
$lang->doc->editedDate = 'Màj le';
$lang->doc->lastEditedBy = 'Last Editor';
$lang->doc->version = 'Version';
$lang->doc->basicInfo = 'Infos de Base';
$lang->doc->deleted = 'Supprimé';
+2
View File
@@ -61,9 +61,11 @@ $lang->doc->keywords = '关键字';
$lang->doc->url = '文档URL';
$lang->doc->files = '附件';
$lang->doc->addedBy = '由谁添加';
$lang->doc->addedByAB = '创建者';
$lang->doc->addedDate = '添加时间';
$lang->doc->editedBy = '由谁更新';
$lang->doc->editedDate = '更新时间';
$lang->doc->lastEditedBy = '最后更新者';
$lang->doc->version = '版本号';
$lang->doc->basicInfo = '基本信息';
$lang->doc->deleted = '已删除';
+17 -22
View File
@@ -194,13 +194,6 @@ $config->execution->datatable->fieldList['name']['fixed'] = 'left';
$config->execution->datatable->fieldList['name']['width'] = 'auto';
$config->execution->datatable->fieldList['name']['required'] = 'yes';
if(!isset($config->setCode) or $config->setCode == 1)
{
$config->execution->datatable->fieldList['code']['title'] = 'execCode';
$config->execution->datatable->fieldList['code']['fixed'] = 'no';
$config->execution->datatable->fieldList['code']['width'] = '95';
$config->execution->datatable->fieldList['code']['required'] = 'no';
}
if($config->systemMode == 'new')
{
@@ -210,21 +203,23 @@ if($config->systemMode == 'new')
$config->execution->datatable->fieldList['project']['required'] = 'no';
}
$config->execution->datatable->fieldList['PM']['title'] = 'owner';
$config->execution->datatable->fieldList['PM']['fixed'] = 'no';
$config->execution->datatable->fieldList['PM']['width'] = '70';
$config->execution->datatable->fieldList['PM']['required'] = 'no';
if(!isset($config->setCode) or $config->setCode == 1)
{
$config->execution->datatable->fieldList['code']['title'] = 'execCode';
$config->execution->datatable->fieldList['code']['fixed'] = 'no';
$config->execution->datatable->fieldList['code']['width'] = '95';
$config->execution->datatable->fieldList['code']['required'] = 'no';
}
$config->execution->datatable->fieldList['status']['title'] = 'execStatus';
$config->execution->datatable->fieldList['status']['fixed'] = 'no';
$config->execution->datatable->fieldList['status']['width'] = '100';
$config->execution->datatable->fieldList['status']['required'] = 'no';
$config->execution->datatable->fieldList['progress']['title'] = 'progress';
$config->execution->datatable->fieldList['progress']['fixed'] = 'no';
$config->execution->datatable->fieldList['progress']['width'] = '70';
$config->execution->datatable->fieldList['progress']['required'] = 'no';
$config->execution->datatable->fieldList['progress']['sort'] = 'no';
$config->execution->datatable->fieldList['PM']['title'] = 'owner';
$config->execution->datatable->fieldList['PM']['fixed'] = 'no';
$config->execution->datatable->fieldList['PM']['width'] = '70';
$config->execution->datatable->fieldList['PM']['required'] = 'no';
$config->execution->datatable->fieldList['openedDate']['title'] = 'openedDate';
$config->execution->datatable->fieldList['openedDate']['fixed'] = 'no';
@@ -253,12 +248,6 @@ $config->execution->datatable->fieldList['realEnd']['width'] = '90';
$config->execution->datatable->fieldList['realEnd']['required'] = 'no';
$config->execution->datatable->fieldList['realEnd']['sort'] = 'no';
$config->execution->datatable->fieldList['teamCount']['title'] = 'teamCount';
$config->execution->datatable->fieldList['teamCount']['fixed'] = 'no';
$config->execution->datatable->fieldList['teamCount']['width'] = '80';
$config->execution->datatable->fieldList['teamCount']['required'] = 'no';
$config->execution->datatable->fieldList['teamCount']['sort'] = 'no';
$config->execution->datatable->fieldList['estimate']['title'] = 'estimate';
$config->execution->datatable->fieldList['estimate']['fixed'] = 'no';
$config->execution->datatable->fieldList['estimate']['width'] = '70';
@@ -277,6 +266,12 @@ $config->execution->datatable->fieldList['left']['width'] = '70';
$config->execution->datatable->fieldList['left']['required'] = 'no';
$config->execution->datatable->fieldList['left']['sort'] = 'no';
$config->execution->datatable->fieldList['progress']['title'] = 'progress';
$config->execution->datatable->fieldList['progress']['fixed'] = 'no';
$config->execution->datatable->fieldList['progress']['width'] = '70';
$config->execution->datatable->fieldList['progress']['required'] = 'no';
$config->execution->datatable->fieldList['progress']['sort'] = 'no';
$config->execution->datatable->fieldList['burn']['title'] = 'burn';
$config->execution->datatable->fieldList['burn']['fixed'] = 'no';
$config->execution->datatable->fieldList['burn']['width'] = '80';
+4 -1
View File
@@ -516,7 +516,10 @@ class execution extends control
$this->app->loadClass('pager', $static = true);
$recTotal = count($tasks2Imported);
$pager = new pager($recTotal, $recPerPage, $pageID);
$tasks2ImportedList = array_chunk($tasks2Imported, $pager->recPerPage, true);
$tasks2ImportedList = empty($tasks2ImportedList) ? $tasks2ImportedList : $tasks2ImportedList[$pageID - 1];
$tasks2ImportedList = $this->loadModel('task')->processTasks($tasks2ImportedList);
/* Save session. */
$this->app->session->set('taskList', $this->app->getURI(true), 'execution');
@@ -525,7 +528,7 @@ class execution extends control
$this->view->pager = $pager;
$this->view->position[] = html::a(inlink('browse', "executionID=$toExecution"), $execution->name);
$this->view->position[] = $this->lang->execution->importTask;
$this->view->tasks2Imported = empty($tasks2ImportedList) ? $tasks2ImportedList : $tasks2ImportedList[$pageID - 1];
$this->view->tasks2Imported = $tasks2ImportedList;
$this->view->executions = $executions;
$this->view->executionID = $execution->id;
$this->view->fromExecution = $fromExecution;
+1
View File
@@ -10,3 +10,4 @@
.c-severity {width: 80px;}
.c-confirmed {overflow: hidden;}
.c-deadline {text-align: center;}
#main {padding-bottom: 40px;}
+1 -1
View File
@@ -10,4 +10,4 @@
#taskList .c-progress{padding-right: 8px; text-align: right;}
#datatable-taskList .c-progress{padding-right: 8px; text-align: right;}
.c-finishedBy, .c-lastEditedBy {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
#executionTaskForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
#executionTaskForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
+24
View File
@@ -0,0 +1,24 @@
$(function()
{
$('#testtaskForm').table(
{
replaceId: 'taskIdList',
statisticCreator: function(table)
{
var $table = table.getTable();
var $checkedRows = $table.find('tbody>tr.checked');
var checkedTotal = $checkedRows.length;
var checkedWait = $checkedRows.filter("[data-status=wait]").length;
var checkedTesting = $checkedRows.filter("[data-status=doing]").length;
var checkedBlocked = $checkedRows.filter("[data-status=blocked]").length;
var checkedDone = $checkedRows.filter("[data-status=done]").length;
var checkedStatistics = checkedAllSummary.replace('%total%', checkedTotal)
.replace('%wait%', checkedWait)
.replace('%testing%', checkedTesting)
.replace('%blocked%', checkedBlocked)
.replace('%done%', checkedDone);
return checkedTotal ? checkedStatistics : pageSummary;
}
});
});
+6 -6
View File
@@ -362,7 +362,7 @@ class executionModel extends model
}
/* Check the workload format and total. */
if(!empty($sprint->percent)) $this->checkWorkload('create', $sprint->percent);
if(!empty($sprint->percent)) $this->checkWorkload('create', $sprint->percent, $sprint->project);
/* Set planDuration and realDuration. */
if($this->config->edition == 'max')
@@ -1147,9 +1147,9 @@ class executionModel extends model
/**
* Check the workload format and total.
*
* @param string $type create|update
* @param int $percent
* @param object $oldExecution
* @param string $type create|update
* @param int $percent
* @param object|int $oldExecution
* @access public
* @return bool
*/
@@ -1170,7 +1170,7 @@ class executionModel extends model
->andWhere('t2.type')->eq('stage')
->andWhere('t2.grade')->eq(1)
->andWhere('t2.deleted')->eq(0)
->andWhere('t2.parent')->eq($oldExecution->parent)
->andWhere('t2.parent')->eq($oldExecution)
->fetch('total');
if($type == 'create') $percentTotal = $percent + $oldPercentTotal;
@@ -4612,7 +4612,7 @@ class executionModel extends model
}
if(empty($execution->children))
{
echo html::a(helper::createLink('execution', 'view', "executionID=$execution->id"), $execution->name);
echo html::a(helper::createLink('execution', 'view', "executionID=$execution->id"), $execution->name, '', 'class="text-ellipsis"');
if(!helper::isZeroDate($execution->end))
{
if($execution->status != 'closed')
+2 -2
View File
@@ -49,8 +49,8 @@
<thead>
<tr>
<th class="c-id-sm"><?php echo $lang->build->id;?></th>
<th class="c-name w-200px text-left"><?php echo $lang->build->product;?></th>
<th class="c-name text-left"><?php echo $lang->build->name;?></th>
<th class="c-name w-200px text-left"><?php echo $lang->build->product;?></th>
<th class="c-url"><?php echo $lang->build->scmPath;?></th>
<th class="c-url"><?php echo $lang->build->filePath;?></th>
<th class="c-date"><?php echo $lang->build->date;?></th>
@@ -63,11 +63,11 @@
<?php foreach($builds as $index => $build):?>
<tr data-id="<?php echo $productID;?>">
<td class="c-id-sm text-muted"><?php echo html::a(helper::createLink('build', 'view', "buildID=$build->id"), sprintf('%03d', $build->id));?></td>
<td class="c-name text-left" title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
<td class="c-name">
<?php if($build->branchName) echo "<span class='label label-outline label-badge'>{$build->branchName}</span>"?>
<?php echo html::a($this->createLink('build', 'view', "build=$build->id"), $build->name);?>
</td>
<td class="c-name text-left" title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
<td class="c-url" title="<?php echo $build->scmPath?>"><?php echo strpos($build->scmPath, 'http') === 0 ? html::a($build->scmPath) : $build->scmPath;?></td>
<td class="c-url" title="<?php echo $build->filePath?>"><?php echo strpos($build->filePath, 'http') === 0 ? html::a($build->filePath) : $build->filePath;?></td>
<td class="c-date"><?php echo $build->date?></td>
+19 -6
View File
@@ -33,6 +33,12 @@
<?php endif;?>
</div>
</div>
<?php
$waitCount = 0;
$testingCount = 0;
$blockedCount = 0;
$doneCount = 0;
?>
<div id="mainContent">
<?php if(empty($tasks)):?>
<div class="table-empty-tip">
@@ -44,7 +50,7 @@
</p>
</div>
<?php else:?>
<form class="main-table table-testtask" data-ride="table" data-group="true" method="post" target='hiddenwin' id='testtaskForm'>
<form class="main-table table-testtask" data-group="true" method="post" target='hiddenwin' id='testtaskForm'>
<table class="table table-grouped has-sort-head" id='taskList'>
<thead>
<?php $vars = "executionID=$executionID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
@@ -61,10 +67,10 @@
</th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $lang->testtask->name);?></th>
<th><?php common::printOrderLink('build', $orderBy, $vars, $lang->testtask->build);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-user'><?php common::printOrderLink('owner', $orderBy, $vars, $lang->testtask->owner);?></th>
<th class='c-date'><?php common::printOrderLink('begin', $orderBy, $vars, $lang->testtask->begin);?></th>
<th class='c-date'><?php common::printOrderLink('end', $orderBy, $vars, $lang->testtask->end);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-actions-5 text-center'><?php echo $lang->actions;?></th>
</tr>
</thead>
@@ -72,7 +78,11 @@
<?php foreach($tasks as $product => $productTasks):?>
<?php $productName = zget($products, $product, '');?>
<?php foreach($productTasks as $task):?>
<tr data-id='<?php echo $product;?>' <?php if($task == reset($productTasks)) echo "class='divider-top'";?>>
<?php if($task->status == 'wait') $waitCount ++;?>
<?php if($task->status == 'doing') $testingCount ++;?>
<?php if($task->status == 'blocked') $blockedCount ++;?>
<?php if($task->status == 'done') $doneCount ++;?>
<tr data-id='<?php echo $product;?>' <?php if($task == reset($productTasks)) echo "class='divider-top'";?> data-status='<?php echo $task->status;?>'>
<?php if($task == reset($productTasks)):?>
<td rowspan='<?php echo count($productTasks);?>' class='c-side text-left group-toggle'>
<a class='text-primary' title='<?php echo $productName;?>'><i class='icon icon-caret-down'></i> <?php echo $productName;?></a>
@@ -88,13 +98,13 @@
</td>
<td class='text-left' title="<?php echo $task->name?>"><?php echo html::a($this->createLink('testtask', 'cases', "taskID=$task->id"), $task->name, '', "data-app='execution'");?></td>
<td title="<?php echo $task->buildName?>"><?php echo ($task->build == 'trunk' || empty($task->buildName)) ? $lang->trunk : html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName);?></td>
<td><?php echo zget($users, $task->owner);?></td>
<td><?php echo $task->begin?></td>
<td><?php echo $task->end?></td>
<?php $status = $this->processStatus('testtask', $task);?>
<td title='<?php echo $status;?>'>
<span class='status-testtask status-<?php echo $task->status?>'><?php echo $status;?></span>
</td>
<td><?php echo zget($users, $task->owner);?></td>
<td><?php echo $task->begin?></td>
<td><?php echo $task->end?></td>
<td class='c-actions'>
<?php
if($canBeChanged)
@@ -136,9 +146,12 @@
?>
</div>
<?php endif;?>
<div class="table-statistic"><?php echo sprintf($lang->testtask->allSummary, $total, $waitCount, $testingCount, $blockedCount, $doneCount);?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
<?php endif;?>
</div>
<?php js::set('pageSummary', sprintf($lang->testtask->allSummary, $total, $waitCount, $testingCount, $blockedCount, $doneCount));?>
<?php js::set('checkedAllSummary', $lang->testtask->checkedAllSummary);?>
<?php include '../../common/view/footer.html.php';?>
+49
View File
@@ -1372,6 +1372,55 @@ class kanban extends control
$this->display();
}
/**
* Import ticket.
*
* @param int $kanbanID
* @param int $regionID
* @param int $groupID
* @param int $columnID
* @param int $selectedProductID
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function importTicket($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
if($_POST)
{
$importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'ticket');
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
foreach($importedIDList as $cardID => $ticketID)
{
$this->loadModel('action')->create('kanbancard', $cardID, 'importedTicket', '', $ticketID);
}
return print(js::locate($this->createLink('kanban', 'view', "kanbanID=$kanbanID"), 'parent.parent'));
}
$this->loadModel('product');
$this->loadModel('ticket');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
$this->view->products = array($this->lang->kanban->allProducts) + $this->product->getPairs();
$this->view->selectedProductID = $selectedProductID;
$this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
$this->view->tickets2Imported = $this->ticket->getTicketByProduct($selectedProductID, '', 'id_desc', $pager);
$this->view->pager = $pager;
$this->view->kanbanID = $kanbanID;
$this->view->regionID = $regionID;
$this->view->groupID = $groupID;
$this->view->columnID = $columnID;
$this->display();
}
/**
* Set a card's color.
*
+88 -1
View File
@@ -343,6 +343,10 @@ function renderKanbanItem(item, $item)
{
renderProductplanItem(item, $item);
}
else if(item.fromType == 'ticket')
{
renderTicketItem(item, $item);
}
else
{
if(!$title.length)
@@ -746,6 +750,88 @@ function renderBuildItem(item, $item)
}
}
/**
* Render execution item.
*
* @param object item
* @param object $item
* @access public
* @return void
*/
function renderTicketItem(item, $item)
{
/* Output header information. */
var privs = item.actions;
if(privs.includes('sortCard')) $item.parent().addClass('sort');
var $header = $item.children('.header');
if(!$header.length) $header = $(
[
'<div class="header">',
'</div>'
].join('')).appendTo($item);
var $titleBox = $header.children('.ticketTitle');
if(!$titleBox.length) $titleBox = $(
[
'<div class="ticketTitle">',
'</div>'
].join('')).appendTo($header);
/* Print ticket name. */
var $title = $titleBox.children('.title');
var name = item.title ? item.title : item.name;
if(!$title.length)
{
var icon = 'file-text';
if(privs.includes('viewTicket') && item.deleted == '0') $title = $('<a class="title"><i class="icon icon-' + icon + '"></i>' + name + '</a>').appendTo($titleBox).attr('href', createLink('ticket', 'view', 'ticketID=' + item.fromID));
if(!privs.includes('viewTicket') || item.deleted == '1') $title = $('<div class="title"><i class="icon icon-' + icon + '"></i>' + name + '</div>').appendTo($titleBox);
}
$title.attr('title', name);
$item.data('card', item);
var $info = $item.children('.info');
if(!$info.length) $info = $(
[
'<div class="info">',
'</div>'
].join('')).appendTo($item);
var $statusBox = $info.children('.execStatus');
if(!$statusBox.length)
{
if(item.deleted == '0')
{
$statusBox = $('<span class="execStatus label label-' + item.objectStatus + '">' + ticketLang.statusList[item.objectStatus] + '</span>').appendTo($info);
}
else
{
$statusBox = $('<span class="execStatus label label-deleted">' + ticketLang.deleted + '</span>').appendTo($info);
}
}
/* Display deadline of execution. */
if(item.deadline != '0000-00-00')
{
var $date = $info.children('.date');
var deadline = $.zui.createDate(item.deadline);
var today = new Date();
var labelType = deadline.toLocaleDateString() == today.toLocaleDateString() ? 'danger' : 'wait';
if(!$date.length) $date = $('<span class="date label label-' + labelType + '"></span>').appendTo($info);
$date.text($.zui.formatDate(deadline, 'MM-dd') + ' ' + kanbancardLang.deadlineAB).attr('title', $.zui.formatDate(deadline, 'yyyy-MM-dd') + ' ' + kanbancardLang.deadlineAB).show();
}
/* Display avatars of ticket assignedTo. */
var $user = $info.children('.user');
var user = [item.assignedTo];
if(users[item.assignedTo])
{
if(!$user.length) $user = $('<div class="user"></div>').appendTo($info);
$user.html(renderUsersAvatar(user, item.id)).attr('title', users[item.assignedTo]);
}
}
/**
* Show error message
* @param {string|object} message Message
@@ -1505,7 +1591,8 @@ $(function()
var importReleaseLink = kanban.object.indexOf('releases') != -1 ? "<li><a class='iframe' data-toggle='modal'' href='" + createLink('kanban', 'importRelease', 'kanbanID=' + kanban.id + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importRelease + '</a></li>' : '';
var importExecutionLink = kanban.object.indexOf('executions') != -1 ? "<li><a class='iframe' data-toggle='modal' href='" + createLink('kanban', 'importExecution', 'kanbanID=' + kanban.id + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importExecution + '</a></li>' : '';
var importBuildLink = kanban.object.indexOf('builds') != -1 ? "<li><a class='iframe' data-toggle='modal' href='" + createLink('kanban', 'importBuild', 'kanbanID=' + kanban.id + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importBuild + '</a></li>' : '';
var importSubmenu = '<ul class="dropdown-menu">' + importPlanLink + importReleaseLink + importExecutionLink + importBuildLink +'</ul>';
var importTicketLink = kanban.object.indexOf('tickets') != -1 ? "<li><a class='iframe' data-toggle='modal' href='" + createLink('kanban', 'importTicket', 'kanbanID=' + kanban.id + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID) + "'>" + kanbanLang.importTicket + '</a></li>' : '';
var importSubmenu = '<ul class="dropdown-menu">' + importPlanLink + importReleaseLink + importExecutionLink + importBuildLink + importTicketLink + '</ul>';
$('.import').parent().append(importSubmenu);
});
+2
View File
@@ -83,6 +83,7 @@ $lang->kanban->importPlan = 'Plan';
$lang->kanban->importRelease = 'Release';
$lang->kanban->importExecution = $lang->execution->common;
$lang->kanban->importBuild = 'Build';
$lang->kanban->importTicket = 'Ticket';
$lang->kanban->allKanban = 'All Kanban';
$lang->kanban->allProjects = 'All ' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : 'Projects');
$lang->kanban->allProducts = 'All Products';
@@ -236,6 +237,7 @@ $lang->kanban->importObjectList['plans'] = 'Product Plan';
$lang->kanban->importObjectList['releases'] = 'Release';
$lang->kanban->importObjectList['builds'] = 'Build';
$lang->kanban->importObjectList['executions'] = 'Execution';
if($this->config->edition != 'open') $lang->kanban->importObjectList['tickets'] = 'Ticket';
$lang->kanban->importObjectList['cards'] = 'Other Kanban Cards';
$lang->kanban->showWIPList[1] = 'Show';
+2
View File
@@ -83,6 +83,7 @@ $lang->kanban->importPlan = 'Plan';
$lang->kanban->importRelease = 'Release';
$lang->kanban->importExecution = $lang->execution->common;
$lang->kanban->importBuild = 'Build';
$lang->kanban->importTicket = 'Ticket';
$lang->kanban->allKanban = 'All Kanban';
$lang->kanban->allProjects = 'All ' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : 'Projects');
$lang->kanban->allProducts = 'All Products';
@@ -236,6 +237,7 @@ $lang->kanban->importObjectList['plans'] = 'Product Plan';
$lang->kanban->importObjectList['releases'] = 'Release';
$lang->kanban->importObjectList['builds'] = 'Build';
$lang->kanban->importObjectList['executions'] = 'Execution';
if($this->config->edition != 'open') $lang->kanban->importObjectList['tickets'] = 'Ticket';
$lang->kanban->importObjectList['cards'] = 'Other Kanban Cards';
$lang->kanban->showWIPList[1] = 'Show';
+2
View File
@@ -83,6 +83,7 @@ $lang->kanban->importPlan = 'Plan';
$lang->kanban->importRelease = 'Release';
$lang->kanban->importExecution = $lang->execution->common;
$lang->kanban->importBuild = 'Build';
$lang->kanban->importTicket = 'Ticket';
$lang->kanban->allKanban = 'All Kanban';
$lang->kanban->allProjects = 'All ' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : 'Projects');
$lang->kanban->allProducts = 'All Products';
@@ -236,6 +237,7 @@ $lang->kanban->importObjectList['plans'] = 'Product Plan';
$lang->kanban->importObjectList['releases'] = 'Release';
$lang->kanban->importObjectList['builds'] = 'Build';
$lang->kanban->importObjectList['executions'] = 'Execution';
if($this->config->edition != 'open') $lang->kanban->importObjectList['tickets'] = 'Ticket';
$lang->kanban->importObjectList['cards'] = 'Other Kanban Cards';
$lang->kanban->showWIPList[1] = 'Show';
+2
View File
@@ -83,6 +83,7 @@ $lang->kanban->importPlan = '计划';
$lang->kanban->importRelease = '发布';
$lang->kanban->importExecution = $lang->execution->common;
$lang->kanban->importBuild = '版本';
$lang->kanban->importTicket = '工单';
$lang->kanban->allKanban = '所有看板';
$lang->kanban->allProjects = '所有' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : '项目');
$lang->kanban->allProducts = '所有产品';
@@ -236,6 +237,7 @@ $lang->kanban->importObjectList['plans'] = '计划';
$lang->kanban->importObjectList['releases'] = '发布';
$lang->kanban->importObjectList['builds'] = '版本';
$lang->kanban->importObjectList['executions'] = $lang->execution->common;
if($this->config->edition != 'open') $lang->kanban->importObjectList['tickets'] = '工单';
$lang->kanban->importObjectList['cards'] = '其他看板卡片';
$lang->kanban->showWIPList[1] = '显示';
+2 -2
View File
@@ -1127,7 +1127,7 @@ class kanbanModel extends model
->andWhere('type')->eq('common')
->fetchAll();
$actions = array('editCard', 'archiveCard', 'deleteCard', 'moveCard', 'setCardColor', 'viewCard', 'sortCard', 'viewExecution', 'viewPlan', 'viewRelease', 'viewBuild');
$actions = array('editCard', 'archiveCard', 'deleteCard', 'moveCard', 'setCardColor', 'viewCard', 'sortCard', 'viewExecution', 'viewPlan', 'viewRelease', 'viewBuild', 'viewTicket');
$cardGroup = array();
foreach($cellList as $cell)
{
@@ -1146,7 +1146,7 @@ class kanbanModel extends model
$card->actions = array();
foreach($actions as $action)
{
if(in_array($action, array('viewExecution', 'viewPlan', 'viewRelease', 'viewBuild')))
if(in_array($action, array('viewExecution', 'viewPlan', 'viewRelease', 'viewBuild', 'viewTicket')))
{
if($card->fromType == 'execution')
{
+86
View File
@@ -0,0 +1,86 @@
<?php
/**
* The import release view of kanban module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Qiyu Xie<xieqiyu@cnezsoft.com>
* @package kanban
* @version $Id: importrelease.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php js::set('kanbanID', $kanbanID);?>
<?php js::set('regionID', $regionID);?>
<?php js::set('groupID', $groupID);?>
<?php js::set('columnID', $columnID);?>
<?php js::set('methodName', $this->app->rawMethod);?>
<div id='mainContent' class='main-content importModal'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->kanban->importAB . $lang->kanban->importTicket;?></h2>
</div>
</div>
<div class='input-group space'>
<span class='input-group-addon'><?php echo $lang->kanban->selectedProduct;?></span>
<?php echo html::select('product', $products, $selectedProductID, "onchange='reloadObjectList(this.value)' class='form-control chosen' data-drop_direction='down'");?>
<span class='input-group-addon'><?php echo $lang->kanban->selectedLane;?></span>
<?php echo html::select('lane', $lanePairs, '', "onchange='setTargetLane(this.value)' class='form-control chosen' data-drop_direction='down'");?>
</div>
<?php if($tickets2Imported):?>
<form class='main-table' method='post' data-ride='table' target='hiddenwin' id='importTicketForm'>
<table class='table table-fixed' id='ticketList'>
<thead>
<tr>
<th class="c-id">
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php echo $lang->idAB;?>
</th>
<th class='c-name'><?php echo $lang->ticket->title;?></th>
<th class='c-pri'><?php echo $lang->ticket->priAB;?></th>
<th class='c-type'><?php echo $lang->ticket->type;?></th>
<th><?php echo $lang->ticket->createdDate;?></th>
<th class='c-name'><?php echo $lang->ticket->assignedTo;?></th>
</tr>
</thead>
<tbody>
<?php foreach($tickets2Imported as $ticket):?>
<tr>
<td class='c-id'>
<div class="checkbox-primary">
<input type='checkbox' name='tickets[]' value='<?php echo $ticket->id;?>'/>
<label></label>
</div>
<?php printf('%03d', $ticket->id);?>
</td>
<?php if(common::hasPriv('ticket', 'view')):?>
<td title='<?php echo $ticket->title;?>'>
<a href='javascript:void(0);' onclick="locateView('ticket', <?php echo $ticket->id;?>)"><?php echo $ticket->title;?></a>
</td>
<?php else:?>
<td title='<?php echo $ticket->title;?>'><?php echo $ticket->title;?></td>
<?php endif;?>
<td><span class='label-pri label-pri-<?php echo $ticket->pri;?>' title='<?php echo zget($this->lang->ticket->priList, $ticket->pri, $ticket->pri);?>'><?php echo zget($this->lang ->ticket->priList, $ticket->pri, $ticket->pri); ?></span></td>
<td title='<?php echo zget($this->lang->ticket->typeList, $ticket->type, $ticket->type);?>'><?php echo zget($this->lang->ticket->typeList, $ticket->type, $ticket->type);?></td>
<td title='<?php echo $ticket->openedDate;?>'><?php echo $ticket->openedDate;?></td>
<td title='<?php echo $ticket->assignedTo;?>'><?php echo $ticket->assignedTo;?></td>
</tr>
<?php endforeach;?>
<tr><?php echo html::hidden('targetLane', key($lanePairs));?></tr>
</tbody>
</table>
<div class='table-footer'>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar show-always"><?php echo html::submitButton($lang->kanban->importAB, '', 'btn btn-default');?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
<?php else:?>
<div class='table-empty-tip'><?php echo $lang->noData;?></div>
<?php endif;?>
</div>
<style>#product_chosen {width: 45% !important}</style>
<?php include '../../common/view/footer.lite.html.php';?>
+13 -1
View File
@@ -754,6 +754,10 @@ class mailModel extends model
{
$sendUsers = array($object->auditedBy, '');
}
elseif($objectType == 'ticket')
{
$sendUsers = $this->{$objectType}->getToAndCcList($object, $action);
}
else
{
$sendUsers = $this->{$objectType}->getToAndCcList($object);
@@ -785,7 +789,15 @@ class mailModel extends model
}
else
{
$this->send($toList, $subject, $mailContent, $ccList);
if($objectType == 'ticket')
{
$emails = $this->loadModel('ticket')->getContactEmails($objectID, $toList, $ccList, $action->action == 'closed');
$this->send($toList, $subject, $mailContent, $ccList, false, $emails);
}
else
{
$this->send($toList, $subject, $mailContent, $ccList);
}
}
if($this->isError()) error_log(join("\n", $this->getError()));
}
+52
View File
@@ -108,6 +108,7 @@ class my extends control
$this->loadModel('bug');
$this->loadModel('testcase');
$this->loadModel('testtask');
$this->loadModel('ticket');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
@@ -198,6 +199,9 @@ class my extends control
/* Get the number of meetings assigned to me. */
$meetings = $this->meeting->getListByUser('futureMeeting', 'id_desc', 0, $pager);
$meetingCount = $pager->recTotal;
$ticketList = $this->ticket->getList('assignedtome', 'id_desc', $pager);
$ticketCount = $pager->recTotal;
}
echo <<<EOF
@@ -223,6 +227,7 @@ if(isMax !== 0)
var reviewCount = $reviewCount;
var qaCount = $qaCount;
var meetingCount = $meetingCount;
var ticketCount = $ticketCount;
}
</script>
EOF;
@@ -1113,6 +1118,9 @@ EOF;
$this->view->users = $this->loadModel('user')->getPairs('all,noletter');
$this->view->queryID = $queryID;
$this->view->mode = 'myMeeting';
$this->view->projects = array(0 => '') + $this->loadModel('project')->getPairsByProgram('', 'all', true);
$this->view->executions = array(0 => '') + $this->loadModel('execution')->getPairs(0, 'all', 'nocode');
$this->view->rooms = array('' => '') + $this->loadModel('meetingroom')->getPairs();
$this->display();
}
@@ -1209,6 +1217,50 @@ EOF;
$this->display();
}
/**
* My ticket.
*
* @param string $browseType
* @param string $param
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function ticket($browseType = 'assignedtome', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$this->loadModel('ticket');
$queryID = $browseType == 'bysearch' ? (int)$param : 0;
$this->session->set('ticketList', $this->app->getURI(true), 'feedback');
$this->app->loadClass('pager', $static = true);
$pager = pager::init($recTotal, $recPerPage, $pageID);
if($browseType != 'bysearch')
{
$tickets = $this->ticket->getList($browseType, $orderBy, $pager);
}
else
{
$tickets = $this->ticket->getBySearch($queryID, $orderBy, $pager);
}
$actionURL = $this->createLink('my', 'work', "mode=ticket&type=bysearch&param=myQueryID&orderBy={$orderBy}&recTotal={$recTotal}&recPerPage={$recPerPage}&pageID={$pageID}");
$this->my->buildTicketSearchForm($queryID, $actionURL);
$this->view->title = $this->lang->ticket->browse;
$this->view->products = $this->loadModel('feedback')->getGrantProducts();
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noletter');
$this->view->tickets = $tickets;
$this->view->orderBy = $orderBy;
$this->view->pager = $pager;
$this->view->browseType = $browseType;
$this->display();
}
/**
* My team.
*
+5
View File
@@ -0,0 +1,5 @@
.c-pri {width: 75px;}
.c-openedDate {width: 210px;}
.c-assignedTo {width: 100px;}
.no-wrap{text-overflow: ellipsis; white-space: nowrap; overflow: hidden;}
+1
View File
@@ -21,6 +21,7 @@ $(function()
$("#subNavbar li[data-id='audit'] a").append('<span class="label label-light label-badge">' + reviewCount + '</span>');
$("#subNavbar li[data-id='nc'] a").append('<span class="label label-light label-badge">' + qaCount + '</span>');
$("#subNavbar li[data-id='myMeeting'] a").append('<span class="label label-light label-badge">' + meetingCount + '</span>');
$("#subNavbar li[data-id='ticket'] a").append('<span class="label label-light label-badge">' + ticketCount + '</span>');
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ $(function()
if($td.find('.label').length > 0) labelWidth = $td.find('.label').width();
$td.find('a').eq(0).css('max-width', $td.width() - labelWidth - 60);
});
toggleFold('#myStoryForm', [], 0, 'story');
$(document).on('click', '.story-toggle', function(e)
{
var $toggle = $(this);
+18
View File
@@ -21,4 +21,22 @@ $(function()
type: 'iframe'
}).trigger('click');
}
$('#todoForm').table(
{
replaceId: 'todoIDList',
statisticCreator: function(table)
{
var $table = table.getTable();
var $checkedRows = $table.find('tbody>tr.checked');
var checkedTotal = $checkedRows.length;
var checkedWait = $checkedRows.filter("[data-status=wait]").length;
var checkedDoing = $checkedRows.filter("[data-status=doing]").length;
var checkedStatistics = checkedSummary.replace('%total%', checkedTotal)
.replace('%wait%', checkedWait)
.replace('%doing%', checkedDoing);
return checkedTotal ? checkedStatistics : pageSummary;
}
});
});
+25
View File
@@ -906,6 +906,31 @@ class myModel extends model
$this->loadModel('search')->setSearchParams($this->config->product->search);
}
/**
* Build ticket search form.
*
* @param string $queryID
* @param string $actionURL
* @access public
* @return mixed
*/
public function buildTicketSearchForm($queryID, $actionURL)
{
$this->loadModel('ticket');
$this->app->loadConfig('ticket');
$this->config->ticket->search['module'] = 'workTicket';
$this->config->ticket->search['queryID'] = $queryID;
$this->config->ticket->search['actionURL'] = $actionURL;
$this->config->ticket->search['params']['product']['values'] = array('' => '') + $this->loadModel('feedback')->getGrantProducts();
$this->config->ticket->search['params']['module']['values'] = array('' => '') + $this->loadModel('tree')->getAllModulePairs();
$grantProducts = $this->loadModel('feedback')->getGrantProducts();
$productIDlist = array_keys($grantProducts);
$this->config->ticket->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productIDlist);
$this->loadModel('search')->setSearchParams($this->config->ticket->search);
}
/**
* Get requirements by search.
*
+7 -1
View File
@@ -41,9 +41,12 @@
<th class="c-name c-object"><?php echo $lang->doc->object;?></th>
<th class="c-num"><?php echo $lang->doc->size;?></th>
<?php if($type != 'openedbyme'):?>
<th class="c-user"><?php echo $lang->doc->addedBy;?></th>
<th class="c-user"><?php echo $lang->doc->addedByAB;?></th>
<?php endif;?>
<th class="c-datetime"><?php echo $lang->doc->addedDate;?></th>
<?php if($type == 'openedbyme'):?>
<th class="c-user"><?php echo $lang->doc->lastEditedBy;?></th>
<?php endif;?>
<th class="c-datetime"><?php echo $lang->doc->editedDate;?></th>
<th class="c-actions-3 text-center"><?php echo $lang->actions;?></th>
</tr>
@@ -68,6 +71,9 @@
<td class="c-user"><?php echo zget($users, $doc->addedBy);?></td>
<?php endif;?>
<td class="c-datetime"><?php echo formatTime($doc->addedDate, 'y-m-d');?></td>
<?php if($type == 'openedbyme'):?>
<td class="c-user"><?php echo zget($users, $doc->editedBy);?></td>
<?php endif;?>
<td class="c-datetime"><?php echo formatTime($doc->editedDate, 'y-m-d');?></td>
<td class="c-actions">
<?php if(common::canBeChanged('doc', $doc)):?>
+1 -1
View File
@@ -84,7 +84,7 @@
$storyLink = $this->createLink('story', 'view', "id=$story->id");
$canBeChanged = common::canBeChanged('story', $story);
?>
<tr>
<tr data-id='<?php echo $story->id?>'>
<td class="c-id">
<?php if($canBatchAction):?>
<div class="checkbox-primary">
-5
View File
@@ -126,11 +126,6 @@
<?php $storyChanged = (!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed')));?>
<?php $storyChanged ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$task->status}'> " . $this->processStatus('task', $task) . "</span>");?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri);?>'><?php echo zget($lang->task->priList, $task->pri);?></span></td>
<td class='c-status'>
<?php $storyChanged = (!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$task->status}'> " . $this->processStatus('task', $task) . "</span>");?>
</td>
<?php if($config->systemMode == 'new'):?>
<?php $projectName = isset($projects[$task->execution]->name) ? $projects[$task->execution]->name : '';?>
<?php $projectID = isset($projects[$task->execution]->id) ? $projects[$task->execution]->id : 0;?>
+13 -2
View File
@@ -44,13 +44,21 @@
</tr>
</thead>
<tbody>
<?php
$waitCount = 0;
$testingCount = 0;
$blockedCount = 0;
?>
<?php foreach($tasks as $task):?>
<?php if($task->status == 'wait') $waitCount ++;?>
<?php if($task->status == 'doing') $testingCount ++;?>
<?php if($task->status == 'blocked') $blockedCount ++;?>
<tr>
<td class="c-id"><?php printf('%03d', $task->id);?></td>
<td class='text-left nobr' title='<?php echo $task->name;?>'><?php echo html::a($this->createLink('testtask', 'view', "taskID=$task->id"), $task->name);?></td>
<td class='nobr' title='<?php echo $task->build == 'trunk' ? $lang->trunk : $task->buildName;?>'><?php $task->build == 'trunk' ? print($lang->trunk) : print(html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName));?></td>
<td class='nobr' title='<?php echo $task->executionName;?>'><?php echo $task->executionName;?></td>
<td title='<?php echo $this->processStatus('testtask', $task);?>'><span class="status-task status-<?php echo $task->status?>"><?php echo $this->processStatus('testtask', $task);?></span></td>
<td title='<?php echo $this->processStatus('testtask', $task);?>'><span class="status-task status-<?php echo $task->status;?>"><?php echo $this->processStatus('testtask', $task);?></span></td>
<td><?php echo $task->begin?></td>
<td><?php echo $task->end?></td>
<td class='c-actions'>
@@ -71,7 +79,10 @@
<?php endforeach;?>
</tbody>
</table>
<div class="table-footer"><?php $pager->show('right', 'pagerjs');?></div>
<div class="table-footer">
<div class="table-statistic"><?php echo $app->rawMethod == 'work' ? sprintf($lang->testtask->mySummary, count($tasks), $waitCount, $testingCount, $blockedCount) : sprintf($lang->testtask->pageSummary, count($tasks));?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</div>
<?php include '../../common/view/footer.html.php';?>
+71
View File
@@ -0,0 +1,71 @@
<?php
/**
* The ticket view file of my module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Xin Zhou <zhouxin@cnezsoft.com>
* @package my
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
<?php js::set('mode', 'ticket');?>
<?php js::set('rawMethod', $app->rawMethod);?>
<div id='mainMenu' class="clearfix">
<div class="btn-toolbar pull-left">
<?php
$recTotalLabel = " <span class='label label-light label-badge'>{$pager->recTotal}</span>";
echo html::a(inlink($app->rawMethod, "mode=ticket&type=assignedtome"), "<span class='text'>{$lang->my->taskMenu->assignedToMe}</span>" . ($browseType == 'assignedtome' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($browseType == 'assignedtome' ? ' btn-active-text' : '') . "'");
?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->user->search;?></a>
</div>
</div>
<div id='mainContent' class="main-row fade">
<div class="cell<?php if($browseType == 'bysearch') echo ' show';?>" id="queryBox" data-module='workTicket'></div>
<?php if(empty($tickets)):?>
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->ticket->noTicket;?></span>
</p>
</div>
<?php else:?>
<form class='main-table' id='opportunityForm' method='post' data-ride="table">
<table class="table has-sort-head" id='ticketList'>
<?php $vars = "browseType=$browseType&param=0&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
<?php $canView = common::hasPriv('ticket', 'view');?>
<thead>
<th class="c-id"><?php common::printOrderLink('id', $orderBy, $vars, $lang->ticket->idAB);?></th>
<th class="c-product"><?php common::printOrderLink('product', $orderBy, $vars, $lang->ticket->product);?></th>
<th class='c-title'><?php common::printOrderLink('title', $orderBy, $vars, $lang->ticket->title);?></th>
<th class='c-pri' title='<?php echo $lang->pri;?>'><?php common::printOrderLink('pri', $orderBy, $vars, $lang->ticket->priAB);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->ticket->status);?></th>
<th class="c-type"><?php common::printOrderLink('type', $orderBy, $vars, $lang->ticket->type);?></th>
<th class='c-openedBy'><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->ticket->createdBy);?></th>
<th class='c-openedDate'><?php common::printOrderLink('openedDate', $orderBy, $vars, $lang->ticket->createdDate);?></th>
<th class='c-assignedTo'><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->ticket->assignedTo);?></th>
<th class='c-actions'><?php echo $lang->actions;?></th>
</thead>
<tbody>
<?php foreach($tickets as $ticket): ?>
<tr>
<td class='c-id'><?php echo $canView ? html::a($this->createLink('ticket', 'view', "id={$ticket->id}"), $ticket->id) : $ticket->id;?></td>
<td class='no-wrap' title="<?php echo zget($products, $ticket->product);?>"><?php echo zget($products, $ticket->product);?></td>
<td class='no-wrap' title="<?php echo $ticket->title;?>"><?php echo $canView ? html::a($this->createLink('ticket', 'view', "id={$ticket->id}"), $ticket->title) : $ticket->title;?></td>
<td><span class='label-pri label-pri-<?php echo $ticket->pri;?>' title='<?php echo zget($lang->ticket->priList, $ticket->pri, $ticket->pri);?>'><?php echo zget($lang->ticket->priList, $ticket->pri); ?></span></td>
<td><?php echo zget($lang->ticket->statusList, $ticket->status);?></td>
<td><?php echo zget($lang->ticket->typeList, $ticket->type);?></td>
<td class='no-wrap' title="<?php echo zget($users, $ticket->openedBy);?>"><?php echo zget($users, $ticket->openedBy);?></td>
<td><?php echo $ticket->openedDate;?></td>
<td><?php echo $this->ticket->printAssignedHtml($ticket, $users);?></td>
<td class='c-actions'><?php echo $this->ticket->buildOperateBrowseMenu($ticket->id);?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'><?php $pager->show('right', 'pagerjs');?></div>
</form>
<?php endif;?>
</div>
<?php include $app->getModuleRoot() . 'common/view/footer.html.php';?>
+11 -2
View File
@@ -56,6 +56,10 @@
<?php endif;?>
</div>
</div>
<?php
$waitCount = 0;
$doingCount = 0;
?>
<div id="mainContent">
<?php if(empty($todos)):?>
<div class="table-empty-tip">
@@ -67,7 +71,7 @@
</p>
</div>
<?php else:?>
<form class="main-table table-todo" data-ride="table" method="post">
<form class="main-table table-todo" method="post" id='todoForm'>
<?php
$canBatchEdit = common::hasPriv('todo', 'batchEdit');
$canBatchFinish = common::hasPriv('todo', 'batchFinish');
@@ -105,7 +109,9 @@
</thead>
<tbody>
<?php foreach($todos as $todo):?>
<tr>
<?php if($todo->status == 'wait') $waitCount ++;?>
<?php if($todo->status == 'doing') $doingCount ++;?>
<tr data-status='<?php echo $todo->status;?>'>
<td class="c-id">
<?php if($canbatchAction):?>
<div class="checkbox-primary">
@@ -192,10 +198,13 @@
}
?>
</div>
<div class="table-statistic"><?php echo sprintf($lang->todo->summary, count($todos), $waitCount, $doingCount);?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
<?php endif;?>
</div>
<?php js::set('listName', 'todoList');?>
<?php js::set('pageSummary', sprintf($lang->todo->summary, count($todos), $waitCount, $doingCount));?>
<?php js::set('checkedSummary', $lang->todo->checkedSummary);?>
<?php include '../../common/view/footer.html.php';?>
+9 -1
View File
@@ -448,7 +448,15 @@ class portModel extends model
foreach($sysDataFields as $field)
{
$dataList[$field] = $this->loadModel($field)->getPairs();
if($field == 'user') $dataList[$field] = $this->loadModel($field)->getPairs('noclosed|nodeleted|noletter');
if($field == 'user')
{
$dataList[$field] = $this->loadModel($field)->getPairs('noclosed|nodeleted|noletter');
unset($dataList[$field]['']);
if(!in_array(strtolower($this->app->methodName) ,array('ajaxgettbody','ajaxgetoptions','showimport')))
{
foreach($dataList[$field] as $key => $value) $dataList[$field][$key] = $value . "(#$key)";
}
}
}
return $dataList;
+3 -1
View File
@@ -55,7 +55,7 @@ th.c-actions {width: 50px;}
#productListForm thead > tr > th.c-checkbox {border-left: none; padding-left: 15px; width: 30px;}
#productListForm tbody > tr > td {padding: 2px 4px;}
#productListForm tbody > tr > td:first-child {text-align: left; padding-left: 15px;}
#productListForm tbody > tr > td.table-nest-title {padding-left: 16px;}
#productListForm tbody > tr > td.table-nest-title {padding-left: 16px; display: flex; align-items: center;}
#productListForm th.table-nest-title .nest-has-checkbox {margin-top: 7px; margin-left: 35px;}
#productListForm th.table-nest-title .nest-none-checkbox {margin-top: 8px; margin-left: 5px;}
#productListForm th.table-nest-title .header {margin-left: 5px;}
@@ -100,3 +100,5 @@ th.c-actions {width: 50px;}
#productTableList .c-manager {padding-left: 14px;}
#productTableList .c-manager a {top: 7px; left: 22px;}
.checkbox-primary {margin-right: 10px;}
.table-nest-title > a, .table-nest-title > span {padding-left: 2px;}
.table-nest-icon {font-size: 14px; top: 50%;}
+2 -1
View File
@@ -20,7 +20,7 @@ a.removeModule:hover {color: red;}
.table-children {border-left: 2px solid #cbd0db; border-right: 2px solid #cbd0db;}
.table tbody > tr.table-children.table-child-top {border-top: 2px solid #cbd0db;}
.table tbody > tr.table-children.table-child-bottom {border-bottom: 2px solid #cbd0db;}
.table td.has-child > a:not(.story-toggle) {max-width: 90%; max-width: calc(100% - 30px); display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.table td.has-child > a:not(.story-toggle) {max-width: 90%; max-width: calc(100% - 50px); display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.table td.has-child > .story-toggle {color: #838a9d; position: relative; top: 1px;}
.table td.has-child > .story-toggle:hover {color: #006af1; cursor: pointer;}
.table td.has-child > .story-toggle > .icon {font-size: 16px; display: inline-block; transition: transform .2s; -ms-transform: rotate(-90deg); -moz-transform: rotate(-90deg); -o-transform: rotate(-90deg); -webkit-transform: rotate(-90deg); transform: rotate(-90deg);}
@@ -40,3 +40,4 @@ a.removeModule:hover {color: red;}
#mainMenu .dropdown-menu>li>a>.icon {top: 4px;}
#productStoryForm tbody tr td .label {max-width: 100px; text-overflow: unset;}
.c-span {margin-left: 19px;}
.btn-toolbar #query span.text{overflow: hidden; width: 52px; vertical-align: middle; margin-right: 1px;}
+2
View File
@@ -4,3 +4,5 @@
td.padding-right {padding-right: 20px !important}
.c-program {width: 150px;}
.c-progress {width: 70px;}
[lang^=zh].c-progress {width: 60px;}
-1
View File
@@ -9,4 +9,3 @@ td.acl {white-space: nowrap;}
.c-openedBy ,.c-acl ,.c-prs ,.c-common {width:110px !important;}
.c-bugs ,.c-type {width:120px !important;}
.c-release {padding-right: 20px !important;}
.c-feedback {padding-right: 20px !important;}
+1 -1
View File
@@ -11,7 +11,7 @@ $(function()
var $title = $('#storyList thead th.c-title');
var headerWidth = $('#storyList thead th.c-title a').innerWidth();
var buttonWidth = $('#storyList thead th.c-title button').innerWidth();
if($title.width() < headerWidth + buttonWidth) $title.width(headerWidth + buttonWidth + 10);
if($title.width() < headerWidth + buttonWidth) $title.width(headerWidth + buttonWidth + 20);
});
$('#storyList td.has-child .story-toggle').each(function()
-1
View File
@@ -39,4 +39,3 @@ $(function()
});
});
});
+2 -2
View File
@@ -214,8 +214,6 @@ $lang->product->noMatched = '"%s" kann nicht gefunden werden.' . $lang->pro
$lang->product->featureBar['browse']['allstory'] = $lang->product->allStory;
$lang->product->featureBar['browse']['unclosed'] = $lang->product->unclosed;
$lang->product->featureBar['browse']['assignedtome'] = $lang->product->assignedToMe;
$lang->product->featureBar['browse']['openedbyme'] = $lang->product->openedByMe;
$lang->product->featureBar['browse']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->featureBar['browse']['reviewbyme'] = $lang->product->reviewByMe;
$lang->product->featureBar['browse']['draftstory'] = $lang->product->draftStory;
$lang->product->featureBar['browse']['more'] = $lang->more;
@@ -224,6 +222,8 @@ $lang->product->featureBar['all']['all'] = $lang->product->allProduct;
$lang->product->featureBar['all']['noclosed'] = $lang->product->unclosed;
$lang->product->featureBar['all']['closed'] = $lang->product->statusList['closed'];
$lang->product->moreSelects['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['activestory'] = $lang->product->activeStory;
+2 -2
View File
@@ -214,8 +214,6 @@ $lang->product->noMatched = '"%s" cannot be found.' . $lang->productCommon;
$lang->product->featureBar['browse']['allstory'] = $lang->product->allStory;
$lang->product->featureBar['browse']['unclosed'] = $lang->product->unclosed;
$lang->product->featureBar['browse']['assignedtome'] = $lang->product->assignedToMe;
$lang->product->featureBar['browse']['openedbyme'] = $lang->product->openedByMe;
$lang->product->featureBar['browse']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->featureBar['browse']['reviewbyme'] = $lang->product->reviewByMe;
$lang->product->featureBar['browse']['draftstory'] = $lang->product->draftStory;
$lang->product->featureBar['browse']['more'] = $lang->more;
@@ -224,6 +222,8 @@ $lang->product->featureBar['all']['all'] = $lang->product->allProduct;
$lang->product->featureBar['all']['noclosed'] = $lang->product->unclosed;
$lang->product->featureBar['all']['closed'] = $lang->product->statusList['closed'];
$lang->product->moreSelects['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['activestory'] = $lang->product->activeStory;
+2 -2
View File
@@ -214,8 +214,6 @@ $lang->product->noMatched = '"%s" cannot be found.' . $lang->productCommon;
$lang->product->featureBar['browse']['allstory'] = $lang->product->allStory;
$lang->product->featureBar['browse']['unclosed'] = $lang->product->unclosed;
$lang->product->featureBar['browse']['assignedtome'] = $lang->product->assignedToMe;
$lang->product->featureBar['browse']['openedbyme'] = $lang->product->openedByMe;
$lang->product->featureBar['browse']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->featureBar['browse']['reviewbyme'] = $lang->product->reviewByMe;
$lang->product->featureBar['browse']['draftstory'] = $lang->product->draftStory;
$lang->product->featureBar['browse']['more'] = $lang->more;
@@ -224,6 +222,8 @@ $lang->product->featureBar['all']['all'] = $lang->product->allProduct;
$lang->product->featureBar['all']['noclosed'] = $lang->product->unclosed;
$lang->product->featureBar['all']['closed'] = $lang->product->statusList['closed'];
$lang->product->moreSelects['openedbyme'] = $lang->product->openedByMe;
$lang->product->moreSelects['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['activestory'] = $lang->product->activeStory;
+1 -1
View File
@@ -215,7 +215,6 @@ $lang->product->featureBar['browse']['allstory'] = '全部';
$lang->product->featureBar['browse']['unclosed'] = $lang->product->unclosed;
$lang->product->featureBar['browse']['assignedtome'] = $lang->product->assignedToMe;
$lang->product->featureBar['browse']['openedbyme'] = $lang->product->openedByMe;
$lang->product->featureBar['browse']['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->featureBar['browse']['reviewbyme'] = $lang->product->reviewByMe;
$lang->product->featureBar['browse']['draftstory'] = $lang->product->draftStory;
$lang->product->featureBar['browse']['more'] = $lang->more;
@@ -224,6 +223,7 @@ $lang->product->featureBar['all']['all'] = '全部' . $lang->productCommon;
$lang->product->featureBar['all']['noclosed'] = $lang->product->unclosed;
$lang->product->featureBar['all']['closed'] = $lang->product->statusList['closed'];
$lang->product->moreSelects['reviewedbyme'] = $lang->product->reviewedByMe;
$lang->product->moreSelects['assignedbyme'] = $lang->product->assignedByMe;
$lang->product->moreSelects['closedbyme'] = $lang->product->closedByMe;
$lang->product->moreSelects['activestory'] = $lang->product->activeStory;
+2 -2
View File
@@ -103,8 +103,8 @@
<td class='c-checkbox'><div class='checkbox-primary program-checkbox'><label></label></div></td>
<?php endif;?>
<td class='text-left table-nest-title' title="<?php echo $program['programName']?>">
<span class="table-nest-icon icon table-nest-toggle"></span>
&nbsp;<span class="icon icon-cards-view"></span>
<i class="table-nest-icon icon table-nest-toggle icon-plus"></i>
<i class="icon icon-cards-view"></i>
<span><?php echo $program['programName']?></span>
</td>
<td class='c-manager'>
-1
View File
@@ -41,7 +41,6 @@ $projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
.btn-group a i.icon-plus, .btn-group a i.icon-link {font-size: 16px;}
.btn-group a.btn-secondary, .btn-group a.btn-primary {border-right: 1px solid rgba(255,255,255,0.2);}
.btn-group button.dropdown-toggle.btn-secondary, .btn-group button.dropdown-toggle.btn-primary {padding:6px;}
#productStoryForm table tbody tr td.c-actions {overflow: visible;}
#productStoryForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
</style>
+1 -1
View File
@@ -118,7 +118,7 @@
</tbody>
</table>
<div class='table-footer'>
<div class="table-statistic"><?php echo strpos(',all,undone,', ",$status,") !== false ? sprintf($lang->project->allSummary, count($projectStats), $waitCount, $doingCount, $suspendedCount, $closedCount) : sprintf($lang->project->summary, count($projectStats));?></div>
<div class="table-statistic"><?php echo $status == 'all' ? sprintf($lang->project->allSummary, count($projectStats), $waitCount, $doingCount, $suspendedCount, $closedCount) : sprintf($lang->project->summary, count($projectStats));?></div>
<?php echo $pager->show('left', 'pagerjs');?>
</div>
</form>
+1 -1
View File
@@ -11,7 +11,7 @@ $(document).on('click', '.task-toggle', function(e)
$(function()
{
toggleFold('#productplanForm', unfoldPlans, productID, 'productplan');
if(viewType != 'kanban') toggleFold('#productplanForm', unfoldPlans, productID, 'productplan');
$('#productplanList tbody tr').each(function()
{
var $content = $(this).find('td.content');
@@ -53,7 +53,7 @@
</p>
</div>
<?php else:?>
<form class='main-table table-productplan' method='post' id='productplanForm' action='<?php echo inlink('batchEdit', "productID=$product->id&branch=$branch")?>'>
<form class='main-table table-productplan' method='post' id='productplanForm' action='<?php echo inlink('batchEdit', "productID=$product->id&branch=$branch")?>' data-preserve-nested='true'>
<table class='table has-sort-head' id="productplanList">
<thead>
<?php $vars = "productID=$productID&branch=$branch&browseType=$browseType&queryID=$queryID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
+1 -2
View File
@@ -4,5 +4,4 @@
#budgetUnit:focus {border-left: 1px solid #0c64eb;}
#dateRange, .futureBox {vertical-align: top !important; padding-top: 13px !important;}
#endList {vertical-align: top; padding-top: 13px;}
[lang^=en] #endList {vertical-align: top; padding-top: 20px;}
#dataform th {vertical-align: top; padding-top: 13px;}
[lang^=en] #endList {padding-top: 20px;}
-1
View File
@@ -2,4 +2,3 @@
#budgetUnit {border-left: 0px;}
#dateRange, .futureBox {vertical-align: top !important; padding-top: 13px !important;}
#endList {vertical-align: top; padding-top: 13px;}
#dataform th {vertical-align: top; padding-top: 13px;}
+1 -1
View File
@@ -11,7 +11,7 @@ $(function()
var statistics = summary;
var checkedStatistics = checkedSummary.replace('%total%', checkedTotal);
if(browseType == 'all' || browseType == 'unclosed')
if(browseType == 'all')
{
var checkedWait = $checkedRows.filter("[data-status=wait]").length;
var checkedDoing = $checkedRows.filter("[data-status=doing]").length;
+1 -1
View File
@@ -91,7 +91,7 @@ $closedCount = 0;
}
?>
</div>
<div class="table-statistic"><?php echo strpos(',all,unclosed,', ",$browseType,") !== false ? sprintf($lang->project->allSummary, count($projectStats), $waitCount, $doingCount, $suspendedCount, $closedCount) : sprintf($lang->project->summary, count($projectStats));?></div>
<div class="table-statistic"><?php echo $browseType == 'all' ? sprintf($lang->project->allSummary, count($projectStats), $waitCount, $doingCount, $suspendedCount, $closedCount) : sprintf($lang->project->summary, count($projectStats));?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
+1 -1
View File
@@ -58,6 +58,6 @@ $config->programplan->customCreateFields = 'PM,percent,attribute,acl,milestone,r
$config->programplan->custom = new stdclass();
$config->programplan->custom->createFields = 'PM,percent,attribute,acl,milestone';
$config->programplan->custom->customGanttFields = 'PM,deadline,status,realBegan,realEnd,progress,taskProgress,estimate,consumed';
$config->programplan->custom->customGanttFields = 'PM,deadline,status,realBegan,realEnd,progress,taskProgress,estimate,consumed,delay,delayDays';
$config->programplan->ganttCustom = new stdclass();
$config->programplan->ganttCustom->ganttFields = 'PM,deadline';
+9
View File
@@ -60,6 +60,9 @@ $lang->programplan->exporting = 'Exporting';
$lang->programplan->exportFail = 'Failed';
$lang->programplan->hideCriticalPath = 'Hide Critical Path';
$lang->programplan->showCriticalPath = 'Show Critical Path';
$lang->programplan->delay = 'Delay';
$lang->programplan->delayDays = 'Delay days';
$lang->programplan->errorBegin = "Project begin date: %s, begin date should be >= project begin date.";
$lang->programplan->errorEnd = "Project end date: %s, end date should be <= project end date.";
$lang->programplan->emptyBegin = '『Begin』should not be blank';
@@ -70,6 +73,10 @@ $lang->programplan->checkEnd = '『End』should be valid date';
$lang->programplan->milestoneList[1] = 'Yes';
$lang->programplan->milestoneList[0] = 'No';
$lang->programplan->delayList = array();
$lang->programplan->delayList[1] = 'Yes';
$lang->programplan->delayList[0] = 'No';
$lang->programplan->noData = 'No Data';
$lang->programplan->children = 'Sub Plan';
$lang->programplan->childrenAB = 'Child';
@@ -89,6 +96,8 @@ $lang->programplan->ganttCustom['progress'] ='Workload Ratio';
$lang->programplan->ganttCustom['taskProgress'] ='Task Progress';
$lang->programplan->ganttCustom['estimate'] ='Estimate';
$lang->programplan->ganttCustom['consumed'] ='Consumed';
$lang->programplan->ganttCustom['delay'] = 'Delay';
$lang->programplan->ganttCustom['delayDays'] = 'Delay days';
$lang->programplan->error = new stdclass();
$lang->programplan->error->percentNumber = '"Workload %" must be digits.';
+9
View File
@@ -60,6 +60,9 @@ $lang->programplan->exporting = '导出';
$lang->programplan->exportFail = '导出失败';
$lang->programplan->hideCriticalPath = '隐藏关键路径';
$lang->programplan->showCriticalPath = '显示关键路径';
$lang->programplan->delay = '是否延期';
$lang->programplan->delayDays = '延期天数';
$lang->programplan->errorBegin = '阶段的开始时间不能小于所属项目的开始时间%s';
$lang->programplan->errorEnd = '阶段的结束时间不能大于所属项目的结束时间%s';
$lang->programplan->emptyBegin = '『计划开始』日期不能为空';
@@ -70,6 +73,10 @@ $lang->programplan->checkEnd = '『计划完成』应当为合法的日
$lang->programplan->milestoneList[1] = '是';
$lang->programplan->milestoneList[0] = '否';
$lang->programplan->delayList = array();
$lang->programplan->delayList[1] = '是';
$lang->programplan->delayList[0] = '否';
$lang->programplan->noData = '暂无数据。';
$lang->programplan->children = '二级计划';
$lang->programplan->childrenAB = '子';
@@ -89,6 +96,8 @@ $lang->programplan->ganttCustom['progress'] ='工作量占比';
$lang->programplan->ganttCustom['taskProgress'] ='任务进度';
$lang->programplan->ganttCustom['estimate'] ='工时';
$lang->programplan->ganttCustom['consumed'] ='消耗工时';
$lang->programplan->ganttCustom['delay'] = '是否延期';
$lang->programplan->ganttCustom['delayDays'] = '延期天数';
$lang->programplan->error = new stdclass();
$lang->programplan->error->percentNumber = '"工作量比例"必须为数字';
+19
View File
@@ -169,6 +169,7 @@ class programplanModel extends model
}
}
$today = helper::today();
$datas = array();
$planIdList = array();
$isMilestone = "<icon class='icon icon-flag icon-sm red'></icon> ";
@@ -205,6 +206,15 @@ class programplanModel extends model
$data->textColor = $this->lang->execution->gantt->stage->textColor;
$data->bar_height = $this->lang->execution->gantt->bar_height;
/* Determines if the object is delay. */
$data->delay = $this->lang->programplan->delayList[0];
$data->delayDays = 0;
if($today > $end)
{
$data->delay = $this->lang->programplan->delayList[1];
$data->delayDays = helper::diffDate($today, substr($end, 0, 10));
}
if($data->endDate > $data->start_date) $data->duration = helper::diffDate(substr($data->endDate, 0, 10), substr($data->start_date, 0, 10)) + 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;
@@ -285,6 +295,15 @@ class programplanModel extends model
$data->textColor = zget($this->lang->execution->gantt->textColor, $task->pri, $this->lang->execution->gantt->defaultTextColor);
$data->bar_height = $this->lang->execution->gantt->bar_height;
/* Determines if the object is delay. */
$data->delay = $this->lang->programplan->delayList[0];
$data->delayDays = 0;
if($today > $end)
{
$data->delay = $this->lang->programplan->delayList[1];
$data->delayDays = helper::diffDate($today, substr($end, 0, 10));
}
/* If multi task then show the teams. */
if($task->mode == 'multi' and !empty($taskTeams[$task->id]))
{
+5 -1
View File
@@ -560,7 +560,9 @@ $(function()
if(showFields.indexOf('taskProgress') != -1) gantt.config.columns.push({name: 'taskProgress', align: 'center', resize: true, width: 60});
if(showFields.indexOf('realBegan') != -1) gantt.config.columns.push({name: 'realBegan', align: 'center', resize: true, width: 80});
if(showFields.indexOf('realEnd') != -1) gantt.config.columns.push({name: 'realEnd', align: 'center', resize: true, width: 80});
if(showFields.indexOf('consumed') != -1) gantt.config.columns.push({name: 'consumed', align: 'center', resize: false, width: 60});
if(showFields.indexOf('consumed') != -1) gantt.config.columns.push({name: 'consumed', align: 'center', resize: true, width: 60});
if(showFields.indexOf('delay') != -1) gantt.config.columns.push({name: 'delay', align: 'center', resize: true, width: 60});
if(showFields.indexOf('delayDays') != -1) gantt.config.columns.push({name: 'delayDays', align: 'center', resize: false, width: 60});
endField = gantt.config.columns.pop();
endField.resize = false;
@@ -578,6 +580,8 @@ $(function()
gantt.locale.labels.column_duration = "<?php echo $lang->programplan->duration;?>";
gantt.locale.labels.column_estimate = "<?php echo $lang->programplan->estimate;?>";
gantt.locale.labels.column_consumed = "<?php echo $lang->programplan->consumed;?>";
gantt.locale.labels.column_delay = "<?php echo $lang->programplan->delay;?>";
gantt.locale.labels.column_delayDays = "<?php echo $lang->programplan->delayDays;?>";
if((module == 'review' && method == 'assess') || dateDetails) gantt.config.show_chart = false;
+3 -1
View File
@@ -517,7 +517,7 @@ class project extends control
$code = '';
$team = '';
$whitelist = '';
$acl = 'private';
$acl = 'open';
$auth = 'extend';
$products = array();
@@ -1052,6 +1052,7 @@ class project extends control
$this->view->productID = $productID;
$this->view->projectID = $projectID;
$this->view->project = $project;
$this->view->projects = $projects;
$this->view->pager = $pager;
$this->view->orderBy = $orderBy;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
@@ -1176,6 +1177,7 @@ class project extends control
/* Process the openedBuild and resolvedBuild fields. */
$bugs = $this->bug->getProjectBugs($projectID, $productID, $branchID, $build, $type, $param, $sort, '', $pager);
$bugs = $this->bug->processBuildForBugs($bugs);
$bugs = $this->bug->checkDelayedBugs($bugs);
/* Get story and task id list. */
$storyIdList = $taskIdList = array();
-1
View File
@@ -25,6 +25,5 @@
#productsBox > #productNameLabel {padding-top: 8px;}
#plansBox .row {display: inline-table; width: 102%;}
#plansBox .col-sm-4 {float: none; display: inline-block; padding-right: 5px;}
#dataform th {vertical-align: top; padding-top: 13px;}
.futureBox {vertical-align: top !important; padding-top: 13px !important;}
#linkPlan {padding-top: 25px !important;}
-1
View File
@@ -4,6 +4,5 @@
#plansBox .col-sm-4 {float: none; display: inline-block;}
#dateRange, .futureBox {vertical-align: top !important; padding-top: 13px !important;}
#endList {vertical-align: top; padding-top: 13px;}
#dataform th {vertical-align: top; padding-top: 13px;}
#linkPlan {padding-top: 25px !important;}
#productsBox .row .col-sm-4.required::after {right: -5px;}
+5 -2
View File
@@ -1,5 +1,5 @@
#executionList > thead > tr > th .table-nest-toggle-global {top: 4px;}
#executionList > thead > tr > th .table-nest-toggle-global:before {color: #a6aab8;}
#executionList > thead > tr > th .table-nest-toggle-global {position: static!important;}
#executionList > thead > tr > th .table-nest-toggle-global:before {color: #a6aab8; position: static!important;}
#executionsSummary {padding-left: 10px;}
#mainMenu .pull-left .checkbox-primary {margin-top: 5px;}
.main-table tbody>tr>td:first-child, .main-table thead>tr>th:first-child { padding-left: 8px; }
@@ -12,3 +12,6 @@ th.table-nest-title .check-all {position: absolute; left: 15px; top: 7px;}
#executionTableList > tr:not(.has-nest-child) .table-nest-toggle {display: none;}
#executionTableList > tr:not(.has-nest-child) .project-type-label {margin-left: 22px;}
.table-statistic {padding-left: 10px;}
td.flex {display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center; margin-bottom: 0px;}
td.c-name > .project-type-label {flex: 0 0 36px; padding-right: 2px;}
.c-name > a, .table-children .text-left > a { padding-left: 5px; text-overflow: clip;}
+4 -4
View File
@@ -617,17 +617,17 @@ class projectModel extends model
}
elseif($module == 'repo')
{
$link = helper::createLink($module, 'browse', "repoID=&branchID=&objectID=%s#app=project");
$link = helper::createLink($module, 'browse', "repoID=&branchID=&objectID=%s") . "#app=project";
}
elseif($module == 'doc')
{
$link = helper::createLink($module, 'tablecontents', "type=project&objectID=%s#app=project");
$link = helper::createLink($module, 'tablecontents', "type=project&objectID=%s") . "#app=project";
}
elseif($module == 'build')
{
if($method == 'create')
{
$link = helper::createLink($module, $method, "executionID=&productID=&projectID=%s#app=project");
$link = helper::createLink($module, $method, "executionID=&productID=&projectID=%s") . "#app=project";
}
else
{
@@ -660,7 +660,7 @@ class projectModel extends model
{
if($method == 'projectsummary')
{
$link = helper::createLink($module, $method, "projectID=%s#app=project");
$link = helper::createLink($module, $method, "projectID=%s"). "#app=project";
}
else
{
+8 -6
View File
@@ -56,6 +56,12 @@
<?php endif;?>
</div>
</div>
<?php
$waitCount = 0;
$doingCount = 0;
$suspendedCount = 0;
$closedCount = 0;
?>
<div id='mainContent' class="main-row fade">
<?php if($this->config->systemMode == 'new'):?>
<div id="sidebar" class="side-col">
@@ -94,10 +100,6 @@
$useDatatable = (!commonModel::isTutorialMode() and (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'));
$setting = $this->datatable->getSetting('project');
$fixedFieldsWidth = $this->datatable->setFixedFieldWidth($setting);
$waitCount = 0;
$doingCount = 0;
$suspendedCount = 0;
$closedCount = 0;
if($useDatatable) include dirname(dirname(dirname(__FILE__))) . '/common/view/datatable.html.php';
?>
@@ -144,7 +146,7 @@
}
?>
</div>
<div class="table-statistic"><?php echo strpos(',all,undone,', ",$browseType,") !== false ? sprintf($lang->project->allSummary, count($projectStats), $waitCount, $doingCount, $suspendedCount, $closedCount) : sprintf($lang->project->summary, count($projectStats));?></div>
<div class="table-statistic"><?php echo $browseType == 'all' ? sprintf($lang->project->allSummary, count($projectStats), $waitCount, $doingCount, $suspendedCount, $closedCount) : sprintf($lang->project->summary, count($projectStats));?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
@@ -172,7 +174,7 @@ $(function()
var statistics = summary;
var checkedStatistics = checkedSummary.replace('%total%', checkedTotal);
if(browseType == 'all' || browseType == 'undone')
if(browseType == 'all')
{
var checkedWait = $checkedRows.filter("[data-status=wait]").length;
var checkedDoing = $checkedRows.filter("[data-status=doing]").length;
+2 -2
View File
@@ -48,8 +48,8 @@
<thead>
<tr>
<th class="c-id-sm"><?php echo $lang->build->id;?></th>
<th class="c-name w-200px text-left"><?php echo $lang->build->product;?></th>
<th class="c-name text-left"><?php echo $lang->build->name;?></th>
<th class="c-name w-200px text-left"><?php echo $lang->build->product;?></th>
<th class="c-name text-left"><?php echo $lang->executionCommon;?></th>
<th class="c-url"><?php echo $lang->build->scmPath;?></th>
<th class="c-url"><?php echo $lang->build->filePath;?></th>
@@ -63,11 +63,11 @@
<?php foreach($builds as $index => $build):?>
<tr data-id="<?php echo $productID;?>">
<td class="c-id-sm text-muted"><?php echo html::a(helper::createLink('build', 'view', "buildID=$build->id"), sprintf('%03d', $build->id), '', "data-app='project'");?></td>
<td class="c-name text-left" title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
<td class="c-name" title='<?php echo $build->name;?>'>
<?php if($build->branchName) echo "<span class='label label-outline label-badge'>{$build->branchName}</span>"?>
<?php echo html::a($this->createLink('build', 'view', "build=$build->id"), $build->name, '', "data-app='project'");?>
</td>
<td class="c-name text-left" title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
<td class="c-name text-left" title='<?php echo $build->executionName;?>'><?php echo $build->executionName;?></td>
<td class="c-url" title="<?php echo $build->scmPath?>"><?php echo strpos($build->scmPath, 'http') === 0 ? html::a($build->scmPath) : $build->scmPath;?></td>
<td class="c-url" title="<?php echo $build->filePath?>"><?php echo strpos($build->filePath, 'http') === 0 ? html::a($build->filePath) : $build->filePath;?></td>
+6 -4
View File
@@ -72,10 +72,12 @@
<thead>
<tr>
<th class='table-nest-title'>
<?php if($canBatchEdit and $showToggleIcon):?>
<a class='table-nest-toggle icon table-nest-toggle-global' data-expand-text='<?php echo $lang->expand; ?>' data-collapse-text='<?php echo $lang->collapse;?>'></a>
<?php endif;?>
<?php echo $lang->nameAB;?>
<div class="flex-between">
<?php echo $lang->nameAB;?>
<?php if($canBatchEdit and $showToggleIcon):?>
<a class='table-nest-toggle icon table-nest-toggle-global' data-expand-text='<?php echo $lang->expand; ?>' data-collapse-text='<?php echo $lang->collapse;?>'></a>
<?php endif;?>
</div>
</th>
<th class='c-user'><?php echo $lang->execution->owner;?></th>
<th class='c-status text-center'><?php echo $lang->project->status;?></th>
+11
View File
@@ -64,9 +64,19 @@
</tr>
</thead>
<tbody>
<?php
$waitCount = 0;
$testingCount = 0;
$blockedCount = 0;
$doneCount = 0;
?>
<?php foreach($tasks as $product => $productTasks):?>
<?php $productName = zget($products, $product, '');?>
<?php foreach($productTasks as $task):?>
<?php if($task->status == 'wait') $waitCount ++;?>
<?php if($task->status == 'doing') $testingCount ++;?>
<?php if($task->status == 'blocked') $blockedCount ++;?>
<?php if($task->status == 'done') $doneCount ++;?>
<tr data-id='<?php echo $product;?>' <?php if($task == reset($productTasks)) echo "class='divider-top'";?>>
<?php if($task == reset($productTasks)):?>
<td rowspan='<?php echo count($productTasks);?>' class='c-side text-left group-toggle'>
@@ -117,6 +127,7 @@
</tbody>
</table>
<div class="table-footer">
<div class="table-statistic"><?php echo sprintf($lang->testtask->allSummary, $total, $waitCount, $testingCount, $blockedCount, $doneCount);?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
+7 -7
View File
@@ -55,7 +55,7 @@ $config->story->excludeCheckFileds = ',uploadImage,category,reviewer,reviewDitto
global $lang, $app;
$config->story->datatable = new stdclass();
$config->story->datatable->defaultField = array('id', 'title', 'plan', 'pri', 'status', 'openedBy', 'estimate', 'reviewedBy', 'stage', 'assignedTo', 'taskCount', 'actions');
$config->story->datatable->defaultField = array('id', 'title', 'pri', 'plan', 'status', 'openedBy', 'estimate', 'reviewedBy', 'stage', 'assignedTo', 'taskCount', 'actions');
$config->story->datatable->fieldList['id']['title'] = 'idAB';
$config->story->datatable->fieldList['id']['fixed'] = 'left';
@@ -77,6 +77,12 @@ $config->story->datatable->fieldList['title']['fixed'] = 'left';
$config->story->datatable->fieldList['title']['width'] = 'auto';
$config->story->datatable->fieldList['title']['required'] = 'yes';
$config->story->datatable->fieldList['pri']['title'] = 'priAB';
$config->story->datatable->fieldList['pri']['fixed'] = 'left';
$config->story->datatable->fieldList['pri']['width'] = '50';
$config->story->datatable->fieldList['pri']['required'] = 'no';
$config->story->datatable->fieldList['pri']['name'] = $this->lang->story->pri;
$config->story->datatable->fieldList['plan']['title'] = 'planAB';
$config->story->datatable->fieldList['plan']['fixed'] = 'no';
$config->story->datatable->fieldList['plan']['width'] = '90';
@@ -84,12 +90,6 @@ $config->story->datatable->fieldList['plan']['required'] = 'no';
$config->story->datatable->fieldList['plan']['control'] = 'select';
$config->story->datatable->fieldList['plan']['dataSource'] = array('module' => 'productplan', 'method' => 'getPairs', 'params' => '$productID');
$config->story->datatable->fieldList['pri']['title'] = 'priAB';
$config->story->datatable->fieldList['pri']['fixed'] = 'left';
$config->story->datatable->fieldList['pri']['width'] = '35';
$config->story->datatable->fieldList['pri']['required'] = 'no';
$config->story->datatable->fieldList['pri']['name'] = $this->lang->story->pri;
$config->story->datatable->fieldList['status']['title'] = 'statusAB';
$config->story->datatable->fieldList['status']['fixed'] = 'no';
$config->story->datatable->fieldList['status']['width'] = '60';
+9 -5
View File
@@ -866,6 +866,7 @@ class story extends control
$this->view->branchTagOption = $branchTagOption;
$this->view->reviewers = array_keys($reviewerList);
$this->view->reviewedReviewer = $reviewedReviewer;
$this->view->lastReviewer = $this->story->getLastReviewer($story->id);
$this->view->productReviewers = $this->user->getPairs('noclosed|nodeleted', array_keys($reviewerList), 0, $productReviewers);
$this->display();
@@ -1158,6 +1159,7 @@ class story extends control
$this->view->needReview = (($this->app->user->account == $this->view->product->PO or $this->config->story->needReview == 0 or !$this->story->checkForceReview()) and empty($reviewer)) ? "checked='checked'" : "";
$this->view->reviewer = implode(',', array_keys($reviewer));
$this->view->productReviewers = $this->user->getPairs('noclosed|nodeleted', $reviewer, 0, $productReviewers);
$this->view->lastReviewer = $this->story->getLastReviewer($story->id);
$this->display();
}
@@ -1233,6 +1235,7 @@ class story extends control
$releaseApp = $tab == 'execution' ? 'product' : $tab;
$this->session->set('productList', $uri . "#app={$tab}", 'product');
$this->session->set('buildList', $uri, $buildApp);
$this->app->loadLang('bug');
$storyID = (int)$storyID;
$story = $this->story->getById($storyID, $version, true);
@@ -1573,11 +1576,12 @@ class story extends control
$reviewerList = $this->story->getReviewerPairs($story->id, $story->version);
$story->reviewer = array_keys($reviewerList);
$this->view->story = $story;
$this->view->actions = $this->action->getList('story', $storyID);
$this->view->reviewers = $this->user->getPairs('noclosed|nodeleted', '', 0, $reviewers);
$this->view->users = $this->user->getPairs('noclosed|noletter');
$this->view->needReview = (($this->app->user->account == $product->PO or $this->config->story->needReview == 0 or !$this->story->checkForceReview()) and empty($story->reviewer)) ? "checked='checked'" : "";
$this->view->story = $story;
$this->view->actions = $this->action->getList('story', $storyID);
$this->view->reviewers = $this->user->getPairs('noclosed|nodeleted', '', 0, $reviewers);
$this->view->users = $this->user->getPairs('noclosed|noletter');
$this->view->needReview = (($this->app->user->account == $product->PO or $this->config->story->needReview == 0 or !$this->story->checkForceReview()) and empty($story->reviewer)) ? "checked='checked'" : "";
$this->view->lastReviewer = $this->story->getLastReviewer($story->id);
$this->display();
}

Some files were not shown because too many files have changed in this diff Show More