Blob Blame Raw
{% extends "repo_master.html" %}
{% from "_formhelper.html" import render_field, render_bootstrap_field, show_comment, show_initial_comment %}

{% block title %}Issue #{{ issueid }} - {{ repo.name }}{% endblock %}
{% set tag = "home"%}

{% block header %}
<link href="{{ url_for('static', filename='fontawesome/font-awesome.min.css') }}"
  rel="stylesheet" />
<link href="{{ url_for('static', filename='emoji/emojione.sprites.css') }}"
  rel="stylesheet" />
<link href="{{ url_for('static', filename='selectize.bootstrap3.css') }}"
  rel="stylesheet" />
{% endblock %}

{% block repo %}
<div class="row m-t-md">
  <div class="col-md-8">

    <h2>
      <span class="issueid label label-default">#{{ issueid }}</span> <span id="issuetitle">{{
          issue.title | noJS("img") | safe }}</span>
    </h2>
<h5 class="text-muted"> Created {{ issue.date_created | humanize}} by {{ issue.user.user }}</h5>


    {{ show_initial_comment(issue, 0, repo, username, issueid, form, issue) }}

    <section id="comments">
    {% if issue.comments %}
      {% for comment in issue.comments %}
        {{ show_comment(comment, comment.id, repo, username, issueid, form, repo_admin) }}
      {% endfor %}
    {% endif %}
    </section>


    <div class="card">
      <div class="card-header">

        <section class="issue_comment add_comment">
        {% if authenticated and form %}

          <form action="{{ url_for('update_issue', username=username,
                   repo=repo.name, issueid=issueid) }}" method="post"
                   onsubmit="return try_async_comment(this)"
                   enctype="multipart/form-data">
          {{ form.csrf_token }}


          <fieldset class="form-group">
            <label for="comment"><strong>Add new comment</strong></label>
            <small class="text-muted pull-right"><span class="btn btn-sm btn-secondary inactive" aria-pressed="false" id="previewinmarkdown">Preview</span></small>
            <textarea class="form-control" rows=8 id="comment" name="comment" placeholder="Enter your comment here"></textarea>

            <div id="preview">
            </div>
          </fieldset>

          Select files OR drag them into the comment field below.
          <input id="file-picker" type="file" name="file" accept="image/*" multiple>
          <fieldset id="progress" style="display: none">
            <div class="progress-trough">
              <div id="progress-bar" class="progress-bar">0%</div>
            </div>
          </fieldset>
          <input type="hidden" name="tag" value="{{ issue.tags_text | join(',') }}" >
          <input type="hidden" name="assignee" value="{{ issue.assignee.username or '' }}" >
          <input type="hidden" name="blocks" value="{{ issue.blocks_text | join(',') }}">
          <input type="hidden" name="depends" value="{{ issue.depends_text | join(',') }}">
            <div>
              <input type="submit" class="btn btn-primary" value="Update Issue">
              <input type="button" class="btn btn-secondary" value="Clear" id="clear_comment" />
            </div>
        </form>
        {% else %}
          <p><a href="{{ url_for('auth_login', next=request.url) }}">Login</a> to comment on this ticket.</p>
        {% endif %}
        </section>

      </div>
    </div>

  </div>
  <div class="col-md-4">
    <div class="card">
      <div class="card-block">
      {% if authenticated and form %}
  <form action="{{ url_for('update_issue', username=username,
           repo=repo.name, issueid=issueid) }}" method="post"
           onsubmit="return try_async_comment(this)"
           enctype="multipart/form-data">
  {{ form.csrf_token }}
          {% endif %}

          <fieldset class="form-group issue-metadata-display">
            <label><strong>Status</strong></label>
            <h2><span class="label label-success">{{ issue.status }}</span></h2>
          </fieldset>

          {% if authenticated and repo_admin %}
            {{ render_bootstrap_field(form.status, formclass="issue-metadata-form") }}
          {% endif%}

          <fieldset class="form-group issue-metadata-display">
            <label><strong>Tags</strong></label>
              <h4>
                {% for tag in issue.tags %}
                  <a class="label label-default" href="{{ url_for('view_issues', username=username, repo=repo.name, tags=tag.tag) }}">{{ tag.tag }}</a>
                {% endfor %}
              </h4>
          </fieldset>

          {% if authenticated and repo_admin %}
          <fieldset class="form-group issue-metadata-form">
            <label for="tag"><strong>Tags</strong></label>
             <input id="tag" type="text" value="{{ issue.tags_text | join(',') }}" placeholder="tag1, tag2" name="tag" title="comma separated list of tags">
          </fieldset>
          {% endif%}

          <fieldset class="form-group issue-metadata-display">
            <label><strong>Assignee</strong></label>
            <div>
              {% if issue.assignee %}
                  <a href="{{ url_for('view_issues', username=username, repo=repo.name, assignee=issue.assignee.username) }}">{{ issue.assignee.username }}</a>
              {% else %}
                unassigned
              {% endif %}
            </div>
          </fieldset>

          {% if authenticated and repo_admin %}
                <fieldset class="form-group issue-metadata-form">
                  <label for="assignee"><strong>Assignee</strong></label>
                  <input class="form-control" value="{{ issue.assignee.username or '' }}" name="assignee" id="assignee" placeholder="username" >
                </fieldset>
          {% endif%}

          <fieldset class="form-group issue-metadata-display">
            <label><strong>Blocked</strong></label>
            <div>
              {% for ticket in issue.parents %}
                  <a href="{{ url_for('view_issue', username=username,
                            repo=repo.name, issueid=ticket.id)
                  }}">{{ ticket.id }}</a>{%- if not loop.last -%},{%- endif -%}
              {% endfor %}
            </div>
          </fieldset>

          {% if authenticated and repo_admin %}
                <fieldset class="form-group issue-metadata-form">
                  <label for="blocks"><strong>Blocked</strong></label>
                  <input class="form-control" id="blocks" type="text" placeholder="issue blocked" name="blocks" value="{{ issue.blocks_text | join(',') }}">
                </fieldset>
          {% endif%}


          <fieldset class="form-group issue-metadata-display">
            <label><strong>Depends on</strong></label>
            <div>
              {% for ticket in issue.children %}
                  <a href="{{ url_for('view_issue', username=username,
                            repo=repo.name, issueid=ticket.id)
                    }}">{{ ticket.id }}</a>{%- if not loop.last -%},{%- endif -%}
              {% endfor %}
            </div>
          </fieldset>

          {% if authenticated and repo_admin %}
                <fieldset class="form-group issue-metadata-form">
                  <label for="depends"><strong>Depends on</strong></label>
                  <input class="form-control" id="depends" type="text" placeholder="issue depending" name="depends" value="{{ issue.depends_text | join(',') }}">
                </fieldset>
          {% endif%}

          <input type="submit" class="btn btn-primary issue-metadata-form" value="Update">
            <a class="btn btn-secondary issue-metadata-form editmetadatatoggle" >cancel</a>
          {% if authenticated and form %}
            </form>
          {% endif %}
          {% if authenticated and repo_admin %}
            <a class="btn btn-secondary issue-metadata-display editmetadatatoggle" >Edit Metadata</a>
          {% endif %}
      </div>
    </div>
  </div>
