* Rename siblings to twins.

This commit is contained in:
Yagami
2022-12-12 14:13:06 +08:00
parent b70f00842f
commit a299a62db1
29 changed files with 236 additions and 236 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
ALTER TABLE `zt_story` ADD COLUMN `siblings` varchar(255) NOT NULL AFTER `linkRequirements`;
ALTER TABLE `zt_story` ADD COLUMN `twins` varchar(255) NOT NULL AFTER `linkRequirements`;
ALTER TABLE `zt_productplan` MODIFY COLUMN `branch` varchar(255) NOT NULL DEFAULT '0';
ALTER TABLE `zt_effort` ADD `extra` text COLLATE 'utf8_general_ci' NOT NULL AFTER `end`;
ALTER TABLE `zt_build` MODIFY COLUMN `branch` varchar(255) NOT NULL DEFAULT '0';
+1 -1
View File
@@ -1480,7 +1480,7 @@ CREATE TABLE IF NOT EXISTS `zt_story` (
`childStories` varchar(255) NOT NULL,
`linkStories` varchar(255) NOT NULL,
`linkRequirements` varchar(255) NOT NULL,
`siblings` varchar(255) NOT NULL,
`twins` varchar(255) NOT NULL,
`duplicateStory` mediumint(8) unsigned NOT NULL,
`version` smallint(6) NOT NULL default '1',
`feedbackBy` varchar(100) NOT NULL,
+1 -1
View File
@@ -396,7 +396,7 @@ $lang->action->label->tolib = 'imported';
$lang->action->label->updatetolib = 'updated';
$lang->action->label->ganttmove = 'sorted';
$lang->action->label->submitreview = 'submitted';
$lang->action->label->syncsiblings = 'synchronized changes';
$lang->action->label->synctwins = 'synchronized changes';
$lang->action->label->relieved = 'relieved';
$lang->action->label->switchtolight = 'switch from ALM mode to light mode';
$lang->action->label->linkedrepo = 'Linked Code Repo';
+1 -1
View File
@@ -396,7 +396,7 @@ $lang->action->label->tolib = 'imported';
$lang->action->label->updatetolib = 'updated';
$lang->action->label->ganttmove = 'sorted';
$lang->action->label->submitreview = 'submitted';
$lang->action->label->syncsiblings = 'synchronized changes';
$lang->action->label->synctwins = 'synchronized changes';
$lang->action->label->relieved = 'relieved';
$lang->action->label->switchtolight = 'switch from ALM mode to light mode';
$lang->action->label->linkedrepo = 'Linked Code Repo';
+1 -1
View File
@@ -396,7 +396,7 @@ $lang->action->label->tolib = 'Importé';
$lang->action->label->updatetolib = 'MàJ';
$lang->action->label->ganttmove = 'sorted';
$lang->action->label->submitreview = 'submitted';
$lang->action->label->syncsiblings = 'synchronized changes';
$lang->action->label->synctwins = 'synchronized changes';
$lang->action->label->relieved = 'relieved';
$lang->action->label->switchtolight = 'switch from ALM mode to light mode';
$lang->action->label->linkedrepo = 'Linked Code Repo';
+1 -1
View File
@@ -306,7 +306,7 @@ $lang->action->label->syncproject = 'start';
$lang->action->label->syncexecution = 'start';
$lang->action->label->startProgram = '(The start of the project sets the status of the program as Ongoing)';
$lang->action->label->submitreview = 'submitted';
$lang->action->label->syncsiblings = 'synchronized changes';
$lang->action->label->synctwins = 'synchronized changes';
$lang->action->label->linkedrepo = 'Linked Code Repo';
$lang->action->label->unlinkedrepo = 'Unlinked Code Repo';
+1 -1
View File
@@ -396,7 +396,7 @@ $lang->action->label->tolib = '导入了';
$lang->action->label->updatetolib = '更新了';
$lang->action->label->ganttmove = '排序了';
$lang->action->label->submitreview = '提交了评审';
$lang->action->label->syncsiblings = '同步修改了';
$lang->action->label->synctwins = '同步修改了';
$lang->action->label->relieved = '解除了';
$lang->action->label->switchtolight = '从全生命周期管理模式切换为轻量管理模式';
$lang->action->label->linkedrepo = '关联代码库到';
+2 -2
View File
@@ -50,7 +50,7 @@ class actionModel extends model
$action->extra = $extra;
if(!defined('IN_UPGRADE')) $action->vision = $this->config->vision;
if($objectType == 'story' and strpos(',reviewpassed,reviewrejected,reviewclarified,reviewreverted,syncsiblings,', ",$actionType,") !== false) $action->actor = $this->lang->action->system;
if($objectType == 'story' and strpos(',reviewpassed,reviewrejected,reviewclarified,reviewreverted,synctwins,', ",$actionType,") !== false) $action->actor = $this->lang->action->system;
/* Use purifier to process comment. Fix bug #2683. */
$action->comment = fixer::stripDataTags($comment);
@@ -961,7 +961,7 @@ class actionModel extends model
}
}
if($action->objectType == 'story' and $action->action == 'syncsiblings')
if($action->objectType == 'story' and $action->action == 'synctwins')
{
if(!empty($extra) and strpos($extra, '|') !== false)
{
+3 -3
View File
@@ -260,13 +260,13 @@ class branch extends control
* @param string $browseType
* @param int $projectID
* @param bool $withMainBranch
* @param string $isSiblings
* @param string $isTwins
* @param string $fieldID
* @param string $multiple
* @access public
* @return void
*/
public function ajaxGetBranches($productID, $oldBranch = 0, $browseType = 'all', $projectID = 0, $withMainBranch = true, $isSiblings = 'no', $fieldID = '0', $multiple = '')
public function ajaxGetBranches($productID, $oldBranch = 0, $browseType = 'all', $projectID = 0, $withMainBranch = true, $isTwins = 'no', $fieldID = '0', $multiple = '')
{
$product = $this->loadModel('product')->getById($productID);
if(empty($product) or $product->type == 'normal') return;
@@ -285,7 +285,7 @@ class branch extends control
$name = $multiple == 'multiple' ? 'branch[]' : 'branch';
if($isSiblings == 'yes') return print(html::select("branches[$fieldID]", $branchTagOption, $oldBranch, "onchange='loadBranchRelation(this.value, $fieldID);' class='form-control chosen control-branch'"));
if($isTwins == 'yes') return print(html::select("branches[$fieldID]", $branchTagOption, $oldBranch, "onchange='loadBranchRelation(this.value, $fieldID);' class='form-control chosen control-branch'"));
return print(html::select($name, $branchTagOption, $oldBranch, "class='form-control' $multiple onchange='loadBranch(this)' data-last='{$oldBranch}'"));
}
+33 -33
View File
@@ -943,7 +943,7 @@ class story extends control
$this->view->title = $this->lang->story->edit . "STORY" . $this->lang->colon . $this->view->story->title;
$this->view->position[] = $this->lang->story->edit;
$this->view->story = $story;
$this->view->siblings = empty($story->siblings) ? array() : $this->story->getByList($story->siblings);
$this->view->twins = empty($story->twins) ? array() : $this->story->getByList($story->twins);
$this->view->stories = $stories;
$this->view->users = $users;
$this->view->product = $product;
@@ -1037,15 +1037,15 @@ class story extends control
/* Get edited stories. */
$stories = $this->story->getByList($storyIdList);
/* Filter siblings. */
$siblings = '';
/* Filter twins. */
$twins = '';
foreach($stories as $id => $story)
{
if(empty($story->siblings)) continue;
$siblings .= "#$id ";
if(empty($story->twins)) continue;
$twins .= "#$id ";
unset($stories[$id]);
}
if(!empty($siblings)) echo js::alert(sprintf($this->lang->story->batchEditTip, $siblings));
if(!empty($twins)) echo js::alert(sprintf($this->lang->story->batchEditTip, $twins));
$this->loadModel('branch');
if($productID and !$executionID)
@@ -1276,7 +1276,7 @@ class story extends control
/* Assign. */
$this->view->title = $this->lang->story->change . "STORY" . $this->lang->colon . $this->view->story->title;
$this->view->siblings = empty($story->siblings) ? array() : $this->story->getByList($story->siblings);
$this->view->twins = empty($story->twins) ? array() : $this->story->getByList($story->twins);
$this->view->branches = $this->loadModel('branch')->getPairs($story->product);
$this->view->users = $this->user->getPairs('pofirst|nodeleted|noclosed', $this->view->story->assignedTo);
$this->view->position[] = $this->lang->story->change;
@@ -1447,7 +1447,7 @@ class story extends control
$this->view->position = $position;
$this->view->product = $product;
$this->view->branches = $product->type == 'normal' ? array() : $this->loadModel('branch')->getPairs($product->id);
$this->view->siblings = !empty($story->siblings) ? $this->story->getByList($story->siblings) : array();
$this->view->twins = !empty($story->twins) ? $this->story->getByList($story->twins) : array();
$this->view->plan = $plan;
$this->view->bugs = $bugs;
$this->view->fromBug = $fromBug;
@@ -1905,10 +1905,10 @@ class story extends control
$stories = $this->story->getByList($storyIdList);
$productStoryList = array();
$productList = array();
$ignoreSiblings = array();
$ignoreTwins = array();
foreach($stories as $story)
{
if(!empty($ignoreSiblings) and isset($ignoreSiblings[$story->id]))
if(!empty($ignoreTwins) and isset($ignoreTwins[$story->id]))
{
unset($stories[$story->id]);
continue;
@@ -1929,9 +1929,9 @@ class story extends control
$branch = $storyProduct->type == 'branch' ? ($story->branch > 0 ? $story->branch : '0') : 'all';
if(!isset($productStoryList[$story->product][$story->branch])) $productStoryList[$story->product][$story->branch] = $this->story->getProductStoryPairs($story->product, $branch, 0, 'all', 'id_desc', 0, '', $story->type);
if(!empty($story->siblings))
if(!empty($story->twins))
{
foreach(explode(',', trim($story->siblings, ',')) as $siblingID) $ignoreSiblings[$siblingID] = $siblingID;
foreach(explode(',', trim($story->twins, ',')) as $twinID) $ignoreTwins[$twinID] = $twinID;
}
}
@@ -1951,7 +1951,7 @@ class story extends control
$actionID = $this->action->create('story', $storyID, 'Closed', htmlSpecialString($this->post->comments[$storyID]), ucfirst($this->post->closedReasons[$storyID]) . ($this->post->duplicateStoryIDList[$storyID] ? ':' . (int)$this->post->duplicateStoryIDList[$storyID] : '') . "|$preStatus");
$this->action->logHistory($actionID, $changes);
if(!empty($stories[$storyID]->siblings)) $this->story->syncSiblings($storyID, $stories[$storyID]->siblings, $changes, 'Closed');
if(!empty($stories[$storyID]->twins)) $this->story->syncTwins($storyID, $stories[$storyID]->twins, $changes, 'Closed');
}
}
@@ -2301,23 +2301,23 @@ class story extends control
$allChanges = $this->story->batchAssignTo();
if(dao::isError()) return print(js::error(dao::getError()));
$assignedSiblings = array();
$assignedTwins = array();
$oldStories = $this->story->getByList($this->post->storyIdList);
foreach($allChanges as $storyID => $changes)
{
$actionID = $this->action->create('story', $storyID, 'Assigned', '', $this->post->assignedTo);
$this->action->logHistory($actionID, $changes);
/* Sync siblings. */
if(!empty($oldStories[$storyID]->siblings))
/* Sync twins. */
if(!empty($oldStories[$storyID]->twins))
{
$siblings = $oldStories[$storyID]->siblings;
foreach(explode(',', $siblings) as $siblingID)
$twins = $oldStories[$storyID]->twins;
foreach(explode(',', $twins) as $twinID)
{
if(in_array($siblingID, $this->post->storyIdList) or isset($assignedSiblings[$siblingID])) $siblings = str_replace(",$siblingID,", ',', $siblings);
if(in_array($twinID, $this->post->storyIdList) or isset($assignedTwins[$twinID])) $twins = str_replace(",$twinID,", ',', $twins);
}
$this->story->syncSiblings($storyID, trim($siblings, ','), $changes, 'Assigned');
foreach(explode(',', trim($siblings, ',')) as $assignedID) $assignedSiblings[$assignedID] = $assignedID;
$this->story->syncTwins($storyID, trim($twins, ','), $changes, 'Assigned');
foreach(explode(',', trim($twins, ',')) as $assignedID) $assignedTwins[$assignedID] = $assignedID;
}
}
}
@@ -3029,27 +3029,27 @@ class story extends control
}
/**
* AJAX: Deleted story sibling.
* AJAX: Deleted story twin.
*
* @access public
* @return void
*/
public function ajaxRelieveSibling()
public function ajaxRelieveTwins()
{
$siblingID = !empty($_POST['siblingID']) ? $_POST['siblingID'] : 0;
$story = $this->story->getByID($siblingID);
$siblings = explode(',', trim($story->siblings, ','));
$twinID = !empty($_POST['twinID']) ? $_POST['twinID'] : 0;
$story = $this->story->getByID($twinID);
$twins = explode(',', trim($story->twins, ','));
if(empty($story->siblings)) return $this->send(array('result' => 'fail'));
if(empty($story->twins)) return $this->send(array('result' => 'fail'));
/* batchUnset siblingID from siblings.*/
$replaceSql = "UPDATE " . TABLE_STORY . " SET siblings = REPLACE(siblings,',$siblingID,', ',') WHERE `product` = $story->product";
/* batchUnset twinID from twins.*/
$replaceSql = "UPDATE " . TABLE_STORY . " SET twins = REPLACE(twins,',$twinID,', ',') WHERE `product` = $story->product";
$this->dbh->exec($replaceSql);
/* Update siblings to empty by siblingID and if siblings eq ','.*/
$this->dao->update(TABLE_STORY)->set('siblings')->eq('')->where('id')->eq($siblingID)->orWhere('siblings')->eq(',')->exec();
/* Update twins to empty by twinID and if twins eq ','.*/
$this->dao->update(TABLE_STORY)->set('twins')->eq('')->where('id')->eq($twinID)->orWhere('twins')->eq(',')->exec();
if(!dao::isError()) $this->loadModel('action')->create('story', $siblingID, 'relieved');
return $this->send(array('result' => 'success', 'silbingsCount' => count($siblings)-1));
if(!dao::isError()) $this->loadModel('action')->create('story', $twinID, 'relieved');
return $this->send(array('result' => 'success', 'silbingsCount' => count($twins)-1));
}
}
+2 -2
View File
@@ -3,5 +3,5 @@
.nav-tabs>li>a {height: 36px;}
.table-form>tbody>tr>th {width: 100px !important;}
.colorpicker {right: 7px; top: 7px; opacity: 1;}
#siblingList td, #siblingTitle td {padding-left: 65px;}
#siblingTitle td {font-weight: 700;}
#twinsList td, #twinsTitle td {padding-left: 65px;}
#twinsTitle td {font-weight: 700;}
+2 -2
View File
@@ -26,6 +26,6 @@
.popover-icon {float:left;}
.popover .content {margin-left:25px;overflow: overlay;}
.hide {display:none !important;}
.sibling > a.viewlink {padding:6px;white-space: nowrap;overflow: hidden;display: inline-flex;max-width: 70%;}
.sibling > span {max-width: 60px;white-space: nowrap;overflow: hidden;}
.twins > a.viewlink {padding:6px;white-space: nowrap;overflow: hidden;display: inline-flex;max-width: 70%;}
.twins > span {max-width: 60px;white-space: nowrap;overflow: hidden;}
.tooltip-inner {max-width: 500px;}
+1 -1
View File
@@ -5,4 +5,4 @@
.needNotReviewBox {width: 130px;}
.needNotReviewBox span.input-group-addon {border: 1px solid #dcdcdc; border-left-width: 0px; width:130px;}
#moduleIdBox .chosen-container, #planIdBox .chosen-container {min-width: unset;}
#legendSiblings .form-group {margin-top: 10px;}
#legendTwins .form-group {margin-top: 10px;}
+10 -10
View File
@@ -95,14 +95,14 @@ function loadURS(allURS)
});
}
$('.sibling').mouseover(function() {
$('.twins').mouseover(function() {
$(this).parent('ul').find('a.unlink').addClass('hide');
$(this).find('.unlink').removeClass('hide');
});
$('.sibling').mouseenter(function() {
$('.twins').mouseenter(function() {
$('[data-toggle="popover"]').popover('hide');
});
$('.sibling').mouseout(function() {
$('.twins').mouseout(function() {
$(this).find('.unlink').addClass('hide');
});
@@ -117,7 +117,7 @@ $('[data-toggle="popover"]').each(function(item) {
function relieve(index)
{
$.post(relieveURL, {siblingID:index}, function(data){
$.post(relieveURL, {twinID:index}, function(data){
$('[data-id="' + index + '"]').popover('hide');
if(data.result == 'success')
@@ -125,12 +125,12 @@ function relieve(index)
if(data.silbingsCount != 0) $('[data-id="' + index + '"]').parent('li').remove();
if(data.silbingsCount == 0 || index == storyID)
{
$('[href="#legendSiblings"]').parent('li').next('li').addClass('active');;
$('[href="#legendSiblings"]').parent('li').remove();
$('#legendSiblings').next('div').addClass('active');
$('#legendSiblings').remove();
$('#siblingTitle').remove();
$('#siblingList').remove();
$('[href="#legendTwins"]').parent('li').next('li').addClass('active');;
$('[href="#legendTwins"]').parent('li').remove();
$('#legendTwins').next('div').addClass('active');
$('#legendTwins').remove();
$('#twinsTitle').remove();
$('#twinsList').remove();
}
}
}, 'json');
+13 -13
View File
@@ -161,9 +161,9 @@ $(window).unload(function(){
$('.addBranchesBox' + itemIndex + ' #planIdBox').css('flex', '0 0 ' + gap + 'px');
$.ajaxSettings.async = false;
loadBranchForSiblings($('#product').val(), branch, itemIndex)
loadModuleForSiblings($('#product').val(), branch, itemIndex)
loadPlanForSiblings($('#product').val(), branch, itemIndex)
loadBranchForTwins($('#product').val(), branch, itemIndex)
loadModuleForTwins($('#product').val(), branch, itemIndex)
loadPlanForTwins($('#product').val(), branch, itemIndex)
$.ajaxSettings.async = true;
$('.addBranchesBox' + itemIndex + ' #branchBox .input-group .input-group-addon').html($.cookie('branchSourceName'))
@@ -238,15 +238,15 @@ function loadBranchRelation(branch, branchIndex)
if(typeof(branch) == 'undefined') branch = 0;
$.ajaxSettings.async = false;
loadModuleForSiblings(productID, branch, branchIndex)
loadPlanForSiblings(productID, branch, branchIndex)
loadModuleForTwins(productID, branch, branchIndex)
loadPlanForTwins(productID, branch, branchIndex)
$.ajaxSettings.async = true;
disableSelectedBranches()
}
/**
* Load branch for siblings.
* Load branch for twins.
*
* @paran int $procutID
* @param int $branch
@@ -254,10 +254,10 @@ function loadBranchRelation(branch, branchIndex)
* @access public
* @return void
*/
function loadBranchForSiblings(productID, branch, branchIndex)
function loadBranchForTwins(productID, branch, branchIndex)
{
var isSiblings = storyType == 'story' ? 'yes' : 'no';
$.get(createLink('branch', 'ajaxGetBranches', "productID=" + productID + "&oldBranch=" + branch + "&param=active&projectID=" + executionID + "&withMainBranch=1&isSiblings=" + isSiblings + "&fieldID=" + branchIndex), function(data)
var isTwins = storyType == 'story' ? 'yes' : 'no';
$.get(createLink('branch', 'ajaxGetBranches', "productID=" + productID + "&oldBranch=" + branch + "&param=active&projectID=" + executionID + "&withMainBranch=1&isTwins=" + isTwins + "&fieldID=" + branchIndex), function(data)
{
if(data)
{
@@ -271,7 +271,7 @@ function loadBranchForSiblings(productID, branch, branchIndex)
}
/**
* Load module for siblings.
* Load module for twins.
*
* @paran int $procutID
* @param int $branch
@@ -279,7 +279,7 @@ function loadBranchForSiblings(productID, branch, branchIndex)
* @access public
* @return void
*/
function loadModuleForSiblings(productID, branch, branchIndex)
function loadModuleForTwins(productID, branch, branchIndex)
{
/* Load module */
var currentModule = 0;
@@ -306,7 +306,7 @@ function loadModuleForSiblings(productID, branch, branchIndex)
}
/**
* Load plan for siblings.
* Load plan for twins.
*
* @paran int $procutID
* @param int $branch
@@ -314,7 +314,7 @@ function loadModuleForSiblings(productID, branch, branchIndex)
* @access public
* @return void
*/
function loadPlanForSiblings(productID, branch, branchIndex)
function loadPlanForTwins(productID, branch, branchIndex)
{
/* Load plan */
if(branch == '0') branch = '';
+4 -4
View File
@@ -77,9 +77,9 @@ $lang->story->order = 'Order';
$lang->story->saveDraft = 'Save as draft';
$lang->story->doNotSubmit = 'Do Not Submit';
$lang->story->currentBranch = 'Current Branch';
$lang->story->siblings = 'Siblings story';
$lang->story->twins = 'Twins story';
$lang->story->relieved = 'Relieved';
$lang->story->relievedSiblings = 'Relieved Siblings';
$lang->story->relievedTwins = 'Relieved Twins';
$lang->story->loadAllStories = 'Load all stories';
$lang->story->editAction = "Edit {$lang->SRCommon}";
@@ -107,7 +107,7 @@ $lang->story->relievedTip = "The twin relationship cannot be restored af
$lang->story->assignSyncTip = "Both twin stories modify the assignor synchronously";
$lang->story->closeSyncTip = "Twin stories are closed synchronously";
$lang->story->activateSyncTip = "Twin stories are activated synchronously";
$lang->story->relievedSiblingsTip = "After product adjustment, the twin relationship of this story will be automatically removed, and the story will no longer be synchronized. Do you want to save?";
$lang->story->relievedTwinsTip = "After product adjustment, the twin relationship of this story will be automatically removed, and the story will no longer be synchronized. Do you want to save?";
$lang->story->batchEditTip = "{$lang->SRCommon} %sis twin stories, and this operation has been filtered.";
$lang->story->id = 'ID';
@@ -356,7 +356,7 @@ $lang->story->action->subdividestory = array('main' => '$date, aufgeteilt
$lang->story->action->unlinkrelatedstory = array('main' => '$date, Verknüpfung aufgelöst durch <strong>$actor</strong> von Story <strong>$extra</strong>.');
$lang->story->action->unlinkchildstory = array('main' => '$date, Verknüpfung aufgelöst durch <strong>$actor</strong> Story <strong>$extra</strong>.');
$lang->story->action->recalledchange = array('main' => '$date, Undo changes by <strong>\$actor</strong>.');
$lang->story->action->syncsiblings = array('main' => "\$date, the system judges that this story is adjusted synchronously due to the \$operate of twin story <strong>\$extra</strong>.", 'operate' => 'operateList');
$lang->story->action->synctwins = array('main' => "\$date, the system judges that this story is adjusted synchronously due to the \$operate of twin story <strong>\$extra</strong>.", 'operate' => 'operateList');
/* Statistical statement. */
$lang->story->report = new stdclass();
+4 -4
View File
@@ -77,9 +77,9 @@ $lang->story->order = 'Order';
$lang->story->saveDraft = 'Save as draft';
$lang->story->doNotSubmit = 'Do Not Submit';
$lang->story->currentBranch = 'Current Branch';
$lang->story->siblings = 'Siblings story';
$lang->story->twins = 'Twins story';
$lang->story->relieved = 'Relieved';
$lang->story->relievedSiblings = 'Relieved Siblings';
$lang->story->relievedTwins = 'Relieved Twins';
$lang->story->loadAllStories = 'Load all stories';
$lang->story->editAction = "Edit {$lang->SRCommon}";
@@ -107,7 +107,7 @@ $lang->story->relievedTip = "The twin relationship cannot be restored af
$lang->story->assignSyncTip = "Both twin stories modify the assignor synchronously";
$lang->story->closeSyncTip = "Twin stories are closed synchronously";
$lang->story->activateSyncTip = "Twin stories are activated synchronously";
$lang->story->relievedSiblingsTip = "After product adjustment, the twin relationship of this story will be automatically removed, and the story will no longer be synchronized. Do you want to save?";
$lang->story->relievedTwinsTip = "After product adjustment, the twin relationship of this story will be automatically removed, and the story will no longer be synchronized. Do you want to save?";
$lang->story->batchEditTip = "{$lang->SRCommon} %sis twin stories, and this operation has been filtered.";
$lang->story->id = 'ID';
@@ -356,7 +356,7 @@ $lang->story->action->subdividestory = array('main' => '$date, decomposed
$lang->story->action->unlinkrelatedstory = array('main' => '$date, unlinked by <strong>$actor</strong> from Story <strong>$extra</strong>.');
$lang->story->action->unlinkchildstory = array('main' => '$date, unlinked by <strong>$actor</strong> Decomposed Story <strong>$extra</strong>.');
$lang->story->action->recalledchange = array('main' => '$date, Undo changes by <strong>\$actor</strong>.');
$lang->story->action->syncsiblings = array('main' => "\$date, the system judges that this story is adjusted synchronously due to the \$operate of twin story <strong>\$extra</strong>.", 'operate' => 'operateList');
$lang->story->action->synctwins = array('main' => "\$date, the system judges that this story is adjusted synchronously due to the \$operate of twin story <strong>\$extra</strong>.", 'operate' => 'operateList');
/* Statistical statement. */
$lang->story->report = new stdclass();
+4 -4
View File
@@ -77,9 +77,9 @@ $lang->story->order = 'Order';
$lang->story->saveDraft = 'Save as draft';
$lang->story->doNotSubmit = 'Do Not Submit';
$lang->story->currentBranch = 'Current Branch';
$lang->story->siblings = 'Siblings story';
$lang->story->twins = 'Twins story';
$lang->story->relieved = 'Relieved';
$lang->story->relievedSiblings = 'Relieved Siblings';
$lang->story->relievedTwins = 'Relieved Twins';
$lang->story->loadAllStories = 'Load all stories';
$lang->story->editAction = "Edit {$lang->SRCommon}";
@@ -107,7 +107,7 @@ $lang->story->relievedTip = "The twin relationship cannot be restored af
$lang->story->assignSyncTip = "Both twin stories modify the assignor synchronously";
$lang->story->closeSyncTip = "Twin stories are closed synchronously";
$lang->story->activateSyncTip = "Twin stories are activated synchronously";
$lang->story->relievedSiblingsTip = "After product adjustment, the twin relationship of this story will be automatically removed, and the story will no longer be synchronized. Do you want to save?";
$lang->story->relievedTwinsTip = "After product adjustment, the twin relationship of this story will be automatically removed, and the story will no longer be synchronized. Do you want to save?";
$lang->story->batchEditTip = "{$lang->SRCommon} %sis twin stories, and this operation has been filtered.";
$lang->story->id = 'ID';
@@ -356,7 +356,7 @@ $lang->story->action->subdividestory = array('main' => '$date, décompos
$lang->story->action->unlinkrelatedstory = array('main' => '$date, dissociée par <strong>$actor</strong> de la Story <strong>$extra</strong>.');
$lang->story->action->unlinkchildstory = array('main' => '$date, dissociée par <strong>$actor</strong> de la sous-Story <strong>$extra</strong>.');
$lang->story->action->recalledchange = array('main' => '$date, Undo changes by <strong>\$actor</strong>.');
$lang->story->action->syncsiblings = array('main' => "\$date, the system judges that this story is adjusted synchronously due to the \$operate of twin story <strong>\$extra</strong>.", 'operate' => 'operateList');
$lang->story->action->synctwins = array('main' => "\$date, the system judges that this story is adjusted synchronously due to the \$operate of twin story <strong>\$extra</strong>.", 'operate' => 'operateList');
/* Statistical statement. */
$lang->story->report = new stdclass();
+2 -2
View File
@@ -99,7 +99,7 @@ $lang->story->syncTip = "The twin story are synchronized except for
$lang->story->assignSyncTip = "Both twin stories modify the assignor synchronously";
$lang->story->closeSyncTip = "Twin stories are closed synchronously";
$lang->story->activateSyncTip = "Twin stories are activated synchronously";
$lang->story->relievedSiblingsTip = "After product adjustment, the twin relationship of this story will be automatically removed, and the story will no longer be synchronized. Do you want to save?";
$lang->story->relievedTwinsTip = "After product adjustment, the twin relationship of this story will be automatically removed, and the story will no longer be synchronized. Do you want to save?";
$lang->story->batchEditTip = "{$lang->SRCommon} %sis twin stories, and this operation has been filtered.";
$lang->story->id = 'ID';
@@ -340,7 +340,7 @@ $lang->story->action->subdividestory = array('main' => '$date, được p
$lang->story->action->unlinkrelatedstory = array('main' => '$date, bị hủy bởi <strong>$actor</strong> từ Câu chuyện <strong>$extra</strong>.');
$lang->story->action->unlinkchildstory = array('main' => '$date, bị hủy bởi <strong>$actor</strong> Câu chuyện được phân rã <strong>$extra</strong>.');
$lang->story->action->recalledchange = array('main' => '$date, Undo changes by <strong>\$actor</strong>.');
$lang->story->action->syncsiblings = array('main' => "\$date, the system judges that this story is adjusted synchronously due to the \$operate of twin story <strong>\$extra</strong>.", 'operate' => 'operateList');
$lang->story->action->synctwins = array('main' => "\$date, the system judges that this story is adjusted synchronously due to the \$operate of twin story <strong>\$extra</strong>.", 'operate' => 'operateList');
/* Statistical statement. */
$lang->story->report = new stdclass();
+4 -4
View File
@@ -77,9 +77,9 @@ $lang->story->order = '排序';
$lang->story->saveDraft = '存为草稿';
$lang->story->doNotSubmit = '保存暂不提交';
$lang->story->currentBranch = '当前%s';
$lang->story->siblings = '孪生需求';
$lang->story->twins = '孪生需求';
$lang->story->relieved = '解除';
$lang->story->relievedSiblings = '解除孪生需求';
$lang->story->relievedTwins = '解除孪生需求';
$lang->story->loadAllStories = '加载所有需求';
$lang->story->editAction = "编辑{$lang->SRCommon}";
@@ -107,7 +107,7 @@ $lang->story->relievedTip = "孪生关系解除后无法恢复,需求
$lang->story->assignSyncTip = "孪生需求均同步修改指派人";
$lang->story->closeSyncTip = "孪生需求均同步关闭";
$lang->story->activateSyncTip = "孪生需求均同步激活";
$lang->story->relievedSiblingsTip = '产品调整后,本需求自动解除孪生关系,需求不再同步,是否保存?';
$lang->story->relievedTwinsTip = '产品调整后,本需求自动解除孪生关系,需求不再同步,是否保存?';
$lang->story->batchEditTip = "{$lang->SRCommon} %s为孪生需求,本次操作已被过滤。";
$lang->story->id = '编号';
@@ -356,7 +356,7 @@ $lang->story->action->subdividestory = array('main' => "\$date, 由 <stro
$lang->story->action->unlinkrelatedstory = array('main' => "\$date, 由 <strong>\$actor</strong> 移除相关{$lang->SRCommon} <strong>\$extra</strong>。");
$lang->story->action->unlinkchildstory = array('main' => "\$date, 由 <strong>\$actor</strong> 移除细分{$lang->SRCommon} <strong>\$extra</strong>。");
$lang->story->action->recalledchange = array('main' => "\$date, 由 <strong>\$actor</strong> 撤销变更。");
$lang->story->action->syncsiblings = array('main' => "\$date, 系统判断由于孪生需求 <strong>\$extra</strong> \$operate,本需求同步调整。", 'operate' => 'operateList');
$lang->story->action->synctwins = array('main' => "\$date, 系统判断由于孪生需求 <strong>\$extra</strong> \$operate,本需求同步调整。", 'operate' => 'operateList');
/* 统计报表。*/
$lang->story->report = new stdclass();
+108 -108
View File
@@ -50,14 +50,14 @@ class storyModel extends model
$story->executions = $this->dao->select('t1.project, t2.name, t2.status, t2.type, t2.multiple')->from(TABLE_PROJECTSTORY)->alias('t1')
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.project = t2.id')
->where('t2.type')->in('sprint,stage,kanban')
->beginIF($story->siblings)->andWhere('t1.story')->in(ltrim($story->siblings, ',') . $story->id)
->beginIF(!$story->siblings)->andWhere('t1.story')->in($story->id)
->beginIF($story->twins)->andWhere('t1.story')->in(ltrim($story->twins, ',') . $story->id)
->beginIF(!$story->twins)->andWhere('t1.story')->in($story->id)
->orderBy('t1.`order` DESC')
->fetchAll('project');
$story->tasks = $this->dao->select('id, name, assignedTo, execution, project, status, consumed, `left`,type')->from(TABLE_TASK)
->where('deleted')->eq(0)
->beginIF($story->siblings)->andWhere('story')->in(ltrim($story->siblings, ',') . $story->id)
->beginIF(!$story->siblings)->andWhere('story')->in($story->id)
->beginIF($story->twins)->andWhere('story')->in(ltrim($story->twins, ',') . $story->id)
->beginIF(!$story->twins)->andWhere('story')->in($story->id)
->orderBy('id DESC')
->fetchGroup('execution');
@@ -168,8 +168,8 @@ class storyModel extends model
/* Get affected bugs. */
$story->bugs = $this->dao->select('*')->from(TABLE_BUG)
->where('status')->ne('closed')
->beginIF($story->siblings)->andWhere('story')->in(ltrim($story->siblings, ',') . $story->id)
->beginIF(!$story->siblings)->andWhere('story')->in($story->id)
->beginIF($story->twins)->andWhere('story')->in(ltrim($story->twins, ',') . $story->id)
->beginIF(!$story->twins)->andWhere('story')->in($story->id)
->andWhere('status')->ne('closed')
->andWhere('deleted')->eq(0)
->orderBy('id desc')->fetchAll();
@@ -177,8 +177,8 @@ class storyModel extends model
/* Get affected cases. */
$story->cases = $this->dao->select('*')->from(TABLE_CASE)
->where('deleted')->eq(0)
->beginIF($story->siblings)->andWhere('story')->in(ltrim($story->siblings, ',') . $story->id)
->beginIF(!$story->siblings)->andWhere('story')->in($story->id)
->beginIF($story->twins)->andWhere('story')->in(ltrim($story->twins, ',') . $story->id)
->beginIF(!$story->twins)->andWhere('story')->in($story->id)
->fetchAll();
return $story;
@@ -443,17 +443,17 @@ class storyModel extends model
}
}
/* bind siblings story id */
/* bind twins story id */
if(count($storyIds) > 1)
{
foreach($storyIds as $siblingsStoryID)
foreach($storyIds as $twinsStoryID)
{
$siblingsArr = array();
$twinsArr = array();
foreach($storyIds as $idItem)
{
if($idItem != $siblingsStoryID) $siblingsArr[] = $idItem;
$siblings = ',' . implode(',', $siblingsArr) . ',';
$this->dao->update(TABLE_STORY)->set('siblings')->eq($siblings)->where('id')->eq($siblingsStoryID)->exec();
if($idItem != $twinsStoryID) $twinsArr[] = $idItem;
$twins = ',' . implode(',', $twinsArr) . ',';
$this->dao->update(TABLE_STORY)->set('twins')->eq($twins)->where('id')->eq($twinsStoryID)->exec();
}
}
}
@@ -803,12 +803,12 @@ class storyModel extends model
$data->files = $story->files = $addedFiles . trim($storyFiles, ',');
$this->dao->insert(TABLE_STORYSPEC)->data($data)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$data->story = $siblingID;
$data->story = $twinID;
$this->dao->insert(TABLE_STORYSPEC)->data($data)->exec();
}
}
@@ -842,12 +842,12 @@ class storyModel extends model
$reviewData->reviewer = $reviewer;
$this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$reviewData->story = $siblingID;
$reviewData->story = $twinID;
$this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec();
}
}
@@ -861,7 +861,7 @@ class storyModel extends model
}
$changes = common::createChanges($oldStory, $story);
if(!empty($oldStory->siblings)) $this->syncSiblings($oldStory->id, $oldStory->siblings, $changes, 'Changed');
if(!empty($oldStory->twins)) $this->syncTwins($oldStory->id, $oldStory->twins, $changes, 'Changed');
return $changes;
}
}
@@ -933,12 +933,12 @@ class storyModel extends model
->remove('files,labels,comment,contactListMenu,stages,reviewer,needNotReview')
->get();
/* Relieve siblings when change product. */
if(!empty($oldStory->siblings) and $story->product != $oldStory->product)
/* Relieve twins when change product. */
if(!empty($oldStory->twins) and $story->product != $oldStory->product)
{
$this->dbh->exec("UPDATE " . TABLE_STORY . " SET siblings = REPLACE(siblings, ',$storyID,', ',') WHERE `product` = $oldStory->product");
$this->dao->update(TABLE_STORY)->set('siblings')->eq('')->where('id')->eq($storyID)->orWhere('siblings')->eq(',')->exec();
$oldStory->siblings = '';
$this->dbh->exec("UPDATE " . TABLE_STORY . " SET twins = REPLACE(twins, ',$storyID,', ',') WHERE `product` = $oldStory->product");
$this->dao->update(TABLE_STORY)->set('twins')->eq('')->where('id')->eq($storyID)->orWhere('twins')->eq(',')->exec();
$oldStory->twins = '';
}
if($oldStory->type == 'story' and !isset($story->linkStories)) $story->linkStories = '';
@@ -992,13 +992,13 @@ class storyModel extends model
->beginIF($oldStory->status == 'reviewing')->andWhere('reviewer')->notin(implode(',', $_POST['reviewer']))
->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->delete()->from(TABLE_STORYREVIEW)
->where('story')->eq($siblingID)
->where('story')->eq($twinID)
->andWhere('version')->eq($oldStory->version)
->beginIF($oldStory->status == 'reviewing')->andWhere('reviewer')->notin(implode(',', $_POST['reviewer']))
->exec();
@@ -1015,12 +1015,12 @@ class storyModel extends model
$reviewData->reviewer = $reviewer;
$this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$reviewData->story = $siblingID;
$reviewData->story = $twinID;
$this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec();
}
}
@@ -1062,13 +1062,13 @@ class storyModel extends model
$data->files = $story->files = $addedFiles . trim($storyFiles, ',');
$this->dao->update(TABLE_STORYSPEC)->data($data)->where('story')->eq((int)$storyID)->andWhere('version')->eq($oldStory->version)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->update(TABLE_STORYSPEC)->data($data)
->where('story')->eq((int)$siblingID)
->where('story')->eq((int)$twinID)
->andWhere('version')->eq($oldStory->version)
->exec();
}
@@ -1202,7 +1202,7 @@ class storyModel extends model
if(isset($story->finalResult)) $this->recordReviewAction($story);
}
if(!empty($oldStory->siblings)) $this->syncSiblings($oldStory->id, $oldStory->siblings, $changes, 'Edited');
if(!empty($oldStory->twins)) $this->syncTwins($oldStory->id, $oldStory->twins, $changes, 'Edited');
return true;
}
@@ -1625,15 +1625,15 @@ class storyModel extends model
->andWhere('reviewer')->eq($this->app->user->account)
->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->update(TABLE_STORYREVIEW)
->set('result')->eq($this->post->result)
->set('reviewDate')->eq($now)
->where('story')->eq($siblingID)
->where('story')->eq($twinID)
->andWhere('version')->eq($oldStory->version)
->andWhere('reviewer')->eq($this->app->user->account)
->exec();
@@ -1670,7 +1670,7 @@ class storyModel extends model
$this->action->logHistory($actionID, $changes);
}
if(!empty($oldStory->siblings)) $this->syncSiblings($oldStory->id, $oldStory->siblings, $changes, 'Reviewed');
if(!empty($oldStory->twins)) $this->syncTwins($oldStory->id, $oldStory->twins, $changes, 'Reviewed');
return true;
}
@@ -1690,7 +1690,7 @@ class storyModel extends model
$actions = array();
$this->loadModel('action');
$reviewedSiblings = array();
$reviewedTwins = array();
$oldStories = $this->getByList($storyIdList);
$hasResult = $this->dao->select('story,version,result')->from(TABLE_STORYREVIEW)->where('story')->in($storyIdList)->andWhere('reviewer')->eq($this->app->user->account)->andWhere('result')->ne('')->orderBy('version')->fetchAll('story');
$reviewerList = $this->dao->select('story,reviewer,result,version')->from(TABLE_STORYREVIEW)->where('story')->in($storyIdList)->orderBy('version')->fetchGroup('story', 'reviewer');
@@ -1720,15 +1720,15 @@ class storyModel extends model
$this->dao->update(TABLE_STORYREVIEW)->set('result')->eq($result)->set('reviewDate')->eq($now)->where('story')->eq($storyID)->andWhere('version')->eq($oldStory->version)->andWhere('reviewer')->eq($this->app->user->account)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->update(TABLE_STORYREVIEW)
->set('result')->eq($result)
->set('reviewDate')->eq($now)
->where('story')->eq($siblingID)
->where('story')->eq($twinID)
->andWhere('version')->eq($oldStory->version)
->andWhere('reviewer')->eq($this->app->user->account)
->exec();
@@ -1758,17 +1758,17 @@ class storyModel extends model
$story->version = $oldStory->version;
$actions[$storyID] = $this->recordReviewAction($story, $result, $reason);
/* Sync siblings. */
/* Sync twins. */
$changes = common::createChanges($oldStory, $story);
if(!empty($oldStory->siblings))
if(!empty($oldStory->twins))
{
$siblings = $oldStory->siblings;
foreach(explode(',', $siblings) as $siblingID)
$twins = $oldStory->twins;
foreach(explode(',', $twins) as $twinID)
{
if(in_array($siblingID, $storyIdList) or isset($reviewedSiblings[$siblingID])) $siblings = str_replace(",$siblingID,", ',', $siblings);
if(in_array($twinID, $storyIdList) or isset($reviewedTwins[$twinID])) $twins = str_replace(",$twinID,", ',', $twins);
}
$this->syncSiblings($storyID, trim($siblings, ','), $changes, 'Reviewed');
foreach(explode(',', trim($siblings, ',')) as $reviewedID) $reviewedSiblings[$reviewedID] = $reviewedID;
$this->syncTwins($storyID, trim($twins, ','), $changes, 'Reviewed');
foreach(explode(',', trim($twins, ',')) as $reviewedID) $reviewedTwins[$reviewedID] = $reviewedID;
}
}
@@ -1793,17 +1793,17 @@ class storyModel extends model
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->andWhere('version')->eq($oldStory->version)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($siblingID)->andWhere('version')->eq($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($twinID)->andWhere('version')->eq($oldStory->version)->exec();
}
}
$changes = common::createChanges($oldStory, $story);
if(!empty($oldStory->siblings)) $this->syncSiblings($storyID, $oldStory->siblings, $changes, 'recalled');
if(!empty($oldStory->twins)) $this->syncTwins($storyID, $oldStory->twins, $changes, 'recalled');
}
/**
@@ -1828,18 +1828,18 @@ class storyModel extends model
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($storyID)->andWHere('version')->eq($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->andWhere('version')->eq($oldStory->version)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($siblingID)->andWHere('version')->eq($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($siblingID)->andWhere('version')->eq($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($twinID)->andWHere('version')->eq($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($twinID)->andWhere('version')->eq($oldStory->version)->exec();
}
}
$changes = common::createChanges($oldStory, $story);
if(!empty($oldStory->siblings)) $this->syncSiblings($storyID, $oldStory->siblings, $changes, 'recalledChange');
if(!empty($oldStory->twins)) $this->syncTwins($storyID, $oldStory->twins, $changes, 'recalledChange');
}
/**
@@ -1872,12 +1872,12 @@ class storyModel extends model
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->andWhere('version')->eq($oldStory->version)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($siblingID)->andWhere('version')->eq($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($twinID)->andWhere('version')->eq($oldStory->version)->exec();
}
}
@@ -1893,12 +1893,12 @@ class storyModel extends model
$reviewData->reviewer = $reviewer;
$this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$reviewData->story = $siblingID;
$reviewData->story = $twinID;
$this->dao->insert(TABLE_STORYREVIEW)->data($reviewData)->exec();
}
}
@@ -1909,7 +1909,7 @@ class storyModel extends model
$this->dao->update(TABLE_STORY)->data($story, 'reviewer')->where('id')->eq($storyID)->exec();
$changes = common::createChanges($oldStory, $story);
if(!empty($oldStory->siblings)) $this->syncSiblings($storyID, $oldStory->siblings, $changes, 'submitReview');
if(!empty($oldStory->twins)) $this->syncTwins($storyID, $oldStory->twins, $changes, 'submitReview');
if(!dao::isError()) return $changes;
return false;
@@ -2050,7 +2050,7 @@ class storyModel extends model
}
$changes = common::createChanges($oldStory, $story);
if(!empty($oldStory->siblings)) $this->syncSiblings($storyID, $oldStory->siblings, $changes, 'Closed');
if(!empty($oldStory->twins)) $this->syncTwins($storyID, $oldStory->twins, $changes, 'Closed');
return $changes;
}
@@ -2571,7 +2571,7 @@ class storyModel extends model
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->checkFlow()->where('id')->eq((int)$storyID)->exec();
$changes = common::createChanges($oldStory, $story);
if(!empty($oldStory->siblings)) $this->syncSiblings($storyID, $oldStory->siblings, $changes, 'Assigned');
if(!empty($oldStory->twins)) $this->syncTwins($storyID, $oldStory->twins, $changes, 'Assigned');
if(!dao::isError()) return $changes;
return false;
}
@@ -2658,12 +2658,12 @@ class storyModel extends model
{
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($siblingID)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($twinID)->exec();
}
}
}
@@ -2674,7 +2674,7 @@ class storyModel extends model
if($oldStory->parent > 0) $this->updateParentStatus($storyID, $oldStory->parent);
$changes = common::createChanges($oldStory, $story);
if(!empty($oldStory->siblings)) $this->syncSiblings($storyID, $oldStory->siblings, $changes, 'Activated');
if(!empty($oldStory->twins)) $this->syncTwins($storyID, $oldStory->twins, $changes, 'Activated');
return $changes;
}
@@ -3768,7 +3768,7 @@ class storyModel extends model
->andWhere('status')->notin('closed,draft')
->andWhere('product')->eq($productID)
->andWhere('plan')->in('0,')
->andWhere('siblings')->eq('')
->andWhere('twins')->eq('')
->beginIF($append)->orWhere('id')->in($append)->fi()
->fetchPairs();
return array(0 => '') + $stories ;
@@ -6042,13 +6042,13 @@ class storyModel extends model
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($story->id)->andWHere('version')->in($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($story->id)->andWhere('version')->in($oldStory->version)->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($siblingID)->andWHere('version')->in($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($siblingID)->andWhere('version')->in($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($twinID)->andWHere('version')->in($oldStory->version)->exec();
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($twinID)->andWhere('version')->in($oldStory->version)->exec();
}
}
}
@@ -6156,13 +6156,13 @@ class storyModel extends model
->andWhere('result')->eq('')
->exec();
/* Sync siblings. */
if(!empty($oldStory->siblings))
/* Sync twins. */
if(!empty($oldStory->twins))
{
foreach(explode(',', trim($oldStory->siblings, ',')) as $siblingID)
foreach(explode(',', trim($oldStory->twins, ',')) as $twinID)
{
$this->dao->delete()->from(TABLE_STORYREVIEW)
->where('story')->eq($siblingID)
->where('story')->eq($twinID)
->andWhere('version')->eq($oldStory->version)
->andWhere('result')->eq('')
->exec();
@@ -6409,14 +6409,14 @@ class storyModel extends model
* Get the story status after activation.
*
* @param int $storyID
* @param bool $hasSiblings
* @param bool $hasTwins
* @access public
* @return void
*/
public function getActivateStatus($storyID, $hasSiblings = true)
public function getActivateStatus($storyID, $hasTwins = true)
{
$status = 'active';
$action = $hasSiblings ? 'closed,reviewrejected,syncsiblings' : 'closed,reviewrejected';
$action = $hasTwins ? 'closed,reviewrejected,synctwins' : 'closed,reviewrejected';
$lastRecord = $this->dao->select('action,extra')->from(TABLE_ACTION)
->where('objectType')->eq('story')
->andWhere('objectID')->eq($storyID)
@@ -6431,7 +6431,7 @@ class storyModel extends model
}
/* When activating twin story, you need to check the status of the twin story selected when closing. */
if($lastAction == 'syncsiblings')
if($lastAction == 'synctwins')
{
$syncStoryID = strpos($lastRecord->extra, '|') !== false ? substr($lastRecord->extra, strpos($lastRecord->extra, '|') + 1) : 0;
$status = $this->getActivateStatus($syncStoryID, false);
@@ -6476,18 +6476,18 @@ class storyModel extends model
}
/**
* Sync siblings.
* Sync twins.
*
* @param int $storyID
* @param string $siblings
* @param string $twins
* @param array $changes
* @param string $operate
* @access public
* @return void
*/
public function syncSiblings($storyID, $siblings, $changes, $operate)
public function syncTwins($storyID, $twins, $changes, $operate)
{
if(empty($siblings) or empty($changes)) return;
if(empty($twins) or empty($changes)) return;
/* Get the fields and values to be synchronized. */
$syncFieldList = array();
@@ -6504,15 +6504,15 @@ class storyModel extends model
/* Synchronize and record dynamics. */
$this->loadModel('action');
$siblings = explode(',', trim($siblings, ','));
foreach($siblings as $siblingID)
$twins = explode(',', trim($twins, ','));
foreach($twins as $twinID)
{
$this->dao->update(TABLE_STORY)->data($syncFieldList)->where('id')->eq((int)$siblingID)->exec();
$this->dao->update(TABLE_STORY)->data($syncFieldList)->where('id')->eq((int)$twinID)->exec();
if(!dao::isError())
{
$this->setStage($siblingID);
$this->setStage($twinID);
$actionID = $this->action->create('story', $siblingID, 'syncsiblings', '', "$operate|$storyID");
$actionID = $this->action->create('story', $twinID, 'synctwins', '', "$operate|$storyID");
$this->action->logHistory($actionID, $changes);
}
}
+1 -1
View File
@@ -28,7 +28,7 @@
<th class='w-80px'><?php echo $lang->story->assignedTo;?></th>
<td class='w-p45'><?php echo html::select('assignedTo', $users, $story->closedBy, 'class="form-control chosen"');?></td><td></td>
</tr>
<?php if(!empty($story->siblings)):?>
<?php if(!empty($story->twins)):?>
<tr>
<th></th>
<td colspan='2'><i class='icon-exclamation-sign'></i> <?php echo $lang->story->activateSyncTip;?></td>
+1 -1
View File
@@ -29,7 +29,7 @@
<th class='w-80px'><?php echo $lang->story->assign;?></th>
<td class='w-p25-f'><?php echo html::select('assignedTo', $users, $story->assignedTo, "class='form-control chosen'");?></td><td></td>
</tr>
<?php if(!empty($story->siblings)):?>
<?php if(!empty($story->twins)):?>
<tr>
<th></th>
<td colspan='2'><i class='icon-exclamation-sign'></i> <?php echo $lang->story->assignSyncTip;?></td>
@@ -1,24 +1,24 @@
<?php
$lang->story->currentBranch = sprintf($this->lang->story->currentBranch, $this->lang->product->branchName[$product->type]);
js::set('relieveURL', inlink('ajaxRelieveSibling'));
js::set('relieveURL', inlink('ajaxRelieveTwins'));
js::set('storyID', $story->id);
js::set('relieved', $lang->story->relieved);
js::set('relievedTip', $lang->story->relievedTip);
js::set('cancel', $lang->cancel);
$canViewLinkStory = common::hasPriv('story', 'view');
$canRelieved = common::hasPriv('story', 'relieved');
array_unshift($siblings, $story);
array_unshift($twins, $story);
$class = isonlybody() ? 'showinonlybody' : 'iframe';
foreach($siblings as $sibling)
foreach($twins as $twin)
{
$id = $sibling->id;
$title = '#' . $id . ' '. $sibling->title;
$branch = isset($branches[$sibling->branch]) ? $branches[$sibling->branch] : '';
$stage = $lang->story->stageList[$sibling->stage];
$labelClass = $story->branch == $sibling->branch ? 'label-primary' : '';
$id = $twin->id;
$title = '#' . $id . ' '. $twin->title;
$branch = isset($branches[$twin->branch]) ? $branches[$twin->branch] : '';
$stage = $lang->story->stageList[$twin->stage];
$labelClass = $story->branch == $twin->branch ? 'label-primary' : '';
echo "<li title='$title' class='sibling'>";
echo "<li title='$title' class='twins'>";
echo "<span class='label {$labelClass} label-outline label-badge' title='$branch'>{$branch}</span> ";
echo "<span class='label label-outline' title='{$stage}'>{$stage}</span> ";
echo ($canViewLinkStory ? html::a($this->createLink('story', 'view', "id=$id", '', true), "$title", '', "class='$class viewlink' data-width='80%'") : "$title");
+4 -4
View File
@@ -73,17 +73,17 @@
<?php echo $this->fetch('file', 'buildform');?>
</td>
</tr>
<?php if(!empty($siblings)):?>
<tr id='siblingTitle'>
<?php if(!empty($twins)):?>
<tr id='twinsTitle'>
<td colspan='2'>
<?php echo $lang->story->changeSyncTip;?>
<span data-toggle='tooltip' data-placement='right' title='<?php echo $lang->story->syncTip;?>'><i class='icon-help'></i></span>
</td>
</tr>
<tr id='siblingList'>
<tr id='twinsList'>
<td colspan='2'>
<ul class='list-unstyled'>
<?php include './blocksibling.html.php';?>
<?php include './blocktwins.html.php';?>
</ul>
</td>
</tr>
+1 -1
View File
@@ -28,7 +28,7 @@
<th class='thWidth'><?php echo $lang->story->closedReason;?></th>
<td class='w-p25-f'><?php echo html::select('closedReason', $reasonList, '', 'class="form-control" onchange="setStory(this.value)"');?></td><td></td>
</tr>
<?php if(!empty($story->siblings)):?>
<?php if(!empty($story->twins)):?>
<tr>
<th></th>
<td colspan='2'><i class='icon-exclamation-sign'></i> <?php echo $lang->story->closeSyncTip;?></td>
+5 -5
View File
@@ -24,8 +24,8 @@
<?php js::set('feedbackSource', $config->story->feedbackSource); ?>
<?php js::set('storyStatus', $story->status);?>
<?php js::set('lastReviewer', explode(',', $lastReviewer))?>
<?php js::set('siblings', $story->siblings)?>
<?php js::Set('relievedSiblingsTip', $lang->story->relievedSiblingsTip)?>
<?php js::set('twins', $story->twins)?>
<?php js::Set('relievedTwinsTip', $lang->story->relievedTwinsTip)?>
<div class='main-content' id='mainContent'>
<form method='post' enctype='multipart/form-data' target='hiddenwin' id='dataform'>
<div class='main-header'>
@@ -100,8 +100,8 @@
</div>
<?php endif;?>
<?php $this->printExtendFields($story, 'div', 'position=left');?>
<?php if(!empty($siblings)):?>
<div class='detail' id='legendSiblings'>
<?php if(!empty($twins)):?>
<div class='detail' id='legendTwins'>
<div class='detail-title'>
<?php echo $lang->story->changeSyncTip;?>
<span data-toggle='tooltip' data-placement='right' title='<?php echo $lang->story->syncTip;?>'><i class='icon-help'></i></span>
@@ -109,7 +109,7 @@
<div class='form-group'>
<div>
<ul class='list-unstyled'>
<?php include './blocksibling.html.php';?>
<?php include './blocktwins.html.php';?>
</ul>
</div>
</div>
+7 -7
View File
@@ -11,10 +11,10 @@
*/
function loadProduct(productID)
{
if(page == 'edit' && siblings && productID != oldProductID)
if(page == 'edit' && twins && productID != oldProductID)
{
confirmRelievedSiblings = confirm(relievedSiblingsTip);
if(!confirmRelievedSiblings)
confirmRelievedTwins = confirm(relievedTwinsTip);
if(!confirmRelievedTwins)
{
$('#product').val(oldProductID);
$('#product').trigger("chosen:updated");
@@ -93,8 +93,8 @@ function loadProductBranches(productID)
$('#branch').remove();
$('#branch_chosen').remove();
var isSiblings = storyType == 'story' && page == 'create' ? 'yes' : 'no';
$.get(createLink('branch', 'ajaxGetBranches', "productID=" + productID + "&oldBranch=0&param=" + param + "&projectID=" + executionID + "&withMainBranch=1&isSiblings=" + isSiblings), function(data)
var isTwins = storyType == 'story' && page == 'create' ? 'yes' : 'no';
$.get(createLink('branch', 'ajaxGetBranches', "productID=" + productID + "&oldBranch=0&param=" + param + "&projectID=" + executionID + "&withMainBranch=1&isTwins=" + isTwins), function(data)
{
if(storyType == 'story' && page == 'create')
{
@@ -130,8 +130,8 @@ function loadProductBranches(productID)
$('#branches0').next('.picker').remove();
$('#branches0').chosen();
loadModuleForSiblings(productID, 0, 0)
loadPlanForSiblings(productID, 0, 0)
loadModuleForTwins(productID, 0, 0)
loadPlanForTwins(productID, 0, 0)
/* Init multi branch icon-plus. */
if($(".table-form select[id^='branches']").length == $('.switchBranch #branchBox option').length)
+9 -9
View File
@@ -419,27 +419,27 @@
<div class="cell">
<div class='tabs'>
<ul class='nav nav-tabs'>
<?php if(!empty($siblings)):?>
<li class='active'><a href='#legendSiblings' data-toggle='tab'><?php echo $lang->story->siblings;?></a></li>
<?php if(!empty($twins)):?>
<li class='active'><a href='#legendTwins' data-toggle='tab'><?php echo $lang->story->twins;?></a></li>
<?php endif;?>
<?php if($this->config->URAndSR and !$hiddenURS):?>
<li class='<?php if(empty($siblings)) echo 'active';?>'><a href='#legendStories' data-toggle='tab'><?php echo $story->type == 'story' ? $lang->story->requirement : $lang->story->story;?></a></li>
<li class='<?php if(empty($twins)) echo 'active';?>'><a href='#legendStories' data-toggle='tab'><?php echo $story->type == 'story' ? $lang->story->requirement : $lang->story->story;?></a></li>
<?php endif;?>
<?php if($story->type == 'story'):?>
<li class="<?php if((!$this->config->URAndSR || $hiddenURS) and empty($siblings)) echo 'active';?>"><a href='#legendProjectAndTask' data-toggle='tab'><?php echo $lang->story->legendProjectAndTask;?></a></li>
<li class="<?php if((!$this->config->URAndSR || $hiddenURS) and empty($twins)) echo 'active';?>"><a href='#legendProjectAndTask' data-toggle='tab'><?php echo $lang->story->legendProjectAndTask;?></a></li>
<?php endif;?>
<li><a href='#legendRelated' data-toggle='tab'><?php echo $lang->story->legendRelated;?></a></li>
</ul>
<div class='tab-content'>
<?php if(!empty($siblings)):?>
<div class='tab-pane active' id='legendSiblings'>
<?php if(!empty($twins)):?>
<div class='tab-pane active' id='legendTwins'>
<ul class="list-unstyled">
<?php include './blocksibling.html.php';?>
<?php include './blocktwins.html.php';?>
</ul>
</div>
<?php endif;?>
<?php if($this->config->URAndSR and !$hiddenURS):?>
<div class='tab-pane <?php if(empty($siblings)) echo 'active';?>' id='legendStories'>
<div class='tab-pane <?php if(empty($twins)) echo 'active';?>' id='legendStories'>
<ul class="list-unstyled">
<?php
$relation = array();
@@ -459,7 +459,7 @@
<?php endif;?>
<?php if($story->type == 'story'):?>
<div class="tab-pane <?php if((!$this->config->URAndSR || $hiddenURS) and empty($siblings)) echo 'active';?>" id='legendProjectAndTask'>
<div class="tab-pane <?php if((!$this->config->URAndSR || $hiddenURS) and empty($twins)) echo 'active';?>" id='legendProjectAndTask'>
<ul class="list-unstyled">
<?php
foreach($story->tasks as $executionTasks)