[define title]People[end]
[define category_css]css/ph_list.css[end]
[if-any is_hotlist][define category2_css]css/ph_detail.css[end][end]
[include "../framework/header.ezt" "hidetabs"]
[include "../framework/js-placeholders.ezt"]

<form method="POST" action=[if-any is_hotlist]"people.do"[else]"list.do"[end] id="membership_form">
<input type="hidden" name="token" value="[form_token]">
[if-any newly_added_views]
  <br/>
  The following new members were successfully added:
  <br/>
  [for newly_added_views]
    <a href="[newly_added_views.detail_url]">[newly_added_views.user.display_name]</a> ([newly_added_views.role])
    <br/>
  [end]
  <br/>
[end]

<div id="colcontrol">
   <div class="list">
     [if-any pagination.visible]
       <div class="pagination">
         [if-any pagination.prev_url]<a href="[pagination.prev_url]"><b>&lsaquo;</b> Prev</a>[end]
         Members [pagination.start] - [pagination.last] of [pagination.total_count]
         [if-any pagination.next_url]<a href="[pagination.next_url]">Next <b>&rsaquo;</b></a>[end]
       </div>
     [end]

     <h4 style="display: inline">[if-any is_hotlist]Hotlist[else]Project[end] People</h4>

     [if-any read_only][else]
       [if-any offer_membership_editing]
        <input type="button" value="Add members"
               id="add_members_button" class="primary">
        <input type="submit" value="Remove members"
               id="removebtn" class="secondary" name="removebtn" disabled="disabled">
        [# TOOD(jrobbins): extra confirmation when removing yourself as owner.]
        [if-any is_hotlist]
          <a id="transfer-ownership" class="buttonify">Transfer ownership</a>
          [include "../features/transfer-hotlist-form.ezt"]
        [end]
       [end]
       [if-any is_hotlist]
        [if-any offer_remove_self]
         <a id="remove-self" class="buttonify">Remove myself</a>
         [include "../features/remove-self-hotlist-form.ezt"]
        [end]
       [end]
     [end]
   </div>

  <table cellspacing="0" cellpadding="2" border="0" class="results striped vt" id="resultstable" width="100%">
  <tbody>
   [if-any pagination.visible_results]

      <tr id="headingrow">
       [if-any offer_membership_editing]
         <th style="border-right:0; padding-right:2px">&nbsp;</th>
       [end]

       <th style="white-space:nowrap">Name</th>
       <th style="white-space:nowrap">Role</th>
       [if-any is_hotlist]
       [else]
       <th style="white-space:nowrap">Autocomplete</th>
       <th style="white-space:nowrap">Notes</th>
       [end]
      </tr>

      [for pagination.visible_results]
       [if-any is_hotlist]
         [include "people-list-row-part.ezt" "hotlist"]
       [else]
        [include "people-list-row-part.ezt" "project"]
       [end]
      [end]

   [else]
    <tr>
     <td colspan="40" class="id">
      <div style="padding: 3em; text-align: center">
       This [if-any is_hotlist]hotlist[else]project[end] does not have any members.
      </div>
     </td>
    </tr>
   [end]


  </tbody>
  </table>
  <div class="list-foot">
    <div class="pagination">
    [if-any pagination.prev_url]<a href="[pagination.prev_url]"><b>&lsaquo;</b> Prev</a>[end]
    [pagination.start] - [pagination.last] of [pagination.total_count]
    [if-any pagination.next_url]<a href="[pagination.next_url]">Next <b>&rsaquo;</b></a>[end]
    </div>
  </div>
</div>

[if-any untrusted_user_groups]
  <div style="width:45em">
    [include "untrusted-user-groups-part.ezt"]
  </div>
[end]

[if-any read_only][else]
  [if-any is_hotlist]
  [include "people-add-members-form.ezt" "hotlist"]
  [else]
  [include "people-add-members-form.ezt" "project"]
  [end]
  [# TODO(jojwang): make more elegant later, just one line]
[end]

</form>

[if-any offer_membership_editing]
  <script type="text/javascript" nonce="[nonce]">
runOnLoad(function() {
    $("add_members_button").addEventListener("click", _openAddMembersForm);

    function _countChecked(opt_className) {
      var numChecked = 0;
      var inputs = document.getElementsByTagName('input');
      for (var i = 0; i < inputs.length; i++) {
        var el = inputs[[]i];
        if (el.type == 'checkbox' && el.name == 'remove' && el.checked &&
            (!opt_className || opt_className == el.className)) {
          numChecked++;
        }
      }
      return numChecked;
    }

   function _enableRemoveButton() {
     var removeButton = document.getElementById('removebtn');
     if (_countChecked() > 0) {
       removeButton.disabled = false;
     } else {
       removeButton.disabled = true;
     }
   }

   setInterval(_enableRemoveButton, 700);

   function _preventAbandonment(event) {
      var meCheckbox = document.getElementById("me_checkbox");
      if (meCheckbox && meCheckbox.checked) {
        numOwnersChecked = _countChecked("owner");
        if (numOwnersChecked == [total_num_owners]) {
          alert("You cannot remove all project owners.");
          event.preventDefault();
        } else {
          if (!confirm("Remove yourself as project owner?\n" +
                       "You will be locked out of making further changes.")) {
              event.preventDefault();
          }
        }
      }
      return true;
   }
   [if-any check_abandonment]
     $("membership_form").addEventListener("submit", _preventAbandonment);
   [end]

   [if-any is_hotlist]
   initializeDialogBox("[hotlist_id]");
   [end]
});
  </script>
[end]
[if-any is_hotlist][if-any offer_remove_self]
  <script type="text/javascript" nonce="[nonce]">
  runOnLoad(function () {initializeDialogBoxRemoveSelf()});
  </script>
[end][end]

<script type="text/javascript" nonce="[nonce]">
runOnLoad(function() {
  function _handleResultsClick(event) {
    var target = event.target;
    if (target.tagName == "A")
      return;
    if (target.classList.contains("rowwidgets") || target.parentNode.classList.contains("rowwidgets"))
      return;
    if (target.tagName != "TR") target = target.parentNode;
    _go(target.attributes[[]"data-url"].value,
        (event.metaKey || event.ctrlKey || event.button == 1));
  };
  _addClickListener($("resultstable"), _handleResultsClick);

});
</script>


[include "../framework/footer.ezt"]
