Merge branch 'master' into 'sprint/master_zhouxudong_56362'
# Conflicts: # module/kanban/model.php
This commit is contained in:
@@ -62,8 +62,8 @@ class usersEntry extends entry
|
||||
|
||||
$password = $this->request('password', '') ? md5($this->request('password')) : '';
|
||||
|
||||
$visions = $this->request('visions', 'rnd');
|
||||
if(is_array($visions)) $visions = implode(',', $visions);
|
||||
$visions = $this->request('visions', array('rnd'));
|
||||
if(!is_array($visions)) $visions = explode(',', $visions);
|
||||
|
||||
$this->setPost('password1', $password);
|
||||
$this->setPost('password2', $password);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
DELETE from zt_report where `code` = 'product-invest';
|
||||
ALTER TABLE `zt_review` ADD docVersion smallint(6) NOT NULL AFTER `doc`;
|
||||
|
||||
DELETE FROM `zt_workflowaction` WHERE `module`='story' AND `action`='browse';
|
||||
|
||||
@@ -6791,7 +6791,6 @@ CREATE OR REPLACE VIEW `ztv_daybugresolve` AS select count(*) AS `bugresolve`,le
|
||||
CREATE OR REPLACE VIEW `ztv_dayactions` AS select count(*) AS `actions`,left(`zt_action`.`date`,10) AS `day` from `zt_action` group by left(`zt_action`.`date`,10);
|
||||
|
||||
REPLACE INTO `zt_report` (`code`, `name`, `module`, `sql`, `vars`, `langs`, `params`, `step`, `desc`, `addedBy`, `addedDate`) VALUES
|
||||
('product-invest', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u6295\\u5165\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u6295\\u5165\\u8868\",\"en\":\"Product Investment\"}', ',product', 'select t1.id,t1.name,1 as projects, round(t3.consumed,2) as consumed from TABLE_PRODUCT as t1\r\n left join TABLE_PROJECTPRODUCT as t2 on t1.id=t2.product\r\n left join ztv_projectsummary as t3 on t2.project=t3.project\r\n left join TABLE_PROJECT as t4 on t2.project=t4.id\r\n left join TABLE_PROGRAM as t5 on t1.program=t5.id\r\n where t1.deleted=\'0\' and t4.deleted=\'0\' and t4.type=\'project\'\r\norder by t5.`order` asc, t1.line desc, t1.`order` asc', '', '{\"projects\":{\"zh-cn\":\"\\u9879\\u76ee\\u6570\",\"zh-tw\":\"\\u9879\\u76ee\\u6570\",\"en\":\"Projects\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"projects\",\"consumed\"],\"reportType\":[\"sum\",\"sum\"],\"sumAppend\":[\"projects\",\"consumed\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u6bcf\\u4e2a\\u4ea7\\u54c1\\u7684\\u9879\\u76ee\\u603b\\u6570\\uff0c\\u5df2\\u7ecf\\u6d88\\u8017\\u7684\\u5de5\\u65f6\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u6bcf\\u500b\\u7522\\u54c1\\u7684\\u9805\\u76ee\\u7e3d\\u6578\\uff0c\\u5df2\\u7d93\\u6d88\\u8017\\u7684\\u5de5\\u6642\\u3002\",\"en\":\"Number of projects and consumed hours.\"}', 'admin', '2015-07-20 14:21:31'),
|
||||
('product-progress', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u5b8c\\u6210\\u5ea6\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u5b8c\\u6210\\u5ea6\\u7d71\\u8a08\\u8868\",\"en\":\"Product Progress\"}', ',product', 'select t1.*,t2.name, (case when t1.status = \'closed\' or t1.stage = \'released\' then 1 else 0 end) as done, 1 as count from TABLE_STORY as t1 \r\nleft join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"count\",\"done\"],\"reportType\":[\"sum\",\"sum\"],\"sumAppend\":[\"count\",\"done\"],\"percent\":{\"1\":\"1\"},\"contrast\":{\"1\":\"count\"},\"showAlone\":{\"1\":\"1\"}}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u603b\\u6570(\\u72b6\\u6001\\u662f\\u5173\\u95ed\\uff0c\\u6216\\u8005\\u7814\\u53d1\\u9636\\u6bb5\\u662f\\u53d1\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u7e3d\\u6578(\\u72c0\\u614b\\u662f\\u95dc\\u9589\\uff0c\\u6216\\u8005\\u7814\\u767c\\u968e\\u6bb5\\u662f\\u767c\\u5e03)\\uff0c\\u5b8c\\u6210\\u7684\\u767e\\u5206\\u6bd4\\u3002\",\"en\":\"Number of total stories,done stories(state is closed, or stage is released), percent of completion.\"}', 'admin', '2015-07-21 15:07:48'),
|
||||
('story-status', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u72b6\\u6001\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u72c0\\u614b\\u5206\\u5e03\\u8868\",\"en\":\"Story Status\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"status\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u72b6\\u6001\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u72c0\\u614b\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and status distribution of stories.\"}', 'admin', '2015-07-21 15:35:38'),
|
||||
('story-stage', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u9636\\u6bb5\\u5206\\u5e03\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u9700\\u6c42\\u968e\\u6bb5\\u5206\\u5e03\\u8868\",\"en\":\"Story Stage\"}', ',product', 'select t1.*,t2.name from TABLE_STORY as t1\r\n left join TABLE_PRODUCT as t2 on t1.product=t2.id \r\nleft join TABLE_PROGRAM as t3 on t2.program=t3.id \r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\'\r\norder by t3.`order` asc, t2.line desc, t2.`order` asc', '', '', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stage\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u4ea7\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u603b\\u6570\\uff0c\\u7814\\u53d1\\u9636\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u7522\\u54c1\\u5217\\u51fa\\u9700\\u6c42\\u7e3d\\u6578\\uff0c\\u7814\\u767c\\u968e\\u6bb5\\u7684\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"Total number and stage distribution of stories \"}', 'admin', '2015-07-21 15:38:34'),
|
||||
|
||||
@@ -85,7 +85,7 @@ public function getKanban4Group($executionID, $browseType, $groupBy, $searchValu
|
||||
$columnData[$columnID]['actions'] = $column->actions;
|
||||
|
||||
$cardOrder = 1;
|
||||
$objects = zget($cardGroup, $columnID, array());
|
||||
$objects = zget($cardGroup, $column->columnType, array());
|
||||
foreach($objects as $object)
|
||||
{
|
||||
if(empty($object)) continue;
|
||||
@@ -104,10 +104,14 @@ public function getKanban4Group($executionID, $browseType, $groupBy, $searchValu
|
||||
|
||||
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->name, $searchValue) === false) continue;
|
||||
$cardData['title'] = $object->title;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,17 +37,17 @@
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class='kanban-cards'>
|
||||
<?php
|
||||
<?php
|
||||
$kanbanview = 'kanban';
|
||||
if($this->cookie->kanbanview) $kanbanview = $this->cookie->kanbanview;
|
||||
|
||||
|
||||
if(!common::hasPriv('execution', $kanbanview))
|
||||
{
|
||||
foreach (explode('|', 'kanban|task|calendar|gantt|tree|grouptask') as $view)
|
||||
foreach (explode('|', 'kanban|task|calendar|gantt|tree|grouptask') as $view)
|
||||
{
|
||||
if(common::hasPriv('execution', $view))
|
||||
{
|
||||
$kanbanview = $view;
|
||||
$kanbanview = $view;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -93,24 +93,24 @@
|
||||
</div>
|
||||
<div class="kanban-footer">
|
||||
<div class='kanban-members pull-left'>
|
||||
<?php $teams = $memberGroup[$kanban->id];?>
|
||||
<?php $teams = isset($memberGroup[$kanban->id]) ? $memberGroup[$kanban->id] : array();?>
|
||||
<?php $count = 0;?>
|
||||
<?php foreach($teams as $member):?>
|
||||
<?php if($count > 2) break;?>
|
||||
<?php $count ++;?>
|
||||
<?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 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 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'>
|
||||
|
||||
@@ -105,7 +105,7 @@ class model extends baseModel
|
||||
$conditions = json_decode($action->conditions);
|
||||
if($action->extensionType == 'extend')
|
||||
{
|
||||
$title = $action->name;
|
||||
if($icon != 'copy' and $methodName != 'create') $title = $action->name;
|
||||
if($conditions) $enabled = $this->loadModel('flow')->checkConditions($conditions, $data);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -518,6 +518,13 @@ class router extends baseRouter
|
||||
/* Remove module and method. */
|
||||
$params = array_slice($params, 2); // $params = array(1);
|
||||
|
||||
if($moduleName == 'flow' and $methodName == 'browse')
|
||||
{
|
||||
$mode = 'browse';
|
||||
if(count($params) > 0 and !is_numeric($params[0])) $mode = array_shift($params);
|
||||
array_unshift($params, $mode);
|
||||
}
|
||||
|
||||
array_unshift($params, $methodName); // $params = array('operate', 1);
|
||||
array_unshift($params, $moduleName); // $params = array('flow', 'operate', 1);
|
||||
|
||||
@@ -537,6 +544,16 @@ class router extends baseRouter
|
||||
|
||||
$params = array_reverse($params); // $params = array('id' => 1);
|
||||
|
||||
if($moduleName == 'flow' and $methodName == 'browse')
|
||||
{
|
||||
$mode = zget($params, 'mode', 'browse');
|
||||
if(is_numeric($mode)) $mode = 'browse';
|
||||
$params['mode'] = $mode;
|
||||
|
||||
$get = array_reverse($_GET);
|
||||
$get['mode'] = $mode;
|
||||
$_GET = array_reverse($get);
|
||||
}
|
||||
$params[$this->config->methodVar] = $methodName; // $param = array('id' => 1, 'f' => 'operate');
|
||||
$params[$this->config->moduleVar] = $moduleName; // $param = array('id' => 1, 'f' => 'operate', 'm' => 'flow');
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ $lang->bug->openedDate = 'ReportedDate';
|
||||
$lang->bug->openedDateAB = 'Reported';
|
||||
$lang->bug->openedBuild = 'Open Build';
|
||||
$lang->bug->assignedTo = 'AssignTo';
|
||||
$lang->bug->assignedToMe = 'AssignToMe';
|
||||
$lang->bug->assignBug = 'AssignedTo';
|
||||
$lang->bug->assignedToAB = 'AssignedTo';
|
||||
$lang->bug->assignedDate = 'AssignedDate';
|
||||
|
||||
@@ -61,6 +61,7 @@ $lang->bug->openedDate = '创建日期';
|
||||
$lang->bug->openedDateAB = '创建日期';
|
||||
$lang->bug->openedBuild = '影响版本';
|
||||
$lang->bug->assignedTo = '指派给';
|
||||
$lang->bug->assignedToMe = '指派给我';
|
||||
$lang->bug->assignBug = '指派给';
|
||||
$lang->bug->assignedToAB = '指派给';
|
||||
$lang->bug->assignedDate = '指派日期';
|
||||
|
||||
+50
-4
@@ -1601,18 +1601,62 @@ class bugModel extends model
|
||||
* @param int $limit
|
||||
* @param object $pager
|
||||
* @param int $executionID
|
||||
* @param int $queryID
|
||||
* @access public
|
||||
* @return void
|
||||
* @return array
|
||||
*/
|
||||
public function getUserBugs($account, $type = 'assignedTo', $orderBy = 'id_desc', $limit = 0, $pager = null, $executionID = 0)
|
||||
public function getUserBugs($account, $type = 'assignedTo', $orderBy = 'id_desc', $limit = 0, $pager = null, $executionID = 0, $queryID = 0)
|
||||
{
|
||||
if(!$this->loadModel('common')->checkField(TABLE_BUG, $type)) return array();
|
||||
$moduleName = $this->app->rawMethod == 'work' ? 'workBug' : 'contributeBug';
|
||||
$queryName = $moduleName . 'Query';
|
||||
$formName = $moduleName . 'Form';
|
||||
|
||||
$bugIDList = array();
|
||||
if($moduleName == 'contributeBug')
|
||||
{
|
||||
$bugsAssignedByMe = $this->loadModel('my')->getAssignedByMe($account, 0, $pager, $orderBy, 0, 'bug');
|
||||
foreach($bugsAssignedByMe as $bugID => $bug)
|
||||
{
|
||||
$bugIDList[$bugID] = $bugID;
|
||||
}
|
||||
}
|
||||
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set($queryName, $query->sql);
|
||||
$this->session->set($formName, $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set($queryName, ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
|
||||
}
|
||||
$query = $this->session->$queryName;
|
||||
$query = preg_replace('/`(\w+)`/', 't1.`$1`', $query);
|
||||
|
||||
if($type != 'bySearch' and !$this->loadModel('common')->checkField(TABLE_BUG, $type)) return array();
|
||||
$bugs = $this->dao->select('t1.*,t2.name as productName')->from(TABLE_BUG)->alias('t1')
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
|
||||
->where('t1.deleted')->eq(0)
|
||||
->beginIF($type == 'bySearch')->andWhere($query)->fi()
|
||||
->beginIF($executionID)->andWhere('t1.execution')->eq($executionID)->fi()
|
||||
->beginIF($type != 'closedBy' and $this->app->moduleName == 'block')->andWhere('t1.status')->ne('closed')->fi()
|
||||
->beginIF($type != 'all')->andWhere("t1.`$type`")->eq($account)->fi()
|
||||
->beginIF($type != 'all' and $type != 'bySearch')->andWhere("t1.`$type`")->eq($account)->fi()
|
||||
->beginIF($type == 'bySearch' and $moduleName == 'workBug')->andWhere("t1.assignedTo")->eq($account)->fi()
|
||||
->beginIF($type == 'bySearch' and $moduleName == 'contributeBug')
|
||||
->andWhere('t1.openedBy', 1)->eq($account)
|
||||
->orWhere('t1.closedBy')->eq($account)
|
||||
->orWhere('t1.resolvedBy')->eq($account)
|
||||
->orWhere('t1.id')->in($bugIDList)
|
||||
->markRight(1)
|
||||
->fi()
|
||||
->orderBy($orderBy)
|
||||
->beginIF($limit > 0)->limit($limit)->fi()
|
||||
->page($pager)
|
||||
@@ -1878,6 +1922,8 @@ class bugModel extends model
|
||||
if(!empty($this->config->isINT)) $firstLetter = '';
|
||||
$users[$account] = $firstLetter . ($user->realname ? $user->realname : $user->account);
|
||||
}
|
||||
|
||||
$users = $this->loadModel('user')->processAccountSort($users);
|
||||
return array('' => '') + $users;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
<div class='cell'>
|
||||
<div class='list-group'>
|
||||
<?php
|
||||
$reruiredModules = ksort($config->custom->requiredModules);
|
||||
foreach($requiredModules as $requiredModule)
|
||||
ksort($config->custom->requiredModules);
|
||||
foreach($config->custom->requiredModules as $requiredModule)
|
||||
{
|
||||
$requiredModuleName = zget($lang->custom->moduleName, $requiredModule, $lang->$requiredModule->common);
|
||||
echo html::a(inlink('required', "module=$requiredModule"), $requiredModuleName, '', "id='{$requiredModule}Tab'");
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
}
|
||||
elseif($doc->contentType == 'markdown')
|
||||
{
|
||||
echo "<textarea id='markdownContent' /></textarea>";
|
||||
echo "<textarea id='markdownContent'></textarea>";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -116,7 +116,7 @@ js::set('docID', $doc->id);
|
||||
}
|
||||
elseif($doc->contentType == 'markdown')
|
||||
{
|
||||
echo "<textarea id='markdownContent' /></textarea>";
|
||||
echo "<textarea id='markdownContent'></textarea>";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -51,6 +51,7 @@ $config->execution->search['fields']['desc'] = $lang->task->desc;
|
||||
$config->execution->search['fields']['assignedTo'] = $lang->task->assignedTo;
|
||||
$config->execution->search['fields']['pri'] = $lang->task->pri;
|
||||
|
||||
if($app->tab == 'my') $config->execution->search['fields']['project'] = $lang->task->project;
|
||||
$config->execution->search['fields']['execution'] = $lang->task->execution;
|
||||
$config->execution->search['fields']['module'] = $lang->task->module;
|
||||
$config->execution->search['fields']['estimate'] = $lang->task->estimate;
|
||||
@@ -86,6 +87,7 @@ $config->execution->search['params']['desc'] = array('operator' => 'in
|
||||
$config->execution->search['params']['assignedTo'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->execution->search['params']['pri'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->task->priList);
|
||||
|
||||
if($app->tab == 'my') $config->execution->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->execution->search['params']['execution'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->execution->search['params']['module'] = array('operator' => 'belong', 'control' => 'select', 'values' => '');
|
||||
$config->execution->search['params']['estimate'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
|
||||
@@ -115,6 +115,7 @@ class execution extends control
|
||||
$this->loadModel('datatable');
|
||||
$this->loadModel('setting');
|
||||
$this->loadModel('product');
|
||||
$this->loadModel('user');
|
||||
|
||||
if(common::hasPriv('execution', 'create')) $this->lang->TRActions = html::a($this->createLink('execution', 'create'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->execution->create, '', "class='btn btn-primary'");
|
||||
|
||||
@@ -211,6 +212,7 @@ class execution extends control
|
||||
/* team member pairs. */
|
||||
$memberPairs = array();
|
||||
foreach($this->view->teamMembers as $key => $member) $memberPairs[$key] = $member->realname;
|
||||
$memberPairs = $this->user->processAccountSort($memberPairs);
|
||||
|
||||
$showAllModule = isset($this->config->execution->task->allModule) ? $this->config->execution->task->allModule : '';
|
||||
$extra = (isset($this->config->execution->task->allModule) && $this->config->execution->task->allModule == 1) ? 'allModule' : '';
|
||||
@@ -227,7 +229,7 @@ class execution extends control
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->status = $status;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|all');
|
||||
$this->view->users = $this->user->getPairs('noletter|all');
|
||||
$this->view->param = $param;
|
||||
$this->view->executionID = $executionID;
|
||||
$this->view->execution = $execution;
|
||||
@@ -918,6 +920,7 @@ class execution extends control
|
||||
{
|
||||
$memberPairs[$key] = $member->realname;
|
||||
}
|
||||
$memberPairs = $this->user->processAccountSort($memberPairs);
|
||||
|
||||
/* Build the search form. */
|
||||
$actionURL = $this->createLink('execution', 'bug', "executionID=$executionID&productID=$productID&orderBy=$orderBy&build=$build&type=bysearch&queryID=myQueryID");
|
||||
@@ -1496,7 +1499,7 @@ class execution extends control
|
||||
$this->view->name = $name;
|
||||
$this->view->code = $code;
|
||||
$this->view->team = $team;
|
||||
$this->view->teams = array(0 => '', $projectID => (isset($project->name) ? $project->name : '')) + $this->execution->getCanCopyObjects((int)$projectID);
|
||||
$this->view->teams = array(0 => '') + $this->execution->getCanCopyObjects((int)$projectID);
|
||||
$this->view->allProjects = array(0 => '') + $this->project->getPairsByModel('all', 0, 'noclosed');
|
||||
$this->view->executionID = $executionID;
|
||||
$this->view->productID = $productID;
|
||||
@@ -2730,7 +2733,7 @@ class execution extends control
|
||||
|
||||
$currentMembers = $this->execution->getTeamMembers($executionID);
|
||||
$members2Import = $this->execution->getMembers2Import($team2Import, array_keys($currentMembers));
|
||||
$teams2Import = $this->loadModel('personnel')->getCopiedObjects($executionID, 'sprint');
|
||||
$teams2Import = $this->loadModel('personnel')->getCopiedObjects($executionID, 'sprint', true);
|
||||
$teams2Import = array('' => '') + $teams2Import;
|
||||
|
||||
/* Append users for get users. */
|
||||
|
||||
@@ -720,6 +720,17 @@ function renderCount($count, count, column)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert to link product.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function tips()
|
||||
{
|
||||
bootbox.alert(needLinkProducts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render header of a column.
|
||||
*/
|
||||
@@ -754,10 +765,11 @@ function renderHeaderCol($column, column, $header, kanbanData)
|
||||
var printMoreBtn = (columnPrivs.includes('setColumn') || columnPrivs.includes('setWIP'));
|
||||
|
||||
/* Render more menu. */
|
||||
if(((column.type == 'backlog' && hasStoryButton) || (column.type == 'wait' && hasTaskButton) || (column.type == 'unconfirmed' && hasBugButton)) && $actions.children('.text-primary').length == 0)
|
||||
if(column.type == 'backlog' || column.type == 'wait' || column.type == 'unconfirmed' && $actions.children('.text-primary').length == 0)
|
||||
{
|
||||
var tips = productID ? '' : 'onclick="tips()"';
|
||||
$actions.append([
|
||||
'<a data-contextmenu="columnCreate" data-type="' + column.type + '" data-kanban="' + kanban.id + '" data-parent="' + (column.parentType || '') + '" class="text-primary">',
|
||||
'<a data-contextmenu="columnCreate" data-type="' + column.type + '" data-kanban="' + kanban.id + '" data-parent="' + (column.parentType || '') + '" class="text-primary"' + ((column.type !== 'wait') ? tips : '') + '>',
|
||||
'<i class="icon icon-expand-alt"></i>',
|
||||
'</a>'
|
||||
].join(''));
|
||||
@@ -820,14 +832,16 @@ function updateRegion(regionID, regionData = [])
|
||||
if(!regionData) regionData = regions[regionID];
|
||||
|
||||
var data = groupBy == 'default' ? regionData.groups : regionData;
|
||||
if(data == null)
|
||||
if(data == null || data.length == 0)
|
||||
{
|
||||
$("div[data-id^=" + regionID + "].region").hide();
|
||||
if(groupBy == 'default') $("div[data-id^=" + regionID + "].region").hide();
|
||||
if(groupBy != 'default') $("div[data-id^=" + regionID + "].kanban").hide();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$("div[data-id^=" + regionID + "].region").show();
|
||||
if(groupBy == 'default') $("div[data-id^=" + regionID + "].region").show();
|
||||
if(groupBy != 'default') $("div[data-id^=" + regionID + "].kanban").show();
|
||||
}
|
||||
$region.empty();
|
||||
$region.data('zui.kanban').render(data);
|
||||
|
||||
@@ -325,6 +325,17 @@ function renderColumnCount($count, count, col)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert to link product.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function tips()
|
||||
{
|
||||
bootbox.alert(needLinkProducts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render header column
|
||||
* @param {JQuery} $col Header column element
|
||||
@@ -343,10 +354,11 @@ function renderHeaderCol($col, col, $header, kanban)
|
||||
if(priv.canCreateTask || priv.canBatchCreateTask) printTaskButton = true;
|
||||
if(priv.canCreateBug || priv.canBatchCreateBug) printBugButton = true;
|
||||
|
||||
if((col.type === 'backlog' && printStoryButton) || (col.type === 'wait' && printTaskButton) || (col.type == 'unconfirmed' && printBugButton))
|
||||
if(col.type === 'backlog' || col.type === 'wait' || col.type == 'unconfirmed')
|
||||
{
|
||||
var tips = productID ? '' : 'onclick="tips()"';
|
||||
$actions.append([
|
||||
'<a data-contextmenu="columnCreate" data-type="' + col.type + '" data-kanban="' + kanban.id + '" data-parent="' + (col.parentType || '') + '" class="text-primary">',
|
||||
'<a data-contextmenu="columnCreate" data-type="' + col.type + '" data-kanban="' + kanban.id + '" data-parent="' + (col.parentType || '') + '" class="text-primary"' + ((col.laneType !== 'task') ? tips : '') + '>',
|
||||
'<i class="icon icon-expand-alt"></i>',
|
||||
'</a>'
|
||||
].join(''));
|
||||
|
||||
@@ -271,6 +271,7 @@ $lang->execution->treeOnlyStory = 'Show Story Only';
|
||||
$lang->execution->storyKanban = 'Story Kanban';
|
||||
$lang->execution->storySort = 'Rank Story';
|
||||
$lang->execution->importPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan?';
|
||||
$lang->execution->needLinkProducts = 'The execution has not been linked with any product, and the related functions cannot be used. Please link the product first and try again.';
|
||||
$lang->execution->iteration = 'Iterations';
|
||||
$lang->execution->iterationInfo = '%s Iterations';
|
||||
$lang->execution->viewAll = 'View All';
|
||||
@@ -396,6 +397,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->countTip = ' (%s member)';
|
||||
$lang->execution->pleaseInput = "Enter";
|
||||
|
||||
/* Statistics. */
|
||||
|
||||
@@ -51,7 +51,7 @@ $lang->execution->canceledBy = '由谁取消';
|
||||
$lang->execution->canceledDate = '取消日期';
|
||||
$lang->execution->begin = '计划开始';
|
||||
$lang->execution->end = '计划完成';
|
||||
$lang->execution->dateRange = '起始日期';
|
||||
$lang->execution->dateRange = '计划起止日期';
|
||||
$lang->execution->realBeganAB = '实际开始';
|
||||
$lang->execution->realEndAB = '实际完成';
|
||||
$lang->execution->realBegan = '实际开始日期';
|
||||
@@ -271,6 +271,7 @@ $lang->execution->treeOnlyStory = "树状图只看{$lang->SRCommon}";
|
||||
$lang->execution->storyKanban = "{$lang->SRCommon}看板";
|
||||
$lang->execution->storySort = "{$lang->SRCommon}排序";
|
||||
$lang->execution->importPlanStory = '创建' . $lang->executionCommon . '成功!\n是否导入计划关联的相关' . $lang->SRCommon . '?';
|
||||
$lang->execution->needLinkProducts = '该执行还未关联任何产品,相关功能无法使用,请先关联产品后再试。';
|
||||
$lang->execution->iteration = '版本迭代';
|
||||
$lang->execution->iterationInfo = '迭代%s次';
|
||||
$lang->execution->viewAll = '查看所有';
|
||||
@@ -396,6 +397,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->countTip = '(%s人)';
|
||||
$lang->execution->pleaseInput = "请输入";
|
||||
|
||||
/* 统计。*/
|
||||
|
||||
@@ -2753,14 +2753,31 @@ class executionModel extends model
|
||||
|
||||
$objectPairs = $this->dao->select('id,name')->from(TABLE_PROJECT)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('project', true)->eq($projectID)
|
||||
->andWhere('type')->ne('project')
|
||||
->andWhere('(project')->eq($projectID)
|
||||
->orWhere('id')->eq($projectID)
|
||||
->markRight(1)
|
||||
->orWhere('id')->eq($projectID)
|
||||
->orderBy('type_asc,openedDate_desc')
|
||||
->limit('9')
|
||||
->fetchPairs();
|
||||
|
||||
$countPairs = $this->dao->select('root, COUNT(*) as count')->from(TABLE_TEAM)
|
||||
->where('( type')->eq('project')
|
||||
->andWhere('root')->eq($projectID)
|
||||
->markRight(1)
|
||||
->orWhere('( type')->eq('execution')
|
||||
->andWhere('root')->in(array_keys($objectPairs))
|
||||
->markRight(1)
|
||||
->groupBy('root')
|
||||
->fetchPairs('root');
|
||||
|
||||
foreach($objectPairs as $objectID => $objectName)
|
||||
{
|
||||
$memberCount = zget($countPairs, $objectID, 0);
|
||||
$countTip = $memberCount > 1 ? str_replace('member', 'members', $this->lang->execution->countTip) : $this->lang->execution->countTip;
|
||||
$objectPairs[$objectID] = $objectName . sprintf($countTip, $memberCount);
|
||||
}
|
||||
|
||||
return $objectPairs;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ js::set('vision', $this->config->vision);
|
||||
js::set('productCount', count($productNames));
|
||||
js::set('executionID', $execution->id);
|
||||
js::set('reviewStoryParis', $reviewStoryParis);
|
||||
js::set('needLinkProducts', $lang->execution->needLinkProducts);
|
||||
js::set('rdSearchValue', '');
|
||||
|
||||
$canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1;
|
||||
@@ -111,9 +112,6 @@ js::set('priv',
|
||||
'canUnlinkStory' => common::hasPriv('execution', 'unlinkStory'),
|
||||
)
|
||||
);
|
||||
js::set('hasStoryButton', $hasStoryButton);
|
||||
js::set('hasBugButton', $hasBugButton);
|
||||
js::set('hasTaskButton', $hasTaskButton);
|
||||
?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
|
||||
@@ -214,4 +214,5 @@ js::set('priv',
|
||||
<?php js::set('fluidBoard', $execution->fluidBoard);?>
|
||||
<?php js::set('displayCards', $execution->displayCards);?>
|
||||
<?php js::set('reviewStoryParis', $reviewStoryParis);?>
|
||||
<?php js::set('needLinkProducts', $lang->execution->needLinkProducts);?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -1606,7 +1606,7 @@ class kanban extends control
|
||||
|
||||
$this->view->canEdit = $from == 'RDKanban' ? 0 : 1;
|
||||
$this->view->column = $column;
|
||||
$this->view->title = $column->name . $this->lang->colon . $this->lang->kanban->setColumn;
|
||||
$this->view->title = $column->name . $this->lang->colon . $this->lang->kanban->editColumn;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -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% - 150px)}
|
||||
.space .spaceTitle.pull-left {overflow: hidden; white-space: nowrap; max-width: calc(100% - 255px)}
|
||||
.spaceName {font-size: 16px; font-weight: bold;}
|
||||
.spaceTitle .icon-cube {font-size: 16px;}
|
||||
.spaceDesc {font-size: 13px; color: #838A9D; margin: -5px 0 5px 18px;}
|
||||
#more .setting {margin-left: -25px; min-width: 80px}
|
||||
|
||||
@@ -16,7 +18,7 @@
|
||||
.kanbans .panel {margin: 0 0; border: 1px solid #DCDCDC; border-radius: 4px; box-shadow: none; cursor: pointer; height: 160px; margin-bottom: 5px;}
|
||||
.kanbans .panel:hover {border-color: #006AF1; box-shadow: 0 0 10px 0 rgba(0,0,100,.25);}
|
||||
.kanbans .panel-heading {padding: 4px 2px 10px 16px;}
|
||||
.kanbans .kanban-name {overflow: hidden; white-space:nowrap; width: 88%; float: left; padding-top: 8px;}
|
||||
.kanbans .kanban-name {overflow: hidden; white-space:nowrap; width: 78%; float: left; padding-top: 8px;}
|
||||
.kanbans .panel .label-closed {background: #AAA !important; color: #FFF; margin-top:-1px !important;}
|
||||
.kanbans .kanban-actions {float: right; visibility: hidden;}
|
||||
.kanbans .kanban-actions .dropdown-menu.pull-right {top:31px; right: -84px; left: auto;}
|
||||
@@ -36,6 +38,8 @@
|
||||
.kanbans .kanban-members > span:after {right: -4px;}
|
||||
.kanbans .kanban-members-total {display: inline-block; margin-left: 6px; position: relative; top: 3px}
|
||||
.kanbans .kanbanAcl {position: absolute; right: 0px; bottom: 2px; color: #838a9d;}
|
||||
.kanbans .kanban-label {margin: 6px 6px 0px 0px; float: left; color: #ff8a53; border: 1px solid #ff8a53;}
|
||||
@media screen and (max-width: 1366px){.kanbans .kanban-name {width: 68%;}}
|
||||
|
||||
a.disabled {pointer-events: none;}
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
.dropdown-menu > li {padding: 0 10px;}
|
||||
.dropdown-menu > li > a > .icon {position: relative; left: -5px;}
|
||||
|
||||
#kanbanContainer {padding-bottom: 0; margin-bottom: 0;}
|
||||
#kanbanContainer {padding-bottom: 0; margin-bottom: 0; border: unset;}
|
||||
#kanbanContainer.fullscreen {overflow: auto;}
|
||||
|
||||
.region {border: 1px solid #dcdcdc; background-color: #fff;}
|
||||
.region {border: 0px solid #dcdcdc; background-color: #fff;}
|
||||
.region + .region {margin-top: 20px;}
|
||||
.region .region-header {padding: 10px;}
|
||||
.region .region-header strong {font-size: 14px; color: #999EAB}
|
||||
@@ -136,3 +136,8 @@
|
||||
@-moz-document url-prefix(){ .region .kanban-lane-items{scrollbar-width:thin; padding:5px 0px 5px 5px !important;} .region .kanban-card .info .user{right: -6px !important;}}
|
||||
#archivedCards .table-empty-tip {border-style: hidden;}
|
||||
#archivedColumns .table-empty-tip {border-style: hidden;}
|
||||
|
||||
#main > .container {padding: 0px 0px 0px 10px; margin: -10px 0px 0px 0px;}
|
||||
@media screen and (max-width: 1366px){#main > .container {padding: 0px 10px 0px 10px; margin: -10px 0px 0px 0px;}}
|
||||
.panel-body {padding: 0px;}
|
||||
#kanbanContainer {background: #efefef; box-shadow: none;}
|
||||
|
||||
@@ -1116,6 +1116,7 @@ function createCardMenu(options)
|
||||
|
||||
var items = [];
|
||||
if(privs.includes('editCard') && card.fromType == '') items.push({label: kanbanLang.editCard, icon: 'edit', url: createLink('kanban', 'editCard', 'cardID=' + card.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
|
||||
if(privs.includes('deleteCard')) items.push({label: card.fromType == '' ? kanbanLang.deleteCard : kanbanLang.removeCard, icon: card.fromType == '' ? 'trash' : 'unlink', url: createLink('kanban', 'deleteCard', 'cardID=' + card.id), attrs: {'target': 'hiddenwin'}});
|
||||
if(privs.includes('performable') && kanban.performable == 1)
|
||||
{
|
||||
if(card.status == 'done')
|
||||
@@ -1127,6 +1128,25 @@ function createCardMenu(options)
|
||||
items.push({label: kanbanLang.finishCard, icon: 'checked', onClick: function(){finishCard(card.id, card.kanban, card.region);}});
|
||||
}
|
||||
}
|
||||
if(privs.includes('archiveCard') && kanban.archived == '1') items.push({label: kanbanLang.archiveCard, icon: 'card-archive', url: createLink('kanban', 'archiveCard', 'cardID=' + card.id), attrs: {'target': 'hiddenwin'}});
|
||||
|
||||
var editCard = (privs.includes('editCard') && card.fromType == '') ? true : false;
|
||||
var deleteCard = privs.includes('deleteCard');
|
||||
var archiveCard = (privs.includes('archiveCard') && kanban.archived == '1') ? true : false;
|
||||
|
||||
var performable = (privs.includes('performable') && kanban.performable == 1) ? true : false;
|
||||
|
||||
var moveCard = privs.includes('moveCard');
|
||||
var setCardColor = privs.includes('setCardColor');
|
||||
|
||||
var basicActions = (editCard || deleteCard || archiveCard) ? true : false;
|
||||
var otherActions = (moveCard || setCardColor) ? true : false;
|
||||
|
||||
if((performable || basicActions) && otherActions)
|
||||
{
|
||||
items.push({type: 'divider'});
|
||||
}
|
||||
|
||||
if(privs.includes('moveCard'))
|
||||
{
|
||||
var moveCardItems = [];
|
||||
@@ -1150,7 +1170,7 @@ function createCardMenu(options)
|
||||
moveCardItems = moveCardItems.reverse();
|
||||
items.push({label: kanbanLang.moveCard, icon: 'move', items: moveCardItems});
|
||||
}
|
||||
if(privs.includes('archiveCard') && kanban.archived == '1') items.push({label: kanbanLang.archiveCard, icon: 'card-archive', url: createLink('kanban', 'archiveCard', 'cardID=' + card.id), attrs: {'target': 'hiddenwin'}});
|
||||
|
||||
if(privs.includes('setCardColor'))
|
||||
{
|
||||
var cardColoritems = [];
|
||||
@@ -1164,7 +1184,6 @@ function createCardMenu(options)
|
||||
};
|
||||
items.push({label: kanbanLang.cardColor, icon: 'color', items: cardColoritems});
|
||||
}
|
||||
if(privs.includes('deleteCard')) items.push({label: card.fromType == '' ? kanbanLang.deleteCard : kanbanLang.removeCard, icon: card.fromType == '' ? 'trash' : 'unlink', url: createLink('kanban', 'deleteCard', 'cardID=' + card.id), attrs: {'target': 'hiddenwin'}});
|
||||
|
||||
var bounds = options.$trigger[0].getBoundingClientRect();
|
||||
items.$options = {x: bounds.right, y: bounds.top};
|
||||
@@ -1180,6 +1199,15 @@ function createColumnMenu(options)
|
||||
var items = [];
|
||||
if(privs.includes('setColumn')) items.push({label: kanbanLang.editColumn, icon: 'edit', url: createLink('kanban', 'setColumn', 'columnID=' + column.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('setWIP')) items.push({label: kanbanLang.setWIP, icon: 'alert', url: createLink('kanban', 'setWIP', 'columnID=' + column.id), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width' : '500px'}});
|
||||
|
||||
var basicActions = (privs.includes('setColumn') || privs.includes('setWIP')) ? true : false;
|
||||
var columnActions = (privs.includes('splitColumn') || privs.includes('createColumn') || privs.includes('copyColumn')) ? true : false;
|
||||
|
||||
if(basicActions && columnActions)
|
||||
{
|
||||
items.push({type: 'divider'});
|
||||
}
|
||||
|
||||
if(privs.includes('splitColumn')) items.push({label: kanbanLang.splitColumn, icon: 'col-split', url: createLink('kanban', 'splitColumn', 'columnID=' + column.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('createColumn'))
|
||||
{
|
||||
@@ -1187,6 +1215,13 @@ function createColumnMenu(options)
|
||||
items.push({label: kanbanLang.createColumnOnRight, icon: 'col-add-right', url: createLink('kanban', 'createColumn', 'columnID=' + column.id + '&position=right'), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
}
|
||||
if(privs.includes('copyColumn')) items.push({label: kanbanLang.copyColumn, icon: 'copy', url: createLink('kanban', 'copyColumn', 'columnID=' + column.id), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
|
||||
var otherActions = ((privs.includes('archiveColumn') && kanban.archived == '1') || privs.includes('deleteColumn')) ? true : false;
|
||||
if(columnActions && otherActions)
|
||||
{
|
||||
items.push({type: 'divider'});
|
||||
}
|
||||
|
||||
if(privs.includes('archiveColumn') && kanban.archived == '1') items.push({label: kanbanLang.archiveColumn, icon: 'card-archive', url: createLink('kanban', 'archiveColumn', 'columnID=' + column.id), attrs: {'target': 'hiddenwin'}});
|
||||
if(privs.includes('deleteColumn')) items.push({label: kanbanLang.deleteColumn, icon: 'trash', url: createLink('kanban', 'deleteColumn', 'columnID=' + column.id), attrs: {'target': 'hiddenwin'}});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
/* Actions. */
|
||||
$lang->kanban->noCard = 'No card';
|
||||
$lang->kanban->create = 'Create Kanban';
|
||||
$lang->kanban->createSpace = 'Create Space';
|
||||
$lang->kanban->editSpace = 'Edit Space';
|
||||
@@ -80,6 +81,7 @@ $lang->kanban->importBuild = 'Build';
|
||||
$lang->kanban->allKanban = 'All Kanban';
|
||||
$lang->kanban->allProjects = 'All ' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : 'Projects');
|
||||
$lang->kanban->allProducts = 'All Products';
|
||||
$lang->kanban->mine = 'Mine';
|
||||
|
||||
/* Fields. */
|
||||
$lang->kanban->space = 'Space';
|
||||
@@ -99,7 +101,8 @@ $lang->kanban->closed = 'Closed';
|
||||
$lang->kanban->closedBy = 'Closed By';
|
||||
$lang->kanban->closedDate = 'Closed Date';
|
||||
$lang->kanban->empty = 'No Kanban';
|
||||
$lang->kanban->teamSumCount = '%s people in total';
|
||||
$lang->kanban->teamSumCount = '%s Pers';
|
||||
$lang->kanban->cardsCount = '%s Card';
|
||||
$lang->kanban->cardCount = 'Card Count';
|
||||
$lang->kanban->activatedBy = 'Activated By';
|
||||
$lang->kanban->activatedDate = 'Activated Date';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
/* Actions. */
|
||||
$lang->kanban->noCard = '暂无卡片';
|
||||
$lang->kanban->create = '创建看板';
|
||||
$lang->kanban->createSpace = '创建空间';
|
||||
$lang->kanban->editSpace = '设置空间';
|
||||
@@ -80,6 +81,7 @@ $lang->kanban->importBuild = '版本';
|
||||
$lang->kanban->allKanban = '所有看板';
|
||||
$lang->kanban->allProjects = '所有' . ($this->config->systemMode == 'classic' ? $lang->executionCommon : '项目');
|
||||
$lang->kanban->allProducts = '所有产品';
|
||||
$lang->kanban->mine = '我负责';
|
||||
|
||||
/* Fields. */
|
||||
$lang->kanban->space = '所属空间';
|
||||
@@ -100,6 +102,7 @@ $lang->kanban->closedBy = '由谁关闭';
|
||||
$lang->kanban->closedDate = '关闭日期';
|
||||
$lang->kanban->empty = '暂时没有看板';
|
||||
$lang->kanban->teamSumCount = '共%s人';
|
||||
$lang->kanban->cardsCount = '共%s张卡片';
|
||||
$lang->kanban->cardCount = '卡片数量';
|
||||
$lang->kanban->activatedBy = '由谁激活';
|
||||
$lang->kanban->activatedDate = '激活日期';
|
||||
|
||||
+43
-14
@@ -1415,7 +1415,6 @@ 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;
|
||||
@@ -1423,7 +1422,6 @@ class kanbanModel extends model
|
||||
}
|
||||
else
|
||||
{
|
||||
if($searchValue != '' and strpos($object->title, $searchValue) === false) continue;
|
||||
$cardData['title'] = $object->title;
|
||||
}
|
||||
|
||||
@@ -3072,28 +3070,41 @@ class kanbanModel extends model
|
||||
{
|
||||
$actions .= "<a data-toggle='dropdown' $btnColor class='btn btn-link dropdown-toggle setting' type='button'>" . '<i class="icon icon-cog-outline"></i> ' . $this->lang->kanban->setting . '</a>';
|
||||
$actions .= "<ul id='kanbanActionMenu' class='dropdown-menu text-left'>";
|
||||
if(common::hasPriv('kanban', 'createRegion') and $CRKanban) $actions .= '<li>' . html::a(helper::createLink('kanban', 'createRegion', "kanbanID=$kanban->id", '', true), '<i class="icon icon-plus"></i>' . $this->lang->kanban->createRegion, '', "class='iframe btn btn-link'") . '</li>';
|
||||
$importWidth = $this->app->getClientLang() == 'en' ? '700' : '550';
|
||||
if(common::hasPriv('kanban', 'import') and $CRKanban) $actions .= '<li>' . html::a(helper::createLink('kanban', 'import', "kanbanID=$kanban->id", '', true), '<i class="icon icon-import"></i>' . $this->lang->kanban->import, '', "class='iframe btn btn-link' data-width=$importWidth") . '</li>';
|
||||
if(common::hasPriv('kanban', 'enableArchived') and $CRKanban) $actions .= '<li>' . html::a(helper::createLink('kanban', 'enableArchived', "kanbanID=$kanban->id", '', true), '<i class="icon icon-card-archive"></i>' . $this->lang->kanban->archived, '', "class='iframe btn btn-link' data-width=400") . '</li>';
|
||||
|
||||
$columnActions = '';
|
||||
if(common::hasPriv('kanban', 'setColumnWidth') and $CRKanban) $columnActions .= '<li>' . html::a(helper::createLink('kanban', 'setColumnWidth', "kanbanID=$kanban->id", '', true), '<i class="icon icon-size-width"></i>' . $this->lang->kanban->columnWidth, '', "class='iframe btn btn-link' data-width=400") . '</li>';
|
||||
if($printSetHeightBtn and $CRKanban)
|
||||
{
|
||||
$width = $this->app->getClientLang() == 'en' ? '750' : '650';
|
||||
$actions .= '<li>' . html::a(helper::createLink('kanban', 'setLaneHeight', "kanbanID=$kanban->id", '', true), '<i class="icon icon-size-height"></i>' . $this->lang->kanban->laneHeight, '', "class='iframe btn btn-link' data-width='$width'") . '</li>';
|
||||
|
||||
$width = $this->app->getClientLang() == 'en' ? '750' : '650';
|
||||
$columnActions .= '<li>' . html::a(helper::createLink('kanban', 'setLaneHeight', "kanbanID=$kanban->id", '', true), '<i class="icon icon-size-height"></i>' . $this->lang->kanban->laneHeight, '', "class='iframe btn btn-link' data-width='$width'") . '</li>';
|
||||
}
|
||||
if(common::hasPriv('kanban', 'setColumnWidth') and $CRKanban) $actions .= '<li>' . html::a(helper::createLink('kanban', 'setColumnWidth', "kanbanID=$kanban->id", '', true), '<i class="icon icon-size-width"></i>' . $this->lang->kanban->columnWidth, '', "class='iframe btn btn-link' data-width=400") . '</li>';
|
||||
if(common::hasPriv('kanban', 'performable') and $CRKanban) $actions .= '<li>' . html::a(helper::createLink('kanban', 'performable', "kanbanID=$kanban->id", '', true), '<i class="icon icon-checked"></i>' . $this->lang->kanban->manageProgress, '', "class='iframe btn btn-link' data-width=40%") . '</li>';
|
||||
$actions .= $columnActions;
|
||||
|
||||
$commonActions = '';
|
||||
if(common::hasPriv('kanban', 'createRegion') and $CRKanban) $commonActions .= '<li>' . html::a(helper::createLink('kanban', 'createRegion', "kanbanID=$kanban->id", '', true), '<i class="icon icon-plus"></i>' . $this->lang->kanban->createRegion, '', "class='iframe btn btn-link'") . '</li>';
|
||||
$importWidth = $this->app->getClientLang() == 'en' ? '700' : '550';
|
||||
if(common::hasPriv('kanban', 'import') and $CRKanban) $commonActions .= '<li>' . html::a(helper::createLink('kanban', 'import', "kanbanID=$kanban->id", '', true), '<i class="icon icon-import"></i>' . $this->lang->kanban->import, '', "class='iframe btn btn-link' data-width=$importWidth") . '</li>';
|
||||
if(common::hasPriv('kanban', 'enableArchived') and $CRKanban) $commonActions .= '<li>' . html::a(helper::createLink('kanban', 'enableArchived', "kanbanID=$kanban->id", '', true), '<i class="icon icon-card-archive"></i>' . $this->lang->kanban->archived, '', "class='iframe btn btn-link' data-width=400") . '</li>';
|
||||
if(common::hasPriv('kanban', 'performable') and $CRKanban) $commonActions .= '<li>' . html::a(helper::createLink('kanban', 'performable', "kanbanID=$kanban->id", '', true), '<i class="icon icon-checked"></i>' . $this->lang->kanban->manageProgress, '', "class='iframe btn btn-link' data-width=40%") . '</li>';
|
||||
|
||||
if($columnActions and $commonActions)
|
||||
{
|
||||
$actions .= "<li class='divider'></li>";
|
||||
}
|
||||
$actions .= $commonActions;
|
||||
|
||||
$kanbanActions = '';
|
||||
if(common::hasPriv('kanban', 'edit')) $kanbanActions .= '<li>' . html::a(helper::createLink('kanban', 'edit', "kanbanID=$kanban->id", '', true), '<i class="icon icon-edit"></i>' . $this->lang->kanban->edit, '', "class='iframe btn btn-link' data-width='75%'") . '</li>';
|
||||
if(common::hasPriv('kanban', 'close') and $kanban->status == 'active') $kanbanActions .= '<li>' . html::a(helper::createLink('kanban', 'close', "kanbanID=$kanban->id", '', true), '<i class="icon icon-off"></i>' . $this->lang->kanban->close, '', "class='iframe btn btn-link'") . '</li>';
|
||||
if(common::hasPriv('kanban', 'activate') and $kanban->status == 'closed') $kanbanActions .= '<li>' . html::a(helper::createLink('kanban', 'activate', "kanbanID=$kanban->id", '', true), '<i class="icon icon-magic"></i>' . $this->lang->kanban->activate, '', "class='iframe btn btn-link'") . '</li>';
|
||||
if(common::hasPriv('kanban', 'delete')) $kanbanActions .= '<li>' . html::a(helper::createLink('kanban', 'delete', "kanbanID=$kanban->id"), '<i class="icon icon-trash"></i>' . $this->lang->kanban->delete, 'hiddenwin', "class='btn btn-link'") . '</li>';
|
||||
if($kanbanActions)
|
||||
|
||||
if($commonActions and $kanbanActions)
|
||||
{
|
||||
$actions .= $printRegionBtn ? "<li class='divider'></li>" . $kanbanActions : $kanbanActions;
|
||||
$actions .= "<li class='divider'></li>";
|
||||
}
|
||||
$actions .= $kanbanActions;
|
||||
|
||||
$actions .= "</ul>";
|
||||
}
|
||||
|
||||
@@ -3431,11 +3442,29 @@ class kanbanModel extends model
|
||||
*/
|
||||
public function getGroupBySpaceList($spaceIdList, $kanbanIdList = '')
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_KANBAN)
|
||||
$spaceList = $this->dao->select('*')->from(TABLE_KANBAN)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('space')->in($spaceIdList)
|
||||
->beginIF($kanbanIdList)->andWhere('id')->in($kanbanIdList)->fi()
|
||||
->fetchGroup('space', 'id');
|
||||
|
||||
$kanbanIDList = array();
|
||||
foreach($spaceList as $kanbanList) $kanbanIDList = array_merge_recursive($kanbanIDList, array_keys($kanbanList));
|
||||
$cardsCount = $this->dao->select('kanban, COUNT(*) as count')->from(TABLE_KANBANCARD)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('kanban')->in($kanbanIDList)
|
||||
->groupBy('kanban')
|
||||
->fetchPairs('kanban');
|
||||
|
||||
foreach($spaceList as $kanbanList)
|
||||
{
|
||||
foreach($kanbanList as $kanban)
|
||||
{
|
||||
$kanban->cardsCount = zget($cardsCount, $kanban->id, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return $spaceList;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,12 +40,12 @@
|
||||
<div class='spaceTitle pull-left'>
|
||||
<div><i class='icon-cube'></i></div>
|
||||
<div>
|
||||
<h4 title="<?php echo $space->name;?>">
|
||||
<p class='spaceName' title="<?php echo $space->name;?>">
|
||||
<?php if($space->status == 'closed'):?>
|
||||
<span class="label label-closed"><?php echo $lang->kanban->closed;?></span>
|
||||
<?php endif;?>
|
||||
<?php echo $space->name;?>
|
||||
</h4>
|
||||
</p>
|
||||
</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>
|
||||
@@ -72,6 +72,9 @@
|
||||
<div class='col' data-id='<?php echo $kanbanID?>'>
|
||||
<div class='panel' data-url='<?php echo $this->createLink('kanban', 'view', "kanbanID=$kanbanID");?>'>
|
||||
<div class='panel-heading'>
|
||||
<?php if($browseType == 'cooperation' and $kanban->owner == $this->app->user->account):?>
|
||||
<span class="label label-outline label-info kanban-label"><?php echo $lang->kanban->mine;?></span>
|
||||
<?php endif;?>
|
||||
<div class='kanban-name'>
|
||||
<?php if($kanban->status == 'closed'):?>
|
||||
<span class="label label-closed"><?php echo $lang->kanban->closed;?></span>
|
||||
@@ -158,7 +161,10 @@
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class='kanban-members-total pull-left'><?php echo sprintf($lang->kanban->teamSumCount, $teamCount);?></div>
|
||||
<?php $teamCountLang = ($teamCount > 1) ? $lang->kanban->teamSumCount : str_replace("Pers", "Person", $lang->kanban->teamSumCount);?>
|
||||
<div class='kanban-members-total pull-left'><?php echo sprintf($teamCountLang, $teamCount);?></div>
|
||||
<?php $cardsCount = ($kanban->cardsCount > 1) ? str_replace("Card", "Cards", $lang->kanban->cardsCount) : $lang->kanban->cardsCount;?>
|
||||
<div class='kanban-members-total pull-right'><?php echo empty($kanban->cardsCount) ? $lang->kanban->noCard : sprintf($cardsCount, $kanban->cardsCount);?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Regular → Executable
+8
-2
@@ -89,8 +89,14 @@ class messageModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
$moduleName = $objectType == 'case' ? 'testcase' : $objectType;
|
||||
$this->loadModel('mail')->sendmail($objectID, $actionID);
|
||||
if($objectType == 'feedback')
|
||||
{
|
||||
$this->loadModel('feedback')->sendmail($objectID, $actionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->loadModel('mail')->sendmail($objectID, $actionID);
|
||||
}
|
||||
|
||||
if(defined('RUN_MODE') and RUN_MODE == 'api') $config->requestType = $requestType;
|
||||
}
|
||||
|
||||
+20
-5
@@ -411,9 +411,12 @@ EOF;
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function task($type = 'assignedTo', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
public function task($type = 'assignedTo', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
$this->loadModel('task');
|
||||
$this->loadModel('execution');
|
||||
$queryID = ($type == 'bySearch') ? (int)$param : 0;
|
||||
|
||||
/* Save session. */
|
||||
if($this->app->viewType != 'json') $this->session->set('taskList', $this->app->getURI(true), 'execution');
|
||||
|
||||
@@ -430,9 +433,13 @@ EOF;
|
||||
{
|
||||
$tasks = $this->my->getAssignedByMe($this->app->user->account, 0, $pager, $sort, 0, 'task');
|
||||
}
|
||||
elseif($type == 'bySearch')
|
||||
{
|
||||
$tasks = $this->my->getTasksBySearch($this->app->user->account, 0, $pager, $sort, $queryID);
|
||||
}
|
||||
else
|
||||
{
|
||||
$tasks = $this->task->getUserTasks($this->app->user->account, $type, 0, $pager, $sort);
|
||||
$tasks = $this->task->getUserTasks($this->app->user->account, $type, 0, $pager, $sort, $queryID);
|
||||
}
|
||||
|
||||
$parents = array();
|
||||
@@ -473,6 +480,9 @@ EOF;
|
||||
/* Get the story language configuration. */
|
||||
$this->app->loadLang('story');
|
||||
|
||||
$actionURL = $this->createLink('my', $this->app->rawMethod, "mode=task&browseType=bySearch&queryID=myQueryID");
|
||||
$this->my->buildTaskSearchForm($queryID, $actionURL);
|
||||
|
||||
/* Assign. */
|
||||
$this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->task;
|
||||
$this->view->position[] = $this->lang->my->task;
|
||||
@@ -505,12 +515,13 @@ EOF;
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function bug($type = 'assignedTo', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
public function bug($type = 'assignedTo', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
/* Save session. load Lang. */
|
||||
$this->loadModel('bug');
|
||||
if($this->app->viewType != 'json') $this->session->set('bugList', $this->app->getURI(true), 'qa');
|
||||
$this->app->loadLang('bug');
|
||||
$queryID = ($type == 'bySearch') ? (int)$param : 0;
|
||||
if($this->app->viewType != 'json') $this->session->set('bugList', $this->app->getURI(true), 'qa');
|
||||
|
||||
/* Load pager. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
@@ -525,12 +536,16 @@ EOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
$bugs = $this->loadModel('bug')->getUserBugs($this->app->user->account, $type, $sort, 0, $pager);
|
||||
$bugs = $this->loadModel('bug')->getUserBugs($this->app->user->account, $type, $sort, 0, $pager, '', $queryID);
|
||||
}
|
||||
|
||||
$bugs = $this->bug->checkDelayedBugs($bugs);
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug', false);
|
||||
|
||||
|
||||
$actionURL = $this->createLink('my', $this->app->rawMethod, "mode=bug&browseType=bySearch&queryID=myQueryID");
|
||||
$this->my->buildBugSearchForm($queryID, $actionURL);
|
||||
|
||||
/* assign. */
|
||||
$this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->bug;
|
||||
$this->view->position[] = $this->lang->my->bug;
|
||||
|
||||
@@ -44,6 +44,7 @@ $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->byQuery = 'Search';
|
||||
|
||||
$lang->my->indexAction = 'My Index';
|
||||
$lang->my->calendarAction = 'My Calendar';
|
||||
|
||||
@@ -44,6 +44,7 @@ $lang->my->storyConcept = $config->URAndSR ? '默认需求概念组合' : '
|
||||
$lang->my->pri = '优先级';
|
||||
$lang->my->alert = '后续您可以点击右上方的头像,选择“个性化设置”修改信息。';
|
||||
$lang->my->assignedToMe = '指派给我';
|
||||
$lang->my->byQuery = '搜索';
|
||||
|
||||
$lang->my->indexAction = '地盘仪表盘';
|
||||
$lang->my->calendarAction = '我的日程';
|
||||
|
||||
@@ -458,4 +458,168 @@ class myModel extends model
|
||||
}
|
||||
return $cases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form for task page of work.
|
||||
*
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildTaskSearchForm($queryID, $actionURL)
|
||||
{
|
||||
$rawMethod = $this->app->rawMethod;
|
||||
$this->loadModel('execution');
|
||||
$this->app->loadConfig('execution');
|
||||
|
||||
$this->config->execution->search['module'] = $rawMethod . 'Task';
|
||||
$this->config->execution->search['actionURL'] = $actionURL;
|
||||
$this->config->execution->search['queryID'] = $queryID;
|
||||
|
||||
if($rawMethod == 'work')
|
||||
{
|
||||
unset($this->config->execution->search['fields']['closedReason']);
|
||||
unset($this->config->execution->search['fields']['closedBy']);
|
||||
unset($this->config->execution->search['fields']['canceledBy']);
|
||||
unset($this->config->execution->search['fields']['closedDate']);
|
||||
unset($this->config->execution->search['fields']['canceledDate']);
|
||||
}
|
||||
|
||||
$projects = $this->loadModel('project')->getPairsByProgram();
|
||||
$this->config->execution->search['params']['project']['values'] = $projects + array('all' => $this->lang->project->allProjects);
|
||||
|
||||
$executions = $this->execution->getPairs();
|
||||
$this->config->execution->search['params']['execution']['values'] = $executions + array('all' => $this->lang->execution->allExecutions);
|
||||
|
||||
$this->config->execution->search['params']['module']['values'] = $this->loadModel('tree')->getAllModulePairs();
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->execution->search);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tasks by search.
|
||||
*
|
||||
* @param string $account
|
||||
* @param int $limit
|
||||
* @param object $pager
|
||||
* @param string $orderBy
|
||||
* @param int $queryID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTasksBySearch($account, $limit = 0, $pager = null, $orderBy = 'id_desc', $queryID = 0)
|
||||
{
|
||||
$moduleName = $this->app->rawMethod == 'work' ? 'workTask' : 'contributeTask';
|
||||
$queryName = $moduleName . 'Query';
|
||||
$formName = $moduleName . 'Form';
|
||||
|
||||
$taskIDList = array();
|
||||
if($moduleName == 'contributeTask')
|
||||
{
|
||||
$tasksAssignedByMe = $this->getAssignedByMe($account, 0, $pager, $orderBy, 0, 'task');
|
||||
foreach($tasksAssignedByMe as $taskID => $task)
|
||||
{
|
||||
$taskIDList[$taskID] = $taskID;
|
||||
}
|
||||
}
|
||||
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set($queryName, $query->sql);
|
||||
$this->session->set($formName, $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set($queryName, ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
|
||||
}
|
||||
|
||||
$query = $this->session->$queryName;
|
||||
|
||||
$query = preg_replace('/`(\w+)`/', 't1.`$1`', $query);
|
||||
$query = str_replace('t1.`project`', 't2.`project`', $query);
|
||||
|
||||
$tasks = $this->dao->select('t1.*, t2.id as executionID, t2.name as executionName, t2.type as executionType, t3.id as storyID, t3.title as storyTitle, t3.status AS storyStatus, t3.version AS latestStoryVersion')
|
||||
->from(TABLE_TASK)->alias('t1')
|
||||
->leftJoin(TABLE_EXECUTION)->alias('t2')->on("t1.execution = t2.id")
|
||||
->leftJoin(TABLE_STORY)->alias('t3')->on('t1.story = t3.id')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t4')->on("t1.project = t4.id")
|
||||
->where($query)
|
||||
->andWhere('t1.deleted')->eq(0)
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->andWhere('(t2.status')->ne('suspended')->orWhere('t4.status')->ne('suspended')->markRight(1)
|
||||
->beginIF($moduleName == 'workTask')->andWhere("t1.assignedTo")->eq($account)
|
||||
->beginIF($moduleName == 'contributeTask')
|
||||
->andWhere('t1.openedBy', 1)->eq($account)
|
||||
->orWhere('t1.closedBy')->eq($account)
|
||||
->orWhere('t1.canceledBy')->eq($account)
|
||||
->orWhere('t1.finishedby', 1)->eq($account)
|
||||
->orWhere('t1.finishedList')->like("%,{$account},%")
|
||||
->orWhere('t1.id')->in($taskIDList)
|
||||
->markRight(1)
|
||||
->fi()
|
||||
->beginIF($this->config->vision)->andWhere('t1.vision')->eq($this->config->vision)->fi()
|
||||
->beginIF($this->config->vision)->andWhere('t2.vision')->eq($this->config->vision)->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t1.execution')->in($this->app->user->view->sprints)->fi()
|
||||
->orderBy($orderBy)
|
||||
->beginIF($limit > 0)->limit($limit)->fi()
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'task', false);
|
||||
|
||||
$taskTeam = $this->dao->select('*')->from(TABLE_TEAM)->where('root')->in(array_keys($tasks))->andWhere('type')->eq('task')->fetchGroup('root');
|
||||
if(!empty($taskTeam))
|
||||
{
|
||||
foreach($taskTeam as $taskID => $team) $tasks[$taskID]->team = $team;
|
||||
}
|
||||
|
||||
if($tasks) return $this->loadModel('task')->processTasks($tasks);
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form for bug page of work.
|
||||
*
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildBugSearchForm($queryID, $actionURL)
|
||||
{
|
||||
$rawMethod = $this->app->rawMethod;
|
||||
$this->loadModel('bug');
|
||||
$this->app->loadConfig('bug');
|
||||
|
||||
$products = $this->loadModel('product')->getPairs();
|
||||
|
||||
$this->config->bug->search['module'] = $rawMethod . 'Bug';
|
||||
$this->config->bug->search['actionURL'] = $actionURL;
|
||||
$this->config->bug->search['queryID'] = $queryID;
|
||||
if($rawMethod == 'work')
|
||||
{
|
||||
unset($this->config->bug->search['fields']['closedDate']);
|
||||
unset($this->config->bug->search['fields']['closedBy']);
|
||||
}
|
||||
|
||||
if($this->config->systemMode == 'new') $this->config->bug->search['params']['project']['values'] = $this->loadModel('project')->getPairsByProgram() + array('all' => $this->lang->bug->allProject) + array('' => '');
|
||||
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('execution')->getPairs();
|
||||
$this->config->bug->search['params']['product']['values'] = $products + array('' => '');
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs();
|
||||
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getAllModulePairs();
|
||||
$this->config->bug->search['params']['severity']['values'] = array(0 => '') + $this->lang->bug->severityList;
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($products);
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->bug->search);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,23 @@
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=closedBy"), "<span class='text'>{$lang->bug->closedByMe}</span>" . ($type == 'closedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'closedBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=assignedBy"), "<span class='text'>{$lang->bug->assignedByMe}</span>" . ($type == 'assignedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'assignedBy' ? ' btn-active-text' : '') . "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=assignedTo"), "<span class='text'>{$lang->bug->assignedToMe}</span>" . ($type == 'assignedTo' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'assignedTo' ? ' btn-active-text' : '') . "'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->my->byQuery;?></a>
|
||||
</div>
|
||||
<div id="mainContent">
|
||||
<?php $dataModule = $app->rawMethod == 'work' ? 'workBug' : 'contributeBug';?>
|
||||
<?php if(empty($bugs)):?>
|
||||
<div class="cell<?php if($type == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo $dataModule;?>></div>
|
||||
<div class="table-empty-tip">
|
||||
<p><span class="text-muted"><?php echo $lang->bug->noBug;?></span></p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class="cell<?php if($type == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo $dataModule;?>></div>
|
||||
<form id='myBugForm' class="main-table table-bug" data-ride="table" method="post" action='<?php echo $this->createLink('bug', 'batchEdit', "productID=0");?>'>
|
||||
<?php
|
||||
$canBatchEdit = (common::hasPriv('bug', 'batchEdit') and $type == 'assignedTo');
|
||||
@@ -43,7 +51,7 @@
|
||||
$canBatchAction = ($canBatchEdit or $canBatchConfirm or $canBatchClose or $canBatchAssignTo);
|
||||
?>
|
||||
<table class="table has-sort-head table-fixed" id='bugList'>
|
||||
<?php $vars = "mode=$mode&type=$type&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
|
||||
<?php $vars = "mode=$mode&type=$type¶m=myQueryID&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="c-id">
|
||||
|
||||
@@ -18,29 +18,38 @@
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php $recTotalLabel = " <span class='label label-light label-badge'>{$pager->recTotal}</span>"; ?>
|
||||
<?php if($app->rawMethod == 'contribute'):?>
|
||||
<?php
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=openedBy"), "<span class='text'>{$lang->my->taskMenu->openedByMe}</span>" . ($type == 'openedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'openedBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=finishedBy"), "<span class='text'>{$lang->my->taskMenu->finishedByMe}</span>" . ($type == 'finishedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'finishedBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=closedBy"), "<span class='text'>{$lang->my->taskMenu->closedByMe}</span>" . ($type == 'closedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'closedBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=canceledBy"), "<span class='text'>{$lang->my->taskMenu->canceledByMe}</span>" . ($type == 'canceledBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'canceledBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=assignedBy"), "<span class='text'>{$lang->my->taskMenu->assignedByMe}</span>" . ($type == 'assignedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'assignedBy' ? ' btn-active-text' : '') . "'");
|
||||
if($app->rawMethod == 'contribute')
|
||||
{
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=openedBy"), "<span class='text'>{$lang->my->taskMenu->openedByMe}</span>" . ($type == 'openedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'openedBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=finishedBy"), "<span class='text'>{$lang->my->taskMenu->finishedByMe}</span>" . ($type == 'finishedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'finishedBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=closedBy"), "<span class='text'>{$lang->my->taskMenu->closedByMe}</span>" . ($type == 'closedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'closedBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=canceledBy"), "<span class='text'>{$lang->my->taskMenu->canceledByMe}</span>" . ($type == 'canceledBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'canceledBy' ? ' btn-active-text' : '') . "'");
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=assignedBy"), "<span class='text'>{$lang->my->taskMenu->assignedByMe}</span>" . ($type == 'assignedBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'assignedBy' ? ' btn-active-text' : '') . "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
echo html::a(inlink($app->rawMethod, "mode=$mode&type=assignedTo"), "<span class='text'>{$lang->my->taskMenu->assignedToMe}</span>" . ($type == 'assignedTo' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'assignedTo' ? ' btn-active-text' : '') . "'");
|
||||
}
|
||||
?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->my->byQuery;?></a>
|
||||
</div>
|
||||
<div id="mainContent">
|
||||
<?php $dataModule = $app->rawMethod == 'work' ? 'workTask' : 'contributeTask';?>
|
||||
<?php if(empty($tasks)):?>
|
||||
<div class="cell<?php if($type == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo $dataModule;?>></div>
|
||||
<div class="table-empty-tip">
|
||||
<p><span class="text-muted"><?php echo $lang->task->noTask;?></span></p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class="cell<?php if($type == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo $dataModule;?>></div>
|
||||
<form id='myTaskForm' class="main-table table-task skip-iframe-modal" method="post">
|
||||
<?php $canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');?>
|
||||
<?php $canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');?>
|
||||
<div class="table-responsive">
|
||||
<table class="table has-sort-head table-fixed" id='taskTable'>
|
||||
<?php $vars = "mode=$mode&type=$type&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
|
||||
<?php $vars = "mode=$mode&type=$type¶m=myQueryID&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="c-id">
|
||||
|
||||
@@ -38,3 +38,4 @@ $lang->personnel->copy = 'Copy Whitelist';
|
||||
|
||||
$lang->personnel->openedPGMTip = 'The program is public and can be accessed by users with Program privileges.';
|
||||
$lang->personnel->selectObjectTips = 'Select %s to copy its whitelist';
|
||||
$lang->personnel->countTip = ' (%s member)';
|
||||
|
||||
@@ -38,3 +38,4 @@ $lang->personnel->copy = 'Copy Whitelist';
|
||||
|
||||
$lang->personnel->openedPGMTip = 'The program is public and can be accessed by users with Program privileges.';
|
||||
$lang->personnel->selectObjectTips = 'Select %s to copy its whitelist';
|
||||
$lang->personnel->countTip = ' (%s member)';
|
||||
|
||||
@@ -38,3 +38,4 @@ $lang->personnel->copy = 'Copy Whitelist';
|
||||
|
||||
$lang->personnel->openedPGMTip = 'The program is public and can be accessed by users with Program privileges.';
|
||||
$lang->personnel->selectObjectTips = 'Select %s to copy its whitelist';
|
||||
$lang->personnel->countTip = ' (%s member)';
|
||||
|
||||
@@ -38,3 +38,4 @@ $lang->personnel->copy = 'Copy Whitelist';
|
||||
|
||||
$lang->personnel->openedPGMTip = 'The program is public and can be accessed by users with Program privileges.';
|
||||
$lang->personnel->selectObjectTips = 'Select %s to copy its whitelist';
|
||||
$lang->personnel->countTip = ' (%s member)';
|
||||
|
||||
@@ -38,3 +38,4 @@ $lang->personnel->copy = '复制白名单';
|
||||
|
||||
$lang->personnel->openedPGMTip = '该项目集是公开状态,有项目集视图权限的人员即可访问。';
|
||||
$lang->personnel->selectObjectTips = '请选择一个%s白名单来复制';
|
||||
$lang->personnel->countTip = '(%s人)';
|
||||
|
||||
@@ -38,3 +38,4 @@ $lang->personnel->copy = '複製白名單';
|
||||
|
||||
$lang->personnel->openedPGMTip = '該項目集是公開狀態,有項目集視圖權限的人員即可訪問。';
|
||||
$lang->personnel->selectObjectTips = '請選擇一個%s白名單來複制';
|
||||
$lang->personnel->countTip = '(%s人)';
|
||||
|
||||
@@ -466,10 +466,11 @@ class personnelModel extends model
|
||||
*
|
||||
* @param int $objectID
|
||||
* @param int $objectType
|
||||
* @param bool $addCount
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCopiedObjects($objectID, $objectType)
|
||||
public function getCopiedObjects($objectID, $objectType, $addCount = false)
|
||||
{
|
||||
$objects = array();
|
||||
|
||||
@@ -512,6 +513,28 @@ class personnelModel extends model
|
||||
}
|
||||
|
||||
unset($objects[$objectID]);
|
||||
|
||||
if($addCount)
|
||||
{
|
||||
$objectType = $objectType == 'sprint' ? 'execution' : $objectType;
|
||||
$countPairs = $this->dao->select('root, COUNT(*) as count')->from(TABLE_TEAM)
|
||||
->where('type')->eq($objectType)
|
||||
->andWhere('root')->in(array_keys($objects))
|
||||
->beginIF($objectType == 'execution')
|
||||
->orWhere('( type')->eq('project')
|
||||
->andWhere('root')->eq($parentID)->markRight(1)
|
||||
->fi()
|
||||
->groupBy('root')
|
||||
->fetchPairs('root');
|
||||
|
||||
foreach($objects as $objectID => $objectName)
|
||||
{
|
||||
$memberCount = zget($countPairs, $objectID, 0);
|
||||
$countTip = $memberCount > 1 ? str_replace('member', 'members', $this->lang->personnel->countTip) : $this->lang->personnel->countTip;
|
||||
$objects[$objectID] = $objectName . sprintf($countTip, $memberCount);
|
||||
}
|
||||
}
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ $config->product->search['fields']['estimate'] = $lang->story->estimate;
|
||||
$config->product->search['fields']['source'] = $lang->story->source;
|
||||
$config->product->search['fields']['sourceNote'] = $lang->story->sourceNote;
|
||||
$config->product->search['fields']['fromBug'] = $lang->story->fromBug;
|
||||
$config->product->search['fields']['category'] = $lang->story->category;
|
||||
|
||||
$config->product->search['fields']['openedBy'] = $lang->story->openedBy;
|
||||
$config->product->search['fields']['reviewedBy'] = $lang->story->reviewedBy;
|
||||
@@ -68,6 +69,7 @@ $config->product->search['params']['estimate'] = array('operator' => '=',
|
||||
$config->product->search['params']['source'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->story->sourceList);
|
||||
$config->product->search['params']['sourceNote'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->product->search['params']['fromBug'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
$config->product->search['params']['category'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->story->categoryList);
|
||||
|
||||
$config->product->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->product->search['params']['reviewedBy'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users');
|
||||
|
||||
@@ -30,6 +30,6 @@ $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']['status'] = array('operator' => '=', 'control' => 'select', 'values' => array('' => '') + $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');
|
||||
|
||||
@@ -1455,7 +1455,7 @@ class project extends control
|
||||
$this->view->depts = array('' => '') + $this->dept->getOptionMenu();
|
||||
$this->view->currentMembers = $currentMembers;
|
||||
$this->view->members2Import = $members2Import;
|
||||
$this->view->teams2Import = array('' => '') + $this->loadModel('personnel')->getCopiedObjects($projectID, 'project');
|
||||
$this->view->teams2Import = array('' => '') + $this->loadModel('personnel')->getCopiedObjects($projectID, 'project', true);
|
||||
$this->view->copyProjectID = $copyProjectID;
|
||||
$this->display();
|
||||
}
|
||||
@@ -1993,4 +1993,20 @@ class project extends control
|
||||
}
|
||||
echo json_encode($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: get executions of a project in html select.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param int $executionID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetExecutions($projectID, $executionID = 0)
|
||||
{
|
||||
$executions = array('' => '') + $this->loadModel('execution')->getPairs($projectID, 'all');
|
||||
|
||||
if($this->app->getViewType() == 'json') return print(json_encode($executionList));
|
||||
return print(html::select('execution', $executions, $executionID, "class='form-control'"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ $lang->project->workdaysExceed = 'No more than『%s』working days';
|
||||
$lang->project->teamMembersCount = ', there are %s team members.';
|
||||
$lang->project->budgetNumber = '『Budget』must be numbers.';
|
||||
$lang->project->budgetGe0 = '『Budget』must be greater than or equal to 0.';
|
||||
$lang->project->allProjects = 'All Projects';
|
||||
|
||||
/* Fields. */
|
||||
$lang->project->common = 'Project';
|
||||
|
||||
@@ -62,6 +62,7 @@ $lang->project->workdaysExceed = '可用工作日不能超过『%s』天';
|
||||
$lang->project->teamMembersCount = ',团队成员共%s人。';
|
||||
$lang->project->budgetNumber = '『预算』金额必须为数字。';
|
||||
$lang->project->budgetGe0 = '『预算』金额必须大于等于0。';
|
||||
$lang->project->allProjects = '所有项目';
|
||||
|
||||
/* Fields. */
|
||||
$lang->project->common = '项目';
|
||||
|
||||
@@ -98,7 +98,7 @@ $lang->story->sourceNote = '来源备注';
|
||||
$lang->story->fromBug = '来源Bug';
|
||||
$lang->story->title = "{$lang->SRCommon}名称";
|
||||
$lang->story->type = "需求类型";
|
||||
$lang->story->category = "类型";
|
||||
$lang->story->category = "类别";
|
||||
$lang->story->color = '标题颜色';
|
||||
$lang->story->toBug = '转Bug';
|
||||
$lang->story->spec = "描述";
|
||||
|
||||
@@ -2986,7 +2986,7 @@ class storyModel extends model
|
||||
->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()
|
||||
->orderBy('t1.`order` desc')
|
||||
->orderBy('t1.`order` desc, t1.`story` desc')
|
||||
->fetchAll('id');
|
||||
return empty($stories) ? array() : $this->formatStories($stories, $type);
|
||||
}
|
||||
|
||||
@@ -5,3 +5,6 @@
|
||||
.pull-left{max-width: 80%;}
|
||||
.MRThWidth {width: 90px !important;}
|
||||
.btn-edit-comment {z-index: 100;}
|
||||
|
||||
#assignedTo a {border-color: transparent;}
|
||||
#assignedTo a:hover {border-color: rgba(0,0,0,.2);}
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
<th class='w-40px'> <?php echo $lang->task->lblPri;?></th>
|
||||
<th> <?php echo $lang->task->name;?></th>
|
||||
<th class='w-100px'><?php echo $lang->task->deadline;?></th>
|
||||
<th class='w-80px'> <?php echo $lang->task->assignedTo;?></th>
|
||||
<th class='w-120px'> <?php echo $lang->task->assignedTo;?></th>
|
||||
<th class='w-80px'> <?php echo $lang->task->status;?></th>
|
||||
<th class='w-60px visible-lg'><?php echo $lang->task->consumedAB . $lang->task->lblHour;?></th>
|
||||
<th class='w-60px visible-lg'><?php echo $lang->task->leftAB . $lang->task->lblHour;?></th>
|
||||
@@ -132,13 +132,12 @@
|
||||
</td>
|
||||
<td class='text-left' title='<?php echo $child->name;?>'><a class="iframe" data-width="90%" href="<?php echo $this->createLink('task', 'view', "taskID=$child->id", '', true); ?>"><?php echo $child->name;?></a></td>
|
||||
<td><?php echo $child->deadline;?></td>
|
||||
<td><?php echo zget($users, $child->assignedTo);?></td>
|
||||
<td id='assignedTo'><?php $this->task->printAssignedHtml($child, $users);?></td>
|
||||
<td><?php echo $this->processStatus('task', $child);?></td>
|
||||
<td class='visible-lg'><?php echo $child->consumed;?></td>
|
||||
<td class='visible-lg'><?php echo $child->left;?></td>
|
||||
<td class='c-actions'>
|
||||
<?php
|
||||
common::printIcon('task', 'assignTo', "executionID=$child->execution&taskID=$child->id", $child, 'list', '', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('task', 'activate', "taskID=$child->id", $child, 'list', '', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe showinonlybody', true);
|
||||
|
||||
@@ -652,6 +652,9 @@ class upgradeModel extends model
|
||||
case 'biz7.0.beta1':
|
||||
$this->processViewFields();
|
||||
break;
|
||||
case 'biz7.0':
|
||||
$this->processFlowPosition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -943,7 +946,8 @@ class upgradeModel extends model
|
||||
case '16_5_beta1': $confirmContent .= file_get_contents($this->getUpgradeFile('16.5.beta1'));
|
||||
case '16_5': $confirmContent .= file_get_contents($this->getUpgradeFile('16.5'));
|
||||
case '17_0_beta1': $confirmContent .= file_get_contents($this->getUpgradeFile('17.0.beta1'));
|
||||
case '17_0_beta2':
|
||||
case '17_0_beta2': $confirmContent .= file_get_contents($this->getUpgradeFile('17.0.beta2'));
|
||||
case '17_0': $confirmContent .= file_get_contents($this->getUpgradeFile('17.0'));
|
||||
}
|
||||
|
||||
return $confirmContent;
|
||||
|
||||
@@ -136,6 +136,9 @@ class userModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the current user first. */
|
||||
$users = $this->processAccountSort($users);
|
||||
|
||||
/* Append empty, closed, and guest users. */
|
||||
if(strpos($params, 'noempty') === false) $users = array('' => '') + $users;
|
||||
if(strpos($params, 'noclosed') === false) $users = $users + array('closed' => 'Closed');
|
||||
@@ -2623,6 +2626,10 @@ class userModel extends model
|
||||
if(!empty($this->config->isINT)) $firstLetter = '';
|
||||
$users[$account] = $firstLetter . ($user->realname ? $user->realname : $user->account);
|
||||
}
|
||||
|
||||
/* Put the current user first. */
|
||||
$users = $this->processAccountSort($users);
|
||||
|
||||
return array('' => '') + $users;
|
||||
}
|
||||
|
||||
@@ -2828,4 +2835,23 @@ class userModel extends model
|
||||
$admins = explode(',', trim($company->admins, ','));
|
||||
$this->app->user = $this->dao->select('*')->from(TABLE_USER)->where('account')->eq($admins[0])->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the current user first.
|
||||
*
|
||||
* @param array $users
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function processAccountSort($users = array())
|
||||
{
|
||||
if(isset($users[$this->app->user->account]))
|
||||
{
|
||||
$currentUser = array();
|
||||
$currentUser[$this->app->user->account] = $users[$this->app->user->account];
|
||||
unset($users[$this->app->user->account]);
|
||||
$users = $currentUser + $users;
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* ZUI: ZUI Kanban View - v1.10.0 - 2022-06-02
|
||||
* ZUI: ZUI Kanban View - v1.10.0 - 2022-06-08
|
||||
* http://openzui.com
|
||||
* GitHub: https://github.com/easysoft/zui.git
|
||||
* Copyright (c) 2022 cnezsoft.com; Licensed MIT
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user