* Code for task #89847.
This commit is contained in:
@@ -1010,4 +1010,47 @@ class group extends control
|
||||
|
||||
return print(html::select('actions[]', $privList, '', "multiple='multiple' class='form-control'"));
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: Get priv's dependent priv list.
|
||||
*
|
||||
* @param string $privIdList
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function ajaxGetDependentPrivs($privIdList)
|
||||
{
|
||||
$relatedPrivs = $this->dao->select('t1.relationPriv,t2.parent,t2.module,t2.method,t3.`key`,t3.value')->from(TABLE_PRIVRELATION)->alias('t1')
|
||||
->leftJoin(TABLE_PRIV)->alias('t2')->on('t1.relationPriv=t2.id')
|
||||
->leftJoin(TABLE_PRIVLANG)->alias('t3')->on('t2.relationPriv=t3.objectID')
|
||||
->leftJoin(TABLE_PRIVMANAGER)->alias('t4')->on('t2.parent=t4.id')
|
||||
->where('t1.priv')->in($privIdList)
|
||||
->andWhere('t1.relationPriv')->notin($privIdList)
|
||||
->andWhere('t2.type')->eq('depend')
|
||||
->andWhere('t3.objectType')->eq('priv')
|
||||
->andWhere('t1.edition')->like("%,{$this->config->edition},%")
|
||||
->andWhere('t1.vision')->like("%,{$this->config->vision},%")
|
||||
->fetchAll('relationPriv');
|
||||
|
||||
if(empty($relatedPrivs)) return print('');
|
||||
|
||||
$modulePairs = $this->group->getPrivManagerPairs('module');
|
||||
$managerList = $this->dao->select('*')->from(TABLE_PRIVMANAGER)->fetchAll('id');
|
||||
$relatedPrivs = $this->group->transformPrivLang($relatedPrivs);
|
||||
$privList = array('depend' => array(), 'recommend' => array());
|
||||
|
||||
foreach($relatedPrivs as $privID => $relatedPriv)
|
||||
{
|
||||
$module = $relatedPriv->module;
|
||||
if(!isset($privList['depend'][$module])) $privList[$type][$module] = array();
|
||||
$moduleCode = $managerList[$relatedPriv->parent]->type == 'package' ? $managerList[$managerList[$relatedPriv->parent]->parent]->code : $managerList[$relatedPriv->parent]->code;
|
||||
$privList['depend'][$module]['title'] = $modulePairs[$moduleCode];
|
||||
$privList['depend'][$module]['module'] = $moduleCode;
|
||||
$privList['depend'][$module]['children'][] = array('title' => $relatedPriv->name, 'relationPriv' => $privID);
|
||||
}
|
||||
|
||||
$privList[$type] = array_values($privList[$type]);
|
||||
|
||||
return print(json_encode($privList));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
.mt-m {margin-top: 16px;}
|
||||
.flex-center {display: flex; justify-content: center; align-items: center;}
|
||||
#mainContent {display: flex; gap: 16px; height: calc(100vh - 120px);}
|
||||
#mainContent > .main {flex: 1 1 75%; overflow-y: auto; min-height: 480px;}
|
||||
#mainContent > .side {flex: 1 1 25%;}
|
||||
.priv-panel {background: #fff; padding: 10px; box-shadow: 0 1px 1px rgb(0 0 0 / 5%), 0 2px 6px 0 rgb(0 0 0 / 5%);}
|
||||
.priv-panel > .panel-content {height: calc(50vh - 160px); overflow-y: auto; min-height: 140px;}
|
||||
.priv-panel > .panel-bottom {padding-top: 20px;}
|
||||
|
||||
/* tree */
|
||||
.tree ul > li {display: inline-block; width: 50%;}
|
||||
.priv-item > .icon {padding-left: 5px;}
|
||||
.empty-tip {height: 100%;}
|
||||
|
||||
.table-bymodule select.form-control {height: 250px;}
|
||||
.group-item {display: block; width: 220px; float: left; font-size: 14px;}
|
||||
.group-item .checkbox-inline label {padding-left: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}
|
||||
|
||||
@@ -110,8 +110,134 @@ function changeParentChecked($item, moduleName, packageID)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init comp recomend-tree.
|
||||
*
|
||||
* @param array data
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function initRecomendTree(data)
|
||||
{
|
||||
$(".menuTree.depend").tree(
|
||||
{
|
||||
data: data,
|
||||
initialState: 'active',
|
||||
itemCreator: function($li, item)
|
||||
{
|
||||
$li.append('<a class="priv-item" data-has-children="' + (item.children ? !!item.children.length : false) + '" href="#" title="' + item.title + '">' + item.title + (item.children ? '' : '<i class="icon icon-close hidden" data-type="depend" data-privid=' + item.privID + ' data-relationpriv=' + item.relationPriv + '></i>') + '</a>');
|
||||
if(item.active) $li.addClass('active open in');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Init comp depend-tree.
|
||||
*
|
||||
* @param array data
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function initDependTree(data)
|
||||
{
|
||||
$(".menuTree.recommend").tree(
|
||||
{
|
||||
data: data,
|
||||
initialState: 'active',
|
||||
itemCreator: function($li, item)
|
||||
{
|
||||
$li.append('<a class="priv-item" data-has-children="' + (item.children ? !!item.children.length : false) + '" href="#" title="' + item.title + '">' + item.title + (item.children ? '' : '<i class="icon icon-close hidden" data-type="recommend" data-privid=' + item.privID + ' data-relationpriv=' + item.relationPriv + '></i>') + '</a>');
|
||||
if(item.active) $li.addClass('active open in');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* update comp tree after click checkbox-label.
|
||||
*
|
||||
* @param obj objTree
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function updatePrivTree(objTree)
|
||||
{
|
||||
$(".menuTree.depend").data('zui.tree').reload(objTree.dependData || [] );
|
||||
if(objTree.dependData && objTree.dependData.length)
|
||||
{
|
||||
$(".menuTree.depend + .empty-tip").addClass('hidden');
|
||||
|
||||
var privCount = 0;
|
||||
$.each(objTree.dependData, function(index, item){if(item.children) privCount += item.children.length;});
|
||||
$(".menuTree.depend").closest('.priv-panel').find('.panel-title .priv-count').html('(' + privCount + ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
$(".menuTree.depend + .empty-tip").removeClass('hidden');
|
||||
$(".menuTree.depend").closest('.priv-panel').find('.panel-title .priv-count').html('');
|
||||
}
|
||||
$(".menuTree.recommend").data('zui.tree').reload(objTree.recommendData || []);
|
||||
if(objTree.recommendData && objTree.recommendData.length)
|
||||
{
|
||||
$(".menuTree.recommend + .empty-tip").addClass('hidden');
|
||||
|
||||
var privCount = 0;
|
||||
$.each(objTree.recommendData, function(index, item){if(item.children) privCount += item.children.length;});
|
||||
$(".menuTree.recommend").closest('.priv-panel').find('.panel-title .priv-count').html('(' + privCount + ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
$(".menuTree.recommend + .empty-tip").removeClass('hidden');
|
||||
$(".menuTree.recommend").closest('.priv-panel').find('.panel-title .priv-count').html('');
|
||||
}
|
||||
if(!canDeleteRelation) $('.side a.priv-item .icon-close').remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get relation side.
|
||||
*
|
||||
* @param int $privID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function getSideRelation(privID)
|
||||
{
|
||||
$.get(createLink('group', 'ajaxGetPrivRelations', "privID=" + privID), function(data)
|
||||
{
|
||||
var objTree = {};
|
||||
if(data)
|
||||
{
|
||||
var relatedPriv = JSON.parse(data);
|
||||
objTree.dependData = relatedPriv.depend;
|
||||
objTree.recommendData = relatedPriv.recommend;
|
||||
}
|
||||
updatePrivTree(objTree);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update depend and recommend privs.
|
||||
*
|
||||
* @param e $e
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function updateRelations(e)
|
||||
{
|
||||
if($('.bg-primary-pale').length) $('.bg-primary-pale').removeClass('bg-primary-pale');
|
||||
$('#privListTable').length > 0 ? $(e.target).closest('tr').addClass('bg-primary-pale') : $(e.target).addClass('bg-primary-pale');
|
||||
|
||||
var selectedID = $('#privListTable').length == 0 ? $(e.target).siblings('input:checkbox').data('id') : $(e.target).closest('tr').attr('data-id');
|
||||
$('.side a#addDependent').attr('href', createLink('group', 'addRelation', "privIdList=" + selectedID + '&type=depend')).removeAttr('disabled');
|
||||
$('.side a#addRecommendation').attr('href', createLink('group', 'addRelation', "privIdList=" + selectedID + '&type=recommend')).removeAttr('disabled');
|
||||
if(!$('.side a#addDependent').hasClass('modaled')) $('.side a#addDependent,.side a#addRecommendation').modal().addClass('modaled');
|
||||
getSideRelation(selectedID);
|
||||
}
|
||||
|
||||
$(function()
|
||||
{
|
||||
initRecomendTree([]);
|
||||
initDependTree([]);
|
||||
|
||||
$('#privList > tbody > tr > th .check-all').change(function()
|
||||
{
|
||||
var id = $(this).find('input[type=checkbox]').attr('id');
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<a href='javascript:;' class='btn btn-link btn-active-text'><span class='text'><?php echo $group->name;?></span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div id='mainContent' class='main main-content'>
|
||||
<form class="load-indicator main-form form-ajax" id="managePrivForm" method="post">
|
||||
<table class='table table-hover table-striped table-bordered'>
|
||||
<thead>
|
||||
@@ -76,88 +76,125 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<form class="load-indicator main-form form-ajax" id="managePrivForm" method="post" target='hiddenwin'>
|
||||
<table class='table table-hover table-striped table-bordered' id='privList'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class='module'><?php echo $lang->group->module;?></th>
|
||||
<th class='package'><?php echo '权限包';?></th>
|
||||
<th class='method' colspan='2'><?php echo $lang->group->method;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($privList as $moduleName => $packages):?>
|
||||
<?php if(!count((array)$packages)) continue;?>
|
||||
<?php
|
||||
$moduleActions = !empty($lang->resource->{$moduleName}) ? $lang->resource->{$moduleName} : null;
|
||||
|
||||
/* Check method in select version. */
|
||||
if($version)
|
||||
{
|
||||
$hasMethod = false;
|
||||
foreach($privMethods as $module => $methods)
|
||||
{
|
||||
foreach($methods as $method)
|
||||
{
|
||||
if(strpos($changelogs, ",$module-$method,") !== false)
|
||||
{
|
||||
$hasMethod = true;
|
||||
break;
|
||||
}
|
||||
if(!$hasMethod) continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$i = 1;
|
||||
|
||||
$modulePrivs = count($privList[$moduleName], 1) - count($selectPrivs[$moduleName], 1);
|
||||
$moduleSelect = array_sum($selectPrivs[$moduleName]);
|
||||
?>
|
||||
<?php foreach($packages as $packageID => $privs):?>
|
||||
<tr class='<?php echo cycle('even, bg-gray');?>'>
|
||||
<?php if($i == 1):?>
|
||||
<th class='text-middle text-left module' rowspan="<?php echo $i == 1 ? count($packages) : 1;?>" data-module='<?php echo $moduleName;?>' all-privs='<?php echo $modulePrivs;?>' select-privs='<?php echo $moduleSelect;?>'>
|
||||
<div class="checkbox-primary checkbox-inline checkbox-left check-all">
|
||||
<input type='checkbox' id='allChecker<?php echo $moduleName;?>' value='1' <?php if(!empty($moduleSelect) and $modulePrivs == $moduleSelect) echo 'checked';?>>
|
||||
<label class='text-left <?php if(!empty($moduleSelect) and $modulePrivs != $moduleSelect) echo 'checkbox-indeterminate-block';?>' for='allChecker<?php echo $moduleName;?>'><?php echo $lang->$moduleName->common;?></label>
|
||||
</div>
|
||||
</th>
|
||||
<?php endif;?>
|
||||
<div id='mainContent'>
|
||||
<div class='main main-content'>
|
||||
<form class="load-indicator main-form form-ajax" id="managePrivForm" method="post" target='hiddenwin'>
|
||||
<table class='table table-hover table-striped table-bordered' id='privList'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class='module'><?php echo $lang->group->module;?></th>
|
||||
<th class='package'><?php echo '权限包';?></th>
|
||||
<th class='method' colspan='2'><?php echo $lang->group->method;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($privList as $moduleName => $packages):?>
|
||||
<?php if(!count((array)$packages)) continue;?>
|
||||
<?php
|
||||
$packagePrivs = count($privs);
|
||||
$packageSelect = $selectPrivs[$moduleName][$packageID];
|
||||
$moduleActions = !empty($lang->resource->{$moduleName}) ? $lang->resource->{$moduleName} : null;
|
||||
|
||||
/* Check method in select version. */
|
||||
if($version)
|
||||
{
|
||||
$hasMethod = false;
|
||||
foreach($privMethods as $module => $methods)
|
||||
{
|
||||
foreach($methods as $method)
|
||||
{
|
||||
if(strpos($changelogs, ",$module-$method,") !== false)
|
||||
{
|
||||
$hasMethod = true;
|
||||
break;
|
||||
}
|
||||
if(!$hasMethod) continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$i = 1;
|
||||
|
||||
$unassigned = (!empty($moduleActions) and !empty($privMethods[$moduleName])) ? array_diff(array_keys(get_object_vars($moduleActions)), $privMethods[$moduleName]) : array();
|
||||
$modulePrivs = count($privList[$moduleName], 1) - count($selectPrivs[$moduleName], 1) + count($unassigned);
|
||||
$moduleSelect = array_sum($selectPrivs[$moduleName]);
|
||||
?>
|
||||
<th class='<?php echo $i == 1 ? 'td-sm' : 'td-md';?> text-middle text-left package' data-module='<?php echo $moduleName;?>' data-package='<?php echo $packageID;?>' all-privs='<?php echo $packagePrivs;?>' select-privs='<?php echo $packageSelect;?>'>
|
||||
<div class="checkbox-primary checkbox-inline checkbox-left check-all">
|
||||
<input type='checkbox' id='allCheckerModule<?php echo $moduleName;?>Package<?php echo $packageID;?>' value='1' <?php if($packagePrivs == $packageSelect) echo 'checked';?>>
|
||||
<label class='text-left <?php if(!empty($packageSelect) and $packagePrivs != $packageSelect) echo 'checkbox-indeterminate-block';?>' for='allCheckerPackage<?php echo $packageID;?>'><?php echo zget($privPackages, $packageID, $lang->group->unassigned);?></label>
|
||||
</div>
|
||||
</th>
|
||||
<?php if(isset($lang->$moduleName->menus)):?>
|
||||
<td class='menus'>
|
||||
<?php echo html::checkbox("actions[$moduleName]", array('browse' => $lang->$moduleName->browse), isset($groupPrivs[$moduleName]) ? $groupPrivs[$moduleName] : '');?>
|
||||
<a href='javascript:;'><i class='icon icon-plus'></i></a>
|
||||
<?php echo html::checkbox("actions[$moduleName]", $lang->$moduleName->menus, isset($groupPrivs[$moduleName]) ? $groupPrivs[$moduleName] : '');?>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<td id='<?php echo $moduleName;?>' class='pv-10px' colspan='<?php echo !empty($lang->$moduleName->menus) ? 1 : 2?>'>
|
||||
<?php foreach($privs as $privID => $priv):?>
|
||||
<div class="group-item" data-module='<?php echo $moduleName;?>' data-package='<?php echo $packageID;?>'>
|
||||
<div class="checkbox-primary">
|
||||
<?php echo html::checkbox("actions[$priv->module]", array($priv->method => $priv->name), isset($groupPrivs[$priv->module][$priv->method]) ? $priv->method : '', "title='{$priv->name}' id='actions[$priv->module]$priv->method' data-id='$privID'");?>
|
||||
<?php foreach($packages as $packageID => $privs):?>
|
||||
<tr class='<?php echo cycle('even, bg-gray');?>'>
|
||||
<?php if($i == 1):?>
|
||||
<th class='text-middle text-left module' rowspan="<?php echo $i == 1 ? count($packages) : 1;?>" data-module='<?php echo $moduleName;?>' all-privs='<?php echo $modulePrivs;?>' select-privs='<?php echo $moduleSelect;?>'>
|
||||
<div class="checkbox-primary checkbox-inline checkbox-left check-all">
|
||||
<input type='checkbox' id='allChecker<?php echo $moduleName;?>' value='1' <?php if(!empty($moduleSelect) and $modulePrivs == $moduleSelect) echo 'checked';?>>
|
||||
<label class='text-left <?php if(!empty($moduleSelect) and $modulePrivs != $moduleSelect) echo 'checkbox-indeterminate-block';?>' for='allChecker<?php echo $moduleName;?>'><?php echo $lang->$moduleName->common;?></label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $i ++;?>
|
||||
<?php endforeach;?>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</th>
|
||||
<?php endif;?>
|
||||
<?php
|
||||
$packagePrivs = count($privs);
|
||||
$packageSelect = $selectPrivs[$moduleName][$packageID] + ($packageID == 0 ? count($unassigned) : 0);
|
||||
?>
|
||||
<th class='<?php echo $i == 1 ? 'td-sm' : 'td-md';?> text-middle text-left package' data-module='<?php echo $moduleName;?>' data-package='<?php echo $packageID;?>' all-privs='<?php echo $packagePrivs;?>' select-privs='<?php echo $packageSelect;?>'>
|
||||
<div class="checkbox-primary checkbox-inline checkbox-left check-all">
|
||||
<input type='checkbox' id='allCheckerModule<?php echo $moduleName;?>Package<?php echo $packageID;?>' value='1' <?php if($packagePrivs == $packageSelect) echo 'checked';?>>
|
||||
<label class='text-left <?php if(!empty($packageSelect) and $packagePrivs != $packageSelect) echo 'checkbox-indeterminate-block';?>' for='allCheckerPackage<?php echo $packageID;?>'><?php echo zget($privPackages, $packageID, $lang->group->unassigned);?></label>
|
||||
</div>
|
||||
</th>
|
||||
<?php if(isset($lang->$moduleName->menus)):?>
|
||||
<td class='menus'>
|
||||
<?php echo html::checkbox("actions[$moduleName]", array('browse' => $lang->$moduleName->browse), isset($groupPrivs[$moduleName]) ? $groupPrivs[$moduleName] : '');?>
|
||||
<a href='javascript:;'><i class='icon icon-plus'></i></a>
|
||||
<?php echo html::checkbox("actions[$moduleName]", $lang->$moduleName->menus, isset($groupPrivs[$moduleName]) ? $groupPrivs[$moduleName] : '');?>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<td id='<?php echo $moduleName;?>' class='pv-10px' colspan='<?php echo !empty($lang->$moduleName->menus) ? 1 : 2?>'>
|
||||
<?php foreach($privs as $privID => $priv):?>
|
||||
<div class="group-item" data-module='<?php echo $moduleName;?>' data-package='<?php echo $packageID;?>'>
|
||||
<div class="checkbox-primary">
|
||||
<?php echo html::checkbox("actions[$priv->module]", array($priv->method => $priv->name), isset($groupPrivs[$priv->module][$priv->method]) ? $priv->method : '', "title='{$priv->name}' id='actions[$priv->module]$priv->method' data-id='$privID'");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
<?php if($packageID == 0):?>
|
||||
<?php foreach($moduleActions as $action => $actionLabel):?>
|
||||
<?php if(array_search($action, $unassigned) === false) continue;?>
|
||||
<div class="group-item" data-module='<?php echo $moduleName;?>' data-package='<?php echo $packageID;?>'>
|
||||
<div class="checkbox-primary">
|
||||
<?php echo html::checkbox("actions[{$moduleName}]", array($action => $lang->$moduleName->$actionLabel), isset($groupPrivs[$moduleName][$action]) ? $action : '', "title='{$lang->$moduleName->$actionLabel}'", 'inline');?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $i ++;?>
|
||||
<?php endforeach;?>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<div class="side">
|
||||
<div class="priv-panel">
|
||||
<div class="panel-title">
|
||||
<?php echo $lang->group->dependentPrivs?>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
<div class="menuTree depend menu-active-primary menu-hover-primary"></div>
|
||||
<div class="empty-tip flex-center">
|
||||
<p><span class="text-muted"><?php echo $lang->noData;?></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="priv-panel mt-m">
|
||||
<div class="panel-title">
|
||||
<?php echo $lang->group->recommendPrivs?>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
<div class="menuTree recommend menu-active-primary menu-hover-primary"></div>
|
||||
<div class="empty-tip flex-center">
|
||||
<p><span class="text-muted"><?php echo $lang->noData;?></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php js::set('groupID', $groupID);?>
|
||||
|
||||
Reference in New Issue
Block a user