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