Bug 30623: Copy permissions from one user to another

This patch adds controls to the patron "Set permissions" page allowing
the user to copy a set of permissions from one patron to another.

The patch also makes a minor correction to global staff interface CSS to
correct the appearance of non-primary split buttons.

To test, apply the patch and rebuild the staff interface CSS. You may
want to clear your browser cache.

- Locate a patron in the staff client and choose More -> Set
  permissions. You might want to start with a staff patron who has
  multiple permissions enabled.
- You should see two new buttons in the toolbar immediately above the
  list of permissions: "Copy settings," a split button with a secondary
  option to choose "Forget copied settings"; and "Paste settings" which
  should be disabled by default.
- Clicking the "Copy settings" button should trigger the copy icon to
  cycle/fade from the copy icon to the check-mark icon and back to the
  copy icon. I thought this interaction needed some visual feedback
  since it doesn't otherwise trigger visible action.
- Clicking the "Copy settings" button should also enable the "Paste
  settings" button.
- Locate another patron, preferable one with permissions visibly
  different from your first choice.
- On their "Set permissions" page, click the "Paste settings" button.
  The list of permissions should expand all settings and all the
  checkboxes should now match your original choice.
- At this stage you could find another patron and paste the same
  permissions again.
- Click "Copy settings -> Forget copied settings." The "Paste settings"
  button should become disabled.
- Using the browser console to check the contents of Local Storage
  should confirm that the "copiedPermissions" entry has been removed.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Owen Leonard 2022-04-26 11:29:13 +00:00 committed by Katrin Fischer
parent 96d0a4f996
commit f49cf32238
Signed by: kfischer
GPG key ID: 0EF6E2C03357A834
2 changed files with 79 additions and 1 deletions

View file

@ -40,6 +40,7 @@
[% INCLUDE 'members-toolbar.inc' %]
<form id="flag_form" method="post" action="/cgi-bin/koha/members/member-flags.pl">
[% INCLUDE 'csrf-token.inc' %]
<input type="hidden" name="member" id="borrowernumber" value="[% patron.borrowernumber | html %]" />
@ -58,12 +59,22 @@
<a id="UncheckAllFlags" class="btn btn-link" href="#">
<i class="fa fa-times"></i> Clear all
</a>
<div class="btn-group">
<button id="copyPermissions" class="btn btn-link"><i class="fa fa-copy"></i> Copy settings</button>
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a id="clearCopied" href="#">Forget copied settings</a></li>
</ul>
</div>
<a href="#" id="pastePermissions" class="btn btn-link disabled"><i class="fa fa-paste"></i> Paste settings</a>
<div class="btn-group pull-right">
Filter: <input type="text" name="permissions_filter" id="permissions_filter" size="20" />
<a href="#" id="clear_filter" style="display:none"><i class="fa fa-times"></i></a>
</div>
</div>
<div class="permissions">
<div class="permissions page-section">
[% FOREACH loo IN loop %]
[% IF ( loo.expand ) %]
<div id="parent-flag-[% loo.flag | html %]" class="open parent">
@ -272,8 +283,57 @@
}
}
});
if( copied = getCopiedPermissions() ){
$("#pastePermissions").removeClass("disabled");
}
/* write to the clipboard now */
$("#copyPermissions").on("click", function(e){
e.preventDefault();
let flags = new Object();
$("#flag_form input:checkbox").each(function(){
flags[ $(this).attr('id') ] = $(this).prop("checked");
});
formText = JSON.stringify( flags );
localStorage.setItem("copiedPermissions", formText );
toggleBtnIcon( $(this), "fa-copy", "fa-check" );
$("#pastePermissions").removeClass("disabled");
});
$("#pastePermissions").on("click", function(e){
e.preventDefault();
$(".toggleall_on").click();
let copiedPermissions = getCopiedPermissions();
let checkBox;
let checked;
for( const permission in copiedPermissions ){
checkBox = `${permission}`;
checked = `${copiedPermissions[permission]}` == "true" ? true : false;
$("#" + checkBox).prop("checked", checked );
}
});
$("#clearCopied").on("click", function(e){
e.preventDefault();
localStorage.removeItem("copiedPermissions");
$("#pastePermissions").addClass("disabled");
});
});
function getCopiedPermissions(){
const copied = localStorage.getItem("copiedPermissions");
let copiedPermissions;
try {
copiedPermissions = JSON.parse( copied );
return copiedPermissions;
} catch ( ex ){
console.error("Bad parse: ", ex.message );
return false;
}
}
function setLibrarian(){
$('input[name="flag"]').each(function() {
if($(this).attr('id') != "flag-0" && !$(this).hasClass('superlib') ){

View file

@ -340,6 +340,7 @@ function logOut() {
localStorage.removeItem("bibs_selected");
localStorage.removeItem("patron_search_selections");
localStorage.removeItem("item_search_selections");
localStorage.removeItem("copiedPermissions");
}
function openHelp() {
@ -787,3 +788,20 @@ function selectBsTabByHash(tabs_container_id) {
$("#" + tabs_container_id + " a:first").tab("show");
}
}
/**
* Fades out a Font Awesome icon, fades in a replacement, and back
* @param {object} element - jQuery object representing the icon's container
* @param {string} start - The icon which will be temporarily replaced
* @param {string} replacement - The icon which will be the temporary replacement
*/
function toggleBtnIcon( element, start, replacement ){
let icon = element.find( "." + start );
icon.fadeOut( 1000, function(){
$(this).removeClass( start ).addClass( replacement ).fadeIn( 1000, function(){
$(this).fadeOut( 1000, function(){
$(this).removeClass( replacement ).addClass( start ).fadeIn( 1000 );
});
});
});
}