Bug 27944: Add "requested" stage in article request process
[koha.git] / koha-tmpl / opac-tmpl / bootstrap / js / overdrive.js
1 /* global OD_password_required __ */
2
3 if ( typeof KOHA == "undefined" || !KOHA ) {
4     var KOHA = {};
5 }
6
7 KOHA.OverDrive = ( function() {
8     var proxy_base_url = '/cgi-bin/koha/svc/overdrive_proxy';
9     var library_base_url = 'http://api.overdrive.com/v1/libraries/';
10     return {
11         Get: function( url, params, callback ) {
12             $.ajax( {
13                 type: 'GET',
14                 url: url.replace( /https?:\/\/api.overdrive.com\/v1/, proxy_base_url ),
15                 dataType: 'json',
16                 data: params,
17                 error: function( xhr, error ) {
18                     try {
19                         callback( JSON.parse( xhr.responseText ));
20                     } catch ( e ) {
21                         callback( {error: xhr.responseText || true} );
22                     }
23                 },
24                 success: callback
25             } );
26         },
27         GetCollectionURL: function( library_id, callback ) {
28             if ( KOHA.OverDrive.collection_url ) {
29                 callback( KOHA.OverDrive.collection_url );
30                 return;
31             }
32
33             KOHA.OverDrive.Get(
34                 library_base_url + library_id,
35                 {},
36                 function ( data ) {
37                     if ( data.error ) {
38                         callback( data );
39                         return;
40                     }
41
42                     KOHA.OverDrive.collection_url = data.links.products.href;
43
44                     callback( data.links.products.href );
45                 }
46             );
47         },
48         Search: function( library_id, q, limit, offset, callback ) {
49             KOHA.OverDrive.GetCollectionURL( library_id, function( data ) {
50                 if ( data.error ) {
51                     callback( data );
52                     return;
53                 }
54
55                 KOHA.OverDrive.Get(
56                     data,
57                     {q: q, limit: limit, offset: offset},
58                     callback
59                 );
60             } );
61         }
62     };
63 } )();
64
65 KOHA.OverDriveCirculation = new function() {
66     var svc_url = '/cgi-bin/koha/svc/overdrive';
67
68     var error_div = $('<div class="overdrive-error">');
69     function display_error ( error ) {
70         error_div.text(error);
71     }
72
73     var login_link = $('<a href="#">')
74         .click(function(e) {
75             e.preventDefault();
76             if( OD_password_required ) { $("#overdrive-login").modal('show'); }
77             else { login(""); }
78         })
79         .text( __("Log in to your OverDrive account") );
80
81     var login_div = $('<div class="overdrive-login">').append(login_link);
82
83     var details = null;
84
85     function is_logged_in() {
86         return details ? details.is_logged_in : false;
87     }
88
89     var checkout_popup = null;
90     $( document ).ready(function() {
91         checkout_popup = $("#overdrive-checkout");
92         $("#overdrive-login-form").submit(function(e){
93             e.preventDefault();
94             $("#overdrive-login").modal('hide');
95             var ODpassword = $("input[name='ODpassword']").val();
96             login( ODpassword );
97         });
98
99         $("#overdrive-login").on("shown.bs.modal", function(){
100             $("#ODpassword").focus();
101         });
102
103         var p = window.opener;
104         var cb;
105         if (p) {
106             try { cb = p.refresh_overdrive_account_details;}
107             catch(err){ return; } //Catch error if opener is not accessible
108             if (cb) {
109                 cb();
110             } else {
111                 p.location.reload();
112             }
113             window.close();
114         }
115     });
116
117     function display_account (container, data) {
118         if (!data.is_logged_in) {
119             $(container).append(login_div);
120             return;
121         }
122
123         var overdrive_link = $('<a href="https://www.overdrive.com/account/" target="overdrive-account" class="overdrive-link" style="float:right">')
124             .text( __( "OverDrive account page" ) );
125         $(container).append(overdrive_link);
126
127         var logout_link = $('<a href="#logout" class="overdrive-logout" style="float:left">')
128             .click(function(e) {
129                 e.preventDefault();
130                 $(container).empty().append(error_div);
131                 logout(function(data) {
132                     display_account(container, data);
133                 });
134             }).text( __("Log out of your OverDrive account") );
135         $(container).append(logout_link);
136         $(container).append('<br style="clear:both;"/>');
137
138         if (data.checkouts) {
139             var checkouts_div = $('<div class="overdrive-div">').html('<h3>' + __("Checkouts") + '</h3>');
140             var checkouts_list = $('<ul class="overdrive-list">');
141             data.checkouts.items.forEach(function(item) {
142                 item_line(checkouts_list, item);
143             });
144             checkouts_div.append(checkouts_list);
145             $(container).append(checkouts_div);
146         }
147
148         if (data.holds) {
149             var holds_div = $('<div class="overdrive-div">').html('<h3>' + __("Holds") + '</h3>');
150             var holds_list = $('<ul class="overdrive-list">');
151             data.holds.items.forEach(function(item) {
152                 item_line(holds_list, item);
153             });
154             holds_div.append(holds_list);
155             $(container).append(holds_div);
156         }
157     }
158
159     function item_line(ul_el, item) {
160         var line = $('<li class="overdrive-item">');
161         if (item.images) {
162             var thumb_url = item.images.thumbnail;
163             if (thumb_url) {
164                 $('<img class="overdrive-item-thumbnail">')
165                     .attr("src", thumb_url)
166                     .appendTo(line);
167             }
168         }
169         $('<div class="overdrive-item-title">')
170             .text(item.title)
171             .appendTo(line);
172         $('<div class="overdrive-item-subtitle">')
173             .html(item.subtitle)
174             .appendTo(line);
175         $('<div class="overdrive-item-author">')
176             .text(item.author)
177             .appendTo(line);
178         var actions = $('<span class="actions">');
179         display_actions(actions, item.id);
180         $('<div id="action_'+item.id+'" class="actions-menu">')
181             .append(actions)
182             .appendTo(line);
183
184         $(ul_el).append(line);
185     }
186
187     function svc_ajax ( method, params, success_callback ) {
188         return $.ajax({
189             method: method,
190             dataType: "json",
191             url: svc_url,
192             data: params,
193             success: function (data) {
194                 if (data.error) {
195                     display_error(data.error);
196                 }
197                 success_callback(data);
198             },
199             error: function(jqXHR, textStatus, errorThrown) {
200                 display_error(errorThrown);
201             }
202         });
203     }
204
205     function load_account_details ( callback ) {
206         svc_ajax('get', { action: "account" }, function(data) {
207             details = data;
208             callback(data);
209         });
210     }
211
212     function login(p) {
213         svc_ajax('get', { action: "login", password: p }, function(data) {
214             details = null;
215             if( data.login_success ){
216                 $(login_div).detach();
217                 if( $("#overdrive-results-page").length > 0 ){
218                     location.reload();
219                 } else {
220                     KOHA.OverDriveCirculation.display_account_details( $("#opac-user-overdrive") );
221                 }
222             }
223         });
224     }
225
226     function logout (callback) {
227         svc_ajax('post', { action: "logout" }, function(data) {
228             details = null;
229             callback(data);
230         });
231     }
232
233     function item_action (params, el, copies_available) {
234         var id = params.id;
235         svc_ajax('post', params, function(data) {
236             if (data.checkouts) {
237                 details.checkouts = data.checkouts;
238             }
239             if (data.holds) {
240                 details.holds = data.holds;
241             }
242             display_actions(el, id, copies_available);
243         });
244     }
245
246     function item_is_checked_out (id) {
247         if ( !(details && details.checkouts) ) {
248             return null;
249         }
250         var id_uc = id.toUpperCase();
251         var items = details.checkouts.items;
252         for (var i = 0; i < items.length; i++) {
253             if ( items[i].id.toUpperCase() == id_uc ) {
254                 return items[i];
255             }
256         }
257         return null;
258     }
259
260     function item_is_on_hold (id) {
261         if ( !(details && details.holds) ) {
262             return false;
263         }
264         var id_uc = id.toUpperCase();
265         var items = details.holds.items;
266         for (var i = 0; i < items.length; i++) {
267             if ( items[i].id.toUpperCase() == id_uc ) {
268                 return items[i];
269             }
270         }
271         return null;
272     }
273
274     function display_actions(el, id, copies_available) {
275         $(el).empty();
276         if (is_logged_in()) {
277
278             var item = item_is_checked_out(id);
279             if (item) {
280                 var expires = new Date(item.expires);
281                 $('<span class="overdrive-item-status">')
282                     .text( __( "Checked out until: " )  + " " + expires.toLocaleString())
283                     .appendTo(el);
284                 $(el).append(" ");
285
286                 if (item.format) {
287                     var download = $('<a href="#">').appendTo(el);
288                     decorate_button(download, __("Download")  + " " + item.format);
289                     svc_ajax('get', {action: "download-url", id: id, format: item.format}, function(data) {
290                         download.attr("href", data.action);
291                     });
292                     $(el).append(" ");
293                 }
294
295                 if (item.formats) {
296                     var lockable_formats = [];
297                     for (var f in item.formats) {
298                         if (f == item.format) continue;
299
300                         if (item.formats[f]) {
301                             var access = $('<a target="_blank">').appendTo(el);
302                             decorate_button(access, __("Access online") + " " + f);
303                             svc_ajax('get', {action: "download-url", id: id, format: f}, function(data) {
304                                 access.attr("href", data.action);
305                             });
306                             $(el).append(" ");
307                         }
308                         else {
309                             lockable_formats.push(f);
310                         }
311                     }
312                     if (lockable_formats.length > 0 && checkout_popup) {
313                         $(el).append( ajax_button( __("Download as:"), function() {
314                             checkout_format(el, id, lockable_formats, copies_available);
315                         }) ).append(" ");
316                     }
317                 }
318
319                 if (item.format) return item;
320
321                 $(el).append( ajax_button( __("Check in"), function() {
322                     if( confirm( __("Are you sure you want to return this item?") ) ) {
323                         item_action({action: "return", id: id}, el, copies_available + 1);
324                     }
325                 }) );
326
327                 return item;
328             }
329
330             item = item_is_on_hold(id);
331             if (item) {
332                 $('<span class="overdrive-status">')
333                     .text( __("On hold") )
334                     .appendTo(el);
335                 $(el).append(" ");
336             }
337
338             if(copies_available && checkout_popup) {
339                 $(el).append( ajax_button( __("Check out") , function() {
340                     if( confirm( __("Are you sure you want to check out this item?") ) ) {
341                         svc_ajax('post', {action: "checkout", id: id}, function(data) {
342                             if (data.checkouts) {
343                                 details.checkouts = data.checkouts;
344                             }
345                             if (data.holds) {
346                                 details.holds = data.holds;
347                             }
348                             item = display_actions(el, id, copies_available - 1);
349                             if (item && item.formats && !item.format) {
350                                 var has_available_formats = false;
351                                 var lockable_formats = [];
352                                 for (var f in item.formats) {
353                                     if (item.formats[f]) {
354                                         has_available_formats = true;
355                                         break;
356                                     }
357                                     lockable_formats.push(f);
358                                 }
359
360                                 if (!has_available_formats) {
361                                     checkout_format(el, id, lockable_formats, copies_available - 1);
362                                 }
363                             }
364                         });
365                     }
366                 }) );
367             }
368             else if (!item) {
369                 $(el).append( ajax_button( __("Place hold"), function() {
370                     item_action({action: "place-hold", id: id}, el, copies_available);
371                 }) );
372             }
373
374             if (item) {
375                 $(el).append( ajax_button( __("Cancel"), function() {
376                     if( confirm( __("Are you sure you want to cancel this hold?") ) ) {
377                         item_action({action: "remove-hold", id: id}, el, copies_available);
378                     }
379                 }) );
380             }
381             return item;
382         }
383     }
384
385     function ajax_button(label, on_click) {
386         var button = $('<a href="#">')
387             .click(function(e) {
388                 e.preventDefault();
389                 on_click();
390             });
391         decorate_button(button, label);
392         return button;
393     }
394
395     function decorate_button(button, label) {
396         $(button)
397             .addClass("btn btn-primary btn-mini")
398             .css("color","white")
399             .text(label);
400     }
401
402     function checkout_format(el, id, formats, copies_available) {
403         if (formats.length == 0) {
404             alert( __("Item cannot be checked out. There are no available formats") );
405             return false;
406         }
407
408         var checkout_format_list = checkout_popup.find("ul.overdrive-format-list").empty();
409         formats.forEach(function (item) {
410             var li = $('<li>').appendTo(checkout_format_list);
411             $('<input name="checkout-format" type="radio">')
412                 .val(item)
413                 .appendTo(li);
414             li.append(item);
415         });
416         checkout_popup.modal("show");
417         checkout_popup.find(".overdrive-checkout-submit").click(function(e) {
418             e.preventDefault();
419             var format = checkout_format_list.find("input[type='radio'][name='checkout-format']:checked").val();
420             item_action({action: "checkout-format", id: id, format: format}, el, copies_available);
421             $(this).unbind( e );
422             checkout_popup.modal("hide");
423         });
424     }
425
426     this.with_account_details = function( el, callback ) {
427         $(el).append(error_div);
428         load_account_details(function(data) {
429             if (!data.is_logged_in) {
430                 $(el).append(login_div);
431             }
432             callback(data);
433         });
434     };
435
436     this.display_account_details = function( el ) {
437         window.refresh_overdrive_account_details = function () {
438             KOHA.OverDriveCirculation.display_account_details( el );
439         };
440         $(el).empty().append(error_div);
441         load_account_details(function(data) {
442             display_account(el, data);
443         });
444     };
445
446     this.display_error = function( el, error ) {
447         $(el).empty().append(error_div);
448         display_error(error);
449     };
450
451     this.is_logged_in = is_logged_in;
452
453     this.add_actions = function(el, id, copies_available) {
454         var actions = $('<span class="actions">');
455         display_actions(actions, id, copies_available);
456         $('<div id="action_'+id+'" class="actions-menu">')
457             .append(actions)
458             .appendTo(el);
459     };
460 };