+ Add create test story tasks function.

This commit is contained in:
tianshujie
2024-01-18 16:24:46 +08:00
parent 27d2a0e7c4
commit 08d73c58e0
11 changed files with 124 additions and 94 deletions
+4 -1
View File
@@ -2698,6 +2698,9 @@ class storyModel extends model
$storyPairs = array();
foreach($stories as $story)
{
$prefix = $story->id . ':';
if($type == 'ignoreID') $prefix = '';
$property = '';
if($type == 'short')
{
@@ -2707,7 +2710,7 @@ class storyModel extends model
{
$property = '(' . $this->lang->story->pri . ':' . (!empty($this->lang->story->priList[$story->pri]) ? $this->lang->story->priList[$story->pri] : 0) . ',' . $this->lang->story->estimate . ':' . $story->estimate . ')';
}
$storyPairs[$story->id] = $story->id . ':' . $story->title . ' ' . $property;
$storyPairs[$story->id] = $prefix . $story->title . ' ' . $property;
}
if($limit == 0) return $storyPairs;
+9 -9
View File
@@ -180,15 +180,15 @@ $config->task->form->close['lastEditedBy'] = array('type' => 'string', 'requ
$config->task->form->close['lastEditedDate'] = array('type' => 'datetime', 'required' => false, 'default' => $now);
$config->task->form->testTask->create = array();
$config->task->form->testTask->create['selectTestStory'] = array('type' => 'int', 'required' => false, 'default' => 0);
$config->task->form->testTask->create['testStory'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testEstStarted'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testDeadline'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testAssignedTo'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testPri'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testEstimate'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['estStartedDitto'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['deadlineDitto'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['selectTestStory'] = array('type' => 'string', 'required' => false, 'default' => 'off');
$config->task->form->testTask->create['testStory'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testEstStarted'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testDeadline'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testAssignedTo'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testPri'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['testEstimate'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['estStartedDitto'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->testTask->create['deadlineDitto'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->recordWorkhour = array();
$config->task->form->recordWorkhour['date'] = array('type' => 'date', 'required' => true, 'default' => array());
+1 -1
View File
@@ -1200,7 +1200,7 @@ class task extends control
*/
public function ajaxGetTestStories(int $executionID, int $taskID = 0)
{
$stories = $this->story->getExecutionStoryPairs($executionID, 0, 'all', '', '', 'active');
$stories = $this->story->getExecutionStoryPairs($executionID, 0, 'all', '', 'ignoreID', 'active');
$testStoryIdList = $this->story->getTestStories(array_keys($stories), $executionID);
$testStories = array();
foreach($stories as $testStoryID => $storyTitle)
+4 -1
View File
@@ -1,2 +1,5 @@
#testTaskTable {table-layout: fixed;}
#testTaskTable tr {border: none;}
#testTaskTable tr > th, #testTaskTable tr > td {padding: 0.5rem;}
#testTaskTable tr > th:not(.c-actions) {border: 1px solid var(--table-border-color);}
#testTaskTable tr > th {background-color: #FFF; font-weight: unset;}
#testTaskTable tr > td {padding: 0;}
+17 -19
View File
@@ -68,33 +68,31 @@ function typeChange(e)
* @access public
* @return void
*/
function toggleSelectTestStory(executionID)
function toggleSelectTestStory()
{
if(typeof(executionID) == 'undefined') executionID = window.executionID;
$('#testStoryBox').load($.createLink('task', 'ajaxGetTestStories', 'executionID=' + executionID + '&taskID=' + taskID));
if(!$('#selectTestStoryBox').hasClass('hidden') && $('#selectTestStory').prop('checked'))
if(!$('[name=selectTestStory]').hasClass('hidden') && $('[name=selectTestStory]').prop('checked'))
{
$('#module').closest('.form-group').addClass('hidden');
$('#multipleBox').closest('.form-group').addClass('hidden');
$('#story').closest('.form-row').addClass('hidden');
$('#estStarted').closest('.form-row').addClass('hidden');
if(!$('#estimate').hasClass('hidden')) $('#estimate').parent().prev().addClass('hidden');
if(!$('#estimate').hasClass('hidden')) $('#estimate').parent().addClass('hidden');
$('#testStoryBox').removeClass('hidden');
$('[data-name=module]').addClass('hidden');
$('[data-name=storyBox]').addClass('hidden');
$('[data-name=datePlan]').addClass('hidden');
$('[data-name=estimate]').addClass('hidden');
$('[name=multiple]').closest('.checkbox-primary').addClass('hidden');
$('[data-name=testStoryBox]').removeClass('hidden');
$('#testStoryBox').load($.createLink('task', 'ajaxGetTestStories', 'executionID=' + executionID + '&taskID=' + taskID));
$('[name^=multiple]').prop('checked', false);
toggleTeam();
}
else
{
$('#module').closest('.form-group').removeClass('hidden');
$('#multipleBox').closest('.form-group').removeClass('hidden');
if(showFields.indexOf('story') != -1) $('#story').closest('.form-row').removeClass('hidden');
$('#estStarted').closest('.form-row').removeClass('hidden');
if(!$('#estimate').hasClass('hidden')) $('#estimate').parent().prev().removeClass('hidden');
if(!$('#estimate').hasClass('hidden')) $('#estimate').parent().removeClass('hidden');
$('#testStoryBox').addClass('hidden');
$('[data-name=module]').removeClass('hidden');
$('[data-name=storyBox]').removeClass('hidden');
$('[data-name=datePlan]').removeClass('hidden');
$('[data-name=estimate]').removeClass('hidden');
$('[name=multiple]').closest('.checkbox-primary').removeClass('hidden');
$('[data-name=testStoryBox]').addClass('hidden');
}
}
+1
View File
@@ -276,6 +276,7 @@ $lang->task->noModule = '<div>您现在还没有模块信息</d
$lang->task->createDenied = "你不能在该{$lang->projectCommon}添加任务";
$lang->task->cannotDeleteParent = '不能删除父任务。';
$lang->task->addChildTask = '因该任务已经产生消耗,为保证数据一致性,我们会帮您创建一条同名子任务记录该消耗。';
$lang->task->selectTestStoryTip = "以下{$lang->SRCommon}将作为此任务的子任务";
$lang->task->error = new stdclass();
$lang->task->error->totalNumber = '"总计消耗"必须为数字';
+1 -1
View File
@@ -1020,7 +1020,7 @@ class taskModel extends model
{
if(!empty($testTasks))
{
$this->config->task->create->requiredFields = str_replace(array(',estimate,', ',story,', ',estStarted,', ',deadline,', ',module,'), ',', $this->config->task->create->requiredFields);
$this->config->task->create->requiredFields = str_replace(array(',estimate,', ',story,', ',estStarted,', ',deadline,', ',module,'), ',', ",{$this->config->task->create->requiredFields},");
}
$taskID = $this->create($task);
+65 -56
View File
@@ -24,23 +24,29 @@ foreach($testStories as $storyID => $storyTitle)
(
h::td
(
picker
(
setID("testStory{$i}"),
set::name("testStory[$i]"),
set::value($storyID),
set::items(array($storyID => $storyTitle))
)
setClass('border-b border-l'),
span($storyID, setClass('ml-2'))
),
h::td
(
picker
(
setID("testStory{$i}"),
set::name("testStory[$i]"),
set::value($storyID),
set::items(array($storyID => $storyTitle)),
set::required(true)
)
),
h::td
(
priPicker
(
setID("testPri{$i}"),
set::name("testPri[$i]"),
set::required(true),
set::value(empty($task->pri) ? 3 : $task->pri),
set::items($lang->task->priList)
set::items(array_filter($lang->task->priList))
)
),
h::td
@@ -49,15 +55,22 @@ foreach($testStories as $storyID => $storyTitle)
(
setID("testEstStarted{$i}"),
set::name("testEstStarted[$i]"),
set::placeholder($lang->task->estStarted),
set::value(empty($task->estStarted) ? '' : $task->estStarted)
)
),
h::td
(
setClass('text-center text-gray border-b'),
span('—')
),
h::td
(
datepicker
(
setID("testDeadline{$i}"),
set::name("testDeadline[$i]"),
set::placeholder($lang->task->deadline),
set::value(empty($task->deadline) ? '' : $task->deadline)
)
),
@@ -86,7 +99,7 @@ foreach($testStories as $storyID => $storyTitle)
),
h::td
(
setClass('center'),
setClass('c-actions'),
btnGroup
(
set::items(array(
@@ -99,59 +112,55 @@ foreach($testStories as $storyID => $storyTitle)
$i ++;
}
formGroup
h::table
(
set::label($lang->task->selectTestStory),
set::labelClass('selectStoryLabel'),
h::table
setClass('table table-form'),
setID('testTaskTable'),
h::thead
(
setClass('table table-form'),
setID('testTaskTable'),
h::thead
h::tr
(
h::tr
setClass('text-gray text-left'),
h::th('ID'),
h::th($lang->task->storyAB),
h::th
(
h::th($lang->task->storyAB),
h::th
(
$lang->task->pri,
set::width('80px'),
setClass(isset($requiredFields['pri']) ? 'required' : '')
),
h::th
(
$lang->task->estStarted,
set::width('140px'),
setClass(isset($requiredFields['estStarted']) ? 'required' : '')
),
h::th
(
$lang->task->deadline,
set::width('140px'),
setClass(isset($requiredFields['deadline']) ? 'required' : '')
),
h::th
(
$lang->task->assignedTo,
set::width('100px')
),
h::th
(
$lang->task->estimate,
set::width('88px'),
setClass(isset($requiredFields['estimate']) ? 'required' : '')
),
h::th
(
$lang->actions,
set::width('70px')
)
$lang->task->pri,
setClass(isset($requiredFields['pri']) ? 'required' : '')
),
h::th
(
$lang->task->datePlan,
set('colspan', 3),
setClass((isset($requiredFields['estStarted']) || isset($requiredFields['deadline'])) ? 'required' : '')
),
h::th
(
$lang->task->assignedTo,
),
h::th
(
$lang->task->estimateAB,
setClass(isset($requiredFields['estimate']) ? 'required' : '')
),
h::th
(
setClass('c-actions'),
)
),
h::tbody
(
$taskTR
)
h::col(setStyle('width', '80px')),
h::col(setStyle('width', 'auto')),
h::col(setStyle('width', '80px')),
h::col(setStyle('width', '140px')),
h::col(setStyle('width', '30px')),
h::col(setStyle('width', '140px')),
h::col(setStyle('width', '120px')),
h::col(setStyle('width', '100px')),
h::col(setStyle('width', '70px')),
),
h::tbody
(
$taskTR
)
);
+13
View File
@@ -179,3 +179,16 @@ $fields->field('taskName')
$fields->field('taskEstimate')
->hidden()
->control('input');
/* Set test story task control. */
$buildTestStoryBox = function($props)
{
return div(setID('testStoryBox'));
};
$fields->field('testStoryBox')
->label($lang->task->selectTestStory)
->labelHint($lang->task->selectTestStoryTip)
->width('full')
->hidden()
->control($buildTestStoryBox);
+5 -3
View File
@@ -21,10 +21,12 @@ jsVar('window.attributeList', $attributeList);
jsVar('teamMemberError', $lang->task->error->teamMember);
jsVar('requiredFields', $config->task->create->requiredFields);
jsVar('estimateNotEmpty', sprintf($lang->error->gt, $lang->task->estimate, '0'));
jsVar('taskID', $taskID ?? 0);
$fields = useFields('task.create');
$fields->autoLoad('execution', 'execution,type,name,assignedToBox,region,lane,module,storyBox,datePlan,pri,estimate,desc,file,mailto,keywords,after,testStoryBox');
$fields->orders('name,assignedToBox', 'desc,module,storyBox');
$fields->orders('name,assignedToBox', 'module,testStoryBox', 'desc,module,storyBox');
$fields->fullModeOrders('type,module,storyBox', 'desc,file,mailto,keywords');
if($execution->type == 'kanban')
{
@@ -38,8 +40,6 @@ if(empty($features['story']) && $execution->type != 'kanban')
$fields->fullModeOrders('type,module,storyBox,assignedToBox', 'desc,file,mailto,keywords');
}
$fields->autoLoad('execution', 'execution,type,name,assignedToBox,region,lane,module,storyBox,datePlan,pri,estimate,desc,file,mailto,keywords,after');
$teamForm = array();
if(empty($task->team))
{
@@ -164,7 +164,9 @@ formGridPanel
on::change('[name=type]', 'typeChange'),
on::change('[name=region]', 'loadLanes'),
on::change('[name=multiple]', 'toggleTeam'),
on::change('[name=selectTestStory]', 'toggleSelectTestStory'),
on::change('#teamTable [name^=team]', 'changeTeamMember'),
on::change('[name=execution]', 'loadAll'),
on::click('[name=isShowAllModule]', 'showAllModule'),
on::click('[name=copyButton]', 'copyStoryTitle'),
on::click('.assignedToList .picker-multi-selection', 'removeTeamMember'),
+4 -3
View File
@@ -551,6 +551,7 @@ class taskZen extends task
{
$formConfig = $this->config->task->form->create;
if($this->post->type == 'affair') $formConfig['assignedTo']['type'] = 'array';
if($this->post->type == 'test') $formConfig['story']['skipRequired'] = true;
$execution = $this->dao->findById($executionID)->from(TABLE_EXECUTION)->fetch();
$team = $this->post->team ? array_filter($this->post->team) : array();
@@ -699,7 +700,7 @@ class taskZen extends task
{
/* Set data for the type of test task that has linked stories. */
$postData = form::data($this->config->task->form->testTask->create)->get();
if(empty($postData->selectTestStory)) return array();
if($postData->selectTestStory == 'off') return array();
$testTasks = array();
foreach($postData->testStory as $key => $storyID)
@@ -714,8 +715,8 @@ class taskZen extends task
$task->estStarted = !empty($postData->testEstStarted[$key]) ? $postData->testEstStarted[$key] : null;
$task->deadline = !empty($postData->testDeadline[$key]) ? $postData->testDeadline[$key] : null;
$task->assignedTo = !empty($postData->testAssignedTo[$key]) ? $postData->testAssignedTo[$key] : '';
$task->estimate = (float)$postData->testEstimate[$key];
$task->left = (float)$postData->testEstimate[$key];
$task->estimate = !empty($postData->testEstimate[$key]) ? (float)$postData->testEstimate[$key] : 0;
$task->left = !empty($postData->testEstimate[$key]) ? (float)$postData->testEstimate[$key] : 0;
$task->type = 'test'; /* Setting the task type to test to prevent duplicate tasks from being created. */
$task->vision = $this->config->vision;