Bugzilla – Attachment 134584 Details for
Bug 23681
Make patron restrictions user definable
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 23681: Add management UI
Bug-23681-Add-management-UI.patch (text/plain), 14.51 KB, created by
Martin Renvoize (ashimema)
on 2022-05-04 11:42:16 UTC
(
hide
)
Description:
Bug 23681: Add management UI
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2022-05-04 11:42:16 UTC
Size:
14.51 KB
patch
obsolete
>From 98e1fe40587b10705da7c8e53581b1e13281e19e Mon Sep 17 00:00:00 2001 >From: Andrew Isherwood <andrew.isherwood@ptfs-europe.com> >Date: Wed, 2 Oct 2019 16:41:07 +0100 >Subject: [PATCH] Bug 23681: Add management UI > >This patch adds UI to allow CRUD operations on restriction types > >Signed-off-by: Benjamin Veasey <B.T.Veasey@lboro.ac.uk> >Sponsored-by: Loughborough University >--- > admin/restrictions.pl | 112 +++++++++++ > .../prog/css/src/staff-global.scss | 6 + > .../prog/en/modules/admin/restrictions.tt | 174 ++++++++++++++++++ > .../intranet-tmpl/prog/js/restrictiontypes.js | 54 ++++++ > 4 files changed, 346 insertions(+) > create mode 100755 admin/restrictions.pl > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js > >diff --git a/admin/restrictions.pl b/admin/restrictions.pl >new file mode 100755 >index 0000000000..e865259fe6 >--- /dev/null >+++ b/admin/restrictions.pl >@@ -0,0 +1,112 @@ >+#!/usr/bin/perl >+ >+# Copyright 2019 PTFS Europe >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use CGI qw ( -utf8 ); >+use C4::Auth; >+use C4::Output; >+use Koha::RestrictionTypes; >+ >+my $input = new CGI; >+my $op = $input->param('op') // 'list'; >+my $code = uc $input->param('code'); >+my @messages = (); >+ >+ >+my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >+ { >+ template_name => "admin/restrictions.tt", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { parameters => 'manage_patron_restrictions' }, >+ debug => 1, >+ } >+); >+ >+if ( $op eq 'add_form') { >+ # Get all existing restrictions, so we can do client-side validation >+ $template->param( >+ existing => scalar Koha::RestrictionTypes->search() >+ ); >+ if ($code) { >+ $template->param( >+ restriction => scalar Koha::RestrictionTypes->find($code) >+ ); >+ } >+} elsif ( $op eq 'add_validate' ) { >+ >+ my $display_text = $input->param('display_text'); >+ my $is_a_modif = $input->param("is_a_modif"); >+ >+ if ($is_a_modif) { >+ # Check whether another restriction already has this display text >+ my $dupe = Koha::RestrictionTypes->find({ >+ display_text => $display_text >+ }); >+ if ($dupe) { >+ push @messages, { >+ type => 'error', code => 'duplicate_display_text' >+ }; >+ } else { >+ my $restriction = Koha::RestrictionTypes->find($code); >+ $restriction->display_text($display_text); >+ $restriction->store; >+ } >+ } else { >+ # Check whether another restriction already has this code >+ my $dupe = Koha::RestrictionTypes->find($code); >+ if ($dupe) { >+ push @messages, { >+ type => 'error', code => 'duplicate_code' >+ }; >+ } else { >+ my $restriction = Koha::RestrictionType->new({ >+ code => $code, >+ display_text => $display_text >+ }); >+ $restriction->store; >+ } >+ } >+ $op = 'list'; >+} elsif ( $op eq 'delete_confirm' ) { >+ $template->param( >+ restriction => scalar Koha::RestrictionTypes->find($code) >+ ); >+} elsif ( $op eq 'delete_confirmed' ) { >+ Koha::RestrictionTypes->find($code)->delete; >+ $op = 'list'; >+} >+ >+$template->param( >+ messages => \@messages, >+ op => $op >+); >+ >+if ( $op eq 'list' ) { >+ my $restrictions = Koha::RestrictionTypes->search(); >+ $template->param( >+ restrictions => $restrictions, >+ ) >+} >+ >+output_html_with_http_headers $input, $cookie, $template->output; >+ >+exit 0; >diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >index cb7198a532..8ddcdc01e6 100644 >--- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >+++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >@@ -4262,6 +4262,12 @@ input.renew { > background-color: rgba(0, 0, 0, 0.1); > } > >+#restriction_form { >+ .type_input { >+ text-transform: uppercase; >+ } >+} >+ > #stage_list_headings { > font-weight: bold; > span { >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt >new file mode 100644 >index 0000000000..6e2353b5a9 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/restrictions.tt >@@ -0,0 +1,174 @@ >+[% USE raw %] >+[% USE Asset %] >+[% USE Koha %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Administration › Patron restrictions › [% IF op == 'add_form' %][% IF ( restriction ) %]Modify restriction '[% restriction.display_text | html %]'[% ELSE %]New restriction[% END %][% END %] >+[% IF op == 'delete_confirm' %]Confirm deletion of restriction '[% restriction.display_text | html %]'[% END %] >+</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+ >+<body id="admin_restrictions" class="admin"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'patrons-admin-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> › [% IF op == 'add_form' %] <a href="/cgi-bin/koha/admin/restrictions.pl">Patron restrictions</a> › [% IF ( restriction ) %]Modify restriction '[% restriction.display_text | html %]'[% ELSE %]New restriction[% END %][% END %] >+[% IF op == 'delete_confirm' %] <a href="/cgi-bin/koha/admin/restrictions.pl">Patron restrictions</a> › Confirm deletion of restriction '[% restriction.display_text | html %]'[% END %] >+[% IF op == 'delete_confirmed' %] <a href="/cgi-bin/koha/admin/categories.pl">Patron restrictions</a> › Restriction deleted[% END %] >+[% IF op == 'list' %]Patron restrictions[% END %]</div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ <div class="col-sm-10 col-sm-push-2"> >+ <main> >+ >+[% FOR m IN messages %] >+ <div class="dialog [% m.type | html %]"> >+ [% SWITCH m.code %] >+ [% CASE 'duplicate_display_text' %] >+ Another restriction already has this label >+ [% CASE 'duplicate_code' %] >+ Another restriction already has this code >+ [% CASE %] >+ [% m.code | html %] >+ [% END %] >+ </div> >+[% END %] >+ >+[% IF op == 'add_form' %] >+ <form id="restriction_form" action="/cgi-bin/koha/admin/restrictions.pl" method="post"> >+ <input type="hidden" name="op" value="add_validate" /> >+ <input type="hidden" name="checked" value="0" /> >+ [% IF restriction %] >+ <h1>Modify restriction [% restriction.display_text | html %]</h1> >+ <input type="hidden" name="is_a_modif" value="1" /> >+ [% ELSE %] >+ <h1>New restriction</h1> >+ [% END %] >+ <fieldset class="rows"> >+ <ol> >+ [% IF restriction %] >+ <li> >+ <span class="label">Code: </span>[% restriction.code | html %] >+ <input type="hidden" name="code" value="[% restriction.code | html %]" /> >+ </li> >+ <li> >+ <label for="display_text" class="required">Label: </label> >+ <input type="text" value="[% restriction.display_text | html %]" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" /> >+ <span class="required">Required</span> >+ </li> >+ [% ELSE %] >+ <li> >+ <label for="code" class="required">Code: </label> >+ <input type="text" name="code" id="code" size="50" maxlength="50" class="required type_input " required="required" /> >+ <span class="required">Required</span> >+ </li> >+ <li> >+ <label for="display_text" class="required">Label: </label> >+ <input type="text" name="display_text" id="display_text" size="50" maxlength="50" class="required" required="required" /> >+ <span class="required">Required</span> >+ </li> >+ [% END %] >+ </ol> >+ </fieldset> >+ >+ <fieldset class="action"> >+ <input type="submit" value="Save" /> >+ <a href="/cgi-bin/koha/admin/restrictions.pl" class="cancel">Cancel</a> >+ </fieldset> >+ </form> >+[% END %] >+ >+[% IF op == 'delete_confirm' %] >+ <form action="/cgi-bin/koha/admin/restrictions.pl" method="post"> >+ <fieldset> >+ <legend> >+ Confirm restriction deletion >+ </legend> >+ >+ <p>Are you sure you want to delete "[% restriction.display_text | html %]"</p> >+ >+ <fieldset class="action"> >+ <input type="hidden" name="op" value="delete_confirmed" /> >+ <input type="hidden" name="code" value="[% restriction.code | html %]" /> >+ <input type="submit" value="Delete this restriction" /> >+ <a class="cancel" href="/cgi-bin/koha/admin/restrictions.pl">Cancel</a> >+ </fieldset> >+ </fieldset> >+ </form> >+[% END %] >+ >+[% IF op == 'list' %] >+ >+ <div id="toolbar" class="btn-toolbar"> >+ <a class="btn btn-default" id="newrestriction" href="/cgi-bin/koha/admin/restrictions.pl?op=add_form"><i class="fa fa-plus"></i> New restriction</a> >+ </div> >+ >+ <h2>Patron restrictions</h2> >+ [% IF searchfield %] >+ You Searched for [% searchfield | html %]</span> >+ [% END %] >+ [% IF restrictions %] >+ <table id="restriction_types"> >+ <thead> >+ <tr> >+ <th scope="col">Code</th> >+ <th scope="col">Label</th> >+ <th scope="col">Default</th> >+ <th scope="col">Actions</th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH restriction IN restrictions %] >+ <tr> >+ <td> >+ [% restriction.code | html %] >+ </td> >+ <td> >+ [% restriction.display_text | html %] >+ </td> >+ <td> >+ [% IF restriction.dflt %]Yes[% END %] >+ </td> >+ <td class="actions"> >+ <a class="btn btn-default btn-xs" href="/cgi-bin/koha/admin/restrictions.pl?op=add_form&code=[% restriction.code | uri %]"><i class="fa fa-pencil"></i> Edit</a> >+ [% IF !restriction.ronly %] >+ <a class="btn btn-default btn-xs" href="/cgi-bin/koha/admin/restrictions.pl?op=delete_confirm&code=[% restriction.code | uri %]"><i class="fa fa-trash"></i> Delete</a> >+ [% END %] >+ </td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ [% ELSE %] >+ <div class="dialog alert">No restrictions have been defined. <a href="/cgi-bin/koha/admin/restrictions.pl?op=add_form">Create a new restriction</a>.</div> >+ [% END %] >+[% END %] >+ >+ </main> >+ </div> <!-- /.col-sm-10.col-sm-push-2 --> >+ >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'admin-menu.inc' %] >+ </aside> >+ </div> <!-- /.col-sm-2.col-sm-pull-10 --> >+ </div> <!-- /.row --> >+ >+[% MACRO jsinclude BLOCK %] >+ [% Asset.js("js/admin-menu.js") | $raw %] >+ [% INCLUDE 'datatables.inc' %] >+ [% INCLUDE 'columns_settings.inc' %] >+ <script> >+ var MSG_DUPLICATE_CODE = _("Restriction code is already in use"); >+ var MSG_DUPLICATE_DISPLAY_TEXT = _("Label is already in use"); >+ var existing = { >+ [% FOREACH ex IN existing %] >+ [% ex.code | $raw %]: '[% ex.display_text | $raw %]', >+ [% END %] >+ }; >+ </script> >+ [% Asset.js("js/restrictiontypes.js") | $raw %] >+[% END %] >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js b/koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js >new file mode 100644 >index 0000000000..d1a4e5383e >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/js/restrictiontypes.js >@@ -0,0 +1,54 @@ >+jQuery.validator.addMethod( "restrictionCode", function(value){ >+ var ex = Object.keys(existing); >+ return (value.length > 0 && ex.indexOf(value.toUpperCase()) > -1) ? >+ false : >+ true; >+}, MSG_DUPLICATE_CODE); >+ >+jQuery.validator.addMethod( "restrictionDisplayText", function(value){ >+ var ex = Object.values(existing).map(function(el) { >+ return el.toLowerCase(); >+ }); >+ return (value.length > 0 && ex.indexOf(value.toLowerCase()) > -1) ? >+ false : >+ true; >+}, MSG_DUPLICATE_DISPLAY_TEXT); >+ >+$(document).ready(function() { >+ KohaTable("restriction_types", { >+ "aoColumnDefs": [{ >+ "aTargets": [-1], >+ "bSortable": false, >+ "bSearchable": false >+ }, { >+ "aTargets": [0, 1], >+ "sType": "natural" >+ }, ], >+ "aaSorting": [ >+ [1, "asc"] >+ ], >+ "sPaginationType": "full", >+ "exportColumns": [0,1], >+ }); >+ >+ $("#restriction_form").validate({ >+ rules: { >+ code: { >+ required: true, >+ restrictionCode: true >+ }, >+ display_text: { >+ required: true, >+ restrictionDisplayText: true >+ } >+ }, >+ messages: { >+ code: { >+ restrictionCode: MSG_DUPLICATE_CODE >+ }, >+ display_text: { >+ restrictionDisplayText: MSG_DUPLICATE_DISPLAY_TEXT >+ } >+ } >+ }); >+}); >-- >2.20.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 23681
:
93769
|
93770
|
93771
|
93772
|
93773
|
93774
|
93775
|
93776
|
93777
|
93778
|
93779
|
93780
|
93781
|
93782
|
93783
|
93784
|
93785
|
93786
|
94862
|
94863
|
94864
|
94865
|
94866
|
94867
|
94868
|
94869
|
94870
|
94896
|
94897
|
94898
|
94899
|
94900
|
94901
|
94902
|
94903
|
94904
|
95148
|
95255
|
95256
|
95257
|
95258
|
95259
|
95260
|
95261
|
95262
|
95263
|
95264
|
99893
|
99894
|
99895
|
99896
|
99897
|
99898
|
99899
|
99900
|
99901
|
99902
|
130373
|
130374
|
130375
|
130376
|
130377
|
130378
|
130379
|
130380
|
130381
|
130382
|
130383
|
130384
|
132302
|
132303
|
132304
|
132305
|
132306
|
132307
|
132308
|
132309
|
132310
|
132311
|
132312
|
132313
|
132314
|
132315
|
132316
|
132318
|
132319
|
132320
|
134512
|
134513
|
134514
|
134515
|
134516
|
134517
|
134518
|
134519
|
134520
|
134521
|
134522
|
134523
|
134524
|
134525
|
134526
|
134527
|
134528
|
134529
|
134580
|
134581
|
134582
|
134583
|
134584
|
134585
|
134586
|
134587
|
134588
|
134589
|
134590
|
134591
|
134592
|
134593
|
134594
|
134595
|
134596
|
134597
|
134598
|
134599
|
134600
|
134601
|
134602
|
134684
|
134685
|
134686
|
134687
|
134688
|
134689
|
134690
|
134691
|
134692
|
134693
|
134694
|
134696
|
134697
|
134698
|
134699
|
134700
|
134701
|
134702
|
134703
|
134704
|
134705
|
134706
|
134707
|
134708
|
136716
|
136717
|
136718
|
136719
|
136720
|
136721
|
136722
|
136723
|
136724
|
136725
|
136726
|
136727
|
136728
|
136729
|
136730
|
136731
|
136732
|
136733
|
136734
|
136735
|
136736
|
136737
|
136738
|
136739
|
137066
|
137067
|
137068
|
137069
|
137070
|
137071
|
137072
|
137073
|
137074
|
137075
|
137076
|
137077
|
137078
|
137079
|
137080
|
137081
|
137082
|
137083
|
137084
|
137085
|
137086
|
137087
|
137088
|
137089
|
137090
|
137091
|
137092
|
137093
|
137094
|
137102
|
137103
|
137104
|
137105
|
137106
|
137107
|
137108
|
137109
|
137110
|
137111
|
137112
|
137113
|
137114
|
137115
|
137116
|
137117
|
137118
|
137119
|
137120
|
137121
|
137122
|
137123
|
137124
|
137125
|
137126
|
137127
|
137128
|
137129
|
137130
|
139250
|
139251
|
139252
|
139253
|
139254
|
139255
|
139256
|
139257
|
139258
|
139259
|
139260
|
139261
|
139262
|
139263
|
139264
|
139265
|
139266
|
139267
|
139268
|
139269
|
139270
|
139271
|
139272
|
139273
|
139509
|
139512
|
139649
|
139717
|
139768
|
139769
|
139770
|
139771
|
139772
|
139773
|
139774
|
139775
|
139776
|
139777
|
139778
|
139779
|
139780
|
139781
|
139782
|
139783
|
139784
|
139785
|
139786
|
139787
|
139788
|
139789
|
139790
|
139791
|
139792
|
139793
|
139794
|
139795