source: branches/2.6/admin/themes/default/template/user_list.tpl @ 27836

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

bug 3053 fixed: columns "groups" and "privacy level" come back in Piwigo 2.6
user manager (which still needs improvement on filtering options...)

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