* Rewrite review story page.
This commit is contained in:
@@ -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' => '');
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
@@ -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;}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -29,7 +29,7 @@ $formTitle = div
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('form-group title'),
|
||||
setClass('form-group form-title'),
|
||||
$story->title,
|
||||
span
|
||||
(
|
||||
|
||||
@@ -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();
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user