Merge branch 'master' into 'liyuchun_fixbug_22074'

# Conflicts:
#   lib/filter/filter.class.php
This commit is contained in:
孙广明
2022-04-28 10:34:02 +00:00
67 changed files with 525 additions and 294 deletions
+1
View File
@@ -129,6 +129,7 @@ zentaoxx:
sed -i 's/footer.html.php/footer.lite.html.php/g' zentaoxx/extension/xuan/common/view/footer.modal.html.php
sed -i 's/v\.//g' zentaoxx/extension/xuan/im/js/debug.js
sed -i 's/helper::jsonEncode(/json_encode(/g' zentaoxx/framework/xuanxuan.class.php
sed -i 's/moduleRoot/getExtensionRoot() . "xuan\/"/' zentaoxx/framework/xuanxuan.class.php
sed -i "s/lang->goback,/lang->goback, '',/g" zentaoxx/extension/xuan/im/view/debug.html.php
sed -i 's/v\.//g' zentaoxx/extension/xuan/client/js/checkupgrade.js
sed -i 's/commonModel::getLicensePropertyValue/extCommonModel::getLicensePropertyValue/g' zentaoxx/extension/xuan/im/control.php
+4
View File
@@ -32,8 +32,12 @@ class executionStoriesEntry extends entry
$stories = $data->data->stories;
$pager = $data->data->pager;
$result = array();
$this->loadModel('product');
foreach($stories as $story)
{
$product = $this->product->getById($story->product);
$story->productStatus = $product->status;
$result[] = $this->format($story, 'openedBy:user,openedDate:time,assignedTo:user,assignedDate:time,reviewedBy:user,reviewedDate:time,lastEditedBy:user,lastEditedDate:time,closedBy:user,closedDate:time,deleted:bool,mailto:userList');
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'stories' => $result));
+20 -52
View File
@@ -14,12 +14,13 @@ class feedbacksEntry extends entry
/**
* GET method.
*
* @param int $projectID
* @access public
* @return void
*/
public function get()
{
if(strpos(strtolower($this->param('fields')), 'moduleandproduct') !== false) return $this->getModuleAndProduct();
$control = $this->loadController('feedback', 'admin');
$control->admin($this->param('status', 'unclosed'), 0, $this->param('orderBy', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
@@ -48,80 +49,47 @@ class feedbacksEntry extends entry
/**
* POST method.
*
* @param int $projectID
* @access public
* @return void
*/
public function post($projectID = 0)
public function post()
{
$fields = 'project,code,name,begin,end,lifetime,desc,days';
$fields = 'module,product,type,title,public,desc,status,feedbackBy,notifyEmail,notify,uid';
$this->batchSetPost($fields);
$projectID = $this->param('project', $projectID);
$this->setPost('project', $projectID);
$this->setPost('acl', $this->request('acl', 'private'));
$this->setPost('PO', $this->request('PO', ''));
$this->setPost('PM', $this->request('PM', ''));
$this->setPost('QD', $this->request('QD', ''));
$this->setPost('RD', $this->request('RD', ''));
$this->setPost('whitelist', $this->request('whitelist', array()));
$this->setPost('products', $this->request('products', array()));
$this->setPost('plans', $this->request('plans', array()));
$control = $this->loadController('execution', 'create'); $this->requireFields('name,code,begin,end,days');
$control->create($projectID);
$control = $this->loadController('feedback', 'create');
$this->requireFields('title,product');
$control->create();
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
$execution = $this->loadModel('execution')->getByID($data->id);
$feedback = $this->loadModel('feedback')->getById($data->id);
$this->send(201, $this->format($execution, 'openedBy:user,openedDate:time,lastEditedBy:user,lastEditedDate:time,closedBy:user,closedDate:time,canceledBy:user,canceledDate:time,PM:user,PO:user,RD:user,QD:user,whitelist:userList,begin:date,end:date,realBegan:date,realEnd:date,deleted:bool'));
$this->send(201, $this->format($feedback, 'openedBy:user,openedDate:time,reviewedBy:user,reviewedDate:time,processedBy:user,processedDate:time,closedBy:user,closedDate:time,editedBy:user,editedDate:time,assignedTo:user,assignedDate:time,feedbackBy:user,mailto:userList,deleted:bool'));
}
/**
* Get drop menu.
* GET method.
*
* @access public
* @return void
*/
public function getDropMenu()
public function getModuleAndProduct()
{
$control = $this->loadController('execution', 'ajaxGetDropMenu');
$control->ajaxGetDropMenu($this->request('executionID', 0), $this->request('module', 'execution'), $this->request('method', 'task'), $this->request('extra', ''));
$control = $this->loadController('feedback', 'create');
$control->create();
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
$account = $this->app->user->account;
$projects = $data->data->projects;
$dropMenu = array('involved' => array(), 'other' => array(), 'closed' => array());
foreach($data->data->executions as $projectID => $projectExecutions)
{
foreach($projectExecutions as $execution)
{
if(helper::diffDate(date('Y-m-d'), $execution->end) > 0) $execution->delay = true;
$teams = $execution->teams;
$execution = $this->filterFields($execution, 'id,project,model,type,name,code,status,PM,delay');
$modules = $data->data->modules;
$products = $data->data->products;
$projectName = zget($projects, $execution->project, '');
if($projectName) $execution->name = $projectName . '/' . $execution->name;
$data = array();
$data['modules'] = $modules;
$data['products'] = $products;
if($execution->status == 'closed')
{
$dropMenu['closed'][] = $execution;
}
elseif($execution->status != 'done' and $execution->status != 'closed' and ($execution->PM == $account or isset($teams->$account)))
{
$dropMenu['involved'][] = $execution;
}
else
{
$dropMenu['other'][] = $execution;
}
}
}
$this->send(200, $dropMenu);
return $this->send(200, $data);
}
}
+4
View File
@@ -32,8 +32,12 @@ class projectStoriesEntry extends entry
$stories = $data->data->stories;
$pager = $data->data->pager;
$result = array();
$this->loadModel('product');
foreach($stories as $story)
{
$product = $this->product->getById($story->product);
$story->productStatus = $product->status;
$result[] = $this->format($story, 'openedBy:user,openedDate:time,assignedTo:user,assignedDate:time,reviewedBy:user,reviewedDate:time,lastEditedBy:user,lastEditedDate:time,closedBy:user,closedDate:time,deleted:bool,mailto:userList');
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'stories' => $result));
+14 -2
View File
@@ -24,7 +24,7 @@ class storiesEntry extends entry
if(!$productID) return $this->sendError(400, 'Need product id.');
$control = $this->loadController('product', 'browse');
$control->browse($productID, $this->param('branch', ''), $this->param('status', 'unclosed'), 0, $this->param('type', 'story'), $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$control->browse($productID, $this->param('branch', ''), $this->param('status', 'unclosed'), 0, $this->param('type', 'story'), $this->param('order', 'id_desc'), 0, $this->param('limit', 500), $this->param('page', 1));
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->sendError(400, 'error');
@@ -33,9 +33,21 @@ class storiesEntry extends entry
$stories = $data->data->stories;
$pager = $data->data->pager;
$result = array();
$this->loadModel('product');
foreach($stories as $story)
{
if(isset($story->children)) $story->children = array_values((array)$story->children);
$product = $this->product->getById($story->product);
$story->productStatus = $product->status;
if(isset($story->children))
{
$story->children = array_values((array)$story->children);
foreach($story->children as $id => $children)
{
$childrenProduct = $this->product->getById($children->product);
$story->children[$id]->productStatus = $childrenProduct->status;
}
}
$result[] = $this->format($story, 'openedBy:user,openedDate:time,assignedTo:user,assignedDate:time,reviewedBy:user,reviewedDate:time,lastEditedBy:user,lastEditedDate:time,closedBy:user,closedDate:time,deleted:bool,mailto:userList');
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'stories' => $result));
+3 -2
View File
@@ -36,8 +36,9 @@ class storyEntry extends Entry
if(isset($story->planTitle)) $story->planTitle = array_values((array)$story->planTitle);
if($story->parent > 0) $story->parentPri = $this->dao->select('pri')->from(TABLE_STORY)->where('id')->eq($story->parent)->fetch('pri');
/* Set product name */
$story->productName = $data->data->product->name;
/* Set product name and status*/
$story->productName = $data->data->product->name;
$story->productStatus = $data->data->product->status;
/* Set module title */
$moduleTitle = '';
+1 -1
View File
@@ -31,7 +31,7 @@ class taskAssignToEntry extends Entry
$control->assignTo($task->execution, $taskID);
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(!$data) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$task = $this->loadModel('task')->getByID($taskID);
-2
View File
@@ -57,8 +57,6 @@ $routes['/stories/:id/child'] = 'storyChild';
$routes['/stories/:id/recall'] = 'storyRecall';
$routes['/stories/:id/review'] = 'storyReview';
$routes['/module/:id/stories'] = 'moduleStories';
$routes['/products/:id/bugs'] = 'bugs';
$routes['/projects/:id/bugs'] = 'projectBugs';
$routes['/executions/:id/bugs'] = 'executionBugs';
@@ -2,6 +2,6 @@
<?php if(trim($config->visions, ',') == 'lite'): ?>
$('#headerActions').css("right", '110px');
<?php else: ?>
$('#headerActions').css("right", '190px');
$('#headerActions').css("right", '205px');
<?php endif; ?>
</script>
</script>
@@ -94,11 +94,23 @@
<div class="kanban-footer">
<div class='kanban-members pull-left'>
<?php $teams = $memberGroup[$kanban->id];?>
<?php $count = 0;?>
<?php foreach($teams as $member):?>
<?php if($count > 2) break;?>
<?php $count ++;?>
<div title="<?php echo zget($users, $member->account);?>">
<?php echo html::smallAvatar(array('avatar' => zget($usersAvatar, $member->account), 'account' => $member->account, 'name' => isset($member->realname) ? $member->realname : '')); ?>
</div>
<?php endforeach;?>
<?php if(count($teams) > 4):?>
<?php echo '<span>… </span>';?>
<?php endif;?>
<?php if(count($teams) > 3):?>
<?php $lastMember = end($teams);?>
<div title="<?php echo $lastMember->realname;?>">
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$lastMember->account], 'account' => $lastMember->account, 'name' => $lastMember->realname), 'avatar-circle avatar-' . key($lastMember)); ?>
</div>
<?php endif;?>
</div>
<div class='kanban-members-count pull-left'><?php echo sprintf($lang->project->teamSumCount, count($teams));?></div>
<div class='kanban-acl pull-right'>
+9 -19
View File
@@ -483,15 +483,6 @@ class baseControl
{
if(empty($cssPath)) continue;
$extModulePath = dirname(dirname($cssPath));
if(realpath($extModulePath) != $realModulePath)
{
$extMethodCssFile = $extModulePath . DS . 'css' . DS . $devicePrefix . $methodName . '.css';
if(is_file($extMethodCssFile)) $css .= file_get_contents($extMethodCssFile);
$extMethodCssLangFile = $extModulePath . DS . 'css' . DS . $devicePrefix . "{$methodName}.{$clientLang}.css";
if(is_file($extMethodCssLangFile)) $css .= file_get_contents($extMethodCssLangFile);
}
$cssMethodExt = $cssPath . $methodName . DS;
$cssCommonExt = $cssPath . 'common' . DS;
@@ -587,13 +578,6 @@ class baseControl
{
if(empty($jsPath)) continue;
$extModulePath = dirname(dirname($jsPath));
if(realpath($extModulePath) != $realModulePath)
{
$extMethodJsFile = $extModulePath . DS . 'js' . DS . $this->devicePrefix . $methodName . '.js';
if(is_file($extMethodJsFile)) $js .= file_get_contents($extMethodJsFile);
}
$jsMethodExt = $jsPath . $methodName . DS;
$jsCommonExt = $jsPath . 'common' . DS;
@@ -928,11 +912,17 @@ class baseControl
$data[$key] = str_replace('%22', '"', urlencode($value));
}
print(urldecode(json_encode($data)));
$response = helper::removeUTF8Bom(ob_get_clean());
if(defined('RUN_MODE') and RUN_MODE == 'api')
{
print(urldecode(json_encode($data)));
$response = helper::removeUTF8Bom(ob_get_clean());
return print($response);
}
if(defined('RUN_MODE') and RUN_MODE == 'api') return print($response);
$obLevel = ob_get_level();
for($i = 0; $i < $obLevel; $i++) ob_end_clean();
$response = helper::removeUTF8Bom(urldecode(json_encode($data)));
die($response);
}
+4 -1
View File
@@ -509,7 +509,10 @@ class baseHTML
setcookie('goback', json_encode($gobackList), $config->cookieLife, $config->webRoot, '', $config->cookieSecure, false);
}
return "<a href='{$gobackLink}' class='btn btn-back $class' $misc>{$label}</a>";
$dataApp = array_search($gobackLink, $gobackList) ? array_search($gobackLink, $gobackList) : '';
$dataApp = empty($dataApp) ? '' : "data-app='$dataApp'";
return "<a href='{$gobackLink}' class='btn btn-back $class' $dataApp $misc>{$label}</a>";
}
/**
+12 -6
View File
@@ -100,16 +100,22 @@ class fixer extends baseFixer
* @access public
* @return object
*/
public function filterEmoji($value){
public function filterEmoji($value)
{
if(is_object($value) or is_array($value))
{
foreach($value as $subValue) $this->filterEmoji($subValue);
foreach($value as $subValue)
{
$subValue = $this->filterEmoji($subValue);
}
}
$value = preg_replace_callback('/./u', function (array $match)
else
{
return strlen($match[0]) >= 4 ? '' : $match[0];
}, $value);
$value = preg_replace_callback('/./u', function (array $match)
{
return strlen($match[0]) >= 4 ? '' : $match[0];
}, $value);
}
return $value;
}
+8
View File
@@ -1299,6 +1299,14 @@ class actionModel extends model
$action->objectLabel = $objectLabel;
$action->product = trim($action->product, ',');
$noLinkObjects = array('program', 'project', 'product', 'execution');
if(in_array($action->objectType, $noLinkObjects))
{
$objectTable = zget($this->config->objectTables, $action->objectType);
$objectDeleted = $this->dao->select('deleted')->from($objectTable)->where('id')->eq($action->objectID)->fetch('deleted');
if($objectDeleted) return $action;
}
if($this->config->edition == 'max'
and strpos($this->config->action->assetType, $action->objectType) !== false
and empty($action->project) and empty($action->product) and empty($action->execution))
+26 -12
View File
@@ -78,7 +78,7 @@ class api extends control
$this->view->libID = $libID;
$this->view->apiID = $apiID;
$this->view->libs = $libs;
$this->view->moduleTree = $libID ? $this->doc->getApiModuleTree($libID, $apiID, 0, $moduleID) : '';
$this->view->moduleTree = $libID ? $this->doc->getApiModuleTree($libID, $apiID, $release, $moduleID) : '';
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->display();
@@ -170,6 +170,8 @@ class api extends control
/**
* Api doc global struct page.
*
* @param int $libID
* @param int $releaseID
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
@@ -177,25 +179,34 @@ class api extends control
* @access public
* @return void
*/
public function struct($libID = 0, $orderBy = 'id', $recTotal = 0, $recPerPage = 15, $pageID = 1)
public function struct($libID = 0, $releaseID = 0, $orderBy = 'id', $recTotal = 0, $recPerPage = 15, $pageID = 1)
{
$libs = $this->doc->getApiLibs();
$this->app->loadClass('pager', $static = true);
$this->lang->modulePageNav = $this->generateLibsDropMenu($libs, $libID);
$this->lang->modulePageNav = $this->generateLibsDropMenu($libs, $libID, $releaseID);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Append id for secend sort. */
$sort = common::appendOrder($orderBy);
$structs = $this->api->getStructByQuery($libID, $pager, $sort);
if($releaseID)
{
$release = $this->api->getRelease($libID, 'byId', $releaseID);
$structs = $this->api->getStructListByRelease($release, '1 = 1 ', $sort);
}
else
{
$structs = $this->api->getStructByQuery($libID, $pager, $sort);
}
common::setMenuVars('doc', $libID);
$this->view->libID = $libID;
$this->view->structs = $structs;
$this->view->orderBy = $orderBy;
$this->view->title = $this->lang->api->struct;
$this->view->pager = $pager;
$this->view->libID = $libID;
$this->view->releaseID = $releaseID;
$this->view->structs = $structs;
$this->view->orderBy = $orderBy;
$this->view->title = $this->lang->api->struct;
$this->view->pager = $pager;
$this->display();
}
@@ -641,6 +652,8 @@ class api extends control
if(empty($libs)) return '';
if(!isset($libs[$libID])) return '';
$methodName = $this->app->rawMethod;
$libName = $libs[$libID]->name;
$output = <<<EOT
<div class='btn-group angle-btn'>
@@ -659,7 +672,7 @@ EOT;
foreach($libs as $key => $lib)
{
$selected = $key == $libID ? 'selected' : '';
$output .= html::a(inlink('index', "libID=$key"), $lib->name, '', "class='$selected' data-app='{$this->app->tab}'");
$output .= html::a(inlink($methodName, "libID=$key"), $lib->name, '', "class='$selected' data-app='{$this->app->tab}'");
}
$output .= "</div></div></div></div></div>";
@@ -682,12 +695,13 @@ EOT;
<div class='table-col'>
<div class='list-group'>
EOT;
$params = $methodName == 'index' ? "libID=$libID&moduleID=0&apiID=0&version=0" : "libID=$libID";
$selected = $version > 0 ? '' : 'selected';
$output .= html::a(inlink('index', "libID=$libID&moduleID=0&apiID=0&version=0&release=0"), $this->lang->api->defaultVersion, '', "class='$selected'");
$output .= html::a(inlink($methodName, $params . "&release=0"), $this->lang->api->defaultVersion, '', "class='$selected'");
foreach($versions as $key => $item)
{
$selected = $key == $version ? 'selected' : '';
$output .= html::a(inlink('index', "libID=$libID&moduleID=0&apiID=0&version=0&release=$key"), $item->version, '', "class='$selected' data-app='{$this->app->tab}'");
$output .= html::a(inlink($methodName, $params . "&release=$key"), $item->version, '', "class='$selected' data-app='{$this->app->tab}'");
}
$output .= "</div></div></div></div></div>";
}
+6 -1
View File
@@ -426,7 +426,12 @@ try {
this.getInitField()
];
}
this.current = this.params[this.structType];
this.current.structType = this.structType;
for(let key = this.current.length - 1; key >= 0; key--)
{
this.current[key].structType = this.structType;
if(this.structType == 'formData' && this.current[key].sub != 1) this.current.splice(key, 1);
}
},
getPadding(sub) {
var padding = 0;
+50 -19
View File
@@ -28,7 +28,9 @@ class apiModel extends model
const PARAMS_TYPE_CUSTOM = 'custom';
/**
* @param object $data
* Create release.
*
* @param object $data
* @access public
* @return int
*/
@@ -339,7 +341,7 @@ class apiModel extends model
}
if($version)
{
$fields = 'spec.*,api.id,api.product,api.lib,api.version,api.paramsExample,api.responseExample,doc.name as libName,module.name as moduleName,api.editedBy,api.editedDate';
$fields = 'spec.*,api.id,api.product,api.lib,api.version,doc.name as libName,module.name as moduleName,api.editedBy,api.editedDate';
}
else
{
@@ -370,7 +372,7 @@ class apiModel extends model
* @access public
* @return array
*/
public function getApiListByRelease($release, $where = '')
public function getApiListByRelease($release, $where = '1 = 1 ')
{
$strJoin = array();
foreach($release->snap['apis'] as $api)
@@ -483,6 +485,33 @@ class apiModel extends model
->fetchAll();
}
/**
* Get struct list by release.
*
* @param object $release
* @param string $where
* @param string $orderBy
* @access public
* @return array
*/
public function getStructListByRelease($release, $where = '1 = 1 ', $orderBy = 'id')
{
$strJoin = array();
foreach($release->snap['structs'] as $struct)
{
$strJoin[] = "(object.id = {$struct['id']} and spec.version = {$struct['version']} )";
}
if($strJoin) $where .= 'and (' . implode(' or ', $strJoin) . ')';
$list = $this->dao->select('object.lib,spec.name,spec.type,spec.desc,spec.attribute,spec.version,spec.addedBy,spec.addedDate,object.id,user.realname as addedName')->from(TABLE_APISTRUCT)->alias('object')
->leftJoin(TABLE_APISTRUCT_SPEC)->alias('spec')->on('object.name = spec.name')
->leftJoin(TABLE_USER)->alias('user')->on('user.account = spec.addedBy')
->where($where)
->orderBy($orderBy)
->fetchAll();
return $list;
}
/**
* @param int $libID
* @param string $pager
@@ -677,22 +706,24 @@ class apiModel extends model
private function getApiSpecByData($data)
{
return array(
'doc' => $data->id,
'module' => $data->module,
'title' => $data->title,
'path' => $data->path,
'protocol' => $data->protocol,
'method' => $data->method,
'requestType' => $data->requestType,
'responseType' => isset($data->responseType) ? $data->responseType : '',
'status' => $data->status,
'owner' => $data->owner,
'desc' => $data->desc,
'version' => $data->version,
'params' => $data->params,
'response' => $data->response,
'addedBy' => $this->app->user->account,
'addedDate' => helper::now(),
'doc' => $data->id,
'module' => $data->module,
'title' => $data->title,
'path' => $data->path,
'protocol' => $data->protocol,
'method' => $data->method,
'requestType' => $data->requestType,
'responseType' => isset($data->responseType) ? $data->responseType : '',
'status' => $data->status,
'owner' => $data->owner,
'desc' => $data->desc,
'version' => $data->version,
'params' => $data->params,
'paramsExample' => $data->paramsExample,
'responseExample' => $data->responseExample,
'response' => $data->response,
'addedBy' => $this->app->user->account,
'addedDate' => helper::now(),
);
}
+1 -1
View File
@@ -30,7 +30,7 @@
<table class='table has-sort-head' id='userList'>
<thead>
<tr>
<?php $vars = "libID={$libID}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<?php $vars = "libID={$libID}&releaseID=$releaseID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<th class='c-id'><?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='c-type'><?php common::printOrderLink('type', $orderBy, $vars, $lang->api->structType);?></th>
<th class='c-name'><?php echo $lang->api->structName;?></th>
+15
View File
@@ -2304,6 +2304,21 @@ class bug extends control
$this->display();
}
/**
* Ajax get product members.
*
* @param int $productID
* @param string $selectedUser
* @access public
* @return string
*/
public function ajaxGetProductMembers($productID, $selectedUser = '')
{
$productMembers = $this->bug->getProductMemberPairs($productID);
return print(html::select('assignedTo', $productMembers, $selectedUser, 'class="form-control"'));
}
/**
* Ajax get project team members.
*
+89 -1
View File
@@ -52,6 +52,68 @@ function loadAll(productID)
}
}
/**
* Load all users as assignedTo list.
*
* @access public
* @return void
*/
function loadAllUsers()
{
var link = createLink('bug', 'ajaxLoadAllUsers', 'selectedUser=' + $('#assignedTo').val());
$.get(link, function(data)
{
if(data)
{
var moduleID = $('#module').val();
var productID = $('#product').val();
setAssignedTo(moduleID, productID);
$('#assignedTo').replaceWith(data);
$('#assignedTo_chosen').remove();
$('#assignedTo').chosen();
}
});
}
/**
* Set the assignedTo field.
*
* @param int $moduleID
* @param int $productID
* @access public
* @return void
*/
function setAssignedTo(moduleID, productID)
{
if(typeof(productID) == 'undefined') productID = $('#product').val();
if(typeof(moduleID) == 'undefined') moduleID = $('#module').val();
var link = createLink('bug', 'ajaxGetModuleOwner', 'moduleID=' + moduleID + '&productID=' + productID);
$.get(link, function(owner)
{
owner = JSON.parse(owner);
var account = owner[0];
var realName = owner[1];
var isExist = false;
var count = $('#assignedTo').find('option').length;
for(var i=0; i < count; i++)
{
if($('#assignedTo').get(0).options[i].value == account)
{
isExist = true;
break;
}
}
if(!isExist && account)
{
option = "<option title='" + realName + "' value='" + account + "'>" + realName + "</option>";
$("#assignedTo").append(option);
}
$('#assignedTo').val(account);
$("#assignedTo").trigger("chosen:updated");
});
}
/**
* Load by branch.
*
@@ -352,7 +414,14 @@ function loadExecutionRelated(executionID)
$('#taskIdBox').innerHTML = '<select id="task"></select>'; // Reset the task.
loadProductStories(currentProductID);
loadTestTasks(currentProductID);
loadProjectTeamMembers(currentProjectID);
if(typeof(currentProjectID) == 'undefined')
{
loadProductMembers(currentProductID);
}
else
{
loadProjectTeamMembers(currentProjectID);
}
currentProjectID != 0 ? loadProjectBuilds(currentProjectID) : loadProductBuilds(currentProductID);
}
@@ -482,6 +551,25 @@ function loadExecutionBuilds(executionID, num)
}
}
/**
* Load product members.
*
* @param productID
* @access public
* @return void
*/
function loadProductMembers(productID)
{
link = createLink('bug', 'ajaxGetProductMembers', 'productID=' + productID + '&selectedUser=' + $('#assignedTo').val());
$.get(link, function(data)
{
if(!data) data = '<select id="assignedTo" name="assignedTo" class="form-control"></select>';
$('#assignedTo').replaceWith(data);
$('#assignedTo_chosen').remove();
$("#assignedTo").chosen();
});
}
/**
* Load project members.
*
-61
View File
@@ -1,26 +1,3 @@
/**
* Load all users as assignedTo list.
*
* @access public
* @return void
*/
function loadAllUsers()
{
var link = createLink('bug', 'ajaxLoadAllUsers', 'selectedUser=' + $('#assignedTo').val());
$.get(link, function(data)
{
if(data)
{
var moduleID = $('#module').val();
var productID = $('#product').val();
setAssignedTo(moduleID, productID);
$('#assignedTo').replaceWith(data);
$('#assignedTo_chosen').remove();
$('#assignedTo').chosen();
}
});
}
/**
* Load team members of the latest execution of a product as assignedTo list.
*
@@ -77,44 +54,6 @@ function setLane(regionID)
});
}
/**
* Set the assignedTo field.
*
* @param int $moduleID
* @param int $productID
* @access public
* @return void
*/
function setAssignedTo(moduleID, productID)
{
if(typeof(productID) == 'undefined') productID = $('#product').val();
if(typeof(moduleID) == 'undefined') moduleID = $('#module').val();
var link = createLink('bug', 'ajaxGetModuleOwner', 'moduleID=' + moduleID + '&productID=' + productID);
$.get(link, function(owner)
{
owner = JSON.parse(owner);
var account = owner[0];
var realName = owner[1];
var isExist = false;
var count = $('#assignedTo').find('option').length;
for(var i=0; i < count; i++)
{
if($('#assignedTo').get(0).options[i].value == account)
{
isExist = true;
break;
}
}
if(!isExist && account)
{
option = "<option title='" + realName + "' value='" + account + "'>" + realName + "</option>";
$("#assignedTo").append(option);
}
$('#assignedTo').val(account);
$("#assignedTo").trigger("chosen:updated");
});
}
$(function()
{
var productID = $('#product').val();
+9 -1
View File
@@ -1837,6 +1837,13 @@ class bugModel extends model
return $bugs;
}
/**
* get Product member pairs.
*
* @param int $productID
* @access public
* @return void
*/
public function getProductMemberPairs($productID)
{
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getTeamMembersPairs();
@@ -1846,7 +1853,8 @@ class bugModel extends model
$users = $this->dao->select("t2.id, t2.account, t2.realname")->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account = t2.account')
->where('t1.root')->in(array_keys($projects))
->andWhere('t1.type')->eq('project')
->beginIF($this->config->systemMode == 'new')->andWhere('t1.type')->eq('project')->fi()
->beginIF($this->config->systemMode == 'classic')->andWhere('t1.type')->eq('execution')->fi()
->andWhere('t2.deleted')->eq(0)
->fi()
->fetchAll('account');
+37
View File
@@ -2532,6 +2532,17 @@ EOD;
/* The ip is same as ip in white list. */
if($ip == $ipWhiteList) return true;
/* If the ip in white list is like 192.168.1.1,192.168.1.10. */
if(strpos($ipWhiteList, ',') !== false)
{
$ipArr = explode(',', $ipWhiteList);
foreach($ipArr as $ipRule)
{
if($this->checkIP($ipRule)) return true;
}
return false;
}
/* If the ip in white list is like 192.168.1.1-192.168.1.10. */
if(strpos($ipWhiteList, '-') !== false)
{
@@ -2543,6 +2554,32 @@ EOD;
return $ip >= $min and $ip <= $max;
}
/* If the ip in white list is like 192.168.1.*. */
if(strpos($ipWhiteList, '*') !== false)
{
$regCount = substr_count($ipWhiteList, '.');
if($regCount == 3)
{
$min = str_replace('*', '0', $ipWhiteList);
$max = str_replace('*', '255', $ipWhiteList);
}
elseif($regCount == 2)
{
$min = str_replace('*', '0.0', $ipWhiteList);
$max = str_replace('*', '255.255', $ipWhiteList);
}
elseif($regCount == 1)
{
$min = str_replace('*', '0.0.0', $ipWhiteList);
$max = str_replace('*', '255.255.255', $ipWhiteList);
}
$min = ip2long(trim($min));
$max = ip2long(trim($max));
$ip = ip2long(trim($ip));
return ($ip >= $min and $ip <= $max);
}
/* If the ip in white list is in IP/CIDR format eg 127.0.0.1/24. Thanks to zcat. */
if(strpos($ipWhiteList, '/') == false) $ipWhiteList .= '/32';
list($ipWhiteList, $netmask) = explode('/', $ipWhiteList, 2);
+1 -1
View File
@@ -17,7 +17,7 @@
#formSettingForm .checkbox-primary {width: 50%; float: left; margin: 3px 0;}
#formSetting .btn {margin-right: 8px;}
</style>
<button type="button" title="<?php echo $lang->customField;?>" class="btn btn-link" data-toggle="dropdown"><i class="icon icon-cog"></i></button>
<button type="button" title="<?php echo $lang->customField;?>" class="btn btn-link" id="customField" data-toggle="dropdown"><i class="icon icon-cog"></i></button>
<div class="dropdown-menu pull-right" id="formSetting">
<form class='with-padding load-indicator' id='formSettingForm' method='post' target='hiddenwin' action='<?php echo $customLink?>'>
<div><?php echo $lang->customField;?></div>
+1 -1
View File
@@ -95,7 +95,7 @@ $(function()
<h4 class="modal-title"><i class="icon-cog-outline"></i> <?php echo $lang->datatable->displaySetting;?></h4>
</div>
<div class="modal-body">
<form class='form-condensed' method='post' target='hiddenwin' action='<?php echo $this->createLink('datatable', 'ajaxSave')?>'>
<form class="form-condensed not-watch" method='post' target='hiddenwin' action='<?php echo $this->createLink('datatable', 'ajaxSave')?>'>
<table class='table table-form'>
<tr>
<td class='w-160px'><?php echo $lang->datatable->showModule;?></td>
+2 -2
View File
@@ -46,7 +46,7 @@ $lang->custom->SRConcept = "SR Concept";
$lang->custom->reviewRule = 'Review Rules';
$lang->custom->switch = "Switch";
$lang->custom->oneUnit = "One {$lang->hourCommon}";
$lang->custom->convertRelationTitle = "Please set the conversion factor of {$lang->hourCommon} to %s first";
$lang->custom->convertRelationTitle = "Please firstly set the conversion factor from {$lang->hourCommon} to %s";
if($config->systemMode == 'new') $lang->custom->execution = 'Execution';
if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = $lang->executionCommon;
@@ -71,7 +71,7 @@ $lang->custom->regionMustNumber = 'The interval must be a number!';
$lang->custom->tipNotEmpty = 'The prompt can not be empty!';
$lang->custom->currencyNotEmpty = 'You have to select one currency at least.';
$lang->custom->defaultNotEmpty = 'The default currency can not be empty';
$lang->custom->convertRelationTips = "After {$lang->hourCommon} is converted to %s, historical data will be uniformly converted to %s";
$lang->custom->convertRelationTips = "After converting {$lang->hourCommon} to %s, the historical data will be converted uniformly to %s.";
$lang->custom->saveTips = 'After clicking save, the current %s will be used as the default estimation unit';
$lang->custom->numberError = 'The interval must be greater than zero!';
+2 -2
View File
@@ -47,7 +47,7 @@ $lang->custom->SRConcept = "SR Concept";
$lang->custom->reviewRule = 'Review Rules';
$lang->custom->switch = "Switch";
$lang->custom->oneUnit = "One {$lang->hourCommon}";
$lang->custom->convertRelationTitle = "Please set the conversion factor of {$lang->hourCommon} to %s first";
$lang->custom->convertRelationTitle = "Please firstly set the conversion factor from {$lang->hourCommon} to %s";
$lang->custom->superReviewers = "Super Reviewer";
if($config->systemMode == 'new') $lang->custom->execution = 'Execution';
@@ -73,7 +73,7 @@ $lang->custom->regionMustNumber = 'The interval must be a number!';
$lang->custom->tipNotEmpty = 'The prompt can not be empty!';
$lang->custom->currencyNotEmpty = 'You have to select one currency at least.';
$lang->custom->defaultNotEmpty = 'The default currency can not be empty';
$lang->custom->convertRelationTips = "After {$lang->hourCommon} is converted to %s, historical data will be uniformly converted to %s";
$lang->custom->convertRelationTips = "After converting {$lang->hourCommon} to %s, the historical data will be converted uniformly to %s.";
$lang->custom->saveTips = 'After clicking save, the current %s will be used as the default estimation unit';
$lang->custom->numberError = 'The interval must be greater than zero!';
+2 -2
View File
@@ -46,7 +46,7 @@ $lang->custom->SRConcept = "SR Concept";
$lang->custom->reviewRule = 'Review Rules';
$lang->custom->switch = "Switch";
$lang->custom->oneUnit = "One {$lang->hourCommon}";
$lang->custom->convertRelationTitle = "Please set the conversion factor of {$lang->hourCommon} to %s first";
$lang->custom->convertRelationTitle = "Please firstly set the conversion factor from {$lang->hourCommon} to %s";
if($config->systemMode == 'new') $lang->custom->execution = 'Execution';
if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = $lang->executionCommon;
@@ -71,7 +71,7 @@ $lang->custom->regionMustNumber = 'The interval must be a number!';
$lang->custom->tipNotEmpty = 'The prompt can not be empty!';
$lang->custom->currencyNotEmpty = 'You have to select one currency at least.';
$lang->custom->defaultNotEmpty = 'The default currency can not be empty';
$lang->custom->convertRelationTips = "After {$lang->hourCommon} is converted to %s, historical data will be uniformly converted to %s";
$lang->custom->convertRelationTips = "After converting {$lang->hourCommon} to %s, the historical data will be converted uniformly to %s.";
$lang->custom->saveTips = 'After clicking save, the current %s will be used as the default estimation unit';
$lang->custom->numberError = 'The interval must be greater than zero!';
+2 -2
View File
@@ -46,7 +46,7 @@ $lang->custom->SRConcept = "SR Concept";
$lang->custom->reviewRule = 'Review Rules';
$lang->custom->switch = "Switch";
$lang->custom->oneUnit = "One {$lang->hourCommon}";
$lang->custom->convertRelationTitle = "Please set the conversion factor of {$lang->hourCommon} to %s first";
$lang->custom->convertRelationTitle = "Please firstly set the conversion factor from {$lang->hourCommon} to %s";
if($config->systemMode == 'new') $lang->custom->execution = 'Execution';
if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = $lang->executionCommon;
@@ -71,7 +71,7 @@ $lang->custom->regionMustNumber = 'The interval must be a number!';
$lang->custom->tipNotEmpty = 'The prompt can not be empty!';
$lang->custom->currencyNotEmpty = 'You have to select one currency at least.';
$lang->custom->defaultNotEmpty = 'The default currency can not bu empty';
$lang->custom->convertRelationTips = "After {$lang->hourCommon} is converted to %s, historical data will be uniformly converted to %s";
$lang->custom->convertRelationTips = "After converting {$lang->hourCommon} to %s, the historical data will be converted uniformly to %s.";
$lang->custom->saveTips = 'After clicking save, the current %s will be used as the default estimation unit';
$lang->custom->numberError = 'The interval must be greater than zero!';
+20 -4
View File
@@ -89,6 +89,18 @@ class docModel extends model
$products = $this->loadModel('product')->getPairs();
$projects = $this->loadModel('project')->getPairsByProgram();
$executions = $this->loadModel('execution')->getPairs();
$waterfalls = array();
if(empty($objectID) and ($type == 'all' or $type == 'execution'))
{
$waterfalls = $this->dao->select('t1.id,t2.name')->from(TABLE_EXECUTION)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')
->where('t1.type')->eq('stage')
->andWhere('t2.type')->eq('project')
->andWhere('t2.model')->eq('waterfall')
->andWhere('t1.deleted')->eq('0')
->andWhere('t2.deleted')->eq('0')
->fetchPairs('id', 'name');
}
$libPairs = array();
while($lib = $stmt->fetch())
@@ -102,8 +114,12 @@ class docModel extends model
if(strpos($extra, 'withObject') !== false)
{
if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name;
if($lib->execution != 0) $lib->name = zget($executions, $lib->execution, '') . ' / ' . $lib->name;
if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name;
if($lib->execution != 0)
{
$lib->name = zget($executions, $lib->execution, '') . ' / ' . $lib->name;
if(!empty($waterfalls[$lib->execution])) $lib->name = $waterfalls[$lib->execution] . ' / ' . $lib->name;
}
}
$libPairs[$lib->id] = $lib->name;
@@ -2267,7 +2283,7 @@ EOT;
if($release)
{
$rel = $this->api->getReleaseById($release);
$rel = $this->api->getRelease($rootID, 'byId', $release);
$docs = $this->api->getApiListByRelease($rel);
}
else
@@ -2288,7 +2304,7 @@ EOT;
$treeMenu = array();
if($release)
{
foreach($release->snap['modules'] as $module)
foreach($rel->snap['modules'] as $module)
{
$this->buildTree($treeMenu, 'api', 0, $rootID, $module, $moduleDocs, $docID, $moduleID);
}
@@ -2650,7 +2666,7 @@ EOT;
if(empty($object))
{
$param = ($type == 'project' and $this->config->vision == 'lite') ? 'model=kanban' : '';
$methodName = $type == 'project' ? 'createGuide' : 'create';
$methodName = ($type == 'project' and $this->config->vision != 'lite') ? 'createGuide' : 'create';
return print(js::locate(helper::createLink($type, $methodName, $param)));
}
}
-1
View File
@@ -1275,7 +1275,6 @@ class executionModel extends model
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->beginIF($status == 'undone')->andWhere('status')->notIN('done,closed')->fi()
->beginIF($status != 'all' and $status != 'undone')->andWhere('status')->in($status)->fi()
->beginIF($status == 'noclosed')->andWhere('status')->notIN('closed')->fi()
->beginIF($devel === true)->andWhere('attribute')->in('dev,qa,release')->fi()
->orderBy($orderBy)
->beginIF($limit)->limit($limit)->fi()
+2
View File
@@ -1,3 +1,5 @@
.pager {margin-top: 0;}
.tree li>a:hover {color: #fff; background-color: #0c64eb;}
.tree li>a.active {color: #fff; background-color: #0c64eb;}
.side-col {width: 210px;}
#sidebar .cell {width: 190px;}
+1
View File
@@ -4,6 +4,7 @@ $config->group->create = new stdclass();
$config->group->edit = new stdclass();
$config->group->create->requiredFields = 'name';
$config->group->edit->requiredFields = 'name';
$config->group->maxToolBarCount = 13;
$config->group->acl = new stdclass();
$config->group->acl->objectTypes['programs'] = 'program';
+1
View File
@@ -38,6 +38,7 @@ $lang->group->noneProduct = "No {$lang->productCommon}";
$lang->group->noneExecution = "No {$lang->execution->common}";
$lang->group->project = 'Project';
$lang->group->group = 'Group';
$lang->group->more = 'More';
global $config;
if($config->systemMode == 'new') $lang->group->noneProject = 'No Project';
+1
View File
@@ -38,6 +38,7 @@ $lang->group->noneProduct = "暂时没有{$lang->productCommon}";
$lang->group->noneExecution = "暂时没有{$lang->execution->common}";
$lang->group->project = '项目';
$lang->group->group = '分组';
$lang->group->more = '更多';
global $config;
if($config->systemMode == 'new') $lang->group->noneProject = '暂时没有项目';
+14 -5
View File
@@ -53,11 +53,20 @@
<?php $active = empty($menu) ? 'btn-active-text' : '';?>
<?php echo html::a(inlink('managePriv', sprintf($params, '')), "<span class='text'>{$lang->group->all}</span>", '', "class='btn btn-link $active'")?>
<?php foreach($lang->mainNav as $module => $title):?>
<?php if(!is_string($title)) continue;?>
<?php $active = $menu == $module ? 'btn-active-text' : '';?>
<?php echo html::a(inlink('managePriv', sprintf($params, $module)), "<span class='text'>" . strip_tags(substr($title, 0, strpos($title, '|'))) . '</span>', '', "class='btn btn-link $active'")?>
<?php endforeach;?>
<?php
$i = 0;
foreach($lang->mainNav as $module => $title)
{
if(!is_string($title)) continue;
$i++;
if($i == $config->group->maxToolBarCount) echo '<div class="btn-group"><a href="javascript:;" data-toggle="dropdown" class="btn btn-link">' . $lang->group->more . '<span class="caret"></span></a><ul class="dropdown-menu">';
$active = $menu == $module ? 'btn-active-text' : '';
if($i >= $config->group->maxToolBarCount) echo '<li>';
echo html::a(inlink('managePriv', sprintf($params, $module)), "<span class='text'>" . strip_tags(substr($title, 0, strpos($title, '|'))) . '</span>', '', "class='btn btn-link $active'");
if($i >= $config->group->maxToolBarCount) echo '</li>';
if($i == count($lang->mainNav->menuOrder) and $i >= $config->group->maxToolBarCount) echo '</ul></div>';
}
?>
<?php $active = $menu == 'other' ? 'btn-active-text' : '';?>
<?php echo html::a(inlink('managePriv', sprintf($params, 'other')), "<span class='text'>{$lang->group->other}</span>", '', "class='btn btn-link $active'");?>
+1 -1
View File
@@ -14,7 +14,7 @@
<div id='mainMenu' class='clearfix'>
<div class='pull-left btn-toolbar'>
<?php
echo html::a($this->createLink('holiday', 'browse'), '<span class="text">' . $lang->holiday->all . '</span>', '', "class='btn btn-link btn-active-text'");
echo html::a($this->createLink('holiday', 'browse'), '<span class="text">' . $lang->holiday->all . '</span>', '', "class='btn btn-link btn-active-text' data-app='oa'");
?>
</div>
<div class='pull-right'>
+3 -3
View File
@@ -218,13 +218,13 @@ class install extends control
if(!empty($_POST))
{
$this->install->grantPriv();
if(dao::isError()) return print(js::error(dao::getError()));
if(dao::isError()) return print(js::error(dao::getError()) . js::locate('back'));
$this->install->updateLang();
if(dao::isError()) return print(js::error(dao::getError()));
if(dao::isError()) return print(js::error(dao::getError()) . js::locate('back'));
if($this->post->importDemoData) $this->install->importDemoData();
if(dao::isError()) echo js::alert($this->lang->install->errorImportDemoData);
if(dao::isError()) return print(js::alert($this->lang->install->errorImportDemoData) . js::locate('back'));
$this->loadModel('setting');
$this->setting->updateVersion($this->config->version);
+21
View File
@@ -0,0 +1,21 @@
$(function()
{
$('#submit').click(function()
{
if($('#company').val().length == 0)
{
alert(errorEmpty.company);
return false;
}
else if($('#account').val().length == 0)
{
alert(errorEmpty.account);
return false;
}
else if($('#password').val().length == 0)
{
alert(errorEmpty.password);
return false;
}
})
})
+2 -1
View File
@@ -10,6 +10,7 @@
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php js::set('errorEmpty', $lang->install->errorEmpty);?>
<style>.modal-body table tr th{text-align: right}</style>
<div class='container'>
<div class='modal-dialog'>
@@ -44,7 +45,7 @@
<strong><?php echo $lang->install->getPriv;?></strong>
</div>
<div class='modal-body'>
<form method='post' target='hiddenwin'>
<form method='post'>
<table class='table table-form mw-400px' style='margin: 0 auto'>
<tr>
<th class='c-company'><?php echo $lang->install->company;?></th>
+2 -2
View File
@@ -1170,8 +1170,8 @@ function createColumnCreateMenu(options)
if(privs.includes('createCard')) items.push({label: kanbanLang.createCard, url: $.createLink('kanban', 'createCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID, '', true), className: 'iframe', attrs: {'data-toggle': 'modal'}});
if(privs.includes('batchCreateCard')) items.push({label: kanbanLang.batchCreateCard, url: $.createLink('kanban', 'batchCreateCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&laneID=' + laneID + '&columnID=' + columnID), attrs: {'data-width': '80%'}});
if(privs.includes('import') && kanban.object.indexOf('cards') != -1) items.push({label: kanbanLang.importCard, url: $.createLink('kanban', 'importCard', 'kanbanID=' + kanbanID + '&regionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID), className: 'iframe', attrs: {'data-toggle': 'modal'}});
if(privs.includes('import') && kanban.object && kanban.object != 'cards') items.push({className: 'parentDivider'});
if(privs.includes('import') && kanban.object && kanban.object != 'cards') items.push({label: kanbanLang.importAB, className: 'import'});
if(privs.includes('import') && kanban.object && kanban.object != 'cards' && vision != 'lite') items.push({className: 'parentDivider'});
if(privs.includes('import') && kanban.object && kanban.object != 'cards' && vision != 'lite') items.push({label: kanbanLang.importAB, className: 'import'});
return items;
}
+1
View File
@@ -20,6 +20,7 @@ $app->loadLang('productplan');
$laneCount = 0;
foreach($regions as $region) $laneCount += $region->laneCount;
js::set('vision', $this->config->vision);
js::set('regions', $regions);
js::set('kanban', $kanban);
js::set('kanbanLang', $lang->kanban);
+5 -1
View File
@@ -627,7 +627,11 @@ class mrModel extends model
public function apiGetMRList($gitlabID, $projectID)
{
$url = sprintf($this->gitlab->getApiRoot($gitlabID), "/projects/$projectID/merge_requests");
return json_decode(commonModel::http($url));
$response = json_decode(commonModel::http($url));
if(empty($response)) $response = array();
return $response;
}
/**
+9 -9
View File
@@ -51,16 +51,16 @@
<form class='main-table' id='ajaxForm' method='post'>
<table id='gitlabProjectList' class='table has-sort-head table-fixed'>
<thead>
<tr>
<tr class='text-left'>
<?php $vars = "mode=$mode&param=$param&objectID=$objectID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<th class='w-60px text-left'><?php common::printOrderLink('id', $orderBy, $vars, $lang->mr->id);?></th>
<th class='w-200px text-left'><?php common::printOrderLink('title', $orderBy, $vars, $lang->mr->title);?></th>
<th class='w-200px text-left'><?php common::printOrderLink('sourceBranch', $orderBy, $vars, $lang->mr->sourceBranch);?></th>
<th class='w-200px text-left'><?php common::printOrderLink('targetBranch', $orderBy, $vars, $lang->mr->targetBranch);?></th>
<th class='w-120px text-left'><?php common::printOrderLink('mergeStatus', $orderBy, $vars, $lang->mr->mergeStatus);?></th>
<th class='w-120px text-left'><?php common::printOrderLink('approvalStatus', $orderBy, $vars, $lang->mr->approvalStatus);?></th>
<th class='w-120px text-left'><?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->mr->author);?></th>
<th class='w-120px c-actions-3'><?php echo $lang->actions;?></th>
<th class='w-60px'><?php common::printOrderLink('id', $orderBy, $vars, $lang->mr->id);?></th>
<th class='c-name'><?php common::printOrderLink('title', $orderBy, $vars, $lang->mr->title);?></th>
<th class='w-200px'><?php common::printOrderLink('sourceBranch', $orderBy, $vars, $lang->mr->sourceBranch);?></th>
<th class='w-200px'><?php common::printOrderLink('targetBranch', $orderBy, $vars, $lang->mr->targetBranch);?></th>
<th class='w-120px'><?php common::printOrderLink('mergeStatus', $orderBy, $vars, $lang->mr->mergeStatus);?></th>
<th class='w-120px'><?php common::printOrderLink('approvalStatus', $orderBy, $vars, $lang->mr->approvalStatus);?></th>
<th class='w-120px'><?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->mr->author);?></th>
<th class='c-actions-5'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
+1 -1
View File
@@ -174,7 +174,7 @@ class my extends control
$reviewCount = $pager->recTotal;
/* Get the number of nc assigned to me. */
$ncList = $this->my->getNcList('assignedToMe', 'id_desc', $pager);
$ncList = $this->my->getNcList('assignedToMe', 'id_desc', $pager, 'active');
$ncCount = $pager->recTotal;
/* Get the number of meetings assigned to me. */
+5 -3
View File
@@ -1058,8 +1058,10 @@ class productModel extends model
$projects = $this->dao->select('t2.id,t2.name')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t1.product')->eq($productID)
->andWhere('t2.type')->eq('project')
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->projects)->fi()
->beginIF($this->config->systemMode == 'new')->andWhere('t2.type')->eq('project')->fi()
->beginIF($this->config->systemMode == 'classic')->andWhere('t2.type')->eq('sprint')->fi()
->beginIF(!$this->app->user->admin and $this->config->systemMode == 'new')->andWhere('t2.id')->in($this->app->user->view->projects)->fi()
->beginIF(!$this->app->user->admin and $this->config->systemMode == 'classic')->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
->beginIF($product->type != 'normal' and $branch !== '')->andWhere('t1.branch')->in($branch)->fi()
->andWhere('t2.deleted')->eq('0')
->orderBy('order_asc')
@@ -1089,7 +1091,7 @@ class productModel extends model
->beginIF($this->config->systemMode == 'classic')->andWhere('t2.type')->eq('sprint')->fi()
->beginIF($browseType != 'all')->andWhere('t2.status')->eq($browseType)->fi()
->beginIF(!$this->app->user->admin and $this->config->systemMode == 'new')->andWhere('t2.id')->in($this->app->user->view->projects)->fi()
->beginIF(!$this->app->user->admin and $this->config->systemMode != 'new')->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
->beginIF(!$this->app->user->admin and $this->config->systemMode == 'classic')->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
->beginIF($this->cookie->involved or $involved)
->andWhere('t2.openedBy', true)->eq($this->app->user->account)
->orWhere('t2.PM')->eq($this->app->user->account)
-1
View File
@@ -1,4 +1,3 @@
.project-type-label.label-outline {width: 50px; min-width: 50px;}
.project-type-label.label {overflow: unset !important; text-overflow: unset !important; white-space: unset !important;}
[lang^='en'] .project-name > .label-warning {width: 55px !important;}
#projectTableList > tr > td.c-name.text-left > div > a {color: #0c60e1;}
+1 -1
View File
@@ -126,7 +126,7 @@
<div class='btn-group'>
<button type='button' class='btn dropdown-toggle' data-toggle='dropdown' title="<?php echo $this->lang->more;?>"><i class='icon-more-alt'></i></button>
<ul class='dropdown-menu pull-right text-center' role='menu'>
<?php common::printIcon('project', 'manageProducts', "projectID=$program->id&from=browse", $program, 'list', 'link', '', "$class", '', "data-app='project'");?>
<?php common::printIcon('project', 'manageProducts', "projectID=$program->id&from=browse", $program, 'list', 'link', '', "$class", '', "data-app={$this->app->tab}");?>
<?php common::printIcon('project', 'whitelist', "projectID=$program->id&module=project&from=browse", $program, 'list', 'shield-check', '', "$class", '', "data-app='project'");?>
<?php if(common::hasPriv('project','delete')) echo html::a($this->createLink("project", "delete", "projectID=$program->id"), "<i class='icon-trash'></i>", 'hiddenwin', "class='btn' title='{$this->lang->delete}' data-group='program'");?>
</ul>
Regular → Executable
+2 -2
View File
@@ -216,7 +216,7 @@ class programplanModel extends model
if(empty($selectCustom)) $selectCustom = $this->loadModel('setting')->getItem("owner={$owner}&module={$module}&section={$section}&key={$object}");
$tasks = array();
if(strpos($selectCustom, 'task') !== false) $tasks = $this->dao->select('*')->from(TABLE_TASK)->where('deleted')->eq(0)->andWhere('execution')->in($planIdList)->fetchAll('id');
$tasks = $this->dao->select('*')->from(TABLE_TASK)->where('deleted')->eq(0)->andWhere('execution')->in($planIdList)->fetchAll('id');
if($baselineID)
{
@@ -265,7 +265,7 @@ class programplanModel extends model
if($data->start_date) $data->start_date = date('d-m-Y', strtotime($data->start_date));
if($data->start_date == '' or $data->endDate == '') $data->duration = 0;
$datas['data'][] = $data;
if(strpos($selectCustom, 'task') !== false) $datas['data'][] = $data;
foreach($stageIndex as $index => $stage)
{
if($stage['planID'] == $task->execution)
+1
View File
@@ -14,6 +14,7 @@
<?php include '../../common/view/gantt.html.php';?>
<style>
#ganttView {height: 600px;}
#ganttView .gantt_layout_cell {min-width: 560px!important;}
#mainContent:before {background: #fff;}
.gantt-fullscreen #header,
.gantt-fullscreen #mainMenu,
+3 -3
View File
@@ -415,7 +415,7 @@ class projectModel extends model
$workhour = new stdclass();
$workhour->totalHours = $this->dao->select('sum(t1.days * t1.hours) AS totalHours')->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.root=t2.id')
->where('t2.project')->in($projectID)
->where('t2.id')->in($projectID)
->andWhere('t2.deleted')->eq(0)
->andWhere('t1.type')->eq('project')
->fetch('totalHours');
@@ -1708,7 +1708,7 @@ class projectModel extends model
if(isset($project->delay)) $suffix = "<span class='label label-danger label-badge'>{$this->lang->project->statusList['delay']}</span>";
if(!empty($suffix) || !empty($prefix)) echo '<div class="project-name' . (empty($prefix) ? '' : ' has-prefix') . (empty($suffix) ? '' : ' has-suffix') . '">';
if(!empty($prefix)) echo $prefix;
echo html::a($projectLink, $project->name, '', "class='text-ellipsis'");
echo html::a($projectLink, $project->name, '', "class='text-ellipsis text-primary'");
if(!empty($suffix)) echo $suffix;
if(!empty($suffix) || !empty($prefix)) echo '</div>';
break;
@@ -1785,7 +1785,7 @@ class projectModel extends model
echo "<div class='btn-group'>";
echo "<button type='button' class='btn dropdown-toggle' data-toggle='context-dropdown' title='{$this->lang->more}'><i class='icon-more-alt'></i></button>";
echo "<ul class='dropdown-menu pull-right text-center' role='menu'>";
common::printIcon($moduleName, 'manageProducts', "projectID=$project->id", $project, 'list', 'link', '', 'btn-action', '', $dataApp . $attr, $this->lang->project->manageProducts);
common::printIcon($moduleName, 'manageProducts', "projectID=$project->id", $project, 'list', 'link', '', 'btn-action', '', $attr, $this->lang->project->manageProducts);
if($this->config->systemMode == 'new') common::printIcon('project', 'whitelist', "projectID=$project->id&module=project&from=$from", $project, 'list', 'shield-check', '', 'btn-action', '', $dataApp . $attr);
if(common::hasPriv($moduleName, 'delete')) echo html::a(helper::createLink($moduleName, "delete", "projectID=$project->id"), "<i class='icon-trash'></i>", 'hiddenwin', "class='btn btn-action' title='{$this->lang->project->delete}'");
echo "</ul>";
+1 -1
View File
@@ -57,7 +57,7 @@ class repoModel extends model
}
common::setMenuVars('devops', $repoID);
if(!session_id()) session_start();
session_start();
$this->session->set('repoID', $repoID);
session_write_close();
}
+23 -1
View File
@@ -15,7 +15,7 @@ $pathInfo = '&root=' . $this->repo->encodePath(empty($path) ? '/' : $path);
if(isset($entry)) $pathInfo .= '&type=file';
?>
<?php js::set('paramsBase', "repoID=$repoID&path=" . $this->repo->encodePath($path) . "&objectID=$objectID&type=$logType");?>
<form id='logForm' class='main-table' data-ride='table' method='post'>
<form id='logForm' class='main-table' data-ride='table' method='post' onsubmit='logsubmit()'>
<table class='table table-fixed'>
<thead>
<tr>
@@ -69,6 +69,11 @@ if(isset($entry)) $pathInfo .= '&type=file';
</div>
</form>
<script>
if($.cookie('sideRepoSelected'))
{
var sideRepoSelectedAry = $.cookie('sideRepoSelected').split(',');
for(i in sideRepoSelectedAry) $("input:checkbox[value='" + sideRepoSelectedAry[i] + "']").attr('checked', 'checked');
}
if($("input:checkbox[name='revision[]']:checked").length < 2)
{
$("input:checkbox[name='revision[]']:lt(2)").attr('checked', 'checked');
@@ -87,6 +92,23 @@ $("input:checkbox[name='revision[]']").click(function(){
}
});
/**
* Method before submit
*
* @access public
* @return void
*/
function logsubmit()
{
$("input:checkbox[name='revision[]']:checked").each(function()
{
var sideRepoSelected = $.cookie('sideRepoSelected') ? $.cookie('sideRepoSelected').split(',') : [];
sideRepoSelected.unshift($(this).val());
sideRepoSelected = sideRepoSelected.slice(0, 2);
$.cookie('sideRepoSelected', sideRepoSelected.join(','), {expires:config.cookieLife, path:config.webRoot});
});
}
$(function()
{
var myPager = $('#repoPageSize').data('zui.pager');
+3 -3
View File
@@ -114,7 +114,7 @@ class report extends control
$this->view->begin = $begin;
$this->view->end = $end;
$this->view->bugs = $this->report->getBugs($begin, $end, $product, $execution);
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed|nodeleted');
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->executions = array('' => '') + $this->report->getProjectExecutions();
$this->view->products = array('' => '') + $this->loadModel('product')->getPairs();
$this->view->execution = $execution;
@@ -137,7 +137,7 @@ class report extends control
$this->view->position[] = $this->lang->report->bugAssign;
$this->view->submenu = 'test';
$this->view->assigns = $this->report->getBugAssign();
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed|nodeleted');
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->display();
}
@@ -195,7 +195,7 @@ class report extends control
$this->view->position[] = $this->lang->report->workload;
$this->view->workload = $this->report->getWorkload($dept, $assign);
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed|nodeleted');
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->depts = $this->loadModel('dept')->getOptionMenu();
$this->view->begin = $begin;
$this->view->end = date('Y-m-d', strtotime($end) - 24 * 3600);
@@ -49,7 +49,9 @@
<thead>
<tr class='colhead'>
<th class='c-id'><?php echo $lang->report->id;?></th>
<?php if($this->config->systemMode == 'new'):?>
<th><?php echo $lang->report->project;?></th>
<?php endif;?>
<th><?php echo $lang->report->execution;?></th>
<th class="c-hours"><?php echo $lang->report->estimate;?></th>
<th class="c-hours"><?php echo $lang->report->consumed;?></th>
@@ -61,7 +63,9 @@
<?php foreach($executions as $id =>$execution):?>
<tr class="text-center">
<td><?php echo $id;?></td>
<?php if($this->config->systemMode == 'new'):?>
<td class="text-left" title="<?php echo $execution->projectName;?>"><?php echo $execution->projectName;?></td>
<?php endif;?>
<td class="text-left" title="<?php echo $execution->name;?>"><?php echo html::a($this->createLink('execution', 'view', "executionID=$id"), $execution->name);?></td>
<td><?php echo round($execution->estimate, 2);?></td>
<td><?php echo round($execution->consumed, 2);?></td>
+2 -2
View File
@@ -1130,8 +1130,8 @@ class story extends control
if($product->type != 'normal') $this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]);
$reviewers = $this->story->getReviewerPairs($storyID, $story->version);
$reviewedBy = trim($story->reviewedBy, ',');
$reviewers = $this->story->getReviewerPairs($storyID, $story->version);
$reviewedBy = trim($story->reviewedBy, ',');
$this->executeHooks($storyID);
-22
View File
@@ -3,7 +3,6 @@ $(function()
$('#needNotReview').on('change', function()
{
$('#reviewer').attr('disabled', $(this).is(':checked') ? 'disabled' : null).trigger('chosen:updated');
getStatus('change', "storyID=" + storyID + ",changed=" + changed + ",needNotReview=" + ($(this).prop('checked') ? 1 : 0));
if($(this).is(':checked'))
{
$('.input-group-addon').removeClass('required');
@@ -15,26 +14,5 @@ $(function()
});
$('#needNotReview').change();
$specBox = $('#spec').closest('td').find('.ke-container iframe.ke-edit-iframe').contents().find('.article-content');
$verifyBox = $('#verify').closest('td').find('.ke-container iframe.ke-edit-iframe').contents().find('.article-content');
$('#title').change(function()
{
newChanged = ($(this).val() != oldStoryTitle || $specBox.html() != oldStorySpec || $verifyBox.html() != oldStoryVerify || $('.file-input-list .file-input.normal').length > 0) ? 1 : 0;
if(changed != newChanged)
{
changed = newChanged;
getStatus('change', "storyID=" + storyID + ",changed=" + changed + ",needNotReview=" + ($('#needNotReview').prop('checked') ? 1 : 0));
}
});
$('.ke-container iframe.ke-edit-iframe').contents().find('.article-content').keyup(function()
{
newChanged = ($('#title').val() != oldStoryTitle || $specBox.html() != oldStorySpec || $verifyBox.html() != oldStoryVerify || $('.file-input-list .file-input.normal').length > 0) ? 1 : 0;
if(changed != newChanged)
{
changed = newChanged;
getStatus('change', "storyID=" + storyID + ",changed=" + changed + ",needNotReview=" + ($('#needNotReview').prop('checked') ? 1 : 0));
}
});
if($('.tabs .tab-content .tab-pane.active').children().length == 0) $('.tabs .nav-tabs li.active').css('border-bottom', '1px solid #ccc');
});
+3 -3
View File
@@ -2401,14 +2401,14 @@ class storyModel extends model
* @access public
* @return array
*/
public function getProductStoryPairs($productID = 0, $branch = 0, $moduleIdList = 0, $status = 'all', $order = 'id_desc', $limit = 0, $type = 'full', $storyType = 'story', $hasParent = true)
public function getProductStoryPairs($productID = 0, $branch = 'all', $moduleIdList = 0, $status = 'all', $order = 'id_desc', $limit = 0, $type = 'full', $storyType = 'story', $hasParent = true)
{
$stories = $this->dao->select('t1.id, t1.title, t1.module, t1.pri, t1.estimate, t2.name AS product')
->from(TABLE_STORY)->alias('t1')->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
->where('1=1')
->beginIF($productID)->andWhere('t1.product')->in($productID)->fi()
->beginIF($moduleIdList)->andWhere('t1.module')->in($moduleIdList)->fi()
->beginIF($branch !== 'all')->andWhere('t1.branch')->in($branch)->fi()
->beginIF($branch !== 'all')->andWhere('t1.branch')->in("0,$branch")->fi()
->beginIF(!$hasParent)->andWhere('t1.parent')->ge(0)->fi()
->beginIF($status and $status != 'all')->andWhere('t1.status')->in($status)->fi()
->andWhere('t1.type')->eq($storyType)
@@ -2916,7 +2916,7 @@ class storyModel extends model
->where('t1.project')->eq((int)$executionID)
->andWhere('t2.deleted')->eq(0)
->beginIF($productID)->andWhere('t2.product')->eq((int)$productID)->fi()
->beginIF($branch !== 'all')->andWhere('t2.branch')->eq($branch)->fi()
->beginIF($branch !== 'all')->andWhere('t2.branch')->in("0,$branch")->fi()
->beginIF($moduleIdList)->andWhere('t2.module')->in($moduleIdList)->fi()
->beginIF($status == 'unclosed')->andWhere('t2.status')->ne('closed')->fi()
->beginIF($status == 'review')->andWhere('t2.status')->in('draft,changed')->fi()
+37 -19
View File
@@ -44,8 +44,7 @@ class task extends control
$extra = str_replace(array(',', ' '), array('&', ''), $extra);
parse_str($extra, $output);
$execution = $this->execution->getById($executionID);
$executions = $this->execution->getPairs(0, 'all', !common::canModify('execution', $execution) ? 'noclosed' : '');
$executions = $this->execution->getPairs(0, 'all', 'noclosed');
$executionID = $this->execution->saveState($executionID, $executions);
$this->execution->setMenu($executionID);
@@ -84,6 +83,7 @@ class task extends control
$task->desc = $todo->desc;
}
$execution = $this->execution->getById($executionID);
$taskLink = $this->createLink('execution', 'browse', "executionID=$executionID&tab=task");
$this->loadModel('kanban');
@@ -272,7 +272,7 @@ class task extends control
$this->view->position = $position;
$this->view->gobackLink = (isset($output['from']) and $output['from'] == 'global') ? $this->createLink('execution', 'task', "executionID=$executionID") : '';
$this->view->execution = $execution;
$this->view->executions = $this->config->systemMode == 'classic' ? $executions : $this->execution->getByProject($projectID, !common::canModify('execution', $execution) ? 'noclosed' : 'all', 0, true);
$this->view->executions = $this->config->systemMode == 'classic' ? $executions : $this->execution->getByProject($projectID, 'undone', 0, true);
$this->view->task = $task;
$this->view->users = $users;
$this->view->storyID = $storyID;
@@ -309,11 +309,6 @@ class task extends control
}
$execution = $this->execution->getById($executionID);
if($this->config->systemMode == 'new')
{
$project = $this->project->getByID($execution->project);
if($project->model == 'waterfall') $this->config->task->create->requiredFields .= ',estStarted,deadline';
}
if($this->app->tab == 'my')
{
@@ -364,16 +359,6 @@ class task extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $taskLink));
}
/* Set Custom*/
foreach(explode(',', $this->config->task->customBatchCreateFields) as $field)
{
if($execution->type == 'stage' and strpos('estStarted,deadline', $field) !== false) continue;
$customFields[$field] = $this->lang->task->$field;
}
$this->view->customFields = $customFields;
$this->view->showFields = $this->config->task->custom->batchCreateFields;
$story = $this->story->getByID($storyID);
if($story)
{
@@ -389,6 +374,21 @@ class task extends control
$showAllModule = isset($this->config->execution->task->allModule) ? $this->config->execution->task->allModule : '';
$modules = $this->loadModel('tree')->getTaskOptionMenu($executionID, 0, 0, $showAllModule ? 'allModule' : '');
/* Set Custom*/
if($this->config->systemMode == 'new')
{
$project = $this->project->getByID($execution->project);
if($project->model == 'waterfall') $this->config->task->create->requiredFields .= ',estStarted,deadline';
}
foreach(explode(',', $this->config->task->customBatchCreateFields) as $field)
{
if($execution->type == 'stage' and strpos('estStarted,deadline', $field) !== false) continue;
$customFields[$field] = $this->lang->task->$field;
}
$this->view->customFields = $customFields;
$this->view->showFields = $this->config->task->custom->batchCreateFields;
if($execution->type == 'kanban')
{
$extra = str_replace(array(',', ' '), array('&', ''), $extra);
@@ -663,7 +663,25 @@ class task extends control
if($showSuhosinInfo) $this->view->suhosinInfo = extension_loaded('suhosin') ? sprintf($this->lang->suhosinInfo, $countInputVars) : sprintf($this->lang->maxVarsInfo, $countInputVars);
/* Set Custom*/
foreach(explode(',', $this->config->task->customBatchEditFields) as $field) $customFields[$field] = $this->lang->task->$field;
if(isset($execution))
{
if($this->config->systemMode == 'new')
{
$project = $this->project->getByID($execution->project);
if($project->model == 'waterfall') $this->config->task->edit->requiredFields .= ',estStarted,deadline';
}
foreach(explode(',', $this->config->task->customBatchEditFields) as $field)
{
if($execution->type == 'stage' and strpos('estStarted,deadline', $field) !== false) continue;
$customFields[$field] = $this->lang->task->$field;
}
}
else
{
foreach(explode(',', $this->config->task->customBatchEditFields) as $field) $customFields[$field] = $this->lang->task->$field;
}
$this->view->customFields = $customFields;
$this->view->showFields = $this->config->task->custom->batchEditFields;
+1
View File
@@ -4,6 +4,7 @@ $(function()
removeDitto();
if($('th.c-name').width() < 200) $('th.c-name').width(200);
if(taskConsumed > 0) bootbox.alert(addChildTask);
$('#customField').on('click', function(){$('#tableBody .chosen-with-drop').removeClass('chosen-with-drop chosen-container-active')});
});
$(document).on('change', "[name^='estStarted'], [name^='deadline']", function()
+6 -1
View File
@@ -105,7 +105,7 @@ class taskModel extends model
/* Check duplicate task. */
if($task->type != 'affair' and $task->name)
{
$result = $this->loadModel('common')->removeDuplicate('task', $task, "execution={$executionID} and story=" . (int)$task->story);
$result = $this->loadModel('common')->removeDuplicate('task', $task, "execution={$executionID} and story=" . (int)$task->story . (isset($task->feedback) ? " and feedback=" . (int)$task->feedback : ''));
if($result['stop'])
{
$taskIdList[$assignedTo] = array('status' => 'exists', 'id' => $result['duplicate']);
@@ -1311,6 +1311,11 @@ class taskModel extends model
return false;
}
if($this->config->systemMode == 'new')
{
$project = $this->loadModel('project')->getByID($oldTask->project);
if($project->model == 'waterfall') $this->config->task->edit->requiredFields .= ',estStarted,deadline';
}
foreach(explode(',', $this->config->task->edit->requiredFields) as $field)
{
$field = trim($field);
+2 -2
View File
@@ -1,7 +1,7 @@
/**
* Confirm batch delete cases.
*
* @param string $actionLink
*
* @param string $actionLink
* @access public
* @return void
*/
+1 -1
View File
@@ -490,7 +490,7 @@ class todo extends control
if($todo->type == 'story') $app = 'product';
$cancelURL = $this->server->HTTP_REFERER;
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success', 'message' => sprintf($this->lang->todo->$confirmNote, $todo->idvalue), 'locate' => $confirmURL));
return print(js::confirm(sprintf($this->lang->todo->$confirmNote, $todo->idvalue), $confirmURL, $cancelURL, $okTarget, 'parent', $app));
return print(strpos($cancelURL, 'calendar') ? json_encode(array(sprintf($this->lang->todo->$confirmNote, $todo->idvalue), $confirmURL)) : js::confirm(sprintf($this->lang->todo->$confirmNote, $todo->idvalue), $confirmURL, $cancelURL, $okTarget, 'parent', $app));
}
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success'));
if(isonlybody()) return print(js::reload('parent.parent'));
+1 -1
View File
@@ -2700,7 +2700,7 @@ class userModel extends model
$personalData['createdStories'] = $this->dao->select($count)->from(TABLE_STORY)->where('openedBy')->eq($account)->andWhere('deleted')->eq('0')->andWhere('type')->eq('story')->fetch('count');
$personalData['createdBugs'] = $this->dao->select($count)->from(TABLE_BUG)->where('openedBy')->eq($account)->andWhere('deleted')->eq('0')->fetch('count');
$personalData['resolvedBugs'] = $this->dao->select($count)->from(TABLE_BUG)->where('resolvedBy')->eq($account)->andWhere('deleted')->eq('0')->fetch('count');
$personalData['createdCases'] = $this->dao->select($count)->from(TABLE_CASE)->where('openedBy')->eq($account)->andWhere('deleted')->eq('0')->andWhere('product')->ne(0)->fetch('count');
$personalData['createdCases'] = $this->dao->select($count)->from(TABLE_CASE)->where('openedBy')->eq($account)->andWhere('deleted')->eq('0')->fetch('count');
if($this->config->edition == 'max')
{
$personalData['createdRisks'] = $this->dao->select($count)->from(TABLE_RISK)->where('createdBy')->eq($account)->andWhere('deleted')->eq('0')->fetch('count');
+1 -1
View File
@@ -38,7 +38,7 @@ include '../../common/view/header.lite.html.php';
if($denyType == 'noview')
{
$menuName = $menu;
$menuName = isset($lang->$menu->common) ? $lang->$module->common : $menu;
if(isset($lang->menu->$menu))list($menuName) = explode('|', $lang->menu->$menu);
printf($lang->user->errorView, $menuName);
}
Regular → Executable
+2 -3
View File
@@ -427,6 +427,7 @@ class weeklyModel extends model
->from(TABLE_TASK)
->where('execution')->in($executionIdList)
->andWhere('consumed')->gt(0)
->andWhere("(estStarted < '$nextMonday' or estStarted='0000-00-00')")
->andWhere('status')->ne('cancel')
->fetchAll('id');
@@ -466,13 +467,12 @@ class weeklyModel extends model
$executions = $this->loadModel('execution')->getList($project, 'all', 'all', 0, 0, 0);
$executionIdList = array_keys($executions);
if($this->config->edition == 'max')
if($this->config->edition != 'open')
{
$AC = $this->dao->select('sum(consumed) as consumed')
->from(TABLE_EFFORT)
->where('objectType')->eq('task')
->andWhere('execution')->in($executionIdList)
->andWhere('date')->ge($monday)
->andWhere('date')->lt($nextMonday)
->fetch('consumed');
}
@@ -482,7 +482,6 @@ class weeklyModel extends model
$AC = $this->dao->select('sum(consumed) as consumed')
->from(TABLE_TASKESTIMATE)
->where('task')->in($taskIdList)
->andWhere('date')->ge($monday)
->andWhere('date')->lt($nextMonday)
->fetch('consumed');
}
@@ -51,14 +51,16 @@ $position[] = $this->lang->client->browse;
</tbody>
</table>
</div>
<?php if($this->config->edition == 'open'):?>
<script>
$(function()
{
$(document).on('click', '.deleter', function()
$('.deleter').on('click', function()
{
$deleter = $(this);
if(confirm('<?php echo $lang->confirmDelete?>'))
{
$.getJSON(deleter.attr('href'), function(data)
$.getJSON($deleter.attr('href'), function(data)
{
if(data.result != 'success') alert(data.message);
return location.reload();
@@ -66,7 +68,7 @@ $(function()
}
return false;
});
})
</script>
<?php endif;?>
<?php include $app->getModuleRoot() . 'common/view/footer.html.php';?>