Merge branch 'sgm_review'
This commit is contained in:
@@ -23,6 +23,7 @@ clean:
|
||||
rm -fr zentaoxx
|
||||
rm -fr tmp/
|
||||
rm -f *.sh
|
||||
rm -f *.deb *.rpm
|
||||
common:
|
||||
mkdir zentaopms
|
||||
cp -fr api zentaopms/
|
||||
@@ -176,7 +177,7 @@ deb:
|
||||
cp ZenTaoPMS.${VERSION}.zip buildroot/opt
|
||||
cd buildroot/opt; unzip ZenTaoPMS.${VERSION}.zip; mv zentaopms zentao; rm ZenTaoPMS.${VERSION}.zip
|
||||
sed -i 's/index.php/\/zentao\/index.php/' buildroot/opt/zentao/www/.htaccess
|
||||
sudo dpkg -b buildroot/ ZenTaoPMS_${VERSION}_1_all.deb
|
||||
sudo dpkg -b buildroot/ ZenTaoPMS.${VERSION}.1.all.deb
|
||||
rm -rf buildroot
|
||||
rpm:
|
||||
mkdir ~/rpmbuild/SPECS -p
|
||||
@@ -252,6 +253,9 @@ ciCommon:
|
||||
rm -fr zentaopms zentaoxx zentaoxx.*.zip
|
||||
make en
|
||||
rm -fr zentaopms zentaoxx zentaoxx.*.zip
|
||||
rm -f $(BUILD_PATH)/ZenTao*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION).zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION).int.zip
|
||||
cp ZenTaoPMS.$(VERSION).zip $(BUILD_PATH)
|
||||
cp ZenTaoPMS.$(VERSION).zip ZenTaoALM.$(VERSION).int.zip $(RELEASE_PATH)
|
||||
ci:
|
||||
make ciCommon
|
||||
php tools/packZip.php $(VERSION)
|
||||
@@ -263,12 +267,7 @@ ci:
|
||||
php tools/packRpm.php $(VERSION)
|
||||
sh rpm.sh
|
||||
rm -rf tmp/
|
||||
rm -f zentaobiz*.zip zentaomax*.zip $(BUILD_PATH)/ZenTaoPMS.$(VERSION).zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION)*.zip $(RELEASE_PATH)/*.deb $(RELEASE_PATH)/*.rpm *.sh
|
||||
cp ZenTaoPMS.$(VERSION).zip $(BUILD_PATH)
|
||||
mv *.zip *.deb *.rpm $(RELEASE_PATH)
|
||||
lite:
|
||||
make ciCommon
|
||||
php tools/packZip.php $(VERSION) $(LITEVERSION)
|
||||
rm -f zentaobiz*.zip zentaomax*.zip $(BUILD_PATH)/ZenTaoPMS.$(VERSION).zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoALM.$(LITEVERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(LITEVERSION)*.zip *.sh
|
||||
cp ZenTaoPMS.$(VERSION).zip $(BUILD_PATH)
|
||||
mv *.zip $(RELEASE_PATH)
|
||||
rm -f zentaobiz*.zip zentaomax*.zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION)*.zip $(RELEASE_PATH)/*.deb $(RELEASE_PATH)/*.rpm *.sh $(RELEASE_PATH)/pmsPack/*.zip $(RELEASE_PATH)/pmsPack/deb/* $(RELEASE_PATH)/pmsPack/rpm/*
|
||||
mv ZenTaoALM.$(VERSION).int.php*.zip ZenTaoPMS.$(VERSION).php*.zip $(RELEASE_PATH)/pmsPack
|
||||
mv *.deb $(RELEASE_PATH)/pmsPack/deb
|
||||
mv *.rpm $(RELEASE_PATH)/pmsPack/rpm
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE `zt_review` ADD docVersion smallint(6) NOT NULL AFTER `doc`;
|
||||
|
||||
DELETE FROM `zt_workflowaction` WHERE `module`='story' AND `action`='browse';
|
||||
DELETE FROM `zt_workflowaction` WHERE `module`='task' AND `action`='browse';
|
||||
DELETE FROM `zt_workflowaction` WHERE `module`='build' AND `action`='browse';
|
||||
@@ -9420,6 +9420,7 @@ CREATE TABLE IF NOT EXISTS `zt_review` (
|
||||
`object` mediumint(8) NOT NULL,
|
||||
`template` mediumint(8) NOT NULL,
|
||||
`doc` mediumint(8) DEFAULT NULL,
|
||||
`docVersion` smallint(6) DEFAULT NULL,
|
||||
`status` char(30) NOT NULL,
|
||||
`reviewedBy` varchar(255) NOT NULL,
|
||||
`auditedBy` varchar(255) NOT NULL,
|
||||
|
||||
@@ -5,7 +5,7 @@ public function __construct($appName = '')
|
||||
if($this->app->getModuleName() == 'kanban') $this->lang->kanban->menu = new stdclass();
|
||||
}
|
||||
|
||||
public function getKanban4Group($executionID, $browseType, $groupBy)
|
||||
public function getKanban4Group($executionID, $browseType, $groupBy, $searchValue = '')
|
||||
{
|
||||
/* Get card data. */
|
||||
$cardList = array();
|
||||
@@ -135,7 +135,7 @@ public function getKanban4Group($executionID, $browseType, $groupBy)
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc')
|
||||
public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc', $searchValue = '')
|
||||
{
|
||||
$cards = $this->dao->select('t1.*, t2.type as columnType')
|
||||
->from(TABLE_KANBANCELL)->alias('t1')
|
||||
|
||||
@@ -285,7 +285,7 @@ function formatTime($time, $format = '')
|
||||
{
|
||||
$time = str_replace('0000-00-00', '', $time);
|
||||
$time = str_replace('00:00:00', '', $time);
|
||||
if(trim($time) == '') return ;
|
||||
if(trim($time) == '') return '';
|
||||
if($format) return date($format, strtotime($time));
|
||||
return trim($time);
|
||||
}
|
||||
|
||||
@@ -103,10 +103,10 @@ class model extends baseModel
|
||||
if($action->extensionType == 'override') return $this->loadModel('flow')->buildActionMenu($moduleName, $action, $data, $type);
|
||||
|
||||
$conditions = json_decode($action->conditions);
|
||||
if($action->extensionType == 'extend' && $conditions)
|
||||
if($action->extensionType == 'extend')
|
||||
{
|
||||
$enabled = $this->loadModel('flow')->checkConditions($conditions, $data);
|
||||
$label = $action->name;
|
||||
$title = $action->name;
|
||||
if($conditions) $enabled = $this->loadModel('flow')->checkConditions($conditions, $data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ class html extends baseHTML
|
||||
$string .= "<input type='checkbox' name='{$name}[]' value='$key' ";
|
||||
$string .= (strpos($checked, ",$key,") !== false) ? " checked ='checked'" : "";
|
||||
$string .= $attrib;
|
||||
$string .= " id='$name$key' /> ";
|
||||
$string .= " id='$name$key' title='{$value}'/> ";
|
||||
$string .= "<label for='$name$key'>" . $value . '</label></div>';
|
||||
}
|
||||
return $string;
|
||||
@@ -391,6 +391,19 @@ class html extends baseHTML
|
||||
*/
|
||||
class js extends baseJS
|
||||
{
|
||||
/**
|
||||
* Open a new app window.
|
||||
*
|
||||
* @param string $app
|
||||
* @param string $url
|
||||
* @static
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
static public function openEntry($app, $url)
|
||||
{
|
||||
return self::start() . "$.apps.open('$url', '$app')" . self::end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,3 +67,16 @@ $config->action->preferredTypeNum = 10;
|
||||
$config->action->preferredType = new stdclass();
|
||||
$config->action->preferredType->new = array('user', 'story', 'task', 'bug', 'case', 'doc', 'program', 'product', 'project', 'execution');
|
||||
$config->action->preferredType->classic = array('user', 'story', 'task', 'bug', 'case', 'doc', 'product', 'execution', 'productplan', 'build');
|
||||
|
||||
global $lang;
|
||||
$config->trash = new stdclass();
|
||||
$config->trash->search['module'] = 'trash';
|
||||
$config->trash->search['fields']['objectName'] = $lang->action->objectName;
|
||||
$config->trash->search['fields']['objectID'] = $lang->action->objectID;
|
||||
$config->trash->search['fields']['actor'] = $lang->action->actor;
|
||||
$config->trash->search['fields']['date'] = $lang->action->date;
|
||||
|
||||
$config->trash->search['params']['objectName'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->trash->search['params']['objectID'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->trash->search['params']['actor'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->trash->search['params']['date'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
|
||||
@@ -40,6 +40,8 @@ class action extends control
|
||||
*
|
||||
* @param string $browseType
|
||||
* @param string $type all|hidden
|
||||
* @param bool $byQuery
|
||||
* @param int $queryID
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
@@ -47,7 +49,7 @@ class action extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function trash($browseType = 'all', $type = 'all', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
public function trash($browseType = 'all', $type = 'all', $byQuery = false, $queryID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->loadModel('backup');
|
||||
|
||||
@@ -81,13 +83,18 @@ class action extends control
|
||||
$this->session->set('practiceLibList', $uri, 'assetlib');
|
||||
$this->session->set('componentLibList', $uri, 'assetlib');
|
||||
|
||||
/* Build the search form. */
|
||||
$queryID = (int)$queryID;
|
||||
$actionURL = $this->createLink('action', 'trash', "browseType=$browseType&type=$type&byQuery=true&queryID=myQueryID");
|
||||
$this->action->buildTrashSearchForm($queryID, $actionURL);
|
||||
|
||||
/* Get deleted objects. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
|
||||
/* Append id for secend sort. */
|
||||
$sort = common::appendOrder($orderBy);
|
||||
$trashes = $this->action->getTrashes($browseType, $type, $sort, $pager);
|
||||
$trashes = $byQuery ? $this->action->getTrashesBySearch($browseType, $type, $queryID, $sort, $pager) : $this->action->getTrashes($browseType, $type, $sort, $pager);
|
||||
$objectTypeList = $this->action->getTrashObjectTypes($type);
|
||||
$objectTypeList = array_keys($objectTypeList);
|
||||
|
||||
@@ -96,6 +103,7 @@ class action extends control
|
||||
$preferredTypeConfig = $this->config->systemMode == 'new' ? $this->config->action->preferredType->new : $this->config->action->preferredType->classic;
|
||||
foreach($objectTypeList as $objectType)
|
||||
{
|
||||
if(!isset($this->config->objectTables[$objectType])) continue;
|
||||
in_array($objectType, $preferredTypeConfig) ? $preferredType[$objectType] = $objectType : $moreType[$objectType] = $objectType;
|
||||
}
|
||||
if(count($preferredType) < $this->config->action->preferredTypeNum)
|
||||
@@ -117,6 +125,9 @@ class action extends control
|
||||
$this->view->preferredType = $preferredType;
|
||||
$this->view->moreType = $moreType;
|
||||
$this->view->preferredTypeConfig = $preferredTypeConfig;
|
||||
$this->view->byQuery = $byQuery;
|
||||
$this->view->queryID = $queryID;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
.table-footer .table-actions {width: auto; visibility: visible; opacity: 1;}
|
||||
.table-footer .table-actions .text {line-height: 28px;}
|
||||
table tbody tr td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
|
||||
#mainContent table tbody tr td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
|
||||
|
||||
#mainMenu .btn-toolbar .btn-group .dropdown-menu .btn-active-text:hover .text {color: #fff}
|
||||
|
||||
.dropdown-menu .btn-active-text:hover .text:after {border-bottom: 0px;}
|
||||
#querybox #searchform{border-bottom: 1px solid #ddd; margin-bottom: 20px;}
|
||||
|
||||
@@ -42,6 +42,7 @@ $lang->action->hideAll = 'Hide All';
|
||||
$lang->action->editComment = 'Edit Comment';
|
||||
$lang->action->create = 'Add Comment';
|
||||
$lang->action->comment = 'Comment';
|
||||
$lang->action->byQuery = 'Search';
|
||||
|
||||
$lang->action->undeleteAction = 'Reset Data';
|
||||
$lang->action->hideOneAction = 'Hide Data';
|
||||
|
||||
@@ -42,6 +42,7 @@ $lang->action->hideAll = '全部隐藏';
|
||||
$lang->action->editComment = '修改备注';
|
||||
$lang->action->create = '添加备注';
|
||||
$lang->action->comment = '备注';
|
||||
$lang->action->byQuery = '搜索';
|
||||
|
||||
$lang->action->undeleteAction = '还原数据';
|
||||
$lang->action->hideOneAction = '隐藏数据';
|
||||
|
||||
@@ -683,6 +683,79 @@ class actionModel extends model
|
||||
return $trashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get deleted objects by search.
|
||||
*
|
||||
* @param string $objectType
|
||||
* @param string $type all|hidden
|
||||
* @param int $queryID
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getTrashesBySearch($objectType, $type, $queryID, $orderBy, $pager = null)
|
||||
{
|
||||
if($queryID and $queryID != 'myQueryID')
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('trashQuery', $query->sql);
|
||||
$this->session->set('trashForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('trashQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->trashQuery == false) $this->session->set('trashQuery', ' 1 = 1');
|
||||
}
|
||||
|
||||
$extra = $type == 'hidden' ? self::BE_HIDDEN : self::CAN_UNDELETED;
|
||||
$trashQuery = $this->session->trashQuery;
|
||||
$trashQuery = preg_replace("/`objectID`/", 't1.`objectID`', $trashQuery);
|
||||
$trashQuery = preg_replace("/`actor`/", 't1.`actor`', $trashQuery);
|
||||
$trashQuery = preg_replace("/`date`/", 't1.`date`', $trashQuery);
|
||||
$table = $this->config->objectTables[$objectType];
|
||||
$nameField = isset($this->config->action->objectNameFields[$objectType]) ? 't2.' . "`{$this->config->action->objectNameFields[$objectType]}`" : '';
|
||||
|
||||
if($nameField) $trashQuery = preg_replace("/`objectName`/", $nameField, $trashQuery);
|
||||
|
||||
if($objectType != 'pipeline')
|
||||
{
|
||||
$trashes = $this->dao->select("t1.*, $nameField as objectName")->from(TABLE_ACTION)->alias('t1')
|
||||
->leftJoin($table)->alias('t2')->on('t1.objectID=t2.id')
|
||||
->where('t1.action')->eq('deleted')
|
||||
->andWhere($trashQuery)
|
||||
->andWhere('t1.extra')->eq($extra)
|
||||
->andWhere('t1.vision')->eq($this->config->vision)
|
||||
->beginIF($objectType != 'all')->andWhere('t1.objectType')->eq($objectType)->fi()
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('objectID');
|
||||
}
|
||||
else
|
||||
{
|
||||
$trashes = $this->dao->select("t1.*, t1.objectType as type, t2.name as objectName, t2.type as objectType")->from(TABLE_ACTION)->alias('t1')
|
||||
->leftJoin(TABLE_PIPELINE)->alias('t2')->on('t1.objectID=t2.id')
|
||||
->where('t1.action')->eq('deleted')
|
||||
->andWhere($trashQuery)
|
||||
->andWhere('t1.extra')->eq($extra)
|
||||
->andWhere('t1.vision')->eq($this->config->vision)
|
||||
->andWhere('(t2.type')->eq('gitlab')
|
||||
->orWhere('t2.type')->eq('jenkins')
|
||||
->markRight(1)
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('objectID');
|
||||
}
|
||||
|
||||
return $trashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object type list of trashes.
|
||||
*
|
||||
@@ -1931,4 +2004,20 @@ class actionModel extends model
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildTrashSearchForm($queryID, $actionURL)
|
||||
{
|
||||
$this->config->trash->search['actionURL'] = $actionURL;
|
||||
$this->config->trash->search['queryID'] = $queryID;
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->trash->search);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,17 +55,20 @@
|
||||
echo '</ul></div>';
|
||||
}
|
||||
?>
|
||||
<?php if($currentObjectType != 'all'):?>
|
||||
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->action->byQuery;?></a>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<?php if($type == 'hidden') echo html::a(inLink('trash', "browseType=all&type=all"), $lang->goback, '', "class='btn'");?>
|
||||
<?php if($type == 'all') echo html::a(inLink('trash', "browseType=all&type=hidden"), "<i class='icon-eye-close'></i> " . $lang->action->dynamic->hidden, '', "class='btn btn-danger'");?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cell<?php if($byQuery) echo ' show';?>" id="queryBox" data-module='trash'></div>
|
||||
<div id='mainContent' class="main-row">
|
||||
<div class='main-table' data-ride='table'>
|
||||
<table class='table has-sort-head'>
|
||||
<?php $vars = "browseType=$currentObjectType&type=$type&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
|
||||
<?php $vars = "browseType=$currentObjectType&type=$type&byQuery=$byQuery&queryID=$queryID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
|
||||
<thead>
|
||||
<tr class='colhead'>
|
||||
<th class='c-object-type'><?php common::printOrderLink('objectType', $orderBy, $vars, $lang->action->objectType);?></th>
|
||||
|
||||
@@ -938,10 +938,12 @@ class bugModel extends model
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('assignedDate', $now)
|
||||
->stripTags($this->config->bug->editor->assignto['id'], $this->config->allowedTags)
|
||||
->remove('comment,showModule')
|
||||
->join('mailto', ',')
|
||||
->get();
|
||||
|
||||
$bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->assignto['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_BUG)
|
||||
->data($bug)
|
||||
->autoCheck()
|
||||
@@ -973,10 +975,12 @@ class bugModel extends model
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('assignedDate', $now)
|
||||
->stripTags($this->config->bug->editor->confirmbug['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->join('mailto', ',')
|
||||
->get();
|
||||
|
||||
$bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->confirmbug['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->checkFlow()->where('id')->eq($bugID)->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
@@ -1044,8 +1048,10 @@ class bugModel extends model
|
||||
->setDefault('resolvedDate', $now)
|
||||
->setDefault('assignedTo', $oldBug->openedBy)
|
||||
->removeIF($this->post->resolution != 'duplicate', 'duplicateBug')
|
||||
->stripTags($this->config->bug->editor->resolve['id'], $this->config->allowedTags)
|
||||
->remove('files,labels')
|
||||
->get();
|
||||
$bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->resolve['id'], $this->post->uid);
|
||||
|
||||
/* Set comment lang for alert error. */
|
||||
$this->lang->bug->comment = $this->lang->comment;
|
||||
@@ -1319,6 +1325,7 @@ class bugModel extends model
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('activatedDate', $now)
|
||||
->setDefault('activatedCount', (int)$oldBug->activatedCount)
|
||||
->stripTags($this->config->bug->editor->activate['id'], $this->config->allowedTags)
|
||||
->add('id', $bugID)
|
||||
->add('resolution', '')
|
||||
->add('status', 'active')
|
||||
@@ -1334,6 +1341,7 @@ class bugModel extends model
|
||||
->remove('comment,files,labels')
|
||||
->get();
|
||||
|
||||
$bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->activate['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->checkFlow()->where('id')->eq((int)$bugID)->exec();
|
||||
$this->dao->update(TABLE_BUG)->set('activatedCount = activatedCount + 1')->where('id')->eq((int)$bugID)->exec();
|
||||
|
||||
@@ -1380,9 +1388,11 @@ class bugModel extends model
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('closedBy', $this->app->user->account)
|
||||
->setDefault('closedDate', $now)
|
||||
->stripTags($this->config->bug->editor->close['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->close['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->checkFlow()->where('id')->eq((int)$bugID)->exec();
|
||||
if($oldBug->execution)
|
||||
{
|
||||
|
||||
@@ -1920,7 +1920,7 @@ EOD;
|
||||
if(strtolower($key) == 'closeddate' && $value == '') continue;
|
||||
if(strtolower($key) == 'actualcloseddate' && $value == '') continue;
|
||||
|
||||
if(isset($old->$key) and $value != stripslashes($old->$key))
|
||||
if(array_key_exists($key, $old) and $value != stripslashes($old->$key))
|
||||
{
|
||||
$diff = '';
|
||||
if(substr_count($value, "\n") > 1 or
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
<div class='cell'>
|
||||
<div class='list-group'>
|
||||
<?php
|
||||
foreach($config->custom->requiredModules as $requiredModule)
|
||||
$reruiredModules = ksort($config->custom->requiredModules);
|
||||
foreach($requiredModules as $requiredModule)
|
||||
{
|
||||
$requiredModuleName = zget($lang->custom->moduleName, $requiredModule, $lang->$requiredModule->common);
|
||||
echo html::a(inlink('required', "module=$requiredModule"), $requiredModuleName, '', "id='{$requiredModule}Tab'");
|
||||
|
||||
Regular → Executable
+22
@@ -792,6 +792,28 @@ class doc extends control
|
||||
return print($select);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get docs by lib.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetDocs($libID)
|
||||
{
|
||||
if(!$libID) return print(html::select('doc', '', '', "class='form-control chosen'"));
|
||||
|
||||
$docIdList = $this->doc->getPrivDocs($libID, 0);
|
||||
$docs = $this->dao->select('id, title')->from(TABLE_DOC)
|
||||
->where('lib')->eq($libID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('id')->in($docIdList)
|
||||
->orderBy('`order` asc')
|
||||
->fetchPairs();
|
||||
|
||||
return print(html::select('doc', $docs, '', "class='form-control chosen'"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax save draft.
|
||||
*
|
||||
|
||||
@@ -3820,17 +3820,18 @@ class execution extends control
|
||||
* @param string $browseType
|
||||
* @param string $groupBy
|
||||
* @param string $from execution|RD
|
||||
* @param string $searchValue
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '', $from = 'execution')
|
||||
public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '', $from = 'execution', $searchValue = '')
|
||||
{
|
||||
$enterTime = date('Y-m-d H:i:s', $enterTime);
|
||||
$lastEditedTime = $this->dao->select("max(lastEditedTime) as lastEditedTime")->from(TABLE_KANBANLANE)->where('execution')->eq($executionID)->fetch('lastEditedTime');
|
||||
|
||||
if($lastEditedTime > $enterTime or $groupBy != 'default')
|
||||
if($lastEditedTime > $enterTime or $groupBy != 'default' or !empty($searchValue))
|
||||
{
|
||||
$kanbanGroup = $from == 'execution' ? $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy) : $this->loadModel('kanban')->getRDKanban($executionID, $browseType, 'id_asc', 0, $groupBy);
|
||||
$kanbanGroup = $from == 'execution' ? $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy) : $this->loadModel('kanban')->getRDKanban($executionID, $browseType, 'id_asc', 0, $groupBy, $searchValue);
|
||||
return print(json_encode($kanbanGroup));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,3 +110,7 @@
|
||||
#mainMenu .divider {margin: 10px}
|
||||
|
||||
.modal-header {padding: 15px 0;}
|
||||
#rdKanbanSearch.input-group {float: left; width: min-content;}
|
||||
#rdKanbanSearchInput {width: 150px;}
|
||||
#rdSearchBox {display: none; width: 150px;}
|
||||
.btn-link.querybox-toggle {background-color: rgba(0,0,0,0);}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#type_chosen .icon-kanban {padding-right: 10px; font-size: 15px;}
|
||||
|
||||
.dropdown-menu a {text-align: left;}
|
||||
.scrollbar-hover {max-height: 2000px; overflow: scroll !important;}
|
||||
.scrollbar-hover {overflow: scroll !important;}
|
||||
.c-type {width: 150px !important; overflow: unset;}
|
||||
.c-group {width: 190px !important; overflow: unset;}
|
||||
.c-type {margin-left: 0px !important;}
|
||||
|
||||
@@ -478,7 +478,8 @@ function renderStoryItem(item, $item, col)
|
||||
.attr('href', $.createLink('story', 'view', 'storyID=' + item.id + '&version=0¶m=' + execution.id, '', true)).attr('data-toggle', 'modal').attr('data-width', '95%');
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.title).find('.text').text(item.title);
|
||||
var title = rdSearchValue != '' ? "<span class='text'>" + item.title.replaceAll(rdSearchValue, "<span class='text-danger'>" + rdSearchValue + "</span>") + "</span>": "<span class='text'>" + item.title + "</span>";
|
||||
$title.attr('title', item.title).find('.text').replaceWith(title);
|
||||
}
|
||||
|
||||
if(scaleSize <= 2)
|
||||
@@ -542,7 +543,8 @@ function renderBugItem(item, $item, col)
|
||||
.attr('href', $.createLink('bug', 'view', 'bugID=' + item.id, '', true)).attr('data-toggle', 'modal').attr('data-width', '80%');
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.title).find('.text').text(item.title);
|
||||
var title = rdSearchValue != '' ? "<span class='text'>" + item.title.replaceAll(rdSearchValue, "<span class='text-danger'>" + rdSearchValue + "</span>") + "</span>": "<span class='text'>" + item.title + "</span>";
|
||||
$title.attr('title', item.title).find('.text').replaceWith(title);
|
||||
}
|
||||
|
||||
if(scaleSize <= 2)
|
||||
@@ -608,7 +610,8 @@ function renderTaskItem(item, $item, col)
|
||||
.attr('href', $.createLink('task', 'view', 'taskID=' + item.id, '', true)).attr('data-toggle', 'modal').attr('data-width', '80%');
|
||||
$title.appendTo($item);
|
||||
}
|
||||
$title.attr('title', item.name).find('.text').text(item.name);
|
||||
var name = rdSearchValue != '' ? "<span class='text'>" + item.name.replaceAll(rdSearchValue, "<span class='text-danger'>" + rdSearchValue + "</span>") + "</span>": "<span class='text'>" + item.name + "</span>";
|
||||
$title.attr('title', item.name).find('.text').replaceWith(name);
|
||||
}
|
||||
|
||||
if(scaleSize <= 2)
|
||||
@@ -792,6 +795,16 @@ function updateRegion(regionID, regionData = [])
|
||||
if(!regionData) regionData = regions[regionID];
|
||||
|
||||
var data = groupBy == 'default' ? regionData.groups : regionData;
|
||||
if(data == null)
|
||||
{
|
||||
$("div[data-id^=" + regionID + "].region").hide();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$("div[data-id^=" + regionID + "].region").show();
|
||||
}
|
||||
$region.empty();
|
||||
$region.data('zui.kanban').render(data);
|
||||
resetRegionHeight('open');
|
||||
return true;
|
||||
@@ -1504,7 +1517,7 @@ $(function()
|
||||
var lastUpdateData;
|
||||
setInterval(function()
|
||||
{
|
||||
$.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD'), function(data)
|
||||
$.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD&searchValue' + rdSearchValue), function(data)
|
||||
{
|
||||
if(data && lastUpdateData !== data)
|
||||
{
|
||||
@@ -1580,3 +1593,58 @@ function resetRegionHeight(fold)
|
||||
$('.region').css('height', regionHeaderHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle RDSearchBox.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function toggleRDSearchBox()
|
||||
{
|
||||
rdSearchValue = '';
|
||||
$('#rdSearchBox').toggle();
|
||||
if($('#rdSearchBox').css('display') == 'block')
|
||||
{
|
||||
$(".querybox-toggle").css("color", "#0c64eb");
|
||||
}
|
||||
else
|
||||
{
|
||||
$(".querybox-toggle").css("color", "");
|
||||
$('#rdKanbanSearchInput').attr('value', '');
|
||||
searchCards('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all cards.
|
||||
*
|
||||
* @param string $value
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function searchCards(value)
|
||||
{
|
||||
rdSearchValue = value;
|
||||
$.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD&searchValue=' + value), function(data)
|
||||
{
|
||||
var kanbanData = $.parseJSON(data);
|
||||
var hideAll = true;
|
||||
$('#kanban').children('.region').children("div[id^='kanban']").each(function()
|
||||
{
|
||||
var regionID = $(this).attr('data-id');
|
||||
if(kanbanData != null) data = groupBy == 'default' ? kanbanData[regionID] : kanbanData[groupBy];
|
||||
|
||||
hideAll = hideAll && !updateRegion(regionID, data);
|
||||
});
|
||||
|
||||
if(hideAll && rdSearchValue != '')
|
||||
{
|
||||
if($('.table-empty-tip').length == 0) $('#kanban').append('<div class="table-empty-tip"><p><span class="text-muted">' + kanbanLang.empty + '</span></p></div>');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('.table-empty-tip').remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -396,6 +396,7 @@ $lang->execution->projectNotEmpty = 'Project cannot be empty.';
|
||||
$lang->execution->confirmStoryToTask = $lang->SRCommon . '%s are converted to tasks in the current. Do you want to convert them anyways?';
|
||||
$lang->execution->ge = "『%s』should be >= actual begin『%s』.";
|
||||
$lang->execution->storyDragError = "The {$lang->SRCommon} is still a draft or has been changed, please drag it after the review";
|
||||
$lang->execution->pleaseInput = "Enter";
|
||||
|
||||
/* Statistics. */
|
||||
$lang->execution->charts = new stdclass();
|
||||
|
||||
@@ -396,6 +396,7 @@ $lang->execution->projectNotEmpty = '所属项目不能为空。';
|
||||
$lang->execution->confirmStoryToTask = '%s' . $lang->SRCommon . '已经在当前' . $lang->execution->common . '中转了任务,请确认是否重复转任务。';
|
||||
$lang->execution->ge = "『%s』应当不小于实际开始时间『%s』。";
|
||||
$lang->execution->storyDragError = "该{$lang->SRCommon}还是草稿或已变更状态,请评审通过后再拖动";
|
||||
$lang->execution->pleaseInput = "请输入";
|
||||
|
||||
/* 统计。*/
|
||||
$lang->execution->charts = new stdclass();
|
||||
|
||||
@@ -818,9 +818,11 @@ class executionModel extends model
|
||||
->setDefault('status', 'doing')
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->stripTags($this->config->execution->editor->start['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->start['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_EXECUTION)->data($execution)
|
||||
->autoCheck()
|
||||
->check($this->config->execution->start->requiredFields, 'notempty')
|
||||
@@ -849,6 +851,7 @@ class executionModel extends model
|
||||
|
||||
$execution = fixer::input('post')
|
||||
->add('id', $executionID)
|
||||
->stripTags($this->config->execution->editor->putoff['id'], $this->config->allowedTags)
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->remove('comment')
|
||||
@@ -857,6 +860,7 @@ class executionModel extends model
|
||||
if($this->config->systemMode == 'new') $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end);
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->putoff['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_EXECUTION)->data($execution)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
@@ -884,8 +888,10 @@ class executionModel extends model
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('suspendedDate', helper::today())
|
||||
->stripTags($this->config->execution->editor->suspend['id'], $this->config->allowedTags)
|
||||
->remove('comment')->get();
|
||||
|
||||
$execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->suspend['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_EXECUTION)->data($execution)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
@@ -913,6 +919,7 @@ class executionModel extends model
|
||||
->setDefault('status', 'doing')
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->stripTags($this->config->execution->editor->activate['id'], $this->config->allowedTags)
|
||||
->remove('comment,readjustTime,readjustTask')
|
||||
->get();
|
||||
|
||||
@@ -922,6 +929,7 @@ class executionModel extends model
|
||||
unset($execution->end);
|
||||
}
|
||||
|
||||
$execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->activate['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_EXECUTION)->data($execution)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
@@ -995,11 +1003,13 @@ class executionModel extends model
|
||||
->setDefault('closedDate', $now)
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->stripTags($this->config->execution->editor->close['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$this->lang->error->ge = $this->lang->execution->ge;
|
||||
|
||||
$execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->close['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_EXECUTION)->data($execution)
|
||||
->autoCheck()
|
||||
->check($this->config->execution->close->requiredFields,'notempty')
|
||||
|
||||
@@ -52,6 +52,7 @@ js::set('vision', $this->config->vision);
|
||||
js::set('productCount', count($productNames));
|
||||
js::set('executionID', $execution->id);
|
||||
js::set('reviewStoryParis', $reviewStoryParis);
|
||||
js::set('rdSearchValue', '');
|
||||
|
||||
$canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1;
|
||||
$canEditRegion = commonModel::hasPriv('kanban', 'editRegion');
|
||||
@@ -136,7 +137,13 @@ js::set('hasTaskButton', $hasTaskButton);
|
||||
</span>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<div class="input-group" id="rdKanbanSearch">
|
||||
<div class="input-control search-box" id="rdSearchBox">
|
||||
<input type="text" name="rdKanbanSearchInput" id="rdKanbanSearchInput" value="" class="form-control" oninput="searchCards(this.value)" placeholder="<?php echo $lang->execution->pleaseInput?>">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
echo html::a('javascript:toggleRDSearchBox()', "<i class='icon-search muted'></i> " . $lang->searchAB, '', "class='btn btn-link querybox-toggle'");
|
||||
echo html::a('javascript:fullScreen()', "<i class='icon-fullscreen muted'></i> " . $lang->kanban->fullScreen, '', "class='btn btn-link'");
|
||||
$actions = '';
|
||||
$printCreateRegion = (common::hasPriv('kanban', 'createRegion') and $groupBy == 'default');
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#spaceList .spaceActions > a{margin-left: 10px;}
|
||||
.space .menu {margin-left: 5px; margin-right:5px;}
|
||||
.space .table-empty-tip {padding: 40px 10px;}
|
||||
.space .spaceTitle.pull-left {overflow: hidden; white-space: nowrap; max-width: calc(100% - 255px)}
|
||||
.space .spaceTitle.pull-left {overflow: hidden; white-space: nowrap; max-width: calc(100% - 150px)}
|
||||
.spaceDesc {font-size: 13px; color: #838A9D; margin: -5px 0 5px 18px;}
|
||||
#more .setting {margin-left: -25px; min-width: 80px}
|
||||
|
||||
.kanbans > .col {width: 25% !important;}
|
||||
@media screen and (max-width: 1500px) {.kanbans > .col {width: 25%;}}
|
||||
|
||||
@@ -26,6 +26,7 @@ $lang->kanban->columnWidth = 'Column Width';
|
||||
$lang->kanban->setColumnWidth = 'Set Column Width';
|
||||
$lang->kanban->deleteLane = 'Delete Lane';
|
||||
$lang->kanban->createColumn = 'Create Column';
|
||||
$lang->kanban->emptyDesc = 'No description';
|
||||
$lang->kanban->editColumn = 'Edit Column';
|
||||
$lang->kanban->sortColumn = 'Sort Column';
|
||||
$lang->kanban->deleteColumn = 'Delete Column';
|
||||
@@ -275,14 +276,14 @@ $lang->kanbanspace->empty = 'No Space';
|
||||
$lang->kanbanspace->aclList['open'] = 'Open (Accessible with kanban view permissions)';
|
||||
$lang->kanbanspace->aclList['private'] = 'Private (For the space owner, team and whitelist members only)';
|
||||
|
||||
$lang->kanbanspace->featureBar['private'] = 'Private Space';
|
||||
$lang->kanbanspace->featureBar['involved'] = 'Involved';
|
||||
$lang->kanbanspace->featureBar['cooperation'] = 'Cooperation Space';
|
||||
$lang->kanbanspace->featureBar['public'] = 'Public Space';
|
||||
$lang->kanbanspace->featureBar['involved'] = 'Involved';
|
||||
$lang->kanbanspace->featureBar['private'] = 'Private Space';
|
||||
|
||||
$lang->kanbanspace->typeList['private'] = 'Private Space';
|
||||
$lang->kanbanspace->typeList['cooperation'] = 'Cooperation Space';
|
||||
$lang->kanbanspace->typeList['public'] = 'Public Space';
|
||||
$lang->kanbanspace->typeList['private'] = 'Private Space';
|
||||
|
||||
$lang->kanbancolumn = new stdclass();
|
||||
$lang->kanbancolumn->name = $lang->kanban->columnName;
|
||||
|
||||
@@ -26,6 +26,7 @@ $lang->kanban->columnWidth = '列宽度';
|
||||
$lang->kanban->setColumnWidth = '设置列宽度';
|
||||
$lang->kanban->deleteLane = '删除泳道';
|
||||
$lang->kanban->createColumn = '创建看板列';
|
||||
$lang->kanban->emptyDesc = '暂无描述';
|
||||
$lang->kanban->editColumn = '编辑看板列';
|
||||
$lang->kanban->sortColumn = '看板列排序';
|
||||
$lang->kanban->deleteColumn = '删除看板列';
|
||||
@@ -275,14 +276,14 @@ $lang->kanbanspace->empty = '暂时没有空间';
|
||||
$lang->kanbanspace->aclList['open'] = '公开(有看板空间视图权限即可访问)';
|
||||
$lang->kanbanspace->aclList['private'] = '私有(只有看板空间负责人、团队成员、白名单可访问)';
|
||||
|
||||
$lang->kanbanspace->featureBar['private'] = '私人空间';
|
||||
$lang->kanbanspace->featureBar['involved'] = '我参与的';
|
||||
$lang->kanbanspace->featureBar['cooperation'] = '协作空间';
|
||||
$lang->kanbanspace->featureBar['public'] = '公共空间';
|
||||
$lang->kanbanspace->featureBar['involved'] = '我参与的';
|
||||
$lang->kanbanspace->featureBar['private'] = '私人空间';
|
||||
|
||||
$lang->kanbanspace->typeList['private'] = '私人空间';
|
||||
$lang->kanbanspace->typeList['cooperation'] = '协作空间';
|
||||
$lang->kanbanspace->typeList['public'] = '公共空间';
|
||||
$lang->kanbanspace->typeList['private'] = '私人空间';
|
||||
|
||||
$lang->kanbancolumn = new stdclass();
|
||||
$lang->kanbancolumn->name = $lang->kanban->columnName;
|
||||
|
||||
+22
-7
@@ -808,13 +808,14 @@ class kanbanModel extends model
|
||||
* @param string $orderBy
|
||||
* @param int $regionID
|
||||
* @param string $groupBy
|
||||
* @param string $searchValue
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getRDKanban($executionID, $browseType = 'all', $orderBy = 'id_desc', $regionID = 0, $groupBy = 'default')
|
||||
public function getRDKanban($executionID, $browseType = 'all', $orderBy = 'id_desc', $regionID = 0, $groupBy = 'default', $searchValue = '')
|
||||
{
|
||||
if($groupBy != 'default') return $this->getKanban4Group($executionID, $browseType, $groupBy);
|
||||
if($groupBy != 'default') return $this->getKanban4Group($executionID, $browseType, $groupBy, $searchValue);
|
||||
|
||||
$kanbanData = array();
|
||||
$actions = array('sortGroup');
|
||||
@@ -823,7 +824,7 @@ class kanbanModel extends model
|
||||
$groupGroup = $this->getGroupGroupByRegions($regionIDList);
|
||||
$laneGroup = $this->getLaneGroupByRegions($regionIDList, $browseType);
|
||||
$columnGroup = $this->getRDColumnGroupByRegions($regionIDList, array_keys($laneGroup));
|
||||
$cardGroup = $this->getCardGroupByExecution($executionID, $browseType, $orderBy);
|
||||
$cardGroup = $this->getCardGroupByExecution($executionID, $browseType, $orderBy, $searchValue);
|
||||
|
||||
foreach($regions as $regionID => $regionName)
|
||||
{
|
||||
@@ -838,13 +839,16 @@ class kanbanModel extends model
|
||||
$lanes = zget($laneGroup, $group->id, array());
|
||||
if(!$lanes) continue;
|
||||
|
||||
foreach($lanes as $lane)
|
||||
foreach($lanes as $key => $lane)
|
||||
{
|
||||
$this->refreshCards($lane);
|
||||
$lane->items = isset($cardGroup[$lane->id]) ? $cardGroup[$lane->id] : array();
|
||||
$lane->defaultCardType = $lane->type;
|
||||
if($searchValue != '' and count($lane->items) == 0) unset($lanes[$key]);
|
||||
}
|
||||
$lanes = array_values($lanes);
|
||||
|
||||
if($searchValue != '' and empty($lanes)) continue;
|
||||
$group->columns = zget($columnGroup, $group->id, array());
|
||||
$group->lanes = $lanes;
|
||||
$group->actions = array();
|
||||
@@ -1250,10 +1254,12 @@ class kanbanModel extends model
|
||||
* @param int $kanbanID
|
||||
* @param string $browseType all|task|bug|story
|
||||
* @param string $orderBy
|
||||
* @param string $searchValue
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc')
|
||||
public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc', $searchValue = '')
|
||||
{
|
||||
$cards = $this->dao->select('t1.*, t2.type as columnType')
|
||||
->from(TABLE_KANBANCELL)->alias('t1')
|
||||
@@ -1297,12 +1303,14 @@ class kanbanModel extends model
|
||||
|
||||
if($cell->type == 'task')
|
||||
{
|
||||
if($searchValue != '' and strpos($object->name, $searchValue) === false) continue;
|
||||
$cardData['name'] = $object->name;
|
||||
$cardData['status'] = $object->status;
|
||||
$cardData['left'] = $object->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($searchValue != '' and strpos($object->title, $searchValue) === false) continue;
|
||||
$cardData['title'] = $object->title;
|
||||
}
|
||||
$cardGroup[$laneID][$cell->columnType][] = $cardData;
|
||||
@@ -1406,12 +1414,14 @@ class kanbanModel extends model
|
||||
|
||||
if($lane->type == 'task')
|
||||
{
|
||||
if($searchValue != '' and strpos($object->name, $searchValue) === false) continue;
|
||||
$cardData['name'] = $object->name;
|
||||
$cardData['status'] = $object->status;
|
||||
$cardData['left'] = $object->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($searchValue != '' and strpos($object->title, $searchValue) === false) continue;
|
||||
$cardData['title'] = $object->title;
|
||||
}
|
||||
|
||||
@@ -1440,10 +1450,12 @@ class kanbanModel extends model
|
||||
* @param int $executionID
|
||||
* @param string $browseType
|
||||
* @param string $groupBy
|
||||
* @param string $searchValue
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getKanban4Group($executionID, $browseType, $groupBy)
|
||||
public function getKanban4Group($executionID, $browseType, $groupBy, $searchValue = '')
|
||||
{
|
||||
/* Get card data. */
|
||||
$cardList = array();
|
||||
@@ -1551,21 +1563,24 @@ class kanbanModel extends model
|
||||
|
||||
if($browseType == 'task')
|
||||
{
|
||||
if($searchValue != '' and strpos($object->name, $searchValue) === false) continue;
|
||||
$cardData['name'] = $object->name;
|
||||
$cardData['status'] = $object->status;
|
||||
$cardData['left'] = $object->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($searchValue != '' and strpos($object->title, $searchValue) === false) continue;
|
||||
$cardData['title'] = $object->title;
|
||||
}
|
||||
|
||||
$laneData['cards'][$column->columnType][] = $cardData;
|
||||
$cardOrder ++;
|
||||
}
|
||||
if(!isset($laneData['cards'][$column->columnType])) $laneData['cards'][$column->columnType] = array();
|
||||
if(empty($searchValue) and !isset($laneData['cards'][$column->columnType])) $laneData['cards'][$column->columnType] = array();
|
||||
}
|
||||
|
||||
if($searchValue != '' and empty($laneData['cards'])) continue;
|
||||
$kanbanGroup[$groupBy]['id'] = $groupBy . $laneID;
|
||||
$kanbanGroup[$groupBy]['columns'] = array_values($columnData);
|
||||
$kanbanGroup[$groupBy]['lanes'][] = $laneData;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanspace->type;?></th>
|
||||
<td><?php echo html::select('type', $typeList, $type, "onchange='changeType(this.value)' class='form-control chosen'");?></td>
|
||||
<td><?php echo html::radio('type', $typeList, $type, "onchange='changeType(this.value)'");?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanspace->type;?></th>
|
||||
<td><?php echo html::select('type', $typeList, $defaultType, "onchange='changeType(this.value)' class='form-control chosen'");?></td>
|
||||
<td><?php echo html::radio('type', $typeList, $defaultType, "onchange='changeType(this.value)'");?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -47,17 +47,23 @@
|
||||
<?php echo $space->name;?>
|
||||
</h4>
|
||||
</div>
|
||||
<p class="spaceDesc text-ellipsis text-primary" title='<?php echo empty($space->desc) ? $lang->kanban->emptyDesc : $space->desc;?>'><?php echo empty($space->desc) ? $lang->kanban->emptyDesc : $space->desc;?></p>
|
||||
</div>
|
||||
<div class='spaceActions pull-right'>
|
||||
<?php $class = $space->status == 'closed' ? 'disabled' : '';?>
|
||||
<?php if($space->status != 'closed' and $browseType != 'involved' and !empty($unclosedSpace)) common::printLink('kanban', 'create', "spaceID={$space->id}&type={$space->type}", '<i class="icon icon-plus"></i> ' . $lang->kanban->create, '', "class='iframe' data-width='75%'", '', true);?>
|
||||
<?php common::printLink('kanban', 'editSpace', "spaceID={$space->id}", '<i class="icon icon-cog-outline"></i> ' . $lang->kanban->setting, '', "class='iframe' data-width='75%'", '', true);?>
|
||||
<?php if($class == 'disabled'):?>
|
||||
<?php common::printLink('kanban', 'activateSpace', "spaceID={$space->id}", '<i class="icon icon-magic"></i> ' . $lang->activate, '', "class='iframe'", '', true);?>
|
||||
<?php else:?>
|
||||
<?php common::printLink('kanban', 'closeSpace', "spaceID={$space->id}", '<i class="icon icon-off"></i> ' . $lang->close, '', "class='iframe'", '', true);?>
|
||||
<?php endif;?>
|
||||
<?php common::printLink('kanban', 'deleteSpace', "spaceID={$space->id}", '<i class="icon icon-trash"></i> ' . $lang->delete, 'hiddenwin', '', '', true);?>
|
||||
<div class="btn-group" id="more">
|
||||
<a href="javascript:;" data-toggle="dropdown" class="btn btn-link " style="border-radius: 4px;"><?php echo $lang->kanban->setting;?><span class="caret"></span></a>
|
||||
<ul class="dropdown-menu setting">
|
||||
<li><?php common::printLink('kanban', 'editSpace', "spaceID={$space->id}", '<i class="icon icon-cog-outline"></i> ' . $lang->kanban->setting, '', "class='iframe' data-width='75%'", '', true);?></li>
|
||||
<li><?php if($class == 'disabled'):?>
|
||||
<?php common::printLink('kanban', 'activateSpace', "spaceID={$space->id}", '<i class="icon icon-magic"></i> ' . $lang->activate, '', "class='iframe'", '', true);?>
|
||||
<?php else:?>
|
||||
<?php common::printLink('kanban', 'closeSpace', "spaceID={$space->id}", '<i class="icon icon-off"></i> ' . $lang->close, '', "class='iframe'", '', true);?>
|
||||
<?php endif;?></li>
|
||||
<li><?php common::printLink('kanban', 'deleteSpace', "spaceID={$space->id}", '<i class="icon icon-trash"></i> ' . $lang->delete, 'hiddenwin', '', '', true);?></li>
|
||||
<ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if(isset($space->kanbans)):?>
|
||||
|
||||
+37
-30
@@ -75,18 +75,19 @@ class my extends control
|
||||
/**
|
||||
* My work view.
|
||||
*
|
||||
* @param string $mode
|
||||
* @param string $type
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @param string $mode
|
||||
* @param string $type
|
||||
* @param string|int $param
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function work($mode = 'task', $type = 'assignedTo', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
public function work($mode = 'task', $type = 'assignedTo', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
echo $this->fetch('my', $mode, "type=$type&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
|
||||
echo $this->fetch('my', $mode, "type=$type¶m=$param&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
|
||||
|
||||
$this->showWorkCount($recTotal, $recPerPage, $pageID);
|
||||
}
|
||||
@@ -210,20 +211,21 @@ EOF;
|
||||
/**
|
||||
* My contribute view.
|
||||
*
|
||||
* @param string $mode
|
||||
* @param string $type
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @param string $mode
|
||||
* @param string $type
|
||||
* @param string|int $param
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function contribute($mode = 'task', $type = 'openedBy', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
public function contribute($mode = 'task', $type = 'openedBy', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
if(($mode == 'issue' or $mode == 'risk') and $type == 'openedBy') $type = 'createdBy';
|
||||
|
||||
echo $this->fetch('my', $mode, "type=$type&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
|
||||
echo $this->fetch('my', $mode, "type=$type¶m=$param&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -596,15 +598,16 @@ EOF;
|
||||
/**
|
||||
* My test case.
|
||||
*
|
||||
* @param string $type assigntome|openedbyme
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @param string $type assigntome|openedbyme
|
||||
* @param string|int $param
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function testcase($type = 'assigntome', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
public function testcase($type = 'assigntome', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
$this->loadModel('testtask');
|
||||
@@ -620,20 +623,24 @@ EOF;
|
||||
|
||||
/* Append id for secend sort. */
|
||||
$sort = common::appendOrder($orderBy);
|
||||
$queryID = ($type == 'bysearch') ? (int)$param : 0;
|
||||
|
||||
$cases = array();
|
||||
if($type == 'assigntome')
|
||||
{
|
||||
$cases = $this->testcase->getByAssignedTo($this->app->user->account, $sort, $pager, 'skip');
|
||||
}
|
||||
elseif($type == 'openedbyme')
|
||||
{
|
||||
$cases = $this->testcase->getByOpenedBy($this->app->user->account, $sort, $pager, 'skip');
|
||||
}
|
||||
if($type == 'assigntome') $cases = $this->testcase->getByAssignedTo($this->app->user->account, $sort, $pager, 'skip');
|
||||
if($type == 'openedbyme') $cases = $this->testcase->getByOpenedBy($this->app->user->account, $sort, $pager, 'skip');
|
||||
if($type == 'bysearch' and $this->app->rawMethod == 'contribute') $cases = $this->my->getTestcasesBySearch($queryID, 'openedbyme', $orderBy, $pager);
|
||||
if($type == 'bysearch' and $this->app->rawMethod == 'work') $cases = $this->my->getTestcasesBySearch($queryID, 'assigntome', $orderBy, $pager);
|
||||
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', $type == 'assigntome' ? false : true);
|
||||
|
||||
$cases = $this->testcase->appendData($cases, $type == 'assigntome' ? 'run' : 'case');
|
||||
|
||||
/* Build the search form. */
|
||||
$currentMethod = $this->app->rawMethod;
|
||||
$actionURL = $this->createLink('my', $currentMethod, "mode=testcase&type=bysearch¶m=myQueryID&orderBy={$orderBy}&recTotal={$recTotal}&recPerPage={$recPerPage}&pageID={$pageID}");
|
||||
$this->config->testcase->search['onMenuBar'] = 'yes';
|
||||
$this->my->buildTestcaseSearchForm($queryID, $actionURL, $currentMethod);
|
||||
|
||||
/* Assign. */
|
||||
$this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->myTestCase;
|
||||
$this->view->position[] = $this->lang->my->myTestCase;
|
||||
|
||||
@@ -43,6 +43,7 @@ $lang->my->testcase = 'My Case';
|
||||
$lang->my->storyConcept = 'Story Concept';
|
||||
$lang->my->pri = 'Priority';
|
||||
$lang->my->alert = 'You can click on your profile at the top right and select "Preference" to modify your information. ';
|
||||
$lang->my->assignedToMe = 'AssignedToMe';
|
||||
|
||||
$lang->my->indexAction = 'My Index';
|
||||
$lang->my->calendarAction = 'My Calendar';
|
||||
|
||||
@@ -43,6 +43,7 @@ $lang->my->testcase = '我的用例';
|
||||
$lang->my->storyConcept = $config->URAndSR ? '默认需求概念组合' : '默认需求概念';
|
||||
$lang->my->pri = '优先级';
|
||||
$lang->my->alert = '后续您可以点击右上方的头像,选择“个性化设置”修改信息。';
|
||||
$lang->my->assignedToMe = '指派给我';
|
||||
|
||||
$lang->my->indexAction = '地盘仪表盘';
|
||||
$lang->my->calendarAction = '我的日程';
|
||||
|
||||
@@ -374,4 +374,88 @@ class myModel extends model
|
||||
}
|
||||
return $objectList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @param string $type
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildTestCaseSearchForm($queryID, $actionURL, $type)
|
||||
{
|
||||
$products = $this->dao->select('id,name')->from(TABLE_PRODUCT)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->products)->fi()
|
||||
->orderBy('order_asc')
|
||||
->fetchPairs();
|
||||
|
||||
$queryName = $type == 'contribute' ? 'contributeTestcase' : 'workTestcase';
|
||||
$this->app->loadConfig('testcase');
|
||||
$this->config->testcase->search['module'] = $queryName;
|
||||
$this->config->testcase->search['queryID'] = $queryID;
|
||||
$this->config->testcase->search['actionURL'] = $actionURL;
|
||||
$this->config->testcase->search['params']['product']['values'] = $products;
|
||||
$this->config->testcase->search['params']['lib']['values'] = $this->loadModel('caselib')->getLibraries();
|
||||
|
||||
unset($this->config->testcase->search['fields']['module']);
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->testcase->search);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get testcases by search.
|
||||
*
|
||||
* @param int $queryID
|
||||
* @param string $type
|
||||
* @param string $orderBy
|
||||
* @param int $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTestcasesBySearch($queryID, $type, $orderBy, $pager)
|
||||
{
|
||||
$queryName = $type == 'openedbyme' ? 'contributeTestcaseQuery' : 'workTestcaseQuery';
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set($queryName, $query->sql);
|
||||
$this->session->set($queryName . 'Form', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set($queryName, ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
|
||||
}
|
||||
|
||||
$myTestcaseQuery = $this->session->$queryName;
|
||||
$myTestcaseQuery = preg_replace('/`(\w+)`/', 't1.`$1`', $myTestcaseQuery);
|
||||
|
||||
if($type == 'openedbyme')
|
||||
{
|
||||
$cases = $this->dao->select('*')->from(TABLE_CASE)->alias('t1')
|
||||
->where($myTestcaseQuery)
|
||||
->andWhere('t1.openedBy')->eq($this->app->user->account)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->orderBy($orderBy)->page($pager)->fetchAll('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
$cases = $this->dao->select('t1.*')->from(TABLE_CASE)->alias('t1')
|
||||
->leftJoin(TABLE_TESTRUN)->alias('t2')->on('t1.id = t2.case')
|
||||
->where($myTestcaseQuery)
|
||||
->andWhere('t2.assignedTo')->eq($this->app->user->account)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->orderBy($orderBy)->page($pager)->fetchAll('id');
|
||||
}
|
||||
return $cases;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,20 @@
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php
|
||||
$recTotalLabel = " <span class='label label-light label-badge'>{$pager->recTotal}</span>";
|
||||
if($app->rawMethod == 'contribute') echo html::a(inlink($app->rawMethod, "mode=$mode&type=openedbyme"), "<span class='text'>{$lang->testcase->openedByMe}</span>" . ($type == 'openedbyme' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'openedbyme' ? ' btn-active-text' : '') . "'");
|
||||
if($app->rawMethod == 'contribute')
|
||||
{
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=openedbyme"), "<span class='text'>{$lang->testcase->openedByMe}</span>" . ($type == 'openedbyme' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'openedbyme' ? ' btn-active-text' : '') . "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=assigntome"), "<span class='text'>{$lang->my->assignedToMe}</span>" . ($type == 'assigntome' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'assigntome' ? ' btn-active-text' : '') . "'");
|
||||
}
|
||||
?>
|
||||
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i><?php $this->loadModel('search');echo $lang->search->common;?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mainContent">
|
||||
<div class="cell<?php if($type == 'bysearch') echo ' show';?>" id="queryBox" data-module=<?php echo ($app->rawMethod == 'contribute' ? 'contributeTestcase' : 'workTestcase');?>></div>
|
||||
<?php if(empty($cases)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p><span class="text-muted"><?php echo $lang->testcase->noCase;?></span></p>
|
||||
|
||||
@@ -872,11 +872,14 @@ class productModel extends model
|
||||
{
|
||||
$oldProduct = $this->getById($productID);
|
||||
$now = helper::now();
|
||||
$product= fixer::input('post')
|
||||
$product = fixer::input('post')
|
||||
->add('id', $productID)
|
||||
->setDefault('status', 'closed')
|
||||
->remove('comment')->get();
|
||||
->stripTags($this->config->product->editor->close['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$product = $this->loadModel('file')->processImgURL($product, $this->config->product->editor->close['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_PRODUCT)->data($product)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
|
||||
@@ -15,3 +15,21 @@ $config->productplan->editor->view = array('id' => 'lastComment', 'tools' => '
|
||||
$config->productplan->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#FFC20E', '#00A78E', '#7FBB00', '#424BAC', '#C0E9FF', '#EC2761');
|
||||
|
||||
$config->productplan->future = '2030-01-01';
|
||||
|
||||
global $app, $lang;
|
||||
$app->loadLang('productplan');
|
||||
$config->productplan->search['module'] = 'productplan';
|
||||
|
||||
$config->productplan->search['fields']['id'] = $lang->productplan->id;
|
||||
$config->productplan->search['fields']['title'] = $lang->productplan->title;
|
||||
$config->productplan->search['fields']['branch'] = $lang->productplan->branch;
|
||||
$config->productplan->search['fields']['status'] = $lang->productplan->status;
|
||||
$config->productplan->search['fields']['begin'] = $lang->productplan->begin;
|
||||
$config->productplan->search['fields']['end'] = $lang->productplan->end;
|
||||
|
||||
$config->productplan->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
$config->productplan->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->productplan->search['params']['branch'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->productplan->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->productplan->statusList);
|
||||
$config->productplan->search['params']['begin'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->productplan->search['params']['end'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
|
||||
@@ -283,15 +283,16 @@ class productplan extends control
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param string $orderBy
|
||||
* @param string $browseType
|
||||
* @param int $queryID
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse($productID = 0, $branch = '', $browseType = 'undone', $orderBy = 'begin_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1 )
|
||||
public function browse($productID = 0, $branch = '', $browseType = 'undone', $queryID = 0, $orderBy = 'begin_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1 )
|
||||
{
|
||||
$branchID = $branch === '' ? 'all' : $branch;
|
||||
if(!$branch) $branch = 0;
|
||||
@@ -313,6 +314,11 @@ class productplan extends control
|
||||
$branchStatusList = array();
|
||||
foreach($branchList as $productBranch) $branchStatusList[$productBranch->id] = $productBranch->status;
|
||||
|
||||
/* Build the search form. */
|
||||
$queryID = $browseType == 'bySearch' ? (int)$queryID : 0;
|
||||
$actionURL = $this->createLink('productplan', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
|
||||
$this->productplan->buildSearchForm($queryID, $actionURL, $product);
|
||||
|
||||
if($viewType == 'kanban')
|
||||
{
|
||||
$branches = array();
|
||||
@@ -353,10 +359,11 @@ class productplan extends control
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->viewType = $viewType;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->plans = $this->productplan->getList($productID, $branch, $browseType, $pager, $sort);
|
||||
$this->view->plans = $this->productplan->getList($productID, $branch, $browseType, $pager, $sort, "", $queryID);
|
||||
$this->view->pager = $pager;
|
||||
$this->view->projects = $this->product->getProjectPairsByProduct($productID, $branch);
|
||||
$this->view->statusList = $this->lang->productplan->featureBar['browse'];
|
||||
$this->view->queryID = $queryID;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* The model file of productplan module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package productplan
|
||||
* @version $Id: model.php 4639 2013-04-11 02:06:35Z chencongzhi520@gmail.com $
|
||||
@@ -75,17 +75,39 @@ class productplanModel extends model
|
||||
* @param object $pager
|
||||
* @param string $orderBy
|
||||
* @param string $param skipparent
|
||||
* @param int $queryID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getList($product = 0, $branch = 0, $browseType = 'undone', $pager = null, $orderBy = 'begin_desc', $param = '')
|
||||
public function getList($product = 0, $branch = 0, $browseType = 'undone', $pager = null, $orderBy = 'begin_desc', $param = '', $queryID = 0)
|
||||
{
|
||||
if(!empty($queryID))
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('productplanQuery', $query->sql);
|
||||
$this->session->set('productplanForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('productplanQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->productplanQuery == false) $this->session->set('productplanQuery', ' 1 = 1');
|
||||
}
|
||||
|
||||
$productplanQuery = $this->session->productplanQuery;
|
||||
|
||||
$date = date('Y-m-d');
|
||||
$plans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)->where('product')->eq($product)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->beginIF(!empty($branch) and $branch != 'all')->andWhere('branch')->eq($branch)->fi()
|
||||
->beginIF(strpos(',all,undone,', ",$browseType,") === false)->andWhere('status')->eq($browseType)->fi()
|
||||
->beginIF(strpos(',all,undone,bySearch,', ",$browseType,") === false)->andWhere('status')->eq($browseType)->fi()
|
||||
->beginIF($browseType == 'undone')->andWhere('status')->in('wait,doing')->fi()
|
||||
->beginIF($browseType == 'bySearch')->andWhere($productplanQuery)->fi()
|
||||
->beginIF(strpos($param, 'skipparent') !== false)->andWhere('parent')->ne(-1)->fi()
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
@@ -1182,4 +1204,23 @@ class productplanModel extends model
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @param object $product
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($queryID, $actionURL, $product)
|
||||
{
|
||||
$this->config->productplan->search['actionURL'] = $actionURL;
|
||||
$this->config->productplan->search['queryID'] = $queryID;
|
||||
|
||||
if($product->type != 'normal') $this->config->productplan->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($product->id, 'noempty');
|
||||
if($product->type == 'normal') unset($this->config->productplan->search['fields']['branch']);
|
||||
$this->loadModel('search')->setSearchParams($this->config->productplan->search);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<?php $active = $menuItem->name == $browseType ? 'btn-active-text' : '';?>
|
||||
<?php echo html::a($this->inlink('browse', "productID=$productID&branch=&browseType={$menuItem->name}"), $label, '', "class='btn btn-link $active' id='{$menuItem->name}'");?>
|
||||
<?php endforeach;?>
|
||||
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i><?php echo $lang->searchAB;?></a>
|
||||
</div>
|
||||
<div class="btn-toolbar pull-right">
|
||||
<div class="btn-group panel-actions">
|
||||
@@ -30,6 +31,7 @@
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell<?php if($browseType == 'bySearch') echo ' show';?>" id="queryBox" data-module='productplan'></div>
|
||||
<div id="mainContent">
|
||||
<?php if(empty($plans)):?>
|
||||
<div class="table-empty-tip">
|
||||
@@ -44,7 +46,7 @@
|
||||
<form class='main-table table-productplan' data-ride='table' method='post' id='productplanForm' action='<?php echo inlink('batchEdit', "productID=$product->id&branch=$branch")?>'>
|
||||
<table class='table has-sort-head' id="productplanList">
|
||||
<thead>
|
||||
<?php $vars = "productID=$productID&branch=$branch&browseType=$browseType&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
|
||||
<?php $vars = "productID=$productID&branch=$branch&browseType=$browseType&queryID=$queryID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
|
||||
<tr>
|
||||
<th class='c-id'>
|
||||
<?php if(common::hasPriv('productplan', 'batchEdit') or common::hasPriv('productplan', 'batchChangeStatus')):?>
|
||||
|
||||
@@ -1582,13 +1582,18 @@ class projectModel extends model
|
||||
$oldProject = $this->getById($projectID, $type);
|
||||
$now = helper::now();
|
||||
|
||||
$editorIdList = $this->config->project->editor->start['id'];
|
||||
if($this->app->rawModule == 'program') $editorIdList = $this->config->program->editor->start['id'];
|
||||
|
||||
$project = fixer::input('post')
|
||||
->add('id', $projectID)
|
||||
->setDefault('status', 'doing')
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->stripTags($editorIdList, $this->config->allowedTags)
|
||||
->remove('comment')->get();
|
||||
|
||||
$project = $this->loadModel('file')->processImgURL($project, $editorIdList, $this->post->uid);
|
||||
$this->dao->update(TABLE_PROJECT)->data($project)
|
||||
->autoCheck()
|
||||
->check($this->config->project->start->requiredFields, 'notempty')
|
||||
@@ -1640,15 +1645,20 @@ class projectModel extends model
|
||||
*/
|
||||
public function suspend($projectID)
|
||||
{
|
||||
$editorIdList = $this->config->project->editor->suspend['id'];
|
||||
if($this->app->rawModule == 'program') $editorIdList = $this->config->program->editor->suspend['id'];
|
||||
|
||||
$oldProject = $this->getById($projectID);
|
||||
$project = fixer::input('post')
|
||||
$project = fixer::input('post')
|
||||
->add('id', $projectID)
|
||||
->setDefault('status', 'suspended')
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', helper::now())
|
||||
->setDefault('suspendedDate', helper::today())
|
||||
->stripTags($editorIdList, $this->config->allowedTags)
|
||||
->remove('comment')->get();
|
||||
|
||||
$project = $this->loadModel('file')->processImgURL($project, $editorIdList, $this->post->uid);
|
||||
$this->dao->update(TABLE_PROJECT)->data($project)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
@@ -1670,6 +1680,9 @@ class projectModel extends model
|
||||
$oldProject = $this->getById($projectID);
|
||||
$now = helper::now();
|
||||
|
||||
$editorIdList = $this->config->project->editor->activate['id'];
|
||||
if($this->app->rawModule == 'program') $editorIdList = $this->config->program->editor->activate['id'];
|
||||
|
||||
$project = fixer::input('post')
|
||||
->add('id', $projectID)
|
||||
->setDefault('realEnd','')
|
||||
@@ -1677,6 +1690,7 @@ class projectModel extends model
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setIF($oldProject->realBegan == '0000-00-00', 'realBegan', helper::today())
|
||||
->stripTags($editorIdList, $this->config->allowedTags)
|
||||
->remove('comment,readjustTime,readjustTask')
|
||||
->get();
|
||||
|
||||
@@ -1686,6 +1700,7 @@ class projectModel extends model
|
||||
unset($project->end);
|
||||
}
|
||||
|
||||
$project = $this->loadModel('file')->processImgURL($project, $editorIdList, $this->post->uid);
|
||||
$this->dao->update(TABLE_PROJECT)->data($project)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
@@ -1742,6 +1757,9 @@ class projectModel extends model
|
||||
$oldProject = $this->getById($projectID);
|
||||
$now = helper::now();
|
||||
|
||||
$editorIdList = $this->config->project->editor->close['id'];
|
||||
if($this->app->rawModule == 'program') $editorIdList = $this->config->program->editor->close['id'];
|
||||
|
||||
$project = fixer::input('post')
|
||||
->add('id', $projectID)
|
||||
->setDefault('status', 'closed')
|
||||
@@ -1749,11 +1767,14 @@ class projectModel extends model
|
||||
->setDefault('closedDate', $now)
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->stripTags($editorIdList, $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$this->lang->error->ge = $this->lang->project->ge;
|
||||
|
||||
$project = $this->loadModel('file')->processImgURL($project, $editorIdList, $this->post->uid);
|
||||
|
||||
$this->dao->update(TABLE_PROJECT)->data($project)
|
||||
->autoCheck()
|
||||
->check($this->config->project->close->requiredFields, 'notempty')
|
||||
|
||||
@@ -830,7 +830,6 @@ class storyModel extends model
|
||||
if(isset($story->stage) and $oldStory->stage != $story->stage) $story->stagedBy = (strpos('tested|verified|released|closed', $story->stage) !== false) ? $this->app->user->account : '';
|
||||
$story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->edit['id'], $this->post->uid);
|
||||
|
||||
|
||||
if(isset($_POST['reviewer']))
|
||||
{
|
||||
$_POST['reviewer'] = array_filter($_POST['reviewer']);
|
||||
@@ -1327,6 +1326,7 @@ class storyModel extends model
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('status', $oldStory->status)
|
||||
->setDefault('reviewedDate', $date)
|
||||
->stripTags($this->config->story->editor->review['id'], $this->config->allowedTags)
|
||||
->setIF($this->post->result == 'revert', 'version', $this->post->preVersion)
|
||||
->setIF($this->post->result == 'clarify', 'assignedTo', $oldStory->lastEditedBy ? $oldStory->lastEditedBy : $oldStory->openedBy)
|
||||
->removeIF($this->post->result != 'reject', 'closedReason, duplicateStory, childStories')
|
||||
@@ -1336,6 +1336,7 @@ class storyModel extends model
|
||||
->add('id', $storyID)
|
||||
->remove('result,preVersion,comment')
|
||||
->get();
|
||||
$story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->review['id'], $this->post->uid);
|
||||
|
||||
/* Fix bug #671. */
|
||||
$this->lang->story->closedReason = $this->lang->story->rejectedReason;
|
||||
@@ -1563,6 +1564,7 @@ class storyModel extends model
|
||||
->setDefault('closedDate', $now)
|
||||
->setDefault('closedBy', $this->app->user->account)
|
||||
->setDefault('assignedDate', $now)
|
||||
->stripTags($this->config->story->editor->close['id'], $this->config->allowedTags)
|
||||
->removeIF($this->post->closedReason != 'duplicate', 'duplicateStory')
|
||||
->removeIF($this->post->closedReason != 'subdivided', 'childStories')
|
||||
->get();
|
||||
@@ -1578,6 +1580,7 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
$this->lang->story->comment = $this->lang->comment;
|
||||
$story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->close['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_STORY)->data($story, 'comment')
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->story->close->requiredFields, 'notempty')
|
||||
@@ -1991,9 +1994,11 @@ class storyModel extends model
|
||||
->add('lastEditedBy', $this->app->user->account)
|
||||
->add('lastEditedDate', $now)
|
||||
->add('assignedDate', $now)
|
||||
->stripTags($this->config->story->editor->assignto['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->assignto['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->checkFlow()->where('id')->eq((int)$storyID)->exec();
|
||||
if(!dao::isError()) return common::createChanges($oldStory, $story);
|
||||
return false;
|
||||
@@ -2054,8 +2059,10 @@ class storyModel extends model
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('assignedDate', $now)
|
||||
->setDefault('activatedDate', $now)
|
||||
->stripTags($this->config->story->editor->activate['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
$story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->activate['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->checkFlow()->where('id')->eq($storyID)->exec();
|
||||
|
||||
if($this->post->status == 'active') $this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->exec();
|
||||
|
||||
@@ -555,7 +555,7 @@ $('#modalTeam .btn').click(function()
|
||||
}
|
||||
else
|
||||
{
|
||||
if(config.onlybody == 'yes')
|
||||
if(config.onlybody == 'yes' && vision == 'lite')
|
||||
{
|
||||
$('.close').parent().click();
|
||||
}
|
||||
|
||||
+17
-1
@@ -113,7 +113,7 @@ class taskModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
$task = $this->file->processImgURL($task, $this->config->task->editor->create['id'], $this->post->uid);
|
||||
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->create['id'], $this->post->uid);
|
||||
|
||||
/* Fix Bug #1525 */
|
||||
$executionType = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($executionID)->fetch('type');
|
||||
@@ -1465,6 +1465,7 @@ class taskModel extends model
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('assignedDate', $now)
|
||||
->stripTags($this->config->task->editor->assignto['id'], $this->config->allowedTags)
|
||||
->remove('comment,showModule')
|
||||
->get();
|
||||
if($oldTask->status != 'done' and $oldTask->status != 'closed' and isset($task->left) and $task->left == 0)
|
||||
@@ -1489,6 +1490,7 @@ class taskModel extends model
|
||||
|
||||
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
|
||||
|
||||
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->assignto['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TASK)
|
||||
->data($task)
|
||||
->autoCheck()
|
||||
@@ -1525,6 +1527,8 @@ class taskModel extends model
|
||||
}
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$editorIdList = $this->config->task->editor->start['id'];
|
||||
if($this->app->getMethodName() == 'restart') $editorIdList = $this->config->task->editor->restart['id'];
|
||||
$now = helper::now();
|
||||
$task = fixer::input('post')
|
||||
->add('id', $taskID)
|
||||
@@ -1532,9 +1536,11 @@ class taskModel extends model
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('status', 'doing')
|
||||
->setIF($oldTask->assignedTo != $this->app->user->account, 'assignedDate', $now)
|
||||
->stripTags($editorIdList, $this->config->allowedTags)
|
||||
->removeIF(!empty($oldTask->team), 'consumed,left')
|
||||
->remove('comment')->get();
|
||||
|
||||
$task = $this->loadModel('file')->processImgURL($task, $editorIdList, $this->post->uid);
|
||||
if($this->post->left == 0)
|
||||
{
|
||||
if(isset($task->consumed) and $task->consumed == 0)
|
||||
@@ -1763,6 +1769,7 @@ class taskModel extends model
|
||||
->setDefault('status', 'done')
|
||||
->setDefault('finishedBy, lastEditedBy', $this->app->user->account)
|
||||
->setDefault('finishedDate, lastEditedDate', $now)
|
||||
->stripTags($this->config->task->editor->finish['id'], $this->config->allowedTags)
|
||||
->removeIF(!empty($oldTask->team), 'finishedBy,status,left')
|
||||
->remove('comment,files,labels,currentConsumed')
|
||||
->get();
|
||||
@@ -1857,6 +1864,7 @@ class taskModel extends model
|
||||
|
||||
if($task->finishedDate == substr($now, 0, 10)) $task->finishedDate = $now;
|
||||
|
||||
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->finish['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TASK)->data($task)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
@@ -1896,9 +1904,11 @@ class taskModel extends model
|
||||
->setDefault('status', 'pause')
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', helper::now())
|
||||
->stripTags($this->config->task->editor->pause['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->pause['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->checkFlow()->where('id')->eq((int)$taskID)->exec();
|
||||
|
||||
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
|
||||
@@ -1932,12 +1942,14 @@ class taskModel extends model
|
||||
->setDefault('assignedDate', $now)
|
||||
->setDefault('closedBy, lastEditedBy', $this->app->user->account)
|
||||
->setDefault('closedDate, lastEditedDate', $now)
|
||||
->stripTags($this->config->task->editor->close['id'], $this->config->allowedTags)
|
||||
->setIF($oldTask->status == 'done', 'closedReason', 'done')
|
||||
->setIF($oldTask->status == 'cancel', 'closedReason', 'cancel')
|
||||
->remove('_recPerPage')
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->close['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->checkFlow()->where('id')->eq((int)$taskID)->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
@@ -1980,9 +1992,11 @@ class taskModel extends model
|
||||
->setDefault('finishedDate', '0000-00-00')
|
||||
->setDefault('canceledBy, lastEditedBy', $this->app->user->account)
|
||||
->setDefault('canceledDate, lastEditedDate', $now)
|
||||
->stripTags($this->config->task->editor->cancel['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->cancel['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->checkFlow()->where('id')->eq((int)$taskID)->exec();
|
||||
if($oldTask->fromBug) $this->dao->update(TABLE_BUG)->set('toTask')->eq(0)->where('id')->eq($oldTask->fromBug)->exec();
|
||||
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
|
||||
@@ -2044,6 +2058,7 @@ class taskModel extends model
|
||||
->setDefault('lastEditedDate', helper::now())
|
||||
->setDefault('assignedDate', helper::now())
|
||||
->setDefault('activatedDate', helper::now())
|
||||
->stripTags($this->config->task->editor->activate['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
@@ -2064,6 +2079,7 @@ class taskModel extends model
|
||||
$task = $this->computeHours4Multiple($oldTask, $task);
|
||||
}
|
||||
|
||||
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->activate['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TASK)->data($task)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->task->activate->requiredFields, 'notempty')
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<?php js::set('toTaskList', !empty($task->id));?>
|
||||
<?php js::set('blockID', $blockID);?>
|
||||
<?php js::set('teamMemberError', $lang->task->error->teamMember);?>
|
||||
<?php js::set('vision', $config->vision);?>
|
||||
<?php if(!empty($storyID)):?>
|
||||
<style> .title-group.required > .required:after {right: 110px;}</style>
|
||||
<?php endif;?>
|
||||
|
||||
+79
-41
@@ -61,6 +61,7 @@ class testcaseModel extends model
|
||||
->setIF($this->config->systemMode == 'new' and $this->app->tab == 'project', 'project', $this->session->project)
|
||||
->setIF($this->app->tab == 'execution', 'execution', $this->session->execution)
|
||||
->setIF($this->post->story != false, 'storyVersion', $this->loadModel('story')->getVersion((int)$this->post->story))
|
||||
->stripTags($this->config->testcase->editor->create['id'], $this->config->allowedTags)
|
||||
->remove('steps,expects,files,labels,stepType,forceNotReview')
|
||||
->setDefault('story', 0)
|
||||
->cleanInt('story,product,branch,module')
|
||||
@@ -77,6 +78,7 @@ class testcaseModel extends model
|
||||
|
||||
/* Value of story may be showmore. */
|
||||
$case->story = (int)$case->story;
|
||||
$case = $this->loadModel('file')->processImgURL($case, $this->config->testcase->editor->create['id'], $this->post->uid);
|
||||
$this->dao->insert(TABLE_CASE)->data($case)->autoCheck()->batchCheck($this->config->testcase->create->requiredFields, 'notempty')->checkFlow()->exec();
|
||||
if(!$this->dao->isError())
|
||||
{
|
||||
@@ -607,7 +609,7 @@ class testcaseModel extends model
|
||||
*/
|
||||
public function getByAssignedTo($account, $orderBy = 'id_desc', $pager = null, $auto = 'no')
|
||||
{
|
||||
return $this->dao->select('t1.*,t2.project,t2.pri,t2.title,t2.type,t2.openedBy,t2.color,t2.product,t2.branch,t2.module,t2.status,t3.name as taskName')->from(TABLE_TESTRUN)->alias('t1')
|
||||
return $this->dao->select('t1.task,t1.case,t1.version,t1.assignedTo,t1.lastRunner,t1.lastRunDate,t1.lastRunResult,t1.status,t2.id as id,t2.project,t2.pri,t2.title,t2.type,t2.openedBy,t2.color,t2.product,t2.branch,t2.module,t2.status,t3.name as taskName')->from(TABLE_TESTRUN)->alias('t1')
|
||||
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
|
||||
->leftJoin(TABLE_TESTTASK)->alias('t3')->on('t1.task = t3.id')
|
||||
->where('t1.assignedTo')->eq($account)
|
||||
@@ -768,6 +770,7 @@ class testcaseModel extends model
|
||||
->join('linkCase', ',')
|
||||
->setForce('status', $status)
|
||||
->cleanInt('story,product,branch,module')
|
||||
->stripTags($this->config->testcase->editor->edit['id'], $this->config->allowedTags)
|
||||
->remove('comment,steps,expects,files,labels,stepType')
|
||||
->get();
|
||||
|
||||
@@ -780,6 +783,7 @@ class testcaseModel extends model
|
||||
array_splice($requiredFieldsArr, $fieldIndex, 1);
|
||||
$requiredFields = implode(',', $requiredFieldsArr);
|
||||
}
|
||||
$case = $this->loadModel('file')->processImgURL($case, $this->config->testcase->editor->edit['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_CASE)->data($case)->autoCheck()->batchCheck($requiredFields, 'notempty')->checkFlow()->where('id')->eq((int)$caseID)->exec();
|
||||
if(!$this->dao->isError())
|
||||
{
|
||||
@@ -883,10 +887,12 @@ class testcaseModel extends model
|
||||
->setDefault('reviewedDate', substr($now, 0, 10))
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->stripTags($this->config->testcase->editor->review['id'], $this->config->allowedTags)
|
||||
->setForce('status', $status)
|
||||
->join('reviewedBy', ',')
|
||||
->get();
|
||||
|
||||
$case = $this->loadModel('file')->processImgURL($case, $this->config->testcase->editor->review['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_CASE)->data($case)->autoCheck()->checkFlow()->where('id')->eq($caseID)->exec();
|
||||
|
||||
if(dao::isError()) return false;
|
||||
@@ -1268,11 +1274,26 @@ class testcaseModel extends model
|
||||
->fetchGroup('case');
|
||||
$oldCases = $this->dao->select('*')->from(TABLE_CASE)->where('id')->in($_POST['id'])->fetchAll('id');
|
||||
}
|
||||
|
||||
$cases = array();
|
||||
$line = 1;
|
||||
$fieldNames = array();
|
||||
$storyVersionPairs = $this->story->getVersions($data->story);
|
||||
|
||||
$cases = array();
|
||||
$line = 1;
|
||||
$fieldNames = array();
|
||||
if($this->config->edition != 'open')
|
||||
{
|
||||
$extendFields = $this->getFlowExtendFields();
|
||||
$notEmptyRule = $this->loadModel('workflowrule')->getByTypeAndRule('system', 'notempty');
|
||||
|
||||
foreach($extendFields as $extendField)
|
||||
{
|
||||
if(strpos(",$extendField->rules,", ",$notEmptyRule->id,") !== false)
|
||||
{
|
||||
$this->config->testcase->create->requiredFields .= ',' . $extendField->field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($data->product as $key => $product)
|
||||
{
|
||||
$caseData = new stdclass();
|
||||
@@ -1289,6 +1310,18 @@ class testcaseModel extends model
|
||||
$caseData->frequency = 1;
|
||||
$caseData->precondition = $data->precondition[$key];
|
||||
|
||||
if($this->config->edition != 'open')
|
||||
{
|
||||
foreach($extendFields as $extendField)
|
||||
{
|
||||
$dataArray = $_POST[$extendField->field];
|
||||
$caseData->{$extendField->field} = $dataArray[$key];
|
||||
if(is_array($caseData->{$extendField->field})) $caseData->{$extendField->field} = join(',', $caseData->{$extendField->field});
|
||||
|
||||
$caseData->{$extendField->field} = htmlSpecialString($caseData->{$extendField->field});
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($this->config->testcase->create->requiredFields))
|
||||
{
|
||||
$requiredFields = explode(',', $this->config->testcase->create->requiredFields);
|
||||
@@ -1300,16 +1333,6 @@ class testcaseModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($this->config->testcase->appendFields))
|
||||
{
|
||||
foreach(explode(',', $this->config->testcase->appendFields) as $appendField)
|
||||
{
|
||||
if(empty($appendField)) continue;
|
||||
$caseData->$appendField = zget($_POST[$appendField], $key, '');
|
||||
if(is_array($caseData->$appendField)) $caseData->$appendField = join(',', $caseData->$appendField);
|
||||
}
|
||||
}
|
||||
|
||||
$cases[$key] = $caseData;
|
||||
$line++;
|
||||
}
|
||||
@@ -1382,34 +1405,38 @@ class testcaseModel extends model
|
||||
$caseData->lastEditedBy = $this->app->user->account;
|
||||
$caseData->lastEditedDate = $now;
|
||||
if($stepChanged and !$forceNotReview) $caseData->status = 'wait';
|
||||
$this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->exec();
|
||||
if($stepChanged)
|
||||
$this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->checkFlow()->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$parentStepID = 0;
|
||||
foreach($steps as $id => $step)
|
||||
if($stepChanged)
|
||||
{
|
||||
$step = (array)$step;
|
||||
if(empty($step['desc'])) continue;
|
||||
$stepData = new stdclass();
|
||||
$stepData->type = ($step['type'] == 'item' and $parentStepID == 0) ? 'step' : $step['type'];
|
||||
$stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0;
|
||||
$stepData->case = $caseID;
|
||||
$stepData->version = $version;
|
||||
$stepData->desc = $step['desc'];
|
||||
$stepData->expect = $step['expect'];
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
|
||||
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
|
||||
if($stepData->type == 'step') $parentStepID = 0;
|
||||
$parentStepID = 0;
|
||||
foreach($steps as $id => $step)
|
||||
{
|
||||
$step = (array)$step;
|
||||
if(empty($step['desc'])) continue;
|
||||
$stepData = new stdclass();
|
||||
$stepData->type = ($step['type'] == 'item' and $parentStepID == 0) ? 'step' : $step['type'];
|
||||
$stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0;
|
||||
$stepData->case = $caseID;
|
||||
$stepData->version = $version;
|
||||
$stepData->desc = $step['desc'];
|
||||
$stepData->expect = $step['expect'];
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
|
||||
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
|
||||
if($stepData->type == 'step') $parentStepID = 0;
|
||||
}
|
||||
}
|
||||
$oldCase->steps = $this->joinStep($oldStep);
|
||||
$caseData->steps = $this->joinStep($steps);
|
||||
$changes = common::createChanges($oldCase, $caseData);
|
||||
|
||||
$this->updateCase2Project($oldCase, $caseData, $caseID);
|
||||
|
||||
$actionID = $this->action->create('case', $caseID, 'Edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
$oldCase->steps = $this->joinStep($oldStep);
|
||||
$caseData->steps = $this->joinStep($steps);
|
||||
$changes = common::createChanges($oldCase, $caseData);
|
||||
|
||||
$this->updateCase2Project($oldCase, $caseData, $caseID);
|
||||
|
||||
$actionID = $this->action->create('case', $caseID, 'Edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1421,7 +1448,7 @@ class testcaseModel extends model
|
||||
$caseData->branch = isset($data->branch[$key]) ? $data->branch[$key] : $branch;
|
||||
if($caseData->story) $caseData->storyVersion = zget($storyVersionPairs, $caseData->story, 1);
|
||||
$caseData->status = !$forceNotReview ? 'wait' : 'normal';
|
||||
$this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->exec();
|
||||
$this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->checkFlow()->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
@@ -2123,7 +2150,13 @@ class testcaseModel extends model
|
||||
|
||||
if(!$case->needconfirm)
|
||||
{
|
||||
if(!isonlybody()) $menu .= $this->buildMenu('testcase', 'edit', $params, $case, 'view', '', '', 'showinonlybody');
|
||||
if(!isonlybody())
|
||||
{
|
||||
$editParams = $params;
|
||||
if($this->app->tab == 'project') $editParams .= "&comment=false&projectID={$this->session->project}";
|
||||
if($this->app->tab == 'execution') $editParams .= "&comment=false&executionID={$this->session->execution}";
|
||||
$menu .= $this->buildMenu('testcase', 'edit', $editParams, $case, 'view', '', '', 'showinonlybody');
|
||||
}
|
||||
if(!$case->isLibCase && $case->auto != 'unit')
|
||||
{
|
||||
$menu .= $this->buildMenu('testcase', 'create', "productID=$case->product&branch=$case->branch&moduleID=$case->module&from=testcase¶m=$case->id", $case, 'view', 'copy');
|
||||
@@ -2161,7 +2194,12 @@ class testcaseModel extends model
|
||||
|
||||
$menu .= $this->buildMenu('testtask', 'results', "runID=0&$params", $case, 'browse', '', '', 'iframe', true, "data-width='95%'");
|
||||
$menu .= $this->buildMenu('testtask', 'runCase', "runID=0&$params&version=$case->version", $case, 'browse', 'play', '', 'runCase iframe', false, "data-width='95%'");
|
||||
$menu .= $this->buildMenu('testcase', 'edit', "caseID=$case->id", $case, 'browse');
|
||||
|
||||
$editParams = $params;
|
||||
if($this->app->tab == 'project') $editParams .= "&comment=false&projectID={$this->session->project}";
|
||||
if($this->app->tab == 'execution') $editParams .= "&comment=false&executionID={$this->session->execution}";
|
||||
$menu .= $this->buildMenu('testcase', 'edit', $editParams, $case, 'browse');
|
||||
|
||||
if($this->config->testcase->needReview || !empty($this->config->testcase->forceReview))
|
||||
{
|
||||
common::printIcon('testcase', 'review', $params, $case, 'browse', 'glasses', '', 'iframe');
|
||||
|
||||
@@ -45,11 +45,19 @@ $(function()
|
||||
<th class='c-stage <?php if(strpos(",$requiredFields,", ',stage,') !== false) echo 'required';?>'><?php echo $lang->testcase->stage?></th>
|
||||
<th class='c-condition <?php if(strpos(",$requiredFields,", ',precondition,') !== false) echo 'required';?>'><?php echo $lang->testcase->precondition?></th>
|
||||
<th class='c-keywords <?php if(strpos(",$requiredFields,", ',keywords,') !== false) echo 'required';?>'><?php echo $lang->testcase->keywords?></th>
|
||||
<?php if(!empty($appendFields)):?>
|
||||
<?php foreach($appendFields as $appendField):?>
|
||||
<th class='c-extend'><?php echo $lang->testcase->{$appendField->field}?></th>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
<?php
|
||||
if(!empty($appendFields))
|
||||
{
|
||||
foreach($appendFields as $field)
|
||||
{
|
||||
if(!$field->show) continue;
|
||||
|
||||
$width = ($field->width && $field->width != 'auto' ? $field->width . 'px' : 'auto');
|
||||
$required = strpos(",$field->rules,", ",$notEmptyRule->id,") !== false ? 'required' : '';
|
||||
echo "<th class='$required c-extend' style='width: $width'>$field->name</th>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<th class='c-step'>
|
||||
<table class='w-p100 table-borderless'>
|
||||
<tr>
|
||||
@@ -106,12 +114,18 @@ $(function()
|
||||
<td style='overflow:visible'><?php echo html::select("stage[$key][]", $lang->testcase->stageList, !empty($case->stage) ? $case->stage : ((!empty($case->id) and isset($cases[$case->id])) ? $cases[$case->id]->stage : ''), "multiple='multiple' class='form-control chosen'")?></td>
|
||||
<td><?php echo html::textarea("precondition[$key]", isset($case->precondition) ? htmlSpecialString($case->precondition) : "", "class='form-control'")?></td>
|
||||
<td><?php echo html::input("keywords[$key]", isset($case->keywords) ? $case->keywords : '', "class='form-control'")?></td>
|
||||
<?php if(!empty($appendFields)):?>
|
||||
<?php $this->loadModel('flow');?>
|
||||
<?php foreach($appendFields as $appendField):?>
|
||||
<td><?php echo $this->flow->buildControl($appendField, zget($case, $appendField->field, ''), "{$appendField->field}[$key]");?></td>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
<?php
|
||||
if(!empty($appendFields))
|
||||
{
|
||||
$this->loadModel('flow');
|
||||
foreach($appendFields as $field)
|
||||
{
|
||||
if(!$field->show) continue;
|
||||
$value = $field->defaultValue ? $field->defaultValue : zget($case, $field->field, '');
|
||||
echo '<td>' . $this->flow->buildControl($field, $value, "$field->field[$key]", true) . '</td>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<td>
|
||||
<?php if(isset($stepData[$key]['desc'])):?>
|
||||
<table class='w-p100 bd-0'>
|
||||
|
||||
@@ -772,8 +772,10 @@ class testtaskModel extends model
|
||||
$testtask = fixer::input('post')
|
||||
->add('id', $taskID)
|
||||
->setDefault('status', 'doing')
|
||||
->stripTags($this->config->testtask->editor->start['id'], $this->config->allowedTags)
|
||||
->remove('comment')->get();
|
||||
|
||||
$testtask = $this->loadModel('file')->processImgURL($testtask, $this->config->testtask->editor->start['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TESTTASK)->data($testtask)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
@@ -838,8 +840,10 @@ class testtaskModel extends model
|
||||
$testtask = fixer::input('post')
|
||||
->add('id', $taskID)
|
||||
->setDefault('status', 'blocked')
|
||||
->stripTags($this->config->testtask->editor->block['id'], $this->config->allowedTags)
|
||||
->remove('comment')->get();
|
||||
|
||||
$testtask = $this->loadModel('file')->processImgURL($testtask, $this->config->testtask->editor->block['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TESTTASK)->data($testtask)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
@@ -861,8 +865,10 @@ class testtaskModel extends model
|
||||
$oldTesttask = $this->getById($taskID);
|
||||
$testtask = fixer::input('post')
|
||||
->setDefault('status', 'doing')
|
||||
->stripTags($this->config->testtask->editor->activate['id'], $this->config->allowedTags)
|
||||
->remove('comment')->get();
|
||||
|
||||
$testtask = $this->loadModel('file')->processImgURL($testtask, $this->config->testtask->editor->activate['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TESTTASK)->data($testtask)
|
||||
->autoCheck()
|
||||
->checkFlow()
|
||||
|
||||
@@ -229,6 +229,49 @@ class tree extends control
|
||||
$title = $this->lang->tree->manageTrainpost;
|
||||
$position[] = $this->lang->tree->manageTrainpost;
|
||||
}
|
||||
elseif(strpos($viewType, 'datasource') !== false)
|
||||
{
|
||||
$params = explode('_', $viewType);
|
||||
if(count($params) == 2)
|
||||
{
|
||||
$datasourceID = $params[1];
|
||||
$manageChild = 'manage' . ucfirst($viewType) . 'Child';
|
||||
$datasource = $this->loadModel('workflowdatasource', 'flow')->getByID($datasourceID);
|
||||
if($datasource)
|
||||
{
|
||||
$this->app->rawModule = 'workflowdatasource';
|
||||
|
||||
$title = $datasource->name;
|
||||
$position[] = $datasource->name;
|
||||
|
||||
$this->lang->tree->$manageChild = $title;
|
||||
|
||||
$root = new stdclass();
|
||||
$root->name = $title;
|
||||
$this->view->root = $root;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* viewType is workflow building category. */
|
||||
else if(strpos($viewType, '_') !== false)
|
||||
{
|
||||
$params = explode('_', $viewType);
|
||||
if(count($params) == 2)
|
||||
{
|
||||
$this->app->rawModule = $params[0];
|
||||
|
||||
$manageChild = 'manage' . ucfirst($viewType) . 'Child';
|
||||
|
||||
$title = $this->lang->tree->common;
|
||||
$position[] = $this->lang->tree->common;
|
||||
|
||||
$this->lang->tree->$manageChild = $title;
|
||||
|
||||
$root = new stdclass();
|
||||
$root->name = $title;
|
||||
$this->view->root = $root;
|
||||
}
|
||||
}
|
||||
|
||||
$parentModules = $this->tree->getParents($currentModuleID);
|
||||
$this->view->title = $title;
|
||||
|
||||
@@ -1187,19 +1187,21 @@ class user extends control
|
||||
* @param int $contactListID
|
||||
* @param string $dropdownName mailto|whitelist
|
||||
* @param string $oldUsers
|
||||
* @param string $extra
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function ajaxGetContactUsers($contactListID, $dropdownName = 'mailto', $oldUsers = '')
|
||||
public function ajaxGetContactUsers($contactListID, $dropdownName = 'mailto', $oldUsers = '', $extra = '')
|
||||
{
|
||||
$list = $contactListID ? $this->user->getContactListByID($contactListID) : '';
|
||||
|
||||
$attr = $dropdownName == 'mailto' ? "data-placeholder='{$this->lang->chooseUsersToMail}'" : '';
|
||||
|
||||
$users = $this->user->getPairs('devfirst|nodeleted|noclosed', $list ? $list->userList : '', $this->config->maxCount);
|
||||
if(!empty($extra) && $extra == 'flow') $users = array_merge(array('deptManager' => $this->lang->workflowdatasource->options['deptManager']), $users);
|
||||
if(isset($this->config->user->moreLink)) $this->config->moreLinks[$dropdownName . "[]"] = $this->config->user->moreLink;
|
||||
|
||||
$defaultUsers = empty($contactListID) ? '' : $list->userList . ',' . trim($oldUsers);
|
||||
if($extra == 'flow' && empty($defaultUsers)) $defaultUsers = trim($oldUsers);
|
||||
return print(html::select($dropdownName . "[]", $users, $defaultUsers, "class='form-control chosen' multiple $attr"));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ foreach(array('zh-cn', 'en') as $langType)
|
||||
|
||||
$command .= "sed -i 's/index.php/\/zentao\/index.php/' zentao/www/.htaccess\n";
|
||||
$command .= "cd ../../\n";
|
||||
$command .= "sudo dpkg -b buildroot/ {$packPrefix}_{$version}_php{$phpVersion}_1_all.deb\n";
|
||||
$command .= "sudo dpkg -b buildroot/ {$packPrefix}.{$version}.php{$phpVersion}.1.all.deb\n";
|
||||
$command .= "mv *.deb ../../\n";
|
||||
|
||||
$command .= "rm -rf buildroot\n";
|
||||
|
||||
+1
-3
@@ -60,9 +60,7 @@ foreach(array('zh-cn', 'en') as $langType)
|
||||
|
||||
$command .= "cd ../../\n";
|
||||
$command .= "rpmbuild --define \"_topdir \${PWD}/rpmbuild\" -ba rpmbuild/SPECS/zentaopms.spec\n";
|
||||
$command .= "cp rpmbuild/RPMS/noarch/$dirName-$version-1.noarch.rpm ./{$dirName}-{$version}-php{$phpVersion}-1.noarch.rpm\n";
|
||||
|
||||
$command .= "mv {$dirName}-{$version}-php{$phpVersion}-1.noarch.rpm ../../\n";
|
||||
$command .= "cp rpmbuild/RPMS/noarch/$dirName-$version-1.noarch.rpm ../../{$packPrefix}.{$version}.php{$phpVersion}.1.noarch.rpm\n";
|
||||
|
||||
$command .= "rm -rf rpmbuild\n";
|
||||
|
||||
|
||||
@@ -91,3 +91,4 @@ a.showMoreImage:hover {opacity: 1;}
|
||||
#headerActions .dropdown-menu:before, #headerActions .dropdown-menu:hover:before {position: absolute; top: -9px; right: 50%; width: 0; height: 0; content: ' '; border-color: transparent transparent #fff transparent; border-style: solid; border-width: 0 10px 10px 10px;}
|
||||
|
||||
.icon-size-width:before {content: "\e9c5"; transform: rotate(90deg); -ms-transform: rotate(90deg); -moz-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg);}
|
||||
.checkbox-primary > label{overflow: hidden;}
|
||||
|
||||
Reference in New Issue
Block a user