diff --git a/module/common/model.php b/module/common/model.php index 7063fa99bc..077d101a37 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -1186,7 +1186,7 @@ class commonModel extends model if($menuItem->link['module'] == 'execution' and $menuItem->link['method'] == 'more') { $executionID = $menuItem->link['vars']; - commonModel::buildMoreButton($executionID, $printHtml); + commonModel::buildMoreButton((int)$executionID, $printHtml); } elseif($menuItem->link['module'] == 'app' and $menuItem->link['method'] == 'serverlink') { diff --git a/module/execution/control.php b/module/execution/control.php index 9dc8998715..47daba8e2e 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1551,7 +1551,7 @@ class execution extends control * @access public * @return void */ - public function create($projectID = '', $executionID = 0, $copyExecutionID = '', $planID = 0, $confirm = 'no', $productID = 0, $extra = '') + public function create(string $projectID = '', int $executionID = 0, string $copyExecutionID = '', int $planID = 0, string $confirm = 'no', int $productID = 0, string $extra = '') { $projectID = (int)$projectID; @@ -1808,7 +1808,8 @@ class execution extends control $this->view->teams = array(0 => '') + $this->execution->getCanCopyObjects((int)$projectID); $this->view->allProjects = array(0 => '') + $this->project->getPairsByModel('all', 0, 'noclosed,multiple'); $this->view->copyProjects = $copyProjects; - $this->view->copyExecutions = array('' => '') + $this->execution->getList($copyProjectID, 'all', 'all', 0, 0, 0, null, false); + $this->view->copyProjectID = $copyProjectID; + $this->view->copyExecutions = $this->execution->getList($copyProjectID, 'all', 'all', 0, 0, 0, null, false); $this->view->executionID = $executionID; $this->view->productID = $productID; $this->view->projectID = $projectID; @@ -4327,13 +4328,15 @@ class execution extends control * Ajax get copy project executions. * * @param int $projectID + * @param int $copyExecutionID * @access public * @return void */ - public function ajaxGetCopyProjectExecutions($projectID = 0) + public function ajaxGetCopyProjectExecutions(int $projectID = 0, int $copyExecutionID = 0) { - $executions = $this->execution->getList($projectID, 'all', 'all', 0, 0, 0, null, false); - echo json_encode($executions); + $this->view->executions = $this->execution->getList($projectID, 'all', 'all', 0, 0, 0, null, false); + $this->view->copyExecutionID = $copyExecutionID; + $this->display(); } /** diff --git a/module/execution/css/create.ui.css b/module/execution/css/create.ui.css index 4638e13b5a..73a256b262 100644 --- a/module/execution/css/create.ui.css +++ b/module/execution/css/create.ui.css @@ -3,3 +3,14 @@ #lifeTimeTips {padding-left: 1rem; align-items: center;} .team-hr {margin-top: 0 !important;} #productsBox .line-btn {width: 48px; margin-right: 32px;} + +#copyExecutionModal .modal-dialog {max-height: unset;} +#copyExecutionModal .copy-title {min-width: 130px;} +#copyExecutionModal .selectProject {width: 20%;} +#copyExecutionModal .execution-block {flex: 0 1 30%; padding: 20px 10px; margin: 4px 12px; overflow: hidden;} +#copyExecutions div.bg-lighter {width: 100%;} +#copyExecutions .btn:hover {--tw-ring-color: var(--color-primary-500);} +#copyExecutions .btn:before {background: none;} +#copyExecutions .btn.primary-outline {background-color: var(--color-primary-50);} +#copyExecutions .btn.primary-outline:after {position: absolute; content: '\e92f'; font-family: ZentaoIcon; font-size: 20px; right: 25px;} +#copyExecutions .btn.primary-outline span{color: rgba(var(--color-fore-rgb),var(--tw-text-opacity));} diff --git a/module/execution/js/ajaxgetcopyprojectexecutions.ui.js b/module/execution/js/ajaxgetcopyprojectexecutions.ui.js new file mode 100644 index 0000000000..35c54d22e9 --- /dev/null +++ b/module/execution/js/ajaxgetcopyprojectexecutions.ui.js @@ -0,0 +1,5 @@ +$(function() +{ + if(hasExecution) $('.confirmBtn').removeClass('hidden'); + if(!hasExecution) $('.confirmBtn').addClass('hidden'); +}) diff --git a/module/execution/js/common.ui.js b/module/execution/js/common.ui.js index 1614d943be..7135b95ec8 100644 --- a/module/execution/js/common.ui.js +++ b/module/execution/js/common.ui.js @@ -258,21 +258,19 @@ function hidePlanBox(attribute) { if(attribute == 'request' || attribute == 'review') { - $('.productsBox .planBox').addClass('hide'); - $('.productsBox .planBox select').attr('disabled', 'disabled'); - $('#productTitle').text(manageProductsLang); + $('#productsBox .planBox').addClass('hidden'); + $('#productsBox .planBox select').attr('disabled', 'disabled'); - $('#plansBox').closest('.form-row').addClass('hide'); + $('#plansBox').closest('.form-row').addClass('hidden'); $('#plansBox').attr('disabled', 'disabled'); } else { - $('.productsBox .planBox').removeClass('hide'); - $('.productsBox .planBox select').attr('disabled', ''); - $('#productTitle').text(manageProductPlanLang); + $('#productsBox .planBox').removeClass('hidden'); + $('#productsBox .planBox select').removeAttr('disabled'); - $('#plansBox').closest('.form-row').removeClass('hide'); - $('#plansBox').attr('disabled', ''); + $('#plansBox').closest('.form-row').removeClass('hidden'); + $('#plansBox').removeAttr('disabled'); } } diff --git a/module/execution/js/create.ui.js b/module/execution/js/create.ui.js index 4381eb9751..6ff233e0d1 100644 --- a/module/execution/js/create.ui.js +++ b/module/execution/js/create.ui.js @@ -1,5 +1,7 @@ $(function() { + loadProjectExecutions(copyProjectID); + if($('#methodHover').length) new zui.Tooltip('#methodHover', {title: methodTip, trigger: 'hover', placement: 'right', type: 'white', 'className': 'text-gray border border-light methodTip'}); if(isStage) @@ -9,8 +11,6 @@ $(function() let attribute = $(this).val(); hidePlanBox(attribute); }) - - $('#attribute').change(); } if(copyExecutionID != 0 || projectID != 0) loadMembers(); @@ -118,3 +118,36 @@ $(document).on('change', '#end', function(e) $("input[name='delta']").prop('checked', false); computeWorkDays(); }); + +/** + * Load copy executions box. + * + * @access public + * @return void + */ +function loadProjectExecutions(projectID) +{ + projectID = parseInt(projectID) ? projectID : $(this).val(); + $('#copyExecutions').load($.createLink('execution', 'ajaxGetCopyProjectExecutions', 'projectID=' + projectID + '©ExecutionID=' + copyExecutionID)); +} + +$(document).off('click', '#copyExecutions button.execution-block').on('click', '#copyExecutions button.execution-block', function(e) +{ + $(this).toggleClass('primary-outline'); + $('.execution-block').not(this).removeClass('primary-outline'); +}); + +/** + * Set copy execution. + * + * @access public + * @return void + */ +function setCopyExecution() +{ + const executionID = $('.execution-block').hasClass('primary-outline') ? $('.execution-block.primary-outline').data('id') : 0; + if(!executionID) projectID = 0; + + loadPage($.createLink('execution', 'create', 'projectID=' + projectID + '&executionID=0©ExecutionID=' + executionID)); + zui.Modal.hide(); +} diff --git a/module/execution/ui/ajaxgetcopyprojectexecutions.html.php b/module/execution/ui/ajaxgetcopyprojectexecutions.html.php new file mode 100644 index 0000000000..270c3b7eea --- /dev/null +++ b/module/execution/ui/ajaxgetcopyprojectexecutions.html.php @@ -0,0 +1,51 @@ + + * @package execution + * @link https://www.zentao.net + */ +namespace zin; + +jsVar('hasExecution', !empty($executions)); + +$executionsBox = array(); +if(empty($executions)) +{ + $executionsBox[] = div + ( + set::class('inline-flex items-center'), + setClass(empty($executions) ? 'bg-lighter h-12' : ''), + icon('exclamation-sign icon-2x pl-2 text-warning'), + span + ( + set::class('font-bold ml-2'), + $lang->execution->copyNoExecution, + ) + ); +} +else +{ + foreach($executions as $id => $execution) + { + if(empty($execution->multiple)) continue; + + $executionsBox[] = btn( + setClass('execution-block justify-start'), + setClass($copyExecutionID == $id ? 'primary-outline' : ''), + set('data-id', $id), + icon + ( + setClass('text-gray'), + $lang->icons[$execution->type] + ), + span($execution->name), + ); + } +} + +/* ====== Render page ====== */ +render(); diff --git a/module/execution/ui/create.html.php b/module/execution/ui/create.html.php index 8988a05caa..212643dbd5 100644 --- a/module/execution/ui/create.html.php +++ b/module/execution/ui/create.html.php @@ -11,15 +11,14 @@ declare(strict_types=1); namespace zin; jsVar('methodTip', $lang->execution->agileplusMethodTip); -jsVar('projectID', $projectID); +jsVar('+projectID', $projectID); +jsVar('copyProjectID', $copyProjectID); jsVar('weekend', $config->execution->weekend); jsVar('errorSameProducts', $lang->execution->errorSameProducts); jsVar('errorSameBranches', $lang->execution->errorSameBranches); jsVar('isStage', $isStage); jsVar('copyExecutionID', $copyExecutionID); jsVar('multiBranchProducts', $multiBranchProducts); -jsVar('manageProductsLang', $lang->project->manageProducts); -jsVar('manageProductPlanLang', $lang->project->manageProductPlan); $methodBox = null; if(!empty($project->model) && $project->model == 'agileplus') @@ -54,7 +53,7 @@ if(!empty($project->model) && $project->model == 'agileplus') } $typeBox = null; -if((empty($project) or $project->model != 'kanban') and $type != 'kanban') +if((empty($project) || $project->model != 'kanban') and $type != 'kanban') { $typeBox = formRow( formGroup @@ -186,7 +185,7 @@ if(isset($project->hasProduct) and !empty($project->hasProduct) and $products) $i ++; } } -elseif(!empty($project) and empty($project->hasProduct) and !in_array($project->model, array('waterfall', 'kanban', 'waterfallplus'))) +elseif(!empty($project) && empty($project->hasProduct) && !in_array($project->model, array('waterfall', 'kanban', 'waterfallplus'))) { $planProductID = current(array_keys($allProducts)); $productsBox[] = formRow( @@ -291,7 +290,7 @@ formPanel ( setClass('primary-pale'), set::icon('copy'), - set::url('#copyProjectModal'), + set::url('#copyExecutionModal'), set('data-destoryOnHide', true), set('data-toggle', 'modal'), $showExecutionExec ? $lang->execution->copyExec : $lang->execution->copy @@ -520,5 +519,48 @@ formPanel ), ); +modalTrigger +( + modal + ( + set::id('copyExecutionModal'), + set::footerClass('justify-center'), + to::header + ( + span + ( + h4 + ( + set::class('copy-title'), + $lang->execution->copyTitle + ) + ), + select + ( + set::class('selectProject'), + set::name('project'), + set::items($copyProjects), + set::value($projectID), + set::required(true), + on::change('loadProjectExecutions'), + ), + ), + to::footer + ( + btn + ( + setClass('primary btn-wide hidden confirmBtn'), + set::text($lang->confirm), + on::click('setCopyExecution'), + ) + ), + div + ( + set::id('copyExecutions'), + setClass('flex items-center flex-wrap'), + ) + ) +); + /* ====== Render page ====== */ render();