Merge branch 'sgm_dropmenu' into 'kanban'
* Code for kanban drop menu. See merge request easycorp/zentaopms!882
This commit is contained in:
@@ -184,6 +184,9 @@ class kanban extends control
|
||||
public function view($kanbanID)
|
||||
{
|
||||
$kanban = $this->kanban->getByID($kanbanID);
|
||||
$space = $this->kanban->getSpaceByID($kanban->space);
|
||||
|
||||
$this->kanban->setSwitcher($kanban);
|
||||
$this->kanban->setHeaderActions($kanban);
|
||||
|
||||
$this->view->title = $this->lang->kanban->view;
|
||||
@@ -404,4 +407,28 @@ class kanban extends control
|
||||
|
||||
return print(html::select('team[]', $users, $list->userList, "class='form-control chosen' multiple"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get kanban menu.
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetKanbanMenu($kanbanID, $moduleName, $methodName)
|
||||
{
|
||||
$kanbanIdList = $this->kanban->getCanViewObjects();
|
||||
$this->view->kanbanList = $this->dao->select('*')->from(TABLE_KANBAN)
|
||||
->where('deleted')->eq('0')
|
||||
->andWhere('id')->in($kanbanIdList)
|
||||
->fetchGroup('space');
|
||||
|
||||
$this->view->kanbanID = $kanbanID;
|
||||
$this->view->spaceList = $this->kanban->getSpacePairs('all');
|
||||
$this->view->module = $moduleName;
|
||||
$this->view->method = $methodName;
|
||||
$this->display();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ $lang->kanban->closedDate = 'Closed Date';
|
||||
$lang->kanban->empty = 'No Kanban';
|
||||
$lang->kanban->teamSumCount = '%s people in total';
|
||||
|
||||
|
||||
$lang->kanban->aclList['open'] = 'Open (Accessible with space view permissions)';
|
||||
$lang->kanban->aclList['private'] = 'Private (For the kanban team, whitelist members and space owner only)';
|
||||
|
||||
@@ -110,6 +109,8 @@ $lang->kanban->noGroup = 'None';
|
||||
$lang->kanban->limitExceeded = 'Limit Exceeded';
|
||||
$lang->kanban->fullScreen = 'Full Screen';
|
||||
$lang->kanban->setting = 'Setting';
|
||||
$lang->kanban->my = 'My';
|
||||
$lang->kanban->other = 'Other';
|
||||
|
||||
$lang->kanban->error = new stdclass();
|
||||
$lang->kanban->error->mustBeInt = 'The WIPs must be positive integer.';
|
||||
@@ -205,4 +206,4 @@ $lang->kanbanregion = new stdclass();
|
||||
$lang->kanbanregion->name = 'Kanban Region';
|
||||
$lang->kanbanregion->default = 'Default Region';
|
||||
|
||||
$lang->kanbancard = new stdclass();
|
||||
$lang->kanbancard = new stdclass();
|
||||
|
||||
@@ -109,6 +109,8 @@ $lang->kanban->noGroup = '无';
|
||||
$lang->kanban->limitExceeded = '超出在制品限制';
|
||||
$lang->kanban->fullScreen = '全屏';
|
||||
$lang->kanban->setting = '设置';
|
||||
$lang->kanban->my = '我的看板';
|
||||
$lang->kanban->other = '其他';
|
||||
|
||||
$lang->kanban->error = new stdclass();
|
||||
$lang->kanban->error->mustBeInt = '在制品数量必须是正整数。';
|
||||
|
||||
+56
-33
@@ -403,34 +403,6 @@ class kanbanModel extends model
|
||||
return $columnData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set kanban headerActions.
|
||||
*
|
||||
* @param object $kanban
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function setHeaderActions($kanban)
|
||||
{
|
||||
$actions = '';
|
||||
$actions .= "<div class='btn-group'>";
|
||||
$actions .= "<a href='javascript:fullScreen();' id='fullScreenBtn' class='btn btn-link'><i class='icon icon-fullscreen'></i> {$this->lang->kanban->fullScreen}</a>";
|
||||
$actions .= "<a data-toggle='dropdown' class='btn btn-link dropdown-toggle' 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')) $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>';
|
||||
|
||||
$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'") . '</li>';
|
||||
if(common::hasPriv('kanban', 'close')) $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', '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) $actions .= "<div class='divider'></div>" . $kanbanActions;
|
||||
|
||||
$actions .= "</ul>";
|
||||
$actions .= "</div>";
|
||||
|
||||
$this->lang->headerActions = $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Kanban by execution id.
|
||||
*
|
||||
@@ -613,16 +585,17 @@ class kanbanModel extends model
|
||||
/**
|
||||
* Get can view objects.
|
||||
*
|
||||
* @param string $objectType space|kanban
|
||||
* @param string $objectType kanbanspace|kanban
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCanViewObjects($objectType)
|
||||
public function getCanViewObjects($objectType = 'kanban')
|
||||
{
|
||||
$table = $this->config->objectTables[$objectType];
|
||||
$objects = $this->dao->select('*')->from($table)->fetchAll('id');
|
||||
$table = $this->config->objectTables[$objectType];
|
||||
$objects = $this->dao->select('*')->from($table)->fetchAll('id');
|
||||
$spaceOwnerPairs = $this->dao->select('id,owner')->from(TABLE_KANBANSPACE)->fetchPairs();
|
||||
|
||||
if($this->app->user->admin) return $objects;
|
||||
if($this->app->user->admin) return array_keys($objects);
|
||||
|
||||
$account = $this->app->user->account;
|
||||
foreach($objects as $objectID => $object)
|
||||
@@ -630,6 +603,7 @@ class kanbanModel extends model
|
||||
if($object->acl == 'private')
|
||||
{
|
||||
$aclUsers = $object->owner . $object->team . $object->whitelist;
|
||||
if($objectType == 'kanban') $aclUsers .= ',' . $spaceOwnerPairs[$object->space];
|
||||
if(strpos(",$aclUsers,", ",$account,") === false) unset($objects[$objectID]);
|
||||
}
|
||||
}
|
||||
@@ -1424,6 +1398,55 @@ class kanbanModel extends model
|
||||
return dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set kanban headerActions.
|
||||
*
|
||||
* @param object $kanban
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function setHeaderActions($kanban)
|
||||
{
|
||||
$actions = '';
|
||||
$actions .= "<div class='btn-group'>";
|
||||
$actions .= "<a href='javascript:fullScreen();' id='fullScreenBtn' class='btn btn-link'><i class='icon icon-fullscreen'></i> {$this->lang->kanban->fullScreen}</a>";
|
||||
$actions .= "<a data-toggle='dropdown' class='btn btn-link dropdown-toggle' 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')) $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>';
|
||||
|
||||
$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'") . '</li>';
|
||||
if(common::hasPriv('kanban', 'close')) $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', '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) $actions .= "<div class='divider'></div>" . $kanbanActions;
|
||||
|
||||
$actions .= "</ul>";
|
||||
$actions .= "</div>";
|
||||
|
||||
$this->lang->headerActions = $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set switcher menu.
|
||||
*
|
||||
* @param object $kanban
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function setSwitcher($kanban)
|
||||
{
|
||||
$currentModule = $this->app->getModuleName();
|
||||
$currentMethod = $this->app->getMethodName();
|
||||
|
||||
$kanbanLink = helper::createLink('kanban', 'ajaxGetKanbanMenu', "objectID=$kanban->id&module=$currentModule&method=$currentMethod");
|
||||
|
||||
$switcher = "<div class='btn-group header-btn' id='swapper'><button data-toggle='dropdown' type='button' class='btn' id='currentItem' title='{$kanban->name}'><span class='text'>{$kanban->name}</span> <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$kanbanLink'>";
|
||||
$switcher .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$switcher .= "</div></div>";
|
||||
|
||||
$this->lang->switcherMenu = $switcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset order of lane.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php js::set('module', $module);?>
|
||||
<?php js::set('method', $method);?>
|
||||
<style>
|
||||
#navTabs {position: sticky; top: 0; background: #fff; z-index: 950;}
|
||||
#navTabs>li {padding: 0px 10px; display: inline-block}
|
||||
#navTabs>li>span {display: inline-block;}
|
||||
#navTabs>li>a {padding: 8px 0px; display: inline-block}
|
||||
#navTabs>li.active>a {font-weight: 700; color: #0c64eb;}
|
||||
#navTabs>li.active>a:before {position: absolute; right: 0; bottom: -1px; left: 0; display: block; height: 2px; content: ' '; background: #0c64eb;}
|
||||
#navTabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover {border: none;}
|
||||
|
||||
#tabContent {margin-top: 10px; z-index: 900;}
|
||||
.kanbanTree ul {list-style: none; margin: 0}
|
||||
.kanbanTree .kanbans>ul {padding-left: 7px;}
|
||||
.kanbanTree .kanbans>ul>li>div {display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center;}
|
||||
.kanbanTree .kanbans>ul>li label {background: rgba(255,255,255,0.5); line-height: unset; color: #838a9d; border: 1px solid #d8d8d8; border-radius: 2px; padding: 1px 4px;}
|
||||
.kanbanTree li a i.icon {font-size: 15px !important;}
|
||||
.kanbanTree li a i.icon:before {min-width: 16px !important;}
|
||||
.kanbanTree li .label {position: unset; margin-bottom: 0;}
|
||||
.kanbanTree li>a, div.hide-in-search>a {display: block; padding: 2px 10px 2px 5px; overflow: hidden; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; border-radius: 4px;}
|
||||
.kanbanTree li>a.selected {color: #e9f2fb; background-color: #0c64eb;}
|
||||
.kanbanTree .tree li>.list-toggle {line-height: 24px;}
|
||||
.kanbanTree .tree li.has-list.open:before {content: unset;}
|
||||
|
||||
#swapper li>div.hide-in-search>a:focus, #swapper li>div.hide-in-search>a:hover {color: #838a9d; cursor: default;}
|
||||
a.kanbanName:focus, a.kanbanName:hover {background: #0c64eb; color: #fff !important;}
|
||||
|
||||
#swapper li > a {padding-top: 4px; padding-bottom: 4px;}
|
||||
#swapper li {padding-top: 0; padding-bottom: 0;}
|
||||
#swapper .tree li>.list-toggle {top: -1px;}
|
||||
</style>
|
||||
<?php
|
||||
$kanbanCounts = array();
|
||||
$kanbanNames = array();
|
||||
$tabActive = '';
|
||||
$myKanbans = 0;
|
||||
$others = 0;
|
||||
$dones = 0;
|
||||
|
||||
foreach($kanbanList as $spaceID => $spaceKanbans)
|
||||
{
|
||||
$kanbanCounts[$spaceID]['myKanban'] = 0;
|
||||
$kanbanCounts[$spaceID]['others'] = 0;
|
||||
$kanbanCounts[$spaceID]['closed'] = 0;
|
||||
|
||||
foreach($spaceKanbans as $kanban)
|
||||
{
|
||||
if($kanban->status != 'closed' and $kanban->owner == $this->app->user->account) $kanbanCounts[$spaceID]['myKanban'] ++;
|
||||
if($kanban->status != 'closed' and !($kanban->owner == $this->app->user->account)) $kanbanCounts[$spaceID]['others'] ++;
|
||||
if($kanban->status == 'closed') $kanbanCounts[$spaceID]['closed'] ++;
|
||||
$kanbanNames[] = $kanban->name;
|
||||
}
|
||||
}
|
||||
$kanbansPinYin = common::convert2Pinyin($kanbanNames);
|
||||
|
||||
$myKanbansHtml = '<ul class="tree tree-angles" data-ride="tree">';
|
||||
$normalKanbansHtml = '<ul class="tree tree-angles" data-ride="tree">';
|
||||
$closedKanbansHtml = '<ul class="tree tree-angles" data-ride="tree">';
|
||||
|
||||
foreach($kanbanList as $spaceID => $spaceKanbans)
|
||||
{
|
||||
/* Add the space name before kanban. */
|
||||
if(isset($spaceList[$spaceID]))
|
||||
{
|
||||
$spaceName = zget($spaceList, $spaceID);
|
||||
|
||||
if($kanbanCounts[$spaceID]['myKanban']) $myKanbansHtml .= '<li><div class="hide-in-search"><a class="text-muted" title="' . $spaceName . '">' . $spaceName . '</a> <label class="label">' . $lang->kanbanspace->common . '</label></div><ul>';
|
||||
if($kanbanCounts[$spaceID]['others']) $normalKanbansHtml .= '<li><div class="hide-in-search"><a class="text-muted" title="' . $spaceName . '">' . $spaceName . '</a> <label class="label">' . $lang->kanbanspace->common . '</label></div><ul>';
|
||||
if($kanbanCounts[$spaceID]['closed']) $closedKanbansHtml .= '<li><div class="hide-in-search"><a class="text-muted" title="' . $spaceName . '">' . $spaceName . '</a> <label class="label">' . $lang->kanbanspace->common . '</label></div><ul>';
|
||||
}
|
||||
|
||||
foreach($spaceKanbans as $index => $kanban)
|
||||
{
|
||||
$selected = $kanban->id == $kanbanID ? 'selected' : '';
|
||||
$link = helper::createLink('kanban', 'view', "kanbanID=%s", '', '', $kanban->id);
|
||||
$kanbanName = '<i class="icon icon-kanban"></i> ' . $kanban->name;
|
||||
|
||||
if($kanban->status != 'closed' and $kanban->owner == $this->app->user->account)
|
||||
{
|
||||
$myKanbansHtml .= '<li>' . html::a(sprintf($link, $kanban->id), $kanbanName, '', "class='$selected kanbanName' title='{$kanban->name}' data-key='" . zget($kanbansPinYin, $kanban->name, '') . "'") . '</li>';
|
||||
|
||||
if($selected == 'selected') $tabActive = 'myKanban';
|
||||
|
||||
$myKanbans ++;
|
||||
}
|
||||
elseif($kanban->status != 'closed' and !($kanban->owner == $this->app->user->account))
|
||||
{
|
||||
$normalKanbansHtml .= '<li>' . html::a(sprintf($link, $kanban->id), $kanbanName, '', "class='$selected kanbanName' title='{$kanban->name}' data-key='" . zget($kanbansPinYin, $kanban->name, '') . "'") . '</li>';
|
||||
|
||||
if($selected == 'selected') $tabActive = 'other';
|
||||
|
||||
$others ++;
|
||||
}
|
||||
elseif($kanban->status == 'closed')
|
||||
{
|
||||
$closedKanbansHtml .= '<li>' . html::a(sprintf($link, $kanban->id), $kanbanName, '', "class='$selected kanbanName' title='$kanbanName' data-key='" . zget($kanbansPinYin, $kanban->name, '') . "'") . '</li>';
|
||||
|
||||
if($selected == 'selected') $tabActive = 'closed';
|
||||
}
|
||||
|
||||
/* If the kanban is the last one in the space, print the closed label. */
|
||||
if(isset($spaceList[$spaceID]) and !isset($spaceKanbans[$index + 1]))
|
||||
{
|
||||
if($kanbanCounts[$spaceID]['myKanban']) $myKanbansHtml .= '</ul></li>';
|
||||
if($kanbanCounts[$spaceID]['others']) $normalKanbansHtml .= '</ul></li>';
|
||||
if($kanbanCounts[$spaceID]['closed']) $closedKanbansHtml .= '</ul></li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$myKanbansHtml .= '</ul>';
|
||||
$normalKanbansHtml .= '</ul>';
|
||||
$closedKanbansHtml .= '</ul>';
|
||||
?>
|
||||
|
||||
<div class="table-row">
|
||||
<div class="table-col col-left">
|
||||
<div class='list-group'>
|
||||
<?php $tabActive = ($myKanbans and ($tabActive == 'closed' or $tabActive == 'myKanban')) ? 'myKanban' : 'other';?>
|
||||
<?php if($myKanbans): ?>
|
||||
<ul class="nav nav-tabs" id="navTabs">
|
||||
<li class="<?php if($tabActive == 'myKanban') echo 'active';?>"><?php echo html::a('#myKanban', $lang->kanban->my, '', "data-toggle='tab' class='not-list-item not-clear-menu'");?><span class="label label-light label-badge"><?php echo $myKanbans;?></span><li>
|
||||
<li class="<?php if($tabActive == 'other') echo 'active';?>"><?php echo html::a('#other', $lang->kanban->other, '', "data-toggle='tab' class='not-list-item not-clear-menu'")?><span class="label label-light label-badge"><?php echo $others;?></span><li>
|
||||
</ul>
|
||||
<?php endif;?>
|
||||
<div class="tab-content kanbanTree" id="tabContent">
|
||||
<div class="tab-pane kanbans <?php if($tabActive == 'myKanban') echo 'active';?>" id="myKanban">
|
||||
<?php echo $myKanbansHtml;?>
|
||||
</div>
|
||||
<div class="tab-pane kanbans <?php if($tabActive == 'other') echo 'active';?>" id="other">
|
||||
<?php echo $normalKanbansHtml;?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-footer">
|
||||
<a class='pull-right toggle-right-col not-list-item'><?php echo $lang->kanban->closed;?><i class='icon icon-angle-right'></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-col col-right kanbanTree">
|
||||
<div class='list-group kanbans'><?php echo $closedKanbansHtml;?></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>scrollToSelected();</script>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
$('.nav-tabs li span').hide();
|
||||
$('.nav-tabs li.active').find('span').show();
|
||||
|
||||
$('.nav-tabs>li a').click(function()
|
||||
{
|
||||
if($('#swapper input[type="search"]').val() == '')
|
||||
{
|
||||
$(this).siblings().show();
|
||||
$(this).parent().siblings('li').find('span').hide();
|
||||
}
|
||||
})
|
||||
|
||||
$('#swapper [data-ride="tree"]').tree('expand');
|
||||
|
||||
$('#swapper #dropMenu .search-box').on('onSearchChange', function(event, value)
|
||||
{
|
||||
if(value != '')
|
||||
{
|
||||
$('div.hide-in-search').siblings('i').addClass('hide-in-search');
|
||||
$('.nav-tabs li span').hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
$('div.hide-in-search').siblings('i').removeClass('hide-in-search');
|
||||
$('li.has-list div.hide-in-search').removeClass('hidden');
|
||||
$('.nav-tabs li.active').find('span').show();
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user