From a7f9fdca861d31a4065f344598e2be4a21991ac1 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Tue, 29 Mar 2022 14:03:53 +0800 Subject: [PATCH 01/20] * Fix bug #18083. --- module/task/lang/en.php | 1 + module/task/lang/zh-cn.php | 1 + module/task/model.php | 7 ++++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/module/task/lang/en.php b/module/task/lang/en.php index c0cf60ed5b..2af706c5a5 100644 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -246,6 +246,7 @@ $lang->task->error->finishedDateEmpty = '"Finished Date" should not be empty.'; $lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Started"'; $lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.'; $lang->task->error->date = 'The date should be >= today.'; +$lang->task->error->statusLeft = 'When the task status is %s, "Hours Left" cannot be 0'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index 8f7f05cecd..1c1c1e027a 100644 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -246,6 +246,7 @@ $lang->task->error->finishedDateEmpty = '实际完成不能为空'; $lang->task->error->finishedDateSmall = '实际完成不能小于实际开始'; $lang->task->error->alreadyConsumed = '当前选中的父任务已有消耗。'; $lang->task->error->date = '日期不能大于今天'; +$lang->task->error->statusLeft = '任务状态为%s时,预计剩余不能为0'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/model.php b/module/task/model.php index f524c69262..8ab54e3e4d 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -998,6 +998,12 @@ class taskModel extends model $requiredFields = str_replace(',estimate,', ',', $requiredFields); } + if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && $task->left == 0) + { + dao::$errors[] = sprintf($this->lang->task->error->statusLeft, $this->lang->task->statusList[$task->status]); + return false; + } + $requiredFields = trim($requiredFields, ','); $this->dao->update(TABLE_TASK)->data($task) @@ -1008,7 +1014,6 @@ class taskModel extends model ->checkIF($task->estimate != false, 'estimate', 'float') ->checkIF($task->left != false, 'left', 'float') ->checkIF($task->consumed != false, 'consumed', 'float') - ->checkIF($task->status != 'wait' and empty($teams) and $task->left == 0 and $task->status != 'cancel' and $task->status != 'closed', 'status', 'equal', 'done') ->batchCheckIF($task->status == 'wait' or $task->status == 'doing', 'finishedBy, finishedDate,canceledBy, canceledDate, closedBy, closedDate, closedReason', 'empty') From 3e70b882104a049062b9d77dddd2acc7392f5f57 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Tue, 29 Mar 2022 14:49:01 +0800 Subject: [PATCH 02/20] * Fix bug #18270. --- module/execution/model.php | 8 -------- module/execution/view/create.html.php | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/module/execution/model.php b/module/execution/model.php index cd6c878de0..6c94f5653f 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -305,14 +305,6 @@ class executionModel extends model $type = 'sprint'; if($project) $type = zget($this->config->execution->modelList, $project->model, 'sprint'); - /* If the execution model is a stage, determine whether the product is linked. */ - $products = array_filter($this->post->products); - if(empty($products)) - { - dao::$errors['message'][] = $this->lang->execution->noLinkProduct; - return false; - } - $this->config->execution->create->requiredFields .= ',project'; } diff --git a/module/execution/view/create.html.php b/module/execution/view/create.html.php index fef68cc881..cce35666a4 100644 --- a/module/execution/view/create.html.php +++ b/module/execution/view/create.html.php @@ -144,8 +144,8 @@
-
- +
+
From e97eab6f68e4cccecde3c4f8f64a3d51ecec1345 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Wed, 30 Mar 2022 08:50:14 +0800 Subject: [PATCH 03/20] * Fix bug #18083. --- module/task/lang/en.php | 3 ++- module/task/lang/zh-cn.php | 3 ++- module/task/model.php | 8 ++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/module/task/lang/en.php b/module/task/lang/en.php index 2af706c5a5..305362d6ea 100644 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -246,7 +246,8 @@ $lang->task->error->finishedDateEmpty = '"Finished Date" should not be empty.'; $lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Started"'; $lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.'; $lang->task->error->date = 'The date should be >= today.'; -$lang->task->error->statusLeft = 'When the task status is %s, "Hours Left" cannot be 0'; +$lang->task->error->leftEmpty = 'When the task status is %s, "Hours Left" cannot be 0'; +$lang->task->error->leftEmptyAB = 'task#%sWhen the task status is %s, "Hours Left" cannot be 0'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index 1c1c1e027a..d8234cc45f 100644 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -246,7 +246,8 @@ $lang->task->error->finishedDateEmpty = '实际完成不能为空'; $lang->task->error->finishedDateSmall = '实际完成不能小于实际开始'; $lang->task->error->alreadyConsumed = '当前选中的父任务已有消耗。'; $lang->task->error->date = '日期不能大于今天'; -$lang->task->error->statusLeft = '任务状态为%s时,预计剩余不能为0'; +$lang->task->error->leftEmpty = '任务状态为%s时,预计剩余不能为0'; +$lang->task->error->leftEmptyAB = 'task#%s任务状态为%s时,预计剩余不能为0'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/model.php b/module/task/model.php index 8ab54e3e4d..7416b93276 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -1000,7 +1000,7 @@ class taskModel extends model if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && $task->left == 0) { - dao::$errors[] = sprintf($this->lang->task->error->statusLeft, $this->lang->task->statusList[$task->status]); + dao::$errors[] = sprintf($this->lang->task->error->leftEmpty, $this->lang->task->statusList[$task->status]); return false; } @@ -1280,6 +1280,11 @@ class taskModel extends model foreach($tasks as $taskID => $task) { + if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && $task->parent > 0 && $task->consumed != 0) + { + dao::$errors[] = sprintf($this->lang->task->error->leftEmptyAB, $taskID, $this->lang->task->statusList[$task->status]); + return false; + } $oldTask = $oldTasks[$taskID]; $this->dao->update(TABLE_TASK)->data($task) ->autoCheck() @@ -1287,7 +1292,6 @@ class taskModel extends model ->checkIF($task->estimate != false, 'estimate', 'float') ->checkIF($task->consumed != false, 'consumed', 'float') ->checkIF($task->left != false, 'left', 'float') - ->checkIF($task->parent > 0 and $task->left == 0 and $task->status != 'cancel' and $task->status != 'closed' and $task->status != 'wait' and $task->consumed != 0, 'status', 'equal', 'done') ->batchCheckIF($task->status == 'wait' or $task->status == 'doing', 'finishedBy, finishedDate,canceledBy, canceledDate, closedBy, closedDate, closedReason', 'empty') From a42d621269b7d04c4b539b108e68b28f9869226c Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Wed, 30 Mar 2022 09:13:13 +0800 Subject: [PATCH 04/20] * Fix bug #18083. --- module/task/lang/en.php | 2 +- module/task/view/batchedit.html.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/task/lang/en.php b/module/task/lang/en.php index 305362d6ea..3a1c97a3f9 100644 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -246,7 +246,7 @@ $lang->task->error->finishedDateEmpty = '"Finished Date" should not be empty.'; $lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Started"'; $lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.'; $lang->task->error->date = 'The date should be >= today.'; -$lang->task->error->leftEmpty = 'When the task status is %s, "Hours Left" cannot be 0'; +$lang->task->error->leftEmpty = 'When the task status is %s, "Hours Left" cannot be 0'; $lang->task->error->leftEmptyAB = 'task#%sWhen the task status is %s, "Hours Left" cannot be 0'; /* Report. */ diff --git a/module/task/view/batchedit.html.php b/module/task/view/batchedit.html.php index 2c1de060e9..ecfdc202fa 100755 --- a/module/task/view/batchedit.html.php +++ b/module/task/view/batchedit.html.php @@ -127,7 +127,7 @@ js::set('dittoNotice', $dittoNotice); ' style='overflow:visible'>module, "class='form-control chosen'")?> ' style='overflow:visible'>assignedTo, "class='form-control chosen' {$disableAssignedTo}");?> type, "class='form-control'");?> - >status, "class='form-control'");?> + >status, "class='form-control' {$disableHour}");?> >estStarted) ? '' : $tasks[$taskID]->estStarted, "class='form-control text-center form-date'");?> >deadline) ? '' : $tasks[$taskID]->deadline, "class='form-control text-center form-date'");?> >pri, "class='form-control'");?> From c7e76c117651a8f8187041c92ddd2069757c8433 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Wed, 30 Mar 2022 13:05:59 +0800 Subject: [PATCH 05/20] * Fix bug #18270. --- module/execution/model.php | 8 +------- module/execution/view/edit.html.php | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/module/execution/model.php b/module/execution/model.php index 6c94f5653f..9ea9d26e07 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -460,13 +460,7 @@ class executionModel extends model dao::$errors['days'] = sprintf($this->lang->project->workdaysExceed, $workdays); return false; } - $products = array_filter($this->post->products); - $noLinkTip = $oldExecution->type != 'kanban' ? $this->lang->execution->noLinkProduct : $this->lang->execution->kanbanNoLinkProduct; - if(empty($products)) - { - dao::$errors['message'][] = $noLinkTip; - return false; - } + /* Get the data from the post. */ $execution = fixer::input('post') ->setDefault('lastEditedBy', $this->app->user->account) diff --git a/module/execution/view/edit.html.php b/module/execution/view/edit.html.php index aba139060f..56ead0a3f4 100644 --- a/module/execution/view/edit.html.php +++ b/module/execution/view/edit.html.php @@ -141,7 +141,7 @@ type != 'normal' and isset($branchGroups[$product->id]);?> id] as $branchID => $branch):?>
-
"> +
id, "class='form-control chosen' $class onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='". $product->type ."'");?> id], $branchID, "class='form-control chosen' $class onchange=\"loadPlans('#products{$i}', this.value)\" data-last='" . $branchID . "'");?> @@ -159,7 +159,7 @@
- +
From 751fb8c117339c1c166f3710712ff2bc41e8ce8f Mon Sep 17 00:00:00 2001 From: songchenxuan Date: Wed, 30 Mar 2022 15:51:39 +0800 Subject: [PATCH 06/20] * Fix taskbatchcreate API bug . --- api/v1/entries/taskbatchcreate.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/api/v1/entries/taskbatchcreate.php b/api/v1/entries/taskbatchcreate.php index 6a65f4c898..d12c273085 100644 --- a/api/v1/entries/taskbatchcreate.php +++ b/api/v1/entries/taskbatchcreate.php @@ -43,21 +43,23 @@ class taskBatchCreateEntry extends Entry $desc = array(); $pri = array(); $stories = array(); + $number = 1; foreach($this->request('tasks') as $task) { if(!isset($task->name) or !isset($task->type)) return $this->send400('Task must have name and type.'); - $modules[] = isset($task->module) ? $task->module : $moduleID; - $parents[] = isset($task->parent) ? $task->parent : $taskID; - $names[] = $task->name; - $colors[] = isset($task->color) ? $task->color : ''; - $types[] = $task->type; - $estimates[] = isset($task->estimate) ? $task->estimate : 0; - $estStarted[] = isset($task->estStarted) ? $task->estStarted : 0; - $deadlines[] = isset($task->deadline) ? $task->deadline : null; - $desc[] = isset($task->desc) ? $task->desc : ''; - $pri[] = isset($task->pri) ? $task->pri : 0; - $stories[] = isset($task->story) ? $task->story : $storyID; + $modules[$number] = isset($task->module) ? $task->module : $moduleID; + $parents[$number] = isset($task->parent) ? $task->parent : $taskID; + $names[$number] = $task->name; + $colors[$number] = isset($task->color) ? $task->color : ''; + $types[$number] = $task->type; + $estimates[$number] = isset($task->estimate) ? $task->estimate : 0; + $estStarted[$number] = isset($task->estStarted) ? $task->estStarted : 0; + $deadlines[$number] = isset($task->deadline) ? $task->deadline : null; + $desc[$number] = isset($task->desc) ? $task->desc : ''; + $pri[$number] = isset($task->pri) ? $task->pri : 0; + $stories[$number] = isset($task->story) ? $task->story : $storyID; + $number += 1; } $this->setPost('module', $modules); $this->setPost('parent', $parents); From 344b65b9388011bb8dd1ec8a10a164f4116befc4 Mon Sep 17 00:00:00 2001 From: songchenxuan Date: Wed, 30 Mar 2022 16:07:15 +0800 Subject: [PATCH 07/20] * Fix API bug. --- api/v1/entries/taskbatchcreate.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/v1/entries/taskbatchcreate.php b/api/v1/entries/taskbatchcreate.php index d12c273085..92fa3d2c47 100644 --- a/api/v1/entries/taskbatchcreate.php +++ b/api/v1/entries/taskbatchcreate.php @@ -43,9 +43,9 @@ class taskBatchCreateEntry extends Entry $desc = array(); $pri = array(); $stories = array(); - $number = 1; - foreach($this->request('tasks') as $task) + foreach($this->request('tasks') as $key => $task) { + $number = $key + 1; if(!isset($task->name) or !isset($task->type)) return $this->send400('Task must have name and type.'); $modules[$number] = isset($task->module) ? $task->module : $moduleID; @@ -59,7 +59,6 @@ class taskBatchCreateEntry extends Entry $desc[$number] = isset($task->desc) ? $task->desc : ''; $pri[$number] = isset($task->pri) ? $task->pri : 0; $stories[$number] = isset($task->story) ? $task->story : $storyID; - $number += 1; } $this->setPost('module', $modules); $this->setPost('parent', $parents); From 74d2ed5ea6b47a57959e44ce9e1d3b7ae8c2c285 Mon Sep 17 00:00:00 2001 From: liyuchun Date: Wed, 30 Mar 2022 17:01:15 +0800 Subject: [PATCH 08/20] * Fix bug #11348. --- module/task/model.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/module/task/model.php b/module/task/model.php index f524c69262..e9f1066081 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -35,6 +35,30 @@ class taskModel extends model if($this->post->selectTestStory) { + /* Check required fields when create test task. */ + foreach($this->post->testStory as $i => $storyID) + { + if(empty($storyID)) continue; + + $task = new stdclass(); + $task->pri = $this->post->testPri[$i]; + $task->estStarted = $this->post->testEstStarted[$i]; + $task->deadline = $this->post->testDeadline[$i]; + $task->assignedTo = $this->post->testAssignedTo[$i]; + $task->estimate = $this->post->testEstimate[$i]; + $task->left = $this->post->testEstimate[$i]; + + $this->dao->insert(TABLE_TASK)->data($task)->batchCheck($requiredFields, 'notempty'); + if(dao::isError()) + { + foreach(dao::getError() as $field => $error) + { + dao::$errors[] = $error; + return false; + } + } + } + $requiredFields = str_replace(",estimate,", ',', "$requiredFields"); $requiredFields = str_replace(",story,", ',', "$requiredFields"); $requiredFields = str_replace(",estStarted,", ',', "$requiredFields"); From 0983c30e8dabd798d146e8fa445323d41d743376 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Wed, 30 Mar 2022 17:26:17 +0800 Subject: [PATCH 09/20] * Fix bug#18083. --- module/task/control.php | 2 +- module/task/lang/en.php | 2 +- module/task/lang/zh-cn.php | 2 +- module/task/model.php | 37 ++++++++++++++++++++++++------------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/module/task/control.php b/module/task/control.php index f869833fb1..d9711ecb04 100644 --- a/module/task/control.php +++ b/module/task/control.php @@ -562,7 +562,7 @@ class task extends control if($this->post->names) { $allChanges = $this->task->batchUpdate(); - if(dao::isError()) return print(js::error(dao::getError())); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); if(!empty($allChanges)) { diff --git a/module/task/lang/en.php b/module/task/lang/en.php index 3a1c97a3f9..4c7464d2d1 100644 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -247,7 +247,7 @@ $lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Start $lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.'; $lang->task->error->date = 'The date should be >= today.'; $lang->task->error->leftEmpty = 'When the task status is %s, "Hours Left" cannot be 0'; -$lang->task->error->leftEmptyAB = 'task#%sWhen the task status is %s, "Hours Left" cannot be 0'; +$lang->task->error->leftEmptyAB = 'task#%sWhen the task status is %s, "Left" cannot be 0'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index d8234cc45f..b289c2171b 100644 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -247,7 +247,7 @@ $lang->task->error->finishedDateSmall = '实际完成不能小于实际开始'; $lang->task->error->alreadyConsumed = '当前选中的父任务已有消耗。'; $lang->task->error->date = '日期不能大于今天'; $lang->task->error->leftEmpty = '任务状态为%s时,预计剩余不能为0'; -$lang->task->error->leftEmptyAB = 'task#%s任务状态为%s时,预计剩余不能为0'; +$lang->task->error->leftEmptyAB = 'task#%s任务状态为%s时,剩余不能为0'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/model.php b/module/task/model.php index 7416b93276..4ffc3f2522 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -998,7 +998,7 @@ class taskModel extends model $requiredFields = str_replace(',estimate,', ',', $requiredFields); } - if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && $task->left == 0) + if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && empty($task->left)) { dao::$errors[] = sprintf($this->lang->task->error->leftEmpty, $this->lang->task->statusList[$task->status]); return false; @@ -1118,7 +1118,6 @@ class taskModel extends model { if(isset($data->modules[$taskID]) and ($data->modules[$taskID] == 'ditto')) $data->modules[$taskID] = isset($prev['module']) ? $prev['module'] : 0; if($data->types[$taskID] == 'ditto') $data->types[$taskID] = isset($prev['type']) ? $prev['type'] : ''; - if($data->statuses[$taskID] == 'ditto') $data->statuses[$taskID] = isset($prev['status']) ? $prev['status'] : ''; if($data->assignedTos[$taskID] == 'ditto') $data->assignedTos[$taskID] = isset($prev['assignedTo']) ? $prev['assignedTo'] : ''; if($data->pris[$taskID] == 'ditto') $data->pris[$taskID] = isset($prev['pri']) ? $prev['pri'] : 0; if($data->finishedBys[$taskID] == 'ditto') $data->finishedBys[$taskID] = isset($prev['finishedBy']) ? $prev['finishedBy'] : ''; @@ -1129,7 +1128,6 @@ class taskModel extends model $prev['module'] = $data->modules[$taskID]; $prev['type'] = $data->types[$taskID]; - $prev['status'] = $data->statuses[$taskID]; $prev['assignedTo'] = $data->assignedTos[$taskID]; $prev['pri'] = $data->pris[$taskID]; $prev['finishedBy'] = $data->finishedBys[$taskID]; @@ -1150,7 +1148,7 @@ class taskModel extends model $task->name = $data->names[$taskID]; $task->module = isset($data->modules[$taskID]) ? $data->modules[$taskID] : 0; $task->type = $data->types[$taskID]; - $task->status = $data->statuses[$taskID]; + $task->status = isset($data->statuses[$taskID]) ? $data->statuses[$taskID] : $oldTask->status; $task->assignedTo = $task->status == 'closed' ? 'closed' : $data->assignedTos[$taskID]; $task->pri = $data->pris[$taskID]; $task->estimate = isset($data->estimates[$taskID]) ? $data->estimates[$taskID] : $oldTask->estimate; @@ -1185,11 +1183,12 @@ class taskModel extends model if($message) return print(js::alert($message)); } - if($data->consumeds[$taskID]) + if(isset($data->consumeds[$taskID])) { if($data->consumeds[$taskID] < 0) { - echo js::alert(sprintf($this->lang->task->error->consumed, $taskID)); + dao::$errors[] = sprintf($this->lang->task->error->consumed, $taskID); + return false; } else { @@ -1261,9 +1260,19 @@ class taskModel extends model /* Check field not empty. */ foreach($tasks as $taskID => $task) { - if($task->status == 'done' and $task->consumed == false) return print(js::error('task#' . $taskID . sprintf($this->lang->error->notempty, $this->lang->task->consumedThisTime))); if($task->status == 'cancel') continue; - if(!empty($task->deadline) and $task->estStarted > $task->deadline) return print(js::error('task#' . $taskID . $this->lang->task->error->deadlineSmall)); + if($task->status == 'done' and $task->consumed == false) + { + dao::$errors[] = 'task#' . $taskID . sprintf($this->lang->error->notempty, $this->lang->task->consumedThisTime); + return false; + } + + if(!empty($task->deadline) and $task->estStarted > $task->deadline) + { + dao::$errors[] = 'task#' . $taskID . $this->lang->task->error->deadlineSmall; + return false; + } + foreach(explode(',', $this->config->task->edit->requiredFields) as $field) { $field = trim($field); @@ -1280,11 +1289,12 @@ class taskModel extends model foreach($tasks as $taskID => $task) { - if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && $task->parent > 0 && $task->consumed != 0) + if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && $task->parent >= 0 && empty($task->left)) { dao::$errors[] = sprintf($this->lang->task->error->leftEmptyAB, $taskID, $this->lang->task->statusList[$task->status]); return false; } + $oldTask = $oldTasks[$taskID]; $this->dao->update(TABLE_TASK)->data($task) ->autoCheck() @@ -1303,6 +1313,11 @@ class taskModel extends model ->batchCheckIF($task->closedReason == 'cancel', 'finishedBy, finishedDate', 'empty') ->where('id')->eq((int)$taskID) ->exec(); + if(dao::isError()) + { + dao::$errors[] = 'task#' . $taskID . dao::getError(true); + return false; + } if($task->status == 'done' and $task->closedReason) $this->dao->update(TABLE_TASK)->set('status')->eq('closed')->where('id')->eq($taskID)->exec(); @@ -1333,10 +1348,6 @@ class taskModel extends model if($task->status != $oldTask->status) $this->loadModel('kanban')->updateLane($oldTask->execution, 'task', $oldTask->id); $allChanges[$taskID] = common::createChanges($oldTask, $task); } - else - { - return print(js::error('task#' . $taskID . dao::getError(true))); - } } if(!dao::isError()) $this->loadModel('score')->create('ajax', 'batchEdit'); return $allChanges; From af7f9bd8e3a74f6f127de683a5335aa58c0af4e6 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Wed, 30 Mar 2022 20:22:17 +0800 Subject: [PATCH 10/20] * Fix bug#18270. --- module/execution/control.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index d4ef2cbb54..5d47dfe10f 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -2549,13 +2549,6 @@ class execution extends control if(!empty($_POST)) { - /* Get executionType and determine whether a product is linked with the stage. */ - $executionType = $this->dao->findById($executionID)->from(TABLE_EXECUTION)->fetch('type'); - if($executionType == 'stage') - { - if(!isset($_POST['products'])) return print(js::alert($this->lang->execution->noLinkProduct) . js::locate($this->createLink('execution', 'manageProducts', "executionID=$executionID&from=$from"))); - } - $oldProducts = $this->product->getProducts($executionID); if($from == 'buildCreate' && $this->session->buildCreate) $browseExecutionLink = $this->session->buildCreate; From 123aec72c47fda266c1a032c380da705d2b15ee3 Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Thu, 31 Mar 2022 08:42:36 +0800 Subject: [PATCH 11/20] * bug #18424, optimize d-n-d UI for kanban, finish drag action when mouse leave document. --- module/execution/js/kanban.js | 1 + module/kanban/js/view.js | 1 + www/js/zui/min.js | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 054986c08c..60da0e0797 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -1338,6 +1338,7 @@ $(function() { selector: '.region, .kanban-board, .kanban-lane', trigger: '.region.sort > .region-header, .kanban-board.sort > .kanban-header > .kanban-group-header, .kanban-lane.sort > .kanban-lane-name', + dropOnMouseleave: true, container: function($ele) { return $ele.parent(); diff --git a/module/kanban/js/view.js b/module/kanban/js/view.js index d7def024ed..89800ac5d2 100644 --- a/module/kanban/js/view.js +++ b/module/kanban/js/view.js @@ -1388,6 +1388,7 @@ function initSortable() { selector: '.region, .kanban-board, .kanban-lane, .kanban-col', trigger: '.region.sort > .region-header, .kanban-board.sort > .kanban-header > .kanban-group-header, .kanban-lane.sort > .kanban-lane-name, .kanban-header-col.sort', + dropOnMouseleave: true, container: function($ele) { return $ele.parent(); diff --git a/www/js/zui/min.js b/www/js/zui/min.js index beb9092f34..49def157ce 100644 --- a/www/js/zui/min.js +++ b/www/js/zui/min.js @@ -1,5 +1,5 @@ /*! - * ZUI: ZUI for Zentao - v1.10.0 - 2022-03-28 + * ZUI: ZUI for Zentao - v1.10.0 - 2022-03-30 * http://openzui.com * GitHub: https://github.com/easysoft/zui.git * Copyright (c) 2022 cnezsoft.com; Licensed MIT @@ -42,7 +42,7 @@ Copyright (c) 2011 Harvest http://getharvest.com MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */ function(){var t,e,i,n,o,a={}.hasOwnProperty,s=function(t,e){function i(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return i.prototype=e.prototype,t.prototype=new i,t.__super__=e.prototype,t},r={zh_cn:{no_results_text:"没有找到"},zh_tw:{no_results_text:"沒有找到"},en:{no_results_text:"No results match"}},l={};n=function(){function e(){this.options_index=0,this.parsed=[]}return e.prototype.add_node=function(t){return"OPTGROUP"===t.nodeName.toUpperCase()?this.add_group(t):this.add_option(t)},e.prototype.add_group=function(e){var i,n,o,a,s,r;for(i=this.parsed.length,this.parsed.push({array_index:i,group:!0,label:this.escapeExpression(e.label),children:0,disabled:e.disabled,title:e.title,search_keys:t.trim(e.getAttribute("data-keys")||"").replace(/,/g," ")}),s=e.childNodes,r=[],o=0,a=s.length;o\"\'\`]/.test(t)?(e={"<":"<",">":">",'"':""","'":"'","`":"`"},i=/&(?!\w+;)|[\<\>\"\'\`]/g,t.replace(i,function(t){return e[t]||"&"})):t},e}(),n.select_to_array=function(t){var e,i,o,a,s;for(i=new n,s=t.childNodes,o=0,a=s.length;o0?(e=document.createElement("li"),e.className="group-result",e.title=t.title,e.innerHTML=t.search_text,this.outerHTML(e)):""},e.prototype.results_update_field=function(){this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing&&(this.winnow_results(),this.autoResizeDrop())},e.prototype.reset_single_select_options=function(){var t,e,i,n,o;for(n=this.results_data,o=[],e=0,i=n.length;e"+i.search_text.substr(l+r.length),i.search_text=c.substr(0,l)+""+c.substr(l)):i.search_keys_match&&i.search_keys.length&&(l=i.search_keys.search(h),c=i.search_keys.substr(0,l+r.length)+""+i.search_keys.substr(l+r.length),i.search_text+='  '+c.substr(0,l)+""+c.substr(l)+""),null!=s&&(s.group_match=!0)):null!=i.group_array_index&&this.results_data[i.group_array_index].search_match&&(i.search_match=!0)));return this.result_clear_highlight(),a<1&&r.length?(this.update_results_content(""),this.no_results(r)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight(t))},e.prototype.search_string_match=function(t,e){var i,n,o,a;if(e.test(t))return!0;if(this.enable_split_word_search&&(t.indexOf(" ")>=0||0===t.indexOf("["))&&(n=t.replace(/\[|\]/g,"").split(" "),n.length))for(o=0,a=n.length;o0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(t.preventDefault(),this.results_showing)return this.result_select(t);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},e.prototype.clipboard_event_checker=function(t){var e=this;return setTimeout(function(){return e.results_search()},50)},e.prototype.container_width=function(){return null!=this.options.width?this.options.width:this.form_field&&this.form_field.classList&&this.form_field.classList.contains("form-control")?"100%":""+this.form_field.offsetWidth+"px"},e.prototype.include_option_in_results=function(t){return!(this.is_multiple&&!this.display_selected_options&&t.selected)&&(!(!this.display_disabled_options&&t.disabled)&&!t.empty)},e.prototype.search_results_touchstart=function(t){return this.touch_started=!0,this.search_results_mouseover(t)},e.prototype.search_results_touchmove=function(t){return this.touch_started=!1,this.search_results_mouseout(t)},e.prototype.search_results_touchend=function(t){if(this.touch_started)return this.search_results_mouseup(t)},e.prototype.outerHTML=function(t){var e;return t.outerHTML?t.outerHTML:(e=document.createElement("div"),e.appendChild(t),e.innerHTML)},e.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:!/iP(od|hone)/i.test(window.navigator.userAgent)&&(!/Android/i.test(window.navigator.userAgent)||!/Mobile/i.test(window.navigator.userAgent))},e.default_multiple_text="",e.default_single_text="",e.default_no_result_text="No results match",e}(),t=jQuery,t.fn.extend({chosen:function(n){return e.browser_is_supported()?this.each(function(e){var o=t(this),a=o.data("chosen");"destroy"===n&&a?a.destroy():a||o.data("chosen",new i(this,t.extend({},o.data(),n)))}):this}}),i=function(e){function i(){return o=i.__super__.constructor.apply(this,arguments)}return s(i,e),i.prototype.setup=function(){return this.form_field_jq=t(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},i.prototype.set_up_html=function(){var e,i;e=["chosen-container"],e.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&e.push(this.form_field.className),this.is_rtl&&e.push("chosen-rtl");var n=this.form_field.getAttribute("data-css-class");return n&&e.push(n),i={"class":e.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(i.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=t("
",i),this.is_multiple?this.container.html('
    '):(this.container.html(''+this.default_text+'
      '),this.compact_search?this.container.addClass("chosen-compact").find(".chosen-search").appendTo(this.container.find(".chosen-single")):this.container.find(".chosen-search").prependTo(this.container.find(".chosen-drop")),this.options.highlight_selected!==!1&&this.container.addClass("chosen-highlight-selected")),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.options.drop_width&&this.dropdown.css("width",this.options.drop_width).addClass("chosen-drop-size-limited"),this.max_drop_width&&this.dropdown.addClass("chosen-auto-max-width"),this.options.no_wrap&&this.dropdown.addClass("chosen-no-wrap"),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},i.prototype.register_observers=function(){var t=this;return this.container.bind("mousedown.chosen",function(e){t.container_mousedown(e)}),this.container.bind("mouseup.chosen",function(e){t.container_mouseup(e)}),this.container.bind("mouseenter.chosen",function(e){t.mouse_enter(e)}),this.container.bind("mouseleave.chosen",function(e){t.mouse_leave(e)}),this.search_results.bind("mouseup.chosen",function(e){t.search_results_mouseup(e)}),this.search_results.bind("mouseover.chosen",function(e){t.search_results_mouseover(e)}),this.search_results.bind("mouseout.chosen",function(e){t.search_results_mouseout(e)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(e){t.search_results_mousewheel(e)}),this.search_results.bind("touchstart.chosen",function(e){t.search_results_touchstart(e)}),this.search_results.bind("touchmove.chosen",function(e){t.search_results_touchmove(e)}),this.search_results.bind("touchend.chosen",function(e){t.search_results_touchend(e)}),this.form_field_jq.bind("chosen:updated.chosen",function(e){t.results_update_field(e)}),this.form_field_jq.bind("chosen:activate.chosen",function(e){t.activate_field(e)}),this.form_field_jq.bind("chosen:open.chosen",function(e){t.container_mousedown(e)}),this.form_field_jq.bind("chosen:close.chosen",function(e){t.input_blur(e)}),this.search_field.bind("blur.chosen",function(e){t.input_blur(e)}),this.search_field.bind("keyup.chosen",function(e){t.keyup_checker(e)}),this.search_field.bind("keydown.chosen",function(e){t.keydown_checker(e)}),this.search_field.bind("focus.chosen",function(e){t.input_focus(e)}),this.search_field.bind("cut.chosen",function(e){t.clipboard_event_checker(e)}),this.search_field.bind("paste.chosen",function(e){t.clipboard_event_checker(e)}),this.is_multiple?this.search_choices.bind("click.chosen",function(e){t.choices_click(e)}):this.container.bind("click.chosen",function(t){t.preventDefault()})},i.prototype.destroy=function(){return t(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},i.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},i.prototype.container_mousedown=function(e){if(!this.is_disabled&&(e&&"mousedown"===e.type&&!this.results_showing&&e.preventDefault(),null==e||!t(e.target).hasClass("search-choice-close")))return this.active_field?this.is_multiple||!e||t(e.target)[0]!==this.selected_item[0]&&!t(e.target).parents("a.chosen-single").length||(e.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),t(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field()},i.prototype.container_mouseup=function(t){if("ABBR"===t.target.nodeName&&!this.is_disabled)return this.results_reset(t)},i.prototype.search_results_mousewheel=function(t){var e;if(t.originalEvent&&(e=-t.originalEvent.wheelDelta||t.originalEvent.detail),null!=e)return t.preventDefault(),"DOMMouseScroll"===t.type&&(e=40*e),this.search_results.scrollTop(e+this.search_results.scrollTop())},i.prototype.blur_test=function(t){if(!this.active_field&&this.container.hasClass("chosen-container-active"))return this.close_field()},i.prototype.close_field=function(){return t(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},i.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},i.prototype.test_active_click=function(e){var i;return i=t(e.target).closest(".chosen-container"),i.length&&this.container[0]===i[0]?this.active_field=!0:this.close_field()},i.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=n.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch"),this.container.removeClass("chosen-with-search")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"),this.container.addClass("chosen-with-search"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},i.prototype.result_do_highlight=function(t,e){if(t.length){var i,n,o,a,s,r,l=-1;this.result_clear_highlight(),this.result_highlight=t,this.result_highlight.addClass("highlighted"),o=parseInt(this.search_results.css("maxHeight"),10),r=this.result_highlight.outerHeight(),s=this.search_results.scrollTop(),a=o+s,n=this.result_highlight.position().top+this.search_results.scrollTop(),i=n+r,this.middle_highlight&&(e||"always"===this.middle_highlight)?l=Math.min(n-r,Math.max(0,n-(o-r)/2)):i>=a?l=i-o>0?i-o:0:n-1?this.search_results.scrollTop(l):this.result_highlight.scrollIntoView&&this.result_highlight.scrollIntoView()}},i.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},i.prototype.results_show=function(){var e=this;if(e.is_multiple&&e.max_selected_options<=e.choices_count())return e.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1;e.results_showing=!0,e.search_field.focus(),e.search_field.val(e.search_field.val()),e.container.addClass("chosen-with-drop"),e.winnow_results(1);var i=e.drop_direction;if("function"==typeof i&&(i=i.call(this)),"auto"===i)if(e.drop_directionFixed)i=e.drop_directionFixed;else{var n=e.container.find(".chosen-drop"),o=n.outerHeight();e.drop_item_height&&o.active-result").length*e.drop_item_height));var a=e.container.offset();a.top+o+30>t(window).height()+t(window).scrollTop()&&(i="up"),e.drop_directionFixed=i}return e.container.toggleClass("chosen-up","up"===i),e.autoResizeDrop(),e.form_field_jq.trigger("chosen:showing_dropdown",{chosen:e})},i.prototype.autoResizeDrop=function(){var e=this,i=e.max_drop_width;if(i){var n=e.container.find(".chosen-drop");n.removeClass("in");var o=0,a=n.find(".chosen-results"),s=a.children("li"),r=parseFloat(a.css("padding-left").replace("px","")),l=parseFloat(a.css("padding-right").replace("px","")),c=(isNaN(r)?0:r)+(isNaN(l)?0:l);s.each(function(){o=Math.max(o,t(this).outerWidth())}),n.css("width",Math.min(o+c+20,i)),e.fixDropWidthTimer=setTimeout(function(){e.fixDropWidthTimer=null,n.addClass("in"),e.winnow_results_set_highlight(1)},50)}},i.prototype.update_results_content=function(t){return this.search_results.html(t)},i.prototype.results_hide=function(){var t=this;return t.fixDropWidthTimer&&(clearTimeout(t.fixDropWidthTimer),t.fixDropWidthTimer=null),t.results_showing&&(t.result_clear_highlight(),t.container.removeClass("chosen-with-drop"),t.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:t}),t.drop_directionFixed=0),t.results_showing=!1},i.prototype.set_tab_index=function(t){var e;if(this.form_field.tabIndex)return e=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=e},i.prototype.set_label_behavior=function(){var e=this;if(this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=t("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0)return this.form_field_label.bind("click.chosen",function(t){return e.is_multiple?e.container_mousedown(t):e.activate_field()})},i.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},i.prototype.search_results_mouseup=function(e){var i;if(i=t(e.target).hasClass("active-result")?t(e.target):t(e.target).parents(".active-result").first(),i.length)return this.result_highlight=i,this.result_select(e),this.search_field.focus()},i.prototype.search_results_mouseover=function(e){var i;if(i=t(e.target).hasClass("active-result")?t(e.target):t(e.target).parents(".active-result").first())return this.result_do_highlight(i)},i.prototype.search_results_mouseout=function(e){if(t(e.target).hasClass("active-result"))return this.result_clear_highlight()},i.prototype.choice_build=function(e){var i,n,o=this;return i=t("
    • ",{"class":"search-choice"}).html(""+e.html+""),e.disabled?i.addClass("search-choice-disabled"):(n=t("",{"class":"search-choice-close","data-option-array-index":e.array_index}),n.bind("click.chosen",function(t){return o.choice_destroy_link_click(t)}),i.append(n)),this.search_container.before(i)},i.prototype.choice_destroy_link_click=function(e){if(e.preventDefault(),e.stopPropagation(),!this.is_disabled)return this.choice_destroy(t(e.target))},i.prototype.choice_destroy=function(t){if(this.result_deselect(t[0].getAttribute("data-option-array-index")))return this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),t.parents("li").first().remove(),this.search_field_scale()},i.prototype.results_reset=function(){var t=this.form_field_jq.val();this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup();var e=this.form_field_jq.val(),i={selected:e};if(t===e||e.length||(i.deselected=t),this.form_field_jq.trigger("change",i),this.sync_sort_field(),this.active_field)return this.results_hide()},i.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},i.prototype.result_select=function(t){var e,i;if(this.result_highlight)return e=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?e.removeClass("active-result"):this.reset_single_select_options(),i=this.results_data[e[0].getAttribute("data-option-array-index")],i.selected=!0,this.form_field.options[i.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(i):this.single_set_selected_text(i.text),(t.metaKey||t.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&(this.form_field_jq.trigger("change",{selected:this.form_field.options[i.options_index].value}),this.sync_sort_field()),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())},i.prototype.single_set_selected_text=function(t){return null==t&&(t=this.default_text),t===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.compact_search&&this.search_field.attr("placeholder",t),this.selected_item.find("span").attr("title",t).text(t)},i.prototype.sync_sort_field=function(){var e=this;if(e.is_multiple&&e.sort_field){var i=t(e.sort_field);if(!i.length)return;var n=[];e.search_choices.find("li.search-choice").each(function(){var i=t(this),o=i.children(".search-choice-close").first().data("optionArrayIndex"),a=e.results_data[o];a&&a.selected&&n.push(a.value)}),i.val(n.join(e.sort_value_splitter)).trigger("change")}},i.prototype.result_deselect=function(t){var e;return e=this.results_data[t],!this.form_field.options[e.options_index].disabled&&(e.selected=!1,this.form_field.options[e.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[e.options_index].value}),this.sync_sort_field(),this.search_field_scale(),!0)},i.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect)return this.selected_item.find("abbr").length||this.selected_item.find("span").first().after(''),this.selected_item.addClass("chosen-single-with-deselect")},i.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":t("
      ").text(t.trim(this.search_field.val())).html()},i.prototype.winnow_results_set_highlight=function(t){var e,i;if(i=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),e=i.length?i.first():this.search_results.find(".active-result").first(),null!=e)return this.result_do_highlight(e,t)},i.prototype.no_results=function(e){var i;return i=t('
    • '+this.results_none_found+' ""
    • '),i.find("span").first().html(e),this.search_results.append(i),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},i.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},i.prototype.keydown_arrow=function(){var t;return this.results_showing&&this.result_highlight?(t=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(t):void 0:this.results_show()},i.prototype.keyup_arrow=function(){var t;return this.results_showing||this.is_multiple?this.result_highlight?(t=this.result_highlight.prevAll("li.active-result"),t.length?this.result_do_highlight(t.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},i.prototype.keydown_backstroke=function(){var t;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(t=this.search_container.siblings("li.search-choice").last(),t.length&&!t.hasClass("search-choice-disabled")?(this.pending_backstroke=t,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},i.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},i.prototype.keydown_checker=function(t){var e,i;switch(e=null!=(i=t.which)?i:t.keyCode,this.search_field_scale(),8!==e&&this.pending_backstroke&&this.clear_backstroke(),e){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(t),this.mouse_on_container=!1;break;case 13:t.preventDefault();break;case 38:t.preventDefault(),this.keyup_arrow();break;case 40:t.preventDefault(),this.keydown_arrow()}},i.prototype.search_field_scale=function(){var e,i,n,o,a,s,r,l,c;if(this.is_multiple){for(n=0,r=0,a="position:absolute; left: -1000px; top: -1000px; display:none;",s=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],l=0,c=s.length;l",{style:a}),e.text(this.search_field.val()),t("body").append(e),r=e.width()+25,e.remove(),i=this.container.outerWidth(),r>i-10&&(r=i-10),this.search_field.css({width:r+"px"})}},i}(e),i.DEFAULTS=l,i.LANGUAGES=r,t.fn.chosen.Constructor=i}.call(this),function(t){"use strict";var e="zui.selectable",i=function(i,n){this.name=e,this.$=t(i),this.id=t.zui.uuid(),this.selectOrder=1,this.selections={},this.getOptions(n),this._init()},n=function(t,e,i){return t>=i.left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height},o=function(t,e){var i=Math.max(t.left,e.left),o=Math.max(t.top,e.top),a=Math.min(t.left+t.width,e.left+e.width),s=Math.min(t.top+t.height,e.top+e.height);return n(i,o,t)&&n(a,s,t)&&n(i,o,e)&&n(a,s,e)};i.DEFAULTS={selector:"li,tr,div",trigger:"",selectClass:"active",rangeStyle:{border:"1px solid "+(t.zui.colorset?t.zui.colorset.primary:"#3280fc"),backgroundColor:t.zui.colorset?new t.zui.Color(t.zui.colorset.primary).fade(20).toCssStr():"rgba(50, 128, 252, 0.2)"},clickBehavior:"toggle",ignoreVal:3,listenClick:!0},i.prototype.getOptions=function(e){this.options=t.extend({},i.DEFAULTS,this.$.data(),e)},i.prototype.select=function(t){this.toggle(t,!0)},i.prototype.unselect=function(t){this.toggle(t,!1)},i.prototype.toggle=function(e,i,n){var o,a,s=this.options.selector,r=this;if(void 0===e)return void this.$.find(s).each(function(){r.toggle(this,i)});if("object"==typeof e?(o=t(e).closest(s),a=o.data("id")):(a=e,o=r.$.find('.selectable-item[data-id="'+a+'"]')),o&&o.length){if(a||(a=t.zui.uuid(),o.attr("data-id",a)),void 0!==i&&null!==i||(i=!r.selections[a]),!!i!=!!r.selections[a]){var l;"function"==typeof n&&(l=n(i)),l!==!0&&(r.selections[a]=!!i&&r.selectOrder++,r.callEvent(i?"select":"unselect",{id:a,selections:r.selections,target:o, -selected:r.getSelectedArray()},r))}r.options.selectClass&&o.toggleClass(r.options.selectClass,i)}},i.prototype.getSelectedArray=function(){var e=[];return t.each(this.selections,function(t,i){i&&e.push(t)}),e},i.prototype.syncSelectionsFromClass=function(){var e=this,i=e.$children=e.$.find(e.options.selector);e.selections={},i.each(function(){var i=t(this);e.selections[i.data("id")]=i.hasClass(e.options.selectClass)})},i.prototype._init=function(){var e,i,n,a,s,r,l,c=this.options,h=this,d=c.ignoreVal,u=!0,p="."+this.name+"."+this.id,f="function"==typeof c.checkFunc?c.checkFunc:null,g="function"==typeof c.rangeFunc?c.rangeFunc:null,m=!1,v=null,y="mousedown"+p,b=function(){a&&h.$children.each(function(){var e=t(this),i=e.offset();i.width=e.outerWidth(),i.height=e.outerHeight();var n=g?g.call(this,a,i):o(a,i);if(f){var s=f.call(h,{intersect:n,target:e,range:a,targetRange:i});s===!0?h.select(e):s===!1&&h.unselect(e)}else n?h.select(e):h.multiKey||h.unselect(e)})},w=function(o){m&&(s=o.pageX,r=o.pageY,a={width:Math.abs(s-e),height:Math.abs(r-i),left:s>e?e:s,top:r>i?i:r},u&&a.width
      ').css(t.extend({zIndex:1060,position:"absolute",top:e,left:i,pointerEvents:"none"},h.options.rangeStyle)).appendTo(t("body")))),n.css(a),clearTimeout(l),l=setTimeout(b,10),u=!1))},x=function(e){t(document).off(p),clearTimeout(v),m&&(m=!1,n&&n.remove(),u||a&&(clearTimeout(l),b(),a=null),h.callEvent("finish",{selections:h.selections,selected:h.getSelectedArray()}),e.preventDefault())},C=function(o){if(m)return x(o);var a=t.zui.getMouseButtonCode(c.mouseButton);if(!(a>-1&&o.button!==a||t(o.target).closest("input,select,textarea,label").length||h.altKey||3===o.which||h.callEvent("start",o)===!1)){var s=h.$children=h.$.find(c.selector);s.addClass("selectable-item");var r=h.multiKey?"multi":c.clickBehavior;if("single"===r&&h.unselect(),c.listenClick&&("multi"===r?h.toggle(o.target):"single"===r?h.select(o.target):"toggle"===r&&h.toggle(o.target,null,function(t){h.unselect()})),h.callEvent("startDrag",o)===!1)return void h.callEvent("finish",{selections:h.selections,selected:h.getSelectedArray()});e=o.pageX,i=o.pageY,n=null,u=!0,m=!0,t(document).on("mousemove"+p,w).on("mouseup"+p,x),v=setTimeout(function(){t(document).on(y,x)},10),o.preventDefault()}},_=c.container&&"default"!==c.container?t(c.container):this.$;c.trigger?_.on(y,c.trigger,C):_.on(y,C),t(document).on("keydown",function(t){var e=t.keyCode;17===e||91==e?h.multiKey=e:18===e&&(h.altKey=!0)}).on("keyup",function(t){h.multiKey=!1,h.altKey=!1})},i.prototype.callEvent=function(e,i){var n=t.Event(e+"."+this.name);this.$.trigger(n,i);var o=n.result,a=this.options[e];return"function"==typeof a&&(o=a.apply(this,Array.isArray(i)?i:[i])),o},t.fn.selectable=function(n){return this.each(function(){var o=t(this),a=o.data(e),s="object"==typeof n&&n;a||o.data(e,a=new i(this,s)),"string"==typeof n&&a[n]()})},t.fn.selectable.Constructor=i,t(function(){t('[data-ride="selectable"]').selectable()})}(jQuery),+function(t,e,i){"use strict";if(!t.fn.droppable)return void console.error("Sortable requires droppable.js");var n="zui.sortable",o={selector:"li,div",dragCssClass:"invisible",sortingClass:"sortable-sorting"},a="order",s=function(e,i){var n=this;n.$=t(e),n.options=t.extend({},o,n.$.data(),i),n.init()};s.DEFAULTS=o,s.NAME=n,s.prototype.init=function(){var e,i=this,n=i.$,o=i.options,s=o.selector,r=o.containerSelector,l=o.sortingClass,c=o.dragCssClass,h=o.targetSelector,d=o.reverse,u=o.moveDirection,p=function(e){e=e||i.getItems(1);var n=e.length;n&&e.each(function(e){var i=d?n-e:e;t(this).attr("data-"+a,i).data(a,i)})};h||p(),n.droppable({handle:o.trigger,target:h?h:r?s+","+r:s,selector:s,container:o.container||n,always:o.always,flex:!0,lazy:o.lazy,canMoveHere:o.canMoveHere,dropToClass:o.dropToClass,before:o.before,nested:!!r,mouseButton:o.mouseButton,noShadow:o.noShadow,stopPropagation:o.stopPropagation,start:function(t){if(c&&t.element.addClass(c),e=!1,i.$element=t.element,!u&&t.targets.length>1){var n=t.targets.eq(0).offset(),o=t.targets.eq(1).offset();u=Math.abs(n.left-o.left)>Math.abs(n.top-o.top)?"h":"v"}p(),i.trigger("start",t)},drag:function(t){if(n.addClass(l),t.isIn){var o=t.element,c=t.target,h=r&&c.is(r);if(h)return void(c.children(s).filter(".dragging").length||(c.append(o),p(b),i.trigger(a,{list:b,element:o})));var f=o.data(a),g=c.data(a);if(f===g)return;var m="h"===u?"left":"top",v=t.mouseOffset[m]-t.lastMouseOffset[m];if(0===v)return;var y=f>g?d:!d;if(v<0&&y||v>0&&!y)return;c[y?"after":"before"](o),e=!0;var b=i.getItems(1);p(b),i.trigger(a,{list:b,element:o})}},finish:function(t){c&&t.element&&t.element.removeClass(c),n.removeClass(l),i.trigger("finish",{list:i.getItems(),element:t.element,changed:e}),i.$element=null}})},s.prototype.destroy=function(){this.$.droppable("destroy"),this.$.data(n,null)},s.prototype.reset=function(){this.destroy(),this.init()},s.prototype.getItems=function(e){var i,n=this,o=n.options.targetSelector;return i=o?"function"==typeof o?o(n.$element,n.$):n.$.find(o):n.$.find(n.options.selector),i=i.not(".drag-shadow"),e?i:i.map(function(){var e=t(this);return{item:e,order:e.data("order")}})},s.prototype.trigger=function(e,i){return t.zui.callEvent(this.options[e],i,this)},t.fn.sortable=function(e){return this.each(function(){var i=t(this),o=i.data(n),a="object"==typeof e&&e;o?"object"==typeof e&&o.reset():i.data(n,o=new s(this,a)),"string"==typeof e&&o[e]()})},t.fn.sortable.Constructor=s}(jQuery,window,document),function(t,e){"use strict";function i(e,i){if("string"==typeof e&&(e="seperator"===e||"divider"===e||"-"===e||"|"===e?{type:"seperator"}:{label:e,id:i}),"seperator"===e.type||"divider"===e.type)return t('
    • ');var n=t("
      ").attr(t.extend({href:e.url||"###","class":e.className,style:e.style},e.attrs)).data("item",e);e.html?e.html===!0?n.html(e.label||e.text):n=t(e.html):n.text(e.label||e.text),e.icon&&n.prepend(''),e.onClick&&n.on("click",e.onClick);var o=t("
    • ").toggleClass("disabled",e.disabled===!0).append(n);return e.items&&o.data("item",e).addClass("dropdown-submenu"),o}function n(e,n,o){var a=o.itemCreator||i,s=typeof e;return"string"===s?e=e.split(","):"function"===s&&(e=e(o)),!!e&&(t.each(e,function(t,e){n.append(a(e,t,o))}),!0)}var o="zui.contextmenu",a={animation:"fade",menuTemplate:'',toggleTrigger:!1,duration:200},s=!1,r={},l="zui-contextmenu-"+t.zui.uuid(),c=0,h=0,d=function(){return t(document).off("mousemove."+o).on("mousemove."+o,function(t){c=t.clientX,h=t.clientY}),r},u=function(e){var i=t("#"+l);return i.length&&i.hasClass("contextmenu-show")&&(!e||(i.data("options")||{}).id===e)},p=null,f=function(e,i){"function"==typeof e&&(i=e,e=null),p&&(clearTimeout(p),p=null);var n=t("#"+l);if(n.length){var o=n.removeClass("contextmenu-show").data("options");if(!e||o.id===e){var a=function(){n.find(".contextmenu-menu").removeClass("open"),o.onHidden&&o.onHidden(),i&&i()};o.onHide&&o.onHide();var s=o.animation;n.find(".contextmenu-menu").removeClass("in"),s?p=setTimeout(a,o.duration):a()}}return r},g=function(i,d,u){t.isPlainObject(i)&&(u=d,d=i,i=d.items),s=!0,d=t.extend({},a,d);var g=t("#"+l);g.length||(g=t('
      ').appendTo("body"));var m=g.find(".contextmenu-menu").empty();m.off("click."+o).on("click."+o,"a,.contextmenu-item",function(e){var i=t(this),n=d.onClickItem&&d.onClickItem(i.data("item"),i,e,d);n!==!1&&f()}).off("mouseenter."+o).on("mouseenter."+o,".dropdown-submenu",function(e){var i=t(this),o=i.data("item"),a=i.children(".dropdown-menu");if(o&&(o.items&&(a.length||(a=t(d.menuTemplate).appendTo(i)),n(o.items,a,d)),i.removeData("item")),a.length){a.removeClass("pull-left").css("top",0);var s=(i[0].getBoundingClientRect(),a[0].getBoundingClientRect()),r=window.innerWidth,l=window.innerHeight;if(s.bottom>l){var c=Math.max(-s.top,l-s.bottom);a.css("top",c)}s.right>r&&a.addClass("pull-left")}}),m.attr("class","contextmenu-menu"+(d.className?" "+d.className:"")),g.attr("class","contextmenu contextmenu-show");var v=d.menuCreator;if(v)m.append(v(i,d));else{m.append(d.menuTemplate);var y=m.children().first(),b=n(i,y,d);if(b===!1)return b}var w=d.animation,x=d.duration;w===!0&&(d.animation=w="fade"),p&&(clearTimeout(p),p=null);var C=function(){m.addClass("in"),d.onShown&&d.onShown(),u&&u()};d.onShow&&d.onShow(),g.data("options",{animation:w,onHide:d.onHide,onHidden:d.onHidden,id:d.id,duration:x});var _=d.x,k=d.y;_===e&&(_=(d.event||d).clientX),_===e&&(_=c),k===e&&(k=(d.event||d).clientY),k===e&&(k=h);var T=window.innerHeight,S=window.innerWidth,y=m.children().first(),D=y.outerWidth(),M=y.outerHeight();if(d.position){var L=d.position({x:_,y:k,width:D,height:M,winHeight:T,winWidth:S},d,m);L&&(_=L.x,k=L.y)}return _=Math.max(0,Math.min(_,S-D)),k=Math.max(0,Math.min(k,T-M)),g.css({left:_,top:k}).show(),m.addClass("open"),w?(m.addClass(w),p=setTimeout(function(){C(),s=!1},10)):(C(),s=!1),r};t.extend(r,{NAME:o,DEFAULTS:a,show:g,hide:f,listenMouse:d,isShow:u}),t.zui({ContextMenu:r});var m=function(e,i){var n=this;n.name=o,n.$=t(e),n.id=t.zui.uuid(),i=n.options=t.extend({trigger:"contextmenu"},r.DEFAULTS,this.$.data(),i);var a=function(t){if("mousedown"!==t.type||2===t.button){if(i.toggleTrigger&&n.isShow())n.hide();else{var e={x:t.clientX,y:t.clientY,event:t};if(n.show(e)===!1)return}return t.preventDefault(),t.returnValue=!1,!1}},s=i.trigger,l=s+"."+o;i.selector?n.$.on(l,i.selector,a):n.$.on(l,a),i.show&&n.show("object"==typeof i.show?i.show:null)};m.prototype.destory=function(){that.$.off("."+o)},m.prototype.hide=function(t){return r.hide(this.id,t)},m.prototype.show=function(e,i){return e=t.extend({id:this.id,$toggle:this.$},this.options,e),r.show(e,i)},m.prototype.isShow=function(){return u(this.id)},t.fn.contextmenu=function(e){return this.each(function(){var i=t(this),n=i.data(o),a="object"==typeof e&&e;n||i.data(o,n=new m(this,a)),"string"==typeof e&&n[e]()})},t.fn.contextmenu.Constructor=m,t.fn.contextDropdown=function(e){t(this).contextmenu(t.extend({trigger:"click",animation:"fade",toggleTrigger:!0,menuCreator:function(e,i){var n=i.$toggle,o=n.attr("data-target");o||(o=n.attr("href"),o=o&&/#/.test(o)&&o.replace(/.*(?=#[^\s]*$)/,""));var a=o?t(o):n.next(".dropdown-menu"),s=i.transferEvent;if(s!==!1){var r="data-contextmenu-index";a.find("a,.contextmenu-item").each(function(e){t(this).attr(r,e)});var l=a.clone();return l.on("string"==typeof s?s:"click","a,.contextmenu-item",function(e){var i=a.find("["+r+'="'+t(this).attr(r)+'"]'),n=i[0];if(n)return n[e.type]?n[e.type]():i.trigger(e.type),e.preventDefault(),e.stopPropagation(),!1}),l}return a.clone()},position:function(t,e,i){var n=e.placement,o=e.$toggle;if(!n){var a=i.find(".dropdown-menu"),s=a.hasClass("pull-right"),r=o.parent().hasClass("dropup");n=s?r?"top-right":"bottom-right":r?"top-left":"bottom-left",s&&a.removeClass("pull-right")}var l=o[0].getBoundingClientRect();switch(n){case"top-left":return{x:l.left,y:Math.floor(l.top-t.height)};case"top-right":return{x:Math.floor(l.right-t.width),y:Math.floor(l.top-t.height)};case"bottom-left":return{x:l.left,y:l.bottom};case"bottom-right":return{x:Math.floor(l.right-t.width),y:l.bottom}}return t}},e))},t(document).on("click",function(e){var i=t(e.target),n=i.closest('[data-toggle="context-dropdown"]');if(n.length){var a=n.data(o);a||n.contextDropdown({show:!0})}else s||i.closest(".contextmenu").length||f()})}(jQuery,void 0),/*! +selected:r.getSelectedArray()},r))}r.options.selectClass&&o.toggleClass(r.options.selectClass,i)}},i.prototype.getSelectedArray=function(){var e=[];return t.each(this.selections,function(t,i){i&&e.push(t)}),e},i.prototype.syncSelectionsFromClass=function(){var e=this,i=e.$children=e.$.find(e.options.selector);e.selections={},i.each(function(){var i=t(this);e.selections[i.data("id")]=i.hasClass(e.options.selectClass)})},i.prototype._init=function(){var e,i,n,a,s,r,l,c=this.options,h=this,d=c.ignoreVal,u=!0,p="."+this.name+"."+this.id,f="function"==typeof c.checkFunc?c.checkFunc:null,g="function"==typeof c.rangeFunc?c.rangeFunc:null,m=!1,v=null,y="mousedown"+p,b=function(){a&&h.$children.each(function(){var e=t(this),i=e.offset();i.width=e.outerWidth(),i.height=e.outerHeight();var n=g?g.call(this,a,i):o(a,i);if(f){var s=f.call(h,{intersect:n,target:e,range:a,targetRange:i});s===!0?h.select(e):s===!1&&h.unselect(e)}else n?h.select(e):h.multiKey||h.unselect(e)})},w=function(o){m&&(s=o.pageX,r=o.pageY,a={width:Math.abs(s-e),height:Math.abs(r-i),left:s>e?e:s,top:r>i?i:r},u&&a.width
    • ').css(t.extend({zIndex:1060,position:"absolute",top:e,left:i,pointerEvents:"none"},h.options.rangeStyle)).appendTo(t("body")))),n.css(a),clearTimeout(l),l=setTimeout(b,10),u=!1))},x=function(e){t(document).off(p),clearTimeout(v),m&&(m=!1,n&&n.remove(),u||a&&(clearTimeout(l),b(),a=null),h.callEvent("finish",{selections:h.selections,selected:h.getSelectedArray()}),e.preventDefault())},C=function(o){if(m)return x(o);var a=t.zui.getMouseButtonCode(c.mouseButton);if(!(a>-1&&o.button!==a||t(o.target).closest("input,select,textarea,label").length||h.altKey||3===o.which||h.callEvent("start",o)===!1)){var s=h.$children=h.$.find(c.selector);s.addClass("selectable-item");var r=h.multiKey?"multi":c.clickBehavior;if("single"===r&&h.unselect(),c.listenClick&&("multi"===r?h.toggle(o.target):"single"===r?h.select(o.target):"toggle"===r&&h.toggle(o.target,null,function(t){h.unselect()})),h.callEvent("startDrag",o)===!1)return void h.callEvent("finish",{selections:h.selections,selected:h.getSelectedArray()});e=o.pageX,i=o.pageY,n=null,u=!0,m=!0,t(document).on("mousemove"+p,w).on("mouseup"+p,x),v=setTimeout(function(){t(document).on(y,x)},10),o.preventDefault()}},_=c.container&&"default"!==c.container?t(c.container):this.$;c.trigger?_.on(y,c.trigger,C):_.on(y,C),t(document).on("keydown",function(t){var e=t.keyCode;17===e||91==e?h.multiKey=e:18===e&&(h.altKey=!0)}).on("keyup",function(t){h.multiKey=!1,h.altKey=!1})},i.prototype.callEvent=function(e,i){var n=t.Event(e+"."+this.name);this.$.trigger(n,i);var o=n.result,a=this.options[e];return"function"==typeof a&&(o=a.apply(this,Array.isArray(i)?i:[i])),o},t.fn.selectable=function(n){return this.each(function(){var o=t(this),a=o.data(e),s="object"==typeof n&&n;a||o.data(e,a=new i(this,s)),"string"==typeof n&&a[n]()})},t.fn.selectable.Constructor=i,t(function(){t('[data-ride="selectable"]').selectable()})}(jQuery),+function(t,e,i){"use strict";if(!t.fn.droppable)return void console.error("Sortable requires droppable.js");var n="zui.sortable",o={selector:"li,div",dragCssClass:"invisible",sortingClass:"sortable-sorting"},a="order",s=function(e,i){var n=this;n.$=t(e),n.options=t.extend({},o,n.$.data(),i),n.init()};s.DEFAULTS=o,s.NAME=n,s.prototype.init=function(){var e,i=this,n=i.$,o=i.options,s=o.selector,r=o.containerSelector,l=o.sortingClass,c=o.dragCssClass,h=o.targetSelector,d=o.reverse,u=o.moveDirection,p=function(e){e=e||i.getItems(1);var n=e.length;n&&e.each(function(e){var i=d?n-e:e;t(this).attr("data-"+a,i).data(a,i)})};h||p(),n.droppable({handle:o.trigger,target:h?h:r?s+","+r:s,selector:s,container:o.container||n,always:o.always,flex:!0,lazy:o.lazy,canMoveHere:o.canMoveHere,dropToClass:o.dropToClass,before:o.before,nested:!!r,mouseButton:o.mouseButton,noShadow:o.noShadow,dropOnMouseleave:o.dropOnMouseleave,stopPropagation:o.stopPropagation,start:function(t){if(c&&t.element.addClass(c),e=!1,i.$element=t.element,!u&&t.targets.length>1){var n=t.targets.eq(0).offset(),o=t.targets.eq(1).offset();u=Math.abs(n.left-o.left)>Math.abs(n.top-o.top)?"h":"v"}p(),i.trigger("start",t)},drag:function(t){if(n.addClass(l),t.isIn){var o=t.element,c=t.target,h=r&&c.is(r);if(h)return void(c.children(s).filter(".dragging").length||(c.append(o),p(b),i.trigger(a,{list:b,element:o})));var f=o.data(a),g=c.data(a);if(f===g)return;var m="h"===u?"left":"top",v=t.mouseOffset[m]-t.lastMouseOffset[m];if(0===v)return;var y=f>g?d:!d;if(v<0&&y||v>0&&!y)return;c[y?"after":"before"](o),e=!0;var b=i.getItems(1);p(b),i.trigger(a,{list:b,element:o})}},finish:function(t){c&&t.element&&t.element.removeClass(c),n.removeClass(l),i.trigger("finish",{list:i.getItems(),element:t.element,changed:e}),i.$element=null}})},s.prototype.destroy=function(){this.$.droppable("destroy"),this.$.data(n,null)},s.prototype.reset=function(){this.destroy(),this.init()},s.prototype.getItems=function(e){var i,n=this,o=n.options.targetSelector;return i=o?"function"==typeof o?o(n.$element,n.$):n.$.find(o):n.$.find(n.options.selector),i=i.not(".drag-shadow"),e?i:i.map(function(){var e=t(this);return{item:e,order:e.data("order")}})},s.prototype.trigger=function(e,i){return t.zui.callEvent(this.options[e],i,this)},t.fn.sortable=function(e){return this.each(function(){var i=t(this),o=i.data(n),a="object"==typeof e&&e;o?"object"==typeof e&&o.reset():i.data(n,o=new s(this,a)),"string"==typeof e&&o[e]()})},t.fn.sortable.Constructor=s}(jQuery,window,document),function(t,e){"use strict";function i(e,i){if("string"==typeof e&&(e="seperator"===e||"divider"===e||"-"===e||"|"===e?{type:"seperator"}:{label:e,id:i}),"seperator"===e.type||"divider"===e.type)return t('
    • ');var n=t("
      ").attr(t.extend({href:e.url||"###","class":e.className,style:e.style},e.attrs)).data("item",e);e.html?e.html===!0?n.html(e.label||e.text):n=t(e.html):n.text(e.label||e.text),e.icon&&n.prepend(''),e.onClick&&n.on("click",e.onClick);var o=t("
    • ").toggleClass("disabled",e.disabled===!0).append(n);return e.items&&o.data("item",e).addClass("dropdown-submenu"),o}function n(e,n,o){var a=o.itemCreator||i,s=typeof e;return"string"===s?e=e.split(","):"function"===s&&(e=e(o)),!!e&&(t.each(e,function(t,e){n.append(a(e,t,o))}),!0)}var o="zui.contextmenu",a={animation:"fade",menuTemplate:'',toggleTrigger:!1,duration:200},s=!1,r={},l="zui-contextmenu-"+t.zui.uuid(),c=0,h=0,d=function(){return t(document).off("mousemove."+o).on("mousemove."+o,function(t){c=t.clientX,h=t.clientY}),r},u=function(e){var i=t("#"+l);return i.length&&i.hasClass("contextmenu-show")&&(!e||(i.data("options")||{}).id===e)},p=null,f=function(e,i){"function"==typeof e&&(i=e,e=null),p&&(clearTimeout(p),p=null);var n=t("#"+l);if(n.length){var o=n.removeClass("contextmenu-show").data("options");if(!e||o.id===e){var a=function(){n.find(".contextmenu-menu").removeClass("open"),o.onHidden&&o.onHidden(),i&&i()};o.onHide&&o.onHide();var s=o.animation;n.find(".contextmenu-menu").removeClass("in"),s?p=setTimeout(a,o.duration):a()}}return r},g=function(i,d,u){t.isPlainObject(i)&&(u=d,d=i,i=d.items),s=!0,d=t.extend({},a,d);var g=t("#"+l);g.length||(g=t('
      ').appendTo("body"));var m=g.find(".contextmenu-menu").empty();m.off("click."+o).on("click."+o,"a,.contextmenu-item",function(e){var i=t(this),n=d.onClickItem&&d.onClickItem(i.data("item"),i,e,d);n!==!1&&f()}).off("mouseenter."+o).on("mouseenter."+o,".dropdown-submenu",function(e){var i=t(this),o=i.data("item"),a=i.children(".dropdown-menu");if(o&&(o.items&&(a.length||(a=t(d.menuTemplate).appendTo(i)),n(o.items,a,d)),i.removeData("item")),a.length){a.removeClass("pull-left").css("top",0);var s=(i[0].getBoundingClientRect(),a[0].getBoundingClientRect()),r=window.innerWidth,l=window.innerHeight;if(s.bottom>l){var c=Math.max(-s.top,l-s.bottom);a.css("top",c)}s.right>r&&a.addClass("pull-left")}}),m.attr("class","contextmenu-menu"+(d.className?" "+d.className:"")),g.attr("class","contextmenu contextmenu-show");var v=d.menuCreator;if(v)m.append(v(i,d));else{m.append(d.menuTemplate);var y=m.children().first(),b=n(i,y,d);if(b===!1)return b}var w=d.animation,x=d.duration;w===!0&&(d.animation=w="fade"),p&&(clearTimeout(p),p=null);var C=function(){m.addClass("in"),d.onShown&&d.onShown(),u&&u()};d.onShow&&d.onShow(),g.data("options",{animation:w,onHide:d.onHide,onHidden:d.onHidden,id:d.id,duration:x});var _=d.x,k=d.y;_===e&&(_=(d.event||d).clientX),_===e&&(_=c),k===e&&(k=(d.event||d).clientY),k===e&&(k=h);var T=window.innerHeight,S=window.innerWidth,y=m.children().first(),D=y.outerWidth(),M=y.outerHeight();if(d.position){var L=d.position({x:_,y:k,width:D,height:M,winHeight:T,winWidth:S},d,m);L&&(_=L.x,k=L.y)}return _=Math.max(0,Math.min(_,S-D)),k=Math.max(0,Math.min(k,T-M)),g.css({left:_,top:k}).show(),m.addClass("open"),w?(m.addClass(w),p=setTimeout(function(){C(),s=!1},10)):(C(),s=!1),r};t.extend(r,{NAME:o,DEFAULTS:a,show:g,hide:f,listenMouse:d,isShow:u}),t.zui({ContextMenu:r});var m=function(e,i){var n=this;n.name=o,n.$=t(e),n.id=t.zui.uuid(),i=n.options=t.extend({trigger:"contextmenu"},r.DEFAULTS,this.$.data(),i);var a=function(t){if("mousedown"!==t.type||2===t.button){if(i.toggleTrigger&&n.isShow())n.hide();else{var e={x:t.clientX,y:t.clientY,event:t};if(n.show(e)===!1)return}return t.preventDefault(),t.returnValue=!1,!1}},s=i.trigger,l=s+"."+o;i.selector?n.$.on(l,i.selector,a):n.$.on(l,a),i.show&&n.show("object"==typeof i.show?i.show:null)};m.prototype.destory=function(){that.$.off("."+o)},m.prototype.hide=function(t){return r.hide(this.id,t)},m.prototype.show=function(e,i){return e=t.extend({id:this.id,$toggle:this.$},this.options,e),r.show(e,i)},m.prototype.isShow=function(){return u(this.id)},t.fn.contextmenu=function(e){return this.each(function(){var i=t(this),n=i.data(o),a="object"==typeof e&&e;n||i.data(o,n=new m(this,a)),"string"==typeof e&&n[e]()})},t.fn.contextmenu.Constructor=m,t.fn.contextDropdown=function(e){t(this).contextmenu(t.extend({trigger:"click",animation:"fade",toggleTrigger:!0,menuCreator:function(e,i){var n=i.$toggle,o=n.attr("data-target");o||(o=n.attr("href"),o=o&&/#/.test(o)&&o.replace(/.*(?=#[^\s]*$)/,""));var a=o?t(o):n.next(".dropdown-menu"),s=i.transferEvent;if(s!==!1){var r="data-contextmenu-index";a.find("a,.contextmenu-item").each(function(e){t(this).attr(r,e)});var l=a.clone();return l.on("string"==typeof s?s:"click","a,.contextmenu-item",function(e){var i=a.find("["+r+'="'+t(this).attr(r)+'"]'),n=i[0];if(n)return n[e.type]?n[e.type]():i.trigger(e.type),e.preventDefault(),e.stopPropagation(),!1}),l}return a.clone()},position:function(t,e,i){var n=e.placement,o=e.$toggle;if(!n){var a=i.find(".dropdown-menu"),s=a.hasClass("pull-right"),r=o.parent().hasClass("dropup");n=s?r?"top-right":"bottom-right":r?"top-left":"bottom-left",s&&a.removeClass("pull-right")}var l=o[0].getBoundingClientRect();switch(n){case"top-left":return{x:l.left,y:Math.floor(l.top-t.height)};case"top-right":return{x:Math.floor(l.right-t.width),y:Math.floor(l.top-t.height)};case"bottom-left":return{x:l.left,y:l.bottom};case"bottom-right":return{x:Math.floor(l.right-t.width),y:l.bottom}}return t}},e))},t(document).on("click",function(e){var i=t(e.target),n=i.closest('[data-toggle="context-dropdown"]');if(n.length){var a=n.data(o);a||n.contextDropdown({show:!0})}else s||i.closest(".contextmenu").length||f()})}(jQuery,void 0),/*! * jQuery Form Plugin * version: 4.2.2 * Requires jQuery v1.7.2 or later From 40f9a85a6f52aaef7b74bf24d37e96244337cb67 Mon Sep 17 00:00:00 2001 From: zenggang Date: Thu, 31 Mar 2022 01:35:50 +0000 Subject: [PATCH 12/20] * Fix bug#21097,21096 --- module/block/control.php | 4 ++-- module/program/model.php | 2 +- module/tutorial/lang/en.php | 4 ++-- module/tutorial/lang/zh-cn.php | 4 ++-- module/tutorial/model.php | 16 +++++++++++++++- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/module/block/control.php b/module/block/control.php index 12609da8ca..bee0955441 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -1354,7 +1354,7 @@ class block extends control $this->app->loadClass('pager', $static = true); $pager = pager::init(0, $count, 1); $this->app->loadLang('execution'); - $this->view->executionStats = $this->loadModel('project')->getStats($this->session->project, $type, 0, 0, 30, 'id_desc', $pager); + $this->view->executionStats = !defined('TUTORIAL') ? $this->loadModel('project')->getStats($this->session->project, $type, 0, 0, 30, 'id_desc', $pager) : array($this->loadModel('tutorial')->getExecution()); } /** @@ -1739,7 +1739,7 @@ class block extends control ->orderBy($orderBy) ->beginIF($limitCount)->limit($limitCount)->fi() ->fetchAll(); - + if($objectType == 'todo') { $this->app->loadClass('date'); diff --git a/module/program/model.php b/module/program/model.php index 49c9e07f15..9def3df994 100644 --- a/module/program/model.php +++ b/module/program/model.php @@ -1259,7 +1259,7 @@ class programModel extends model */ public function getProjectStats($programID = 0, $browseType = 'undone', $queryID = 0, $orderBy = 'id_desc', $pager = null, $programTitle = 0, $involved = 0, $queryAll = false) { - if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectStats(); + if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectStats($browseType); /* Init vars. */ $projects = $this->getProjectList($programID, $browseType, $queryID, $orderBy, $pager, $programTitle, $involved, $queryAll); diff --git a/module/tutorial/lang/en.php b/module/tutorial/lang/en.php index 7f7124b580..18742840c3 100644 --- a/module/tutorial/lang/en.php +++ b/module/tutorial/lang/en.php @@ -59,12 +59,12 @@ $lang->tutorial->tasks['createProject']['desc'] = "

      Create a project:

        $lang->tutorial->tasks['manageTeam'] = array('title' => "Manage Project Team"); $lang->tutorial->tasks['manageTeam']['mode'] = 'new'; -$lang->tutorial->tasks['manageTeam']['nav'] = array('app' => 'project', 'module' => 'project', 'method' => 'managemembers', 'menuModule' => '', 'menu' => '#navbar>.nav>li[data-id="browse"],#cards>.col>.panel:first .project-name,#projectTableList>tr:first>.c-name a,#navbar>.nav>li[data-id="settings"],#subNavbar>.nav>li[data-id="members"],.manage-team-btn', 'target' => '.manage-team-btn', 'vars' => 'projectID=0', 'form' => '#teamForm', 'requiredFields' => 'accounts1,accounts', 'submit' => '#submit', 'targetPageName' => 'Manage team members'); +$lang->tutorial->tasks['manageTeam']['nav'] = array('app' => 'project', 'module' => 'project', 'method' => 'managemembers', 'menuModule' => '', 'menu' => '#navbar>.nav>li[data-id="browse"],#cards>.col>.panel:first .project-name,#projectForm td.c-name:first a,#navbar>.nav>li[data-id="settings"],#subNavbar>.nav>li[data-id="members"],.manage-team-btn', 'target' => '.manage-team-btn', 'vars' => 'projectID=0', 'form' => '#teamForm', 'requiredFields' => 'accounts1,accounts', 'submit' => '#submit', 'targetPageName' => 'Manage team members'); $lang->tutorial->tasks['manageTeam']['desc'] = "

        Manage project team members:

        • Open project Team Manage Team Members Page;
        • Choose users for the team.
        • Save
        "; $lang->tutorial->tasks['createProjectExecution'] = array('title' => 'Create a ' . $lang->executionCommon); $lang->tutorial->tasks['createProjectExecution']['mode'] = 'new'; -$lang->tutorial->tasks['createProjectExecution']['nav'] = array('app' => 'project', 'module' => 'execution', 'method' => 'create', 'menuModule' => 'browse', 'menu' => '#navbar>.nav>li[data-id="browse"],#cards>.col>.panel:first .project-name,#projectTableList>tr:first>.c-name a,#navbar>.nav>li[data-id="execution"],.create-execution-btn', 'form' => '#dataform', 'submit' => '#submit', 'target' => '.create-execution-btn', 'targetPageName' => 'Create' . $lang->executionCommon); +$lang->tutorial->tasks['createProjectExecution']['nav'] = array('app' => 'project', 'module' => 'execution', 'method' => 'create', 'menuModule' => 'browse', 'menu' => '#navbar>.nav>li[data-id="browse"],#cards>.col>.panel:first .project-name,#projectForm td.c-name:first a,#navbar>.nav>li[data-id="execution"],.create-execution-btn', 'form' => '#dataform', 'submit' => '#submit', 'target' => '.create-execution-btn', 'targetPageName' => 'Create' . $lang->executionCommon); $lang->tutorial->tasks['createProjectExecution']['desc'] = "

        Create a new {$lang->executionCommon}:

        • Open Project {$lang->executionCommon} list Create {$lang->executionCommon};
        • Fill the form with {$lang->executionCommon} information;
        • Save {$lang->executionCommon}
        "; $lang->tutorial->tasks['createExecution'] = array('title' => 'Create a ' . $lang->executionCommon); diff --git a/module/tutorial/lang/zh-cn.php b/module/tutorial/lang/zh-cn.php index b6510d7eea..a698817db8 100644 --- a/module/tutorial/lang/zh-cn.php +++ b/module/tutorial/lang/zh-cn.php @@ -59,12 +59,12 @@ $lang->tutorial->tasks['createProject']['desc'] = "

        在系统创建一个新 $lang->tutorial->tasks['manageTeam'] = array('title' => "管理项目团队"); $lang->tutorial->tasks['manageTeam']['mode'] = 'new'; -$lang->tutorial->tasks['manageTeam']['nav'] = array('app' => 'project', 'module' => 'project', 'method' => 'managemembers', 'menuModule' => '', 'menu' => '#navbar>.nav>li[data-id="browse"],#cards>.col>.panel:first .project-name,#projectTableList>tr:first>.c-name a,#navbar>.nav>li[data-id="settings"],#subNavbar>.nav>li[data-id="members"],.manage-team-btn', 'target' => '.manage-team-btn', 'vars' => 'projectID=0', 'form' => '#teamForm', 'requiredFields' => 'accounts1', 'submit' => '#submit', 'targetPageName' => '团队管理'); +$lang->tutorial->tasks['manageTeam']['nav'] = array('app' => 'project', 'module' => 'project', 'method' => 'managemembers', 'menuModule' => '', 'menu' => '#navbar>.nav>li[data-id="browse"],#cards>.col>.panel:first .project-name,#projectForm td.c-name:first a,#navbar>.nav>li[data-id="settings"],#subNavbar>.nav>li[data-id="members"],.manage-team-btn', 'target' => '.manage-team-btn', 'vars' => 'projectID=0', 'form' => '#teamForm', 'requiredFields' => 'accounts1', 'submit' => '#submit', 'targetPageName' => '团队管理'); $lang->tutorial->tasks['manageTeam']['desc'] = "

        管理项目团队成员:

        • 打开 项目 设置 团队 团队管理 页面;
        • 选择要加入项目团队的成员;
        • 保存团队成员信息。
        "; $lang->tutorial->tasks['createProjectExecution'] = array('title' => '添加' . $lang->executionCommon); $lang->tutorial->tasks['createProjectExecution']['mode'] = 'new'; -$lang->tutorial->tasks['createProjectExecution']['nav'] = array('app' => 'project', 'module' => 'execution', 'method' => 'create', 'menuModule' => 'browse', 'menu' => '#navbar>.nav>li[data-id="browse"],#cards>.col>.panel:first .project-name,#projectTableList>tr:first>.c-name a,#navbar>.nav>li[data-id="execution"],.create-execution-btn', 'form' => '#dataform', 'submit' => '#submit', 'target' => '.create-execution-btn', 'targetPageName' => '添加' . $lang->executionCommon); +$lang->tutorial->tasks['createProjectExecution']['nav'] = array('app' => 'project', 'module' => 'execution', 'method' => 'create', 'menuModule' => 'browse', 'menu' => '#navbar>.nav>li[data-id="browse"],#cards>.col>.panel:first .project-name,#projectForm td.c-name:first a,#navbar>.nav>li[data-id="execution"],.create-execution-btn', 'form' => '#dataform', 'submit' => '#submit', 'target' => '.create-execution-btn', 'targetPageName' => '添加' . $lang->executionCommon); $lang->tutorial->tasks['createProjectExecution']['desc'] = "

        在系统创建一个新的{$lang->executionCommon}:

        • 打开 项目 {$lang->executionCommon} 添加{$lang->executionCommon} 页面;
        • 在{$lang->executionCommon}表单中填写要创建的{$lang->executionCommon}信息;
        • 保存{$lang->executionCommon}信息。
        "; $lang->tutorial->tasks['createExecution'] = array('title' => '创建' . $lang->executionCommon); diff --git a/module/tutorial/model.php b/module/tutorial/model.php index 3353025775..36ae07fe70 100644 --- a/module/tutorial/model.php +++ b/module/tutorial/model.php @@ -178,10 +178,11 @@ class tutorialModel extends model /** * Get project stats for tutorial * + * @param string $browseType * @access public * @return array */ - public function getProjectStats() + public function getProjectStats($browseType = '') { $project = $this->getProject(); $emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0); @@ -191,6 +192,8 @@ class tutorialModel extends model $project->teamMembers = array_keys($this->getTeamMembers()); $project->teamCount = count($project->teamMembers); + if($browseType and $browseType != 'all') $project->name .= '-' . $browseType; // Fix bug #21096 + $projectStat[$project->id] = $project; return $projectStat; } @@ -300,6 +303,17 @@ class tutorialModel extends model $execution->totalEstimate = 0; $execution->displayCards = 0; $execution->fluidBoard = 0; + + /* Fix bug #21097. */ + $hours = new stdclass(); + $hours->totalEstimate = 52; + $hours->totalConsumed = 43; + $hours->totalLeft = 7; + $hours->progress = 86; + $hours->totalReal = 50; + + $execution->hours = $hours; + $execution->burns = array(35, 35); return $execution; } From 47fe27dfe751f31917caf4ac0ffebdbaecf702f7 Mon Sep 17 00:00:00 2001 From: zhengrunyu Date: Thu, 31 Mar 2022 09:56:28 +0800 Subject: [PATCH 13/20] * Add api for project. --- api/v1/entries/project.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/api/v1/entries/project.php b/api/v1/entries/project.php index 2251b7fdbe..b7a0812cad 100644 --- a/api/v1/entries/project.php +++ b/api/v1/entries/project.php @@ -62,6 +62,11 @@ class projectEntry extends entry $project->teams = $teams; break; + case "products": + $project->products = array(); + $productList = $this->loadModel('product')->getOrderedProducts('all', 40, $projectID); + foreach($productList as $product) $project->products[$product->id] = $product->name; + break; case "stat": $project->stat = $data->data->statData; break; From bc12fbdf607d8e99db9cae49bc424cbb926b6bfd Mon Sep 17 00:00:00 2001 From: liyang <“liyang@easycorp.ltd”> Date: Thu, 31 Mar 2022 10:08:52 +0800 Subject: [PATCH 14/20] update kanbancard --- test/data/kanbancard.yaml | 15 +++++++++------ test/data/kanbancell.yaml | 7 +++++-- test/data/zentao/config.php | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/test/data/kanbancard.yaml b/test/data/kanbancard.yaml index 7422226af8..8b41cb3652 100644 --- a/test/data/kanbancard.yaml +++ b/test/data/kanbancard.yaml @@ -10,18 +10,21 @@ fields: - field: group range: 1-100{8} - field: fromID - range: "0" + range: 0{800},1-70,1-10,101-200,1-20 - field: fromType - range: "" + range: []{800},productplan{70},release{10},execution{100},build{20} - field: name - range: 1-1000000 - prefix: "卡片" + fields: + - field: name1 + range: 卡片{800},[]{200} + - field: name2 + range: 1-800,[]{200} - field: status range: doing,doing,done - field: pri - range: "3" + range: 3{800},0{200} - field: assignedTo - range: "admin" + range: admin{800},[]{200} - field: desc range: "" - field: begin diff --git a/test/data/kanbancell.yaml b/test/data/kanbancell.yaml index fb53137baa..901509dee9 100644 --- a/test/data/kanbancell.yaml +++ b/test/data/kanbancell.yaml @@ -16,7 +16,10 @@ fields: - field: card1 prefix: "," postfix: "," - range: 1-800:2 + range: 1-1000:2 - field: card2 postfix: "," - range: 2-800:2 + range: 2-1000:2 + - field: card3 + postfix: "," + range: 801-1000:2 diff --git a/test/data/zentao/config.php b/test/data/zentao/config.php index e639a4127e..35b4a398a4 100644 --- a/test/data/zentao/config.php +++ b/test/data/zentao/config.php @@ -60,7 +60,7 @@ $builder->kanbanregion = array('rows' => 100, 'extends' => array('kanbanregion', $builder->kanbangroup = array('rows' => 100, 'extends' => array('kanbangroup','kanbangroup')); $builder->kanbanlane = array('rows' => 100, 'extends' => array('kanbanlane','kanbanlane')); $builder->kanbancolumn = array('rows' => 400, 'extends' => array('kanbancolumn','kanbancolumn')); -$builder->kanbancard = array('rows' => 800, 'extends' => array('kanbancard','kanbancard')); +$builder->kanbancard = array('rows' => 1000, 'extends' => array('kanbancard','kanbancard')); $builder->kanbancell = array('rows' => 400, 'extends' => array('kanbancell','kanbancell')); $builder->kanbanregionproject = array('rows' => 180, 'extends' => array('kanbanregion','kanbanregionproject')); From 2dc5aec4229eb2dac9db4a67dcc997d7366497e0 Mon Sep 17 00:00:00 2001 From: liyang <“liyang@easycorp.ltd”> Date: Thu, 31 Mar 2022 10:46:48 +0800 Subject: [PATCH 15/20] update kanban data --- test/data/kanban.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/data/kanban.yaml b/test/data/kanban.yaml index 54f26af451..0df05382ee 100644 --- a/test/data/kanban.yaml +++ b/test/data/kanban.yaml @@ -61,6 +61,7 @@ fields: range: "0" - field: object range: "" + prefix: "plans,releases,builds,executions,cards" - field: createdBy range: "admin" - field: createdDate From 8efcc37f4bafe86b1feae138613936d99bf57313 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Thu, 31 Mar 2022 11:02:59 +0800 Subject: [PATCH 16/20] * Fix bug #18083. --- module/task/lang/en.php | 4 ++-- module/task/lang/zh-cn.php | 4 ++-- module/task/model.php | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/module/task/lang/en.php b/module/task/lang/en.php index 4c7464d2d1..b6eacee3be 100644 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -246,8 +246,8 @@ $lang->task->error->finishedDateEmpty = '"Finished Date" should not be empty.'; $lang->task->error->finishedDateSmall = '"Finished Date" should be > "Real Started"'; $lang->task->error->alreadyConsumed = 'The currently selected parent task has been consumed.'; $lang->task->error->date = 'The date should be >= today.'; -$lang->task->error->leftEmpty = 'When the task status is %s, "Hours Left" cannot be 0'; -$lang->task->error->leftEmptyAB = 'task#%sWhen the task status is %s, "Left" cannot be 0'; +$lang->task->error->leftEmptyAB = 'When the task status is %s, "Hours Left" cannot be 0'; +$lang->task->error->leftEmpty = 'Task#%sWhen the task status is %s, "Left" cannot be 0'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index b289c2171b..f1a9a910b1 100644 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -246,8 +246,8 @@ $lang->task->error->finishedDateEmpty = '实际完成不能为空'; $lang->task->error->finishedDateSmall = '实际完成不能小于实际开始'; $lang->task->error->alreadyConsumed = '当前选中的父任务已有消耗。'; $lang->task->error->date = '日期不能大于今天'; -$lang->task->error->leftEmpty = '任务状态为%s时,预计剩余不能为0'; -$lang->task->error->leftEmptyAB = 'task#%s任务状态为%s时,剩余不能为0'; +$lang->task->error->leftEmptyAB = '任务状态为%s时,预计剩余不能为0'; +$lang->task->error->leftEmpty = 'Task#%s任务状态为%s时,剩余不能为0'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/model.php b/module/task/model.php index 4ffc3f2522..93ed0af681 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -998,9 +998,9 @@ class taskModel extends model $requiredFields = str_replace(',estimate,', ',', $requiredFields); } - if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && empty($task->left)) + if(strpos(',doing,pause,', $task->status) && empty($teams) && empty($task->left)) { - dao::$errors[] = sprintf($this->lang->task->error->leftEmpty, $this->lang->task->statusList[$task->status]); + dao::$errors[] = sprintf($this->lang->task->error->leftEmptyAB, $this->lang->task->statusList[$task->status]); return false; } @@ -1263,13 +1263,13 @@ class taskModel extends model if($task->status == 'cancel') continue; if($task->status == 'done' and $task->consumed == false) { - dao::$errors[] = 'task#' . $taskID . sprintf($this->lang->error->notempty, $this->lang->task->consumedThisTime); + dao::$errors[] = 'Task#' . $taskID . sprintf($this->lang->error->notempty, $this->lang->task->consumedThisTime); return false; } if(!empty($task->deadline) and $task->estStarted > $task->deadline) { - dao::$errors[] = 'task#' . $taskID . $this->lang->task->error->deadlineSmall; + dao::$errors[] = 'Task#' . $taskID . $this->lang->task->error->deadlineSmall; return false; } @@ -1289,9 +1289,9 @@ class taskModel extends model foreach($tasks as $taskID => $task) { - if(strpos(',done,wait,cancel,closed,', $task->status) === false && empty($teams) && $task->parent >= 0 && empty($task->left)) + if(strpos(',doing,pause,', $task->status) && empty($teams) && $task->parent >= 0 && empty($task->left)) { - dao::$errors[] = sprintf($this->lang->task->error->leftEmptyAB, $taskID, $this->lang->task->statusList[$task->status]); + dao::$errors[] = sprintf($this->lang->task->error->leftEmpty, $taskID, $this->lang->task->statusList[$task->status]); return false; } @@ -1315,7 +1315,7 @@ class taskModel extends model ->exec(); if(dao::isError()) { - dao::$errors[] = 'task#' . $taskID . dao::getError(true); + dao::$errors[] = 'Task#' . $taskID . dao::getError(true); return false; } From 2dc3d02da0a664e6fd8d77c44d8fe7cfcf29480d Mon Sep 17 00:00:00 2001 From: zhengrunyu Date: Thu, 31 Mar 2022 11:16:45 +0800 Subject: [PATCH 17/20] * Fix api for project. --- api/v1/entries/project.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/v1/entries/project.php b/api/v1/entries/project.php index b7a0812cad..38096ddc09 100644 --- a/api/v1/entries/project.php +++ b/api/v1/entries/project.php @@ -63,9 +63,9 @@ class projectEntry extends entry $project->teams = $teams; break; case "products": - $project->products = array(); + $project->products = array(); $productList = $this->loadModel('product')->getOrderedProducts('all', 40, $projectID); - foreach($productList as $product) $project->products[$product->id] = $product->name; + foreach($productList as $product) $project->products[] = $product; break; case "stat": $project->stat = $data->data->statData; From 3d5c425501d81affd2fe9b703b4d51ad294e5a9e Mon Sep 17 00:00:00 2001 From: zenggang Date: Thu, 31 Mar 2022 03:26:57 +0000 Subject: [PATCH 18/20] * Adjust code --- module/tutorial/model.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/module/tutorial/model.php b/module/tutorial/model.php index 36ae07fe70..ad45c76f6d 100644 --- a/module/tutorial/model.php +++ b/module/tutorial/model.php @@ -271,6 +271,14 @@ class tutorialModel extends model */ public function getExecution() { + /* Fix bug #21097. */ + $hours = new stdclass(); + $hours->totalEstimate = 52; + $hours->totalConsumed = 43; + $hours->totalLeft = 7; + $hours->progress = 86; + $hours->totalReal = 50; + $execution = new stdclass(); $execution->id = 3; $execution->project = 2; @@ -303,17 +311,8 @@ class tutorialModel extends model $execution->totalEstimate = 0; $execution->displayCards = 0; $execution->fluidBoard = 0; - - /* Fix bug #21097. */ - $hours = new stdclass(); - $hours->totalEstimate = 52; - $hours->totalConsumed = 43; - $hours->totalLeft = 7; - $hours->progress = 86; - $hours->totalReal = 50; - - $execution->hours = $hours; - $execution->burns = array(35, 35); + $execution->hours = $hours; + $execution->burns = array(35, 35); return $execution; } From ce422e102f67550eab7a6327bd110f60eaacf9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Thu, 31 Mar 2022 11:31:38 +0800 Subject: [PATCH 19/20] * Fix my - preference bug. --- module/common/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/common/model.php b/module/common/model.php index fb2200d17a..6b81d3bd1e 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -2257,7 +2257,7 @@ EOD; $module = $this->app->getModuleName(); $method = $this->app->getMethodName(); - if($module == 'index' || $module == 'tutorial' || $module == 'install' || $module == 'upgrade' || ($module == 'user' && ($method == 'login' || $method == 'deny' || $method == 'logout')) || ($module == 'my' && $method == 'changepassword') || ($module == 'file' && $method == 'read') || ($module == 'file' && $method == 'download') || ($module == 'file' && $method == 'uploadimages')) return; + if($module == 'index' || $module == 'tutorial' || $module == 'install' || $module == 'upgrade' || ($module == 'user' && ($method == 'login' || $method == 'deny' || $method == 'logout')) || ($module == 'my' && ($method == 'changepassword' || $method == 'preference')) || ($module == 'file' && $method == 'read') || ($module == 'file' && $method == 'download') || ($module == 'file' && $method == 'uploadimages')) return; $url = helper::safe64Encode($_SERVER['REQUEST_URI']); $redirectUrl = helper::createLink('index', 'index', "open=$url"); From 33f46615dfef2d4b13bbcb0aa4ae1f54d4522f95 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 31 Mar 2022 13:33:00 +0800 Subject: [PATCH 20/20] * Add auto test of kanban. --- test/class/kanban.class.php | 199 +++++++++++++++--- test/model/kanban/getcanviewobjects.php | 2 +- test/model/kanban/getkanbandata.php | 24 +++ test/model/kanban/getkanbanidbyregion.php | 23 ++ test/model/kanban/getkanbanpairs.php | 24 +++ test/model/kanban/getlanebyid.php | 24 +++ test/model/kanban/getlanegroupbyregion.php | 42 ++++ test/model/kanban/getlanegroupbyregions.php | 42 ++++ test/model/kanban/getlanepairsbygroup.php | 24 +++ test/model/kanban/getlanepairsbyregion.php | 43 ++++ test/model/kanban/getlanes4group.php | 40 ++++ test/model/kanban/getobjectgroup.php | 39 ++++ test/model/kanban/getplankanban.php | 26 +++ .../kanban/getrdcolumngroupbyregions.php | 32 +++ test/model/kanban/getrdkanban.php | 31 +++ 15 files changed, 581 insertions(+), 34 deletions(-) create mode 100755 test/model/kanban/getkanbandata.php create mode 100755 test/model/kanban/getkanbanidbyregion.php create mode 100755 test/model/kanban/getkanbanpairs.php create mode 100755 test/model/kanban/getlanebyid.php create mode 100755 test/model/kanban/getlanegroupbyregion.php create mode 100755 test/model/kanban/getlanegroupbyregions.php create mode 100755 test/model/kanban/getlanepairsbygroup.php create mode 100755 test/model/kanban/getlanepairsbyregion.php create mode 100755 test/model/kanban/getlanes4group.php create mode 100755 test/model/kanban/getobjectgroup.php create mode 100755 test/model/kanban/getplankanban.php create mode 100755 test/model/kanban/getrdcolumngroupbyregions.php create mode 100755 test/model/kanban/getrdkanban.php diff --git a/test/class/kanban.class.php b/test/class/kanban.class.php index 6e22e60c08..ef7afa2043 100644 --- a/test/class/kanban.class.php +++ b/test/class/kanban.class.php @@ -249,31 +249,86 @@ class kanbanTest return $object; } + /** + * Test get kanban data. + * + * @param int $kanbanID + * @access public + * @return string + */ public function getKanbanDataTest($kanbanID) { $objects = $this->objectModel->getKanbanData($kanbanID); if(dao::isError()) return dao::getError(); - return $objects; + $columnCount = 0; + $laneCount = 0; + $cardCount = 0; + foreach($objects as $regions) + { + foreach($regions->groups as $group) + { + foreach($group->lanes as $lane) $cardCount += count($lane->items); + + $columnCount += count($group->columns); + $laneCount += count($group->lanes); + } + } + return 'columns:' . $columnCount . ', lanes:' . $laneCount . ', cards:' . $cardCount; } - public function getPlanKanbanTest($product, $branchID = 0, $planGroup = '') + /** + * Test get plan kanban. + * + * @param int $productID + * @param int $branchID + * @access public + * @return string + */ + public function getPlanKanbanTest($productID, $branchID = 0) { - $objects = $this->objectModel->getPlanKanban($product, $branchID = 0, $planGroup = ''); + global $tester; + $product = $tester->loadModel('product')->getByID($productID); + + $tester->loadModel('productplan'); + $planGroup = $product->type == 'normal' ? $tester->productplan->getList($product->id, 0, 'all', '', 'begin_desc', 'skipparent') : $tester->productplan->getGroupByProduct($product->id, 'skipParent', '', 'begin_desc'); + + $objects = $this->objectModel->getPlanKanban($product, $branchID, $planGroup); if(dao::isError()) return dao::getError(); - return $objects; + $laneCount = 0; + $cardCount = 0; + foreach($objects->lanes as $lane) + { + foreach($lane->items as $item) $cardCount += count($item); + } + return 'lanes:' . count($objects->lanes) . ', cards:' . $cardCount; } - public function getRDKanbanTest($executionID, $browseType = 'all', $orderBy = 'id_desc', $regionID = 0, $groupBy = 'default') + public function getRDKanbanTest($executionID, $browseType = 'all', $regionID = 0) { - $objects = $this->objectModel->getRDKanban($executionID, $browseType = 'all', $orderBy = 'id_desc', $regionID = 0, $groupBy = 'default'); + $objects = $this->objectModel->getRDKanban($executionID, $browseType, 'id_desc', $regionID); if(dao::isError()) return dao::getError(); - return $objects; + $columnCount = 0; + $laneCount = 0; + $cardCount = 0; + foreach($objects as $regions) + { + foreach($regions->groups as $group) + { + $columnCount += count($group->columns); + $laneCount += count($group->lanes); + foreach($group->lanes as $lane) + { + foreach($lane->items as $item) $cardCount += count($item); + } + } + } + return 'columns:' . $columnCount . ', lanes:' . $laneCount . ', cards:' . $cardCount; } public function getRegionByIDTest($regionID) @@ -294,13 +349,20 @@ class kanbanTest return $objects; } + /** + * Test get kanban id by region id. + * + * @param int $regionID + * @access public + * @return int + */ public function getKanbanIDByRegionTest($regionID) { - $objects = $this->objectModel->getKanbanIDByRegion($regionID); + $object = $this->objectModel->getKanbanIDByRegion($regionID); if(dao::isError()) return dao::getError(); - return $objects; + return $object; } /** @@ -324,20 +386,31 @@ class kanbanTest public function getLaneGroupByRegionsTest($regions, $browseType = 'all') { - $objects = $this->objectModel->getLaneGroupByRegions($regions, $browseType = 'all'); + $objects = $this->objectModel->getLaneGroupByRegions($regions, $browseType); if(dao::isError()) return dao::getError(); - return $objects; + $count = 0; + foreach($objects as $object) $count += count($object); + return $count; } + /** + * Test get lane pairs by group id. + * + * @param int $groupID + * @param string $orderBy + * @access public + * @return string + */ public function getLanePairsByGroupTest($groupID, $orderBy = '`order`_asc') { $objects = $this->objectModel->getLanePairsByGroup($groupID, $orderBy = '`order`_asc'); if(dao::isError()) return dao::getError(); - return $objects; + $names = implode(',', $objects); + return $names; } public function getColumnGroupByRegionsTest($regions, $order = 'order') @@ -376,13 +449,23 @@ class kanbanTest return $objects; } + /** + * Test get RD column group by regions. + * + * @param int $regions + * @param array $groupIDList + * @access public + * @return int + */ public function getRDColumnGroupByRegionsTest($regions, $groupIDList = array()) { - $objects = $this->objectModel->getRDColumnGroupByRegions($regions, $groupIDList = array()); + $objects = $this->objectModel->getRDColumnGroupByRegions($regions, $groupIDList); if(dao::isError()) return dao::getError(); - return $objects; + $count = 0; + foreach($objects as $object) $count += count($object); + return $count; } /** @@ -431,10 +514,7 @@ class kanbanTest { foreach($types['lanes'] as $lane) { - foreach($lane['cards'] as $card) - { - $cardCount += count($card); - } + foreach($lane['cards'] as $card) $cardCount += count($card); } $columnCount += count($types['columns']); $laneCount += count($types['lanes']); @@ -458,26 +538,46 @@ class kanbanTest if(empty($objects)) { $this->objectModel->createExecutionLane($executionID, $browseType, $groupBy); - $objects = $this->objectModel->getExecutionKanban($executionID, $browseType, $groupBy); + $objects = $this->objectModel->getKanban4Group($executionID, $browseType, $groupBy); } if(dao::isError()) return dao::getError(); $laneCount = 0; - foreach($objects as $types) - { - $laneCount += count($types['lanes']); - } + foreach($objects as $types) $laneCount += count($types['lanes']); + return 'lanes:' . $laneCount; } - public function getLanes4GroupTest($executionID, $browseType, $groupBy, $cardList) + /** + * Test get kanban for group view. + * + * @param int $executionID + * @param string $browseType + * @param string $groupBy + * @access public + * @return void + */ + public function getLanes4GroupTest($executionID, $browseType, $groupBy) { + global $tester; + /* Get group objects. */ + if($browseType == 'story') $cardList = $tester->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory'); + if($browseType == 'bug') $cardList = $tester->loadModel('bug')->getExecutionBugs($executionID); + if($browseType == 'task') $cardList = $tester->loadModel('execution')->getKanbanTasks($executionID, "id"); $objects = $this->objectModel->getLanes4Group($executionID, $browseType, $groupBy, $cardList); + if(empty($objects)) + { + $this->objectModel->createExecutionLane($executionID, $browseType, $groupBy); + $objects = $this->objectModel->getLanes4Group($executionID, $browseType, $groupBy); + } + if(dao::isError()) return dao::getError(); - return $objects; + $names = ''; + foreach($objects as $object) $names .= ',' . $object->name; + return $names; } public function getSpaceListTest($browseType, $pager = null) @@ -498,13 +598,21 @@ class kanbanTest return $objects; } - public function getKanbanPairsTest() + /** + * Test get Kanban pairs. + * + * @param string $user + * @access public + * @return int + */ + public function getKanbanPairsTest($user) { + su($user); $objects = $this->objectModel->getKanbanPairs(); if(dao::isError()) return dao::getError(); - return $objects; + return count($objects); } /** @@ -556,22 +664,39 @@ class kanbanTest return $objects; } + /** + * Test get lane pairs by region id. + * + * @param int $regionID + * @param string $type + * @access public + * @return string + */ public function getLanePairsByRegionTest($regionID, $type = 'all') { - $objects = $this->objectModel->getLanePairsByRegion($regionID, $type = 'all'); + $objects = $this->objectModel->getLanePairsByRegion($regionID, $type); if(dao::isError()) return dao::getError(); - return $objects; + $names = implode(',', $objects); + return $names; } + /** + * Test get lane group by regionid. + * + * @param int $regionID + * @param string $type + * @access public + * @return int + */ public function getLaneGroupByRegionTest($regionID, $type = 'all') { - $objects = $this->objectModel->getLaneGroupByRegion($regionID, $type = 'all'); + $objects = $this->objectModel->getLaneGroupByRegion($regionID, $type); if(dao::isError()) return dao::getError(); - return $objects; + return count($objects[$regionID]); } /** @@ -1116,13 +1241,20 @@ class kanbanTest return $object; } + /** + * Test get lane by id. + * + * @param int $laneID + * @access public + * @return object + */ public function getLaneByIdTest($laneID) { - $objects = $this->objectModel->getLaneById($laneID); + $object = $this->objectModel->getLaneById($laneID); if(dao::isError()) return dao::getError(); - return $objects; + return $object; } public function getObjectGroupTest($executionID, $type, $groupBy) @@ -1131,6 +1263,7 @@ class kanbanTest if(dao::isError()) return dao::getError(); + $objects = implode(',', $objects); return $objects; } diff --git a/test/model/kanban/getcanviewobjects.php b/test/model/kanban/getcanviewobjects.php index 874fbee425..cf2e4db4d8 100755 --- a/test/model/kanban/getcanviewobjects.php +++ b/test/model/kanban/getcanviewobjects.php @@ -13,7 +13,7 @@ pid=1 $kanban = new kanbanTest(); -$userList = array('admin', 'po1', 'po2', 'user1', 'user2', 'pm1', 'pm2'); +$userList = array('admin', 'po1', 'po2', 'user1', 'user2', 'pm1', 'pm2'); $objectType = array('kanban', 'kanbanspace'); $paramList = array('noclosed', 'private', 'cooperation', 'public', 'involved'); diff --git a/test/model/kanban/getkanbandata.php b/test/model/kanban/getkanbandata.php new file mode 100755 index 0000000000..723cd52b84 --- /dev/null +++ b/test/model/kanban/getkanbandata.php @@ -0,0 +1,24 @@ +#!/usr/bin/env php +getKanbanData(); +cid=1 +pid=1 + +*/ + +$kanbanIDList = array('1', '2', '3', '4', '5', '1000001'); + +$kanban = new kanbanTest(); + +r($kanban->getKanbanDataTest($kanbanIDList[0])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban1的视图 +r($kanban->getKanbanDataTest($kanbanIDList[1])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban2的视图 +r($kanban->getKanbanDataTest($kanbanIDList[2])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban3的视图 +r($kanban->getKanbanDataTest($kanbanIDList[3])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban4的视图 +r($kanban->getKanbanDataTest($kanbanIDList[4])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban5的视图 +r($kanban->getKanbanDataTest($kanbanIDList[5])) && p() && e('columns:0, lanes:0, cards:0'); // 测试获取不存在的kanban的视图 diff --git a/test/model/kanban/getkanbanidbyregion.php b/test/model/kanban/getkanbanidbyregion.php new file mode 100755 index 0000000000..c486008c37 --- /dev/null +++ b/test/model/kanban/getkanbanidbyregion.php @@ -0,0 +1,23 @@ +#!/usr/bin/env php +getKanbanIDByRegion(); +cid=1 +pid=1 + +*/ +$regionIDList = array('1', '2', '3', '4', '5', '1000001'); + +$kanban = new kanbanTest(); + +r($kanban->getKanbanIDByRegionTest($regionIDList[0])) && p() && e('1'); // 测试通过区域1获取看板id +r($kanban->getKanbanIDByRegionTest($regionIDList[1])) && p() && e('2'); // 测试通过区域2获取看板id +r($kanban->getKanbanIDByRegionTest($regionIDList[2])) && p() && e('3'); // 测试通过区域3获取看板id +r($kanban->getKanbanIDByRegionTest($regionIDList[3])) && p() && e('4'); // 测试通过区域4获取看板id +r($kanban->getKanbanIDByRegionTest($regionIDList[4])) && p() && e('5'); // 测试通过区域5获取看板id +r($kanban->getKanbanIDByRegionTest($regionIDList[5])) && p() && e('0'); // 测试通过不存在的区域获取看板id diff --git a/test/model/kanban/getkanbanpairs.php b/test/model/kanban/getkanbanpairs.php new file mode 100755 index 0000000000..99562a08af --- /dev/null +++ b/test/model/kanban/getkanbanpairs.php @@ -0,0 +1,24 @@ +#!/usr/bin/env php +getKanbanPairs(); +cid=1 +pid=1 + +*/ + +$userList = array('admin', 'po1', 'po2', 'user1', 'user2', 'pm1', 'pm2'); + +$kanban = new kanbanTest(); + +r($kanban->getKanbanPairsTest($userList[0])) && p() && e('100'); //获取用户admin可以看到的看板pairs +r($kanban->getKanbanPairsTest($userList[1])) && p() && e('32'); //获取用户po1可以看到的看板pairs +r($kanban->getKanbanPairsTest($userList[2])) && p() && e('32'); //获取用户po2可以看到的看板pairs +r($kanban->getKanbanPairsTest($userList[3])) && p() && e('32'); //获取用户user1可以看到的看板pairs +r($kanban->getKanbanPairsTest($userList[4])) && p() && e('32'); //获取用户user2可以看到的看板pairs +r($kanban->getKanbanPairsTest($userList[5])) && p() && e('32'); //获取用户pm1可以看到的看板pairs +r($kanban->getKanbanPairsTest($userList[6])) && p() && e('32'); //获取用户pm2可以看到的看板pairs diff --git a/test/model/kanban/getlanebyid.php b/test/model/kanban/getlanebyid.php new file mode 100755 index 0000000000..2b14b2d76a --- /dev/null +++ b/test/model/kanban/getlanebyid.php @@ -0,0 +1,24 @@ +#!/usr/bin/env php +getLaneById(); +cid=1 +pid=1 + +*/ + +$laneIDList = array('1', '2', '3', '4', '5', '1000001'); + +$kanban = new kanbanTest(); + +r($kanban->getLaneByIdTest($laneIDList[0])) && p('name,type,region,group') && e('默认泳道,common,1,1'); // 测试通过id1获取泳道信息 +r($kanban->getLaneByIdTest($laneIDList[1])) && p('name,type,region,group') && e('默认泳道,common,2,2'); // 测试通过id2获取泳道信息 +r($kanban->getLaneByIdTest($laneIDList[2])) && p('name,type,region,group') && e('默认泳道,common,3,3'); // 测试通过id3获取泳道信息 +r($kanban->getLaneByIdTest($laneIDList[3])) && p('name,type,region,group') && e('默认泳道,common,4,4'); // 测试通过id4获取泳道信息 +r($kanban->getLaneByIdTest($laneIDList[4])) && p('name,type,region,group') && e('默认泳道,common,5,5'); // 测试通过id5获取泳道信息 +r($kanban->getLaneByIdTest($laneIDList[5])) && p('name,type,region,group') && e('0'); // 测试通过不存在的id获取泳道信息 diff --git a/test/model/kanban/getlanegroupbyregion.php b/test/model/kanban/getlanegroupbyregion.php new file mode 100755 index 0000000000..030c057ed1 --- /dev/null +++ b/test/model/kanban/getlanegroupbyregion.php @@ -0,0 +1,42 @@ +#!/usr/bin/env php +getLaneGroupByRegion(); +cid=1 +pid=1 + +*/ + +$regionIDList = array('101', '102', '103', '104', '105', '1000001'); +$type = array('bug', 'task', 'story'); + +$kanban = new kanbanTest(); +r($kanban->getLaneGroupByRegionTest($regionIDList[0])) && p() && e('3'); // 测试获取区域101的泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[0], $type[0])) && p() && e('1'); // 测试获取区域101的bug泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[0], $type[1])) && p() && e('1'); // 测试获取区域101的task泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[0], $type[2])) && p() && e('1'); // 测试获取区域101的story泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[1])) && p() && e('3'); // 测试获取区域102的泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[1], $type[0])) && p() && e('1'); // 测试获取区域102的bug泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[1], $type[1])) && p() && e('1'); // 测试获取区域102的task泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[1], $type[2])) && p() && e('1'); // 测试获取区域102的story泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[2])) && p() && e('3'); // 测试获取区域103的泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[2], $type[0])) && p() && e('1'); // 测试获取区域103的bug泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[2], $type[1])) && p() && e('1'); // 测试获取区域103的task泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[2], $type[2])) && p() && e('1'); // 测试获取区域103的story泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[3])) && p() && e('3'); // 测试获取区域104的泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[3], $type[0])) && p() && e('1'); // 测试获取区域104的bug泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[3], $type[1])) && p() && e('1'); // 测试获取区域104的task泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[3], $type[2])) && p() && e('1'); // 测试获取区域104的story泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[4])) && p() && e('3'); // 测试获取区域105的泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[4], $type[0])) && p() && e('1'); // 测试获取区域105的bug泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[4], $type[1])) && p() && e('1'); // 测试获取区域105的task泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[4], $type[2])) && p() && e('1'); // 测试获取区域105的story泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[5])) && p() && e('0'); // 测试获取不存在的区域的泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[5], $type[0])) && p() && e('0'); // 测试获取不存在的区域的bug泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[5], $type[1])) && p() && e('0'); // 测试获取不存在的区域的task泳道 +r($kanban->getLaneGroupByRegionTest($regionIDList[5], $type[2])) && p() && e('0'); // 测试获取不存在的区域的story泳道 diff --git a/test/model/kanban/getlanegroupbyregions.php b/test/model/kanban/getlanegroupbyregions.php new file mode 100755 index 0000000000..2f9e094b16 --- /dev/null +++ b/test/model/kanban/getlanegroupbyregions.php @@ -0,0 +1,42 @@ +#!/usr/bin/env php +getLaneGroupByRegions(); +cid=1 +pid=1 + +*/ +$regionsList = array('101,102,103', '104,105,106', '107,108,109', '110,111,112', '113,114,115', '1000001'); +$type = array('bug', 'task', 'story'); + +$kanban = new kanbanTest(); + +r($kanban->getLaneGroupByRegionsTest($regionsList[0])) && p() && e('9'); // 测试获取区域101,102,103的泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[0], $type[0])) && p() && e('3'); // 测试获取区域101,102,103的bug泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[0], $type[1])) && p() && e('3'); // 测试获取区域101,102,103的task泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[0], $type[2])) && p() && e('3'); // 测试获取区域101,102,103的story泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[1])) && p() && e('9'); // 测试获取区域104,105,106的泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[1], $type[0])) && p() && e('3'); // 测试获取区域104,105,106的bug泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[1], $type[1])) && p() && e('3'); // 测试获取区域104,105,106的task泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[1], $type[2])) && p() && e('3'); // 测试获取区域104,105,106的story泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[2])) && p() && e('9'); // 测试获取区域107,108,109的泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[2], $type[0])) && p() && e('3'); // 测试获取区域107,108,109的bug泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[2], $type[1])) && p() && e('3'); // 测试获取区域107,108,109的task泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[2], $type[2])) && p() && e('3'); // 测试获取区域107,108,109的story泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[3])) && p() && e('9'); // 测试获取区域110,111,112的泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[3], $type[0])) && p() && e('3'); // 测试获取区域110,111,112的bug泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[3], $type[1])) && p() && e('3'); // 测试获取区域110,111,112的task泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[3], $type[2])) && p() && e('3'); // 测试获取区域110,111,112的story泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[4])) && p() && e('9'); // 测试获取区域113,114,115的泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[4], $type[0])) && p() && e('3'); // 测试获取区域113,114,115的bug泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[4], $type[1])) && p() && e('3'); // 测试获取区域113,114,115的task泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[4], $type[2])) && p() && e('3'); // 测试获取区域113,114,115的story泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[5])) && p() && e('0'); // 测试获取不存在的区域的泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[5], $type[0])) && p() && e('0'); // 测试获取不存在的区域的bug泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[5], $type[1])) && p() && e('0'); // 测试获取不存在的区域的task泳道 +r($kanban->getLaneGroupByRegionsTest($regionsList[5], $type[2])) && p() && e('0'); // 测试获取不存在的区域的story泳道 diff --git a/test/model/kanban/getlanepairsbygroup.php b/test/model/kanban/getlanepairsbygroup.php new file mode 100755 index 0000000000..51ba429f89 --- /dev/null +++ b/test/model/kanban/getlanepairsbygroup.php @@ -0,0 +1,24 @@ +#!/usr/bin/env php +getLanePairsByGroup(); +cid=1 +pid=1 + +*/ + +$groupIDList = array('101', '102', '103', '104', '105', '1000001'); + +$kanban = new kanbanTest(); + +r($kanban->getLanePairsByGroupTest($groupIDList[0])) && p() && e('研发需求'); // 获取泳道组101的泳道 +r($kanban->getLanePairsByGroupTest($groupIDList[1])) && p() && e('Bug'); // 获取泳道组102的泳道 +r($kanban->getLanePairsByGroupTest($groupIDList[2])) && p() && e('任务'); // 获取泳道组103的泳道 +r($kanban->getLanePairsByGroupTest($groupIDList[3])) && p() && e('研发需求'); // 获取泳道组104的泳道 +r($kanban->getLanePairsByGroupTest($groupIDList[4])) && p() && e('Bug'); // 获取泳道组105的泳道 +r($kanban->getLanePairsByGroupTest($groupIDList[5])) && p() && e('0'); // 获取不存在泳道组的泳道 diff --git a/test/model/kanban/getlanepairsbyregion.php b/test/model/kanban/getlanepairsbyregion.php new file mode 100755 index 0000000000..39bdb8d1c9 --- /dev/null +++ b/test/model/kanban/getlanepairsbyregion.php @@ -0,0 +1,43 @@ +#!/usr/bin/env php +getLanePairsByRegion(); +cid=1 +pid=1 + +*/ + +$regionIDList = array('101', '102', '103', '104', '105', '1000001'); +$type = array('bug', 'task', 'story'); + +$kanban = new kanbanTest(); + +r($kanban->getLanePairsByRegionTest($regionIDList[0])) && p() && e('研发需求,Bug,任务'); // 测试获取区域101的泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[0], $type[0])) && p() && e('Bug'); // 测试获取区域101的bug泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[0], $type[1])) && p() && e('任务'); // 测试获取区域101的task泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[0], $type[2])) && p() && e('研发需求'); // 测试获取区域101的story泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[1])) && p() && e('研发需求,Bug,任务'); // 测试获取区域102的泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[1], $type[0])) && p() && e('Bug'); // 测试获取区域102的bug泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[1], $type[1])) && p() && e('任务'); // 测试获取区域102的task泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[1], $type[2])) && p() && e('研发需求'); // 测试获取区域102的story泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[2])) && p() && e('研发需求,Bug,任务'); // 测试获取区域103的泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[2], $type[0])) && p() && e('Bug'); // 测试获取区域103的bug泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[2], $type[1])) && p() && e('任务'); // 测试获取区域103的task泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[2], $type[2])) && p() && e('研发需求'); // 测试获取区域103的story泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[3])) && p() && e('研发需求,Bug,任务'); // 测试获取区域104的泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[3], $type[0])) && p() && e('Bug'); // 测试获取区域104的bug泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[3], $type[1])) && p() && e('任务'); // 测试获取区域104的task泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[3], $type[2])) && p() && e('研发需求'); // 测试获取区域104的story泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[4])) && p() && e('研发需求,Bug,任务'); // 测试获取区域105的泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[4], $type[0])) && p() && e('Bug'); // 测试获取区域105的bug泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[4], $type[1])) && p() && e('任务'); // 测试获取区域105的task泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[4], $type[2])) && p() && e('研发需求'); // 测试获取区域105的story泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[5])) && p() && e('0'); // 测试获取不存在的区域的泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[5], $type[0])) && p() && e('0'); // 测试获取不存在的区域的bug泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[5], $type[1])) && p() && e('0'); // 测试获取不存在的区域的task泳道 +r($kanban->getLanePairsByRegionTest($regionIDList[5], $type[2])) && p() && e('0'); // 测试获取不存在的区域的story泳道 diff --git a/test/model/kanban/getlanes4group.php b/test/model/kanban/getlanes4group.php new file mode 100755 index 0000000000..2c69fc4c58 --- /dev/null +++ b/test/model/kanban/getlanes4group.php @@ -0,0 +1,40 @@ +#!/usr/bin/env php +getLanes4Group(); +cid=1 +pid=1 + +*/ +$executionIDList = array('101', '102', '103', '104', '105'); +$browseTypeList = array('story', 'task', 'bug'); +$groupByList = array('pri', 'category', 'module', 'source', 'assignedTo', 'story', 'severity'); + +$kanban = new kanbanTest(); + +r($kanban->getLanes4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[0])) && p() && e(',优先级: 无,2,4'); // 获取执行101 story pri的泳道 +r($kanban->getLanes4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[1])) && p() && e(',类型: 无,功能'); // 获取执行101 story category的泳道 +r($kanban->getLanes4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[2])) && p() && e(',所属模块: 无,产品模块2,产品模块4'); // 获取执行101 story module的泳道 +r($kanban->getLanes4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[3])) && p() && e(',来源: 无,用户,市场'); // 获取执行101 story source的泳道 +r($kanban->getLanes4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[0])) && p() && e(',优先级: 无,1,2,4'); // 获取执行102 task pri的泳道 +r($kanban->getLanes4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[2])) && p() && e(',所属模块: 无,模块4,模块10,模块13,模块16'); // 获取执行102 task module的泳道 +r($kanban->getLanes4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[4])) && p() && e(',指派给: 无'); // 获取执行102 task assignedTo的泳道 +r($kanban->getLanes4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[5])) && p() && e(',相关研发需求: 无,用户需求5'); // 获取执行102 task story的泳道 +r($kanban->getLanes4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[0])) && p() && e(',优先级: 无,1,3,4'); // 获取执行101 bug pri的泳道 +r($kanban->getLanes4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[2])) && p() && e(',所属模块: 无,产品模块11,产品模块12,产品模块13'); // 获取执行101 bug module的泳道 +r($kanban->getLanes4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[4])) && p() && e(',指派给: 无,admin,测试1'); // 获取执行101 bug assignedTo的泳道 +r($kanban->getLanes4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[6])) && p() && e(',严重程度: 无,1,3,4'); // 获取执行101 bug severity的泳道 +r($kanban->getLanes4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[0])) && p() && e(',优先级: 无,2,4'); // 获取执行101 story pri的泳道 +r($kanban->getLanes4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[1])) && p() && e(',类型: 无,功能'); // 获取执行101 story category的泳道 +r($kanban->getLanes4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[2])) && p() && e(',所属模块: 无,产品模块14,产品模块16'); // 获取执行101 story module的泳道 +r($kanban->getLanes4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[3])) && p() && e(',来源: 无,用户,其他'); // 获取执行101 story source的泳道 +r($kanban->getLanes4GroupTest($executionIDList[4], $browseTypeList[1], $groupByList[0])) && p() && e(',优先级: 无,1,2,3'); // 获取执行102 task pri的泳道 +r($kanban->getLanes4GroupTest($executionIDList[4], $browseTypeList[1], $groupByList[2])) && p() && e(',所属模块: 无,模块13,模块37,模块40,模块43'); // 获取执行102 task module的泳道 +r($kanban->getLanes4GroupTest($executionIDList[4], $browseTypeList[1], $groupByList[4])) && p() && e(',指派给: 无'); // 获取执行102 task assignedTo的泳道 +r($kanban->getLanes4GroupTest($executionIDList[4], $browseTypeList[1], $groupByList[5])) && p() && e(',相关研发需求: 无,用户需求17'); // 获取执行102 task story的泳道 +system("./ztest init"); diff --git a/test/model/kanban/getobjectgroup.php b/test/model/kanban/getobjectgroup.php new file mode 100755 index 0000000000..fff58fe98c --- /dev/null +++ b/test/model/kanban/getobjectgroup.php @@ -0,0 +1,39 @@ +#!/usr/bin/env php +getObjectGroup(); +cid=1 +pid=1 + +*/ +$executionIDList = array('101', '102', '103', '104', '105'); +$browseTypeList = array('story', 'task', 'bug'); +$groupByList = array('pri', 'category', 'module', 'source', 'assignedTo', 'story', 'severity'); + +$kanban = new kanbanTest(); + +r($kanban->getObjectGroupTest($executionIDList[0], $browseTypeList[0], $groupByList[0])) && p() && e('4,2'); // 获取执行101 story pri的分组 +r($kanban->getObjectGroupTest($executionIDList[0], $browseTypeList[0], $groupByList[1])) && p() && e('feature'); // 获取执行101 story category的分组 +r($kanban->getObjectGroupTest($executionIDList[0], $browseTypeList[0], $groupByList[2])) && p() && e('1824,1822'); // 获取执行101 story module的分组 +r($kanban->getObjectGroupTest($executionIDList[0], $browseTypeList[0], $groupByList[3])) && p() && e('user,market'); // 获取执行101 story source的分组 +r($kanban->getObjectGroupTest($executionIDList[1], $browseTypeList[1], $groupByList[0])) && p() && e('4,2,1'); // 获取执行102 task pri的分组 +r($kanban->getObjectGroupTest($executionIDList[1], $browseTypeList[1], $groupByList[2])) && p() && e('36,33,30,24'); // 获取执行102 task module的分组 +r($kanban->getObjectGroupTest($executionIDList[1], $browseTypeList[1], $groupByList[4])) && p() && e('0'); // 获取执行102 task assignedTo的分组 +r($kanban->getObjectGroupTest($executionIDList[1], $browseTypeList[1], $groupByList[5])) && p() && e('8,6,0'); // 获取执行102 task story的分组 +r($kanban->getObjectGroupTest($executionIDList[2], $browseTypeList[2], $groupByList[0])) && p() && e('4,3,1'); // 获取执行101 bug pri的分组 +r($kanban->getObjectGroupTest($executionIDList[2], $browseTypeList[2], $groupByList[2])) && p() && e('1833,1832,1831,0'); // 获取执行101 bug module的分组 +r($kanban->getObjectGroupTest($executionIDList[2], $browseTypeList[2], $groupByList[4])) && p() && e('test1,admin'); // 获取执行101 bug assignedTo的分组 +r($kanban->getObjectGroupTest($executionIDList[2], $browseTypeList[2], $groupByList[6])) && p() && e('4,3,1'); // 获取执行101 bug severity的分组 +r($kanban->getObjectGroupTest($executionIDList[3], $browseTypeList[0], $groupByList[0])) && p() && e('4,2'); // 获取执行101 story pri的分组 +r($kanban->getObjectGroupTest($executionIDList[3], $browseTypeList[0], $groupByList[1])) && p() && e('feature'); // 获取执行101 story category的分组 +r($kanban->getObjectGroupTest($executionIDList[3], $browseTypeList[0], $groupByList[2])) && p() && e('1836,1834'); // 获取执行101 story module的分组 +r($kanban->getObjectGroupTest($executionIDList[3], $browseTypeList[0], $groupByList[3])) && p() && e('user,other'); // 获取执行101 story source的分组 +r($kanban->getObjectGroupTest($executionIDList[4], $browseTypeList[1], $groupByList[0])) && p() && e('3,2,1'); // 获取执行102 task pri的分组 +r($kanban->getObjectGroupTest($executionIDList[4], $browseTypeList[1], $groupByList[2])) && p() && e('63,60,57,33'); // 获取执行102 task module的分组 +r($kanban->getObjectGroupTest($executionIDList[4], $browseTypeList[1], $groupByList[4])) && p() && e('0'); // 获取执行102 task assignedTo的分组 +r($kanban->getObjectGroupTest($executionIDList[4], $browseTypeList[1], $groupByList[5])) && p() && e('20,18,0'); // 获取执行102 task story的分组 diff --git a/test/model/kanban/getplankanban.php b/test/model/kanban/getplankanban.php new file mode 100755 index 0000000000..b1a25f814b --- /dev/null +++ b/test/model/kanban/getplankanban.php @@ -0,0 +1,26 @@ +#!/usr/bin/env php +getPlanKanban(); +cid=1 +pid=1 + +*/ + +$productIDList = array('1', '2', '3', '41', '42'); +$branchIDList = array('0', '1', '3'); + +$kanban = new kanbanTest(); + +r($kanban->getPlanKanbanTest($productIDList[0])) && p() && e('lanes:1, cards:3'); // 测试获取产品1的计划看板 +r($kanban->getPlanKanbanTest($productIDList[1])) && p() && e('lanes:1, cards:3'); // 测试获取产品2的计划看板 +r($kanban->getPlanKanbanTest($productIDList[2])) && p() && e('lanes:1, cards:3'); // 测试获取产品3的计划看板 +r($kanban->getPlanKanbanTest($productIDList[3])) && p() && e('lanes:3, cards:2'); // 测试获取产品4的计划看板 +r($kanban->getPlanKanbanTest($productIDList[3], $branchIDList[1])) && p() && e('lanes:1, cards:1'); // 测试获取产品4 分支1的计划看板 +r($kanban->getPlanKanbanTest($productIDList[4])) && p() && e('lanes:3, cards:2'); // 测试获取产品5的计划看板 +r($kanban->getPlanKanbanTest($productIDList[4], $branchIDList[2])) && p() && e('lanes:1, cards:1'); // 测试获取产品5 分支3的计划看板 diff --git a/test/model/kanban/getrdcolumngroupbyregions.php b/test/model/kanban/getrdcolumngroupbyregions.php new file mode 100755 index 0000000000..89242d2468 --- /dev/null +++ b/test/model/kanban/getrdcolumngroupbyregions.php @@ -0,0 +1,32 @@ +#!/usr/bin/env php +getRDColumnGroupByRegions(); +cid=1 +pid=1 + +*/ + +$regions = array('1', '2', '3,4', '5,6,7', '8,9,10,11'); +$groupIDList = array('1', '2', '3', '5,6', '8,10'); + +$kanban = new kanbanTest(); + +r($kanban->getRDColumnGroupByRegionsTest($regions[0])) && p() && e('4'); // 测试获取region 1 执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[0], $groupIDList[0])) && p() && e('4'); // 测试获取region 1 group 1执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[0], $groupIDList[1])) && p() && e('0'); // 测试获取region 1 group 2执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[1])) && p() && e('4'); // 测试获取region 2 执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[1], $groupIDList[1])) && p() && e('4'); // 测试获取region 2 group 2执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[1], $groupIDList[0])) && p() && e('0'); // 测试获取region 2 group 1执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[2])) && p() && e('8'); // 测试获取region 3 执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[2], $groupIDList[2])) && p() && e('4'); // 测试获取region 3 group 3执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[2], $groupIDList[0])) && p() && e('0'); // 测试获取region 3 group 1执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[3])) && p() && e('12'); // 测试获取region 4 执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[3], $groupIDList[3])) && p() && e('8'); // 测试获取region 4 group 5,6执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[4])) && p() && e('16'); // 测试获取region 5 执行看板泳道列组 +r($kanban->getRDColumnGroupByRegionsTest($regions[4], $groupIDList[4])) && p() && e('8'); // 测试获取region 5 group 8,10执行看板泳道列组 diff --git a/test/model/kanban/getrdkanban.php b/test/model/kanban/getrdkanban.php new file mode 100755 index 0000000000..feffb0a8ae --- /dev/null +++ b/test/model/kanban/getrdkanban.php @@ -0,0 +1,31 @@ +#!/usr/bin/env php +getRDKanban(); +cid=1 +pid=1 + +*/ +$executionIDList = array('161', '162', '163', '164', '165'); +$browseTypeList = array('all', 'story', 'task', 'bug'); +$regionIDList = array('0', '101', '102', '103', '104', '105'); +$groupBy = 'pri'; + +$kanban = new kanbanTest(); + +r($kanban->getRDKanbanTest($executionIDList[0])) && p() && e('columns:27, lanes:3, cards:5'); // 获取执行161的执行看板 +r($kanban->getRDKanbanTest($executionIDList[0], $browseTypeList[0], $regionIDList[1])) && p() && e('columns:27, lanes:3, cards:8'); // 获取执行161 all region 101的执行看板 +r($kanban->getRDKanbanTest($executionIDList[0], $browseTypeList[0], $regionIDList[2])) && p() && e('columns:0, lanes:0, cards:0'); // 获取执行161 all region 102的执行看板 +r($kanban->getRDKanbanTest($executionIDList[1])) && p() && e('columns:27, lanes:3, cards:5'); // 获取执行162的执行看板 +r($kanban->getRDKanbanTest($executionIDList[1], $browseTypeList[1], $regionIDList[2])) && p() && e('columns:11, lanes:1, cards:2'); // 获取执行162 story region 102的执行看板 +r($kanban->getRDKanbanTest($executionIDList[2])) && p() && e('columns:27, lanes:3, cards:0'); // 获取执行163的执行看板 +r($kanban->getRDKanbanTest($executionIDList[2], $browseTypeList[2], $regionIDList[3])) && p() && e('columns:7, lanes:1, cards:4'); // 获取执行163 task region 103的执行看板 +r($kanban->getRDKanbanTest($executionIDList[3])) && p() && e('columns:27, lanes:3, cards:0'); // 获取执行164的执行看板 +r($kanban->getRDKanbanTest($executionIDList[3], $browseTypeList[3], $regionIDList[4])) && p() && e('columns:9, lanes:1, cards:3'); // 获取执行164 bug region 104的执行看板 +r($kanban->getRDKanbanTest($executionIDList[4])) && p() && e('columns:27, lanes:3, cards:0'); // 获取执行165的执行看板 +r($kanban->getRDKanbanTest($executionIDList[4], $browseTypeList[1], $regionIDList[5])) && p() && e('columns:11, lanes:1, cards:2'); // 获取执行165 story region 105的执行看板