From 411da36aa67f8e3a647ecec9b69ab16269c3b61a Mon Sep 17 00:00:00 2001 From: wangyidong Date: Mon, 14 Apr 2025 13:11:44 +0800 Subject: [PATCH] * [pref story #72428] Show stage tip when add sub stage. --- module/programplan/config/form.php | 1 + module/programplan/js/create.ui.js | 54 ++++++++++++++++++++++++--- module/programplan/model.php | 37 ++++++++++-------- module/programplan/ui/create.html.php | 13 +++---- 4 files changed, 77 insertions(+), 28 deletions(-) diff --git a/module/programplan/config/form.php b/module/programplan/config/form.php index 8967acb087..1f0f691d53 100644 --- a/module/programplan/config/form.php +++ b/module/programplan/config/form.php @@ -25,6 +25,7 @@ $config->programplan->form->create['milestone'] = array('label' => $lang->progr $config->programplan->form->create['desc'] = array('label' => $lang->programplan->desc, 'type' => 'string', 'control' => 'textarea', 'required' => false, 'default' => '', 'filter' => 'trim'); $config->programplan->form->create['output'] = array('label' => '', 'type' => 'string', 'control' => 'text', 'required' => false, 'default' => ''); $config->programplan->form->create['level'] = array('label' => '', 'type' => 'string', 'control' => 'text', 'required' => false, 'default' => 0); +$config->programplan->form->create['syncData'] = array('label' => '', 'type' => 'string', 'control' => 'text', 'required' => false, 'default' => 0); $config->programplan->form->edit = array(); $config->programplan->form->edit['parent'] = array('required' => false, 'type' => 'int', 'default' => 0); diff --git a/module/programplan/js/create.ui.js b/module/programplan/js/create.ui.js index f6d88546ed..d2934c648c 100644 --- a/module/programplan/js/create.ui.js +++ b/module/programplan/js/create.ui.js @@ -2,10 +2,54 @@ 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; + $this = this; + if(action == 'addSub' && $row.find('td[data-name="id"] input[name^=id]').val() > 0) + { + const $syncData = $row.find('td[data-name="syncData"] input[name^=syncData]'); + if(!$syncData.hasClass('confirmed') && $syncData.val() == '0') + { + $syncData.addClass('confirmed'); + const executionID = $row.find('td[data-name="id"] input[name^=id]').val(); + $.get($.createLink('project', 'ajaxCheckHasStageData', `executionID=${executionID}`), function(hasData) + { + if(hasData) + { + zui.Modal.confirm(confirmCreateTip).then((res) => + { + if(res) + { + $syncData.val('1'); + window.clickToAddRow($this, action, $row, rowIndex); + } + else + { + $row.find('td[data-name="ACTIONS"] [data-type="addSub"]').attr('disabled', 'disabled').addClass('disabled'); + } + }); + } + else + { + window.clickToAddRow($this, action, $row, rowIndex); + } + }); + } + else if($syncData.val() == '1') + { + window.clickToAddRow($this, action, $row, rowIndex); + } + } + else + { + window.clickToAddRow($this, action, $row, rowIndex); + } +}; + +window.clickToAddRow = function($this, action, $row, rowIndex) +{ + 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; $row.find('input[data-name="estimate"]').prop('readonly', true); // 如果有子任务,不允许修改预计工时 const nextLevel = level + 1; @@ -20,7 +64,7 @@ window.handleClickBatchFormAction = function(action, $row, rowIndex) $row = $nextRow; } - this.addRow(rowIndex, nextGid); + $this.addRow(rowIndex, nextGid); }; window.handleRenderRow = function($row, index, data) diff --git a/module/programplan/model.php b/module/programplan/model.php index 94547e3f26..cdb47edd0b 100755 --- a/module/programplan/model.php +++ b/module/programplan/model.php @@ -324,11 +324,11 @@ class programplanModel extends model * @param int $projectID * @param int $productID * @param int $parentID - * @param int $syncData + * @param int $totalSyncData * @access public * @return bool */ - public function create(array $plans, int $projectID = 0, int $productID = 0, int $parentID = 0, int $syncData = 0): bool + public function create(array $plans, int $projectID = 0, int $productID = 0, int $parentID = 0, int $totalSyncData = 0): bool { if(empty($plans)) dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->name); if(dao::isError()) return false; @@ -343,12 +343,14 @@ class programplanModel extends model $updateUserViewIdList = array(); $enabledPoints = array(); $parallel = 0; - $firstStageID = 0; $parents = array(); + $prevSyncData = null; + $prevLevel = 0; foreach($plans as $plan) { - $level = $plan->level; - unset($plan->level); + $level = $plan->level; + $syncData = $plan->syncData; + unset($plan->level, $plan->syncData); $parallel = isset($plan->parallel) ? $plan->parallel : 0; if(!empty($plan->point)) $enabledPoints = array_merge($enabledPoints, $plan->point); @@ -360,16 +362,18 @@ class programplanModel extends model $changes = $this->programplanTao->updateRow($stageID, $projectID, $plan); if(dao::isError()) return false; - if(empty($changes)) continue; - $actionID = $this->action->create('execution', $stageID, 'edited'); - $this->action->logHistory($actionID, $changes); + if(!empty($changes)) + { + $actionID = $this->action->create('execution', $stageID, 'edited'); + $this->action->logHistory($actionID, $changes); - /* Add PM to stage teams and project teams. */ - if(!empty($plan->PM)) $this->execution->addExecutionMembers($stageID, array($plan->PM)); - if($plan->acl != 'open') $updateUserViewIdList[] = $stageID; + /* Add PM to stage teams and project teams. */ + if(!empty($plan->PM)) $this->execution->addExecutionMembers($stageID, array($plan->PM)); + if($plan->acl != 'open') $updateUserViewIdList[] = $stageID; - $this->updateSubStageAttr($stageID, $plan->attribute); + $this->updateSubStageAttr($stageID, $plan->attribute); + } } else { @@ -383,15 +387,18 @@ class programplanModel extends model $this->execution->updateProducts($stageID, $linkProducts); if($plan->acl != 'open') $updateUserViewIdList[] = $stageID; - - if(!$firstStageID) $firstStageID = $stageID; } + + if($prevSyncData && $prevLevel == $level - 1) $this->programplanTao->syncParentData($stageID, $parents[$prevLevel]); + if($totalSyncData && $prevSyncData === null && $parentID) $this->programplanTao->syncParentData($stageID, $parentID); + + $prevSyncData = $syncData; + $prevLevel = $level; } if($project && $project->model == 'ipd') $this->dao->update(TABLE_PROJECT)->set('parallel')->eq($parallel)->where('id')->eq($projectID)->exec(); if($updateUserViewIdList) $this->loadModel('user')->updateUserView($updateUserViewIdList, 'sprint'); if($enabledPoints) $this->programplanTao->updatePoint($projectID, $enabledPoints); - if($syncData && $firstStageID) $this->programplanTao->syncParentData($firstStageID, $parentID); return true; } diff --git a/module/programplan/ui/create.html.php b/module/programplan/ui/create.html.php index b854e9cc29..eb55f0345f 100644 --- a/module/programplan/ui/create.html.php +++ b/module/programplan/ui/create.html.php @@ -55,12 +55,7 @@ $fnGenerateStageByProductList = function() use ($productID, $productList, $proje $items[] = array('text' => $product, 'active' => $productID == $key, 'url' => createLink('programplan', 'create', "projectID=$project->id&productID=$key&planID=$planID&executionType=stage&from=&syncData={$syncData}")); } - return dropdown - ( - $defaultName, - span(setClass('caret')), - set::items($items) - ); + return dropdown($defaultName, span(setClass('caret')), set::items($items)); }; /* Generate checkboxes for sub-stage management. */ @@ -92,7 +87,7 @@ $fnGenerateSubPlanManageFields = function() use ($lang, $planID, $project, $exec }; /* Generate form fields. */ -$fnGenerateFields = function() use ($config, $lang, $requiredFields, $showFields, $fields, $PMUsers, $enableOptionalAttr, $programPlan, $planID, $executionType, $project) +$fnGenerateFields = function() use ($config, $lang, $requiredFields, $showFields, $fields, $PMUsers, $enableOptionalAttr, $programPlan, $planID, $executionType, $project, $syncData) { $items = array(); @@ -117,7 +112,8 @@ $fnGenerateFields = function() use ($config, $lang, $requiredFields, $showFields unset($field['options']); /* Assgn item data to PM field. */ - if($name == 'PM') $field['items'] = $PMUsers; + if($name == 'PM') $field['items'] = $PMUsers; + if($name == 'syncData') $field['value'] = $syncData; /* Set hidden attribute. */ if(!str_contains($renderFields, ",$name,")) $field['hidden'] = true; @@ -230,6 +226,7 @@ jsVar('planGrade', $programPlan ? $programPlan->grade + 1 : 1); jsVar('syncData', $syncData); jsVar('cropStageTip', $lang->programplan->cropStageTip); jsVar('typeList', $lang->execution->typeList); +jsVar('confirmCreateTip', $lang->project->confirmCreateStage); jsVar('errorLang', $lang->programplan->error); jsVar('ipdStagePoint', $project->model == 'ipd' ? $config->review->ipdReviewPoint : array()); jsVar('attributeList', $project->model == 'ipd' ? $lang->stage->ipdTypeList : $lang->stage->typeList);