diff --git a/.gitignore b/.gitignore
index 5529453cfe..1a682f8be0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,7 @@ tmp/cache/*
tmp/extension/*
.gitkeep
.bak
+.idea
+.gitignore
+_log
+framework/
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000..94a25f7f4c
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/helper.class.php b/framework/helper.class.php
index 165ba1bab1..dc33d2ffa0 100644
--- a/framework/helper.class.php
+++ b/framework/helper.class.php
@@ -141,3 +141,11 @@ function formatTime($time, $format = '')
if($format) return date($format, strtotime($time));
return trim($time);
}
+
+function b($val)
+{
+ echo '
+ |
+
+ id", sprintf('%03d', $child->id))) printf('%03d', $child->id);?>
+ |
+ task->priList, $child->pri, $child->pri)?>'>pri == '0' ? '' : zget($lang->task->priList, $child->pri, $child->pri);?> |
+
+ product][$child->branch])) echo "" . $branchGroups[$child->product][$child->branch] . '';?>
+ module) echo "" . $modulePairs[$child->module] . '';?>
+ id", $child->name, null, "style='color: $child->color'")) echo $child->name;
+ if($child->fromBug) echo html::a($this->createLink('bug', 'view', "id=$child->fromBug"), "[BUG#$child->fromBug]", '_blank', "class='bug'");
+ ?>
+ |
+
+ storyStatus == 'active' and $child->latestStoryVersion > $child->storyVersion);
+ if($storyChanged)
+ {
+ echo "({$lang->story->changed} ";
+ echo html::a($this->createLink('task', 'confirmStoryChange', "taskID=$child->id"), $lang->confirm, 'hiddenwin');
+ echo ")";
+ }
+ else
+ {
+ echo $lang->task->statusList[$child->status];
+ }
+ ?>
+ |
+ deadline, 0, 4) > 0) echo substr($child->deadline, 5, 6);?> |
+
+ cookie->windowWidth > $this->config->wideSize):?>
+ openedDate, 5, 6);?> |
+
+
+ >assignedTo == 'closed' ? 'Closed' : zget($users, $child->assignedTo, $child->assignedTo);?> |
+ finishedBy, $child->finishedBy);?> |
+
+ cookie->windowWidth > $this->config->wideSize):?>
+ finishedDate, 5, 6);?> |
+
+
+ estimate;?> |
+ consumed;?> |
+ left;?> |
+ progess?>% |
+ type == 'sprint')
+ {
+ echo '';
+ if($child->storyID)
+ {
+ if(!common::printLink('story', 'view', "storyid=$child->storyID", $child->storyTitle)) print $child->storyTitle;
+ }
+ echo ' | ';
+ }
+ ?>
+
+ project&taskID=$child->id", $child, 'list', '', '', 'iframe', true);
+ common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
+
+ common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true);
+ if($browseType == 'needconfirm')
+ {
+ $lang->task->confirmStoryChange = $lang->confirm;
+ common::printIcon('task', 'confirmStoryChange', "taskid=$child->id", '', 'list', '', 'hiddenwin');
+ }
+ common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
+ common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
+ common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list');
+ common::printIcon('task', 'batchCreate', "", $child, 'list','plus','','','','',$lang->task->children);
+ ?>
+ |
+
+
+
diff --git a/module/task/config.php b/module/task/config.php
index b5bbbc3481..ca4fc78573 100644
--- a/module/task/config.php
+++ b/module/task/config.php
@@ -183,5 +183,5 @@ $config->task->datatable->fieldList['story']['required'] = 'no';
$config->task->datatable->fieldList['actions']['title'] = 'actions';
$config->task->datatable->fieldList['actions']['fixed'] = 'right';
-$config->task->datatable->fieldList['actions']['width'] = '140';
+$config->task->datatable->fieldList['actions']['width'] = '180';
$config->task->datatable->fieldList['actions']['required'] = 'yes';
diff --git a/module/task/control.php b/module/task/control.php
index 4beb48389d..002e5c1db6 100644
--- a/module/task/control.php
+++ b/module/task/control.php
@@ -169,12 +169,15 @@ class task extends control
/**
* Batch create task.
*
- * @param int $projectID
- * @param int $storyID
+ * @param int $projectID
+ * @param int $storyID
+ * @param int $iframe
+ * @param int $taskID
+ *
* @access public
- * @return void
+ * @return mixed
*/
- public function batchCreate($projectID = 0, $storyID = 0, $iframe = 0)
+ public function batchCreate($projectID = 0, $storyID = 0, $iframe = 0, $taskID = 0)
{
$project = $this->project->getById($projectID);
$taskLink = $this->createLink('project', 'browse', "projectID=$projectID&tab=task");
@@ -213,6 +216,7 @@ class task extends control
$this->view->project = $project;
$this->view->stories = $stories;
$this->view->modules = $modules;
+ $this->view->parent = $taskID;
$this->view->storyID = $storyID;
$this->view->story = $this->story->getByID($storyID);
$this->view->storyTasks = $this->task->getStoryTaskCounts(array_keys($stories), $projectID);
@@ -426,10 +430,20 @@ class task extends control
die(js::locate($this->createLink('task', 'view', "taskID=$taskID"), 'parent'));
}
+ $task = $this->task->getByID($taskID);
+
+ $members = $this->project->getTeamMemberPairs($projectID, 'nodeleted');
+ /* Compute next assignedTo. */
+ if(!empty($task->team))
+ {
+ $task->assignedTo = $this->task->getNextUser(array_keys($task->team), $task->assignedTo);
+ $members = $this->task->getMemberPairs($task);
+ }
+
$this->view->title = $this->view->project->name . $this->lang->colon . $this->lang->task->assign;
$this->view->position[] = $this->lang->task->assign;
-
- $this->view->users = $this->project->getTeamMemberPairs($projectID, 'nodeleted');
+ $this->view->task = $task;
+ $this->view->users = $members;
$this->display();
}
@@ -518,6 +532,8 @@ class task extends control
$task->storyFiles = $this->loadModel('file')->getByObject('story', $task->story);
}
+ if($task->team) $this->lang->task->assign = $this->lang->task->transmit;
+
/* Update action. */
if($task->assignedTo == $this->app->user->account) $this->loadModel('action')->read('task', $taskID);
diff --git a/module/task/js/common.js b/module/task/js/common.js
index f6b1f07a1c..140db4051e 100644
--- a/module/task/js/common.js
+++ b/module/task/js/common.js
@@ -14,3 +14,46 @@ function checkLeft()
}
}
}
+
+$('.btn-move-up, .btn-move-down').click(function()
+{
+ var $this = $(this);
+ if($this.hasClass('btn-move-up'))
+ {
+ $(this).parents('tr').prev().before($(this).parents('tr'));
+ }
+ else
+ {
+ $this.parents('tr').next().after($(this).parents('tr'));
+ }
+ $('.btn-move-up, .btn-move-down').removeClass('disabled').removeAttr('disabled');
+
+ adjustSortBtn();
+});
+function adjustSortBtn()
+{
+ $('.btn-move-up:first').addClass('disabled').attr('disabled', 'disabled');
+ $('.btn-move-down:last').addClass('disabled').attr('disabled', 'disabled');
+}
+
+$('#modalTeam .btn').click(function()
+{
+ var team = '';
+ var time = 0;
+ $('[name*=team]').each(function()
+ {
+ if($(this).find('option:selected').text() != '')
+ {
+ team += ' ' + $(this).find('option:selected').text();
+ }
+
+ estimate = parseFloat($(this).parents('td').next('td').find('[name*=teamEstimate]').val());
+ if(!isNaN(estimate))
+ {
+ time += estimate;
+ }
+
+ $('#teamMember').val(team);
+ $('#estimate').val(time);
+ })
+})
diff --git a/module/task/js/create.js b/module/task/js/create.js
index e50bb46e83..bdb27f8b2f 100644
--- a/module/task/js/create.js
+++ b/module/task/js/create.js
@@ -202,3 +202,26 @@ $(document).ready(function()
return false;
});
});
+
+/* show team menu. */
+$('[name^=multiple]').change(function()
+{
+ if($(this).prop('checked'))
+ {
+ $('#assignedTo, #assignedTo_chosen').addClass('hidden');
+ $('.team-group').removeClass('hidden');
+ $('#estimate').attr('readonly', true);
+ }
+ else
+ {
+ $('#assignedTo, #assignedTo_chosen').removeClass('hidden');
+ $('.team-group').addClass('hidden');
+ $('#estimate').attr('readonly', false);
+ }
+});
+
+$(".btn[data-toggle='modalTeam']").click(function()
+{
+ $('#modalTeam').modal('show');
+ adjustSortBtn();
+});
\ No newline at end of file
diff --git a/module/task/js/edit.js b/module/task/js/edit.js
index 6ed08f4209..401c03d80e 100644
--- a/module/task/js/edit.js
+++ b/module/task/js/edit.js
@@ -67,3 +67,25 @@ function loadProjectMembers(projectID)
/* empty function. */
function setPreview(){}
+$(".btn[data-toggle='modalTeam']").click(function()
+{
+ $('#modalTeam').modal('show')
+ adjustSortBtn();
+});
+
+$(document).ready(function()
+{
+ /* show team menu. */
+ $('[name=multiple]').change(function()
+ {
+ var checked = $(this).prop('checked');
+ if(checked)
+ {
+ $('#teamTr').removeClass('hidden');
+ }
+ else
+ {
+ $('#teamTr').addClass('hidden');
+ }
+ });
+});
\ No newline at end of file
diff --git a/module/task/lang/en.php b/module/task/lang/en.php
index 94cbe81964..c863c97ed8 100644
--- a/module/task/lang/en.php
+++ b/module/task/lang/en.php
@@ -95,6 +95,15 @@ $lang->task->deleteEstimate = 'Delete Man-Hour';
$lang->task->colorTag = 'Color Tag';
$lang->task->files = 'Files';
$lang->task->hasConsumed = 'Consumed';
+$lang->task->multiple = 'Multiple Tasks';
+$lang->task->multipleAB = 'Multiple';
+$lang->task->team = 'Team';
+$lang->task->transmit = 'Transfer';
+$lang->task->transmitTo = 'Transfer To';
+$lang->task->children = 'Child';
+$lang->task->childrenAB = 'Child';
+$lang->task->parent = 'Parent Task';
+$lang->task->unfinished = 'Unfinished';
$lang->task->ditto = 'Ditto';
$lang->task->dittoNotice = "This Task does not belong to the Project as the previous one does!";
diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php
index 60e5fd64a1..54e7d352d0 100644
--- a/module/task/lang/zh-cn.php
+++ b/module/task/lang/zh-cn.php
@@ -39,62 +39,71 @@ $lang->task->progess = '进度';
$lang->task->progessTips = '已消耗/(已消耗+剩余)';
$lang->task->copy = '复制任务';
-$lang->task->common = '任务';
-$lang->task->id = '编号';
-$lang->task->project = '所属' . $lang->projectCommon;
-$lang->task->module = '所属模块';
-$lang->task->moduleAB = '模块';
-$lang->task->story = '相关需求';
-$lang->task->storySpec = '需求描述';
-$lang->task->storyVerify = '验收标准';
-$lang->task->name = '任务名称';
-$lang->task->type = '任务类型';
-$lang->task->pri = '优先级';
-$lang->task->mailto = '抄送给';
-$lang->task->estimate = '最初预计';
-$lang->task->estimateAB = '预';
-$lang->task->left = '预计剩余';
-$lang->task->leftAB = '剩';
-$lang->task->consumed = '总消耗';
-$lang->task->consumedAB = '消耗';
-$lang->task->hour = '小时';
-$lang->task->consumedThisTime = '工时';
-$lang->task->leftThisTime = '剩余';
-$lang->task->datePlan = '日程规划';
-$lang->task->estStarted = '预计开始';
-$lang->task->realStarted = '实际开始';
-$lang->task->date = '日期';
-$lang->task->deadline = '截止日期';
-$lang->task->deadlineAB = '截止';
-$lang->task->status = '任务状态';
-$lang->task->desc = '任务描述';
-$lang->task->assign = '指派';
-$lang->task->assignTo = $lang->task->assign;
-$lang->task->batchAssignTo = '批量指派';
-$lang->task->assignedTo = '指派给';
-$lang->task->assignedToAB = '指派给';
-$lang->task->assignedDate = '指派日期';
-$lang->task->openedBy = '由谁创建';
-$lang->task->openedDate = '创建日期';
-$lang->task->openedDateAB = '创建';
-$lang->task->finishedBy = '由谁完成';
-$lang->task->finishedByAB = '完成者';
-$lang->task->finishedDate = '完成时间';
-$lang->task->finishedDateAB = '完成';
-$lang->task->canceledBy = '由谁取消';
-$lang->task->canceledDate = '取消时间';
-$lang->task->closedBy = '由谁关闭';
-$lang->task->closedDate = '关闭时间';
-$lang->task->closedReason = '关闭原因';
-$lang->task->lastEditedBy = '最后修改';
-$lang->task->lastEditedDate = '最后修改日期';
-$lang->task->lastEdited = '最后编辑';
-$lang->task->recordEstimate = '工时';
-$lang->task->editEstimate = '编辑工时';
-$lang->task->deleteEstimate = '删除工时';
-$lang->task->colorTag = '颜色标签';
-$lang->task->files = '附件';
-$lang->task->hasConsumed = '已消耗';
+$lang->task->common = '任务';
+$lang->task->id = '编号';
+$lang->task->project = '所属' . $lang->projectCommon;
+$lang->task->module = '所属模块';
+$lang->task->moduleAB = '模块';
+$lang->task->story = '相关需求';
+$lang->task->storySpec = '需求描述';
+$lang->task->storyVerify = '验收标准';
+$lang->task->name = '任务名称';
+$lang->task->type = '任务类型';
+$lang->task->pri = '优先级';
+$lang->task->mailto = '抄送给';
+$lang->task->estimate = '最初预计';
+$lang->task->estimateAB = '预';
+$lang->task->left = '预计剩余';
+$lang->task->leftAB = '剩';
+$lang->task->consumed = '总消耗';
+$lang->task->consumedAB = '消耗';
+$lang->task->hour = '小时';
+$lang->task->consumedThisTime = '工时';
+$lang->task->leftThisTime = '剩余';
+$lang->task->datePlan = '日程规划';
+$lang->task->estStarted = '预计开始';
+$lang->task->realStarted = '实际开始';
+$lang->task->date = '日期';
+$lang->task->deadline = '截止日期';
+$lang->task->deadlineAB = '截止';
+$lang->task->status = '任务状态';
+$lang->task->desc = '任务描述';
+$lang->task->assign = '指派';
+$lang->task->assignTo = $lang->task->assign;
+$lang->task->batchAssignTo = '批量指派';
+$lang->task->assignedTo = '指派给';
+$lang->task->assignedToAB = '指派给';
+$lang->task->assignedDate = '指派日期';
+$lang->task->openedBy = '由谁创建';
+$lang->task->openedDate = '创建日期';
+$lang->task->openedDateAB = '创建';
+$lang->task->finishedBy = '由谁完成';
+$lang->task->finishedByAB = '完成者';
+$lang->task->finishedDate = '完成时间';
+$lang->task->finishedDateAB = '完成';
+$lang->task->canceledBy = '由谁取消';
+$lang->task->canceledDate = '取消时间';
+$lang->task->closedBy = '由谁关闭';
+$lang->task->closedDate = '关闭时间';
+$lang->task->closedReason = '关闭原因';
+$lang->task->lastEditedBy = '最后修改';
+$lang->task->lastEditedDate = '最后修改日期';
+$lang->task->lastEdited = '最后编辑';
+$lang->task->recordEstimate = '工时';
+$lang->task->editEstimate = '编辑工时';
+$lang->task->deleteEstimate = '删除工时';
+$lang->task->colorTag = '颜色标签';
+$lang->task->files = '附件';
+$lang->task->hasConsumed = '已消耗';
+$lang->task->multiple = '多人任务';
+$lang->task->multipleAB = '多人';
+$lang->task->team = '团队';
+$lang->task->transmit = '转交';
+$lang->task->transmitTo = '转交给';
+$lang->task->children = '子任务';
+$lang->task->childrenAB = '子';
+$lang->task->parent = '父任务';
+$lang->task->unfinished = '未完成';
$lang->task->ditto = '同上';
$lang->task->dittoNotice = "该任务与上一任务不属于同一项目!";
@@ -104,13 +113,13 @@ $lang->task->noAssigned = '未指派';
$lang->task->noFinished = '未完成';
$lang->task->noClosed = '未关闭';
-$lang->task->statusList[''] = '';
-$lang->task->statusList['wait'] = '未开始';
-$lang->task->statusList['doing'] = '进行中';
-$lang->task->statusList['done'] = '已完成';
-$lang->task->statusList['pause'] = '已暂停';
-$lang->task->statusList['cancel'] = '已取消';
-$lang->task->statusList['closed'] = '已关闭';
+$lang->task->statusList[''] = '';
+$lang->task->statusList['wait'] = '未开始';
+$lang->task->statusList['doing'] = '进行中';
+$lang->task->statusList['done'] = '已完成';
+$lang->task->statusList['pause'] = '已暂停';
+$lang->task->statusList['cancel'] = '已取消';
+$lang->task->statusList['closed'] = '已关闭';
$lang->task->typeList[''] = '';
$lang->task->typeList['design'] = '设计';
@@ -122,11 +131,11 @@ $lang->task->typeList['ui'] = '界面';
$lang->task->typeList['affair'] = '事务';
$lang->task->typeList['misc'] = '其他';
-$lang->task->priList[0] = '';
-$lang->task->priList[3] = '3';
-$lang->task->priList[1] = '1';
-$lang->task->priList[2] = '2';
-$lang->task->priList[4] = '4';
+$lang->task->priList[0] = '';
+$lang->task->priList[3] = '3';
+$lang->task->priList[1] = '1';
+$lang->task->priList[2] = '2';
+$lang->task->priList[4] = '4';
$lang->task->reasonList[''] = '';
$lang->task->reasonList['done'] = '已完成';
@@ -155,7 +164,7 @@ $lang->task->noticeLinkStory = "没有可关联的相关需求,您可以
$lang->task->noticeSaveRecord = '您有尚未保存的工时记录,请先将其保存。';
$lang->task->commentActions = '%s. %s, 由