* Rewrite review story page.

This commit is contained in:
wangyidong
2023-06-08 13:33:37 +08:00
parent 8267f0ca7b
commit bf78bd0c31
9 changed files with 272 additions and 47 deletions
+12 -1
View File
@@ -53,10 +53,21 @@ $config->story->form->batchCreate['reviewer'] = array('type' => 'array', 'co
$config->story->form->batchCreate['keywords'] = array('type' => 'string', 'control' => 'text', 'required' => false, 'default' => '');
$config->story->form->change = array();
$config->story->form->change['reviewer'] = array('type' => 'array', 'control' => 'multi-select', 'required' => true, 'default' => '', 'options' => '');
$config->story->form->change['reviewer'] = array('type' => 'array', 'control' => 'multi-select', 'required' => true, 'default' => '', 'filter' => 'join', 'options' => '');
$config->story->form->change['title'] = array('type' => 'string', 'control' => 'text', 'required' => true, 'filter' => 'trim');
$config->story->form->change['color'] = array('type' => 'string', 'control' => 'color', 'required' => false, 'default' => '');
$config->story->form->change['spec'] = array('type' => 'string', 'control' => 'editor', 'required' => false, 'default' => '');
$config->story->form->change['verify'] = array('type' => 'string', 'control' => 'editor', 'required' => false, 'default' => '');
$config->story->form->change['status'] = array('type' => 'string', 'control' => 'hidden', 'required' => false, 'default' => '');
$config->story->form->change['lastEditedDate'] = array('type' => 'string', 'control' => 'hidden', 'required' => false, 'default' => '');
$config->story->form->review = array();
$config->story->form->review['reviewedDate'] = array('type' => 'date', 'control' => 'text', 'required' => false, 'default' => '');
$config->story->form->review['result'] = array('type' => 'string', 'control' => 'select', 'required' => true, 'default' => '', 'options' => '', 'title' => $lang->story->reviewResult);
$config->story->form->review['assignedTo'] = array('type' => 'string', 'control' => 'select', 'required' => false, 'default' => '', 'options' => 'users');
$config->story->form->review['closedReason'] = array('type' => 'string', 'control' => 'select', 'required' => false, 'default' => '', 'options' => $lang->story->reasonList, 'title' => $lang->story->rejectedReason);
$config->story->form->review['pri'] = array('type' => 'int', 'control' => 'select', 'required' => false, 'default' => '', 'options' => $lang->story->priList);
$config->story->form->review['estimate'] = array('type' => 'float', 'control' => 'text', 'required' => false, 'default' => '');
$config->story->form->review['duplicateStory'] = array('type' => 'string', 'control' => 'text', 'required' => false, 'default' => '');
$config->story->form->review['childStories'] = array('type' => 'string', 'control' => 'text', 'required' => false, 'default' => '');
$config->story->form->review['status'] = array('type' => 'string', 'control' => 'hidden', 'required' => false, 'default' => '');
+6 -42
View File
@@ -1042,51 +1042,15 @@ class story extends control
return print(js::locate($this->createLink($module, $method, $params), 'parent'));
}
/* Get story and product. */
$story = $this->story->getById($storyID);
$product = $this->dao->findById($story->product)->from(TABLE_PRODUCT)->fields('name, id')->fetch();
$this->story->replaceURLang($story->type);
/* Set menu. */
if($this->app->tab == 'project')
{
$this->loadModel('project')->setMenu($this->session->project);
}
elseif($this->app->tab == 'product')
{
$this->product->setMenu($product->id, $story->branch);
}
elseif($this->app->tab == 'execution')
{
$this->loadModel('execution')->setMenu($this->session->execution);
}
/* Set the review result options. */
$this->commonAction($storyID);
$story = $this->view->story;
$reviewers = $this->story->getReviewerPairs($storyID, $story->version);
$this->lang->story->resultList = $this->lang->story->reviewResultList;
$this->story->getAffectedScope($story);
if($story->status == 'reviewing')
{
if($story->version == 1) unset($this->lang->story->resultList['revert']);
if($story->version > 1) unset($this->lang->story->resultList['reject']);
}
$this->view->title = $this->lang->story->review . "STORY" . $this->lang->colon . $story->title;
$this->view->product = $product;
$this->view->story = $story;
$this->view->actions = $this->action->getList('story', $storyID);
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed', "$story->lastEditedBy,$story->openedBy");
$this->view->title = $this->lang->story->review . "STORY" . $this->lang->colon . $story->title;
$this->view->fields = $this->storyZen->getFormFieldsForReview($storyID);
$this->view->reviewers = $reviewers;
$this->view->isLastOne = count(array_diff(array_keys($reviewers), explode(',', $story->reviewedBy))) == 1 ? true : false;
/* Get the affcected things. */
$this->story->getAffectedScope($this->view->story);
$this->app->loadLang('task');
$this->app->loadLang('bug');
$this->app->loadLang('testcase');
$this->app->loadLang('execution');
$this->view->isLastOne = count(array_diff(array_keys($reviewers), explode(',', $story->reviewedBy))) <= 1;
$this->display();
}
-2
View File
@@ -1,2 +0,0 @@
#mainContent .title{font-size:16px; font-weight: bold; padding-top:4px;}
#mainContent .title .label{margin-left:10px; font-weight:normal; margin-top:3px;}
+3
View File
@@ -0,0 +1,3 @@
#mainContent .form-title{font-size:16px; font-weight: bold; padding-top:4px; background:none;}
#mainContent .form-title .label{margin-left:10px; font-weight:normal; margin-top:3px;}
+47
View File
@@ -0,0 +1,47 @@
window.switchShow = function(obj)
{
var result = $(obj).val();
$('#priBox').addClass('hidden');
$('#estimateBox').addClass('hidden');
if(result == 'reject')
{
$('#rejectedReasonBox').removeClass('hidden');
$('#assignedToBox').addClass('hidden');
}
else if(result == 'revert')
{
$('#rejectedReasonBox').addClass('hidden');
$('#duplicateStoryBox').addClass('hidden');
$('#childStoriesBox').addClass('hidden');
if(isLastOne) $('#assignedToBox').removeClass('hidden');
}
else if(result == 'clarify')
{
$('#rejectedReasonBox').addClass('hidden');
$('#duplicateStoryBox').addClass('hidden');
$('#childStoriesBox').addClass('hidden');
$('#rejectedReasonBox').addClass('hidden');
if(isLastOne) $('#assignedToBox').removeClass('hidden');
}
else
{
$('#rejectedReasonBox').addClass('hidden');
$('#duplicateStoryBox').addClass('hidden');
$('#childStoriesBox').addClass('hidden');
$('#rejectedReasonBox').addClass('hidden');
if(isLastOne) $('#assignedToBox').removeClass('hidden');
if(result == 'pass')
{
$('#priBox').removeClass('hidden');
$('#estimateBox').removeClass('hidden');
}
}
}
window.setStory = function(obj)
{
var reason = $(obj).val();
$('#duplicateStoryBox').toggleClass('hidden', reason != 'duplicate');
$('#childStoriesBox').toggleClass('hidden', reason != 'subdivided');
}
+1 -1
View File
@@ -162,7 +162,7 @@ class storyModel extends model
*/
public function getAffectedScope($story)
{
$users = $this->loadModel('user')->getPairs('pofirst|nodeleted|noclosed', $story->assignedTo);
$users = $this->loadModel('user')->getPairs('pofirst|nodeleted|noclosed', "{$story->lastEditedBy},{$story->openedBy},{$story->assignedTo}");
$story = $this->storyTao->getAffectedProjects($story, $users);
$story = $this->storyTao->getAffectedBugs($story, $users);
+1 -1
View File
@@ -29,7 +29,7 @@ $formTitle = div
),
div
(
setClass('form-group title'),
setClass('form-group form-title'),
$story->title,
span
(
+153
View File
@@ -0,0 +1,153 @@
<?php
declare(strict_types=1);
/**
* The change view file of story module of ZenTaoPMS.
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Wang Yidong <yidong@easycorp.ltd>
* @package story
* @link https://www.zentao.net
*/
namespace zin;
jsVar('storyID', $story->id);
jsVar('storyType', $story->type);
jsVar('rawModule', $this->app->rawModule);
jsVar('isMultiple', count($reviewers) > 1);
jsVar('isLastOne', $isLastOne);
$formTitle = div
(
span
(
setClass('form-label'),
$lang->story->reviewAction
),
div
(
setClass('form-group form-title'),
$story->title,
span
(
setClass('label text-gray size-sm'),
$story->id
)
),
);
$formItems = array();
foreach($fields as $field => $attr)
{
$width = zget($attr, 'width', '1/3');
$fieldName = zget($attr, 'name', $field);
$control = array();
$control['type'] = $attr['control'];
if(!empty($attr['options'])) $control['items'] = $attr['options'];
$formItems[$field] = formRow
(
formGroup
(
set::width($width),
set::name($fieldName),
set::label($attr['title']),
set::control($control),
set::value($attr['default']),
set::required($attr['required'])
)
);
}
$affectedProjects = array();
$affectedTaskCount = 0;
foreach($story->executions as $executionID => $execution)
{
$teams = '';
foreach($story->teams[$executionID] as $member) $teams .= zget($users, $member) . ' ';
$affectedTaskCount += count($story->tasks[$executionID]);
$affectedProjects[] = h6
(
$execution->name,
$teams ? small(icon('group'), $teams) : null
);
$affectedProjects[] = dtable
(
set::cols($config->story->affect->projects->fields),
set::data(array_values($story->tasks[$executionID]))
);
}
$formItems['affected'] = formGroup
(
setClass('w-full'),
set::label($lang->story->checkAffection),
tabs
(
setClass('w-full'),
tabPane
(
to::suffix(label($affectedTaskCount)),
set::key('affectedProjects'),
set::title($lang->story->affectedProjects),
set::active(true),
$affectedProjects,
),
tabPane
(
to::suffix(label(count($story->bugs))),
set::key('affectedBugs'),
set::title($lang->story->affectedBugs),
empty($story->bugs) ? null : dtable
(
set::cols($config->story->affect->bugs->fields),
set::data(array_values($story->bugs))
)
),
tabPane
(
to::suffix(label(count($story->cases))),
set::key('affectedCases'),
set::title($lang->story->affectedCases),
empty($story->cases) ? null : dtable
(
set::cols($config->story->affect->cases->fields),
set::data(array_values($story->cases))
)
),
empty($story->twins) ? null : tabPane
(
to::suffix(label(count($story->twins))),
set::key('affectedTwins'),
set::title($lang->story->affectedTwins),
dtable
(
set::cols($config->story->affect->twins->fields),
set::data(array_values($story->twins))
)
),
)
);
$formItems['result']->add(on::change('switchShow(e.target);'));
$formItems['assignedTo']->add(set::id('assignedToBox'))->add(set::hidden(!$isLastOne));
$formItems['closedReason']->add(set::id('rejectedReasonBox'))->add(set::hidden(true))->add(on::change('setStory(e.target);'));
$formItems['duplicateStory']->add(set::id('duplicateStoryBox'))->add(set::hidden(true));
$formItems['pri']->add(set::id('priBox'))->add(set::hidden(true));
$formItems['estimate']->add(set::id('estimateBox'))->add(set::hidden(true));
$formItems['childStories']->add(set::id('childStoriesBox'))->add(set::hidden(true));
$formItems['status']->add(set::hidden(true));
panel
(
setClass('panel-form mx-auto'),
set::title(''),
form
(
$formTitle,
$formItems,
),
h::hr(set::class('mt-6 mb-6')),
history()
);
render();
+49
View File
@@ -435,6 +435,14 @@ class storyZen extends story
return $fields;
}
/**
* 获取变更需求的表单字段。
* Get form fields for change story.
*
* @param int $storyID
* @access protected
* @return array
*/
protected function getFormFieldsForChange(int $storyID): array
{
$story = $this->view->story;
@@ -466,6 +474,47 @@ class storyZen extends story
return $fields;
}
/**
* 获取评审需求的表单字段。
* Get form fields for review story.
*
* @param int $storyID
* @access protected
* @return array
*/
protected function getFormFieldsForReview(int $storyID): array
{
$story = $this->view->story;
$fields = $this->config->story->form->review;
$users = $this->loadModel('user')->getPairs('nodeleted|noclosed', "$story->lastEditedBy,$story->openedBy");
$resultList = $this->lang->story->reviewResultList;
if($story->status == 'reviewing')
{
if($story->version == 1) unset($resultList['revert']);
if($story->version > 1) unset($resultList['reject']);
}
foreach($fields as $field => $attr)
{
if(isset($attr['options']) and $attr['options'] == 'users') $fields[$field]['options'] = $users;
if(!isset($fields[$field]['name'])) $fields[$field]['name'] = $field;
if(!isset($fields[$field]['title'])) $fields[$field]['title'] = zget($this->lang->story, $field);
}
$fields['result']['options'] = $resultList;
$fields['reviewedDate']['default'] = helper::now();
$fields['assignedTo']['default'] = $story->assignedTo;
$fields['pri']['default'] = $story->pri;
$fields['estimate']['default'] = $story->estimate;
$fields['status']['default'] = $story->status;
$fields['closedReason']['required'] = true;
$fields['duplicateStory']['required'] = true;
$fields['comment'] = array('type' => 'string', 'control' => 'editor', 'required' => false, 'default' => '', 'name' => 'comment', 'title' => $this->lang->comment, 'width' => 'full');
return $fields;
}
/**
* 设置模块字段的表单字段。
* Set module form field.