Bug 35206: Adjust style of add button on curbside pickups administration
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / admin / curbside_pickup.tt
1 [% USE raw %]
2 [% USE KohaSpan %]
3 [% USE Koha %]
4 [% USE Asset %]
5 [% USE TablesSettings %]
6 [% PROCESS 'i18n.inc' %]
7 [% SET footerjs = 1 %]
8 [% INCLUDE 'doc-head-open.inc' %]
9 <title>[% FILTER collapse %]
10     [% t("Curbside pickup") | html %] &rsaquo;
11     [% t("Administration") | html %] &rsaquo;
12     [% t("Koha") | html %]
13 [% END %]</title>
14 [% INCLUDE 'doc-head-close.inc' %]
15 <style>
16     .pickup-slot {
17         border: 2px solid #b9d8d9;
18         padding: 0 .1em;
19         margin: 0 .1em;
20     }
21 </style>
22 </head>
23
24 <body id="admin_curbside_pickup" class="admin">
25 [% WRAPPER 'header.inc' %]
26     [% INCLUDE 'prefs-admin-search.inc' %]
27 [% END %]
28
29 [% USE format_minutes = format('%02d') %]
30 [% MACRO minutes_format BLOCK %][% IF m != "" %][% format_minutes(m) | html %][% END %][% END %]
31
32 [% WRAPPER 'sub-header.inc' %]
33     [% WRAPPER breadcrumbs %]
34         [% WRAPPER breadcrumb_item %]
35             <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
36         [% END %]
37         [% WRAPPER breadcrumb_item bc_active= 1 %]
38             <span>Curbside pickup</span>
39         [% END %]
40     [% END #/ WRAPPER breadcrumbs %]
41 [% END #/ WRAPPER sub-header.inc %]
42
43 <div class="main container-fluid">
44     <div class="row">
45         <div class="col-sm-10 col-sm-push-2">
46             <main>
47
48 [% FOR m IN messages %]
49     <div class="dialog [% m.type | html %]">
50         [% SWITCH m.code %]
51         [% CASE %]
52             <span>[% m.code | html %]</span>
53         [% END %]
54     </div>
55 [% END %]
56
57 [% IF op == 'list' %]
58
59     <h1>Curbside pickup configuration</h1>
60
61     [% UNLESS Koha.Preference('CurbsidePickup') %]
62         [% SET pref_CurbsidePickup_link = '<a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=CurbsidePickup">CurbsidePickup</a>' %]
63         <div class="dialog message">The [% pref_CurbsidePickup_link | $raw | $KohaSpan %] preference is not enabled, do not forget to enable it to turn the feature on.</div>
64     [% END %]
65     <form method="post" class="form">
66         <div id="curbside_pickup_tabs" class="toptabs">
67             <ul class="nav nav-tabs" role="tablist">
68                 [% FOREACH l IN libraries %]
69                     [% IF loop.first %]
70                     <li role="presentation" class="active">
71                     [% ELSE %]
72                     <li role="presentation">
73                     [% END %]
74                         <a href="#conf-[% l.branchcode | uri %]" aria-controls="conf-[% l.branchcode | html %]" role="tab" data-toggle="tab">[% l.branchname | html %]</a>
75                     </li>
76                 [% END %]
77             </ul>
78
79             <div class="tab-content">
80                 [% FOREACH l IN libraries %]
81                     [% SET branchcode = l.branchcode %]
82                     [% IF loop.first %]
83                     <div id="conf-[% l.branchcode | html %]" role="tabpanel" class="tab-pane active">
84                     [% ELSE %]
85                     <div id="conf-[% l.branchcode | html %]" role="tabpanel" class="tab-pane">
86                     [% END %]
87                         <fieldset class="rows" style="float: none;">
88                             <ol>
89                                 <li>
90                                     <label for="enable-[% l.branchcode | html %]">Enable: </label>
91                                     [% IF policies.$branchcode.enabled %]
92                                         <input name="enable-[% l.branchcode | html %]" id="enable-[% l.branchcode | html %]" value="1" type="checkbox" checked>
93                                     [% ELSE %]
94                                         <input name="enable-[% l.branchcode | html %]" id="enable-[% l.branchcode | html %]" value="1" type="checkbox">
95                                     [% END %]
96                                     <span class="hint">Enable curbside pickup.<span>
97                                 </li>
98
99                                 <li>
100                                     <label for="interval-[% l.branchcode | html %]">Pickup interval: </label>
101                                     <input name="interval-[% l.branchcode | html %]" id="interval-[% l.branchcode | html %]" value="[% policies.$branchcode.pickup_interval | html %]" type="text">
102                                     <span class="hint">Number of minutes each curbside pickup interaction will take.</span>
103                                 </li>
104
105                                 <li>
106                                     <label for="max-per-interval-[% l.branchcode | html %]">Maximum patrons per interval: </label>
107                                     <input name="max-per-interval-[% l.branchcode | html %]" id="max-per-interval-[% l.branchcode | html %]" value="[% policies.$branchcode.patrons_per_interval | html %]" type="text">
108                                     <span class="hint">Maximum number of simultaneous pickups per interval.</span>
109                                 </li>
110
111                                 <li>
112                                     <label for="patron-scheduled-[% l.branchcode | html %]">Patron-scheduled pickup: </label>
113                                     [% IF policies.$branchcode.patron_scheduled_pickup %]
114                                         <input name="patron-scheduled-[% l.branchcode | html %]" id="patron-scheduled-[% l.branchcode | html %]" value="1" type="checkbox" checked>
115                                     [% ELSE %]
116                                         <input name="patron-scheduled-[% l.branchcode | html %]" id="patron-scheduled-[% l.branchcode | html %]" value="1" type="checkbox">
117                                     [% END %]
118                                     <span class="hint">Enable patrons to schedule their own curbside pickups.</span>
119                                 </li>
120
121                                 <li>
122                                     <label for="enable-waiting-holds-only-[% l.branchcode | html %]">Enable for waiting holds only: </label>
123                                     [% IF policies.$branchcode.enable_waiting_holds_only %]
124                                         <input name="enable-waiting-holds-only-[% l.branchcode | html %]" id="enable-waiting-holds-only-[% l.branchcode | html %]" value="1" type="checkbox" checked>
125                                     [% ELSE %]
126                                         <input name="enable-waiting-holds-only-[% l.branchcode | html %]" id="enable-waiting-holds-only-[% l.branchcode | html %]" value="1" type="checkbox">
127                                     [% END %]
128                                     <span class="hint">Enable only if the patron has waiting holds.</span>
129                                 </li>
130                             </ol>
131                         </fieldset>
132
133                         <fieldset class="rows" style="float: none;">
134                             <legend>Curbside pickup hours</legend>
135
136                             <em>Times should be in 24-hour format (00:00 to 23:59).</em>
137
138                             <ol class="pickup_hours"></ol>
139
140                             <ol>
141                                 <li>
142                                     <label>New slot:</label>
143                                     [% days = { "0" = t("Sunday"), "1" = t("Monday"), "2" = t("Tuesday"), "3" = t("Wednesday"), "4" = t("Thursday"), "5" = t("Friday"), "6" = t("Saturday") } %]
144                                     [% SET CalendarFirstDayOfWeek = Koha.Preference("CalendarFirstDayOfWeek") %]
145                                     <div>
146                                         <select id="day-[% l.branchcode | html %]">
147                                             [% FOR i IN [0, 1, 2, 3, 4, 5, 6] %]
148                                                 [% SET d = ( CalendarFirstDayOfWeek + i ) % 7 %]
149                                                 <option value="[% d | html %]">[% days.$d | html %]</option>
150                                             [% END %]
151                                         </select>
152                                             <span>
153                                                 From <input type="text" size="5" class="noEnterSubmit" id="new-start-[% l.branchcode | html %]" placeholder="00:00" />
154                                                 to <input type="text" size="5" class="noEnterSubmit" id="new-end-[% l.branchcode | html %]" placeholder="23:55" />
155                                             </span>
156                                         <input type="button" class="btn btn-default btn-sm add-new-slot" data-branchcode="[% l.branchcode | html %]" value="Add" />
157                                         <span id="invalid_slot_warning" style="display:none;">Invalid format for this new slot, must be '00:00 to 23:59'.</span>
158                                     </div>
159                                 </li>
160
161                             </ol>
162                         </fieldset>
163                     </div>
164                 [% END %]
165             </div>
166         </div>
167
168         <input type="hidden" name="op" value="save" />
169
170         <fieldset class="action">
171             <input type="submit" class="btn btn-primary" value="Save configuration" />
172         </fieldset>
173     </form>
174 [% END %]
175
176             </main>
177         </div> <!-- /.col-sm-10.col-sm-push-2 -->
178
179         <div class="col-sm-2 col-sm-pull-10">
180             <aside>
181                 [% INCLUDE 'admin-menu.inc' %]
182             </aside>
183         </div> <!-- /.col-sm-2.col-sm-pull-10 -->
184      </div> <!-- /.row -->
185
186 [% MACRO jsinclude BLOCK %]
187     [% Asset.js("js/admin-menu.js") | $raw %]
188     <script>
189
190         let opening_slots = {};
191         let slots;
192         [% FOR l IN libraries %]
193             [% SET branchcode = l.branchcode %]
194             slots = [];
195             [% FOR p IN policies.$branchcode.opening_slots %]
196                 slots.push('%s-%s-%s'.format("[% p.day | html %]", format_hhmm("[% p.start_hour | html %]:[% p.start_minute | html %]"), format_hhmm("[% p.end_hour | html %]:[% p.end_minute | html %]")));
197             [% END %]
198             opening_slots["[% l.branchcode | html %]"] = slots;
199         [% END %]
200
201         function format_hhmm(hhmm){
202             let hh, mm;
203             [ hh, mm ] = hhmm.split(':');
204             return String(hh).padStart(2, '0') + ':' + String(mm).padStart(2, '0');
205         }
206         function format_slot(slot){
207             let day, start, end;
208             [ day, start, end ] = slot.split("-");
209             return format_hhmm(start) + _(" to ") + format_hhmm(end);
210         }
211         function delete_slot(node, branchcode){
212             let slot = $(node).find('input').val();
213             opening_slots[branchcode] = $.grep(opening_slots[branchcode], function(elt, index) {
214                 return elt !== slot;
215             });
216             refresh_pickup_hours(branchcode);
217         }
218         function refresh_pickup_hours(branchcode) {
219             let slots_per_day = {};
220             opening_slots[branchcode].forEach(function(slot){
221                 let day, start, end;
222                 [ day, start, end ] = slot.split("-");
223                 if(!slots_per_day[day]) slots_per_day[day] = [];
224                 slots_per_day[day].push(slot);
225             });
226
227             $("#conf-"+branchcode).find(".pickup_hours li").remove();
228
229             const CalendarFirstDayOfWeek = [% Koha.Preference("CalendarFirstDayOfWeek") || 0 | html %];
230             [0, 1, 2, 3, 4, 5, 6]
231                .map(i => ( CalendarFirstDayOfWeek + i ) % 7)
232                .filter(d => d in slots_per_day)
233                .map( day => {
234                     let li_node = $('<li><label>'+get_day_lib(day)+'<label></li>');
235                     slots_per_day[day].sort().forEach(function(slot) {
236                         let span_node = $('<span class="pickup-slot"></span>');
237                         span_node.append('<input type="hidden" name="pickup-slot-'+branchcode+'" value="'+slot+'"/>');
238                         span_node.append('<span>'+format_slot(slot)+'</span>');
239
240                         let delete_link = $('<a href="#" on> <i class="fa fa-trash-can" aria-hidden="true" title="%s"></i>'.format(_("Remove this slot"))).on('click', function(e){ e.preventDefault(); delete_slot($(this).closest('li'), branchcode); });
241                         span_node.append(delete_link);
242
243                         span_node.appendTo(li_node);
244                     });
245                     li_node.appendTo($("#conf-"+branchcode).find(".pickup_hours"));
246                 });
247         }
248         function get_day_lib(day){
249             let lib;
250             switch(day){
251             case 0:
252                 lib = _("Sunday");
253                 break;
254             case 1:
255                 lib = _("Monday");
256                 break;
257             case 2:
258                 lib = _("Tuesday");
259                 break;
260             case 3:
261                 lib = _("Wednesday");
262                 break;
263             case 4:
264                 lib = _("Thursday");
265                 break;
266             case 5:
267                 lib = _("Friday");
268                 break;
269             case 6:
270                 lib = _("Saturday");
271                 break;
272             }
273             return lib;
274         }
275
276         $(document).ready(function(){
277             [% FOR l IN libraries %]
278                 refresh_pickup_hours("[% l.branchcode | html %]");
279             [% END %]
280
281             $(".add-new-slot").on("click", function(){
282                 let branchcode = $(this).data('branchcode');
283                 let day = $("#day-" + branchcode).val();
284                 let start = $("#new-start-" + branchcode).val();
285                 let end = $("#new-end-" + branchcode).val();
286
287                 let start_hour, start_minute, end_hour, end_minute;
288                 [ start_hour, start_minute ] = start.split(":");
289                 [ end_hour, end_minute ] = end.split(":");
290                 if ( start_hour === undefined
291                   || start_minute === undefined
292                   || end_hour === undefined
293                   || end_minute === undefined
294                   || isNaN(parseInt(start_hour))
295                   || isNaN(parseInt(end_hour))
296                   || isNaN(parseInt(start_minute))
297                   || isNaN(parseInt(end_minute))
298                   || start_hour > 23 || start_minute > 59
299                   || end_hour > 23 || end_minute > 59
300                   ) {
301                     $("#invalid_slot_warning").show();
302                     return;
303                 } else {
304                     $("#invalid_slot_warning").hide();
305                 }
306
307                 let new_slot = day + '-' + start + '-' + end;
308                 if ( opening_slots[branchcode].indexOf(new_slot) < 0 )
309                     opening_slots[branchcode].push(new_slot);
310
311                 refresh_pickup_hours(branchcode);
312             })
313         });
314     </script>
315 [% END %]
316 [% INCLUDE 'intranet-bottom.inc' %]