Bug 24387: (QA follow-up) Add missing filters
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / tools / additional-contents.tt
1 [% USE raw %]
2 [% USE Asset %]
3 [% USE Koha %]
4 [% USE KohaDates %]
5 [% USE Branches %]
6 [% SET footerjs = 1 %]
7 [% INCLUDE 'doc-head-open.inc' %]
8 <title>Additional contents &rsaquo; Tools &rsaquo; Koha</title>
9 [% INCLUDE 'doc-head-close.inc' %]
10 [% UNLESS ( wysiwyg ) %]
11     [% Asset.css("lib/codemirror/codemirror.css") | $raw %]
12     [% Asset.css("lib/codemirror/lint.min.css") | $raw %]
13     <style>
14         .CodeMirror {
15             resize: vertical;
16             z-index: 0;
17         }
18     </style>
19 [% END %]
20 </head>
21
22 <body id="tools_additional-contents" class="tools">
23 [% INCLUDE 'header.inc' %]
24 [% INCLUDE 'cat-search.inc' %]
25
26 <nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
27     <ol>
28         <li>
29             <a href="/cgi-bin/koha/mainpage.pl">Home</a>
30         </li>
31         <li>
32             <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a>
33         </li>
34
35         [% IF op == 'add_form' %]
36             <li>
37                 <a href="/cgi-bin/koha/tools/additional-contents.pl">Additional contents</a>
38             </li>
39             <li>
40                 <a href="#" aria-current="page">
41                     [% IF additional_content.idnew %]
42                         Modify additional content
43                     [% ELSE %]
44                         Add additional content
45                     [% END %]
46                 </a>
47             </li>
48         [% ELSE %]
49             <li>
50                 <a href="#" aria-current="page">
51                     Additional contents
52                     ([% IF category == 'news' %]News[% ELSE %]HTML customizations[% END %])
53                 </a>
54             </li>
55         [% END %]
56     </ol>
57 </nav>
58
59 [% IF op == 'add_form' %]
60 <div class="main container-fluid">
61     <div class="row">
62         <div class="col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
63 [% ELSE %]
64 <div class="main container-fluid">
65     <div class="row">
66         <div class="col-sm-10 col-sm-push-2">
67 [% END %]
68
69 <main>
70
71     [% FOR m IN messages %]
72         <div class="dialog [% m.type | html %]">
73             [% SWITCH m.code %]
74             [% CASE 'error_on_update' %]
75                 An error occurred when updating this content. Perhaps it already exists.
76             [% CASE 'error_on_insert' %]
77                 An error occurred when adding this content. Check the logs
78             [% CASE 'error_on_delete' %]
79                 An error occurred when deleting this content. Check the logs.
80             [% CASE 'success_on_update' %]
81                 Content updated successfully.
82             [% CASE 'success_on_insert' %]
83                 Content added successfully.
84             [% CASE 'success_on_delete' %]
85                 Content deleted successfully.
86             [% CASE %]
87                 [% m.code | html %]
88             [% END %]
89         </div>
90     [% END %]
91
92     [% IF op == 'add_form' %]
93         [% PROCESS add_form %]
94     [% ELSE %]
95         [% PROCESS list %]
96     [% END %]
97
98 </main>
99
100         [% IF op != 'add_form' %]
101             </div> <!-- /.col-sm-10.col-sm-push-2 -->
102
103             <div class="col-sm-2 col-sm-pull-10">
104                 <aside>
105
106                     <div id="news-filter">
107                         <form action="/cgi-bin/koha/tools/additional-contents.pl" method="get">
108                             <h4>Filter</h4>
109                             <fieldset class="brief">
110                                 <ol>
111                                     <li>
112                                         <label for="news_keyword">Keyword:</label>
113                                         <input type="text" name="news_keyword" id="news_keyword" />
114                                     </li>
115                                     <li>
116                                         <label for="news_display_location">Display location:</label>
117                                         <select name="news_display_location" id="news_display_location">
118                                             <option value="">All</option>
119                                             [% PROCESS locations_options category => category %]
120                                         </select>
121                                     </li>
122                                     <li>
123                                         <label for="news_library">Library: </label>
124                                         <select id="news_library" name="news_library">
125                                             <option value=""></option>
126                                             <option value="">All libraries</option>
127                                             [% PROCESS options_for_libraries libraries => Branches.all( selected => branchcode, unfiltered => 1, ) %]
128                                         </select>
129                                     </li>
130                                     <li>
131                                         <label>
132                                             <input type="checkbox" name="show_expired" id="show_expired" /> Show expired
133                                         </label>
134                                     </li>
135                                 </ol>
136                             </fieldset>
137                         </form>
138                     </div>
139
140                     [% INCLUDE 'tools-menu.inc' %]
141                 </aside>
142             </div> <!-- /.col-sm-2.col-sm-pull-10 -->
143         [% END %]
144     </div> <!-- /.row -->
145 </div> <!-- /.main.container-fluid -->
146
147 [% BLOCK add_form %]
148     [% IF additional_content %]
149         <h1>Modify an additional content</h1>
150     [% ELSE %]
151         <h1>New additional content ([% IF category == 'news' %]News[% ELSE %]HTML customizations[% END %])</h1>
152     [% END %]
153
154     <div id="toolbar" class="btn-toolbar">
155         <div class="btn-group">
156             <button class="btn btn-default" id="submit_form"><i class="fa fa-save"></i> Save</button>
157         </div>
158         <a class="btn btn-default cancel" href="/cgi-bin/koha/tools/additional-contents.pl"><i class="fa fa-remove"></i> Cancel</a>
159     </div>
160
161     <form id="add_additional_content" method="post" action="/cgi-bin/koha/tools/additional-contents.pl" class="validate">
162         <input type="hidden" name="op" value="add_validate" />
163         <input type="hidden" name="id" value="[% additional_content.idnew | html %]" />
164         <input type="hidden" name="category" value="[% category | html %]" />
165         <fieldset class="rows">
166             <ol>
167                 <li>
168                     [% IF additional_content %]
169                         <span class="label">Code:</span> [% additional_content.code | html %]
170                         <input type="hidden" id="code" name="code" value="[% additional_content.code | html %]" />
171                     [% ELSE %]
172                         <label for="code" class="required">Code:</label>
173                         <input type="text" id="code" name="code" size="20" maxlength="20" value="" required="required"/>
174                         <span class="required">Required</span>
175                     [% END %]
176                 </li>
177                 <li>
178                     <label for="location">Display location:</label>
179                     <select id="location" name="location">
180                         [% PROCESS locations_options location => additional_content.location %]
181                     </select>
182                 </li>
183                 <li>
184                     <label for="branchcode">Library: </label>
185                     <select id="branchcode" name="branchcode">
186                         [% IF additional_content.branchcode == '' %]
187                             <option value="" selected="selected">All libraries</option>
188                         [% ELSE %]
189                             <option value="">All libraries</option>
190                         [% END %]
191                         [% PROCESS options_for_libraries libraries => Branches.all( selected => additional_content.branchcode, unfiltered => 1, ) %]
192                     </select>
193                 </li>
194                 [% UNLESS languages.size %]
195                     <li>
196                         <label for="title" class="required">Title: </label>
197                         <input id="title" size="30" type="text" name="title" value="[% additional_content.title | html %]" required="required" class="required" /> <span class="required">Required</span>
198                     </li>
199                 [% END %]
200                 <li>
201                     <label for="from">Publication date: </label>
202                     <input id="from" type="text" name="published_on" size="15" value="[% additional_content.published_on | html %]" class="datepickerfrom" />
203                     <div class="hint">[% INCLUDE 'date-format.inc' %]</div>
204                 </li>
205                 <li>
206                     <label for="to">Expiration date: </label>
207                     <input id="to" type="text" name="expirationdate" size="15" value="[% additional_content.expirationdate | html %]" class="datepickerto" />
208                     <div class="hint">
209                         [% INCLUDE 'date-format.inc' %]
210                         [% IF category == 'news' %]
211                             <br>News will still be accessible by direct URL if expired.
212                         [% END %]
213                     </div>
214                 </li>
215                 <li>
216                     <label for="number">Appear in position: </label>
217                     [% IF ( additional_content.number ) %]
218                         <input id="number" size="3" name="number" type="text" value="[% additional_content.number | html %]" />
219                     [% ELSE %]
220                         <input id="number" size="3" name="number" type="text" />
221                     [% END %]
222                 </li>
223             </ol>
224         </fieldset>
225
226         [% IF languages.size %]
227             <div style="clear:both"></div>
228             <div id="tabs">
229                 <ul>
230                     [% FOR language IN languages %]
231                         [% IF language.lang == 'default' %]
232                             <li><a href="#lang_default">Default</a></li>
233                         [% ELSE %]
234                             <li><a href="#lang_[% language.lang | uri %]">[% language.description | html %]</a></li>
235                         [% END %]
236                     [% END %]
237                 </ul>
238
239                 [% FOR language IN languages %]
240                     <div id="lang_[% language.lang | uri %]" class="lang" data-lang="[% language.description | html %]">
241                         <div style="clear:both;">
242
243                             <fieldset>[%# FIXME We should remove list-style:none; and use class="rows" here but it does not work. Owen please help! %]
244                                 <ol>
245                                     <li style="list-style: none;">
246                                         <label for="title_[% language.lang | html %]">Title: </label>
247                                         <input id="title_[% language.lang| html %]" size="30" type="text" name="title" value="[% translated_contents.item(language.lang).title | html %]"></span>
248                                     </li>
249                                     <li style="list-style: none;">
250                                         <label for="content_[% language.lang | html %]">Content: </label>
251                                         <textarea name="content" id="content_[% language.lang | html %]"  cols="75" rows="10">[% translated_contents.item(language.lang).content | html %]</textarea>
252                                         <input type="hidden" name="lang" value="[% language.lang | html %]" />
253                                     </li>
254                                 </ol>
255                             </fieldset>
256                         </div>
257                     </div>
258                 [% END %]
259             </div>
260         [% ELSE %]
261             <div id="lang_default">
262                 <div style="clear:both;">
263                     <textarea name="content" id="content_default"  cols="75" rows="10">[% additional_content.content | html %]</textarea>
264                 </div>
265             </div>
266         [% END %]
267     </form>
268 [% END %]
269
270 [% BLOCK list %]
271
272     <div id="toolbar" class="btn-toolbar">
273         <a class="btn btn-default" id="newentry" href="/cgi-bin/koha/tools/additional-contents.pl?op=add_form&category=[% category | html %]"><i class="fa fa-plus"></i> New entry</a>
274     </div>
275
276     <h2>Additional contents ([% IF category == 'news' %]News[% ELSE %]HTML customizations[% END %])</h2>
277     [% IF category == 'news' %]
278         See <a href="/cgi-bin/koha/tools/additional-contents.pl?category=html_customizations">HTML customizations</a>
279     [% ELSE %]
280         See <a href="/cgi-bin/koha/tools/additional-contents.pl?category=news">News</a>
281     [% END %]
282
283     [% IF additional_contents.count %]
284         <form id="del_form" method="post" action="/cgi-bin/koha/tools/additional-contents.pl">
285             <table id="table_additional_contents">
286                 <thead>
287                     <tr>
288                         <th class="NoSort">&nbsp;</th>
289                         <th>Location</th>
290                         <th>Library</th>
291                         <th>Number</th>
292                         <th>Publication date</th>
293                         <th>Expiration date</th>
294                         <th class="anti-the">Title</th>
295                         <th>Author</th>
296                         <th class="anti-the">News</th>
297                         <th class="NoSort noExport">Actions</th>
298                     </tr>
299                 </thead>
300                 <tbody>
301                     [% FOREACH c IN additional_contents%]
302                         [% IF ( c.is_expired ) %]<tr class="expired">[% ELSE %]<tr>[% END %]
303                         <td>
304                             <input type="checkbox" name="ids" value="[% c.idnew | html %]" />
305                         </td>
306                         <td>
307                             [% IF c.category == 'news' %]
308                                 [% IF c.location == 'staff_and_opac' %]All
309                                 [% ELSIF c.location == 'staff_only' %]Librarian interface
310                                 [% ELSIF c.location == 'opac_only' %]OPAC
311                                 [% ELSIF c.location == 'slip' %]Slip
312                                 [% ELSE %]Unknown ('[% location | html %]')
313                                 [% END %]
314                             [% ELSE %]
315                                 [% c.location | html %]
316                             [% END %]
317                         </td>
318                         <td>
319                             [% IF ( c.branchcode == "" ) -%]
320                             All libraries
321                             [% ELSE %][% c.library.branchname | html %]
322                             [% END %]
323                         </td>
324                         <td>[% c.number | html %]</td>
325                         <td data-order="[% c.published_on | html %]">[% c.published_on | $KohaDates %]</td>
326                         <td data-order="[% c.expirationdate | html %]">[% c.expirationdate | $KohaDates %] [% IF ( c.is_expired ) %](<span class="expired">expired</span>)[% END %]</td>
327                         <td>[% c.title | html %]</td>
328                         <td>[% IF ( c.author) %][% INCLUDE 'patron-title.inc' patron=c.author %][% END %]</td>
329                         <td>
330                             <div class="btn-group">
331                                 <a class="preview_news btn btn-default btn-xs" data-number="[% loop.count | html %]"><i class="fa fa-eye" aria-hidden="true"></i> Preview content</a>
332                             </div>
333                             <div id="contentModal[% loop.count | html %]" class="modal" tabindex="-1" role="dialog" data-number="[% loop.count | html %]">
334                                 <div class="modal-dialog" role="document">
335                                     <div class="modal-content modal-lg">
336                                         <div class="modal-header">
337                                             <h5 class="modal-title">Preview of: "[% c.title | html %]"</h5>
338                                         </div>
339                                     <div class="modal-body">
340                                         [% c.content | $raw %]
341                                     </div>
342                                     <div class="modal-footer">
343                                         <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
344                                     </div>
345                                 </div>
346                             </div>
347                         </td>
348                         <td class="actions">
349                             [% IF ( wysiwyg ) %]
350                                 [% SET editmode = "wysiwyg" %]
351                             [% ELSE %]
352                                 [% SET editmode = "text" %]
353                             [% END %]
354                             <div class="btn-group dropup">
355                                 <a href="/cgi-bin/koha/tools/additional-contents.pl?op=add_form&amp;id=[% c.idnew | uri %]&editmode=[% editmode | uri %]" class="btn btn-default btn-xs"> <i class="fa fa-pencil"></i> Edit</a><button class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
356                                     <span class="caret"></span>
357                                 </button>
358                                 <ul class="dropdown-menu pull-right">
359                                     <li>
360                                         [% IF ( wysiwyg ) %]
361                                             <a href="/cgi-bin/koha/tools/additional-contents.pl?op=add_form&amp;id=[% c.idnew | uri %]&editmode=text"><i class="fa fa-pencil"></i> Edit with text editor</a>
362                                         [% ELSE %]
363                                             <a href="/cgi-bin/koha/tools/additional-contents.pl?op=add_form&amp;id=[% c.idnew | uri %]&editmode=wysiwyg"><i class="fa fa-pencil"></i> Edit with WYSIWYG editor</a>
364                                         [% END %]
365                                     </li>
366                                 </ul>
367                             </div>
368                             <div class="btn-group">
369                                 <a href="/cgi-bin/koha/tools/additional-contents.pl?op=del&amp;ids=[% c.idnew | uri %]" class="delete_news btn btn-default btn-xs"><i class="fa fa-trash"></i> Delete</a>
370                             </div>
371                         </td>
372                     </tr>
373                     [% END %]
374                 </tbody>
375             </table>
376             <input type="hidden" name="op" value="del" />
377             <fieldset class="action"><input type="submit" class="button" value="Delete selected" /></fieldset>
378         </form>
379     [% ELSE %]
380         <div class="dialog message">There are no additional contents.</div>
381     [% END %]
382 [% END %]
383
384 [% BLOCK locations_options %]
385     [% IF category == 'news' %]
386         [% IF location == "staff_and_opac" %]
387             <option value="staff_and_opac" selected="selected">Librarian and OPAC interfaces</option>
388         [% ELSE %]
389             <option value="staff_and_opac">Librarian and OPAC interfaces</option>
390         [% END %]
391
392         [% IF location == "staff_only" %]
393             <option value="staff_only" selected="selected">Librarian interface</option>
394         [% ELSE %]
395             <option value="staff_only">Librarian interface</option>
396         [% END %]
397
398         [% IF location == "opac_only" %]
399             <option value="opac_only" selected="selected">OPAC</option>
400         [% ELSE %]
401             <option value="opac_only">OPAC</option>
402         [% END %]
403
404         [% IF location == "slip" %]
405             <option value="slip" selected="selected">Slip</option>
406         [% ELSE %]
407             <option value="slip">Slip</option>
408         [% END %]
409     [% ELSE %]
410         [% FOREACH l IN [ 'OpacNavRight', 'opacheader', 'OpacCustomSearch', 'OpacMainUserBlock', 'opaccredits', 'OpacLoginInstructions', 'OpacSuggestionInstructions', 'ArticleRequestsDisclaimerText' ] %]
411             [% IF l == location %]
412                 <option value="[% l | html %]" selected="selected">[% l | html %]</option>
413             [% ELSE %]
414                 <option value="[% l | html %]">[% l | html %]</option>
415             [% END %]
416         [% END %]
417     [% END %]
418 [% END %]
419
420 [% MACRO jsinclude BLOCK %]
421     [% INCLUDE 'calendar.inc' %]
422     [% Asset.js("js/tools-menu.js") | $raw %]
423     [% Asset.js("lib/hc-sticky.js") | $raw %]
424     [% IF additional_contents.count %]
425         [% INCLUDE 'datatables.inc' %]
426         <script>
427             $('.preview_news').click( function() {
428                 modalNumber = $(this).attr('data-number');
429                 $('.modal[data-number="'+modalNumber+'"]').modal('show');
430             })
431             function Checkbox(){
432                 var form = document.getElementById('del_form');
433                 var inputs = form.getElementsByTagName('input');
434                 var checked = false;
435                 for (var i=0; i<inputs.length; i++) {
436                     if (inputs[i].type == 'checkbox' && inputs[i].name == 'ids') {
437                         checked = inputs[i].checked;
438                         if (checked) return true;
439                     }
440                 }
441             }
442
443             function filterDataTable( table, column, term ){
444                 if( column ){
445                     table.column( column ).search( term ).draw();
446                 } else {
447                     table.search( term ).draw();
448                 }
449                 clearFilter( term );
450             }
451
452             function clearFilter( term ){
453                 if( term == "" ){
454                     $(".dt_button_clear_filter").addClass("disabled");
455                 } else {
456                     $(".dt_button_clear_filter").removeClass("disabled");
457                 }
458             }
459
460             /* Custom table search configuration: If a table row
461                has an "expired" class, hide it UNLESS the
462                show_expired checkbox is checked */
463             $.fn.dataTable.ext.search.push(
464                 function( settings, searchData, index, rowData, counter ) {
465                     var row = $(settings.aoData[index].nTr);
466                     if( row.hasClass("expired") && !$("#show_expired").prop("checked") ){
467                         return false;
468                     } else {
469                         return true;
470                     }
471                 }
472             );
473
474             $(document).ready(function() {
475
476                 var table = $("#table_additional_contents").DataTable($.extend(true, {}, dataTablesDefaults, {
477                     "order": [[ 4, "desc" ]],
478                     "aoColumnDefs": [
479                         { "sortable": false, "searchable": false, 'targets': [ 'NoSort' ] },
480                         { "type": "anti-the", "targets": [ "anti-the" ] }
481                     ],
482                     "sPaginationType": "full_numbers"
483                 }));
484
485                 $(".delete_news").on("click", function(){
486                     return confirmDelete( _("Are you sure you want to delete this news item? This cannot be undone.") );
487                 });
488
489                 $("#del_form").on("submit",function(){
490                     if ( Checkbox() ) {
491                         return confirmDelete( _("Are you sure you want to delete the selected news?") );
492                     } else {
493                         alert(_("Please select a news item to delete."));
494                         return false;
495                     }
496                 });
497
498                 $("#show_expired").on("change", function(){
499                     /* redraw the DataTable according to the custom search function */
500                     table.draw();
501                 });
502
503                 table.on( 'search.dt', function () {
504                     var term = table.search();
505                     $("#news_keyword").val( term );
506                 });
507
508                 $("#news_keyword").on("keyup", function(){
509                     var term = $(this).val();
510                     filterDataTable( table, null, term );
511                 });
512
513                 $("#news_display_location").on("change", function(){
514                     var term = $(this).val();
515                     filterDataTable( table, 1, term );
516                 });
517
518                 $("#news_library").on("change", function(){
519                     // Table must be filtered by the <option>'s text, not its value
520                     var opt = $(this).find("option:selected").text();
521                     filterDataTable( table, 2, opt );
522                 });
523
524                 $(".dt_button_clear_filter").on("click", function(){
525                     table.search('').columns().search('').draw();
526                     $("#news-filter select").each(function(){
527                         $(this).val("");
528                     });
529                 });
530             });
531         </script>
532     [% ELSE %]
533         <script>
534             $(document).ready(function() {
535                 $("#tabs").tabs();
536                 $("#add_additional_content").validate({
537                     submitHandler: function(form){
538                         if ( ! $("#title_default").val().length > 0 ) {
539                             alert(__("Please specify a title for 'Default'"));
540                             return false;
541                         }
542
543                         form.submit();
544                     }
545                 });
546
547                 $("#submit_form").on("click",function(){
548                     $("#add_additional_content").submit();
549                 });
550
551                 Sticky = $("#toolbar");
552                 Sticky.hcSticky({
553                     stickTo: ".main",
554                     stickyClass: "floating"
555                 });
556
557             });
558         </script>
559     [% END %]
560     [% UNLESS ( wysiwyg ) %]
561         [% Asset.js( "lib/codemirror/codemirror.min.js" ) | $raw %]
562         [% Asset.js( "lib/codemirror/xml.min.js" ) | $raw %]
563         [% Asset.js( "lib/codemirror/lint.min.js" ) | $raw %]
564         [% Asset.js( "lib/linters/htmlhint.min.js" ) | $raw %]
565         [% Asset.js( "lib/codemirror/html-lint.min.js" ) | $raw %]
566         <script>
567             var editor = CodeMirror.fromTextArea(document.getElementById('content'), {
568                 lineNumbers: true,
569                 lineWrapping: true,
570                 lint: true,
571                 mode: "text/html",
572                 gutters: ["CodeMirror-lint-markers"],
573                 viewportMargin: Infinity,
574             });
575         </script>
576     [% ELSE %]
577         [% Asset.js("lib/tiny_mce/tinymce.min.js") | $raw %]
578         [% INCLUDE 'str/tinymce_i18n.inc' %]
579         <script>
580             tinyMCE.init({
581                 verify_html: false,
582                 force_br_newlines : false,
583                 force_p_newlines : false,
584                 forced_root_block : '',
585                 branding : false,
586                 relative_urls : false,
587                 content_css : "[% interface | html %]/[% theme | html %]/css/tinymce.css",
588                 menubar : "file edit view insert format tools table",
589                 mode : "specific_textareas",
590                 plugins : "autoresize table hr link image charmap lists code emoticons",
591                 extended_valid_elements:"style,link[href|rel]",
592                 custom_elements:"style,link,~link",
593                 toolbar : [
594                     "formatselect | bold italic | cut copy paste | alignleft aligncenter alignright | outdent indent | image link unlink anchor cleanup hr",
595                     "table | bullist numlist | undo redo | removeformat | emoticons charmap | forecolor backcolor | code visualaid help"
596                 ],
597             });
598         </script>
599     [% END # /UNLESS wysiwyg %]
600 [% END %]
601
602 [% INCLUDE 'intranet-bottom.inc' %]