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

Last change on this file since 28703 was 28703, checked in by mistic100, 10 years ago

add dark selectize theme + "ternary" template modifier

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