* Replace with common::buildOperateMenu to get the story actions.

This commit is contained in:
liumengyi
2024-03-27 13:57:45 +08:00
parent 2207675db0
commit 14252630d3
3 changed files with 148 additions and 14 deletions
+117
View File
@@ -53,3 +53,120 @@ $config->story->custom->batchCreateFields = 'module,plan,spec,pri,estimate,revie
$config->story->custom->batchEditFields = 'branch,module,plan,estimate,pri,source,stage,closedBy,closedReason';
$config->story->excludeCheckFields = ',uploadImage,category,reviewer,reviewDitto,lanes,regions,branch,pri,';
global $app, $lang;
$config->story->actionList = array();
$config->story->actionList['change']['icon'] = 'alert';
$config->story->actionList['change']['text'] = $lang->story->change;
$config->story->actionList['change']['hint'] = $lang->story->change;
$config->story->actionList['change']['url'] = array('module' => 'story', 'method' => 'change', 'params' => 'storyID={id}');
$config->story->actionList['change']['data-app'] = $app->tab;
$config->story->actionList['submitReview']['icon'] = 'confirm';
$config->story->actionList['submitReview']['text'] = $lang->story->submitReview;
$config->story->actionList['submitReview']['hint'] = $lang->story->submitReview;
$config->story->actionList['submitReview']['url'] = array('module' => 'story', 'method' => 'submitReview', 'params' => 'storyID={id}&storyType={type}');
$config->story->actionList['submitReview']['data-toggle'] = 'modal';
$config->story->actionList['recall']['icon'] = 'undo';
$config->story->actionList['recall']['text'] = $lang->story->recall;
$config->story->actionList['recall']['hint'] = $lang->story->recall;
$config->story->actionList['recall']['url'] = array('module' => 'story', 'method' => 'recall', 'params' => 'storyID={id}&from=view&confirm=no&storyType={type}');
$config->story->actionList['recall']['data-app'] = $app->tab;
$config->story->actionList['recall']['className'] = 'ajax-submit';
$config->story->actionList['recallChange']['icon'] = 'undo';
$config->story->actionList['recallChange']['text'] = $lang->story->recallChange;
$config->story->actionList['recallChange']['hint'] = $lang->story->recallChange;
$config->story->actionList['recallChange']['url'] = array('module' => 'story', 'method' => 'recall', 'params' => 'storyID={id}&from=view&confirm=no&storyType={type}');
$config->story->actionList['recallChange']['data-app'] = $app->tab;
$config->story->actionList['recallChange']['className'] = 'ajax-submit';
$config->story->actionList['review']['icon'] = 'alert';
$config->story->actionList['review']['text'] = $lang->story->review;
$config->story->actionList['review']['hint'] = $lang->story->review;
$config->story->actionList['review']['url'] = array('module' => 'story', 'method' => 'review', 'params' => 'storyID={id}&from=' . $app->tab . '&storyType={type}');
$config->story->actionList['review']['data-app'] = $app->tab;
$config->story->actionList['subdivide']['icon'] = 'split';
$config->story->actionList['subdivide']['text'] = $lang->story->subdivide;
$config->story->actionList['subdivide']['hint'] = $lang->story->subdivide;
$config->story->actionList['subdivide']['url'] = array('module' => 'story', 'method' => 'batchCreate', 'params' => 'productID={product}&branch={branch}&moduleID={module}&storyID={id}&executionID={executionID}&plan=0&storyType=story');
$config->story->actionList['subdivide']['data-app'] = $app->tab;
$config->story->actionList['assignTo']['icon'] = 'hand-right';
$config->story->actionList['assignTo']['text'] = $lang->story->assignTo;
$config->story->actionList['assignTo']['hint'] = $lang->story->assignTo;
$config->story->actionList['assignTo']['url'] = array('module' => 'story', 'method' => 'assignTo', 'params' => 'storyID={id}&kanbanGroup=default&from=&storyType={type}');
$config->story->actionList['assignTo']['data-toggle'] = 'modal';
$config->story->actionList['close']['icon'] = 'off';
$config->story->actionList['close']['text'] = $lang->story->close;
$config->story->actionList['close']['hint'] = $lang->story->close;
$config->story->actionList['close']['url'] = array('module' => 'story', 'method' => 'close', 'params' => 'storyID={id}&from=&storyType={type}');
$config->story->actionList['close']['data-toggle'] = 'modal';
$config->story->actionList['activate']['icon'] = 'magic';
$config->story->actionList['activate']['text'] = $lang->story->activate;
$config->story->actionList['activate']['hint'] = $lang->story->activate;
$config->story->actionList['activate']['url'] = array('module' => 'story', 'method' => 'activate', 'params' => 'storyID={id}&storyType={type}');
$config->story->actionList['activate']['data-toggle'] = 'modal';
$config->story->actionList['importToLib']['icon'] = 'assets';
$config->story->actionList['importToLib']['text'] = $lang->story->importToLib;
$config->story->actionList['importToLib']['hint'] = $lang->story->importToLib;
$config->story->actionList['importToLib']['url'] = '#importToLib';
$config->story->actionList['importToLib']['data-toggle'] = 'modal';
$app->loadLang('testcase');
$config->story->actionList['createTestcase']['text'] = $lang->story->create;
$config->story->actionList['createTestcase']['hint'] = $lang->story->create;
$config->story->actionList['createTestcase']['url'] = array('module' => 'testcase', 'method' => 'create', 'params' => 'product={product}&branch={branch}&moduleID=0&from=&param=0&storyid={id}');
$config->story->actionList['createTestcase']['data-size'] = 'lg';
$config->story->actionList['createTestcase']['data-toggle'] = 'modal';
$config->story->actionList['batchCreateTestcase']['text'] = $lang->story->batchCreate;
$config->story->actionList['batchCreateTestcase']['hint'] = $lang->story->batchCreate;
$config->story->actionList['batchCreateTestcase']['url'] = array('module' => 'testcase', 'method' => 'batchCreate', 'params' => 'product={product}&branch={branch}&moduleID=0&storyid={id}');
$config->story->actionList['batchCreateTestcase']['data-size'] = 'lg';
$config->story->actionList['batchCreateTestcase']['data-toggle'] = 'modal';
$config->story->actionList['testcase']['type'] = 'dropdown';
$config->story->actionList['testcase']['text'] = $lang->testcase->common;
$config->story->actionList['testcase']['hint'] = $lang->testcase->common;
$config->story->actionList['testcase']['caret'] = 'up';
$config->story->actionList['testcase']['placement'] = 'top-end';
$config->story->actionList['testcase']['items'] = array('createTestcase', 'batchCreateTestcase');
$app->loadLang('task');
$config->story->actionList['createTask']['icon'] = 'plus';
$config->story->actionList['createTask']['text'] = $lang->task->create;
$config->story->actionList['createTask']['hint'] = $lang->task->create;
$config->story->actionList['createTask']['url'] = array('module' => 'task', 'method' => 'create', 'params' => 'executionID={execution}&storyID={id}&moduleID={module}');
$config->story->actionList['createTask']['data-size'] = 'lg';
$config->story->actionList['createTask']['data-toggle'] = 'modal';
$config->story->actionList['edit']['icon'] = 'edit';
$config->story->actionList['edit']['text'] = $lang->story->edit;
$config->story->actionList['edit']['hint'] = $lang->story->edit;
$config->story->actionList['edit']['url'] = array('module' => 'story', 'method' => 'edit', 'params' => 'storyID={id}&kanbanGroup=default&storyType={type}');
$config->story->actionList['edit']['data-app'] = $app->tab;
$config->story->actionList['edit']['notInModal'] = true;
$config->story->actionList['copy']['icon'] = 'copy';
$config->story->actionList['copy']['text'] = $lang->story->copy;
$config->story->actionList['copy']['hint'] = $lang->story->copy;
$config->story->actionList['copy']['url'] = array('module' => 'story', 'method' => 'create', 'params' => 'product={product}&branch={branch}&moduleID={module}&storyID={id}&executionID=0&bugID=0&planID=0&todoID=0&extra=&storyType={type}');
$config->story->actionList['copy']['data-app'] = $app->tab;
$config->story->actionList['copy']['notInModal'] = true;
$config->story->actionList['delete']['icon'] = 'trash';
$config->story->actionList['delete']['text'] = $lang->task->delete;
$config->story->actionList['delete']['hint'] = $lang->task->delete;
$config->story->actionList['delete']['url'] = array('module' => 'story', 'method' => 'delete', 'params' => 'storyID={id}');
$config->story->actionList['delete']['className'] = 'ajax-submit';
$config->story->actions = new stdclass();
$config->story->actions->view = array();
$config->story->actions->view['mainActions'] = array('change', 'submitReview', 'recall', 'recallChange', 'review', 'subdivide', 'assignTo', 'close', 'activate', 'importToLib', 'testcase', 'createTask');
$config->story->actions->view['suffixActions'] = array('edit', 'copy', 'delete');
+27 -11
View File
@@ -3157,14 +3157,30 @@ class storyModel extends model
global $app, $config;
$action = strtolower($action);
if($action == 'recall') return strpos('reviewing,changing', $story->status) !== false;
if($action == 'close') return $story->status != 'closed';
if($action == 'activate') return $story->status == 'closed';
if($action == 'assignto') return $story->status != 'closed';
if($action == 'batchcreate' and $story->parent > 0) return false;
if($action == 'batchcreate' and !empty($story->twins)) return false;
if($action == 'batchcreate' and $story->type == 'requirement' and $story->status != 'closed') return strpos('draft,reviewing,changing', $story->status) === false;
if($action == 'submitreview' and strpos('draft,changing', $story->status) === false) return false;
if($action == 'recallchange') return $story->status == 'changing';
if($action == 'recall') return $story->status == 'reviewing';
if($action == 'close') return $story->status != 'closed';
if($action == 'activate') return $story->status == 'closed';
if($action == 'assignto') return $story->status != 'closed';
if($action == 'batchcreate' && $story->parent > 0) return false;
if($action == 'batchcreate' && !empty($story->twins)) return false;
if($action == 'submitreview' && strpos('draft,changing', $story->status) === false) return false;
if($action == 'subdivide' && (!helper::isAjaxRequest('modal') || $config->vision != 'lite')) return false;
if($action == 'batchcreate' && $story->type == 'requirement' && $story->status != 'closed') return strpos('draft,reviewing,changing', $story->status) === false;
if($action == 'createtestcase' || $action == 'batchcreatetestcase') return $config->vision != 'lite' && $story->parent >= 0 && $story->type != 'requirement';
if($action == 'createtask')
{
if($app->tab == 'project' && !empty($_SESSION['project']))
{
global $dao;
$project = $dao->findByID($_SESSION['project'])->from(TABLE_PROJECT)->fetch();
}
return ($app->tab == 'execution' || (!empty($project) && $project->multiple == '0')) && $story->status == 'active' && $story->type == 'story';
}
$disabledFeatures = ",{$config->disabledFeatures},";
if($action == 'importToLib') return in_array($config->edition, array('max', 'ipd')) && $app->tab == 'project' && common::hasPriv('story', 'importToLib') && strpos($disabledFeatures, ',assetlibStorylib,') === false && strpos($disabledFeatures, ',assetlib,') === false;
static $shadowProducts = array();
static $taskGroups = array();
@@ -3176,7 +3192,7 @@ class storyModel extends model
foreach($stmt as $row) $shadowProducts[$row->id] = $row->id;
}
if($hasShadow and empty($taskGroups[$story->id])) $taskGroups[$story->id] = $app->dbQuery('SELECT id FROM ' . TABLE_TASK . " WHERE story = $story->id")->fetch();
if($hasShadow && empty($taskGroups[$story->id])) $taskGroups[$story->id] = $app->dbQuery('SELECT id FROM ' . TABLE_TASK . " WHERE story = $story->id")->fetch();
if(isset($story->parent) && $story->parent < 0 && strpos($config->story->list->actionsOperatedParentStory, ",$action,") === false) return false;
@@ -3193,8 +3209,8 @@ class storyModel extends model
$story->notReview = isset($story->notReview) ? $story->notReview : array();
$isSuperReviewer = strpos(',' . trim(zget($config->story, 'superReviewers', ''), ',') . ',', ',' . $app->user->account . ',');
if($action == 'change') return (($isSuperReviewer !== false or count($story->reviewer) == 0 or count($story->notReview) == 0) and $story->status == 'active');
if($action == 'review') return (($isSuperReviewer !== false or in_array($app->user->account, $story->notReview)) and $story->status == 'reviewing');
if($action == 'change') return (($isSuperReviewer !== false || count($story->reviewer) == 0 || count($story->notReview) == 0) && $story->status == 'active');
if($action == 'review') return (($isSuperReviewer !== false || in_array($app->user->account, $story->notReview)) && $story->status == 'reviewing');
return true;
}
+4 -3
View File
@@ -17,9 +17,6 @@ include($this->app->getModuleRoot() . 'ai/ui/promptmenu.html.php');
$isInModal = isInModal();
$isRequirement = $story->type == 'requirement';
$isStoryType = $story->type == 'story';
$actions = $this->story->buildOperateMenu($story, 'view', $project ? $project : null);
if($story->deleted) $actions = array();
if($isInModal) $actions = false;
/* 版本列表。Version list. */
$versions = array();
@@ -173,6 +170,10 @@ $versionBtn = count($versions) > 1 ? to::title(dropdown
set::items($versions)
)) : null;
$actions = $story->deleted || $isInModal ? array() : $this->loadModel('common')->buildOperateMenu($story);
$hasDivider = !empty($actions['mainActions']) && !empty($actions['suffixActions']);
$actions = array_merge($actions['mainActions'], array(array('type' => 'divider')), $actions['suffixActions']);
if(!$hasDivider) unset($actions['type']);
detail
(
set::objectType('story'),