</div>

{% endblock %}

{% block jscripts %}
{{ super() }}
<script type="text/javascript">
  var UPLOAD_URL = "{{ url_for('upload_issue', repo=repo.name, issueid=issue.id, username=username) }}";
</script>
<script type="text/javascript"
    src="{{ url_for('static', filename='emoji/jquery.textcomplete.min.js') }}">
</script>
<script type="text/javascript"
    src="{{ url_for('static', filename='emoji/emojione.min.js') }}">
</script>
<script type="text/javascript"
  src="{{ url_for('static', filename='upload.js') }}">
</script>
<script src="{{ url_for('static', filename='selectize.min.js') }}" rel="text/javascript"/>
<script type="text/javascript">

var emojiStrategy;
$.getJSON(
  '{{ url_for("static", filename="emoji/emoji_strategy.json") }}',
  function( data ) {
    emojiStrategy =  data;
  }
);

{% if authenticated and form %}
$(document).ready(function() {
  // Set up the drag/drop zone.
  initDropbox("{{ form.csrf_token.current_token }}", "#comment");

  // Set up the handler for the file input box.
  $("#file-picker").on("change", function() {
    doUpload("{{ form.csrf_token.current_token }}", this.files);
  });
});
{% endif %}

$(function() {
  var folder = '{{url_for("static", filename="emoji/png/") }}';
  var json_url = '{{ url_for("static", filename="emoji/emoji_strategy.json") }}';
  emoji_complete(json_url, folder);
});

