* Finish task #91374, and fix bug of manage workflow privs by package.

This commit is contained in:
liumengyi
2023-04-17 17:45:29 +08:00
parent 655f1c0753
commit ae8f5f3ac5
5 changed files with 132 additions and 65 deletions
+13 -10
View File
@@ -52,8 +52,8 @@
#privList tbody > tr > td {padding: 4px 20px 20px 20px;}
#privList .group-item {margin-top: 16px;}
#privList .group-item .checkbox-inline label {padding-left: 3px;}
#privList.table-bordered td, #privList.table-bordered th {border-top-style: dashed; border-bottom-style: dashed; border-color: #FFF;}
#privList.table-bordered td, #privList.table-bordered thead th:last-child {border-color: #F5F6F8;}
.table-bordered td, .table-bordered th {border-top-style: dashed; border-bottom-style: dashed; border-color: #FFF;}
.table-bordered td, .table-bordered thead th:last-child {border-color: #F5F6F8;}
.check-all>label.checkbox-indeterminate-block:before {content: ' '; opacity: 1; transform: scale(1);}
.priv-footer {padding: 14px; z-index: 11; box-shadow: inset 0 0px 0px rgb(0 0 0 / 10%), 0 0 5px rgb(0 0 0 / 10%); position: relative; min-height: 40px; background: #fff; border-radius: 0 0 4px 4px;}
.priv-footer .btn {margin 0px; padding-top: 7px;}
@@ -69,14 +69,17 @@ main#main {padding-bottom: 0px;}
#privPackageList div.package {display: inline-block; width: calc(25% - 5px); padding: 10px 0;}
#privPackageList .package + .package {padding: 0;}
#privPackageList .package .check-all {display: inline-block; height: 20px;}
#privPackageList .package input {margin-left: 0px; left: 0px; height: 20px;}
#privPackageList .package input {margin-top: 0px; margin-left: 0px; left: 0px; height: 20px;}
#privPackageList .package label {padding-left: 0; display: inline-block;}
#privPackageList .package .list-toggle {width: 20px; font-size: 14px; line-height: 20px; color: #cbd0db; text-align: center; cursor: pointer; -webkit-transition: all .2s; -o-transition: all .2s; transition: all .2s; vertical-align: top;}
#privPackageList .package .list-toggle:before {content: "\f0da";}
#privPackageList .package.open .list-toggle {transform: rotate(90deg);}
#privPackageList .package.open .list-toggle:before {transform: rotate(90deg);}
#privPackageList .group-item {display: inline-block; width: 158px; margin-bottom: 15px;}
#privPackageList .privs {padding: 20px 20px 0 20px; margin: 10px 0px;border: 1px solid #F5F6F8; background-color: #F9FAFB; position: relative; display: block; max-width: unset; box-shadow: unset; z-index: 1;}
#privPackageList .privs, #privPackageList .menus-privs {padding: 20px 20px 0 20px; margin: 10px 0px;border: 1px solid #D9DBE1; background-color: #F9FAFB; position: relative; display: block; max-width: unset; box-shadow: unset; z-index: 1;}
#privPackageList .menus-privs {margin-top: 35px; border-style: dashed;}
#privPackageList .popover .popover-content {display: inline-block; padding: 0;}
#privPackageList .popover .arrow {border-bottom-color: #F5F6F8; top: -10px;}
#privPackageList .popover .arrow {border-bottom-color: #D9DBE1; top: -10px;}
#privPackageList .popover .arrow:after {border-bottom-color: #F9FAFB;}
#privPackageList .group-item .checkbox-inline label {padding-left: 0}
#privPackageList .group-item {display: inline-block; width: 158px; margin-bottom: 15px;}
#privPackageList .group-item > .checkbox-primary {display: inline-block;}
#privPackageList .priv-toggle.icon {width: 12px; height: 12px; position: relative; display: inline-block; color: #9EA3B0; margin-left: 4px;}
#privPackageList .priv-toggle.icon:before {content: "\e925"; font-size: 12px; min-width: unset; transform: scale(0.5); font-weight: 900;}
#privPackageList .priv-toggle.icon:after {position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; display: inline-block; content: ""; border: 1px solid; border-radius: 10%;}
#privPackageList .priv-toggle.icon.open:before {content: "\e926";}
+88 -7
View File
@@ -302,7 +302,7 @@ function groupItemChange()
if($('#privPackageList').length > 0)
{
var dataid = $(this).attr('data-id');
var $priv = $('#privPackageList').find('.privs.hidden .group-item input[data-id="' + dataid + '"]');
var $priv = $('#privPackageList').find('.group-item input[data-id="' + dataid + '"]');
if(checked)
{
$priv.attr('checked', 'checked');
@@ -440,18 +440,18 @@ $(function()
updatePrivTree(selectedPrivIdList);
}));
$('#privPackageList .list-toggle.icon').click(function()
$('#privPackageList .package > .priv-toggle.icon').click(function()
{
var opened = $(this).closest('.package').hasClass('open');
var opened = $(this).hasClass('open');
$('#privPackageList .package').removeClass('open');
$('#privPackageList .package > .priv-toggle.icon').removeClass('open');
$('.privs.popover').remove();
if(!opened)
{
$(this).closest('.package').addClass('open');
var moduleName = $(this).closest('.package').attr('data-module');
var packageID = $(this).closest('.package').attr('data-package');
$(this).addClass('open');
var moduleName = $(this).closest('.package').attr('data-module');
var packageID = $(this).closest('.package').attr('data-package');
/* The privs should be inserted after which permission package. */
var perRowPackages = Math.floor($(this).closest('td').width() / $(this).closest('td').find('.package').width());
@@ -479,4 +479,85 @@ $(function()
}
}
});
$('#privPackageList .package-column').on('click', '.privs .priv-toggle.icon', (function()
{
var opened = $(this).hasClass('open');
$('#privPackageList .group-item > .priv-toggle.icon').removeClass('open');
$('.menus-privs.popover').remove();
if(!opened)
{
$(this).addClass('open');
var moduleName = $(this).closest('.privs').attr('data-module');
var packageID = $(this).closest('.privs').attr('data-package');
/* The menus privs should be inserted after which priv. */
var perRowPrivs = Math.floor($(this).closest('.popover-content').width() / $(this).closest('.popover-content').find('.group-item').width());
var privIndex = $(this).closest('.group-item').index();
var appendIndex = (Math.floor(privIndex / perRowPrivs) + 1) * perRowPrivs - 1;
var $menusPrivs = $(this).closest('.group-item').find('.menus-privs')
var $showPrivs = $('<div class="menus-privs popover bottom" data-module="' + moduleName + '" data-package="' + packageID + '">' + $menusPrivs.html() + '</div>');
/* Calculate the triangle position of privs popover. */
var position = $(this).closest('.popover-content').width() * (privIndex % perRowPrivs) + 30;
$showPrivs.find('.arrow').css('left', position + 'px');
if($(this).closest('.popover-content').find('.group-item:not(.menus-item)').eq(appendIndex).length == 0)
{
$showPrivs.css('margin-bottom', '0');
$(this).closest('.popover-content').find('.group-item:not(.menus-item)').eq(-1).after($showPrivs);
}
else
{
$(this).closest('.popover-content').find('.group-item:not(.menus-item)').eq(appendIndex).after($showPrivs);
}
}
}));
$('#privPackageList .package-column').on('click', '.menus-privs input[type=checkbox]', (function()
{
groupItemChange();
var $menusPrivs = $(this).closest('.popover-content').find('.menus-item');
var $parentPrivs = $(this).closest('.privs').find('.checkbox-primary.check-all');
var allPrivs = $menusPrivs.length;
var selectPrivs = $menusPrivs.find('input[checked=checked]').length;
if(allPrivs > 0 && allPrivs == selectPrivs)
{
$parentPrivs.find('input').attr('checked', 'checked');
$parentPrivs.find('label').removeClass('checkbox-indeterminate-block');
}
else if(selectPrivs == 0)
{
$parentPrivs.find('input').removeAttr('checked');
$parentPrivs.find('label').removeClass('checkbox-indeterminate-block');
}
else
{
$parentPrivs.find('input').removeAttr('checked');
$parentPrivs.find('label').addClass('checkbox-indeterminate-block');
}
}));
$('#privPackageList .package-column').on('click', '.privs .check-all', (function()
{
var checked = $(this).find('input[type=checkbox]').prop('checked');
var $children = $(this).closest('.privs').find('.menus-privs .menus-item');
if(checked)
{
$children.find('input').attr('checked', 'checked');
$children.find('label').removeClass('checkbox-indeterminate-block');
}
else
{
$children.find('input').removeAttr('checked');
}
$children.find('label').removeClass('checkbox-indeterminate-block');
$(this).find('label').removeClass('checkbox-indeterminate-block');
changeParentChecked($(this), $(this).closest('.group-item').attr('data-module'), $(this).closest('.group-item').attr('data-package'));
}));
});
+1
View File
@@ -2079,6 +2079,7 @@ class groupModel extends model
if(isset($allPrivs[$module][$method])) continue;
if(!$this->checkMenuModule($menu, $module)) continue;
if(!isset($this->lang->{$module}->{$methodLabel})) $this->app->loadLang($module);
if(isset($this->lang->$module->menus) and $method == 'browse') continue;
$key = "{$module}-{$method}";
$priv = new stdclass();
+3 -3
View File
@@ -97,7 +97,7 @@
<?php
$i = 1;
$modulePrivs = count($privList[$moduleName], 1) - count($selectPrivs[$moduleName], 1) - (isset($lang->$moduleName->menus) ? 1 : 0);
$modulePrivs = count($privList[$moduleName], 1) - count($selectPrivs[$moduleName], 1);
$moduleSelect = array_sum($selectPrivs[$moduleName]);
?>
<?php foreach($packages as $packageID => $privs):?>
@@ -113,7 +113,7 @@
</th>
<?php endif;?>
<?php
$packagePrivs = count($privs) - (isset($lang->$moduleName->menus) ? 1 : 0);
$packagePrivs = count($privs);
$packageSelect = $selectPrivs[$moduleName][$packageID];
?>
<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;?>'>
@@ -138,7 +138,7 @@
<?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):?>
<?php if(!empty($lang->$moduleName->menus) and $priv->method == 'browse') continue;?>
<?php if(!empty($lang->$moduleName->menus) and ($priv->method == 'browse' or in_array($priv->method, array_keys($lang->$moduleName->menus)))) continue;?>
<div class="group-item" data-module='<?php echo $moduleName;?>' data-package='<?php echo $packageID;?>' data-id='<?php echo zget($priv, 'id', 0);?>'>
<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='$priv->action'");?>
+27 -45
View File
@@ -119,18 +119,42 @@
<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->other);?></label>
</div>
<i class="list-toggle icon"></i>
<i class="priv-toggle icon"></i>
</div>
<div class="privs hidden" data-module='<?php echo $moduleName;?>' data-package='<?php echo $packageID;?>'>
<div class="arrow"></div>
<div class='popover-content'>
<?php foreach($privs as $privID => $priv):?>
<?php if(isset($lang->$moduleName->menus)):?>
<?php
$menusPrivs = count($lang->$moduleName->menus);
$menusSelect = count(array_intersect(array_keys($lang->$moduleName->menus), array_keys(zget($groupPrivs, $moduleName, array()))));
?>
<div class="group-item" data-id='0' data-module='<?php echo $moduleName;?>' data-package='0'>
<div class="checkbox-primary checkbox-inline checkbox-left check-all">
<input type='checkbox' value='browse' <?php if($menusPrivs == $menusSelect) echo 'checked';?>>
<label class='text-left <?php if(!empty($menusSelect) and $menusPrivs != $menusSelect) echo 'checkbox-indeterminate-block';?>' for='actions[<?php echo $moduleName;?>]browse'><?php echo $lang->$moduleName->browse;?></label>
</div>
<i class="priv-toggle icon"></i>
<div class='menus-privs hidden data-module='<?php echo $moduleName;?>' data-package='<?php echo $packageID;?>''>
<div class="arrow"></div>
<div class='popover-content'>
<?php foreach($lang->$moduleName->menus as $method => $name):?>
<div class="group-item menus-item" data-id='<?php echo "$moduleName-$method";?>' data-module='<?php echo $moduleName;?>' data-package='0'>
<?php echo html::checkbox("actions[$moduleName]", array($method => $name), isset($groupPrivs[$moduleName][$method]) ? $groupPrivs[$moduleName][$method] : '', "title='{$name}' id='actions[$moduleName]$method' data-id='$moduleName-$method'");?>
</div>
<?php endforeach;?>
</div>
</div>
</div>
<?php endif;?>
<?php foreach($privs as $privID => $priv):?>
<?php if(!empty($lang->$moduleName->menus) and ($priv->method == 'browse' or in_array($priv->method, array_keys($lang->$moduleName->menus)))) continue;?>
<div class="group-item" data-id='<?php echo zget($priv, 'id', 0);?>' 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='$priv->action'");?>
</div>
</div>
<?php endforeach;?>
<?php endforeach;?>
</div>
</div>
<?php endforeach;?>
@@ -186,45 +210,3 @@
<?php js::set('relatedPrivData', json_encode($relatedPrivData));?>
<?php js::set('selectedPrivIdList', $selectedPrivIdList);?>
<?php js::set('excludeIdList', $excludePrivsIdList);?>
<script>
$(document).ready(function()
{
$(".icon-help").popover();
/**
* 隐藏列表标签。
* Hide tabs except the browse list tab.
*/
$('.menus input[name^=actions]:not(input[value=browse])').parent('.checkbox-primary').hide();
/**
* 切换列表标签的显示。
* Toggle display of tabs except the browse list tab.
*/
$('.menus .icon-plus').click(function()
{
$(this).toggleClass('icon-minus', 'icon-plus');
$('.menus input[name^=actions]:not(input[value=browse])').parent('.checkbox-primary').toggle();
})
/**
* 勾选浏览列表标签时,自动勾选下面的所有标签。
* Check all tabs when the Browse list tab is selected.
*/
$('.menus input[value=browse]').change(function()
{
$(this).parents('.menus').find('[name^=actions]').prop('checked', $(this).prop('checked'));
});
/**
* 勾选浏览列表标签下面的任意一个标签时,自动勾选浏览列表标签。
* Check the browse list tab when any one of the tabs is selected.
*/
$('.menus input[name^=actions]:not(input[value=browse])').click(function()
{
var $parent = $(this).parents('.menus');
$parent.find('input[value=browse]').prop('checked', $parent.find('input[name^=actions]:not(input[value=browse]):checked').length > 0);
})
});
</script>