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

Last change on this file since 30341 was 29389, checked in by plg, 10 years ago

feature 3133: add colorscheme parameter for themes. This way we can use the
appropriate CSS for selectize (and other things)

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