/*  var cache = {};
  $( "#tag" ).autocomplete({
    source: function( request, response ) {
      var pattern = request.term;
      if ( pattern in cache ) {
        response( cache[ pattern ] );
        return;
      }

      $.getJSON(
        "{{ url_for('api_ns.api_project_tags', repo=repo.name, username=username) }}", {
          pattern: request.term
        },
        function( data ) {
          cache[ pattern ] = data.tags;
          response( data.tags );
        }
      );
    },
    minLength: 0,
    delay: 200,
  });*/


  var cur_hash = null;

  highlight_comment = function() {
    var _hash = window.location.hash;
    if (_hash != cur_hash) {
      $( cur_hash ).css(
        "background", "linear-gradient(to bottom, #ededed 0%, #fff 100%)"
      );
    };
    cur_hash = _hash;
    if ( _hash ) {
      $( _hash ).css(
        "background", "linear-gradient(to bottom, #eded98 0%, #fff 100%)"
      );
    };
    return false;
  };

  $(window.onload=highlight_comment());
  $(window).on('hashchange', highlight_comment);

  $(".comment_body").each(function(ind, obj) {
    var source = $(obj).html();
    var preview = emojione.toImage(source);
    $(obj).html(preview);
  });

  $(".edit_btn").click(function() {
    var commentid = $( this ).attr('data-comment');
    var _url = '{{ request.base_url }}' + '/comment/' + commentid + '/edit';
    $.ajax({
        url: _url + '?js=1',
        type: 'GET',
        dataType: 'html',
        success: function(res) {
            var el = $('#comment-' + commentid);
            var sec = el.parent().children()[1];
            $(sec).hide();
            $(sec).after(res);
            cancel_edit_btn();
        },
        error: function() {
            alert('Could not make edit work');
        }
    });
    return false;
  });

  function cancel_edit_btn() {
    $( ".cancel" ).click(
      function() {
        $(this).closest('#comments').find('.comment_body').show();
        $(this).closest('.edit_comment').remove();
        return false;
      }
    );
  };

});
</script>

{% if config['EVENTSOURCE_SOURCE'] and not issue.private %}
<script type="text/javascript"
  src="{{ url_for('static', filename='issue_ev.js') }}"></script>

<script type="text/javascript">
var source = null;
var sse = true;
if (!!window.EventSource) {
  source = new EventSource('{{ config["EVENTSOURCE_SOURCE"]
    + request.script_root + request.path }}');
  source.addEventListener('error', function(e) {
    sse = false;
  }, false);
}

window.onbeforeunload = function() {
    source.close()
};

source.addEventListener('message', function(e) {
  console.log(e.data);
  var data = $.parseJSON(e.data);
  var _issues_url ='<a href="{{
    url_for('view_issues', username=username, repo=repo.name)}}';
  var _api_issues_url ='{{
    url_for('api_ns.api_view_issue', username=username,
            repo=repo.name, issueid='-123456789')}}';
  var _issue_url ='<a href="{{
    url_for('view_issue', username=username,
            repo=repo.name, issueid='-123456789')}}">';
  process_event(data, "{{ issue.uid }}", _issue_url,
                _issues_url, _api_issues_url);

  }, false);

