source: trunk/admin/themes/default/template/user_list.tpl @ 25844

Last change on this file since 25844 was 25844, checked in by mistic100, 7 years ago

don't display "null" when email address is empty on users manager

  • Property svn:eol-style set to LF
File size: 38.0 KB
Line 
1{combine_script id='common' load='footer' path='admin/themes/default/js/common.js'}
2
3{combine_script id='jquery.dataTables' load='footer' path='themes/default/js/plugins/jquery.dataTables.js'}
4{combine_css path="themes/default/js/plugins/datatables/css/jquery.dataTables.css"}
5
6{combine_script id='jquery.chosen' load='footer' path='themes/default/js/plugins/chosen.jquery.min.js'}
7{combine_css path="themes/default/js/plugins/chosen.css"}
8
9{combine_script id='jquery.ui.slider' require='jquery.ui' load='footer' path='themes/default/js/ui/minified/jquery.ui.slider.min.js'}
10{combine_css path="themes/default/js/ui/theme/jquery.ui.slider.css"}
11
12{footer_script}
13var selectedMessage_pattern = "{'%d of %d users selected'|translate|escape:javascript}";
14var selectedMessage_none = "{'No user selected of %d users'|translate|escape:javascript}";
15var selectedMessage_all = "{'All %d users are selected'|translate|escape:javascript}";
16var applyOnDetails_pattern = "{'on the %d selected users'|translate|escape:javascript}";
17var newUser_pattern = "✔ {'User %s added'|translate|escape:javascript}";
18var registeredOn_pattern = "{'Registered on %s, %s.'|translate|escape:javascript}";
19var lastVisit_pattern = "{'Last visit on %s, %s.'|translate|escape:javascript}";
20var missingConfirm = "{'You need to confirm deletion'|translate|escape:javascript}";
21var missingUsername = "{'Please, enter a login'|translate|escape:javascript}";
22
23var allUsers = [{$all_users}];
24var selection = [{$selection}];
25var pwg_token = "{$PWG_TOKEN}";
26
27var truefalse = {
28  true:"{'Yes'|translate}",
29  false:"{'No'|translate}",
30};
31{/footer_script}
32
33{footer_script}{literal}
34jQuery(document).ready(function() {
35  /**
36   * Add user
37   */
38  jQuery("#addUser").click(function() {
39    jQuery("#addUserForm").toggle();
40    jQuery("#showAddUser .infos").hide();
41    jQuery("input[name=username]").focus();
42    return false;
43  });
44
45  jQuery("#addUserClose").click(function() {
46    jQuery("#addUserForm").hide();
47    return false;
48  });
49
50  jQuery("#addUserForm").submit(function() {
51    jQuery.ajax({
52      url: "ws.php?format=json&method=pwg.users.add",
53      type:"POST",
54      data: jQuery(this).serialize(),
55      beforeSend: function() {
56        jQuery("#addUserForm .errors").hide();
57
58        if (jQuery("input[name=username]").val() == "") {
59          jQuery("#addUserForm .errors").html('✘ '+missingUsername).show();
60          return false;
61        }
62
63        jQuery("#addUserForm .loading").show();
64      },
65      success:function(data) {
66        oTable.fnDraw();
67        jQuery("#addUserForm .loading").hide();
68
69        var data = jQuery.parseJSON(data);
70        if (data.stat == 'ok') {
71          jQuery("#addUserForm input[type=text], #addUserForm input[type=password]").val("");
72
73          var new_user = data.result.users[0];
74          allUsers.push(parseInt(new_user.id));
75          jQuery("#showAddUser .infos").html(sprintf(newUser_pattern, new_user.username)).show();
76          checkSelection();
77
78          jQuery("#addUserForm").hide();
79        }
80        else {
81          jQuery("#addUserForm .errors").html('✘ '+data.message).show();
82        }
83      },
84      error:function(XMLHttpRequest, textStatus, errorThrows) {
85        jQuery("#addUserForm .loading").hide();
86      }
87    });
88
89    return false;
90  });
91
92  /**
93   * Table with users
94   */
95  /**
96   * find the key from a value in the startStopValues array
97   */
98  function getSliderKeyFromValue(value, values) {
99    for (var key in values) {
100      if (values[key] >= value) {
101        return key;
102      }
103    }
104    return 0;
105  }
106
107  var recent_period_values = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,25,30,40,50,60,80,99];
108
109  function getRecentPeriodInfoFromIdx(idx) {
110    return sprintf(
111      "{/literal}{'%d days'|@translate}{literal}",
112      recent_period_values[idx]
113    );
114  }
115
116  var nb_image_page_values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,35,40,45,50,60,70,80,90,100,200,300,500,999];
117
118  function getNbImagePageInfoFromIdx(idx) {
119    return sprintf(
120      "{/literal}{'%d photos per page'|@translate}{literal}",
121      nb_image_page_values[idx]
122    );
123  }
124
125  /* Formating function for row details */
126  function fnFormatDetails(oTable, nTr) {
127    var userId = oTable.fnGetData(nTr)[0];
128    console.log("userId = "+userId);
129    var sOut = null;
130
131    jQuery.ajax({
132      url: "ws.php?format=json&method=pwg.users.getList",
133      type:"POST",
134      data: {
135        user_id: userId,
136        display: "all",
137      },
138      success:function(data) {
139        jQuery("#user"+userId+" .loading").hide();
140
141        var data = jQuery.parseJSON(data);
142        if (data.stat == 'ok') {
143          var user = data.result.users[0];
144
145          var userDetails = '<form>';
146          userDetails += '<div class="userActions">';
147          userDetails += '<span class="changePasswordDone infos" style="display:none">&#x2714; {/literal}{'Password updated'|translate|escape:javascript}{literal}</span>';
148          userDetails += '<span class="changePassword" style="display:none">{/literal}{'New password'|translate}{literal} <input type="text"> <a href="#" class="buttonLike updatePassword"><img src="themes/default/images/ajax-loader-small.gif" style="margin-bottom:-1px;margin-left:1px;display:none;"><span class="text">{/literal}{'Submit'|translate|escape:javascript}{literal}</span></a> <a href="#" class="cancel">{/literal}{'Cancel'|translate|escape:javascript}{literal}</a></span>';
149          userDetails += '<a class="icon-key changePasswordOpen" href="#">{/literal}{'Change password'|translate|escape:javascript}{literal}</a>';
150          userDetails += '<br><a target="_blank" href="admin.php?page=user_perm&amp;user_id='+userId+'" class="icon-lock">{/literal}{'Permissions'|translate|escape:javascript}{literal}</a>';
151          userDetails += '<br><span class="userDelete"><img class="loading" src="themes/default/images/ajax-loader-small.gif" style="display:none;"><a href="#" class="icon-trash" data-user_id="'+userId+'">{/literal}{'Delete'|translate|escape:javascript}{literal}</a></span>';
152          userDetails += '</div>';
153
154          userDetails += '<span class="changeUsernameOpen"><strong class="username">'+user.username+'</strong> <a href="#" class="icon-pencil">{/literal}{'Change username'|translate|escape:javascript}{literal}</a></span>';
155          userDetails += '<span class="changeUsername" style="display:none">';
156          userDetails += '<input type="text"> <a href="#" class="buttonLike updateUsername"><img src="themes/default/images/ajax-loader-small.gif" style="margin-bottom:-1px;margin-left:1px;display:none;"><span class="text">{/literal}{'Submit'|translate}{literal}</span></a> <a href="#" class="cancel">{/literal}{'Cancel'|translate|escape:javascript}{literal}</a>';
157          userDetails += '</span>';
158
159          userDetails += '<div class="userStats">';
160          userDetails += sprintf(registeredOn_pattern, user.registration_date_string, user.registration_date_since);
161
162          if (typeof user.last_visit != 'undefined') {
163            userDetails += '<br>'+sprintf(lastVisit_pattern, user.last_visit_string, user.last_visit_since);
164          }
165
166          userDetails += '</div>';
167          userDetails += '<div class="userPropertiesContainer">';
168          userDetails += '<input type="hidden" name="user_id" value="'+user.id+'">';
169          userDetails += '<div class="userPropertiesSet">';
170          userDetails += '<div class="userPropertiesSetTitle">{/literal}{'Properties'|translate}{literal}</div>';
171
172          userDetails += '<div class="userProperty"><strong>{/literal}{'Email address'|translate}{literal}</strong>';
173          userDetails += '<br><input name="email" type="text" value="'+ (user.email||'') +'"></div>';
174
175          userDetails += '<div class="userProperty"><strong>{/literal}{'Status'|translate}{literal}</strong>';
176          userDetails += '<br><select name="status">';
177          jQuery("#action select[name=status] option").each(function() {
178            var selected = '';
179            if (user.status == jQuery(this).val()) {
180              selected = ' selected="selected"';
181            }
182            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
183          });
184          userDetails += '</select></div>';
185
186          userDetails += '<div class="userProperty"><strong>{/literal}{'Privacy level'|translate}{literal}</strong>';
187          userDetails += '<br><select name="level">';
188          jQuery("#action select[name=level] option").each(function() {
189            var selected = '';
190            if (user.level == jQuery(this).val()) {
191              selected = ' selected="selected"';
192            }
193            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
194          });
195          userDetails += '</select></div>';
196
197          var checked = '';
198          if (user.enabled_high == 'true') {
199            checked = ' checked="checked"';
200          }
201          userDetails += '<div class="userProperty"><label><input type="checkbox" name="enabled_high"'+checked+'> <strong>{/literal}{'High definition enabled'|translate}{literal}</strong></label>';
202          userDetails += '</div>';
203
204          userDetails += '<div class="userProperty"><strong>{/literal}{'Groups'|translate}{literal}</strong>';
205          userDetails += '<br><select multiple class="chzn-select" style="width:340px;" name="group_id[]">';
206          jQuery("#action select[name=associate] option").each(function() {
207            var selected = '';
208            if (user.groups.indexOf( parseInt(jQuery(this).val()) ) != -1) {
209              selected = ' selected="selected"';
210            }
211            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
212          });
213          userDetails += '</select></div>';
214          // userDetails += '<br>'+user.groups.join(",")+'</div>';
215
216          userDetails += '</div><div class="userPropertiesSet userPrefs">';
217          userDetails += '<div class="userPropertiesSetTitle">{/literal}{'Preferences'|translate}{literal}</div>';
218
219          userDetails += '<div class="userProperty"><strong class="nb_image_page_infos"></strong>';
220          userDetails += '<div class="nb_image_page"></div>';
221          userDetails += '<input type="hidden" name="nb_image_page" value="'+user.nb_image_page+'">';
222          userDetails += '</div>';
223
224          userDetails += '<div class="userProperty"><strong>{/literal}{'Theme'|translate|escape:javascript}{literal}</strong>';
225          userDetails += '<br><select name="theme">';
226          jQuery("#action select[name=theme] option").each(function() {
227            var selected = '';
228            if (user.theme == jQuery(this).val()) {
229              selected = ' selected="selected"';
230            }
231            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
232          });
233          userDetails += '</select></div>';
234
235          userDetails += '<div class="userProperty"><strong>{/literal}{'Language'|translate}{literal}</strong>';
236          userDetails += '<br><select name="language">';
237          jQuery("#action select[name=language] option").each(function() {
238            var selected = '';
239            if (user.language == jQuery(this).val()) {
240              selected = ' selected="selected"';
241            }
242            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
243          });
244          userDetails += '</select></div>';
245
246          userDetails += '<div class="userProperty"><strong>{/literal}{'Recent period'|translate}{literal}</strong> <span class="recent_period_infos"></span>';
247          userDetails += '<div class="recent_period"></div>';
248          userDetails += '<input type="hidden" name="recent_period" value="'+user.recent_period+'">';
249          userDetails += '</div>';
250
251          var checked = '';
252          if (user.expand == 'true') {
253            checked = ' checked="checked"';
254          }
255          userDetails += '<div class="userProperty"><label><input type="checkbox" name="expand"'+checked+'> <strong>{/literal}{'Expand all albums'|translate}{literal}</strong></label>';
256          userDetails += '</div>';
257
258          var checked = '';
259          if (user.show_nb_comments == 'true') {
260            checked = ' checked="checked"';
261          }
262          userDetails += '<div class="userProperty"><label><input type="checkbox" name="show_nb_comments"'+checked+'> <strong>{/literal}{'Show number of comments'|translate}{literal}</strong></label>';
263          userDetails += '</div>';
264
265          var checked = '';
266          if (user.show_nb_hits == 'true') {
267            checked = ' checked="checked"';
268          }
269          userDetails += '<div class="userProperty"><label><input type="checkbox" name="show_nb_hits"'+checked+'> <strong>{/literal}{'Show number of hits'|translate}{literal}</strong></label>';
270          userDetails += '</div>';
271          userDetails += '</div>';
272          userDetails += '<div style="clear:both"></div></div>';
273
274          userDetails += '<span class="infos propertiesUpdateDone" style="display:none">&#x2714; ';
275          userDetails += sprintf("{/literal}{'User %s updated'|translate|escape:javascript}{literal}", user.username);
276          userDetails += '</span>';
277          userDetails += '<input type="submit" value="{/literal}{'Update user'|translate|escape:javascript}{literal}" style="display:none;" data-user_id="'+userId+'">';
278          userDetails += '<img class="submitWait" src="themes/default/images/ajax-loader-small.gif" style="display:none">'
279          userDetails += '</form>';
280
281          jQuery("#user"+userId).append(userDetails);
282          jQuery(".chzn-select").chosen();
283
284          /* nb_image_page slider */
285          var nb_image_page_init = getSliderKeyFromValue(jQuery('input[name=nb_image_page]').val(), nb_image_page_values);
286         
287          jQuery('#user'+userId+' .nb_image_page_infos').html(getNbImagePageInfoFromIdx(nb_image_page_init));
288         
289          jQuery('#user'+userId+' .nb_image_page').slider({
290            range: "min",
291            min: 0,
292            max: nb_image_page_values.length - 1,
293            value: nb_image_page_init,
294            slide: function( event, ui ) {
295              jQuery('#user'+userId+' .nb_image_page_infos').html(getNbImagePageInfoFromIdx(ui.value));
296            },
297            stop: function( event, ui ) {
298              jQuery('#user'+userId+' input[name=nb_image_page]').val(nb_image_page_values[ui.value]).trigger('change');
299            }
300          });
301
302          /* recent_period slider */
303          var recent_period_init = getSliderKeyFromValue(jQuery('input[name=recent_period]').val(), recent_period_values);
304          jQuery('#user'+userId+' .recent_period_infos').html(getRecentPeriodInfoFromIdx(recent_period_init));
305         
306          jQuery('#user'+userId+' .recent_period').slider({
307            range: "min",
308            min: 0,
309            max: recent_period_values.length - 1,
310            value: recent_period_init,
311            slide: function( event, ui ) {
312              jQuery('#user'+userId+' .recent_period_infos').html(getRecentPeriodInfoFromIdx(ui.value));
313            },
314            stop: function( event, ui ) {
315              jQuery('#user'+userId+' input[name=recent_period]').val(recent_period_values[ui.value]).trigger('change');
316            }
317          });
318        }
319        else {
320          console.log('error loading user details');
321        }
322      },
323      error:function(XMLHttpRequest, textStatus, errorThrows) {
324        console.log('technical error loading user details');
325      }
326    });
327 
328    return '<div id="user'+userId+'" class="userProperties"><img class="loading" src="themes/default/images/ajax-loader-small.gif"></div>';
329  }
330
331  /* change password */
332  jQuery(document).on('click', '.changePasswordOpen',  function() {
333    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
334
335    jQuery(this).hide();
336    jQuery('#user'+userId+' .changePasswordDone').hide();
337    jQuery('#user'+userId+' .changePassword').show();
338    jQuery('#user'+userId+' .changePassword input[type=text]').focus();
339
340    return false;
341  });
342
343  jQuery(document).on('click', '.changePassword a.updatePassword',  function() {
344    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
345
346    jQuery('#user'+userId+' .changePassword a .text').hide();
347    jQuery('#user'+userId+' .changePassword a img').show();
348
349    jQuery.ajax({
350      url: "ws.php?format=json&method=pwg.users.setInfo",
351      type:"POST",
352      data: {
353        user_id:userId,
354        password: jQuery('#user'+userId+' .changePassword input[type=text]').val()
355      },
356      beforeSend: function() {
357        jQuery('#user'+userId+' .changePassword input[type=text]').val("");
358      },
359      success:function(data) {
360        jQuery('#user'+userId+' .changePassword a .text').show();
361        jQuery('#user'+userId+' .changePassword a img').hide();
362        jQuery('#user'+userId+' .changePassword').hide();
363        jQuery('#user'+userId+' .changePasswordOpen').show();
364        jQuery('#user'+userId+' .changePasswordDone').show();
365      },
366      error:function(XMLHttpRequest, textStatus, errorThrows) {
367      }
368    });
369
370    return false;
371  });
372
373  jQuery(document).on('click', '.changePassword a.cancel',  function() {
374    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
375
376    jQuery('#user'+userId+' .changePassword').hide();
377    jQuery('#user'+userId+' .changePasswordOpen').show();
378
379    return false;
380  });
381
382  /* change username */
383  jQuery(document).on('click', '.changeUsernameOpen a',  function() {
384    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
385    var username = jQuery('#user'+userId+' .username').html();
386
387    jQuery('#user'+userId+' .changeUsernameOpen').hide();
388    jQuery('#user'+userId+' .changeUsername').show();
389    jQuery('#user'+userId+' .changeUsername input[type=text]').val(username).focus();
390
391    return false;
392  });
393
394  jQuery(document).on('click', 'a.updateUsername',  function() {
395    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
396
397    jQuery('#user'+userId+' .changeUsername a .text').hide();
398    jQuery('#user'+userId+' .changeUsername a img').show();
399
400    jQuery.ajax({
401      url: "ws.php?format=json&method=pwg.users.setInfo",
402      type:"POST",
403      data: {
404        user_id:userId,
405        username: jQuery('#user'+userId+' .changeUsername input[type=text]').val()
406      },
407      success:function(data) {
408        jQuery('#user'+userId+' .changeUsername a .text').show();
409        jQuery('#user'+userId+' .changeUsername a img').hide();
410        jQuery('#user'+userId+' .changeUsername').hide();
411        jQuery('#user'+userId+' .changeUsernameOpen').show();
412
413        var data = jQuery.parseJSON(data);
414        jQuery('#user'+userId+' .username').html(data.result.users[0].username);
415      },
416      error:function(XMLHttpRequest, textStatus, errorThrows) {
417      }
418    });
419
420    return false;
421  });
422
423  jQuery(document).on('click', '.changeUsername a.cancel',  function() {
424    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
425
426    jQuery('#user'+userId+' .changeUsername').hide();
427    jQuery('#user'+userId+' .changeUsernameOpen').show();
428
429    return false;
430  });
431
432  /* display the "save" button when a field changes */
433  jQuery(document).on('change', '.userProperties input, .userProperties select',  function() {
434    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
435
436    jQuery('#user'+userId+' input[type=submit]').show();
437    jQuery('#user'+userId+' .propertiesUpdateDone').hide();
438  });
439
440  /* delete user */
441  jQuery(document).on('click', '.userDelete a',  function() {
442    if (!confirm("{/literal}{'Are you sure?'|translate|escape:javascript}{literal}")) {
443      return false;
444    }
445
446    var userId = jQuery(this).data('user_id');
447    var username = jQuery('#user'+userId+' .username').html();
448
449    jQuery.ajax({
450      url: "ws.php?format=json&method=pwg.users.delete",
451      type:"POST",
452      data: {
453        user_id:userId,
454        pwg_token:pwg_token
455      },
456      beforeSend: function() {
457        jQuery('#user'+userId+' .userDelete .loading').show();
458      },
459      success:function(data) {
460        oTable.fnDraw();
461        jQuery('#showAddUser .infos').html('&#x2714; User '+username+' deleted').show();
462      },
463      error:function(XMLHttpRequest, textStatus, errorThrows) {
464        jQuery('#user'+userId+' .userDelete .loading').hide();
465      }
466    });
467
468    return false;
469  });
470
471  jQuery(document).on('click', '.userProperties input[type=submit]',  function() {
472    var userId = jQuery(this).data('user_id');
473
474    var formData = jQuery('#user'+userId+' form').serialize();
475
476    if (jQuery('#user'+userId+' form select[name="group_id[]"] option:selected').length == 0) {
477      formData += '&group_id=-1';
478    }
479
480    if (!jQuery('#user'+userId+' form input[name=enabled_high]').is(':checked')) {
481      formData += '&enabled_high=false';
482    }
483
484    if (!jQuery('#user'+userId+' form input[name=expand]').is(':checked')) {
485      formData += '&expand=false';
486    }
487
488    if (!jQuery('#user'+userId+' form input[name=show_nb_hits]').is(':checked')) {
489      formData += '&show_nb_hits=false';
490    }
491
492    if (!jQuery('#user'+userId+' form input[name=show_nb_comments]').is(':checked')) {
493      formData += '&show_nb_comments=false';
494    }
495
496    jQuery.ajax({
497      url: "ws.php?format=json&method=pwg.users.setInfo",
498      type:"POST",
499      data: formData,
500      beforeSend: function() {
501        jQuery('#user'+userId+' .submitWait').show();
502      },
503      success:function(data) {
504        jQuery('#user'+userId+' .submitWait').hide();
505        jQuery('#user'+userId+' input[type=submit]').hide();
506        jQuery('#user'+userId+' .propertiesUpdateDone').show();
507      },
508      error:function(XMLHttpRequest, textStatus, errorThrows) {
509        jQuery('#user'+userId+' .submitWait').hide();
510      }
511    });
512
513    return false;
514  });
515
516  /* Add event listener for opening and closing details
517   * Note that the indicator for showing which row is open is not controlled by DataTables,
518   * rather it is done here
519   */
520  jQuery(document).on('click', '#userList tbody td .openUserDetails',  function() {
521    var nTr = this.parentNode.parentNode;
522    if (jQuery(this).hasClass('icon-angle-circled-up')) {
523      /* This row is already open - close it */
524      jQuery(this).removeClass('icon-angle-circled-up').addClass('icon-angle-circled-down').attr('title', 'Open user details');
525      oTable.fnClose( nTr );
526    }
527    else {
528      /* Open this row */
529      jQuery(this).removeClass('icon-angle-circled-down').addClass('icon-angle-circled-up').attr('title', 'Close user details');
530      oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
531    }
532  });
533
534
535  /* first column must be prefixed with the open/close icon */
536  var aoColumns = [
537    {
538      'bVisible':false
539    },
540    {
541      "mRender": function(data, type, full) {
542        return '<span title="Open user details" class="icon-angle-circled-down openUserDetails"></span> <label><input type="checkbox" data-user_id="'+full[0]+'"> '+data+'</label>';
543      }
544    }
545  ];
546
547  for (i=2; i<jQuery("#userList thead tr th").length; i++) {
548    aoColumns.push(null);
549  }
550
551  var oTable = jQuery('#userList').dataTable({
552    "iDisplayLength": 10,
553    "bDeferRender": true,
554    "bProcessing": true,
555    "bServerSide": true,
556                "sServerMethod": "POST",
557    "sAjaxSource": "admin/user_list_backend.php",
558    "oLanguage": {
559      "sProcessing": "{/literal}{'Loading...'|translate|escape:'javascript'}{literal}",
560      "sLengthMenu": sprintf("{/literal}{'Show %s users'|translate|escape:'javascript'}{literal}", '_MENU_'),
561      "sZeroRecords": "{/literal}{'No matching user found'|translate|escape:'javascript'}{literal}",
562      "sInfo": sprintf("{/literal}{'Showing %s to %s of %s users'|translate|escape:'javascript'}{literal}", '_START_', '_END_', '_TOTAL_'),
563      "sInfoEmpty": "{/literal}{'No matching user found'|translate|escape:'javascript'}{literal}",
564      "sInfoFiltered": sprintf("{/literal}{'(filtered from %s total users)'|translate|escape:'javascript'}{literal}", '_MAX_'),
565      "sSearch": '<span class="icon-search"></span>'+"{/literal}{'Search'|translate|escape:'javascript'}{literal}",
566      "sLoadingRecords": "{/literal}{'Loading...'|translate|escape:'javascript'}{literal}",
567      "oPaginate": {
568          "sFirst":    "{/literal}{'First'|translate|escape:'javascript'}{literal}",
569          "sPrevious": '← '+"{/literal}{'Previous'|translate|escape:'javascript'}{literal}",
570          "sNext":     "{/literal}{'Next'|translate|escape:'javascript'}{literal}"+' →',
571          "sLast":     "{/literal}{'Last'|translate|escape:'javascript'}{literal}",
572      }
573    },
574    "fnDrawCallback": function( oSettings ) {
575      jQuery("#userList input[type=checkbox]").each(function() {
576        var user_id = jQuery(this).data("user_id");
577        jQuery(this).prop('checked', (selection.indexOf(user_id) != -1));
578      });
579    },
580    "aoColumns": aoColumns
581  });
582
583  /**
584   * Selection management
585   */
586  function checkSelection() {
587    if (selection.length > 0) {
588      jQuery("#forbidAction").hide();
589      jQuery("#permitAction").show();
590
591      jQuery("#applyOnDetails").text(
592        sprintf(
593          applyOnDetails_pattern,
594          selection.length
595        )
596      );
597
598      if (selection.length == allUsers.length) {
599        jQuery("#selectedMessage").text(
600          sprintf(
601            selectedMessage_all,
602            allUsers.length
603          )
604        );
605      }
606      else {
607        jQuery("#selectedMessage").text(
608          sprintf(
609            selectedMessage_pattern,
610            selection.length,
611            allUsers.length
612          )
613        );
614      }
615    }
616    else {
617      jQuery("#forbidAction").show();
618      jQuery("#permitAction").hide();
619
620      jQuery("#selectedMessage").text(
621        sprintf(
622          selectedMessage_none,
623          allUsers.length
624        )
625      );
626    }
627
628    jQuery("#applyActionBlock .infos").hide();
629  }
630
631  jQuery(document).on('change', '#userList input[type=checkbox]',  function() {
632    var user_id = jQuery(this).data("user_id");
633
634    array_delete(selection, user_id);
635
636    if (jQuery(this).is(":checked")) {
637      selection.push(user_id);
638    }
639
640    checkSelection();
641  });
642
643  jQuery("#selectAll").click(function () {
644    selection = allUsers;
645    jQuery("#userList input[type=checkbox]").prop('checked', true);
646    checkSelection();
647    return false;
648  });
649
650  jQuery("#selectNone").click(function () {
651    selection = [];
652    jQuery("#userList input[type=checkbox]").prop('checked', false);
653    checkSelection();
654    return false;
655  });
656
657  jQuery("#selectInvert").click(function () {
658    var newSelection = [];
659    for(var i in allUsers)
660    {
661      if (selection.indexOf(allUsers[i]) == -1) {
662        newSelection.push(allUsers[i]);
663      }
664    }
665    selection = newSelection;
666
667    jQuery("#userList input[type=checkbox]").each(function() {
668      var user_id = jQuery(this).data("user_id");
669      jQuery(this).prop('checked', (selection.indexOf(user_id) != -1));
670    });
671
672    checkSelection();
673    return false;
674  });
675
676  /**
677   * Action management
678   */
679  jQuery("[id^=action_]").hide();
680 
681  jQuery("select[name=selectAction]").change(function () {
682    jQuery("#applyActionBlock .infos").hide();
683
684    jQuery("[id^=action_]").hide();
685
686    jQuery("#action_"+$(this).prop("value")).show();
687 
688    if (jQuery(this).val() != -1) {
689      jQuery("#applyActionBlock").show();
690    }
691    else {
692      jQuery("#applyActionBlock").hide();
693    }
694  });
695
696  jQuery("#permitAction input, #permitAction select").click(function() {
697    jQuery("#applyActionBlock .infos").hide();
698  });
699
700  jQuery("#applyAction").click(function() {
701    var action = jQuery("select[name=selectAction]").prop("value");
702    var method = 'pwg.users.setInfo';
703    var data = {
704      user_id: selection
705    };
706
707    switch (action) {
708      case 'delete':
709        if (!jQuery("input[name=confirm_deletion]").is(':checked')) {
710          alert(missingConfirm);
711          return false;
712        }
713        method = 'pwg.users.delete';
714        data.pwg_token = pwg_token;
715        break;
716      case 'group_associate':
717        method = 'pwg.groups.addUser';
718        data.group_id = jQuery("select[name=associate]").prop("value");
719        break;
720      case 'group_dissociate':
721        method = 'pwg.groups.deleteUser';
722        data.group_id = jQuery("select[name=dissociate]").prop("value");
723        break;
724      case 'status':
725        data.status = jQuery("select[name=status]").prop("value");
726        break;
727      case 'enabled_high':
728        data.enabled_high = jQuery("input[name=enabled_high]:checked").val();
729        break;
730      case 'level':
731        data.level = jQuery("select[name=level]").val();
732        break;
733      case 'nb_image_page':
734        data.nb_image_page = jQuery("input[name=nb_image_page]").val();
735        break;
736      case 'theme':
737        data.theme = jQuery("select[name=theme]").val();
738        break;
739      case 'language':
740        data.language = jQuery("select[name=language]").val();
741        break;
742      case 'recent_period':
743        data.recent_period = jQuery("input[name=recent_period]").val();
744        break;
745      case 'expand':
746        data.expand = jQuery("input[name=expand]:checked").val();
747        break;
748      case 'show_nb_comments':
749        data.show_nb_comments = jQuery("input[name=show_nb_comments]:checked").val();
750        break;
751      case 'show_nb_hits':
752        data.show_nb_hits = jQuery("input[name=show_nb_hits]:checked").val();
753        break;
754      default:
755        alert("Unexpected action");
756        return false;
757    }
758
759    jQuery.ajax({
760      url: "ws.php?format=json&method="+method,
761      type:"POST",
762      data: data,
763      beforeSend: function() {
764        jQuery("#applyActionLoading").show();
765      },
766      success:function(data) {
767        oTable.fnDraw();
768        jQuery("#applyActionLoading").hide();
769        jQuery("#applyActionBlock .infos").show();
770
771        if (action == 'delete') {
772          var allUsers_new = [];
773          for(var i in allUsers)
774          {
775            if (selection.indexOf(allUsers[i]) == -1) {
776              allUsers_new.push(allUsers[i]);
777            }
778          }
779          allUsers = allUsers_new;
780          console.log('allUsers_new.length = '+allUsers_new.length);
781          selection = [];
782          checkSelection();
783        }
784      },
785      error:function(XMLHttpRequest, textStatus, errorThrows) {
786        jQuery("#applyActionLoading").hide();
787      }
788    });
789
790    return false;
791  });
792
793});
794{/literal}{/footer_script}
795
796{literal}
797<style>
798.dataTables_wrapper, .dataTables_info {clear:none;}
799table.dataTable {clear:right;padding-top:10px;}
800.dataTable td img {margin-bottom: -6px;margin-left: -6px;}
801.paginate_enabled_previous, .paginate_enabled_previous:hover, .paginate_disabled_previous, .paginate_enabled_next, .paginate_enabled_next:hover, .paginate_disabled_next {background:none;}
802.paginate_enabled_previous, .paginate_enabled_next {color:#005E89 !important;}
803.paginate_enabled_previous:hover, .paginate_enabled_next:hover {color:#D54E21 !important; text-decoration:underline !important;}
804
805.paginate_disabled_next, .paginate_enabled_next {padding-right:3px;}
806.bulkAction {margin-top:10px;}
807#addUserForm p {margin-left:0;}
808#applyActionBlock .actionButtons {margin-left:0;}
809span.infos, span.errors {background-image:none; padding:2px 5px; margin:0;border-radius:5px;}
810
811.userStats {margin-top:10px;}
812.recent_period_infos {margin-left:10px;}
813.nb_image_page, .recent_period {width:340px;margin-top:5px;}
814</style>
815{/literal}
816
817<div class="titrePage">
818  <h2>{'User list'|@translate}</h2>
819</div>
820
821<p class="showCreateAlbum" id="showAddUser">
822  <a href="#" id="addUser" class="icon-plus-circled">{'Add a user'|translate}</a>
823  <span class="infos" style="display:none"></span>
824</p>
825
826<form id="addUserForm" style="display:none" method="post" name="add_user" action="{$F_ADD_ACTION}">
827  <fieldset>
828    <legend>{'Add a user'|@translate}</legend>
829
830    <p>
831      <strong>{'Username'|translate}</strong><br>
832      <input type="text" name="username" maxlength="50" size="20">
833    </p>
834
835    <p>
836      <strong>{'Password'|translate}</strong><br>
837      <input type="{if $Double_Password}password{else}text{/if}" name="password">
838    </p>
839   
840{if $Double_Password}
841    <p>
842      <strong>{'Confirm Password'|@translate}</strong><br>
843      <input type="password" name="password_confirm">
844    </p>
845{/if}
846
847    <p>
848      <strong>{'Email address'|@translate}</strong><br>
849      <input type="text" name="email">
850    </p>
851
852    <p>
853      <label><input type="checkbox" name="send_password_by_mail"> <strong>{'Send connection settings by email'|@translate}</strong></label>
854    </p>
855
856    <p class="actionButtons">
857      <input class="submit" name="submit_add" type="submit" value="{'Submit'|@translate}">
858      <a href="#" id="addUserClose">{'Cancel'|@translate}</a>
859      <span class="loading" style="display:none"><img src="themes/default/images/ajax-loader-small.gif"></span>
860      <span class="errors" style="display:none"></span>
861    </p>
862  </fieldset>
863</form>
864
865<form method="post" name="preferences" action="">
866
867<table id="userList">
868  <thead>
869    <tr>
870      <th>id</th>
871      <th>{'Username'|@translate}</th>
872      <th>{'Status'|@translate}</th>
873      <th>{'Email address'|@translate}</th>
874      <th>{'registration date'|@translate}</th>
875    </tr>
876  </thead>
877</table>
878
879<div style="clear:right"></div>
880
881<p class="checkActions">
882  {'Select:'|@translate}
883  <a href="#" id="selectAll">{'All'|@translate}</a>,
884  <a href="#" id="selectNone">{'None'|@translate}</a>,
885  <a href="#" id="selectInvert">{'Invert'|@translate}</a>
886
887  <span id="selectedMessage"></span>
888</p>
889
890<fieldset id="action">
891  <legend>{'Action'|@translate}</legend>
892
893  <div id="forbidAction"{if count($selection) != 0} style="display:none"{/if}>{'No user selected, no action possible.'|@translate}</div>
894  <div id="permitAction"{if count($selection) == 0} style="display:none"{/if}>
895
896    <select name="selectAction">
897      <option value="-1">{'Choose an action'|@translate}</option>
898      <option disabled="disabled">------------------</option>
899      <option value="delete" class="icon-trash">{'Delete selected users'|@translate}</option>
900      <option value="status">{'Status'|@translate}</option>
901      <option value="group_associate">{'associate to group'|translate}</option>
902      <option value="group_dissociate">{'dissociate from group'|@translate}</option>
903      <option value="enabled_high">{'High definition enabled'|@translate}</option>
904      <option value="level">{'Privacy level'|@translate}</option>
905      <option value="nb_image_page">{'Number of photos per page'|@translate}</option>
906      <option value="theme">{'Theme'|@translate}</option>
907      <option value="language">{'Language'|@translate}</option>
908      <option value="recent_period">{'Recent period'|@translate}</option>
909      <option value="expand">{'Expand all albums'|@translate}</option>
910{if $ACTIVATE_COMMENTS}
911      <option value="show_nb_comments">{'Show number of comments'|@translate}</option>
912{/if}
913      <option value="show_nb_hits">{'Show number of hits'|@translate}</option>
914    </select>
915
916    {* delete *}
917    <div id="action_delete" class="bulkAction">
918      <p><label><input type="checkbox" name="confirm_deletion" value="1"> {'Are you sure?'|@translate}</label></p>
919    </div>
920
921    {* status *}
922    <div id="action_status" class="bulkAction">
923      <select name="status">
924        {html_options options=$pref_status_options selected=$pref_status_selected}
925      </select>
926    </div>
927
928    {* group_associate *}
929    <div id="action_group_associate" class="bulkAction">
930      {html_options name=associate options=$association_options selected=$associate_selected}
931    </div>
932
933    {* group_dissociate *}
934    <div id="action_group_dissociate" class="bulkAction">
935      {html_options name=dissociate options=$association_options selected=$dissociate_selected}
936    </div>
937
938    {* enabled_high *}
939    <div id="action_enabled_high" class="bulkAction">
940      <label><input type="radio" name="enabled_high" value="true">{'Yes'|@translate}</label>
941      <label><input type="radio" name="enabled_high" value="false" checked="checked">{'No'|@translate}</label>
942    </div>
943
944    {* level *}
945    <div id="action_level" class="bulkAction">
946      <select name="level" size="1">
947        {html_options options=$level_options selected=$level_selected}
948      </select>
949    </div>
950
951    {* nb_image_page *}
952    <div id="action_nb_image_page" class="bulkAction">
953      <input size="4" maxlength="3" type="text" name="nb_image_page" value="{$NB_IMAGE_PAGE}">
954    </div>
955
956    {* theme *}
957    <div id="action_theme" class="bulkAction">
958      <select name="theme" size="1">
959        {html_options options=$theme_options selected=$theme_selected}
960      </select>
961    </div>
962
963    {* language *}
964    <div id="action_language" class="bulkAction">
965      <select name="language" size="1">
966        {html_options options=$language_options selected=$language_selected}
967      </select>
968    </div>
969
970    {* recent_period *}
971    <div id="action_recent_period" class="bulkAction">
972      <input type="text" size="3" maxlength="2" name="recent_period" value="{$RECENT_PERIOD}">
973    </div>
974
975    {* expand *}
976    <div id="action_expand" class="bulkAction">
977      <label><input type="radio" name="expand" value="true">{'Yes'|@translate}</label>
978      <label><input type="radio" name="expand" value="false" checked="checked">{'No'|@translate}</label>
979    </div>
980
981    {* show_nb_comments *}
982    <div id="action_show_nb_comments" class="bulkAction">
983      <label><input type="radio" name="show_nb_comments" value="true">{'Yes'|@translate}</label>
984      <label><input type="radio" name="show_nb_comments" value="false" checked="checked">{'No'|@translate}</label>
985    </div>
986
987    {* show_nb_hits *}
988    <div id="action_show_nb_hits" class="bulkAction">
989      <label><input type="radio" name="show_nb_hits" value="true">{'Yes'|@translate}</label>
990      <label><input type="radio" name="show_nb_hits" value="false" checked="checked">{'No'|@translate}</label>
991    </div>
992
993    <p id="applyActionBlock" style="display:none" class="actionButtons">
994      <input id="applyAction" class="submit" type="submit" value="{'Apply action'|@translate}" name="submit"> <span id="applyOnDetails"></span>
995      <span id="applyActionLoading" style="display:none"><img src="themes/default/images/ajax-loader-small.gif"></span>
996      <span class="infos" style="display:none">&#x2714; {'Users modified'|translate}</span>
997    </p>
998
999  </div> {* #permitAction *}
1000</fieldset>
1001
1002</form>
Note: See TracBrowser for help on using the repository browser.