* Refactor batchcreate task pages.

This commit is contained in:
tianshujie
2023-05-16 11:06:40 +08:00
parent 6a4c66c3fa
commit df8b733691
8 changed files with 225 additions and 34 deletions
+1 -1
View File
@@ -107,7 +107,7 @@ $config->task->form->batchCreate['name'] = array('type' => 'array', 're
$config->task->form->batchCreate['color'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->batchCreate['type'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->batchCreate['assignedTo'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->batchCreate['estimated'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->batchCreate['estimate'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->batchCreate['estStarted'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->batchCreate['deadline'] = array('type' => 'array', 'required' => false, 'default' => array());
$config->task->form->batchCreate['desc'] = array('type' => 'array', 'required' => false, 'default' => array());
+4 -2
View File
@@ -122,8 +122,10 @@ class task extends control
if(!empty($_POST))
{
/* 批量创建任务。 Batch create tasks. */
$postData = form::data($this->config->task->form->batchCreate);
$tasks = $this->taskZen->prepareTasks4BatchCreate($execution, $postData->rawdata);
$postData = form::data($this->config->task->form->batchCreate);
$tasks = $this->taskZen->prepareTasks4BatchCreate($execution, $postData->get(), $taskID);
if(dao::isError()) return print(js::error(dao::getError()));
$taskIdList = $this->task->batchCreate($execution, $tasks, $taskID, $output);
if(dao::isError()) return print(js::error(dao::getError()));
+27
View File
@@ -0,0 +1,27 @@
/* Get select of stories.*/
function setStories()
{
const moduleID = $(this).val();
const index = $(this).closest('td').attr('data-init');
const link = $.createLink('story', 'ajaxGetExecutionStories', 'executionID=' + executionID + '&productID=0&branch=all&moduleID=' + moduleID + '&storyID=0&num=' + index + '&type=short');
$.get(link, function(stories)
{
var $story = $('#story_' + index);
var storyID = $story.val();
if(!stories) stories = '<select id="story' + index + '" name="story[' + index + ']" class="form-control"></select>';
$story.replaceWith(stories);
$story.val(storyID);
if($('#zeroTaskStory').hasClass('checked'))
{
$story.find('option').each(function()
{
value = $(this).attr('value');
if(value != 'ditto' && storyTasks[value] > 0)
{
$(this).hide();
if(storyID == value) $story.val('');
}
})
}
});
}
+2 -3
View File
@@ -1,8 +1,5 @@
$(function()
{
lifetimeList = JSON.parse(lifetimeList);
attributeList = JSON.parse(attributeList);
if(hideStory)
{
$("input[name='after'][value='toStoryList']").parent().hide();
@@ -93,6 +90,7 @@ function toggleSelectTestStory()
$('#estStarted').closest('.form-row').addClass('hidden');
$('#estimate').parent().prev().addClass('hidden');
$('#estimate').parent().addClass('hidden');
$('#testStoryBox').removeClass('hidden');
$('[name^=multiple]').prop('checked', false);
showTeamBox();
@@ -105,6 +103,7 @@ function toggleSelectTestStory()
$('#estStarted').closest('.form-row').removeClass('hidden');
$('#estimate').parent().prev().removeClass('hidden');
$('#estimate').parent().removeClass('hidden');
$('#testStoryBox').addClass('hidden');
}
}
+7 -5
View File
@@ -1711,12 +1711,14 @@ class taskModel extends model
->andWhere('t1.vision')->eq($this->config->vision)
->fetch();
if(!$task) return false;
$task->openedDate = !empty($task->openedDate) ? substr($task->openedDate, 0, 19) : null;
$task->finishedDate = !empty($task->finishedDate) ? substr($task->finishedDate, 0, 19) : null;
$task->canceledDate = !empty($task->canceledDate) ? substr($task->canceledDate, 0, 19) : null;
$task->closedDate = !empty($task->closedDate) ? substr($task->closedDate, 0, 19) : null;
$task->openedDate = !empty($task->openedDate) ? substr($task->openedDate, 0, 19) : null;
$task->finishedDate = !empty($task->finishedDate) ? substr($task->finishedDate, 0, 19) : null;
$task->canceledDate = !empty($task->canceledDate) ? substr($task->canceledDate, 0, 19) : null;
$task->closedDate = !empty($task->closedDate) ? substr($task->closedDate, 0, 19) : null;
$task->lastEditedDate = !empty($task->lastEditedDate) ? substr($task->lastEditedDate, 0, 19) : null;
$task->realStarted = !empty($task->realStarted) ? substr($task->realStarted, 0, 19) : null;
$task->realStarted = !empty($task->realStarted) ? substr($task->realStarted, 0, 19) : null;
$task->mailto = empty($task->mailto) ? '' : $task->mailto;
$children = $this->dao->select('*')->from(TABLE_TASK)->where('parent')->eq($taskID)->andWhere('deleted')->eq(0)->fetchAll('id');
$task->children = $children;
+165
View File
@@ -0,0 +1,165 @@
<?php
declare(strict_types=1);
/**
* The batchCreate view file of task module of ZenTaoPMS.
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Shujie Tian<tianshujie@easycorp.ltd>
* @package task
* @link https://www.zentao.net
*/
namespace zin;
/* ====== Preparing and processing page data ====== */
jsVar('executionID', $execution->id);
jsVar('storyTasks', $storyTasks);
/* zin: Set variables to define picker options for form. */
$items = array();
/* Field of ID. */
$items[] = array
(
'name' => 'id',
'label' => $lang->idAB,
'control' => 'index',
'width' => '30px',
);
/* Field of module. */
$items[] = array
(
'name' => 'module',
'label' => $lang->task->module,
'control' => 'select',
'value' => $moduleID,
'items' => $modules,
'width' => '180px',
);
/* Field of story. */
if(!$hideStory)
{
$items[] = array
(
'name' => 'story',
'label' => $lang->task->story,
'control' => 'select',
'items' => $stories,
'width' => '200px',
'ditto' => true,
);
}
/* Field of name. */
$items[] = array
(
'name' => 'name',
'label' => $lang->task->name,
'width' => '165px',
);
/* Field of region and lane. */
if($execution->type == 'kanban')
{
$items[] = array
(
'name' => 'regions',
'label' => $lang->kanbancard->region,
'control' => 'select',
'value' => $regionID,
'items' => $regionPairs,
'width' => '180px',
);
$items[] = array
(
'name' => 'lanes',
'label' => $lang->kanbancard->lane,
'control' => 'select',
'value' => $laneID,
'items' => $lanePairs,
'width' => '180px',
);
}
/* Field of type. */
$items[] = array
(
'name' => 'type',
'label' => $lang->task->type,
'control' => 'select',
'items' => $lang->task->typeList,
'width' => '100px',
'ditto' => true,
);
/* Field of assignedTo. */
$items[] = array
(
'name' => 'assignedTo',
'label' => $lang->task->assignedTo,
'control' => 'select',
'items' => $members,
'width' => '130px',
'ditto' => true,
);
/* Field of estimate. */
$items[] = array
(
'name' => 'estimate',
'label' => $lang->task->estimateAB,
'width' => '70px',
);
/* Field of estStarted. */
$items[] = array
(
'name' => 'estStarted',
'label' => $lang->task->estStarted,
'control' => 'date',
'width' => '120px',
'ditto' => true,
);
/* Field of deadline. */
$items[] = array
(
'name' => 'deadline',
'label' => $lang->task->deadline,
'control' => 'date',
'width' => '120px',
'ditto' => true,
);
/* Field of desc. */
$items[] = array
(
'name' => 'desc',
'label' => $lang->task->desc,
'control' => 'editor',
'width' => '150px',
);
/* Field of pri. */
$items[] = array
(
'name' => 'pri',
'label' => $lang->task->pri,
'control' => 'select',
'items' => $lang->task->priList,
'width' => '130px',
'ditto' => true,
);
/* ====== Define the page structure with zin widgets ====== */
formBatchPanel
(
set::items($items),
on::change('[data-name="module"]', 'setStories'),
);
/* ====== Render page ====== */
render();
+3 -2
View File
@@ -25,8 +25,8 @@ jsVar('requiredFields', $config->task->create->requiredFields);
jsVar('estimateNotEmpty', sprintf($lang->error->gt, $lang->task->estimate, '0'));
jsVar('window.lifetime', $execution->lifetime);
jsVar('window.attribute', $execution->attribute);
jsVar('window.lifetimeList', json_encode($lifetimeList));
jsVar('window.attributeList', json_encode($attributeList));
jsVar('window.lifetimeList', $lifetimeList);
jsVar('window.attributeList', $attributeList);
jsVar('hasProduct', $execution->hasProduct);
jsVar('hideStory', $hideStory);
$requiredFields = array();
@@ -253,6 +253,7 @@ formPanel
setClass('empty-story-tip input-control has-prefix has-suffix'),
$storyEmptyPreTip,
input(
set::name(''),
prop('readonly'),
prop('onfocus', 'this.blur()'),
),
+16 -21
View File
@@ -544,12 +544,13 @@ class taskZen extends task
* 处理批量创建任务的请求数据。
* Process the request data for batch create tasks.
*
* @param object $execution
* @param object $formData
* @param object $execution
* @param object $formData
* @param int $taskID
* @access protected
* @return object[]|false
*/
protected function prepareTasks4BatchCreate(object $execution, object $formData): array|false
protected function prepareTasks4BatchCreate(object $execution, object $formData, int $taskID): array|false
{
/* 去除重复数据。 Deduplicated data. */
$tasks = $this->removeDuplicate4BatchCreate($execution, $formData);
@@ -569,6 +570,8 @@ class taskZen extends task
$data = array();
foreach($formData->name as $i => $name)
{
if(empty($name)) continue;
/* 给同上的变量赋值。 Assign values to ditto fields. */
$story = !isset($tasks->story[$i]) || $tasks->story[$i] == 'ditto' ? $story : $tasks->story[$i];
$module = !isset($tasks->module[$i]) || $tasks->module[$i] == 'ditto' ? $module : $tasks->module[$i];
@@ -577,19 +580,9 @@ class taskZen extends task
$estStarted = !isset($tasks->estStarted[$i]) || isset($tasks->estStartedDitto[$i]) ? $estStarted : $tasks->estStarted[$i];
$deadline = !isset($tasks->deadline[$i]) || isset($tasks->deadlineDitto[$i]) ? $deadline : $tasks->deadline[$i];
/* 检查任务名称为空的数据。 Check the data whick task's name. */
if(empty($tasks->name[$i]))
{
if($this->common->checkValidRow('task', $tasks, $i))
{
dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->task->name);
return false;
}
continue;
}
$dittoFields = array('story' => $story, 'module' => $module, 'type' => $type, 'assignedTo' => $assignedTo, 'estStarted' => $estStarted, 'deadline' => $deadline);
$data[$i] = $this->buildData4BatchCreate($execution, $tasks, $i, $dittoFields, $extendFields);
$data[$i] = $this->buildData4BatchCreate($execution, $tasks, $i, $dittoFields, $extendFields, $taskID);
}
return $data;
@@ -652,10 +645,11 @@ class taskZen extends task
* @param int $index
* @param array $dittoFields
* @param array $extendFields
* @param int $taskID
* @access protected
* @return object
*/
protected function buildData4BatchCreate(object $execution, object $tasks, int $index, array $dittoFields, array $extendFields): object
protected function buildData4BatchCreate(object $execution, object $tasks, int $index, array $dittoFields, array $extendFields, int $taskID): object
{
extract($dittoFields);
$now = helper::now();
@@ -665,10 +659,10 @@ class taskZen extends task
$task->type = $type;
$task->module = (int)$module;
$task->assignedTo = $assignedTo;
$task->color = $tasks->color[$index];
$task->color = isset($tasks->color[$index]) ? $tasks->color[$index] : '';
$task->name = $tasks->name[$index];
$task->desc = nl2br($tasks->desc[$index]);
$task->pri = $tasks->pri[$index];
$task->pri = (int)$tasks->pri[$index];
$task->estimate = $tasks->estimate[$index] ? $tasks->estimate[$index] : 0;
$task->left = $tasks->estimate[$index] ? $tasks->estimate[$index] : 0;
$task->project = $execution->project;
@@ -678,7 +672,7 @@ class taskZen extends task
$task->status = 'wait';
$task->openedBy = $this->app->user->account;
$task->openedDate = $now;
$task->parent = $tasks->parent[$index];
$task->parent = $taskID;
$task->vision = isset($tasks->vision[$index]) ? $tasks->vision[$index] : 'rnd';
$task->version = 1;
if($story) $task->storyVersion = (int)$this->dao->findById($task->story)->from(TABLE_STORY)->fetch('version');
@@ -1103,8 +1097,8 @@ class taskZen extends task
{
$this->loadModel('kanban');
$regionID = (int)$output['regionID'];
$laneID = (int)$output['laneID'];
$regionID = isset($output['regionID']) ? (int)$output['regionID'] : 0;
$laneID = isset($output['laneID']) ? (int)$output['laneID'] : 0;
$regionPairs = $this->kanban->getRegionPairs($executionID, 0, 'execution');
$regionID = $regionID ? $regionID : key($regionPairs);
$lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'task');
@@ -1360,7 +1354,7 @@ class taskZen extends task
{
/* 获取区域和泳道下拉数据,并设置区域和泳道的默认值。 */
/* Get region and lane dropdown data and set default values for regions and lanes. */
if($execution->type == 'kanban') $this->assignKanbanRelatedVars($execution->id, $output);
if($execution->type == 'kanban') $this->assignKanban4Create($execution->id, $output);
if($taskID)
{
@@ -1390,6 +1384,7 @@ class taskZen extends task
$this->view->taskConsumed = isset($task) ? $task->consumed : 0;
$this->view->customFields = $customFields;
$this->view->checkedFields = $checkedFields;
$this->view->hideStory = $this->task->isNoStoryExecution($execution);
$this->display();
}