Merge branch 'master' into zenops_38
This commit is contained in:
+1
-1
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
|
||||
if(!function_exists('getWebRoot')){function getWebRoot(){}}
|
||||
|
||||
/* 基本设置。Basic settings. */
|
||||
$config->version = '17.2'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->version = '17.3'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->liteVersion = '1.2'; // 迅捷版版本。 The version of Lite.
|
||||
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
|
||||
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
|
||||
|
||||
@@ -271,6 +271,7 @@ $filter->project->task->cookie['projectTaskOrder'] = 'reg::orderBy';
|
||||
$filter->project->task->cookie['windowWidth'] = 'int';
|
||||
$filter->project->export->cookie['checkedItem'] = 'reg::checked';
|
||||
$filter->project->execution->cookie['pagerExecutionAll'] = 'int';
|
||||
$filter->project->execution->cookie['showTask'] = 'code';
|
||||
|
||||
$filter->projectstory->story->cookie['storyModuleParam'] = 'int';
|
||||
$filter->projectstory->story->cookie['pagerProductBrowse'] = 'int';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,3 +14,5 @@ ALTER TABLE `zt_doc` CHANGE `assignedDate` `assignedDate` datetime NOT NULL AFTE
|
||||
|
||||
UPDATE `zt_approval` SET `createdDate` = '';
|
||||
ALTER TABLE `zt_approval` CHANGE `createdDate` `createdDate` datetime NOT NULL AFTER `createdBy`;
|
||||
|
||||
ALTER TABLE `zt_reviewissue` ADD `approval` MEDIUMINT NOT NULL AFTER `review`;
|
||||
|
||||
@@ -9526,6 +9526,7 @@ CREATE TABLE IF NOT EXISTS `zt_reviewissue` (
|
||||
`id` mediumint(8) NOT NULL AUTO_INCREMENT,
|
||||
`project` mediumint(8) unsigned NOT NULL,
|
||||
`review` mediumint(8) NOT NULL,
|
||||
`approval` mediumint(8) NOT NULL,
|
||||
`injection` mediumint(8) NOT NULL,
|
||||
`identify` mediumint(8) NOT NULL,
|
||||
`type` char(30) NOT NULL DEFAULT 'review',
|
||||
|
||||
@@ -1,3 +1,96 @@
|
||||
2022-07-13 17.3
|
||||
完成的需求
|
||||
14130 点击按钮执行升级后禁用升级按钮
|
||||
14578 总计消耗不为0时再次点击完成任务后消耗工时可以填写为0
|
||||
15349 产品模块的维护增加历史记录
|
||||
26444 重新激活父任务时需要同步更新子任务的历史记录
|
||||
27723 年度总结按部门查看增加权限控制
|
||||
30114 实现禅道中累积流图的帮助功能
|
||||
30121 实现禅道执行视图下的需求累积流图
|
||||
30128 实现禅道执行视图下的任务累积流图
|
||||
30190 创建看板时增加复制看板功能
|
||||
31342 批量创建任务表单的右侧增加添加和删除行的操作
|
||||
31746 Scrum看板中任务看板按需求分组时需求以卡片方式展示
|
||||
31848 删除测试测试单列表中操作按钮中间的小竖线
|
||||
32329 跨应用跳转页面时直接展示跳转后的页面
|
||||
32584 瀑布项目阶段列表中阶段名称前增加展开、收起按钮
|
||||
32834 任务创建页面修改自定义表单后不影响已录入内容
|
||||
32994 时间设置错误提示删除日历自动展开效果
|
||||
33003 非所有标签的列表内容为空时,删除新建操作
|
||||
33085 需求提交页面修改自定义表单后不影响已录入内容
|
||||
33132 修改干系人新增页面中用户字段未定义提示
|
||||
33168 复制执行页面增加项目的选择菜单
|
||||
33170 BUG提交页面修改自定义表单后不影响已录入内容
|
||||
33171 用例提交页面修改自定义表单后不影响已录入内容
|
||||
33180 批量提需求表单的右侧增加添加和删除行的操作
|
||||
33181 批量提Bug表单的右侧增加添加和删除行的操作
|
||||
33182 批量建用例表单的右侧增加添加和删除行的操作
|
||||
33307 加大bug提交页面中操作系统输入框的宽度
|
||||
33308 加大bug提交页面中“关键词“字段标题框宽度
|
||||
33415 用例库中的用例可以多次导入到同一个产品的不同模块
|
||||
33418 瀑布项目阶段设置页面里程碑字段居中显示
|
||||
33419 瀑布项目阶段设置页面中操作字段居中显示
|
||||
33438 缩短组织下团队列表页面姓名跟用户名字段的间距
|
||||
33445 bug提交页面中刷新按钮改为图标显示
|
||||
33446 列表中日期没有定义时展示为空
|
||||
33448 缩小bug编辑页面中标题输入框宽度
|
||||
33516 后台全局设置中文档模板列表的的删除按钮改为垃圾桶样式
|
||||
33519 后台自定义页面修改提示语样式
|
||||
33540 优化搜索条件保存按钮样式
|
||||
33542 用例列表页面的执行时间格式调整
|
||||
33547 项目测试单列表的报告列表按钮修改
|
||||
33607 项目集列表中对展开和收起的状态做记录
|
||||
33617 瀑布项目阶段列表增加显示任务设置
|
||||
33673 我参与标签中能显示我负责和我在团队中的空间和看板
|
||||
33705 项目中测试的Bug列表增加产品模块功能
|
||||
33706 执行中测试的Bug列表增加产品模块功能
|
||||
33707 执行中测试的用例列表增加产品模块功能
|
||||
33775 详情页面中附件增加预览和下载按钮
|
||||
33777 研发需求变更页面增加附件编辑操作
|
||||
33782 地盘仪表盘待处理区块对齐调整
|
||||
33807 产品矩阵列表居左显示
|
||||
33879 阶段列表中展示任务列表
|
||||
33896 实现禅道执行视图下的Bug累积流图
|
||||
33939 后台通知设置页面中“评论”字段修改为“备注”
|
||||
33953 项目创建页面中,关联产品下拉框增加不可点击状态
|
||||
33970 测试仪表盘测试统计区块中统计字体颜色调整
|
||||
33972 增加国际版地盘任务列表页面截止日期字段的宽度
|
||||
33973 计划详情列表中返回路径优化
|
||||
33983 我的地盘日程中右侧任务和软需切换样式调整
|
||||
33986 产品发布创建页面里程碑选中状态修改
|
||||
33987 执行任务列表预计、消耗、剩余、进度字段居右显示
|
||||
33988 执行任务列表"截止"字段居左显示
|
||||
33999 统计产品页面删除“筛选条件"字段
|
||||
34028 后台二次开发API列表页面表头字段加粗
|
||||
34029 执行任务列表页面“完成者”字段内容过多时省略显示
|
||||
34036 专业研发看板项目的执行模块添加累积流图入口
|
||||
34038 累积流图中增加更新按钮
|
||||
34048 累积流图页增加下拉框支持切换类型
|
||||
34049 累积流图展示平均周期时间和吞吐率
|
||||
34050 累积流图中增加悬浮样式
|
||||
34138 scrum看板页面卡片局部刷新
|
||||
34139 通用看板页面卡片局部刷新
|
||||
34140 看板项目专业研发看板编辑区域后自动刷新
|
||||
34142 专业研发看板页面卡片局部刷新
|
||||
34266 修改产品计划详情页面提研发需求按钮的下拉菜单为右对齐
|
||||
34349 国际版地盘仪表盘添加区块弹窗中待办和待处理的英文修改
|
||||
34350 国际版中编辑和详情页面附件重命名的英文修改为Rename
|
||||
34354 修改产品研发需求提交页面中附件操作按钮颜色
|
||||
34367 累积流图增加隐藏周末按钮
|
||||
34387 需求提交页面产品分支输入框显示完整
|
||||
34497 邮箱修改密码优化格式校验提示语
|
||||
34580 任务详情编辑页面中,团队设置弹窗增加关闭按钮
|
||||
34609 修改产品分支合并的提示样式
|
||||
34610 当所有标签的列表内容均为空时,增加新建按钮
|
||||
34611 修改后台系统安全设置页面的提示语样式
|
||||
修复的Bug
|
||||
23123 项目/执行的Bug页左上角下拉组件未显示多分支产品的分支下拉
|
||||
23827 批量编辑项目时,提示文案不清晰
|
||||
24923 英文下项目集下新增干系人页面字段名称换行
|
||||
24976 内禅3.3版本需求列表需求名称显示3个点
|
||||
24981 隐藏来源没有同步隐藏其关联的文本框
|
||||
25070 后台-自定义-必填项-任务-建任务页面设置最初预计为必填项,创建多人任务团队成员预计工时为空也可以保存
|
||||
|
||||
2022-06-29 17.2
|
||||
完成的需求
|
||||
12709 创建某一类型的待办时,若无指派给我的内容列表提示用户
|
||||
|
||||
@@ -12,10 +12,11 @@ public function __construct($appName = '')
|
||||
* @param int $browseType
|
||||
* @param int $groupBy
|
||||
* @param string $searchValue
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getKanban4Group($executionID, $browseType, $groupBy, $searchValue = '')
|
||||
public function getKanban4Group($executionID, $browseType, $groupBy, $searchValue = '', $orderBy = 'pri_asc')
|
||||
{
|
||||
/* Get card data. */
|
||||
$cardList = array();
|
||||
@@ -23,7 +24,8 @@ public function getKanban4Group($executionID, $browseType, $groupBy, $searchValu
|
||||
if($browseType == 'bug') $cardList = $this->loadModel('bug')->getExecutionBugs($executionID);
|
||||
if($browseType == 'task') $cardList = $this->loadModel('execution')->getKanbanTasks($executionID, "id");
|
||||
|
||||
$lanes = $this->getLanes4Group($executionID, $browseType, $groupBy, $cardList);
|
||||
if($groupBy == 'story' and $browseType == 'task' and !isset($this->lang->kanban->orderList[$orderBy])) $orderBy = 'pri_asc';
|
||||
$lanes = $this->getLanes4Group($executionID, $browseType, $groupBy, $cardList, $orderBy);
|
||||
if(empty($lanes)) return array();
|
||||
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
@@ -70,6 +72,33 @@ public function getKanban4Group($executionID, $browseType, $groupBy, $searchValu
|
||||
$laneData['type'] = $browseType;
|
||||
$laneData['defaultCardType'] = $browseType;
|
||||
|
||||
if($browseType == 'task' and $groupBy == 'story')
|
||||
{
|
||||
$columnData[0]['id'] = 0;
|
||||
$columnData[0]['type'] = 'story';
|
||||
$columnData[0]['name'] = zget($this->lang->kanban->orderList, $orderBy, '');
|
||||
$columnData[0]['color'] = '#333';
|
||||
$columnData[0]['limit'] = '-1';
|
||||
$columnData[0]['laneType'] = $browseType;
|
||||
$columnData[0]['asParent'] = false;
|
||||
$columnData[0]['parentType'] = '';
|
||||
$columnData[0]['actions'] = array();
|
||||
|
||||
if(empty($searchValue) or strpos($lane->name, $searchValue) !== false)
|
||||
{
|
||||
$cardData = array();
|
||||
$cardData['id'] = $laneID;
|
||||
$cardData['title'] = $lane->name;
|
||||
$cardData['order'] = 1;
|
||||
$cardData['pri'] = $lane->pri;
|
||||
$cardData['estimate'] = '';
|
||||
$cardData['assignedTo'] = $lane->assignedTo;
|
||||
$cardData['deadline'] = '';
|
||||
$cardData['severity'] = '';
|
||||
$laneData['cards']['story'][] = $cardData;
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct kanban column data. */
|
||||
foreach($columns as $column)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,9 @@ class project extends control
|
||||
if($this->execution->isClickable($kanban, 'delete')) $executionActions[$kanbanID][] = 'delete';
|
||||
}
|
||||
|
||||
$allExecution = $this->execution->getList($projectID, 'all', 'all');
|
||||
$this->view->allExecutionsNum = count($allExecution);
|
||||
|
||||
$this->view->title = $this->lang->project->kanban;
|
||||
|
||||
$this->view->kanbanList = array_values($kanbanList);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->execution->noExecution;?></span>
|
||||
<?php if(common::hasPriv('execution', 'create') and $status == "all"):?>
|
||||
<?php if(common::hasPriv('execution', 'create') and empty($allExecutionsNum)):?>
|
||||
<?php echo html::a($this->createLink('execution', 'create', "projectID=$projectID"), "<i class='icon icon-plus'></i> " . $lang->project->createKanban, '', "class='btn btn-info' data-app='project'");?>
|
||||
<?php endif;?>
|
||||
</p>
|
||||
|
||||
@@ -966,8 +966,9 @@ class baseJS
|
||||
{
|
||||
$cancleAction = "$cancleTarget.location = '$cancleURL';";
|
||||
}
|
||||
|
||||
$js .= <<<EOT
|
||||
if(strpos($_SERVER['HTTP_USER_AGENT'], 'xuanxuan') === false)
|
||||
{
|
||||
$js .= <<<EOT
|
||||
if(confirm("$message"))
|
||||
{
|
||||
$confirmAction
|
||||
@@ -977,6 +978,12 @@ else
|
||||
$cancleAction
|
||||
}
|
||||
EOT;
|
||||
}
|
||||
else
|
||||
{
|
||||
$js .= $confirmAction;
|
||||
}
|
||||
|
||||
$js .= self::end();
|
||||
return $js;
|
||||
}
|
||||
|
||||
@@ -210,6 +210,7 @@ $lang->action->desc->importedbuild = '$date, imported to <strong>$extra</
|
||||
$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";
|
||||
$lang->action->desc->adjusttasktowait = '$date, System Reminder: The task status will be set to Not Started as the consumed work hour is adjusted to 0. ' . "\n";
|
||||
|
||||
/* Used to describe the history of operations related to parent-child tasks. */
|
||||
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
|
||||
@@ -306,7 +307,7 @@ $lang->action->label->suspended = 'suspended ';
|
||||
$lang->action->label->login = 'Login';
|
||||
$lang->action->label->logout = "Logout";
|
||||
$lang->action->label->notified = "Notified";
|
||||
$lang->action->label->deleteestimate = "deleted ";
|
||||
$lang->action->label->deleteestimate = "deleted hours";
|
||||
$lang->action->label->linked2build = "linked ";
|
||||
$lang->action->label->linked2bug = "linked ";
|
||||
$lang->action->label->linked2testtask = "linked";
|
||||
|
||||
@@ -210,6 +210,7 @@ $lang->action->desc->importedbuild = '$date, imported to <strong>$extra</
|
||||
$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";
|
||||
$lang->action->desc->adjusttasktowait = '$date, System Reminder: The task status will be set to Not Started as the consumed work hour is adjusted to 0. ' . "\n";
|
||||
|
||||
/* Used to describe the history of operations related to parent-child tasks. */
|
||||
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
|
||||
@@ -306,7 +307,7 @@ $lang->action->label->suspended = 'suspended ';
|
||||
$lang->action->label->login = 'login';
|
||||
$lang->action->label->logout = "logout";
|
||||
$lang->action->label->notified = "Notified";
|
||||
$lang->action->label->deleteestimate = "deleted ";
|
||||
$lang->action->label->deleteestimate = "deleted hours";
|
||||
$lang->action->label->linked2build = "linked ";
|
||||
$lang->action->label->linked2bug = "linked ";
|
||||
$lang->action->label->linked2testtask = "linked";
|
||||
|
||||
@@ -210,6 +210,7 @@ $lang->action->desc->importedbuild = '$date, imported to <strong>$extra</
|
||||
$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";
|
||||
$lang->action->desc->adjusttasktowait = '$date, System Reminder: The task status will be set to Not Started as the consumed work hour is adjusted to 0. ' . "\n";
|
||||
|
||||
/* Used to describe the history of operations related to parent-child tasks. */
|
||||
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> a créé un sous-tâche <strong>$extra</strong>。' . "\n";
|
||||
|
||||
@@ -210,6 +210,7 @@ $lang->action->desc->importedbuild = '$date, 由 <strong>$actor</strong>
|
||||
$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";
|
||||
$lang->action->desc->adjusttasktowait = '$date, 系统判断由于消耗工时调整为0,将任务状态置为未开始。' . "\n";
|
||||
|
||||
/* 用来描述和父子任务相关的操作历史记录。*/
|
||||
$lang->action->desc->createchildren = '$date, 由 <strong>$actor</strong> 创建子任务 <strong>$extra</strong>。' . "\n";
|
||||
|
||||
@@ -73,7 +73,7 @@ class actionModel extends model
|
||||
if($this->post->uid) $this->file->updateObjectID($this->post->uid, $objectID, $objectType);
|
||||
|
||||
/* Call the message notification function. */
|
||||
$this->loadModel('message')->send(strtolower($objectType), $objectID, $actionType, $actionID, $actor);
|
||||
$this->loadModel('message')->send(strtolower($objectType), $objectID, $actionType, $actionID, $actor, $extra);
|
||||
|
||||
/* Add index for global search. */
|
||||
$this->saveIndex($objectType, $objectID, $actionType);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
$i = 0;
|
||||
foreach($actions as $action)
|
||||
{
|
||||
if($action->action == 'adjusttasktowait') continue;
|
||||
$user = zget($users, $action->actor);
|
||||
if($action->action == 'login' or $action->action == 'logout') $action->objectName = $action->objectLabel = '';
|
||||
if($action->objectType == 'sonarqubeproject') $action->objectName = $action->extra;
|
||||
|
||||
+102
-87
@@ -417,22 +417,23 @@ class bug extends control
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, 0)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
@@ -726,22 +727,23 @@ class bug extends control
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
@@ -999,22 +1001,23 @@ class bug extends control
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
|
||||
if(isset($execution->type) and $execution->type == 'kanban')
|
||||
{
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', 0, $kanbanGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
@@ -1415,23 +1418,24 @@ class bug extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$bug = $this->bug->getById($bugID);
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$bug = $this->bug->getById($bugID);
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($this->app->tab == 'execution' and isset($execution->type) and $execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', 0, $kanbanGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', 0, $kanbanGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
elseif($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
else
|
||||
@@ -1644,23 +1648,24 @@ class bug extends control
|
||||
parse_str($extra, $output);
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($this->app->tab == 'execution' and isset($execution->type) and $execution->type == 'kanban')
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
elseif($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
else
|
||||
@@ -1748,22 +1753,23 @@ class bug extends control
|
||||
parse_str($extra, $output);
|
||||
if(isonlybody())
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($this->app->tab == 'execution' and isset($execution->type) and $execution->type == 'kanban')
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
elseif($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
else
|
||||
@@ -1857,23 +1863,24 @@ class bug extends control
|
||||
parse_str($extra, $output);
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($this->app->tab == 'execution' and isset($execution->type) and $execution->type == 'kanban')
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
elseif($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
else
|
||||
@@ -1926,23 +1933,24 @@ class bug extends control
|
||||
parse_str($extra, $output);
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execution = $this->loadModel('execution')->getByID($bug->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($this->app->tab == 'execution' and isset($execution->type) and $execution->type == 'kanban')
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
elseif($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
else
|
||||
@@ -2022,11 +2030,14 @@ class bug extends control
|
||||
/**
|
||||
* Batch close bugs.
|
||||
*
|
||||
* @param int $releaseID
|
||||
* @param string $viewType
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchClose()
|
||||
public function batchClose($releaseID = '', $viewType = '')
|
||||
{
|
||||
if($releaseID) $this->post->bugIDList = $this->post->unlinkBugs;
|
||||
if($this->post->bugIDList)
|
||||
{
|
||||
$bugIDList = $this->post->bugIDList;
|
||||
@@ -2051,6 +2062,10 @@ class bug extends control
|
||||
}
|
||||
$this->loadModel('score')->create('ajax', 'batchOther');
|
||||
if(isset($skipBugs)) echo js::alert(sprintf($this->lang->bug->skipClose, join(',', $skipBugs)));
|
||||
if($viewType)
|
||||
{
|
||||
return print(js::locate($this->createLink($viewType, 'view', "releaseID=$releaseID&type=bug"), 'parent'));
|
||||
}
|
||||
}
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
@@ -2144,13 +2159,13 @@ class bug extends control
|
||||
|
||||
if($from == 'taskkanban')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($bug->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'bug' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent', '', "parent.updateKanban(\"bug\", $kanbanData)"));
|
||||
}
|
||||
|
||||
|
||||
@@ -425,6 +425,7 @@ $lang->bug->placeholder->newBuildName = 'Nom Nouv Build';
|
||||
|
||||
$lang->bug->featureBar['browse']['all'] = $lang->bug->allBugs;
|
||||
$lang->bug->featureBar['browse']['unclosed'] = $lang->bug->unclosed;
|
||||
$lang->bug->featureBar['browse']['openedbyme'] = $lang->bug->openedByMe;
|
||||
$lang->bug->featureBar['browse']['assigntome'] = $lang->bug->assignToMe;
|
||||
$lang->bug->featureBar['browse']['resolvedbyme'] = $lang->bug->resolvedByMe;
|
||||
|
||||
@@ -432,7 +433,6 @@ $lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved;
|
||||
$lang->bug->featureBar['browse']['more'] = $lang->more;
|
||||
|
||||
$lang->bug->moreSelects['assignedbyme'] = $lang->bug->assignedByMe;
|
||||
$lang->bug->moreSelects['openedbyme'] = $lang->bug->openedByMe;
|
||||
$lang->bug->moreSelects['unconfirmed'] = $lang->bug->unconfirmed;
|
||||
$lang->bug->moreSelects['assigntonull'] = $lang->bug->assignToNull;
|
||||
$lang->bug->moreSelects['longlifebugs'] = $lang->bug->longLifeBugs;
|
||||
|
||||
@@ -28,6 +28,8 @@ class caselibModel extends model
|
||||
if(!empty($products) and $this->session->product) $this->loadModel('qa')->setMenu($products, $this->session->product);
|
||||
if(empty($products)) $this->loadModel('qa')->setMenu(array(0 => ''), 0);
|
||||
|
||||
$this->lang->qa->menu->caselib['subModule'] .= ',testcase';
|
||||
|
||||
if($libraries)
|
||||
{
|
||||
$libName = '';
|
||||
|
||||
@@ -245,7 +245,7 @@ $lang->scrum->menu->settings['subMenu']->group = array('link' => "{$lang->
|
||||
/* Waterfall menu. */
|
||||
$lang->waterfall->menu = new stdclass();
|
||||
$lang->waterfall->menu->index = array('link' => "$lang->dashboard|project|index|project=%s");
|
||||
$lang->waterfall->menu->execution = array('link' => "{$lang->stage->common}|project|execution|status=all&projectID=%s", 'subModule' => 'programplan');
|
||||
$lang->waterfall->menu->execution = array('link' => "{$lang->stage->common}|project|execution|status=all&projectID=%s", 'subModule' => 'programplan,task');
|
||||
$lang->waterfall->menu->story = array('link' => "$lang->SRCommon|projectstory|story|project=%s", 'subModule' => 'projectstory,tree', 'exclude' => 'projectstory-track');
|
||||
$lang->waterfall->menu->design = array('link' => "{$lang->design->common}|design|browse|project=%s");
|
||||
$lang->waterfall->menu->qa = array('link' => "{$lang->qa->common}|project|bug|projectID=%s", 'subModule' => 'testcase,testtask,bug,testreport', 'alias' => 'bug,testtask,testcase,testreport');
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
</div>
|
||||
<ul class="timeline timeline-tag-left <?php if($browseType == 'all') echo 'margin-l-50px';?>">
|
||||
<?php foreach($actions as $i => $action):?>
|
||||
<?php if($action->action == 'adjusttasktowait') continue;?>
|
||||
<?php if(empty($firstAction)) $firstAction = $action;?>
|
||||
<li <?php if($action->major) echo "class='active'";?>>
|
||||
<div>
|
||||
|
||||
@@ -44,9 +44,10 @@
|
||||
<?php endif;?>
|
||||
<td class='text-left SRBox'><?php echo $URSR['SRName'];?></td>
|
||||
<td class='c-actions'>
|
||||
<?php $disabled = $key == $config->custom->URSR ? "disabled=disabled" : '';?>
|
||||
<?php $disabled = $key == $config->custom->URSR ? "disabled=disabled" : '';?>
|
||||
<?php $deleteLink = empty($disabled) ? $this->createLink('custom', 'deleteStoryConcept', "id=$key") : '#';?>
|
||||
<?php if(common::hasPriv('custom', 'editStoryConcept')) echo html::a($this->createLink('custom', 'editStoryConcept', "id=$key", '', true), "<i class='icon icon-edit'></i>", '', "class='btn iframe' data-width=" . ($this->config->URAndSR ? "480px" : "330px") . " title={$lang->edit}");?>
|
||||
<?php if(common::hasPriv('custom', 'deleteStoryConcept')) echo html::a($this->createLink('custom', 'deleteStoryConcept', "id=$key"), "<i class='icon icon-trash'></i>", 'hiddenwin', "class='btn' $disabled title={$lang->delete} data-group='admin'");?>
|
||||
<?php if(common::hasPriv('custom', 'deleteStoryConcept')) echo html::a($deleteLink, "<i class='icon icon-trash'></i>", 'hiddenwin', "class='btn' $disabled title={$lang->delete} data-group='admin'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
|
||||
@@ -3260,22 +3260,23 @@ class execution extends control
|
||||
return $this->send($response);
|
||||
}
|
||||
|
||||
$execution = $this->execution->getByID($executionID);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execution = $this->execution->getByID($executionID);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent', '', "parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
elseif($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent', '', "parent.updateKanban(\"story\", $kanbanData)"));
|
||||
}
|
||||
|
||||
@@ -3668,18 +3669,6 @@ class execution extends control
|
||||
$from = $this->app->tab;
|
||||
if($from == 'execution') $this->session->set('executionList', $this->app->getURI(true), 'execution');
|
||||
|
||||
if($from == 'project')
|
||||
{
|
||||
$projects = $this->project->getPairsByProgram();
|
||||
$projectID = $this->project->saveState($projectID, $projects);
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
$this->view->project = $project;
|
||||
$this->project->setMenu($projectID);
|
||||
|
||||
if(!$projectID) return print(js::locate($this->createLink('project', 'browse')));
|
||||
if(!empty($project->model) and $project->model == 'kanban' and !(defined('RUN_MODE') and RUN_MODE == 'api')) return print(js::locate($this->createLink('project', 'index', "projectID=$projectID")));
|
||||
}
|
||||
|
||||
if($this->app->viewType == 'mhtml')
|
||||
{
|
||||
if($this->app->rawModule == 'project' and $this->app->rawMethod == 'execution')
|
||||
@@ -3713,11 +3702,8 @@ class execution extends control
|
||||
$parents = array();
|
||||
if($parentIdList) $parents = $this->execution->getByIdList($parentIdList);
|
||||
|
||||
$allExecutionsNum = $this->dao->select('COUNT(id) AS count')->from(TABLE_PROJECT)
|
||||
->where('project')->eq($projectID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch();
|
||||
$this->view->allExecutionsNum = $allExecutionsNum;
|
||||
$allExecutionsNum = $this->project->getStats($projectID, 'all');
|
||||
$this->view->allExecutionsNum = count($allExecutionsNum);
|
||||
|
||||
$this->view->executionStats = $executionStats;
|
||||
$this->view->productList = $this->loadModel('product')->getProductPairsByProject($projectID);
|
||||
@@ -3978,8 +3964,8 @@ class execution extends control
|
||||
$projectID = $this->dao->findByID($executionID)->from(TABLE_EXECUTION)->fetch('project');
|
||||
$planStories = array_keys($planStory);
|
||||
|
||||
$this->execution->linkStory($executionID, $planStories, $planProducts, $extra);
|
||||
if($this->config->systemMode == 'new' and $executionID != $projectID) $this->execution->linkStory($projectID, $planStories, $planProducts);
|
||||
$this->execution->linkStory($executionID, $planStories, $planProducts, $extra);
|
||||
}
|
||||
|
||||
$moduleName = 'execution';
|
||||
|
||||
@@ -811,8 +811,6 @@ function tips()
|
||||
function renderHeaderCol($column, column, $header, kanbanData)
|
||||
{
|
||||
if(groupBy == 'story' && column.type == 'story') return;
|
||||
console.log(groupBy);
|
||||
console.log(column.type);
|
||||
/* Render group header. */
|
||||
var privs = kanbanData.actions;
|
||||
var columnPrivs = kanbanData.columns[0].actions;
|
||||
|
||||
@@ -434,8 +434,7 @@ $lang->execution->charts->cfd = new stdclass();
|
||||
$lang->execution->charts->cfd->cfdTip = "<p>
|
||||
1. The CFD(Cumulative Flow Diagram)reflects the trend of accumulated workload at each stage over time.<br>
|
||||
2. The horizontal axis represents the date, and the vertical axis represents the number of work items.<br>
|
||||
3. To learn about the team's delivery, you can calculate the WIP quantity, delivery rate and average lead time through the CFD.
|
||||
<p>";
|
||||
3. To learn about the team's delivery, you can calculate the WIP quantity, delivery rate and average lead time through the CFD. <p>";
|
||||
$lang->execution->charts->cfd->cycleTime = 'Average cycle time';
|
||||
$lang->execution->charts->cfd->cycleTimeTip = 'Average cycle time of each card from development start to completion';
|
||||
$lang->execution->charts->cfd->throughput = 'Throughput Rate';
|
||||
|
||||
@@ -434,8 +434,7 @@ $lang->execution->charts->cfd = new stdclass();
|
||||
$lang->execution->charts->cfd->cfdTip = "<p>
|
||||
1. The CFD(Cumulative Flow Diagram)reflects the trend of accumulated workload at each stage over time.<br>
|
||||
2. The horizontal axis represents the date, and the vertical axis represents the number of work items.<br>
|
||||
3. To learn about the team's delivery, you can calculate the WIP quantity, delivery rate and average lead time through the CFD.
|
||||
<p>";
|
||||
3. To learn about the team's delivery, you can calculate the WIP quantity, delivery rate and average lead time through the CFD. <p>";
|
||||
$lang->execution->charts->cfd->cycleTime = 'Average cycle time';
|
||||
$lang->execution->charts->cfd->cycleTimeTip = 'Average cycle time of each card from development start to completion';
|
||||
$lang->execution->charts->cfd->throughput = 'Throughput Rate';
|
||||
|
||||
@@ -300,10 +300,7 @@ $lang->execution->statusSelects[''] = 'Plus...';
|
||||
$lang->execution->statusSelects['wait'] = 'En Attente';
|
||||
$lang->execution->statusSelects['doing'] = 'En Cours';
|
||||
$lang->execution->statusSelects['undone'] = 'Non terminées';
|
||||
$lang->execution->statusSelects['myinvolved'] = $lang->execution->myInvolved;
|
||||
$lang->execution->statusSelects['finishedbyme'] = 'Terminées par moi';
|
||||
$lang->execution->statusSelects['assignedbyme'] = $lang->execution->assignedByMe;
|
||||
$lang->execution->statusSelects['needconfirm'] = 'A confirmer';
|
||||
$lang->execution->statusSelects['done'] = 'Faites';
|
||||
$lang->execution->statusSelects['closed'] = 'Fermées';
|
||||
$lang->execution->statusSelects['cancel'] = 'Annulées';
|
||||
@@ -503,6 +500,9 @@ $lang->execution->typeList['kanban'] = 'Kanban';
|
||||
$lang->execution->featureBar['task']['all'] = $lang->execution->allTasks;
|
||||
$lang->execution->featureBar['task']['unclosed'] = $lang->execution->unclosed;
|
||||
$lang->execution->featureBar['task']['assignedtome'] = $lang->execution->assignedToMe;
|
||||
$lang->execution->featureBar['task']['myinvolved'] = $lang->execution->myInvolved;
|
||||
$lang->execution->featureBar['task']['assignedbyme'] = $lang->execution->assignedByMe;
|
||||
$lang->execution->featureBar['task']['needconfirm'] = 'Changed';
|
||||
$lang->execution->featureBar['task']['status'] = $lang->execution->statusSelects[''];
|
||||
|
||||
$lang->execution->featureBar['all']['all'] = $lang->execution->all;
|
||||
|
||||
@@ -4305,6 +4305,103 @@ class executionModel extends model
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print execution nested list.
|
||||
*
|
||||
* @param object $execution
|
||||
* @param int $isChild
|
||||
* @param array $users
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function printNestedList($execution, $isChild = false, $users, $productID)
|
||||
{
|
||||
$this->loadModel('task');
|
||||
$this->loadModel('execution');
|
||||
$this->loadModel('programplan');
|
||||
|
||||
if(!$isChild)
|
||||
{
|
||||
$trClass = 'is-top-level table-nest-child-hide';
|
||||
$trAttrs = "data-id='$execution->id' data-order='$execution->order' data-nested='true'";
|
||||
}
|
||||
else
|
||||
{
|
||||
$trClass = 'is-nest-child';
|
||||
$trAttrs = "data-id={$execution->id} data-parent={$execution->parent}";
|
||||
$trAttrs .= " data-nest-parent='$execution->parent' data-order='$execution->order' data-nest-path=',$execution->parent,$execution->id,'";
|
||||
}
|
||||
|
||||
$burns = join(',', $execution->burns);
|
||||
echo "<tr $trAttrs class=$trClass>";
|
||||
echo "<td><span id=$execution->id class='table-nest-icon icon table-nest-toggle'></span>";
|
||||
if($this->config->systemMode == 'new')
|
||||
{
|
||||
$spanClass = $execution->type == 'stage' ? 'label-warning' : 'label-info';
|
||||
echo "<span class='project-type-label label label-outline $spanClass'>{$this->lang->execution->typeList[$execution->type]}</span> ";
|
||||
}
|
||||
echo html::a(helper::createLink('execution', 'view', "executionID=$execution->id"), $execution->name);
|
||||
echo '<td>' . zget($users, $execution->PM) . '</td>';
|
||||
echo "<td class='status-{$execution->status}'>" . zget($this->lang->project->statusList, $execution->status) . '</td>';
|
||||
echo '<td>' . html::ring($execution->hours->progress) . '</td>';
|
||||
echo '<td>' . $execution->begin . '</td>';
|
||||
echo '<td>' . $execution->end . '</td>';
|
||||
echo "<td class='hours' title='{$execution->hours->totalEstimate}{$this->lang->execution->workHour}'>" . $execution->hours->totalEstimate . $this->lang->execution->workHourUnit . '</td>';
|
||||
echo "<td class='hours' title='{$execution->hours->totalConsumed}{$this->lang->execution->workHour}'>" . $execution->hours->totalConsumed . $this->lang->execution->workHourUnit . '</td>';
|
||||
echo "<td class='hours' title='{$execution->hours->totalLeft}{$this->lang->execution->workHour}'>" . $execution->hours->totalLeft . $this->lang->execution->workHourUnit . '</td>';
|
||||
echo "<td id='spark-{$execution->id}' class='sparkline text-left no-padding' values='$burns'></td>";
|
||||
echo '<td class="c-actions">';
|
||||
common::printIcon('execution', 'start', "executionID={$execution->id}", $execution, 'list', '', '', 'iframe', true);
|
||||
$class = !empty($execution->children) ? 'disabled' : '';
|
||||
common::printIcon('task', 'create', "executionID={$execution->id}", $execution, 'list', '', '', $class, false, "data-app='execution'");
|
||||
|
||||
if($execution->type == 'stage')
|
||||
{
|
||||
if($execution->grade == 1 && $this->loadModel('programplan')->isCreateTask($execution->id))
|
||||
{
|
||||
common::printIcon('programplan', 'create', "program={$execution->parent}&productID=$productID&planID=$execution->id", $execution, 'list', 'split', '', '', '', '', $this->lang->programplan->createSubPlan);
|
||||
}
|
||||
else
|
||||
{
|
||||
$disabled = ($execution->grade == 2) ? ' disabled' : '';
|
||||
echo common::hasPriv('programplan', 'create') ? html::a('javascript:alert("' . $this->lang->programplan->error->createdTask . '");', '<i class="icon-programplan-create icon-split"></i>', '', 'class="btn ' . $disabled . '"') : '';
|
||||
}
|
||||
}
|
||||
|
||||
common::printIcon('programplan', 'edit', "stageID=$execution->id&projectID=$execution->project", $execution, 'list', '', '', 'iframe', true);
|
||||
|
||||
$disabled = !empty($execution->children) ? ' disabled' : '';
|
||||
if($execution->status != 'closed' and common::hasPriv('execution', 'close', $execution))
|
||||
{
|
||||
common::printIcon('execution', 'close', "stageID=$execution->id", $execution, 'list', 'off', 'hiddenwin' , $disabled . ' iframe', true, '', $this->lang->execution->close);
|
||||
}
|
||||
elseif($execution->status == 'closed' and common::hasPriv('execution', 'activate', $execution))
|
||||
{
|
||||
common::printIcon('execution', 'activate', "stageID=$execution->id", $execution, 'list', 'magic', 'hiddenwin' , $disabled . ' iframe', true, '', $this->lang->execution->activate);
|
||||
}
|
||||
|
||||
if(common::hasPriv('execution', 'delete', $execution))
|
||||
{
|
||||
common::printIcon('execution', 'delete', "stageID=$execution->id&confirm=no", $execution, 'list', 'trash', 'hiddenwin' , $disabled, '', '', $this->lang->delete);
|
||||
}
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
if(!empty($execution->children))
|
||||
{
|
||||
foreach($execution->children as $child) $this->printNestedList($child, true, $users, $productID);
|
||||
}
|
||||
|
||||
if(!empty($execution->tasks))
|
||||
{
|
||||
foreach($execution->tasks as $task)
|
||||
{
|
||||
$showmore = (count($execution->tasks) == 50) && ($task == end($execution->tasks));
|
||||
echo $this->task->buildNestedList($execution, $task, false, $showmore, $users);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user view of execution and it's product.
|
||||
*
|
||||
|
||||
@@ -73,7 +73,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $from == 'execution' ? $lang->execution->noExecutions : $lang->execution->noExecution;?></span>
|
||||
<?php if(empty($allExecutionsNum->count)):?>
|
||||
<?php if(empty($allExecutionsNum)):?>
|
||||
<?php if(common::hasPriv('programplan', 'create') and $isStage):?>
|
||||
<?php echo html::a($this->createLink('programplan', 'create', "projectID=$projectID&productID=$productID"), "<i class='icon icon-plus'></i> " . $lang->programplan->create, '', "class='btn btn-info'");?>
|
||||
<?php else: ?>
|
||||
|
||||
@@ -148,7 +148,7 @@ js::set('priv',
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<div class="input-group" id="rdKanbanSearch">
|
||||
<div class="input-control search-box" id="rdSearchBox">
|
||||
<input type="text" name="rdKanbanSearchInput" id="rdKanbanSearchInput" value="" class="form-control" oninput="searchCards(this.value)" placeholder="<?php echo $lang->execution->pleaseInput?>">
|
||||
<input type="text" name="rdKanbanSearchInput" id="rdKanbanSearchInput" value="" class="form-control" oninput="searchCards(this.value)" placeholder="<?php echo $lang->execution->pleaseInput?>" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<div class="input-group" id="taskKanbanSearch">
|
||||
<div class="input-control search-box" id="searchBox">
|
||||
<input type="text" name="taskKanbanSearchInput" id="taskKanbanSearchInput" value="" class="form-control" oninput="searchCards(this.value)" placeholder="<?php echo $lang->execution->pleaseInput;?>">
|
||||
<input type="text" name="taskKanbanSearchInput" id="taskKanbanSearchInput" value="" class="form-control" oninput="searchCards(this.value)" placeholder="<?php echo $lang->execution->pleaseInput;?>" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
@@ -280,9 +280,14 @@ class file extends control
|
||||
$file = $this->file->getById($fileID);
|
||||
$this->dao->delete()->from(TABLE_FILE)->where('id')->eq($fileID)->exec();
|
||||
$this->loadModel('action')->create($file->objectType, $file->objectID, 'deletedFile', '', $extra=$file->title);
|
||||
|
||||
/* Fix Bug #1518. */
|
||||
$fileRecord = $this->dao->select('id')->from(TABLE_FILE)->where('pathname')->eq($file->pathname)->fetch();
|
||||
if(empty($fileRecord)) @unlink($file->realPath);
|
||||
|
||||
/* Update test case version for test case synchronization. */
|
||||
if($file->objectType == 'testcase') $this->file->updateTestcaseVersion($file);
|
||||
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
}
|
||||
@@ -331,9 +336,12 @@ class file extends control
|
||||
|
||||
$extension = "." . $file->extension;
|
||||
$actionID = $this->loadModel('action')->create($file->objectType, $file->objectID, 'editfile', '', $fileName);
|
||||
$changes[] = array('field' => 'fileName', 'old' => $file->title . $extension, 'new' => $fileName);
|
||||
$changes[] = array('field' => 'fileName', 'old' => $file->title, 'new' => $fileName);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
/* Update test case version for test case synchronization. */
|
||||
if($file->objectType == 'testcase' and $file->title != $fileName) $this->file->updateTestcaseVersion($file);
|
||||
|
||||
return print(js::reload('parent.parent'));
|
||||
}
|
||||
|
||||
|
||||
@@ -1046,4 +1046,23 @@ class fileModel extends model
|
||||
->andWhere('deleted')->eq('0')
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update test case version.
|
||||
*
|
||||
* @param object $file
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function updateTestcaseVersion($file)
|
||||
{
|
||||
$oldCase = $this->loadModel('testcase')->getByID($file->objectID);
|
||||
$isLibCase = ($oldCase->lib and empty($oldCase->product));
|
||||
if($isLibCase)
|
||||
{
|
||||
$fromcaseVersion = $this->dao->select('fromCaseVersion')->from(TABLE_CASE)->where('fromCaseID')->eq($file->objectID)->fetch('fromCaseVersion');
|
||||
$fromcaseVersion += 1;
|
||||
$this->dao->update(TABLE_CASE)->set('`fromCaseVersion`')->eq($fromcaseVersion)->where('`fromCaseID`')->eq($file->objectID)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
.radio-inline {margin-left: 10px !important;}
|
||||
#region_chosen.chosen-container .chosen-results {max-height: 115px;}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanregion->style;?></th>
|
||||
<td><?php echo html::radio('region', $regions, 'custom');?></td>
|
||||
<td><?php echo html::select('region', $regions, 'custom', "class='form-control chosen' data-drop_direction='up'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2' class='form-actions text-center'>
|
||||
|
||||
@@ -59,10 +59,12 @@ class messageModel extends model
|
||||
* @param int $objectID
|
||||
* @param string $actionType
|
||||
* @param int $actionID
|
||||
* @param string $actor
|
||||
* @param string $extra
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function send($objectType, $objectID, $actionType, $actionID, $actor = '')
|
||||
public function send($objectType, $objectID, $actionType, $actionID, $actor = '', $extra = '')
|
||||
{
|
||||
$objectType = strtolower($objectType);
|
||||
$messageSetting = $this->config->message->setting;
|
||||
|
||||
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = '<p>ZenTao 15.0+ a new "Youth Blue" theme
|
||||
$lang->misc->feature->visionsDesc = "<p>The concept of interface has been added since 16.5. Users can deal with R & D affairs in <span style='color: #0c60e1'>[R&D]</span> and daily office affairs in <span style='color: #0c60e1'>[Lite]</span>.</p><p>You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.</p>";
|
||||
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
|
||||
|
||||
$lang->misc->releaseDate['17.3'] = '2022-07-13';
|
||||
$lang->misc->releaseDate['17.2'] = '2022-06-29';
|
||||
$lang->misc->releaseDate['17.1'] = '2022-06-16';
|
||||
$lang->misc->releaseDate['17.0'] = '2022-06-02';
|
||||
@@ -184,6 +185,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['17.3'][] = array('title' => "UI optimization of the modules such as statistics and background, the use case library will synchronize the function optimization information. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.2'][] = array('title' => "Adjust the display of agile project block; optimize the UI of programs, projects and tests; optimize the detailed experience. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.1'][] = array('title' => "Modify the interaction problem of execution, project module. Complete customer's high priority requirements. The detail experience is optimized, fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.0'][] = array('title' => 'The detail experience is optimized, fix bugs.', 'desc' => '');
|
||||
|
||||
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = '<p>ZenTao 15.0+ a new "Youth Blue" theme
|
||||
$lang->misc->feature->visionsDesc = "<p>The concept of interface has been added since 16.5. Users can deal with R & D affairs in <span style='color: #0c60e1'>[R&D]</span> and daily office affairs in <span style='color: #0c60e1'>[Lite]</span>.</p><p>You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.</p>";
|
||||
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
|
||||
|
||||
$lang->misc->releaseDate['17.3'] = '2022-07-13';
|
||||
$lang->misc->releaseDate['17.2'] = '2022-06-29';
|
||||
$lang->misc->releaseDate['17.1'] = '2022-06-16';
|
||||
$lang->misc->releaseDate['17.0'] = '2022-06-02';
|
||||
@@ -184,6 +185,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['17.3'][] = array('title' => "UI optimization of the modules such as statistics and background, the use case library will synchronize the function optimization information. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.2'][] = array('title' => "Adjust the display of agile project block; optimize the UI of programs, projects and tests; optimize the detailed experience. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.1'][] = array('title' => "Modify the interaction problem of execution, project module. Complete customer's high priority requirements. The detail experience is optimized, fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.0'][] = array('title' => 'The detail experience is optimized, fix bugs.', 'desc' => '');
|
||||
|
||||
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = '<p>ZenTao 15.0+ a new "Youth Blue" theme
|
||||
$lang->misc->feature->visionsDesc = "<p>The concept of interface has been added since 16.5. Users can deal with R & D affairs in <span style='color: #0c60e1'>[R&D]</span> and daily office affairs in <span style='color: #0c60e1'>[Lite]</span>.</p><p>You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.</p>";
|
||||
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png';
|
||||
|
||||
$lang->misc->releaseDate['17.3'] = '2022-07-13';
|
||||
$lang->misc->releaseDate['17.2'] = '2022-06-29';
|
||||
$lang->misc->releaseDate['17.1'] = '2022-06-16';
|
||||
$lang->misc->releaseDate['17.0'] = '2022-06-02';
|
||||
@@ -184,6 +185,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['17.3'][] = array('title' => "UI optimization of the modules such as statistics and background, the use case library will synchronize the function optimization information. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.2'][] = array('title' => "Adjust the display of agile project block; optimize the UI of programs, projects and tests; optimize the detailed experience. Fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.1'][] = array('title' => "Modify the interaction problem of execution, project module. Complete customer's high priority requirements. The detail experience is optimized, fix bugs.", 'desc' => '');
|
||||
$lang->misc->feature->all['17.0'][] = array('title' => 'The detail experience is optimized, fix bugs.', 'desc' => '');
|
||||
|
||||
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = "<p>禅道15系列上线了全新的“
|
||||
$lang->misc->feature->visionsDesc = "<p>从16.5开始增加了界面概念,用户可以在<span style='color:#0c60e1'>[研发综合界面]</span>中处理研发事务、在<span style='color:#0c60e1'>[迅捷界面]</span>处理日常办公事务。</p><p>在头像右侧即可查看当前所处界面,点击当前界面名称可查看和切换其他的界面。</p>";
|
||||
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions.png';
|
||||
|
||||
$lang->misc->releaseDate['17.3'] = '2022-07-13';
|
||||
$lang->misc->releaseDate['17.2'] = '2022-06-29';
|
||||
$lang->misc->releaseDate['17.1'] = '2022-06-16';
|
||||
$lang->misc->releaseDate['17.0'] = '2022-06-02';
|
||||
@@ -184,6 +185,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['17.3'][] = array('title' => '统计、后台等模块的UI优化,用例库同步用例信息功能优化。修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['17.2'][] = array('title' => '调整敏捷项目区块的展示,项目集、项目和测试相关UI优化,细节体验优化。修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['17.1'][] = array('title' => '修改执行、项目模块的交互问题,完成客户巴高优先级需求,细节体验优化。修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['17.0'][] = array('title' => '细节体验优化。修复Bug。', 'desc' => '');
|
||||
|
||||
@@ -207,6 +207,8 @@ $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;
|
||||
@@ -215,9 +217,7 @@ $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['assignedbyme'] = $lang->product->assignedByMe;
|
||||
$lang->product->moreSelects['reviewedbyme'] = $lang->product->reviewedByMe;
|
||||
$lang->product->moreSelects['closedbyme'] = $lang->product->closedByMe;
|
||||
$lang->product->moreSelects['activestory'] = $lang->product->activeStory;
|
||||
$lang->product->moreSelects['changedstory'] = $lang->product->changedStory;
|
||||
|
||||
@@ -72,7 +72,7 @@ class productplan extends control
|
||||
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $planID));
|
||||
if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => 'parent.refreshPlan()'));
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('productplan', 'browse', "productID=$productID&branch=$branchID&browseType=wait")));
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('productplan', 'browse', "productID=$productID&branch=$branchID&browseType=all")));
|
||||
}
|
||||
|
||||
$this->commonAction($productID, $branchID);
|
||||
|
||||
@@ -15,3 +15,4 @@ tbody.sortable > tr > td.sort-handler {color: #3c4353 !important;}
|
||||
.has-suffix > a {max-width: calc(100% - 100px); padding-right: 5px; color: #0c60e1; display: inline-block; max-width: calc(100% - 50px);}
|
||||
|
||||
div.checkbox-primary + span.table-nest-icon {margin-left:0px !important;}
|
||||
#checkAll + label.hover:after {border-width: 0px;}
|
||||
|
||||
@@ -59,6 +59,7 @@ $(function()
|
||||
$('#programSummary').addClass('hidden');
|
||||
$('#projectsSummary').remove();
|
||||
$('.editCheckbox').after(statistic);
|
||||
$(this).next('label').addClass('hover');
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -66,8 +67,19 @@ $(function()
|
||||
$('#programForm').removeClass('has-row-checked');
|
||||
$('#programSummary').removeClass('hidden');
|
||||
$('#projectsSummary').addClass('hidden');
|
||||
$(this).next('label').removeClass('hover');
|
||||
}
|
||||
});
|
||||
|
||||
/* Solve the problem that clicking the browser back button causes the checkbox to be selected by default. */
|
||||
setTimeout(function()
|
||||
{
|
||||
$(":checkbox[name^='projectIdList']").each(function()
|
||||
{
|
||||
$(this).prop('checked', false);
|
||||
});
|
||||
$('.table-footer #checkAll').prop('checked', false);
|
||||
}, 10);
|
||||
});
|
||||
|
||||
function showEditCheckbox(show)
|
||||
|
||||
@@ -23,6 +23,7 @@ $lang->programplan->createSubPlan = 'Create Sub Plan';
|
||||
$lang->programplan->parent = 'Parent Stage';
|
||||
$lang->programplan->emptyParent = 'N/A';
|
||||
$lang->programplan->name = 'Stage Name';
|
||||
$lang->programplan->status = 'Stage Progress';
|
||||
$lang->programplan->PM = 'Stage Manager';
|
||||
$lang->programplan->acl = 'Access Control';
|
||||
$lang->programplan->subStageName = 'Sub Stage Name';
|
||||
|
||||
@@ -23,6 +23,7 @@ $lang->programplan->createSubPlan = 'Create Sub Stage';
|
||||
$lang->programplan->parent = 'Parent Stage';
|
||||
$lang->programplan->emptyParent = 'N/A';
|
||||
$lang->programplan->name = 'Stage Name';
|
||||
$lang->programplan->status = 'Stage Progress';
|
||||
$lang->programplan->PM = 'Stage Manager';
|
||||
$lang->programplan->acl = 'Access Control';
|
||||
$lang->programplan->subStageName = 'Sub Stage Name';
|
||||
|
||||
@@ -23,6 +23,7 @@ $lang->programplan->createSubPlan = 'Create Sub Plan';
|
||||
$lang->programplan->parent = 'Parent Stage';
|
||||
$lang->programplan->emptyParent = 'N/A';
|
||||
$lang->programplan->name = 'Stage Name';
|
||||
$lang->programplan->status = 'Stage Progress';
|
||||
$lang->programplan->PM = 'Stage Manager';
|
||||
$lang->programplan->acl = 'Access Control';
|
||||
$lang->programplan->subStageName = 'Sub Stage Name';
|
||||
|
||||
@@ -23,6 +23,7 @@ $lang->programplan->createSubPlan = '创建二级阶段';
|
||||
$lang->programplan->parent = '父阶段';
|
||||
$lang->programplan->emptyParent = '无';
|
||||
$lang->programplan->name = '阶段名称';
|
||||
$lang->programplan->status = '阶段进度';
|
||||
$lang->programplan->PM = '阶段负责人';
|
||||
$lang->programplan->acl = '访问控制';
|
||||
$lang->programplan->subStageName = '子阶段名称';
|
||||
|
||||
@@ -493,7 +493,10 @@ class project extends control
|
||||
$products = $this->product->getProducts($copyProjectID);
|
||||
foreach($products as $product)
|
||||
{
|
||||
$productPlans[$product->id] = $this->loadModel('productplan')->getPairs($product->id, '', 'noclosed');
|
||||
foreach($product->branches as $branch)
|
||||
{
|
||||
$productPlans[$product->id][$branch] = $this->loadModel('productplan')->getPairs($product->id, $branch, 'noclosed', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,10 +965,40 @@ class project extends control
|
||||
*/
|
||||
public function execution($status = 'all', $projectID = 0, $orderBy = 'order_asc', $productID = 0, $recTotal = 0, $recPerPage = 100, $pageID = 1)
|
||||
{
|
||||
$uri = $this->app->getURI(true);
|
||||
$this->app->session->set('executionList', $uri, 'project');
|
||||
$this->loadModel('execution');
|
||||
$this->loadModel('task');
|
||||
$this->loadModel('programplan');
|
||||
|
||||
echo $this->fetch('execution', 'all', "status=$status&projectID=$projectID&orderBy=$orderBy&productID=$productID&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
|
||||
$projects = $this->project->getPairsByProgram();
|
||||
$projectID = $this->project->saveState($projectID, $projects);
|
||||
$project = $this->project->getByID($projectID);
|
||||
$this->project->setMenu($projectID);
|
||||
|
||||
if(!$projectID) return print(js::locate($this->createLink('project', 'browse')));
|
||||
if(!empty($project->model) and $project->model == 'kanban' and !(defined('RUN_MODE') and RUN_MODE == 'api')) return print(js::locate($this->createLink('project', 'index', "projectID=$projectID")));
|
||||
|
||||
/* Load pager and get tasks. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$allExecution = $this->project->getStats($projectID, 'all');
|
||||
$this->view->allExecutionNum = count($allExecution);
|
||||
|
||||
$this->view->title = $this->lang->execution->allExecutions;
|
||||
$this->view->position[] = $this->lang->execution->allExecutions;
|
||||
|
||||
$this->view->executionStats = $this->project->getStats($projectID, $status, $productID, 0, 30, $orderBy, $pager, $this->cookie->showTask);
|
||||
$this->view->productList = $this->loadModel('product')->getProductPairsByProject($projectID);
|
||||
$this->view->productID = $productID;
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->project = $project;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->status = $status;
|
||||
$this->view->isStage = (isset($project->model) and $project->model == 'waterfall') ? true : false;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#executionList > thead > tr > th .table-nest-toggle-global {top: 6px}
|
||||
#executionList > thead > tr > th .table-nest-toggle-global:before {color: #a6aab8;}
|
||||
#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; }
|
||||
@@ -146,6 +146,17 @@ $(function()
|
||||
});
|
||||
|
||||
$(document).on('change', "select[id^='branch']", disableSelectedBranch);
|
||||
|
||||
if(requiredFields.indexOf('budget') >= 0 && budget == 0)
|
||||
{
|
||||
$('#budget').removeAttr('disabled');
|
||||
$('td .checkbox-primary').addClass('hidden');
|
||||
}
|
||||
if(requiredFields.indexOf('budget') >= 0 && budget != 0)
|
||||
{
|
||||
$('td .checkbox-primary').addClass('hidden');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
$(function()
|
||||
{
|
||||
$('input[name^="showTask"]').click(function()
|
||||
{
|
||||
var show = $(this).is(':checked') ? 1 : 0;
|
||||
$.cookie('showTask', show, {expires:config.cookieLife, path:config.webRoot});
|
||||
window.location.reload();
|
||||
});
|
||||
})
|
||||
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
function handleScroll(e)
|
||||
{
|
||||
var relative = 200; // 相对距离
|
||||
$('tr.showmore').each(function()
|
||||
{
|
||||
var $showmore = $(this);
|
||||
var offsetTop = $showmore[0].offsetTop;
|
||||
if(offsetTop == 0) return true;
|
||||
|
||||
if(getScrollTop() + getWindowHeight() >= offsetTop - relative)
|
||||
{
|
||||
throttle(loadData($showmore), 150)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function loadData($showmore)
|
||||
{
|
||||
$showmore.removeClass('showmore');
|
||||
|
||||
var executionID = $showmore.attr('data-parent');
|
||||
var maxTaskID = $showmore.attr('data-id');
|
||||
var link = createLink('task', 'ajaxGetTasks', 'executionID=' + executionID + '&maxTaskID=' + maxTaskID);
|
||||
$.get(link, function(data)
|
||||
{
|
||||
$showmore.after(data);
|
||||
$(".iframe").modalTrigger({type:'iframe'});
|
||||
|
||||
$('#executionForm').table('initNestedList');
|
||||
})
|
||||
}
|
||||
|
||||
function throttle(fn, threshhold)
|
||||
{
|
||||
var last;
|
||||
var timer;
|
||||
threshhold || (threshhold = 250);
|
||||
|
||||
return function()
|
||||
{
|
||||
var context = this;
|
||||
var args = arguments;
|
||||
|
||||
var now = +new Date()
|
||||
|
||||
if (last && now < last + threshhold)
|
||||
{
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function ()
|
||||
{
|
||||
last = now
|
||||
fn.apply(context, args)
|
||||
}, threshhold)
|
||||
}
|
||||
else
|
||||
{
|
||||
last = now
|
||||
fn.apply(context, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getScrollTop()
|
||||
{
|
||||
return scrollTop = document.body.scrollTop + document.documentElement.scrollTop
|
||||
}
|
||||
|
||||
function getWindowHeight()
|
||||
{
|
||||
return document.compatMode == "CSS1Compat" ? windowHeight = document.documentElement.clientHeight : windowHeight = document.body.clientHeight
|
||||
}
|
||||
@@ -1527,6 +1527,7 @@ class projectModel extends model
|
||||
$projects[$projectID]->id = $projectID;
|
||||
$projects[$projectID]->name = $projectName;
|
||||
$projects[$projectID]->code = $projectCode;
|
||||
$projects[$projectID]->model = $oldProjects[$projectID]->model;
|
||||
$projects[$projectID]->PM = $data->PMs[$projectID];
|
||||
$projects[$projectID]->begin = $data->begins[$projectID];
|
||||
$projects[$projectID]->end = isset($data->ends[$projectID]) ? $data->ends[$projectID] : LONG_TIME;
|
||||
@@ -1582,7 +1583,17 @@ class projectModel extends model
|
||||
->where('id')->eq($projectID)
|
||||
->exec();
|
||||
|
||||
if(dao::isError()) helper::end(js::error('project#' . $projectID . dao::getError(true)));
|
||||
if(dao::isError())
|
||||
{
|
||||
$errors = dao::getError();
|
||||
foreach($errors as $key => $error)
|
||||
{
|
||||
dao::$errors[$key][0] = 'project#' . $projectID . $error[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$linkedProducts = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs();
|
||||
@@ -2306,7 +2317,7 @@ class projectModel extends model
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getStats($projectID = 0, $status = 'undone', $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'id_asc', $pager = null)
|
||||
public function getStats($projectID = 0, $status = 'undone', $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'id_asc', $pager = null, $withTasks = false)
|
||||
{
|
||||
if(empty($productID))
|
||||
{
|
||||
@@ -2382,6 +2393,31 @@ class projectModel extends model
|
||||
$burns[$executionID] = $executionBurns;
|
||||
}
|
||||
|
||||
if($withTasks)
|
||||
{
|
||||
$executionTasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('status')->notin('closed,cancel')
|
||||
->andWhere('execution')->in(array_keys($executions))
|
||||
->orderBy('id_asc')
|
||||
->fetchGroup('execution', 'id');
|
||||
|
||||
foreach($executionTasks as $executionID => $tasks)
|
||||
{
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
if($task->parent > 0)
|
||||
{
|
||||
if(isset($executionTasks[$executionID][$task->parent]))
|
||||
{
|
||||
$executionTasks[$executionID][$task->parent]->children[$task->id] = $task;
|
||||
unset($executionTasks[$executionID][$task->id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process executions. */
|
||||
$parents = array();
|
||||
$children = array();
|
||||
@@ -2407,6 +2443,11 @@ class projectModel extends model
|
||||
|
||||
$execution->children = array();
|
||||
$execution->grade == 1 ? $parents[$execution->id] = $execution : $children[$execution->parent][] = $execution;
|
||||
if(isset($executionTasks) and isset($executionTasks[$execution->id]))
|
||||
{
|
||||
$tasks = array_chunk($executionTasks[$execution->id], 50, true);
|
||||
$execution->tasks = $tasks[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* In the case of the waterfall model, calculate the sub-stage. */
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<?php js::set('productName', $lang->product->name);?>
|
||||
<?php js::set('manageProducts', $lang->project->manageProducts);?>
|
||||
<?php $requiredFields = $config->project->create->requiredFields;?>
|
||||
<?php js::set('requiredFields', $requiredFields);?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
@@ -77,7 +78,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class='checkbox-primary c-future'>
|
||||
<div class="checkbox-primary c-future <?php echo strpos($requiredFields, 'budget') !== false ? 'hidden' : '';?>">
|
||||
<input type='checkbox' id='future' name='future' value='1' />
|
||||
<label for='future'><?php echo $lang->project->future;?></label>
|
||||
</div>
|
||||
@@ -109,16 +110,18 @@
|
||||
<div class='row'>
|
||||
<?php $i = 0;?>
|
||||
<?php foreach($products as $product):?>
|
||||
<?php foreach($product->branches as $branch):?>
|
||||
<div class="col-sm-4" style="margin-bottom: 10px; padding-right: 6px;">
|
||||
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
|
||||
<div class="input-group<?php if($hasBranch) echo ' has-branch';?>">
|
||||
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "'");?>
|
||||
<span class='input-group-addon fix-border'></span>
|
||||
<?php if($hasBranch) echo html::select("branch[$i]", $branchGroups[$product->id], key($product->branches), "class='form-control chosen' onchange=\"loadPlans('#products{$i}', this.value)\"");?>
|
||||
<?php if($hasBranch) echo html::select("branch[$i]", $branchGroups[$product->id], $branch, "class='form-control chosen' onchange=\"loadPlans('#products{$i}', this.value)\"");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php $i++;?>
|
||||
<?php endforeach;?>
|
||||
<?php endforeach;?>
|
||||
<div class='col-sm-4 <?php if($programID) echo 'required';?>' style="padding-right: 6px;">
|
||||
<div class='input-group'>
|
||||
<?php echo html::select("products[$i]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");?>
|
||||
@@ -146,12 +149,15 @@
|
||||
<?php if($copyProjectID):?>
|
||||
<?php $i = 0;?>
|
||||
<?php foreach($products as $product):?>
|
||||
<?php $plans = zget($productPlans, $product->id, array(0 => ''));?>
|
||||
<div class="col-sm-4" id="plan<?php echo $i;?>"><?php echo html::select("plans[" . $product->id . "]", $plans, '', "class='form-control chosen' multiple");?></div>
|
||||
<?php $productPlan = zget($productPlans, $product->id, array(0 => ''));?>
|
||||
<?php foreach($product->branches as $branch):?>
|
||||
<?php $plans = zget($productPlan, $branch, array(0 => ''));?>
|
||||
<div class="col-sm-4" id="plan<?php echo $i;?>"><?php echo html::select('plans[' . $product->id . '][' . $branch . '][]', $plans, '', "class='form-control chosen' multiple");?></div>
|
||||
<?php $i++;?>
|
||||
<?php endforeach;?>
|
||||
<?php endforeach;?>
|
||||
<?php else:?>
|
||||
<div class="col-sm-4" id="plan0" style="padding-right: 6px;"><?php echo html::select("plans[][]", '', '', "class='form-control chosen' multiple");?></div>
|
||||
<div class="col-sm-4" id="plan0" style="padding-right: 6px;"><?php echo html::select("plans[][][]", '', '', "class='form-control chosen' multiple");?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
<?php js::set('multiBranchProducts', $multiBranchProducts);?>
|
||||
<?php $aclList = $project->parent ? $lang->project->subAclList : $lang->project->aclList;?>
|
||||
<?php $requiredFields = $config->project->edit->requiredFields;?>
|
||||
<?php js::set('requiredFields', $requiredFields);?>
|
||||
<?php js::set('budget', $project->budget);?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php js::set('projectID', $projectID);?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<div class='btn-group'>
|
||||
<?php $viewName = $productID != 0 ? zget($productList,$productID) : $lang->product->allProduct;?>
|
||||
<a href='javascript:;' class='btn btn-link btn-limit' data-toggle='dropdown'><span class='text' title='<?php echo $viewName;?>'><?php echo $viewName;?></span> <span class='caret'></span></a>
|
||||
<ul class='dropdown-menu' style='max-height:240px; max-width: 300px; overflow-y:auto'>
|
||||
<?php
|
||||
$class = '';
|
||||
if($productID == 0) $class = 'class="active"';
|
||||
echo "<li $class>" . html::a($this->createLink('project', 'execution', "status=$status&projectID=$projectID&orderby=$orderBy"), $lang->product->allProduct) . "</li>";
|
||||
foreach($productList as $key => $product)
|
||||
{
|
||||
$class = $productID == $key ? 'class="active"' : '';
|
||||
echo "<li $class>" . html::a($this->createLink('project', 'execution', "status=$status&projectID=$projectID&orderby=$orderBy&productID=$key"), $product) . "</li>";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php foreach($lang->execution->featureBar['all'] as $key => $label):?>
|
||||
<?php $label = "<span class='text'>$label</span>";?>
|
||||
<?php if($status == $key) $label .= " <span class='label label-light label-badge'>{$pager->recTotal}</span>";?>
|
||||
<?php echo html::a($this->createLink('project', 'execution', "status=$key&projectID=$projectID&orderBy=$orderBy&productID=$productID"), $label, '', "class='btn btn-link' id='{$key}Tab'");?>
|
||||
<?php endforeach;?>
|
||||
<?php echo html::checkbox('showTask', array('1' => $lang->programplan->stageCustom->task), '', $this->cookie->showTask ? 'checked=checked' : '');?>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<?php common::printLink('execution', 'export', "status=$status&productID=$productID&orderBy=$orderBy&from=project", "<i class='icon-export muted'> </i> " . $lang->export, '', "class='btn btn-link export'")?>
|
||||
<?php if(common::hasPriv('programplan', 'create') and $isStage):?>
|
||||
<?php echo html::a($this->createLink('programplan', 'create', "projectID=$projectID&productID=$productID"), "<i class='icon icon-plus'></i> " . $lang->programplan->create, '', "class='btn btn-primary'");?>
|
||||
<?php else: ?>
|
||||
<?php if(common::hasPriv('execution', 'create')) echo html::a($this->createLink('execution', 'create', "projectID=$projectID"), "<i class='icon icon-sm icon-plus'></i> " . $lang->execution->create, '', "class='btn btn-primary create-execution-btn' data-app='execution' onclick='$(this).removeAttr(\"data-toggle\")'");?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<div id='mainContent' class="main-row fade">
|
||||
<?php if(empty($executionStats)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->execution->noExecution;?></span>
|
||||
<?php if(empty($allExecutionNum)):?>
|
||||
<?php if(common::hasPriv('programplan', 'create') and $isStage):?>
|
||||
<?php echo html::a($this->createLink('programplan', 'create', "projectID=$projectID&productID=$productID"), "<i class='icon icon-plus'></i> " . $lang->programplan->create, '', "class='btn btn-info'");?>
|
||||
<?php else: ?>
|
||||
<?php if(common::hasPriv('execution', 'create')):?>
|
||||
<?php echo html::a($this->createLink('execution', 'create', "projectID=$projectID"), "<i class='icon icon-plus'></i> " . $lang->execution->create, '', "class='btn btn-info' data-app='execution'");?>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
</p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<?php $canBatchEdit = common::hasPriv('execution', 'batchEdit'); ?>
|
||||
<form class='main-table' id='executionForm' method='post' data-ride='table' data-nested='true' data-expand-nest-child='false' data-checkable='false' data-enable-empty-nested-row='true' data-replace-id='executionTableList' data-preserve-nested='true'>
|
||||
<table class="table table-from table-fixed table-nested" id="executionList">
|
||||
<?php $vars = "status=$status&orderBy=%s";?>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='table-nest-title'>
|
||||
<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 echo $lang->nameAB;?>
|
||||
</th>
|
||||
<th class='c-user'><?php echo $lang->execution->owner;?></th>
|
||||
<th class='c-status'><?php echo $lang->project->status;?></th>
|
||||
<th class='c-hours'><?php echo $lang->project->progress;?></th>
|
||||
<th class='c-date'><?php echo $lang->programplan->begin;?></th>
|
||||
<th class='c-date'><?php echo $lang->programplan->end;?></th>
|
||||
<th class='c-hours'><?php echo $lang->task->estimateAB;?></th>
|
||||
<th class='c-hours'><?php echo $lang->task->consumedAB;?></th>
|
||||
<th class='c-hours'><?php echo $lang->task->leftAB;?> </th>
|
||||
<th class='c-progress'><?php echo $lang->execution->burn;?> </th>
|
||||
<th class='text-center c-actions-6'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="executionTableList">
|
||||
<?php foreach($executionStats as $execution):?>
|
||||
<?php $this->execution->printNestedList($execution, false, $users, $productID);?>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class='table-footer'>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php js::set('status', $status)?>
|
||||
<?php js::set('orderBy', $orderBy)?>
|
||||
<script>
|
||||
$("#<?php echo $status;?>Tab").addClass('btn-active-text');
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -150,9 +150,10 @@
|
||||
<div class='actions'><?php echo html::a("javascript:showLink({$release->id}, \"bug\")", '<i class="icon-bug"></i> ' . $lang->release->linkBug, '', "class='btn btn-primary'");?></div>
|
||||
<div class='linkBox cell hidden'></div>
|
||||
<?php endif;?>
|
||||
<form class='main-table table-bug' method='post' target='hiddenwin' action="<?php echo inLink('batchUnlinkBug', "releaseID=$release->id");?>" id='linkedBugsForm' data-ride="table">
|
||||
<form class='main-table table-bug' method='post' target='hiddenwin' id='linkedBugsForm' data-ride="table">
|
||||
<table class='table has-sort-head' id='bugList'>
|
||||
<?php $canBatchUnlink = common::hasPriv('projectrelease', 'batchUnlinkBug');?>
|
||||
<?php $canBatchClose = common::hasPriv('bug', 'batchClose');?>
|
||||
<?php $vars = "releaseID={$release->id}&type=bug&link=$link¶m=$param&orderBy=%s";?>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
@@ -178,7 +179,7 @@
|
||||
<?php $bugLink = $this->createLink('bug', 'view', "bugID=$bug->id", '', true);?>
|
||||
<tr>
|
||||
<td class='c-id text-left'>
|
||||
<?php if($canBatchUnlink and $canBeChanged):?>
|
||||
<?php if(($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
|
||||
<div class="checkbox-primary">
|
||||
<input type='checkbox' name='unlinkBugs[]' value='<?php echo $bug->id;?>'/>
|
||||
<label></label>
|
||||
@@ -208,10 +209,21 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<div class='table-footer'>
|
||||
<?php if($countBugs and $canBatchUnlink and $canBeChanged):?>
|
||||
<?php if($countBugs and ($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<div class="table-actions btn-toolbar">
|
||||
<?php echo html::submitButton($lang->release->batchUnlink, '', 'btn');?>
|
||||
<?php
|
||||
if($canBatchUnlink and $canBeChanged)
|
||||
{
|
||||
$unlinkURL = $this->createLink('projectrelease', 'batchUnlinkBug', "releaseID=$release->id");
|
||||
echo html::a("###", $lang->release->batchUnlink, '', "onclick='setFormAction(\"$unlinkURL\", \"hiddenwin\", this)' class='btn'");
|
||||
}
|
||||
if($canBatchClose and $canBeChanged)
|
||||
{
|
||||
$closeURL = $this->createLink('bug', 'batchClose', "releaseID=$release->id&viewType=projectrelease");
|
||||
echo html::a("###", $lang->story->batchClose, '', "onclick='setFormAction(\"$closeURL\", \"hiddenwin\", this)' class='btn'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class='table-statistic'><?php echo sprintf($lang->release->resolvedBugs, $countBugs);?></div>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -152,9 +152,10 @@
|
||||
<div class='actions'><?php echo html::a("javascript:showLink({$release->id}, \"bug\")", '<i class="icon-bug"></i> ' . $lang->release->linkBug, '', "class='btn btn-primary'");?></div>
|
||||
<div class='linkBox cell hidden'></div>
|
||||
<?php endif;?>
|
||||
<form class='main-table table-bug' method='post' target='hiddenwin' action="<?php echo inLink('batchUnlinkBug', "releaseID=$release->id");?>" id='linkedBugsForm' data-ride="table">
|
||||
<form class='main-table table-bug' method='post' target='hiddenwin' id='linkedBugsForm' data-ride="table">
|
||||
<table class='table has-sort-head' id='bugList'>
|
||||
<?php $canBatchUnlink = common::hasPriv('release', 'batchUnlinkBug');?>
|
||||
<?php $canBatchClose = common::hasPriv('bug', 'batchClose');?>
|
||||
<?php $vars = "releaseID={$release->id}&type=bug&link=$link¶m=$param&orderBy=%s";?>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
@@ -180,7 +181,7 @@
|
||||
<?php $bugLink = $this->createLink('bug', 'view', "bugID=$bug->id", '', true);?>
|
||||
<tr>
|
||||
<td class='c-id text-left'>
|
||||
<?php if($canBatchUnlink and $canBeChanged):?>
|
||||
<?php if($canBatchUnlink or $canBatchClose and $canBeChanged):?>
|
||||
<div class="checkbox-primary">
|
||||
<input type='checkbox' name='unlinkBugs[]' value='<?php echo $bug->id;?>'/>
|
||||
<label></label>
|
||||
@@ -210,10 +211,21 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<div class='table-footer'>
|
||||
<?php if($countBugs and $canBatchUnlink and $canBeChanged):?>
|
||||
<?php if($countBugs and ($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<div class="table-actions btn-toolbar">
|
||||
<?php echo html::submitButton($lang->release->batchUnlink, '', 'btn');?>
|
||||
<?php
|
||||
if($canBatchUnlink)
|
||||
{
|
||||
$unlinkURL = inlink('batchUnlinkBug', "release=$release->id");
|
||||
echo html::a('###', $lang->release->batchUnlink, '', "onclick='setFormAction(\"$unlinkURL\", \"hiddenwin\", this)' class='btn'");
|
||||
}
|
||||
if($canBatchClose)
|
||||
{
|
||||
$closeURL = $this->createLink('bug', 'batchClose', "release=$release->id&viewType=release");
|
||||
echo html::a("###", $lang->story->batchClose, '', "onclick='setFormAction(\"$closeURL\", \"hiddenwin\", this)' class='btn'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class='table-statistic'><?php echo sprintf($lang->release->resolvedBugs, $countBugs);?></div>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -129,7 +129,7 @@ $config->story->datatable->fieldList['estimate']['required'] = 'no';
|
||||
|
||||
$config->story->datatable->fieldList['stage']['title'] = 'stageAB';
|
||||
$config->story->datatable->fieldList['stage']['fixed'] = 'no';
|
||||
$config->story->datatable->fieldList['stage']['width'] = '70';
|
||||
$config->story->datatable->fieldList['stage']['width'] = '75';
|
||||
$config->story->datatable->fieldList['stage']['required'] = 'no';
|
||||
|
||||
$config->story->datatable->fieldList['openedBy']['title'] = 'openedByAB';
|
||||
|
||||
+88
-79
@@ -162,12 +162,14 @@ class story extends control
|
||||
$object = $this->dao->findById((int)$objectID)->from(TABLE_PROJECT)->fetch();
|
||||
if($object->type != 'project')
|
||||
{
|
||||
if($this->config->systemMode == 'new') $this->action->create('story', $storyID, 'linked2project', '', $object->project);
|
||||
|
||||
$actionType = $object->type == 'kanban' ? 'linked2kanban' : 'linked2execution';
|
||||
$this->loadModel('action')->create('story', $storyID, $actionType, '', $objectID);
|
||||
$this->action->create('story', $storyID, $actionType, '', $objectID);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->loadModel('action')->create('story', $storyID, 'linked2project', '', $objectID);
|
||||
$this->action->create('story', $storyID, 'linked2project', '', $objectID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,23 +197,24 @@ class story extends control
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, 0)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban(\"story\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
@@ -499,8 +502,8 @@ class story extends control
|
||||
{
|
||||
$products = array();
|
||||
foreach($mails as $story) $products[$story->storyID] = $productID;
|
||||
$this->execution->linkStory($executionID, $stories, $products, $extra, $lanes);
|
||||
if($executionID != $this->session->project) $this->execution->linkStory($this->session->project, $stories, $products);
|
||||
$this->execution->linkStory($executionID, $stories, $products, $extra, $lanes);
|
||||
}
|
||||
|
||||
/* If storyID not equal zero, subdivide this story to child stories and close it. */
|
||||
@@ -518,22 +521,23 @@ class story extends control
|
||||
$execution = $this->execution->getByID($executionID);
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"story\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
@@ -749,22 +753,23 @@ class story extends control
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $kanbanGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $kanbanGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"story\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
@@ -1081,21 +1086,22 @@ class story extends control
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
if($this->app->tab == 'execution')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"story\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
@@ -1163,11 +1169,11 @@ class story extends control
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $taskSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
@@ -1315,13 +1321,13 @@ class story extends control
|
||||
|
||||
if($this->app->tab == 'execution' and $from == 'taskkanban')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($this->session->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($this->session->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent', '', "parent.updateKanban(\"story\", $kanbanData)"));
|
||||
}
|
||||
|
||||
@@ -1363,21 +1369,22 @@ class story extends control
|
||||
{
|
||||
$this->loadModel('kanban')->updateLane($this->session->execution, 'story', $storyID);
|
||||
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($this->session->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($this->session->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"story\", $kanbanData)"));
|
||||
}
|
||||
}
|
||||
@@ -1506,12 +1513,12 @@ class story extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
{
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$this->loadModel('kanban')->updateLane($this->session->execution, 'story', $storyID);
|
||||
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
@@ -1520,10 +1527,11 @@ class story extends control
|
||||
}
|
||||
elseif($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($this->session->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($this->session->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"story\", $kanbanData)"));
|
||||
}
|
||||
else
|
||||
@@ -1870,23 +1878,24 @@ class story extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$execution = $this->execution->getByID($this->session->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($this->app->tab == 'execution' and $execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $kanbanGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $kanbanGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
elseif($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"story\", $kanbanData)"));
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($execution->id, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban('$execLaneType', $kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -3931,7 +3931,7 @@ class storyModel extends model
|
||||
if($story->stage == 'projected') $title = $this->lang->story->subDivideTip['projected'];
|
||||
}
|
||||
}
|
||||
$menu .= $this->buildMenu('story', 'batchCreate', "productID=$story->product&branch=$story->branch&module=$story->module&$params&executionID={$this->session->project}", $story, $type, 'split', '', 'showinonlybody', '', '', $title);
|
||||
$menu .= $this->buildMenu('story', 'batchCreate', "productID=$story->product&branch=$story->branch&module=$story->module&$params", $story, $type, 'split', '', 'showinonlybody', '', '', $title);
|
||||
}
|
||||
if($this->app->rawModule == 'projectstory' and $this->config->vision != 'lite') $menu .= $this->buildMenu('projectstory', 'unlinkStory', "projectID={$this->session->project}&$params", $story, $type, 'unlink', 'hiddenwin', 'showinonlybody');
|
||||
|
||||
|
||||
+219
-135
@@ -49,6 +49,7 @@ class task extends control
|
||||
$executionID = $this->execution->saveState($executionID, $executions);
|
||||
$execution = $this->execution->getById($executionID);
|
||||
$this->execution->setMenu($executionID);
|
||||
if($this->app->tab == 'project') $this->loadModel('project')->setMenu($this->session->project);
|
||||
|
||||
$this->execution->getLimitedExecution();
|
||||
$limitedExecutions = !empty($_SESSION['limitedExecutions']) ? $_SESSION['limitedExecutions'] : '';
|
||||
@@ -185,22 +186,23 @@ class task extends control
|
||||
{
|
||||
if($this->app->tab == 'execution' or $this->config->vision == 'lite')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, 0)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->kanban->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->kanban->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -347,6 +349,7 @@ class task extends control
|
||||
|
||||
/* Set menu. */
|
||||
$this->execution->setMenu($execution->id);
|
||||
if($this->app->tab == 'project') $this->loadModel('project')->setMenu($this->session->project);
|
||||
|
||||
/* When common task are child tasks, query whether common task are consumed. */
|
||||
$taskConsumed = 0;
|
||||
@@ -372,22 +375,23 @@ class task extends control
|
||||
{
|
||||
if($this->app->tab == 'execution' or $this->config->vision == 'lite')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, 0)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($executionID, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -542,23 +546,24 @@ class task extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -575,6 +580,8 @@ class task extends control
|
||||
}
|
||||
}
|
||||
|
||||
if($this->app->tab == 'project') $this->loadModel('project')->setMenu($this->session->project);
|
||||
|
||||
$tasks = $this->task->getParentTaskPairs($this->view->execution->id, $this->view->task->parent);
|
||||
if(isset($tasks[$taskID])) unset($tasks[$taskID]);
|
||||
|
||||
@@ -777,24 +784,25 @@ class task extends control
|
||||
if($this->viewType == 'json' or (defined('RUN_MODE') && RUN_MODE == 'api')) return $this->send(array('result' => 'success'));
|
||||
if(isonlybody())
|
||||
{
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroup, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
if($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -899,6 +907,7 @@ class task extends control
|
||||
$this->session->set('executionList', $this->app->getURI(true), 'execution');
|
||||
|
||||
$this->commonAction($taskID);
|
||||
if($this->app->tab == 'project') $this->loadModel('project')->setMenu($this->session->project);
|
||||
|
||||
$taskID = (int)$taskID;
|
||||
$task = $this->task->getById($taskID, true);
|
||||
@@ -1035,24 +1044,25 @@ class task extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
if($output['from'] == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -1110,20 +1120,21 @@ class task extends control
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
if($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -1182,19 +1193,36 @@ class task extends control
|
||||
*/
|
||||
public function deleteEstimate($estimateID, $confirm = 'no')
|
||||
{
|
||||
if($confirm == 'no')
|
||||
$estimate = $this->task->getEstimateById($estimateID);
|
||||
$task = $this->task->getById($estimate->task);
|
||||
if($confirm == 'no' and $task->consumed - $estimate->consumed != 0)
|
||||
{
|
||||
return print(js::confirm($this->lang->task->confirmDeleteEstimate, $this->createLink('task', 'deleteEstimate', "estimateID=$estimateID&confirm=yes")));
|
||||
}
|
||||
elseif($confirm == 'no' and $task->consumed - $estimate->consumed == 0)
|
||||
{
|
||||
return print(js::confirm($this->lang->task->confirmDeleteLastEstimate, $this->createLink('task', 'deleteEstimate', "estimateID=$estimateID&confirm=yes")));
|
||||
}
|
||||
else
|
||||
{
|
||||
$estimate = $this->task->getEstimateById($estimateID);
|
||||
$changes = $this->task->deleteEstimate($estimateID);
|
||||
if(dao::isError()) return print(js::error(dao::getError()));
|
||||
|
||||
$actionID = $this->loadModel('action')->create('task', $estimate->task, 'DeleteEstimate');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
return print(js::reload('parent'));
|
||||
if($task->consumed - $estimate->consumed == 0)
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('task', $estimate->task, 'Adjusttasktowait');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
if($task->consumed - $estimate->consumed == 0)
|
||||
{
|
||||
return print(js::reload('parent.parent'));
|
||||
}
|
||||
else
|
||||
{
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1251,24 +1279,25 @@ class task extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == "kanban")
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
if($output['from'] == "taskkanban")
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -1347,25 +1376,26 @@ class task extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
if($output['from'] == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -1413,24 +1443,25 @@ class task extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
|
||||
}
|
||||
if($from == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -1495,23 +1526,24 @@ class task extends control
|
||||
}
|
||||
}
|
||||
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
if($output['from'] == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -1665,25 +1697,26 @@ class task extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
if($output['from'] == 'taskkanban')
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -1730,25 +1763,26 @@ class task extends control
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
if($execution->type == "kanban")
|
||||
{
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
if($output['from'] == "taskkanban")
|
||||
{
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
@@ -1806,13 +1840,13 @@ class task extends control
|
||||
if(isonlybody()) return print(js::reload('parent.parent'));
|
||||
if($from == 'taskkanban')
|
||||
{
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($this->session->execution, $execLaneType, $execGroupBy, $rdSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
|
||||
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($this->session->execution, $execLaneType, $execGroupBy, $taskSearchValue);
|
||||
$kanbanType = $execLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
return print(js::closeModal('parent', '', "parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
|
||||
@@ -1862,6 +1896,56 @@ class task extends control
|
||||
echo html::select('task', empty($tasks) ? array('' => '') : $tasks, $taskID, "class='form-control'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get tasks for execution list.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param int $maxTaskID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetTasks($executionID, $maxTaskID = 0)
|
||||
{
|
||||
$this->loadModel('task');
|
||||
$this->loadModel('execution');
|
||||
$execution = $this->dao->findById($executionID)->from(TABLE_EXECUTION)->fetch();
|
||||
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('status')->notin('closed,cancel')
|
||||
->andWhere('execution')->eq($executionID)
|
||||
->andWhere('id')->gt($maxTaskID)
|
||||
->orderBy('id_asc')
|
||||
->fetchAll('id');
|
||||
|
||||
$users = $this->loadModel('user')->getPairs('noletter|nodeleted');
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
if($task->parent > 0)
|
||||
{
|
||||
if(isset($tasks[$task->parent]))
|
||||
{
|
||||
$tasks[$task->parent]->children[$task->id] = $task;
|
||||
unset($tasks[$task->id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($tasks)) die('');
|
||||
|
||||
$list = '';
|
||||
$tasks = array_chunk($tasks, 50, true);
|
||||
$tasks = $tasks[0];
|
||||
$count = count($tasks);
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
$showmore = ($count == 50) && ($task == end($tasks));
|
||||
$list .= $this->task->buildNestedList($execution, $task, false, $showmore, $users);
|
||||
}
|
||||
|
||||
die($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: get the actions of a task. for web app.
|
||||
*
|
||||
|
||||
@@ -127,7 +127,8 @@ function loadExecutionStories(executionID)
|
||||
*/
|
||||
function loadModuleMenu(executionID)
|
||||
{
|
||||
var link = createLink('tree', 'ajaxGetOptionMenu', 'rootID=' + executionID + '&viewtype=task');
|
||||
var extra = $('#showAllModule').prop('checked') ? 'allModule' : '';
|
||||
var link = createLink('tree', 'ajaxGetOptionMenu', 'rootID=' + executionID + '&viewtype=task&branch=0&rootModuleID=0&returnType=html&fieldID=&needManage=0&extra=' + extra);
|
||||
$('#moduleIdBox').load(link, function(){$('#module').chosen();});
|
||||
}
|
||||
|
||||
@@ -501,11 +502,12 @@ $(document).ready(function()
|
||||
|
||||
$('#showAllModule').change(function()
|
||||
{
|
||||
var moduleID = $('#moduleIdBox #module').val();
|
||||
var extra = $(this).prop('checked') ? 'allModule' : '';
|
||||
var executionID = $('#execution').val();
|
||||
var moduleID = $('#moduleIdBox #module').val();
|
||||
var extra = $(this).prop('checked') ? 'allModule' : '';
|
||||
$('#moduleIdBox').load(createLink('tree', 'ajaxGetOptionMenu', "rootID=" + executionID + '&viewType=task&branch=0&rootModuleID=0&returnType=html&fieldID=&needManage=0&extra=' + extra), function()
|
||||
{
|
||||
$('#moduleIdBox #module').val(moduleID).chosen();
|
||||
$('#module').val(moduleID).chosen();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+21
-21
@@ -214,27 +214,27 @@ $lang->task->legendDesc = 'Aufgabenbeschreibung';
|
||||
$lang->task->legendDetail = 'Task Detail';
|
||||
$lang->task->legendMisc = 'Misc.';
|
||||
|
||||
$lang->task->confirmDelete = "Möchten Sie diese Aufgabe löschen?";
|
||||
$lang->task->confirmDeleteEstimate = "Möchten Sie das löschen?";
|
||||
$lang->task->copyStoryTitle = "Story kopieren";
|
||||
$lang->task->afterSubmit = "Nach der Erstellung,";
|
||||
$lang->task->successSaved = "Erstellt!";
|
||||
$lang->task->delayWarning = " <strong class='text-danger'> Verzögerung %s Tage </strong>";
|
||||
$lang->task->remindBug = "Diese Aufgabe wurde aus einem Bus erzeugt. Möchten Sie den Bug aktualisieren:%s?";
|
||||
$lang->task->remindIssue = "This task is converted from a issue. Do you want to update the Issue:%s?";
|
||||
$lang->task->confirmChangeExecution = "Wenn Sie {$lang->executionCommon} ändern, das verwendete Modul, Story and Assignor will be changed. Do you want to do it?";
|
||||
$lang->task->confirmFinish = '"Reststunden " sind 0. Möchten Sue den Status auf Erledigt setzen?';
|
||||
$lang->task->confirmRecord = '"Reststunden " sind 0. Möchten Sie den Task auf Erledigt setzen?';
|
||||
$lang->task->confirmTransfer = '"Reststunden " sind 0. Möchten Sie den Task transferieren?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "Es wurde keine Story verknüpft. Sie können %s für dieses Projekt, anschließend %s.";
|
||||
$lang->task->noticeSaveRecord = 'Ihre Stunden wurden nicht gespeichrt. Bitte erst speichern.';
|
||||
$lang->task->commentActions = '%s. %s, kommentiert von <strong>%s</strong>.';
|
||||
$lang->task->deniedNotice = 'Nur %s kann die Aufgabe %s.';
|
||||
$lang->task->noTask = 'Keine Aufagben. ';
|
||||
$lang->task->createDenied = 'Aufgben erstellen it in diesem Projekt gesperrt';
|
||||
$lang->task->cannotDeleteParent = 'Cannot delete parent task';
|
||||
$lang->task->addChildTask = 'Because the task has already consumed consumption, to ensure data consistency, we will help you create a subtask with the same name to record the consumption.';
|
||||
$lang->task->confirmDelete = "Möchten Sie diese Aufgabe löschen?";
|
||||
$lang->task->confirmDeleteLastEstimate = "Do you want to delete the log? After deleting the last work log, the task status will be adjusted to Not Started.";
|
||||
$lang->task->copyStoryTitle = "Story kopieren";
|
||||
$lang->task->afterSubmit = "Nach der Erstellung,";
|
||||
$lang->task->successSaved = "Erstellt!";
|
||||
$lang->task->delayWarning = " <strong class='text-danger'> Verzögerung %s Tage </strong>";
|
||||
$lang->task->remindBug = "Diese Aufgabe wurde aus einem Bus erzeugt. Möchten Sie den Bug aktualisieren:%s?";
|
||||
$lang->task->remindIssue = "This task is converted from a issue. Do you want to update the Issue:%s?";
|
||||
$lang->task->confirmChangeExecution = "Wenn Sie {$lang->executionCommon} ändern, das verwendete Modul, Story and Assignor will be changed. Do you want to do it?";
|
||||
$lang->task->confirmFinish = '"Reststunden " sind 0. Möchten Sue den Status auf Erledigt setzen?';
|
||||
$lang->task->confirmRecord = '"Reststunden " sind 0. Möchten Sie den Task auf Erledigt setzen?';
|
||||
$lang->task->confirmTransfer = '"Reststunden " sind 0. Möchten Sie den Task transferieren?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "Es wurde keine Story verknüpft. Sie können %s für dieses Projekt, anschließend %s.";
|
||||
$lang->task->noticeSaveRecord = 'Ihre Stunden wurden nicht gespeichrt. Bitte erst speichern.';
|
||||
$lang->task->commentActions = '%s. %s, kommentiert von <strong>%s</strong>.';
|
||||
$lang->task->deniedNotice = 'Nur %s kann die Aufgabe %s.';
|
||||
$lang->task->noTask = 'Keine Aufagben. ';
|
||||
$lang->task->createDenied = 'Aufgben erstellen it in diesem Projekt gesperrt';
|
||||
$lang->task->cannotDeleteParent = 'Cannot delete parent task';
|
||||
$lang->task->addChildTask = 'Because the task has already consumed consumption, to ensure data consistency, we will help you create a subtask with the same name to record the consumption.';
|
||||
|
||||
$lang->task->error = new stdclass();
|
||||
$lang->task->error->totalNumber = '"Total Cost" must be numbers.';
|
||||
|
||||
+22
-21
@@ -214,27 +214,28 @@ $lang->task->legendDesc = 'Task Description';
|
||||
$lang->task->legendDetail = 'Task Detail';
|
||||
$lang->task->legendMisc = 'Misc.';
|
||||
|
||||
$lang->task->confirmDelete = "Do you want to delete this task?";
|
||||
$lang->task->confirmDeleteEstimate = "Do you want to delete it?";
|
||||
$lang->task->copyStoryTitle = "Copy Story";
|
||||
$lang->task->afterSubmit = "Next ";
|
||||
$lang->task->successSaved = "Created!";
|
||||
$lang->task->delayWarning = " <strong class='text-danger'> Delay %s days </strong>";
|
||||
$lang->task->remindBug = "This task is converted from a bug. Do you want to update the Bug:%s?";
|
||||
$lang->task->remindIssue = "This task is converted from a issue. Do you want to update the Issue:%s?";
|
||||
$lang->task->confirmChangeExecution = "If you change {$lang->executionCommon}, Module, Story and AssignedTo will also be changed. Do you want to change it?";
|
||||
$lang->task->confirmFinish = '"Left Hour" is 0. Do you want to change the status to "Finished"?';
|
||||
$lang->task->confirmRecord = '"Left Hour" is 0. Do you want to set the task as "Finished"?';
|
||||
$lang->task->confirmTransfer = '"Left Hour" is 0,Do you want to transfer task?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "No story has been linked. You can %s for this project, then %s.";
|
||||
$lang->task->noticeSaveRecord = 'Your Hour is not saved. Please save it first.';
|
||||
$lang->task->commentActions = '%s. %s, commented by <strong>%s</strong>.';
|
||||
$lang->task->deniedNotice = 'Only the %s can %s the task.';
|
||||
$lang->task->noTask = 'No tasks yet. ';
|
||||
$lang->task->createDenied = 'Create Task is denied in this project';
|
||||
$lang->task->cannotDeleteParent = 'Cannot delete parent task';
|
||||
$lang->task->addChildTask = 'Because the task has cost hours, ZenTao will create a child task with the same name to record the cost housrs to ensure data consistency.';
|
||||
$lang->task->confirmDelete = "Do you want to delete this task?";
|
||||
$lang->task->confirmDeleteEstimate = "Do you want to delete it?";
|
||||
$lang->task->confirmDeleteLastEstimate = "Do you want to delete the log? After deleting the last work log, the task status will be adjusted to Not Started.";
|
||||
$lang->task->copyStoryTitle = "Copy Story";
|
||||
$lang->task->afterSubmit = "Next ";
|
||||
$lang->task->successSaved = "Created!";
|
||||
$lang->task->delayWarning = " <strong class='text-danger'> Delay %s days </strong>";
|
||||
$lang->task->remindBug = "This task is converted from a bug. Do you want to update the Bug:%s?";
|
||||
$lang->task->remindIssue = "This task is converted from a issue. Do you want to update the Issue:%s?";
|
||||
$lang->task->confirmChangeExecution = "If you change {$lang->executionCommon}, Module, Story and AssignedTo will also be changed. Do you want to change it?";
|
||||
$lang->task->confirmFinish = '"Left Hour" is 0. Do you want to change the status to "Finished"?';
|
||||
$lang->task->confirmRecord = '"Left Hour" is 0. Do you want to set the task as "Finished"?';
|
||||
$lang->task->confirmTransfer = '"Left Hour" is 0,Do you want to transfer task?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "No story has been linked. You can %s for this project, then %s.";
|
||||
$lang->task->noticeSaveRecord = 'Your Hour is not saved. Please save it first.';
|
||||
$lang->task->commentActions = '%s. %s, commented by <strong>%s</strong>.';
|
||||
$lang->task->deniedNotice = 'Only the %s can %s the task.';
|
||||
$lang->task->noTask = 'No tasks yet. ';
|
||||
$lang->task->createDenied = 'Create Task is denied in this project';
|
||||
$lang->task->cannotDeleteParent = 'Cannot delete parent task';
|
||||
$lang->task->addChildTask = 'Because the task has cost hours, ZenTao will create a child task with the same name to record the cost housrs to ensure data consistency.';
|
||||
|
||||
$lang->task->error = new stdclass();
|
||||
$lang->task->error->totalNumber = '"Total Cost" must be numbers.';
|
||||
|
||||
+22
-21
@@ -214,27 +214,28 @@ $lang->task->legendDesc = 'Description Tâche';
|
||||
$lang->task->legendDetail = 'Task Detail';
|
||||
$lang->task->legendMisc = 'Misc.';
|
||||
|
||||
$lang->task->confirmDelete = "Voulez-vous réellement supprimer cette tâche ?";
|
||||
$lang->task->confirmDeleteEstimate = "Voulez-vous la supprimer ?";
|
||||
$lang->task->copyStoryTitle = '<span style="color:blue;">StoryModel</span>';
|
||||
$lang->task->afterSubmit = "Suiv. ";
|
||||
$lang->task->successSaved = "Créée !";
|
||||
$lang->task->delayWarning = " <strong class='text-danger'> Retard %s jours </strong>";
|
||||
$lang->task->remindBug = "Cette tâche a été convertie depuis un bug. Voulez-vous mettre à jour le Bug : %s ?";
|
||||
$lang->task->remindIssue = "This task is converted from a issue. Do you want to update the Issue:%s?";
|
||||
$lang->task->confirmChangeExecution = "Si vous changez {$lang->executionCommon}, Module, Story et AssignedTo seront également changés. Voulez-vous le faire ?";
|
||||
$lang->task->confirmFinish = '"Heures Restantes" à 0. Voulez-vous passer le statut à "Terminée" ?';
|
||||
$lang->task->confirmRecord = '"Heures Restantes" à 0. Voulez-vous passer le statut de la tâche à "Finie" ?';
|
||||
$lang->task->confirmTransfer = '"Heures Restantes" à 0. Voulez-vous transférer la tâche ?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "Aucune Story n'est associée. Vous pouvez %s pour ce projet, alors %s.";
|
||||
$lang->task->noticeSaveRecord = "Votre temps n'a pas été sauvé. Enregistrez-le d'abord.";
|
||||
$lang->task->commentActions = '%s. %s, commenté par <strong>%s</strong>.';
|
||||
$lang->task->deniedNotice = 'Seulement le %s peut %s la tâche.';
|
||||
$lang->task->noTask = "Pas de tâche pour l'instant. ";
|
||||
$lang->task->createDenied = 'La création de tâches est interdite dans ce projet';
|
||||
$lang->task->cannotDeleteParent = 'Impossible de supprimer la tâche parente';
|
||||
$lang->task->addChildTask = 'Because the task has already consumed consumption, to ensure data consistency, we will help you create a subtask with the same name to record the consumption.';
|
||||
$lang->task->confirmDelete = "Voulez-vous réellement supprimer cette tâche ?";
|
||||
$lang->task->confirmDeleteEstimate = "Voulez-vous la supprimer ?";
|
||||
$lang->task->confirmDeleteLastEstimate = "Do you want to delete the log? After deleting the last work log, the task status will be adjusted to Not Started.";
|
||||
$lang->task->copyStoryTitle = '<span style="color:blue;">StoryModel</span>';
|
||||
$lang->task->afterSubmit = "Suiv. ";
|
||||
$lang->task->successSaved = "Créée !";
|
||||
$lang->task->delayWarning = " <strong class='text-danger'> Retard %s jours </strong>";
|
||||
$lang->task->remindBug = "Cette tâche a été convertie depuis un bug. Voulez-vous mettre à jour le Bug : %s ?";
|
||||
$lang->task->remindIssue = "This task is converted from a issue. Do you want to update the Issue:%s?";
|
||||
$lang->task->confirmChangeExecution = "Si vous changez {$lang->executionCommon}, Module, Story et AssignedTo seront également changés. Voulez-vous le faire ?";
|
||||
$lang->task->confirmFinish = '"Heures Restantes" à 0. Voulez-vous passer le statut à "Terminée" ?';
|
||||
$lang->task->confirmRecord = '"Heures Restantes" à 0. Voulez-vous passer le statut de la tâche à "Finie" ?';
|
||||
$lang->task->confirmTransfer = '"Heures Restantes" à 0. Voulez-vous transférer la tâche ?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "Aucune Story n'est associée. Vous pouvez %s pour ce projet, alors %s.";
|
||||
$lang->task->noticeSaveRecord = "Votre temps n'a pas été sauvé. Enregistrez-le d'abord.";
|
||||
$lang->task->commentActions = '%s. %s, commenté par <strong>%s</strong>.';
|
||||
$lang->task->deniedNotice = 'Seulement le %s peut %s la tâche.';
|
||||
$lang->task->noTask = "Pas de tâche pour l'instant. ";
|
||||
$lang->task->createDenied = 'La création de tâches est interdite dans ce projet';
|
||||
$lang->task->cannotDeleteParent = 'Impossible de supprimer la tâche parente';
|
||||
$lang->task->addChildTask = 'Because the task has already consumed consumption, to ensure data consistency, we will help you create a subtask with the same name to record the consumption.';
|
||||
|
||||
$lang->task->error = new stdclass();
|
||||
$lang->task->error->totalNumber = '"Coût Total" doit être numérique.';
|
||||
|
||||
+22
-21
@@ -214,27 +214,28 @@ $lang->task->legendDesc = '任务描述';
|
||||
$lang->task->legendDetail = '任务详情';
|
||||
$lang->task->legendMisc = '其他相关';
|
||||
|
||||
$lang->task->confirmDelete = "您确定要删除这个任务吗?";
|
||||
$lang->task->confirmDeleteEstimate = "您确定要删除这个记录吗?";
|
||||
$lang->task->copyStoryTitle = "同{$lang->SRCommon}";
|
||||
$lang->task->afterSubmit = "添加之后";
|
||||
$lang->task->successSaved = "成功添加,";
|
||||
$lang->task->delayWarning = " <strong class='text-danger'> 延期%s天 </strong>";
|
||||
$lang->task->remindBug = "该任务为Bug转化得到,是否更新Bug:%s ?";
|
||||
$lang->task->remindIssue = "该任务为问题转化得到,是否更新问题:%s ?";
|
||||
$lang->task->confirmChangeExecution = "修改{$lang->executionCommon}会导致相应的所属模块、相关{$lang->SRCommon}和指派人发生变化,确定吗?";
|
||||
$lang->task->confirmFinish = '"预计剩余"为0,确认将任务状态改为"已完成"吗?';
|
||||
$lang->task->confirmRecord = '"剩余"为0,任务将标记为"已完成",您确定吗?';
|
||||
$lang->task->confirmTransfer = '"当前剩余"为0,任务将被转交,您确定吗?';
|
||||
$lang->task->noticeTaskStart = '"总计消耗"和"预计剩余"不能同时为0';
|
||||
$lang->task->noticeLinkStory = "没有可关联的相关{$lang->SRCommon},您可以为当前项目%s,然后%s";
|
||||
$lang->task->noticeSaveRecord = '您有尚未保存的工时记录,请先将其保存。';
|
||||
$lang->task->commentActions = '%s. %s, 由 <strong>%s</strong> 添加备注。';
|
||||
$lang->task->deniedNotice = '当前任务只有%s才可以%s。';
|
||||
$lang->task->noTask = '暂时没有任务。';
|
||||
$lang->task->createDenied = '你不能在该项目添加任务';
|
||||
$lang->task->cannotDeleteParent = '不能删除父任务。';
|
||||
$lang->task->addChildTask = '因该任务已经产生消耗,为保证数据一致性,我们会帮您创建一条同名子任务记录该消耗。';
|
||||
$lang->task->confirmDelete = "您确定要删除这个任务吗?";
|
||||
$lang->task->confirmDeleteEstimate = "您确定要删除这个记录吗?";
|
||||
$lang->task->confirmDeleteLastEstimate = "您确定要删除该条日志吗?删除最后一条工时日志后,该任务状态将调整为未开始。";
|
||||
$lang->task->copyStoryTitle = "同{$lang->SRCommon}";
|
||||
$lang->task->afterSubmit = "添加之后";
|
||||
$lang->task->successSaved = "成功添加,";
|
||||
$lang->task->delayWarning = " <strong class='text-danger'> 延期%s天 </strong>";
|
||||
$lang->task->remindBug = "该任务为Bug转化得到,是否更新Bug:%s ?";
|
||||
$lang->task->remindIssue = "该任务为问题转化得到,是否更新问题:%s ?";
|
||||
$lang->task->confirmChangeExecution = "修改{$lang->executionCommon}会导致相应的所属模块、相关{$lang->SRCommon}和指派人发生变化,确定吗?";
|
||||
$lang->task->confirmFinish = '"预计剩余"为0,确认将任务状态改为"已完成"吗?';
|
||||
$lang->task->confirmRecord = '"剩余"为0,任务将标记为"已完成",您确定吗?';
|
||||
$lang->task->confirmTransfer = '"当前剩余"为0,任务将被转交,您确定吗?';
|
||||
$lang->task->noticeTaskStart = '"总计消耗"和"预计剩余"不能同时为0';
|
||||
$lang->task->noticeLinkStory = "没有可关联的相关{$lang->SRCommon},您可以为当前项目%s,然后%s";
|
||||
$lang->task->noticeSaveRecord = '您有尚未保存的工时记录,请先将其保存。';
|
||||
$lang->task->commentActions = '%s. %s, 由 <strong>%s</strong> 添加备注。';
|
||||
$lang->task->deniedNotice = '当前任务只有%s才可以%s。';
|
||||
$lang->task->noTask = '暂时没有任务。';
|
||||
$lang->task->createDenied = '你不能在该项目添加任务';
|
||||
$lang->task->cannotDeleteParent = '不能删除父任务。';
|
||||
$lang->task->addChildTask = '因该任务已经产生消耗,为保证数据一致性,我们会帮您创建一条同名子任务记录该消耗。';
|
||||
|
||||
$lang->task->error = new stdclass();
|
||||
$lang->task->error->totalNumber = '"总计消耗"必须为数字';
|
||||
|
||||
+75
-4
@@ -719,7 +719,6 @@ class taskModel extends model
|
||||
$task->assignedTo = $childTask->assignedTo;
|
||||
$task->assignedDate = $now;
|
||||
}
|
||||
|
||||
$task->finishedBy = '';
|
||||
$task->finishedDate = '';
|
||||
$task->closedBy = '';
|
||||
@@ -749,6 +748,7 @@ class taskModel extends model
|
||||
if($status == 'doing' and $parentTask->status == 'wait') $action = 'Started';
|
||||
if($status == 'doing' and $parentTask->status == 'pause') $action = 'Restarted';
|
||||
if($status == 'doing' and $parentTask->status != 'wait' and $parentTask->status != 'pause') $action = 'Activated';
|
||||
if($status == 'wait' and $parentTask->status != 'wait') $action = 'Adjusttasktowait';
|
||||
if($action)
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('task', $parentID, $action, '', '', '', false);
|
||||
@@ -833,7 +833,8 @@ class taskModel extends model
|
||||
$currentTask->consumed += (float)$member->consumed;
|
||||
$currentTask->left += (float)$member->left;
|
||||
}
|
||||
if(empty($oldTask->team) and isset($oldTask->consumed)) $currentTask->consumed += (float)$oldTask->consumed;
|
||||
|
||||
if($this->app->rawMethod == 'edit' and empty($oldTask->team) and isset($oldTask->consumed)) $currentTask->consumed += (float)$oldTask->consumed;
|
||||
|
||||
if(!empty($task))
|
||||
{
|
||||
@@ -1236,7 +1237,7 @@ class taskModel extends model
|
||||
return false;
|
||||
}
|
||||
|
||||
if(empty($task->closedReason))
|
||||
if(empty($task->closedReason) and $task->status == 'closed')
|
||||
{
|
||||
if($oldTask->status == 'done') $task->closedReason = 'done';
|
||||
if($oldTask->status == 'cancel') $task->closedReason = 'cancel';
|
||||
@@ -2834,7 +2835,19 @@ class taskModel extends model
|
||||
$data->consumed = $consumed;
|
||||
$data->left = $left;
|
||||
$data->status = ($left == 0 && $consumed != 0) ? 'done' : $task->status;
|
||||
|
||||
if($left == 0 and $consumed != 0)
|
||||
{
|
||||
$data->status = 'done';
|
||||
}
|
||||
elseif($consumed == 0)
|
||||
{
|
||||
$data->status = 'wait';
|
||||
$data->left = $task->left + $estimate->consumed;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data->status = $task->status;
|
||||
}
|
||||
if(!empty($task->team))
|
||||
{
|
||||
$oldConsumed = $task->team[$estimate->account]->consumed;
|
||||
@@ -3734,6 +3747,64 @@ class taskModel extends model
|
||||
->fetchPairs('actor');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build nested list.
|
||||
*
|
||||
* @param objecct $execution
|
||||
* @param object $task
|
||||
* @param bool $isChild
|
||||
* @param bool $showmore
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function buildNestedList($execution, $task, $isChild = false, $showmore = false, $users)
|
||||
{
|
||||
$showmore = $showmore ? 'showmore' : '';
|
||||
$trAttrs = "data-id=$task->id";
|
||||
if(!$isChild)
|
||||
{
|
||||
$path = $execution->grade == 2 ? "$execution->parent,$execution->id,$task->id," : ",$execution->id,$task->id,";
|
||||
$trAttrs .= " data-parent=$execution->id data-nest-parent=$execution->id data-nest-path=$path";
|
||||
if(empty($task->children)) $trAttrs .= " data-nested='false'";
|
||||
$trClass = empty($task->children) ? '' : " has-nest-child";
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = $execution->grade == 2 ? "$execution->parent,$execution->id,$task->parent,$task->id," : ",$execution->id,$task->parent,$task->id,";
|
||||
$trClass = 'is-nest-child no-nest';
|
||||
$trAttrs .= " data-nested='false' data-parent=$task->parent data-nest-parent=$task->parent data-nest-path=$path";
|
||||
}
|
||||
|
||||
$list = "<tr $trAttrs class='$trClass $showmore'>";
|
||||
$list .= '<td>';
|
||||
if($task->parent > 0) $list .= '<span class="label label-badge label-light" title="' . $this->lang->task->children . '">' . $this->lang->task->childrenAB . '</span> ';
|
||||
$list .= html::a(helper::createLink('task', 'view', "id=$task->id"), $task->name, '', "data-app='project'");
|
||||
$list .= '</td>';
|
||||
$list .= '<td>' . zget($users, $task->assignedTo, '') . '</td>';
|
||||
$list .= "<td class='status-{$task->status}'>" . $this->processStatus('task', $task) . '</td>';
|
||||
$list .= '<td></td>';
|
||||
$list .= '<td>' . $task->estStarted . '</td>';
|
||||
$list .= '<td>' . $task->deadline . '</td>';
|
||||
$list .= '<td>' . $task->estimate . $this->lang->execution->workHourUnit . '</td>';
|
||||
$list .= '<td>' . $task->consumed . $this->lang->execution->workHourUnit . '</td>';
|
||||
$list .= '<td>' . $task->left . $this->lang->execution->workHourUnit . '</td>';
|
||||
$list .= '<td></td>';
|
||||
$list .= '<td class="c-actions">';
|
||||
$list .= $this->buildOperateMenu($task, 'browse');
|
||||
$list .= '</td></tr>';
|
||||
|
||||
if(!empty($task->children))
|
||||
{
|
||||
foreach($task->children as $child)
|
||||
{
|
||||
$showmore = (count($task->children) == 50) && ($child == end($task->children));
|
||||
$list .= $this->buildNestedList($execution, $child, true, $showmore, $users);
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build task menu.
|
||||
*
|
||||
|
||||
@@ -1403,10 +1403,33 @@ class testcase extends control
|
||||
$case = $this->testcase->getById($caseID);
|
||||
$libCase = $this->testcase->getById($libcaseID);
|
||||
$version = $case->version + 1;
|
||||
|
||||
$this->dao->delete()->from(TABLE_FILE)->where('objectType')->eq('testcase')->andWhere('objectID')->eq($caseID)->exec();
|
||||
foreach($libCase->files as $fileID => $file)
|
||||
{
|
||||
$fileName = pathinfo($file->pathname, PATHINFO_FILENAME);
|
||||
$datePath = substr($file->pathname, 0, 6);
|
||||
$realPath = $this->app->getAppRoot() . "www/data/upload/{$this->app->company->id}/" . "{$datePath}/" . $fileName;
|
||||
|
||||
$rand = rand();
|
||||
$newFileName = $fileName . 'copy' . $rand;
|
||||
$newFilePath = $this->app->getAppRoot() . "www/data/upload/{$this->app->company->id}/" . "{$datePath}/" . $newFileName;
|
||||
copy($realPath, $newFilePath);
|
||||
|
||||
$newFileName = $file->pathname;
|
||||
$newFileName = str_replace('.', "copy$rand.", $newFileName);
|
||||
|
||||
unset($file->id, $file->realPath, $file->webPath);
|
||||
$file->objectID = $caseID;
|
||||
$file->pathname = $newFileName;
|
||||
$this->dao->insert(TABLE_FILE)->data($file)->exec();
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_CASE)
|
||||
->set('version')->eq($version)
|
||||
->set('fromCaseVersion')->eq($version)
|
||||
->set('precondition')->eq($libCase->precondition)
|
||||
->set('title')->eq($libCase->title)
|
||||
->where('id')->eq($caseID)
|
||||
->exec();
|
||||
|
||||
@@ -1417,6 +1440,7 @@ class testcase extends control
|
||||
$step->version = $version;
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($step)->exec();
|
||||
}
|
||||
|
||||
echo js::locate($this->createLink('testcase', 'view', "caseID=$caseID&version=$version"), 'parent');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
if(isLibCase)
|
||||
{
|
||||
$('#subNavbar [data-id=testcase]').removeClass('active');
|
||||
$('#navbar [data-id=testcase]').removeClass('active');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#subNavbar [data-id=testcase]').addClass('active');
|
||||
$('#navbar [data-id=testcase]').addClass('active');
|
||||
}
|
||||
|
||||
if(config.onlybody != 'yes')$(".runCase").modalTrigger({width:'90%', type:'iframe', afterHide:function(){parent.location.href=parent.location.href;}});
|
||||
if(config.onlybody != 'yes')$(".results").modalTrigger({width:'90%', type:'iframe'});
|
||||
|
||||
|
||||
+22
-12
@@ -285,7 +285,7 @@ class testcaseModel extends model
|
||||
->leftJoin(TABLE_STORY)->alias('t4')->on('t3.story=t4.id')
|
||||
->where('t1.project')->in($executions)
|
||||
->beginIF(!empty($productID))->andWhere('t2.product')->eq((int)$productID)->fi()
|
||||
->beginIF($branch !== 'all')->andWhere('t2.branch')->eq($branch)->fi()
|
||||
->beginIF(!empty($productID) and $branch !== 'all')->andWhere('t2.branch')->eq($branch)->fi()
|
||||
->beginIF($moduleIdList)->andWhere('t2.module')->in($moduleIdList)->fi()
|
||||
->beginIF($browseType == 'wait')->andWhere('t2.status')->eq($browseType)->fi()
|
||||
->beginIF($auto == 'unit')->andWhere('t2.auto')->eq('unit')->fi()
|
||||
@@ -342,7 +342,7 @@ class testcaseModel extends model
|
||||
->where('t1.project')->eq((int)$executionID)
|
||||
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi()
|
||||
->beginIF(!empty($moduleID))->andWhere('t4.path')->like("%,$moduleID,%")->fi()
|
||||
->andWhere('t2.branch')->eq($branchID)
|
||||
->beginIF(!empty($productID))->andWhere('t2.branch')->eq($branchID)->fi()
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->andWhere('t3.version > t2.storyVersion')
|
||||
->andWhere("t3.status")->eq('active')
|
||||
@@ -358,7 +358,7 @@ class testcaseModel extends model
|
||||
->beginIF($browseType != 'all' and $browseType != 'byModule')->andWhere('t2.status')->eq($browseType)->fi()
|
||||
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi()
|
||||
->beginIF(!empty($moduleID))->andWhere('t3.path')->like("%,$moduleID,%")->fi()
|
||||
->andWhere('t2.branch')->eq($branchID)
|
||||
->beginIF(!empty($productID))->andWhere('t2.branch')->eq($branchID)->fi()
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
@@ -520,7 +520,7 @@ class testcaseModel extends model
|
||||
->andWhere('t2.version > t1.storyVersion')
|
||||
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi()
|
||||
->beginIF($this->app->tab == 'project')->andWhere('t3.project')->eq($this->session->project)->fi()
|
||||
->beginIF($branch !== 'all')->andWhere('t1.branch')->eq($branch)->fi()
|
||||
->beginIF($branch !== 'all' and !empty($productID))->andWhere('t1.branch')->eq($branch)->fi()
|
||||
->beginIF($modules)->andWhere('t1.module')->in($modules)->fi()
|
||||
->beginIF($auto != 'unit')->andWhere('t1.auto')->ne('unit')->fi()
|
||||
->beginIF($auto == 'unit')->andWhere('t1.auto')->eq('unit')->fi()
|
||||
@@ -799,15 +799,12 @@ class testcaseModel extends model
|
||||
$this->dao->update(TABLE_CASE)->data($case)->autoCheck()->batchCheck($requiredFields, 'notempty')->checkFlow()->where('id')->eq((int)$caseID)->exec();
|
||||
if(!$this->dao->isError())
|
||||
{
|
||||
$isLibCase = ($oldCase->lib and empty($oldCase->product));
|
||||
$titleChanged = ($case->title != $oldCase->title);
|
||||
if($isLibCase and $titleChanged) $this->dao->update(TABLE_CASE)->set('`title`')->eq($case->title)->where('`fromCaseID`')->eq($caseID)->exec();
|
||||
|
||||
$this->updateCase2Project($oldCase, $case, $caseID);
|
||||
|
||||
if($stepChanged)
|
||||
{
|
||||
$parentStepID = 0;
|
||||
$isLibCase = ($oldCase->lib and empty($oldCase->product));
|
||||
if($isLibCase)
|
||||
{
|
||||
$fromcaseVersion = $this->dao->select('fromCaseVersion')->from(TABLE_CASE)->where('fromCaseID')->eq($caseID)->fetch('fromCaseVersion');
|
||||
@@ -1103,6 +1100,11 @@ class testcaseModel extends model
|
||||
foreach($cases as $caseID => $case)
|
||||
{
|
||||
$oldCase = $this->getByID($caseID);
|
||||
|
||||
$caseChanged = false;
|
||||
if($oldCase->title != $case->title) $caseChanged = true;
|
||||
if($oldCase->precondition != $case->precondition) $caseChanged = true;
|
||||
|
||||
$this->dao->update(TABLE_CASE)->data($case)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->testcase->edit->requiredFields, 'notempty')
|
||||
@@ -1112,11 +1114,7 @@ class testcaseModel extends model
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$isLibCase = ($oldCase->lib and empty($oldCase->product));
|
||||
$titleChanged = ($case->title != $oldCase->title);
|
||||
$case->product = $oldCase->product;
|
||||
if($isLibCase and $titleChanged) $this->dao->update(TABLE_CASE)->set('`title`')->eq($case->title)->where('`fromCaseID`')->eq($caseID)->exec();
|
||||
|
||||
$this->updateCase2Project($oldCase, $case, $caseID);
|
||||
|
||||
$this->executeHooks($caseID);
|
||||
@@ -1138,6 +1136,14 @@ class testcaseModel extends model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$isLibCase = ($oldCase->lib and empty($oldCase->product));
|
||||
if($isLibCase and $caseChanged)
|
||||
{
|
||||
$fromcaseVersion = $this->dao->select('fromCaseVersion')->from(TABLE_CASE)->where('fromCaseID')->eq($caseID)->fetch('fromCaseVersion');
|
||||
$fromcaseVersion += 1;
|
||||
$this->dao->update(TABLE_CASE)->set('`fromCaseVersion`')->eq($fromcaseVersion)->where('`fromCaseID`')->eq($caseID)->exec();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2357,6 +2363,10 @@ class testcaseModel extends model
|
||||
|
||||
if(!$this->forceNotReview() and $stepChanged) $status = 'wait';
|
||||
|
||||
if(!empty($_POST['title']) and $case->title != $this->post->title) $stepChanged = true;
|
||||
if(!empty($_POST['precondition']) and $case->precondition != $this->post->precondition) $stepChanged = true;
|
||||
if(!empty($_POST['labels'][0])) $stepChanged = true;
|
||||
|
||||
return array($stepChanged, $status);
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ js::set('suiteID', $suiteID);
|
||||
<h4 class="modal-title"><?php echo $lang->testcase->importToLib;?></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method='post' class='form-ajax' action='<?php echo $this->createLink('testcase', 'importToLib');?>'>
|
||||
<form method='post' class='form-ajax not-watch' action='<?php echo $this->createLink('testcase', 'importToLib');?>'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<td class='select-lib'><?php echo $lang->testcase->selectLibAB;?></td>
|
||||
|
||||
@@ -366,14 +366,6 @@
|
||||
<?php
|
||||
js::set('fullscreen', $lang->fullscreen);
|
||||
js::set('retrack', $lang->retrack);
|
||||
js::set('isLibCase', $isLibCase);
|
||||
?>
|
||||
<?php if(!$isLibCase):?>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
$('#subNavbar [data-id=testcase]').addClass('active');
|
||||
$('#navbar [data-id=testcase]').addClass('active');
|
||||
})
|
||||
</script>
|
||||
<?php endif;?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -517,6 +517,7 @@ class tree extends control
|
||||
{
|
||||
$changeFunc = '';
|
||||
if($viewType == 'bug' or $viewType == 'case') $changeFunc = "onchange='loadModuleRelated()'";
|
||||
if($viewType == 'task') $changeFunc = "onchange='setStories(this.value, $rootID)'";
|
||||
$field = $fieldID ? "modules[$fieldID]" : 'module';
|
||||
|
||||
$currentModule = $this->tree->getById($currentModuleID);
|
||||
@@ -538,7 +539,8 @@ class tree extends control
|
||||
if($returnType == 'mhtml')
|
||||
{
|
||||
$changeFunc = '';
|
||||
if($viewType == 'task' or $viewType == 'bug' or $viewType == 'case') $changeFunc = "onchange='loadModuleRelated()'";
|
||||
if($viewType == 'bug' or $viewType == 'case') $changeFunc = "onchange='loadModuleRelated()'";
|
||||
if($viewType == 'task') $changeFunc = "onchange='setStories(this.value, $rootID)'";
|
||||
$field = $fieldID ? "modules[$fieldID]" : 'module';
|
||||
$output = html::select("$field", $optionMenu, '', "class='input' $changeFunc");
|
||||
die($output);
|
||||
|
||||
@@ -20,6 +20,7 @@ $config->upgrade->maxVersion['max3_1_beta2'] = '17_0_beta2';
|
||||
$config->upgrade->maxVersion['max3_1'] = '17_0';
|
||||
$config->upgrade->maxVersion['max3_2'] = '17_1';
|
||||
$config->upgrade->maxVersion['max3_3'] = '17_2';
|
||||
$config->upgrade->maxVersion['max3_4'] = '17_3';
|
||||
|
||||
$config->upgrade->bizVersion = array();
|
||||
$config->upgrade->bizVersion['biz1_0'] = '9_5_1';
|
||||
@@ -78,6 +79,7 @@ $config->upgrade->bizVersion['biz7_0_beta2'] = '17_0_beta2';
|
||||
$config->upgrade->bizVersion['biz7_0'] = '17_0';
|
||||
$config->upgrade->bizVersion['biz7_1'] = '17_1';
|
||||
$config->upgrade->bizVersion['biz7_2'] = '17_2';
|
||||
$config->upgrade->bizVersion['biz7_3'] = '17_3';
|
||||
|
||||
$config->upgrade->proVersion = array();
|
||||
$config->upgrade->proVersion['pro1_0'] = '3_1';
|
||||
|
||||
@@ -161,6 +161,7 @@ $lang->upgrade->fromVersions['17_0_beta2'] = '17.0.beta2';
|
||||
$lang->upgrade->fromVersions['17_0'] = '17.0';
|
||||
$lang->upgrade->fromVersions['17_1'] = '17.1';
|
||||
$lang->upgrade->fromVersions['17_2'] = '17.2';
|
||||
$lang->upgrade->fromVersions['17_3'] = '17.3';
|
||||
|
||||
global $config;
|
||||
/* Lite. */
|
||||
@@ -326,6 +327,7 @@ $lang->upgrade->fromVersions['biz7_0_beta2'] = 'Biz7.0.beta2';
|
||||
$lang->upgrade->fromVersions['biz7_0'] = 'Biz7.0';
|
||||
$lang->upgrade->fromVersions['biz7_1'] = 'Biz7.1';
|
||||
$lang->upgrade->fromVersions['biz7_2'] = 'Biz7.2';
|
||||
$lang->upgrade->fromVersions['biz7_3'] = 'Biz7.3';
|
||||
|
||||
/* Max. */
|
||||
$lang->upgrade->fromVersions['max2_0_beta4'] = 'Max2.0.beta4';
|
||||
@@ -347,3 +349,4 @@ $lang->upgrade->fromVersions['max3_1_beta1'] = 'Max3.1.beta1';
|
||||
$lang->upgrade->fromVersions['max3_1_beta2'] = 'Max3.1.beta2';
|
||||
$lang->upgrade->fromVersions['max3_1'] = 'Max3.1';
|
||||
$lang->upgrade->fromVersions['max3_2'] = 'Max3.2';
|
||||
$lang->upgrade->fromVersions['max3_3'] = 'Max3.3';
|
||||
|
||||
@@ -692,6 +692,9 @@ class upgradeModel extends model
|
||||
case 'max3_0':
|
||||
$this->moveResult2Node();
|
||||
break;
|
||||
case 'max3_3':
|
||||
$this->addReviewIssusApprovalData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,6 +972,8 @@ class upgradeModel extends model
|
||||
$confirmContent .= file_get_contents($this->getUpgradeFile('17.1'));
|
||||
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan5.6.sql';
|
||||
$confirmContent .= file_get_contents($xuanxuanSql);
|
||||
case '17_2':
|
||||
$confirmContent .= file_get_contents($this->getUpgradeFile('17.2'));
|
||||
}
|
||||
|
||||
return $confirmContent;
|
||||
@@ -6509,6 +6514,46 @@ class upgradeModel extends model
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add review issue approval data.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function addReviewIssusApprovalData()
|
||||
{
|
||||
$reviewIssues = $this->dao->select('id,review,type')->from(TABLE_REVIEWISSUE)
|
||||
->where('type')->eq('review')
|
||||
->andWhere('approval')->eq(0)
|
||||
->andWhere('deleted')->eq('0')
|
||||
->fetchAll('review');
|
||||
|
||||
if(empty($reviewIssues)) return false;
|
||||
|
||||
$reviewIds = array_unique(array_column($reviewIssues, 'review'));
|
||||
|
||||
$approvalsPairs = $this->dao->select('objectID, max(id) as approval')->from(TABLE_APPROVAL)
|
||||
->where('objectID')->in($reviewIds)
|
||||
->andWhere('objectType')->eq('review')
|
||||
->andWhere('result')->eq('fail')
|
||||
->andWhere('deleted')->eq(0)
|
||||
->groupBy('objectID')
|
||||
->fetchAll('objectID');
|
||||
|
||||
/* Add approval data. */
|
||||
foreach($reviewIssues as $reviewIssue)
|
||||
{
|
||||
if(!isset($approvalsPairs[$reviewIssue->review]->approval)) continue;
|
||||
$this->dao->update(TABLE_REVIEWISSUE)
|
||||
->set('approval')->eq($approvalsPairs[$reviewIssue->review]->approval)
|
||||
->where('review')->eq($reviewIssue->review)
|
||||
->andWhere('type')->eq('review')
|
||||
->andWhere('approval')->eq(0)
|
||||
->andWhere('deleted')->eq('0')
|
||||
->exec();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Xuan: Add `index` column to all message partition tables.
|
||||
*
|
||||
|
||||
@@ -10,3 +10,5 @@ body {background: #1183fb linear-gradient(-90deg, #0a48d1 0%, #1183fb 100%); bac
|
||||
#forgetForm .form-actions {padding-bottom: 20px;}
|
||||
.required:after {top: 32px; right: -15px;}
|
||||
.resetBox {float: right; font-size: 8px; margin-right: 2px;}
|
||||
#forgetForm .form-actions > .btn-wide {min-width: 45%;}
|
||||
#forgetForm .form-actions > a.btn-wide {margin-right: 0px;}
|
||||
|
||||
@@ -11,3 +11,5 @@ body {background: #1183fb linear-gradient(-90deg, #0a48d1 0%, #1183fb 100%); bac
|
||||
.required:after {top: 32px; right: -15px;}
|
||||
#resetPanel .form-group .input-group {width: 100%}
|
||||
#resetPanel .form-group .input-group.required:after {top: 6px;}
|
||||
#resetPanel .form-actions > .btn-wide {min-width: 45%;}
|
||||
#resetPanel .form-actions > a.btn-wide {margin-right: 0px;}
|
||||
|
||||
@@ -207,14 +207,22 @@ class xuanxuanIm extends imModel
|
||||
foreach($userMessages as $message)
|
||||
{
|
||||
/* Group by $message->content->content->objectType, ...->parentType, ...->action, ...->actor */
|
||||
$contentData = json_decode($message->content);
|
||||
$contentData = json_decode($contentData->content);
|
||||
$contentDataOuter = json_decode($message->content);
|
||||
$contentData = json_decode($contentDataOuter->content);
|
||||
if(isset($contentData->contentType) && $contentData->contentType == 'text')
|
||||
{
|
||||
$messageGroups[$contentData->contentType][] = $message;
|
||||
continue;
|
||||
}
|
||||
$messageGroups["$contentData->objectType-$contentData->parentType-$contentData->action-$contentData->actor"][] = $message;
|
||||
if ($contentData->objectType == 'story' && $contentData->action == 'reviewed')
|
||||
{
|
||||
$extra = explode(',', $contentDataOuter->extra)[0];
|
||||
$messageGroups["$contentData->objectType-$contentData->parentType-$contentData->action-$contentData->actor-$extra"][] = $message;
|
||||
}
|
||||
else
|
||||
{
|
||||
$messageGroups["$contentData->objectType-$contentData->parentType-$contentData->action-$contentData->actor"][] = $message;
|
||||
}
|
||||
}
|
||||
foreach($messageGroups as $groupKey => $messages)
|
||||
{
|
||||
@@ -225,25 +233,24 @@ class xuanxuanIm extends imModel
|
||||
$notificationContent = json_decode($notification->content);
|
||||
$notificationInnerContent = json_decode($notificationContent->content);
|
||||
|
||||
/* Inner content: array($parentID => array($content1, $content2)) */
|
||||
$objectGroups = array($notificationInnerContent->parent => array($notificationInnerContent));
|
||||
/* Inner content: array($id => array($content1, $content2)) */
|
||||
$objectGroups = array($notificationInnerContent->id => array($notificationInnerContent));
|
||||
foreach($messages as $message)
|
||||
{
|
||||
$messageContent = json_decode($message->content);
|
||||
$messageInnerContent = json_decode($messageContent->content);
|
||||
$objectGroups[$messageInnerContent->parent][] = $messageInnerContent;
|
||||
$objectGroups[$messageInnerContent->id][] = $messageInnerContent;
|
||||
}
|
||||
$objectTotal = 0;
|
||||
foreach($objectGroups as $parent => $objectGroup)
|
||||
foreach($objectGroups as $id => $objectGroup)
|
||||
{
|
||||
$object = current($objectGroup);
|
||||
$object->count = count($objectGroup);
|
||||
$object->url = $object->parentURL;
|
||||
unset($object->title);
|
||||
|
||||
$objectGroups[$parent] = $object;
|
||||
$objectTotal += $object->count;
|
||||
$objectGroups[$id] = $object;
|
||||
}
|
||||
$objectTotal = count($objectGroups);
|
||||
$notificationContent->content = json_encode(array_values($objectGroups));
|
||||
/* Hack alert: title count replacement currently assumes that default count is 1. */
|
||||
$notification->title = substr_replace($notification->title, "$objectTotal", strrpos($notification->title, '1'), 1);
|
||||
|
||||
@@ -3,7 +3,10 @@ $lang->message->typeList['xuanxuan'] = 'Chat';
|
||||
|
||||
$lang->message->sender = 'ZenTao';
|
||||
|
||||
$lang->message->notifyTitle = '%s %s%d %s';
|
||||
$lang->message->notifyTitle = '%s %s%d %s';
|
||||
$lang->message->notifyPassTitle = '%s passed %d stories';
|
||||
$lang->message->notifyClarifyTitle = '%s clarify %d stories';
|
||||
$lang->message->notifyRejectTitle = '%s reject %d stories';
|
||||
|
||||
$lang->message->mr = new stdClass();
|
||||
$lang->message->mr->logTitle = 'Build log';
|
||||
|
||||
@@ -3,7 +3,10 @@ $lang->message->typeList['xuanxuan'] = 'Chat';
|
||||
|
||||
$lang->message->sender = 'ZenTao';
|
||||
|
||||
$lang->message->notifyTitle = '%s %s%d %s';
|
||||
$lang->message->notifyTitle = '%s %s%d %s';
|
||||
$lang->message->notifyPassTitle = '%s passed %d stories';
|
||||
$lang->message->notifyClarifyTitle = '%s clarify %d stories';
|
||||
$lang->message->notifyRejectTitle = '%s reject %d stories';
|
||||
|
||||
$lang->message->mr = new stdClass();
|
||||
$lang->message->mr->logTitle = 'Build log';
|
||||
|
||||
@@ -3,7 +3,10 @@ $lang->message->typeList['xuanxuan'] = 'Chat';
|
||||
|
||||
$lang->message->sender = 'ZenTao';
|
||||
|
||||
$lang->message->notifyTitle = '%s %s%d %s';
|
||||
$lang->message->notifyTitle = '%s %s%d %s';
|
||||
$lang->message->notifyPassTitle = '%s passed %d stories';
|
||||
$lang->message->notifyClarifyTitle = '%s clarify %d stories';
|
||||
$lang->message->notifyRejectTitle = '%s reject %d stories';
|
||||
|
||||
$lang->message->mr = new stdClass();
|
||||
$lang->message->mr->logTitle = 'Build log';
|
||||
|
||||
@@ -3,7 +3,10 @@ $lang->message->typeList['xuanxuan'] = '聊天';
|
||||
|
||||
$lang->message->sender = '禅道项目管理';
|
||||
|
||||
$lang->message->notifyTitle = '%s %s%d个%s';
|
||||
$lang->message->notifyTitle = '%s %s%d个%s';
|
||||
$lang->message->notifyPassTitle = '%s 通过了%d个研发需求';
|
||||
$lang->message->notifyClarifyTitle = '%s 驳回了%d个研发需求';
|
||||
$lang->message->notifyRejectTitle = '%s 拒绝了%d个研发需求';
|
||||
|
||||
$lang->message->mr = new stdClass();
|
||||
$lang->message->mr->logTitle = '构建日志';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
class xuanxuanMessage extends messageModel
|
||||
{
|
||||
public function send($objectType, $objectID, $actionType, $actionID, $actor = '')
|
||||
public function send($objectType, $objectID, $actionType, $actionID, $actor = '', $extra = '')
|
||||
{
|
||||
$messageSetting = $this->config->message->setting;
|
||||
if(is_string($messageSetting)) $messageSetting = json_decode($messageSetting, true);
|
||||
@@ -44,6 +44,22 @@ class xuanxuanMessage extends messageModel
|
||||
->fetch();
|
||||
$field = $this->config->action->objectNameFields[$objectType];
|
||||
$title = $objectType == 'mr' ? '' : sprintf($this->lang->message->notifyTitle, $this->app->user->realname, $this->lang->action->label->$actionType, 1, $this->lang->action->objectTypes[$objectType]);
|
||||
if ($objectType == 'story' && $actionType == 'reviewed' && !empty($extra))
|
||||
{
|
||||
$notifyType = strtolower(explode(',', $extra)[0]);
|
||||
if ($notifyType == 'pass')
|
||||
{
|
||||
$title = $objectType == 'mr' ? '' : sprintf($this->lang->message->notifyPassTitle, $this->app->user->realname, 1);
|
||||
}
|
||||
else if($notifyType == 'clarify')
|
||||
{
|
||||
$title = $objectType == 'mr' ? '' : sprintf($this->lang->message->notifyClarifyTitle, $this->app->user->realname, 1);
|
||||
}
|
||||
else if($notifyType == 'reject')
|
||||
{
|
||||
$title = $objectType == 'mr' ? '' : sprintf($this->lang->message->notifyRejectTitle, $this->app->user->realname, 1);
|
||||
}
|
||||
}
|
||||
|
||||
$server = $this->loadModel('im')->getServer('zentao');
|
||||
$onlybody = isset($_GET['onlybody']) ? $_GET['onlybody'] : '';
|
||||
@@ -52,7 +68,7 @@ class xuanxuanMessage extends messageModel
|
||||
$url = $server . helper::createLink($objectType == 'kanbancard' ? 'kanban' : $objectType, 'view', "id=$dataID", 'html');
|
||||
|
||||
$target = '';
|
||||
if(!empty($object->assignedTo)) $target .= $object->assignedTo;
|
||||
if(!empty($object->assignedTo)) $target .= $object->assignedTo == 'closed' ? $object->openedBy : $object->assignedTo;
|
||||
if(!empty($object->mailto)) $target .= ",{$object->mailto}";
|
||||
if(($objectType == 'mr' or $objectType == 'kanbancard') and !empty($object->createdBy)) $target .= ",{$object->createdBy}";
|
||||
$target = trim($target, ',');
|
||||
@@ -130,6 +146,7 @@ class xuanxuanMessage extends messageModel
|
||||
$contentData->actions = array();
|
||||
$contentData->url = "xxc:openInApp/zentao-integrated/" . urlencode($url);
|
||||
}
|
||||
$contentData->extra = $extra;
|
||||
|
||||
$content = json_encode($contentData);
|
||||
$avatarUrl = $server . $this->app->getWebRoot() . 'favicon.ico';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
<?php
|
||||
$this->loadExtension('xuanxuan')->send($objectType, $objectID, $actionType, $actionID, $actor);
|
||||
$this->loadExtension('xuanxuan')->send($objectType, $objectID, $actionType, $actionID, $actor, $extra);
|
||||
|
||||
Reference in New Issue
Block a user