* code for task#803.
* add batchEdit for story.
This commit is contained in:
@@ -1553,6 +1553,16 @@ INSERT INTO `zt_groupPriv` (`company`, `group`, `module`, `method`) VALUES
|
||||
(1, 3, 'todo', 'batchEdit'),
|
||||
(1, 4, 'todo', 'batchEdit'),
|
||||
(1, 5, 'todo', 'batchEdit'),
|
||||
(1, 1, 'story', 'batchEdit'),
|
||||
(1, 2, 'story', 'batchEdit'),
|
||||
(1, 3, 'story', 'batchEdit'),
|
||||
(1, 4, 'story', 'batchEdit'),
|
||||
(1, 5, 'story', 'batchEdit'),
|
||||
(1, 1, 'story', 'batchClose'),
|
||||
(1, 2, 'story', 'batchClose'),
|
||||
(1, 3, 'story', 'batchClose'),
|
||||
(1, 4, 'story', 'batchClose'),
|
||||
(1, 5, 'story', 'batchClose'),
|
||||
(1, 1, 'task', 'batchEdit'),
|
||||
(1, 2, 'task', 'batchEdit'),
|
||||
(1, 3, 'task', 'batchEdit'),
|
||||
|
||||
@@ -157,7 +157,7 @@ $lang->release->menu = $lang->product->menu;
|
||||
/* 项目视图菜单设置。*/
|
||||
$lang->project->menu->list = '%s';
|
||||
$lang->project->menu->task = array('link' => '任务|project|task|projectID=%s', 'subModule' => 'task', 'alias' => 'grouptask,importtask');
|
||||
$lang->project->menu->story = array('link' => '需求|project|story|projectID=%s');
|
||||
$lang->project->menu->story = array('link' => '需求|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'batchedit');
|
||||
$lang->project->menu->bug = 'Bug|project|bug|projectID=%s';
|
||||
$lang->project->menu->dynamic = '动态|project|dynamic|projectID=%s';
|
||||
$lang->project->menu->build = array('link' => '版本|project|build|projectID=%s', 'subModule' => 'build');
|
||||
|
||||
@@ -57,12 +57,14 @@ $lang->resource->product->ajaxGetPlans = 'ajaxGetPlans';
|
||||
$lang->resource->story->create = 'create';
|
||||
$lang->resource->story->batchCreate = 'batchCreate';
|
||||
$lang->resource->story->edit = 'edit';
|
||||
$lang->resource->story->batchEdit = 'batchEdit';
|
||||
$lang->resource->story->export = 'export';
|
||||
$lang->resource->story->delete = 'delete';
|
||||
$lang->resource->story->view = 'view';
|
||||
$lang->resource->story->change = 'lblChange';
|
||||
$lang->resource->story->review = 'lblReview';
|
||||
$lang->resource->story->close = 'lblClose';
|
||||
$lang->resource->story->batchClose = 'batchClose';
|
||||
$lang->resource->story->activate = 'lblActivate';
|
||||
$lang->resource->story->tasks = 'tasks';
|
||||
$lang->resource->story->report = 'reportChart';
|
||||
@@ -374,6 +376,8 @@ $lang->changelog['3.1'][] = 'todo-batchCreate';
|
||||
|
||||
$lang->changelog['3.2'][] = 'my-changePassword';
|
||||
$lang->changelog['3.2'][] = 'todo-batchEdit';
|
||||
$lang->changelog['3.2'][] = 'story-batchEdit';
|
||||
$lang->changelog['3.2'][] = 'story-batchClose';
|
||||
$lang->changelog['3.2'][] = 'task-batchEdit';
|
||||
$lang->changelog['3.2'][] = 'bug-batchEdit';
|
||||
$lang->changelog['3.2'][] = 'testcase-batchEdit';
|
||||
|
||||
@@ -7,3 +7,20 @@ function browseByModule()
|
||||
$('#featurebar .active').removeClass('active');
|
||||
$('#bymoduleTab').addClass('active');
|
||||
}
|
||||
|
||||
/**
|
||||
* Change form action.
|
||||
*
|
||||
* @param formName $formName
|
||||
* @param actionName $actionName
|
||||
* @param actionLink $actionLink
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function changeAction(formName, actionName, actionLink)
|
||||
{
|
||||
if(actionName == 'batchEdit') $('#' + formName).attr('target', '');
|
||||
if(actionName == 'batchClose') $('#' + formName).attr('target', 'hiddenwin');
|
||||
$('#' + formName).attr('action', actionLink).submit();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,81 +38,105 @@ var browseType = '<?php echo $browseType;?>';
|
||||
</div>
|
||||
</div>
|
||||
<div id='querybox' class='<?php if($browseType !='bysearch') echo 'hidden';?>'><?php echo $searchForm;?></div>
|
||||
<table class='cont-lt1'>
|
||||
<tr valign='top'>
|
||||
<td class='side <?php echo $treeClass;?>' id='treebox'>
|
||||
<div class='box-title'><?php echo $productName;?></div>
|
||||
<div class='box-content'>
|
||||
<?php echo $moduleTree;?>
|
||||
<div class='a-right'>
|
||||
<?php if(common::hasPriv('product', 'edit')) echo html::a($this->createLink('product', 'edit', "productID=$productID"), $lang->edit);?>
|
||||
<?php if(common::hasPriv('product', 'delete')) echo html::a($this->createLink('product', 'delete', "productID=$productID&confirm=no"), $lang->delete, 'hiddenwin');?>
|
||||
<?php if(common::hasPriv('tree', 'browse')) echo html::a($this->createLink('tree', 'browse', "rootID=$productID&view=story"), $lang->tree->manage);?>
|
||||
<form method='post' id='productStoryForm'>
|
||||
<table class='cont-lt1'>
|
||||
<tr valign='top'>
|
||||
<td class='side <?php echo $treeClass;?>' id='treebox'>
|
||||
<div class='box-title'><?php echo $productName;?></div>
|
||||
<div class='box-content'>
|
||||
<?php echo $moduleTree;?>
|
||||
<div class='a-right'>
|
||||
<?php if(common::hasPriv('product', 'edit')) echo html::a($this->createLink('product', 'edit', "productID=$productID"), $lang->edit);?>
|
||||
<?php if(common::hasPriv('product', 'delete')) echo html::a($this->createLink('product', 'delete', "productID=$productID&confirm=no"), $lang->delete, 'hiddenwin');?>
|
||||
<?php if(common::hasPriv('tree', 'browse')) echo html::a($this->createLink('tree', 'browse', "rootID=$productID&view=story"), $lang->tree->manage);?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class='divider <?php echo $treeClass;?>'></td>
|
||||
<td>
|
||||
<table class='table-1 fixed colored tablesorter datatable'>
|
||||
<thead>
|
||||
<tr class='colhead'>
|
||||
<?php $vars = "productID=$productID&browseType=$browseType¶m=$moduleID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
|
||||
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th class='w-pri'><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
|
||||
<th class='w-p30'><?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
|
||||
<th><?php common::printOrderLink('plan', $orderBy, $vars, $lang->story->planAB);?></th>
|
||||
<th><?php common::printOrderLink('source', $orderBy, $vars, $lang->story->source);?></th>
|
||||
<th><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
|
||||
<th><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
|
||||
<th class='w-hour'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
|
||||
<th><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
|
||||
<th><?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
|
||||
<th class='w-150px {sorter:false}'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $totalEstimate = 0.0;?>
|
||||
<?php foreach($stories as $key => $story):?>
|
||||
<?php
|
||||
$viewLink = $this->createLink('story', 'view', "storyID=$story->id");
|
||||
$totalEstimate += $story->estimate;
|
||||
$canView = common::hasPriv('story', 'view');
|
||||
?>
|
||||
<tr class='a-center'>
|
||||
<td><?php if($canView) echo html::a($viewLink, sprintf('%03d', $story->id)); else printf('%03d', $story->id);?></td>
|
||||
<td><?php echo $lang->story->priList[$story->pri];?></td>
|
||||
<td class='a-left nobr'><nobr><?php echo html::a($viewLink, $story->title);?></nobr></td>
|
||||
<td class='nobr'><?php echo $story->planTitle;?></td>
|
||||
<td><?php echo $lang->story->sourceList[$story->source];?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
<td><?php echo $story->estimate;?></td>
|
||||
<td class='<?php echo $story->status;?>'><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
<td>
|
||||
<?php
|
||||
$vars = "story={$story->id}";
|
||||
if(!common::printLink('testcase', 'create', "productID=$story->product&module=0&from=¶m=0&$vars", $lang->story->createCase)) echo $lang->story->createCase . ' ';
|
||||
if(!($story->status != 'closed' and common::printLink('story', 'change', $vars, $lang->story->change))) echo $lang->story->change . ' ';
|
||||
if(!(($story->status == 'draft' or $story->status == 'changed') and common::printLink('story', 'review', $vars, $lang->story->review))) echo $lang->story->review . ' ';
|
||||
if(!common::printLink('story', 'edit', $vars, $lang->edit)) echo $lang->edit;
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan='11' class='a-right'>
|
||||
<div class='f-left'><?php printf($lang->product->storySummary, count($stories), $totalEstimate);?></div>
|
||||
<?php $pager->show();?>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td class='divider <?php echo $treeClass;?>'></td>
|
||||
<td>
|
||||
<table class='table-1 fixed colored tablesorter datatable'>
|
||||
<thead>
|
||||
<tr class='colhead'>
|
||||
<?php $vars = "productID=$productID&browseType=$browseType¶m=$moduleID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
|
||||
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th class='w-pri'><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
|
||||
<th class='w-p30'><?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
|
||||
<th><?php common::printOrderLink('plan', $orderBy, $vars, $lang->story->planAB);?></th>
|
||||
<th><?php common::printOrderLink('source', $orderBy, $vars, $lang->story->source);?></th>
|
||||
<th><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
|
||||
<th><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
|
||||
<th class='w-hour'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
|
||||
<th><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
|
||||
<th><?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
|
||||
<th class='w-150px {sorter:false}'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $totalEstimate = 0.0;?>
|
||||
<?php foreach($stories as $key => $story):?>
|
||||
<?php
|
||||
$viewLink = $this->createLink('story', 'view', "storyID=$story->id");
|
||||
$totalEstimate += $story->estimate;
|
||||
$canView = common::hasPriv('story', 'view');
|
||||
?>
|
||||
<tr class='a-center'>
|
||||
<td>
|
||||
<input type='checkbox' name='storyIDList[<?php echo $story->id;?>]' value='<?php echo $story->id;?>' />
|
||||
<?php if($canView) echo html::a($viewLink, sprintf('%03d', $story->id)); else printf('%03d', $story->id);?>
|
||||
</td>
|
||||
<td><?php echo $lang->story->priList[$story->pri];?></td>
|
||||
<td class='a-left nobr'><nobr><?php echo html::a($viewLink, $story->title);?></nobr></td>
|
||||
<td class='nobr'><?php echo $story->planTitle;?></td>
|
||||
<td><?php echo $lang->story->sourceList[$story->source];?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
<td><?php echo $story->estimate;?></td>
|
||||
<td class='<?php echo $story->status;?>'><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
<td>
|
||||
<?php
|
||||
$vars = "story={$story->id}";
|
||||
if(!common::printLink('testcase', 'create', "productID=$story->product&module=0&from=¶m=0&$vars", $lang->story->createCase)) echo $lang->story->createCase . ' ';
|
||||
if(!($story->status != 'closed' and common::printLink('story', 'change', $vars, $lang->story->change))) echo $lang->story->change . ' ';
|
||||
if(!(($story->status == 'draft' or $story->status == 'changed') and common::printLink('story', 'review', $vars, $lang->story->review))) echo $lang->story->review . ' ';
|
||||
if(!common::printLink('story', 'edit', $vars, $lang->edit)) echo $lang->edit;
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan='11' class='a-right'>
|
||||
<div class='f-left'>
|
||||
<?php
|
||||
if(count($stories))
|
||||
{
|
||||
echo html::selectAll() . html::selectReverse();
|
||||
|
||||
if(common::hasPriv('story', 'batchEdit'))
|
||||
{
|
||||
$actionLink = $this->createLink('story', 'batchEdit', "from=productBrowse&productID=$productID&projectID=0&orderBy=$orderBy");
|
||||
echo html::commonButton($lang->story->batchEdit, "onclick=\"changeAction('productStoryForm', 'batchEdit', '$actionLink')\"");
|
||||
}
|
||||
if(common::hasPriv('story', 'batchClose') and strtolower($browseType) != 'closedbyme' and strtolower($browseType) != 'closedstory')
|
||||
{
|
||||
$actionLink = $this->createLink('story', 'batchClose');
|
||||
echo html::commonButton($lang->story->batchClose, "onclick=\"changeAction('productStoryForm', 'batchClose', '$actionLink')\"");
|
||||
}
|
||||
}
|
||||
printf($lang->product->storySummary, count($stories), $totalEstimate);
|
||||
?>
|
||||
</div>
|
||||
<?php $pager->show();?>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<script language='javascript'>
|
||||
$('#module<?php echo $moduleID;?>').addClass('active')
|
||||
$('#<?php echo $browseType;?>Tab').addClass('active')
|
||||
|
||||
@@ -2,3 +2,19 @@ $(document).ready(function()
|
||||
{
|
||||
$("a.iframe").colorbox({width:640, height:480, iframe:true, transition:'none'});
|
||||
});
|
||||
|
||||
/**
|
||||
* Change form action.
|
||||
*
|
||||
* @param formName $formName
|
||||
* @param actionName $actionName
|
||||
* @param actionLink $actionLink
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function changeAction(formName, actionName, actionLink)
|
||||
{
|
||||
if(actionName == 'batchEdit') $('#' + formName).attr('target', '');
|
||||
if(actionName == 'batchClose') $('#' + formName).attr('target', 'hiddenwin');
|
||||
$('#' + formName).attr('action', actionLink).submit();
|
||||
}
|
||||
|
||||
@@ -12,63 +12,93 @@
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/tablesorter.html.php';?>
|
||||
<table class='table-1 fixed colored tablesorter datatable'>
|
||||
<caption class='caption-tl'>
|
||||
<div class='f-left'><?php echo $lang->project->story;?></div>
|
||||
<div class='f-right'>
|
||||
<?php
|
||||
if($productID) common::printLink('story', 'create', "productID=$productID&moduleID=0&story=0&project=$project->id", $lang->story->create);
|
||||
if(common::hasPriv('project', 'linkstory')) echo html::a($this->createLink('project', 'linkstory', "project=$project->id"), $lang->project->linkStory);
|
||||
?>
|
||||
</div>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr class='colhead'>
|
||||
<?php $vars = "projectID={$project->id}&orderBy=%s"; ?>
|
||||
<th class='w-id {sorter:false}'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th class='w-pri {sorter:false}'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
|
||||
<th class='{sorter:false}'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
|
||||
<th class='w-user {sorter:false}'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
|
||||
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
|
||||
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
|
||||
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
|
||||
<th class='w-status {sorter:false}'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
|
||||
<th class='w-50px'> <?php echo $lang->story->taskCount;?></th>
|
||||
<th class='w-100px {sorter:false}'> <?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $totalEstimate = 0;?>
|
||||
<?php foreach($stories as $key => $story):?>
|
||||
<?php
|
||||
$storyLink = $this->createLink('story', 'view', "storyID=$story->id");
|
||||
$totalEstimate += $story->estimate;
|
||||
?>
|
||||
<tr class='a-center'>
|
||||
<td><?php echo html::a($storyLink, sprintf('%03d', $story->id));?></td>
|
||||
<td><?php echo $lang->story->priList[$story->pri];?></td>
|
||||
<td class='a-left nobr'><?php echo html::a($storyLink,$story->title);?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
<td><?php echo $story->estimate;?></td>
|
||||
<td class='<?php echo $story->status;?>'><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
<td class='linkbox'>
|
||||
<?php
|
||||
$tasksLink = $this->createLink('story', 'tasks', "storyID=$story->id&projectID=$project->id");
|
||||
$storyTasks[$story->id] > 0 ? print(html::a($tasksLink, $storyTasks[$story->id], '', 'class="iframe"')) : print(0);
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<form method='post' id='projectStoryForm'>
|
||||
<table class='table-1 fixed colored tablesorter datatable'>
|
||||
<caption class='caption-tl'>
|
||||
<div class='f-left'><?php echo $lang->project->story;?></div>
|
||||
<div class='f-right'>
|
||||
<?php
|
||||
$param = "projectID={$project->id}&story={$story->id}";
|
||||
common::printLink('task', 'create', $param, $lang->project->wbs);
|
||||
common::printLink('project', 'unlinkStory', $param, $lang->unlink, 'hiddenwin');
|
||||
if($productID) common::printLink('story', 'create', "productID=$productID&moduleID=0&story=0&project=$project->id", $lang->story->create);
|
||||
if(common::hasPriv('project', 'linkstory')) echo html::a($this->createLink('project', 'linkstory', "project=$project->id"), $lang->project->linkStory);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
<tfoot><tr><td colspan='10'><?php printf($lang->product->storySummary, count($stories), $totalEstimate);?></td></tr></tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr class='colhead'>
|
||||
<?php $vars = "projectID={$project->id}&orderBy=%s"; ?>
|
||||
<th class='w-id {sorter:false}'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th class='w-pri {sorter:false}'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
|
||||
<th class='{sorter:false}'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
|
||||
<th class='w-user {sorter:false}'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
|
||||
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
|
||||
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
|
||||
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
|
||||
<th class='w-status {sorter:false}'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
|
||||
<th class='w-50px'> <?php echo $lang->story->taskCount;?></th>
|
||||
<th class='w-100px {sorter:false}'> <?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $totalEstimate = 0;?>
|
||||
<?php foreach($stories as $key => $story):?>
|
||||
<?php
|
||||
$storyLink = $this->createLink('story', 'view', "storyID=$story->id");
|
||||
$totalEstimate += $story->estimate;
|
||||
?>
|
||||
<tr class='a-center'>
|
||||
<td>
|
||||
<input type='checkbox' name='storyIDList[<?php echo $story->id;?>]' value='<?php echo $story->id;?>' />
|
||||
<?php echo html::a($storyLink, sprintf('%03d', $story->id));?>
|
||||
</td>
|
||||
<td><?php echo $lang->story->priList[$story->pri];?></td>
|
||||
<td class='a-left nobr'><?php echo html::a($storyLink,$story->title);?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
<td><?php echo $story->estimate;?></td>
|
||||
<td class='<?php echo $story->status;?>'><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
<td class='linkbox'>
|
||||
<?php
|
||||
$tasksLink = $this->createLink('story', 'tasks', "storyID=$story->id&projectID=$project->id");
|
||||
$storyTasks[$story->id] > 0 ? print(html::a($tasksLink, $storyTasks[$story->id], '', 'class="iframe"')) : print(0);
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$param = "projectID={$project->id}&story={$story->id}";
|
||||
common::printLink('task', 'create', $param, $lang->project->wbs);
|
||||
common::printLink('project', 'unlinkStory', $param, $lang->unlink, 'hiddenwin');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan='10'>
|
||||
<div class='f-left'>
|
||||
<?php
|
||||
if(count($stories))
|
||||
{
|
||||
echo html::selectAll() . html::selectReverse();
|
||||
|
||||
if(common::hasPriv('story', 'batchEdit'))
|
||||
{
|
||||
$actionLink = $this->createLink('story', 'batchEdit', "from=projectStory&productID=0&projectID=$project->id&orderBy=$orderBy");
|
||||
echo html::commonButton($lang->story->batchEdit, "onclick=\"changeAction('projectStoryForm', 'batchEdit', '$actionLink')\"");
|
||||
}
|
||||
if(common::hasPriv('story', 'batchClose'))
|
||||
{
|
||||
$actionLink = $this->createLink('story', 'batchClose', "from=projectStory&productID=0");
|
||||
echo html::commonButton($lang->story->batchClose, "onclick=\"changeAction('projectStoryForm', 'batchClose', '$actionLink')\"");
|
||||
}
|
||||
}
|
||||
printf($lang->product->storySummary, count($stories), $totalEstimate);
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</form>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -21,6 +21,7 @@ class story extends control
|
||||
{
|
||||
parent::__construct();
|
||||
$this->loadModel('product');
|
||||
$this->loadModel('project');
|
||||
$this->loadModel('tree');
|
||||
$this->loadModel('user');
|
||||
}
|
||||
@@ -267,6 +268,96 @@ class story extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch edit story.
|
||||
*
|
||||
* @param string $from productBrowse|projectStory|storyBatchEdit.
|
||||
* @param int $productID
|
||||
* @param int $projectID
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchEdit($from = '', $productID = 0, $projectID = 0, $orderBy = '')
|
||||
{
|
||||
/* Get post data for product-Browse or project-Story. */
|
||||
if($from == 'productBrowse' or $from == 'projectStory')
|
||||
{
|
||||
/* Init vars. */
|
||||
$editedStories = array();
|
||||
$storyIDList = $this->post->storyIDList ? $this->post->storyIDList : array();
|
||||
$columns = 9;
|
||||
$showSuhosinInfo = false;
|
||||
|
||||
/* Get all stories. */
|
||||
if(!$projectID)
|
||||
{
|
||||
/* Set menu. */
|
||||
$this->product->setMenu($this->product->getPairs('nodeleted'), $productID);
|
||||
$allStories = $this->dao->select('*')->from(TABLE_STORY)->where($this->session->storyReport)->orderBy($orderBy)->fetchAll('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->lang->story->menu = $this->lang->project->menu;
|
||||
$this->project->setMenu($this->project->getPairs('nodeleted'), $projectID);
|
||||
$this->lang->set('menugroup.story', 'project');
|
||||
$allStories = $this->story->getProjectStories($projectID, $orderBy);
|
||||
}
|
||||
if(!$allStories) $allStories = array();
|
||||
|
||||
/* Initialize the stories whose need to edited. */
|
||||
foreach($allStories as $story) if(in_array($story->id, $storyIDList)) $editedStories[$story->id] = $story;
|
||||
|
||||
/* Judge whether the editedStories is too large. */
|
||||
$showSuhosinInfo = $this->loadModel('common')->judgeSuhosinSetting(count($editedStories), $columns);
|
||||
|
||||
/* Set the sessions. */
|
||||
$this->app->session->set('showSuhosinInfo', $showSuhosinInfo);
|
||||
|
||||
/* Assign. */
|
||||
if(!$projectID)
|
||||
{
|
||||
$product = $this->product->getByID($productID);
|
||||
$this->view->header['title'] = $product->name . $this->lang->colon . $this->lang->story->batchEdit;
|
||||
}
|
||||
else
|
||||
{
|
||||
$project = $this->project->getByID($projectID);
|
||||
$this->view->header['title'] = $project->name . $this->lang->colon . $this->lang->story->batchEdit;
|
||||
}
|
||||
if($showSuhosinInfo) $this->view->suhosinInfo = $this->lang->suhosinInfo;
|
||||
$this->view->position[] = $this->lang->story->common;
|
||||
$this->view->position[] = $this->lang->story->batchEdit;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted');
|
||||
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'story');
|
||||
$this->view->plans = $this->loadModel('productplan')->getPairs($productID);
|
||||
$this->view->productID = $productID;
|
||||
$this->view->editedStories = $editedStories;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
/* Get post data for story-batchEdit. */
|
||||
elseif($from == 'storyBatchEdit')
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
|
||||
$allChanges = $this->story->batchUpdate();
|
||||
|
||||
if($allChanges)
|
||||
{
|
||||
foreach($allChanges as $storyID => $changes)
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('story', $storyID, 'Edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
$this->sendMail($storyID, $actionID);
|
||||
}
|
||||
}
|
||||
}
|
||||
die(js::locate($this->session->storyList, 'parent'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change a story.
|
||||
*
|
||||
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Set duplicate field.
|
||||
*
|
||||
* @param string $resolution
|
||||
* @param int $storyID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setDuplicateAndChild(resolution, storyID)
|
||||
{
|
||||
if(resolution == 'duplicate')
|
||||
{
|
||||
$('#childStoryBox' + storyID).hide();
|
||||
$('#duplicateStoryBox' + storyID).show();
|
||||
}
|
||||
else if(resolution == 'subdivided')
|
||||
{
|
||||
$('#duplicateStoryBox' + storyID).hide();
|
||||
$('#childStoryBox' + storyID).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#duplicateStoryBox' + storyID).hide();
|
||||
$('#childStoryBox' + storyID).hide();
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,9 @@ $lang->story->change = "Change";
|
||||
$lang->story->changed = 'Changed';
|
||||
$lang->story->review = 'Review';
|
||||
$lang->story->edit = "Edit";
|
||||
$lang->story->batchEdit = "Batch edit";
|
||||
$lang->story->close = 'Close';
|
||||
$lang->story->batchClose = 'Batch close';
|
||||
$lang->story->activate = 'Activate';
|
||||
$lang->story->delete = "Delete";
|
||||
$lang->story->view = "Info";
|
||||
@@ -165,6 +167,7 @@ $lang->story->needNotReview = "needn't review";
|
||||
$lang->story->afterSubmit = "After created";
|
||||
$lang->story->successSaved = "Successfully saved";
|
||||
$lang->story->confirmDelete = "Are you sure to delete this story?";
|
||||
$lang->story->confirmBatchClose = "Are you sure to close those stories?";
|
||||
$lang->story->errorFormat = 'Error format';
|
||||
$lang->story->errorEmptyTitle = "Title can't be empty";
|
||||
$lang->story->mustChooseResult = 'Must choose s result';
|
||||
|
||||
@@ -17,7 +17,9 @@ $lang->story->change = "变更";
|
||||
$lang->story->changed = '需求变更';
|
||||
$lang->story->review = '评审';
|
||||
$lang->story->edit = "编辑需求";
|
||||
$lang->story->batchEdit = "批量编辑";
|
||||
$lang->story->close = '关闭';
|
||||
$lang->story->batchClose = '批量关闭';
|
||||
$lang->story->activate = '激活';
|
||||
$lang->story->delete = "删除需求";
|
||||
$lang->story->view = "需求详情";
|
||||
@@ -165,6 +167,7 @@ $lang->story->needNotReview = '不需要评审';
|
||||
$lang->story->afterSubmit = "添加之后";
|
||||
$lang->story->successSaved = "需求成功添加,";
|
||||
$lang->story->confirmDelete = "您确认删除该需求吗?";
|
||||
$lang->story->confirmBatchClose = "您确认关闭这些需求吗?";
|
||||
$lang->story->errorFormat = '需求数据有误';
|
||||
$lang->story->errorEmptyTitle = '标题不能为空';
|
||||
$lang->story->mustChooseResult = '必须选择评审结果';
|
||||
|
||||
@@ -345,6 +345,84 @@ class storyModel extends model
|
||||
if(!dao::isError()) return common::createChanges($oldStory, $story);
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch update story.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchUpdate()
|
||||
{
|
||||
/* Init vars. */
|
||||
$stories = array();
|
||||
$allChanges = array();
|
||||
$now = helper::now();
|
||||
$storyIDList = $this->post->storyIDList ? $this->post->storyIDList : array();
|
||||
|
||||
/* Adjust whether the post data is complete, if not, remove the last element of $taskIDList. */
|
||||
if($this->session->showSuhosinInfo) array_pop($storyIDList);
|
||||
|
||||
/* Init $stories. */
|
||||
if(!empty($storyIDList))
|
||||
{
|
||||
foreach($storyIDList as $storyID)
|
||||
{
|
||||
$oldStory = $this->getById($storyID);
|
||||
|
||||
$story->lastEditedBy = $this->app->user->account;
|
||||
$story->lastEditedDate = $now;
|
||||
$story->status = $oldStory->status;
|
||||
$story->title = htmlspecialchars($this->post->titles[$storyID]);
|
||||
$story->estimate = $this->post->estimates[$storyID];
|
||||
$story->pri = $this->post->pris[$storyID];
|
||||
$story->module = $this->post->modules[$storyID];
|
||||
$story->plan = $this->post->plans[$storyID];
|
||||
$story->source = $this->post->sources[$storyID];
|
||||
$story->stage = isset($this->post->stages[$storyID]) ? $this->post->stages[$storyID] : $oldStory->stage;
|
||||
$story->closedBy = isset($this->post->closedBys[$storyID]) ? $this->post->closedBys[$storyID] : $oldStory->closedBy;
|
||||
$story->closedReason = isset($this->post->closedReasons[$storyID]) ? $this->post->closedReasons[$storyID] : $oldStory->closedReason;
|
||||
$story->duplicateStory = isset($this->post->duplicateStories[$storyID]) ? $this->post->duplicateStories[$storyID] : $oldStory->duplicateStory;
|
||||
$story->childStories = isset($this->post->childStoriesIDList[$storyID]) ? $this->post->childStoriesIDList[$storyID] : $oldStory->childStories;
|
||||
|
||||
if($story->title != $oldStory->title) $story->status = 'changed';
|
||||
if($story->plan !== false and $story->plan == '') $story->plan = 0;
|
||||
if($story->closedBy != false and $oldStory->closedDate == '') $story->closedDate = $now;
|
||||
if($story->closedReason != false and $oldStory->closedDate == '') $story->closedDate = $now;
|
||||
if($story->closedBy != false or $story->closedReason != false) $story->status = 'closed';
|
||||
if($story->closedReason != false and $story->closedBy == false) $story->closedBy = $this->app->user->account;
|
||||
|
||||
$stories[$storyID] = $story;
|
||||
unset($story);
|
||||
}
|
||||
|
||||
foreach($stories as $storyID => $story)
|
||||
{
|
||||
$oldStory = $this->getById($storyID);
|
||||
|
||||
$this->dao->update(TABLE_STORY)->data($story)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->story->edit->requiredFields, 'notempty')
|
||||
->checkIF($story->closedBy, 'closedReason', 'notempty')
|
||||
->checkIF($story->closedReason == 'done', 'stage', 'notempty')
|
||||
->checkIF($story->closedReason == 'duplicate', 'duplicateStory', 'notempty')
|
||||
->checkIF($story->closedReason == 'subdivided', 'childStories', 'notempty')
|
||||
->where('id')->eq((int)$storyID)
|
||||
->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$allChanges[$storyID] = common::createChanges($oldStory, $story);
|
||||
}
|
||||
else
|
||||
{
|
||||
die(js::error('story#' . $storyID . dao::getError(true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $allChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Review a story.
|
||||
*
|
||||
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* The batch edit view of story module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2012 青岛易软天创网络科技有限公司 (QingDao Nature Easy Soft Network Technology Co,LTD www.cnezsoft.com)
|
||||
* @license LGPL (http://www.gnu.org/licenses/lgpl.html)
|
||||
* @author Congzhi Chen <congzhi@cnezsoft.com>
|
||||
* @package story
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<form method='post' target='hiddenwin' action="<?php echo $this->inLink('batchEdit', "from=storyBatchEdit&productID=$productID")?>">
|
||||
<table class='table-1 fixed'>
|
||||
<caption><?php echo $lang->story->common . $lang->colon . $lang->story->batchEdit;?></caption>
|
||||
<tr>
|
||||
<th class='w-30px'> <?php echo $lang->idAB;?></th>
|
||||
<th> <?php echo $lang->story->title;?></th>
|
||||
<th class='w-30px'> <?php echo $lang->story->estimateAB;?></th>
|
||||
<th class='w-50px'> <?php echo $lang->priAB;?></th>
|
||||
<th class='w-100px'><?php echo $lang->story->module;?></th>
|
||||
<th class='w-100px'><?php echo $lang->story->planAB;?></th>
|
||||
<th class='w-80px'> <?php echo $lang->story->source;?></th>
|
||||
<th class='w-60px'> <?php echo $lang->story->status;?></th>
|
||||
<th class='w-80px'> <?php echo $lang->story->stageAB;?></th>
|
||||
<th class='w-100px'><?php echo $lang->story->closedBy;?></th>
|
||||
<th class='w-120px'><?php echo $lang->story->closedReason;?></th>
|
||||
</tr>
|
||||
<?php foreach($editedStories as $story):?>
|
||||
<tr class='a-center'>
|
||||
<td><?php echo $story->id . html::hidden("storyIDList[$story->id]", $story->id);?></td>
|
||||
<td><?php echo html::input("titles[$story->id]", $story->title, 'class=text-1'); echo "<span class='star'>*</span>";?></td>
|
||||
<td><?php echo html::input("estimates[$story->id]", $story->estimate, 'class=text-1'); echo "<span class='star'>*</span>";?></td>
|
||||
<td><?php echo html::select("pris[$story->id]", (array)$lang->story->priList, $story->pri, 'class=select-1');?></td>
|
||||
<td><?php echo html::select("modules[$story->id]", $moduleOptionMenu, $story->module, 'class=select-1');?></td>
|
||||
<td><?php echo html::select("plans[$story->id]", $plans, $story->plan, 'class=select-1');?></td>
|
||||
<td><?php echo html::select("sources[$story->id]", $lang->story->sourceList, $story->source, 'class=select-1');?></td>
|
||||
<td><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
|
||||
<?php if($story->status != 'draft'):?>
|
||||
<td><?php echo html::select("stages[$story->id]", $lang->story->stageList, $story->stage, 'class=select-1');?></td>
|
||||
<?php else:?>
|
||||
<td><?php echo html::select("stages[$story->id]", $lang->story->stageList, $story->stage, 'class="select-1" disabled="disabled"');?></td>
|
||||
<?php endif;?>
|
||||
|
||||
<?php if($story->status == 'closed'):?>
|
||||
<td><?php echo html::select("closedBys[$story->id]", $users, $story->closedBy, 'class="select-1"');?></td>
|
||||
<?php else:?>
|
||||
<td><?php echo html::select("closedBys[$story->id]", $users, $story->closedBy, 'class="select-1" disabled="disabled"');?></td>
|
||||
<?php endif;?>
|
||||
|
||||
<?php if($story->status == 'closed'):?>
|
||||
<td>
|
||||
<div class='f-left'><?php echo html::select("closedReasons[$story->id]", $lang->story->reasonList, $story->closedReason, "class=w-60px onchange=setDuplicateAndChild(this.value,$story->id)");?></div>
|
||||
|
||||
<div class='f-left' id='<?php echo 'duplicateStoryBox' . $story->id;?>' <?php if($story->closedReason != 'duplicate') echo "style='display:none'";?>>
|
||||
<?php echo html::input("duplicateStoryIDList[$story->id]", '', "class=w-30px placeholder='{$lang->idAB}'");?>
|
||||
</div>
|
||||
|
||||
<div class='f-left' id='<?php echo 'childStoryBox' . $story->id;?>' <?php if($story->closedReason != 'subdivided') echo "style='display:none'";?>>
|
||||
<?php echo html::input("childStoriesIDList[$story->id]", '', "class=w-30px placeholder='{$lang->idAB}'");?>
|
||||
</div>
|
||||
</td>
|
||||
<?php else:?>
|
||||
<td class='f-left'><?php echo html::select("closedReasons[$story->id]", $lang->story->reasonList, $story->closedReason, 'class="w-60px" disabled="disabled"');?></td>
|
||||
<?php endif;?>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
<?php if(isset($suhosinInfo)):?>
|
||||
<tr><td colspan='11'><div class='f-left blue'><?php echo $suhosinInfo;?></div></td></tr>
|
||||
<?php endif;?>
|
||||
<tr><td colspan='11' class='a-center'><?php echo html::submitButton();?></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
Reference in New Issue
Block a user