{% if authenticated and form %}
function try_async_comment(form) {
  if (!sse) {
    $(form).off('submit');
    form.submit();
    return false;
  }
  var _url = form.action + "?js=1";
  var _data = $(form).serialize();
  var btn = $(document.activeElement);
  if (btn[0].name == 'drop_comment'){
    _data += '&drop_comment=' + btn[0].value;
    return true;
  }
  $.post( _url, _data )
    .done(function(data) {
      if(data == 'ok') {
        {# The event-source server will automatically refresh the UI #}
        $('#comment').val('');
        $('#comments').find('.comment_body').show();
        $('#comments').find('.edit_comment').remove();
      } else {
        // Make the browser submit the form sync
        $(form).off('submit');
        form.submit();
      }
    })
    .fail(function() {
      // Make the browser submit the form sync
      $(form).off('submit');
      form.submit();
    })
  return false;
};
{% endif %}

</script>
{% endif %}
<script>
$( document ).ready(function() {
    console.log( "ready!" );

  $( ".editmetadatatoggle" ).click(
    function() {
      $( ".issue-metadata-form" ).toggle();
      $( ".issue-metadata-display" ).toggle();
    }
  );

  $('#assignee').selectize({
      valueField: 'user',
      labelField: 'user',
      searchField: 'user',
      maxItems: 1,
      create: false,
      load: function(query, callback) {
          if (!query.length) return callback();
          $.getJSON(
            "{{ url_for('api_ns.api_users') }}", {
              pattern: query.term
            },
            function( data ) {
              callback( data.users.map(function(x) { return { user: x }; }) );
            }
          );
      }
  });


$('#blocks').selectize({
      plugins: ['remove_button'],
      valueField: 'id',
      labelField: 'id',
      searchField: ['id', 'title'],
      preload: 'focus',
      render: {
          option: function(item, escape) {
              return '<div><span>'+escape(item.id)+'</span> <span>'+escape(item.title)+'</span></div>';
          },
          item: function(item, escape) {
              return '<div><span>#'+escape(item.id)+'</span></div>';
          },
      },
      create: false,
      load: function(query, callback) {
          $.getJSON(
            "{{ url_for('api_ns.api_view_issues', username=username, repo=repo.name) }}",
            function( data ) {
              console.log(data.issues);
              callback(data.issues);
            }
          );
      }
  });

$('#depends').selectize({
      plugins: ['remove_button'],
      valueField: 'id',
      labelField: 'id',
      searchField: ['id', 'title'],
      preload: 'focus',
      render: {
          option: function(item, escape) {
              return '<div><span>'+escape(item.id)+'</span> <span>'+escape(item.title)+'</span></div>';
          },
          item: function(item, escape) {
              return '<div><span>#'+escape(item.id)+'</span></div>';
          },
      },
      create: false,
      load: function(query, callback) {
          $.getJSON(
            "{{ url_for('api_ns.api_view_issues', username=username, repo=repo.name) }}",
            function( data ) {
              console.log(data.issues);
              callback(data.issues);
            }
          );
      }
  });


  $( ".reply" ).click(
    function() {
      var _section = $(this).parent().parent().parent();
      var _comment = _section.find('.comment_body');
      var _text = _comment.text().split("\n");
      var _output = new Array();
      for (cnt = 0; cnt < _text.length - 1; cnt ++) {
          _output[cnt] = '> ' + jQuery.trim(_text[cnt + 1]);
      }
      $( "#comment" ).val(_output.join("\n"));
    }
  );

  $( "#clear_comment").click(
    function() {
      $( "#comment" ).val("");
    }
  );



    var available_tags = [];
    {%for tog in tag_list %}
      available_tags.push("{{tog.tag}}");
    {%endfor%}
    var items = available_tags.map(function(x) { return { item: x }; });

    $('#tag').selectize({
        delimiter: ',',
        options: items,
        persist: false,
        create: true,
    labelField: "item",
    valueField: "item"
    });
  $( "#preview" ).hide();
  $( "#previewinmarkdown" ).click(
    function(event, ui) {
        if ($( "#previewinmarkdown" ).hasClass("inactive")){
          var _text = $( "#comment" ).val();
          var _url = "{{ url_for('markdown_preview') }}";
            $.ajax({
                url: _url ,
                type: 'POST',
                data: {
                  content: _text,
                  csrf_token: "{{ form.csrf_token.current_token }}",
                },
                dataType: 'html',
                success: function(res) {
                    $( "#preview" ).html(res);
                    $( "#previewinmarkdown" ).removeClass("inactive");
                    $( "#previewinmarkdown" ).addClass("active");
                    $( "#comment" ).hide();
                    $( "#preview" ).show();
                },
                error: function() {
                    alert('Unable to generate preview!');
                }
            });
            return false;
          } else if ($( "#previewinmarkdown" ).hasClass("active")){
            $( "#previewinmarkdown" ).addClass("inactive");
            $( "#previewinmarkdown" ).removeClass("active");
            $( "#comment" ).show();
            $( "#preview" ).hide();
          }
    }
  );

});
</script>
{% endblock %}