From b500d8d98faa52032dd3d5c36943fc3dc9c36cd9 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Mon, 25 Nov 2024 15:37:25 +0800 Subject: [PATCH] * [perf story #69668] Adjust task batchcreate. --- module/task/config/form.php | 1 + module/task/js/batchcreate.ui.js | 77 +++++++++++++++++++++++++++++ module/task/model.php | 15 ++++-- module/task/ui/batchcreate.html.php | 18 ++++--- 4 files changed, 100 insertions(+), 11 deletions(-) diff --git a/module/task/config/form.php b/module/task/config/form.php index 70dbabc5f7..224f299adb 100644 --- a/module/task/config/form.php +++ b/module/task/config/form.php @@ -131,6 +131,7 @@ $config->task->form->batchcreate['column'] = array('type' => 'int', $config->task->form->batchcreate['openedBy'] = array('type' => 'string', 'required' => false, 'default' => $account); $config->task->form->batchcreate['openedDate'] = array('type' => 'datetime', 'required' => false, 'default' => $now); $config->task->form->batchcreate['vision'] = array('type' => 'string', 'required' => false, 'default' => $config->vision); +$config->task->form->batchcreate['level'] = array('type' => 'string', 'required' => false, 'default' => 0); $config->task->form->pause = array(); $config->task->form->pause['lastEditedBy'] = array('type' => 'string', 'required' => false, 'default' => $account); diff --git a/module/task/js/batchcreate.ui.js b/module/task/js/batchcreate.ui.js index 61fb30a70b..9a376d7ad1 100644 --- a/module/task/js/batchcreate.ui.js +++ b/module/task/js/batchcreate.ui.js @@ -198,3 +198,80 @@ function checkBatchEstStartedAndDeadline(event) } } } + +window.handleClickBatchFormAction = function(action, $row, rowIndex) +{ + if(action !== 'addSub' && action !== 'addSibling') return; + + if(!this.nestedLevelMap) this.nestedLevelMap = {}; + const level = this.nestedLevelMap[$row.attr('data-gid')] || 0; + const nextGid = this._idSeed++; + this.nestedLevelMap[nextGid] = action === 'addSub' ? level + 1 : level; + + if(action == 'addSibling') + { + $rawRow = $row; + while(true) + { + $nextRow = $row.next(); + if($nextRow.length == 0 || $nextRow.attr('data-level') <= level) + { + rowIndex = $nextRow.length == 0 ? $row.index() : $nextRow.index() - 1; + break; + } + + $row = $nextRow; + } + } + this.addRow(rowIndex, nextGid); +}; + +window.handleRenderRow = function($row, index) +{ + if(!this.nestedLevelMap) this.nestedLevelMap = {}; + + /* 上一行: */ + const $prevRow = $row.prev(); + + /* 从行中查找层级文本展示元素: */ + const nestedTextSelector = 'td[data-name="name"] .input-group-addon'; + + /* 获取当前行的层级,下面可能会根据上一行层级修改当前行层级: */ + let level = this.nestedLevelMap[$row.attr('data-gid')] || 0; + + /* 当前行层级信息文本: */ + let text = '1'; + + /* 处理有上一行的情况: */ + if($prevRow.length) + { + /* 根据上一行层级,重新计算当前行层级: */ + const prevLevel = +$prevRow.attr('data-level') || 0; + if(prevLevel < level) level = prevLevel + 1; + + /* 根据上一行的层级文本,生成当前行的层级文本: */ + const prevText = $prevRow.find(nestedTextSelector).text(); + const parts = prevText.split('.'); + if(prevLevel === level) parts[level] = +parts[level] + 1; + else if(prevLevel > level) + { + parts.length = level + 1; + parts[level] = +parts[level] + 1; + } + else parts[level] = 1; + text = parts.join('.'); + } + else + { + /* 如果没有上一行,当前行层级为 0: */ + level = 0; + } + + /* 存储当前行层级信息: */ + this.nestedLevelMap[$row.attr('data-gid')] = level; + $row.attr('data-level', level); + + /* 创建隐藏表单域用于向服务器提交当前行层级信息。 */ + $row.find(nestedTextSelector).text(text).append(``); + if(edition == 'open' && (level > 0 || parentID)) $row.find('button[data-type=addSub]').attr('disabled', 'disabled'); +}; diff --git a/module/task/model.php b/module/task/model.php index b317058d76..3be1926dc7 100755 --- a/module/task/model.php +++ b/module/task/model.php @@ -497,18 +497,27 @@ class taskModel extends model $executionID = !empty($tasks) ? current($tasks)->execution : 0; $taskIdList = array(); + $parents = array(); foreach($tasks as $task) { /* Get the lane and column of the current task. */ $laneID = $task->lane; $columnID = $task->column; - unset($task->lane); - unset($task->column); + $level = $task->level; + unset($task->lane, $task->column, $task->level); /* Create a task. */ $taskID = $this->create($task); if(!$taskID) return false; + $parents[$level] = $taskID; + $task->id = $taskID; + if($level > 0) + { + $this->dao->update(TABLE_TASK)->set('parent')->eq($parents[$level - 1])->where('id')->eq($taskID)->exec(); + $this->updateParent($task, false); + } + /* Update Kanban and story stage. */ if(!empty($task->story)) { @@ -3231,7 +3240,7 @@ class taskModel extends model * @access public * @return void */ - public function updateParent(object $task, bool $isParentChanged): void + public function updateParent(object $task, bool $isParentChanged = false): void { $oldTask = $this->fetchByID($task->id); $parentTask = empty($task->parent) ? null : $this->fetchByID((int)$task->parent); diff --git a/module/task/ui/batchcreate.html.php b/module/task/ui/batchcreate.html.php index a4bd681a39..a881924de0 100644 --- a/module/task/ui/batchcreate.html.php +++ b/module/task/ui/batchcreate.html.php @@ -13,6 +13,8 @@ namespace zin; include($this->app->getModuleRoot() . 'ai/ui/inputinject.html.php'); /* ====== Preparing and processing page data ====== */ +jsVar('edition', $config->edition); +jsVar('parentID', (int)$parent); jsVar('executionID', $execution->id); jsVar('storyTasks', $storyTasks); jsVar('parentEstStarted', isset($parentTask) ? $parentTask->estStarted : ''); @@ -141,6 +143,12 @@ if($execution->type == 'kanban') ); } +$batchFormOptions = array(); +$batchFormOptions['fixedActions'] = true; // 滚动时固定操作列。 +$batchFormOptions['actions'] = array(array('type' => 'addSibling', 'icon' => 'icon-plus', 'text' => '添加同级'), array('type' => 'addSub', 'icon' => 'icon-split', 'text' => '添加子级'), 'delete'); // 定义操作列按钮,在此处添加一个添加子级按钮。 +$batchFormOptions['onClickAction'] = jsRaw('window.handleClickBatchFormAction'); // 定义操作列按钮点击事件处理函数。 +$batchFormOptions['onRenderRow'] = jsRaw('window.handleRenderRow'); // 定义行渲染事件处理函数。 + /* ====== Define the page structure with zin widgets ====== */ formBatchPanel @@ -150,6 +158,7 @@ formBatchPanel set::pasteField('name'), set::customFields(array('list' => $customFields, 'show' => explode(',', $showFields), 'key' => 'batchCreateFields')), set::headingActionsClass('flex-auto row-reverse justify-between w-11/12'), + set::batchFormOptions($batchFormOptions), $taskConsumed > 0 ? on::inited()->call('zui.Modal.alert', $lang->task->addChildTask) : null, to::headingActions ( @@ -162,13 +171,6 @@ formBatchPanel ) ), formBatchItem - ( - set::name('id'), - set::label($lang->idAB), - set::control('index'), - set::width('32px') - ), - formBatchItem ( set::name('module'), set::label($lang->task->module), @@ -187,7 +189,7 @@ formBatchPanel formBatchItem ( set::name('name'), - set::control('colorInput'), + set::control(array('control' => 'inputGroup', 'id' => '', 'items' => array('#', array('control' => 'colorInput', 'name' => 'name')))), set::label($lang->task->name), set::width('240px') ),