{% extends "repo_master.html" %}
{% from "_formhelper.html" import show_comment, show_pr_initial_comment, render_bootstrap_field %}
{% from "_repo_renderdiff.html" import repo_renderdiff %}
{% block title %}
{%- if pull_request -%}
PR#{{ requestid }}: {{ pull_request.title | noJS(ignore="img") | safe }}
{%- endif
%} - {{ repo.url_path }}
{% endblock %}
{% set tag = "home" %}
{% block header %}
<link type="text/css" rel="stylesheet" nonce="{{ g.nonce }}" href="{{
url_for('static', filename='vendor/emojione/emojione.sprites.css') }}?version={{ g.version}}"/>
<link type="text/css" rel="stylesheet" nonce="{{ g.nonce }}" href="{{
url_for('static', filename='vendor/selectize/selectize.bootstrap3.css') }}?version={{ g.version}}"/>
<link type="text/css" rel="stylesheet" nonce="{{ g.nonce }}" href="{{
url_for('static', filename='vendor/jquery.atwho/jquery.atwho.css') }}?version={{ g.version}}"/>
{% endblock %}
{% block repo %}
<div class="d-flex align-items-start">
<h4 class="ml-1">
<div>
{% if pull_request.status == 'Open' %}
<span class="fa fa-fw text-success fa-arrow-circle-down pt-1"></span>
<span class="text-success font-weight-bold">#{{requestid}}</span>
{% elif pull_request.status == 'Merged' %}
<span class="fa fa-fw text-info fa-arrow-circle-down pt-1"></span>
<span class="text-info font-weight-bold">#{{requestid}}</span>
{% elif pull_request.status == 'Closed' %}
<span class="fa fa-fw text-danger fa-arrow-circle-down pt-1"></span>
<span class="text-danger font-weight-bold">#{{requestid}}</span>
{% endif %}
<span class="font-weight-bold">
{{ pull_request.title | noJS(ignore="img") | safe}}
</span>
{% if g.authenticated and (g.fas_user.username == pull_request.user.username
or g.repo_committer) and pull_request.status == 'Open'%}
<a class="btn btn-sm btn-outline-secondary border-0"
href="{{ url_for(
'ui_ns.request_pull_edit',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid) }}"
title="Update title"><i class="fa fa-pencil"></i></a>
{% endif %}
</div>
<div>
<small>
{% if pull_request.status == 'Open' %}
<span data-toggle="tooltip" title="{{pull_request.date_created | format_datetime}}">
<span class="text-success font-weight-bold">Opened</span> {{ pull_request.date_created |humanize }}
</span>
<span title="{{ pull_request.user.html_title }}"> by {{ pull_request.user.user }}.</span>
<span class="text-muted" data-toggle="tooltip" title="{{pull_request.updated_on | format_datetime}}">
Modified {{ pull_request.updated_on |humanize }}
</span>
{% elif pull_request.status == 'Merged' %}
<span data-toggle="tooltip" title="{{pull_request.closed_at | format_datetime}}">
<span class="text-info font-weight-bold">Merged</span> {{ pull_request.closed_at |humanize }}
</span>
by
<span title="{{ pull_request.closed_by.html_title }}">{{ pull_request.closed_by.user }}.</span>
<span class="text-muted" data-toggle="tooltip" title="{{pull_request.date_created | format_datetime}}">
<span class="font-weight-bold">Opened</span> {{ pull_request.date_created |humanize }}
</span>
<span class="text-muted" title="{{ pull_request.user.html_title }}">by {{ pull_request.user.user }}.</span>
{% elif pull_request.status == 'Closed' %}
<span data-toggle="tooltip" title="{{pull_request.closed_at | format_datetime}}">
<span class="text-danger font-weight-bold">Closed</span> {{ pull_request.closed_at |humanize }}
</span>
by
<span title="{{ pull_request.closed_by.html_title }}">{{ pull_request.closed_by.user }}.</span>
<span class="text-muted" data-toggle="tooltip" title="{{pull_request.date_created | format_datetime}}">
<span class="font-weight-bold">Opened</span> {{ pull_request.date_created |humanize }}
</span>
<span class="text-muted" title="{{ pull_request.user.html_title }}">by {{ pull_request.user.user }}.</span>
{% endif %}
</small>
</div>
<div class="mt-2">
<small>
{% if pull_request.remote_git or pull_request.project_from.is_fork %}
<span class="badge badge-light badge-pill border border-secondary font-1em">
{% if pull_request.remote_git %}
<i class="fa fa-globe"></i>
{{pull_request.remote_git}}
{% elif pull_request.project_from.is_fork %}
<i class="fa fa-code-fork"></i>
{% if pull_request.project_from.namespace %}
{{pull_request.project_from.namespace}}/
{% endif %}
{% if pull_request.project_from.is_fork -%}
{{ pull_request.project_from.user.user }}/
{%- endif -%}
{{pull_request.project_from.name}}
{% endif %}
</span>
{% endif %}
<a href="{{ url_for('ui_ns.view_tree',
repo=pull_request.project_from.name,
username=pull_request.project_from.user.user
if pull_request.project_from.is_fork else None,
namespace=repo.namespace,
identifier=pull_request.branch_from)
}}"
class="badge badge-secondary badge-pill border border-secondary font-1em">
<span class="fa fa-random"></span>
{{ pull_request.branch_from }}
</a>
into
<a href="{{ url_for('ui_ns.view_tree',
repo=pull_request.project.name,
username=pull_request.project.user.user
if pull_request.project.is_fork else None,
namespace=repo.namespace,
identifier=pull_request.branch)
}}"
class="badge badge-secondary badge-pill border border-secondary font-1em">
<i class="fa fa-random"></i>
{{ pull_request.branch }}
</a>
</small>
</div>
</h4>
<div class="ml-auto d-flex">
{% if g.authenticated and (g.fas_user.username == pull_request.user.username
or g.repo_committer) and pull_request.status == 'Open'%}
{% if pull_request.status == 'Open' and g.authenticated and
(g.repo_committer or g.fas_user.username == pull_request.user.username) %}
{% if mergeform and pull_request.remote %}
<form class="inline" action="{{ url_for(
'ui_ns.refresh_request_pull',
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
repo=repo.name, requestid=requestid) }}" method="POST">
<button type="submit" value="Refresh" id="refresh_pr"
class="btn btn-outline-primary btn-sm" title="Refresh the remote pull request">
<span class="fa fa-refresh"></span> Refresh
</button>
{{ mergeform.csrf_token }}
</form>
{% endif %}
<form class="inline" action="{{ url_for(
'ui_ns.close_request_pull',
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
repo=repo.name, requestid=requestid) }}" method="POST">
{% endif %}
{% if pull_request.status == 'Open' and g.authenticated and
(g.repo_committer or g.fas_user.username == pull_request.user.username) %}
{{ mergeform.csrf_token }}
<button type="submit" value="Close" id="close_pr"
class="btn btn-outline-danger btn-sm" title="Close PR without merging it" data-toggle="tooltip">
<span class="fa fa-times"></span> Close
</button>
{% endif %}
{% if pull_request.status == 'Open' and g.authenticated and
(g.repo_committer or g.fas_user.username == pull_request.user.username) %}
</form>
{% endif %}
{% endif %}
{% if pull_request.status == 'Open' %}
<div class="dropdown float-right ml-1">
<span class="dropdown dropdown-btn">
<a href="#" id="merge_dropdown_btn"
class="btn btn-outline-secondary btn-sm disabled dropdown-toggle" data-toggle="dropdown">
<span class="fa fa-circle-o-notch fa-spin fa-fw"></span> <span id="merge-status-text">Merge</span>
</a>
<div id="merge-alert" class="text-xs-center dropdown-menu dropdown-menu-right p-0">
<div class="alert text-center mb-0">
{% if pull_request.status == 'Open' and g.repo_committer and pull_request.allow_rebase %}
<small id="merge-alert-message"></small>
<form action="{{ url_for('ui_ns.merge_request_pull',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid)
}}" method="POST" id="merge_pr_form">
{{ mergeform.csrf_token }}
<button id="merge_btn" type="submit"
class="btn btn-block my-2">Merge</button>
{% if can_delete_branch %}
<div class="small">
{{ mergeform.delete_branch }} {{ mergeform.delete_branch.label }}
</div>
{% endif %}
</form>
<button id="rebase_btn" type="submit"
class="btn btn-block my-2">Rebase</button>
{% else %}
<small id="merge-alert-message"></small>
{% endif %}
</div>
</div>
</span>
{% if g.authenticated and trigger_ci %}
<span class="dropdown dropdown-btn">
<a href="#" id="ci_dropdown_btn"
class="btn btn-outline-primary btn-sm btn-info dropdown-toggle" data-toggle="dropdown">
Rerun CI
</a>
<div class="text-xs-center dropdown-menu dropdown-menu-right p-0">
<form action="{{ url_for('ui_ns.ci_trigger_request_pull',
repo=repo.name,
username=repo.username if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid)
}}" method="POST" id="ci_pr_trigger_form">
{{ trigger_ci_pr_form.csrf_token }}
{{ trigger_ci_pr_form.comment(id="ci_pr_comment", hidden=True) }}
{% for comment, meta in trigger_ci|dictsort %}
<a class="dropdown-item trigger-ci-btn" href="#" title="{{ meta["description"] }}"
data-comment="{{ comment }}">{{ meta["name"] }}</a>
{% endfor %}
</form>
</div>
</span>
{% endif %}
</div>
{% endif %}
{% if pull_request.status == 'Closed' and g.authenticated and
(g.repo_committer or g.fas_user.username == pull_request.user.username) %}
<form action="{{ url_for(
'ui_ns.reopen_request_pull',
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
repo=repo.name, requestid=requestid) }}" method="POST">
{{ mergeform.csrf_token }}
<button type="submit" value="Reopen" id="reopen_pr"
class="btn btn-sm btn-outline-danger" title="Reopen PR">
Reopen Pull Request
</button>
</form>
{% endif %}
</div>
</div>
<div class="row" id="pr-wrapper">
<div class="col-md-12">
<ul class="nav nav-tabs nav-small my-4 border-bottom" role="tablist" id="pr-tabs">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" role="tab" href="#comments">
Comments
</a>
</li>
<li class="nav-item">
<a class="nav-link {% if not pull_request %}active{%
endif %}" data-toggle="tab" role="tab" href="#request_diff">
<span>Files Changed </span>
<span class="badge badge-secondary badge-pill">
{{ diff|length if diff else 0}}
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" role="tab" href="#commit_list">
<span>Commits </span>
<span class="badge badge-secondary badge-pill">
{{ diff_commits|length }}
</span>
</a>
</li>
<li class="nav-item ml-auto">
<a class="nav-link" href="{{ url_for(
'ui_ns.request_pull_patch',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid) }}">
<span class="hidden-sm-down">Patch</span>
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane" role="tabpanel" id="commit_list">
<div class="list-group">
{% for commit in diff_commits %}
{% if pull_request.status and pull_request.project_from.is_fork %}
{% set commit_link = url_for(
'ui_ns.view_commit',
repo=pull_request.project_from.name,
username=pull_request.project_from.user.user,
namespace=repo.namespace,
commitid=commit.oid.hex)%}
{% set tree_link = url_for(
'ui_ns.view_tree', username=pull_request.project_from.user.user, namespace=repo.namespace,
repo=repo.name, identifier=commit.hex) %}
{% elif pull_request.remote %}
{% set commit_link = None %}
{% else %}
{% set commit_link = url_for('ui_ns.view_commit',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
commitid=commit.oid.hex) %}
{% set tree_link = url_for(
'ui_ns.view_tree',
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
repo=repo.name, identifier=commit.hex) %}
{% endif %}
<div class="list-group-item">
<div class="row align-items-center">
<div class="col">
{% if commit_link %}
<a class="notblue" href="{{commit_link}}">
{% endif %}
<strong>{{ commit.message.strip().split('\n')[0] }}</strong>
{% if commit_link %}
</a>
{% endif %}
<div>
{{commit.author|author2user_commits(
link=url_for('ui_ns.view_commits',
repo=repo.name,
branchname=branchname,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
author=commit.author.email),
cssclass="notblue")|safe}}
<span class="commitdate"
title="{{ commit.commit_time|format_ts }}"> •
{{ commit.commit_time|humanize }}</span>
</div>
</div>
<div class="col-xs-auto pr-3 text-right">
<div class="btn-group">
<a href="{{ commit_link }}"
class="btn btn-outline-primary font-weight-bold {{'disabled' if not commit_link}}">
<code>{{ commit.hex|short }}</code>
</a>
<a class="btn btn-outline-primary font-weight-bold {{'disabled' if not commit_link}}" href="{{tree_link}}"><span class="fa fa-file-code-o fa-fw"></span></a>
</div>
</div>
</div>
</div>
{% else %}
<p class="error"> No commits found </p>
{% endfor %}
</div>
</div>
<div class="tab-pane" role="tabpanel" id="request_diff">
{% if g.authenticated %}
<form action="{{ url_for('ui_ns.pull_request_drop_comment',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid)
}}" method="post" class="icon form_pr_drop_comment">
{% endif %}
{{repo_renderdiff(diff=diff,
diff_commits=diff_commits,
pull_request=pull_request,
repo=repo,
username=username,
namespace=namespace)}}
{% if g.authenticated %}
{{ mergeform.csrf_token }}
</form>
{% endif %}
</div>
<div class="tab-pane active" role="tabpanel" id="comments">
<div class="row">
<div class="col-md-8">
{{ show_pr_initial_comment(pull_request, repo, form, username) }}
<section class="request_comment" >
<form action="{{ url_for('ui_ns.pull_request_drop_comment',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid)
}}" method="post" id="request_comment" class="form_pr_drop_comment">
{% if pull_request.comments %}
{% for comment in pull_request.comments %}
{% if comment.commit_id %}
{{ show_comment(comment, comment.id, repo, username,
requestid, form, PRinline=True) }}
{% elif comment.notification %}
<div class="d-flex align-items-center px-3 py-2 mb-3">
<div class="">
{{ comment.user.default_email | avatar(24) | safe }}
</div>
<span class="font-size-09 autogenerated-comment pl-4">{{ comment.comment | markdown | noJS | safe }}</span>
<div class="text-muted ml-auto">
<span title="{{ comment.date_created | format_datetime }}">{{
comment.date_created | humanize }}</span>
</div>
</div>
{% else %}
{{ show_comment(comment, comment.id, repo, username,
requestid, form) }}
{% endif %}
{% endfor %}
{{ mergeform.csrf_token }}
{% endif %}
</form>
</section>
{% if g.authenticated and mergeform %}
<div class="card mt-5">
{% if g.authenticated %}
<div class="card-header pb-0 pt-1 bg-light">
<div class="row">
<div class="col align-self-center">
<span><strong>Add new comment</strong></span>
</div>
<div class="col">
<ul class="nav nav-tabs float-right">
<li class="nav-item">
<a class="nav-link pointer" id="previewinmarkdown">Preview</a>
</li>
<li class="nav-item">
<a class="nav-link active pointer" id="editinmarkdown">Edit</a>
</li>
</ul>
{% if repo.quick_replies %}
{% include "quick_reply.html" %}
{% endif %}
</div>
</div>
</div>
<form action="{{ url_for(
'ui_ns.pull_request_add_comment',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid) }}"
method="post" class="form_pr_add_comment">
{{ mergeform.csrf_token }}
<div class="card-body">
<textarea class="form-control" rows=8 id="comment" name="comment"
placeholder="Enter your comment here" tabindex=1></textarea>
<div id="preview" class="p-1">
</div>
</div>
<div class="d-flex align-items-center card-footer bg-light">
<small>Comments use <a href="https://docs.pagure.org/pagure/usage/markdown.html"
target="_blank" rel="noopener noreferrer" class="notblue">Markdown Syntax</a></small>
<div class="ml-auto">
<input type="submit" class="btn btn-primary"
value="Submit Comment" tabindex=2 />
</div>
</div>
</form>
{% endif %}
</div>
<div class="small">
<p>
Pull this pull-request locally
<a href="#" id="local_pull_info_btn">
<span class="fa fa-arrow-circle-down fa-fw fa-1x">
</span>
</a>
</p>
<pre id="local_pull_info" class="hidden">git fetch {{ config.get('GIT_URL_GIT') }}{{ repo.fullname }}.git refs/pull/{{ pull_request.id }}/head:pr{{ pull_request.id }}</pre>
</div>
{% endif %}
</div>
<div class="col-md-4">
<div>
<div class="mb-4">
<h5 class="d-flex align-items-center font-weight-bold border-bottom">
<div class="py-2 text-uppercase font-size-09">Metadata</div>
{% if g.authenticated and mergeform
and (g.repo_user
or g.fas_user.username == pull_request.user.user) %}
<div class="ml-auto">
<a class="btn btn-outline-primary border-0 btn-sm issue-metadata-display editmetadatatoggle pointer" ><i class="fa fa-fw fa-pencil"></i></a>
<a class="btn btn-outline-secondary border-0 btn-sm issue-metadata-form hidden editmetadatatoggle pointer" ><i class="fa fa-fw fa-times"></i></a>
</div>
{% endif %}
</h5>
{% if g.authenticated and mergeform and g.repo_user %}
<form method="POST" action="{{ url_for('ui_ns.update_pull_requests',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid) }}">
<fieldset class="form-group issue-metadata-form hidden">
<label><strong>Assignee</strong></label>
<div>
<input value="{{ pull_request.assignee.username or '' }}"
name="user" id="assignee" placeholder="username" >
{{ mergeform.csrf_token }}
</div>
</fieldset>
{% endif %}
<fieldset class="form-group issue-metadata-display ml-1">
<label class="mb-1 pl-1"> <i class="fa fa-fw fa-user-plus"></i> <strong>Assignee</strong></label>
<div id="assignee_plain">
<div class="ml-2" title="{{ pull_request.assignee.html_title if pull_request.assignee else '' }}">
{% if pull_request.assignee.username %}
<div class="mt-1">{{pull_request.assignee.username| avatar(size=24) | safe}}
<a href="{{ url_for(
'ui_ns.request_pulls',
repo=repo.name,
username=username,
namespace=repo.namespace,
assignee=pull_request.assignee.username)
}}" title="{{ pull_request.assignee.html_title }}">
{{ pull_request.assignee.username }}
</a>
{% if g.authenticated and (pull_request.assignee.username == g.fas_user.username) %}
— <a class="pointer" id="drop-btn"
title="drop the assignment of this pull-request">
Drop
</a>
{% endif %}
</div>
{% else %}
<div class="text-muted">
<span class="text-muted">None</span>
{% if g.authenticated and (g.repo_user or g.fas_user.username == pull_request.user.user) and pull_request.status|lower == 'open'
and (not pull_request.assignee or pull_request.assignee.username != g.fas_user.username)
and not repo.settings.get('pull_request_tracker_read_only', False) %}
— <a class="pointer" id="take-btn"
title="assign this pull_request to you"> Take </a>
{% endif %}
</div>
{% endif %}
</div>
</div>
</fieldset>
{% if g.authenticated and (
g.repo_user
or g.fas_user.username == pull_request.user.user) %}
<fieldset class="form-group issue-metadata-form hidden">
<label class="mb-1"><i class="fa fa-fw fa-tag"></i> <strong>Tags</strong></label>
<input id="tag" type="text" placeholder="tag1, tag2" name="tag"
title="comma separated list of tags"
value="{{ pull_request.tags_text | join(',') }}" />
</fieldset>
{% endif%}
<fieldset class="form-group issue-metadata-display ml-1">
<label class="mb-0"><strong>Tags</strong></label>
{% if pull_request.tags %}
<h4 id="taglist" class="ml-2">
{% for tag in pull_request.tags %}
<a id="tag-{{ tag.tag }}" title="{{ tag.tag_description }}"
data-bg-color="{{ tag.tag_color }}"
class="badge badge-primary text-left my-1 p-2 badge-tag"
href="{{ url_for('ui_ns.request_pulls',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
tags=tag.tag) }}">
{{ tag.tag }}
</a>
{% endfor %}
</h4>
{% else %}
<div class="text-muted">No Tags</div>
{% endif %}
</fieldset>
{% if g.authenticated and mergeform
and (g.repo_user
or g.fas_user.username == pull_request.user.user) %}
<input type="submit" class="btn btn-primary issue-metadata-form hidden" value="Update">
</form>
{% endif %}
</div>
{% if pull_request.flags %}
<div class="mb-4">
<h5 class="d-flex align-items-center font-weight-bold border-bottom">
<div class="py-2 text-uppercase font-size-09">Flags</div>
</h5>
<div class="list-group list-group-flush">
{% for flag in pull_request.flags %}
<a href="{{ flag.url }}" class="list-group-item list-group-item-action border-0 pl-2 pr-2">
<div>
<span class="font-weight-bold">
{{ flag.username }}
</span>
<div class="float-right">
<span class="badge {{ flag | flag2label }} font-size-09">
{{ flag.status }}
{%- if flag.percent %} ({{ flag.percent }}%) {%- endif %}
</span>
</div>
</div>
<small><div class="clearfix">
<span>{{ flag.comment }}</span>
<div title="{% if
flag.date_created == flag.date_updated -%}
Created at {% else -%} Updated at {% endif -%}
{{ flag.date_updated }}" class="float-right">
{{ flag.date_updated | humanize }}</div>
</div>
</small>
</a>
{% endfor%}
</div>
</div>
{% endif %}
{% if g.authenticated %}
<div class="mt-3">
<h5 class="d-flex align-items-center font-weight-bold border-bottom">
<div class="py-2 text-uppercase font-size-09">
Subscribers
<span class="badge badge-secondary badge-pill font-size-09 ml-1" id="subscribers-count">{{subscribers|count}}</span>
</div>
<div class="ml-auto">
<a href="#" class="btn btn-sm btn-link" id="subcribe-btn"
{% if g.fas_user.username in subscribers -%}
title="Unsubscribe from this pull-request">Unsubscribe
{%- else -%}
title="Subscribe to this pull-request">Subscribe
{%- endif -%}
</a>
</div>
</h5>
{% if subscribers %}
<div id="subscribers_list" class="p-2">
{% for subscriber in subscribers %}
<a href="{{ url_for('ui_ns.view_user', username=subscriber)
}}" title="{{ subscriber }}" id="sub-avatar-{{subscriber}}">{{
subscriber |avatar(size=30, css_class="pb-1") | safe
}}</a>
{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
</div>
{% if diff %}
<div class="mt-3">
<h5 class="d-flex align-items-center font-weight-bold border-bottom">
<div class="py-2 text-uppercase font-size-09">
Changes Summary
<span class="badge badge-secondary badge-pill font-size-09 ml-1">{{ diff|length if diff else 0}}</span>
</div>
</h5>
{% macro changeschangedfile(filepath, added, removed, diffanchor) -%}
<a href="#_{{diffanchor}}" class="list-group-item list-group-item-action pl-2 pr-2 border-0">
<div class="clearfix">
<div class="float-right">
<span class="font-size-09 badge badge-success">+{{added}}</span>
<span class="font-size-09 badge badge-danger">-{{removed}}</span>
</div>
<div class="pull-xs-left pr-changes-description">
<strong>file <span class="text-muted">changed</span></strong>
</div>
</div>
<div class="ellipsis pr-changes-description">
<small>{{filepath}}</small>
</div>
</a>
{%- endmacro %}
{% macro changesrenamedfile(oldfilepath, newfilepath, added, removed, diffanchor) -%}
<a href="#_{{diffanchor}}" class="list-group-item list-group-item-action pl-2 pr-2 border-0">
<div class="clearfix">
<div class="float-right"><span class="font-size-09 badge badge-success">+{{added}}</span> <span class="font-size-09 badge badge-danger">-{{removed}}</span></div>
<div class="pull-xs-left pr-changes-description"><strong>file <span class="text-warning">renamed</span></strong></div>
</div>
<div class="ellipsis pr-changes-description">
<strike class="text-muted">{{oldfilepath}}</strike> <br/>
<small>{{newfilepath}}</small>
</div>
</a>
{%- endmacro %}
{% macro changesdeletedfile(filepath, added, removed, diffanchor) -%}
<a href="#_{{diffanchor}}" class="list-group-item list-group-item-action pl-2 pr-2 border-0">
<div class="clearfix">
<div class="float-right"><span class="font-size-09 badge badge-danger">-{{removed}}</span></div>
<div class="pull-xs-left pr-changes-description"><strong>file <span class="text-danger">removed</span></strong></div>
</div>
<div class="ellipsis pr-changes-description">
<small>{{filepath}}</small>
</div>
</a>
{%- endmacro %}
{% macro changesaddedfile(filepath, added, removed, diffanchor) -%}
<a href="#_{{diffanchor}}" class="list-group-item list-group-item-action pl-2 pr-2 border-0">
<div class="clearfix">
<div class="float-right"><span class="font-size-09 badge badge-success">+{{added}}</span></div>
<div class="pull-xs-left pr-changes-description"><strong>file <span class="text-success">added</span></strong></div>
</div>
<div class="ellipsis pr-changes-description">
<small>{{ filepath | unicode }}</small>
</div>
</a>
{%- endmacro %}
<div class="list-group list-group-flush">
{% for patch in diff %}
{% set patchstats = (patch | patch_stats) %}
{%- if patchstats["status"] == 'D' -%}
{{ changesdeletedfile(patchstats["new_path"], patchstats["lines_added"], patchstats["lines_removed"], loop.index) }}
{%-elif patchstats["status"] == 'A' -%}
{{ changesaddedfile(patchstats["new_path"], patchstats["lines_added"], patchstats["lines_removed"], loop.index) }}
{%-elif patchstats["status"] == 'M' -%}
{{ changeschangedfile(patchstats["new_path"], patchstats["lines_added"], patchstats["lines_removed"], loop.index) }}
{%- else -%}
{{changesrenamedfile(patchstats["old_path"], patchstats["new_path"], patchstats["lines_added"], patchstats["lines_removed"], loop.index) }}
{%-endif-%}
{% endfor %}
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div> <!-- tab content-->
</div>
</div>
{% endblock %}
{% block jscripts %}
{{ super() }}
<script type="text/javascript" nonce="{{ g.nonce }}" src="{{
url_for('static', filename='vendor/jquery.textcomplete/jquery.textcomplete.min.js') }}?version={{ g.version}}"></script>
<script type="text/javascript" nonce="{{ g.nonce }}" src="{{
url_for('static', filename='vendor/emojione/emojione.min.js') }}?version={{ g.version}}"></script>
<script type="text/javascript" nonce="{{ g.nonce }}" src="{{
url_for('static', filename='emoji/emojicomplete.js') }}?version={{ g.version}}"></script>
<script type="text/javascript" nonce="{{ g.nonce }}" src="{{
url_for('static', filename='vendor/selectize/selectize.min.js') }}?version={{ g.version}}"> </script>
<script type="text/javascript" nonce="{{ g.nonce }}" src="{{
url_for('static', filename='vendor/jquery.caret/jquery.caret.min.js') }}?version={{ g.version}}"></script>
<script type="text/javascript" nonce="{{ g.nonce }}" src="{{
url_for('static', filename='vendor/jquery.atwho/jquery.atwho.min.js') }}?version={{ g.version}}"></script>
<script type="text/javascript" nonce="{{ g.nonce }}" src="{{
url_for('static', filename='request_ev.js') }}?version={{ g.version}}"></script>
<script type="text/javascript" nonce="{{ g.nonce }}">
function cancel_edit_btn() {
$(".cancel").unbind();
$(".cancel").click(
function() {
var item = $(this).closest('section');
$(item.parent().find('.issue_comment')).show();
$(item.parent().find('.issue_actions')).show();
var form = item.find('.pr_comment_form');
{# regular comments have the .pr_comment_form within the closest section #}
if (form.length){
$(form).remove();
} else {
{# inline comments have the section within the .pr_comment_form #}
var form = $(this).closest('.pr_comment_form').parent();
$(form).remove();
}
return false;
}
);
};
function setup_edit_btns() {
$(".edit_btn").unbind();
$(".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().find('.issue_comment');
$(sec).hide();
el.parent().find('.issue_actions').hide();
$(sec).after(res);
cancel_edit_btn();
},
error: function() {
alert('Could not make edit work');
}
});
return false;
});
};
function setup_reply_btns() {
$(".reply").unbind();
$( ".reply" ).click(
function() {
var _section = $(this).closest('.card');
var _comment = _section.find('.comment_body');
var _text = _comment.text().split("\n");
var _output = new Array();
for (var cnt=0; cnt < _text.length; cnt++) {
_output[cnt] = '> ' + _text[cnt];
}
var _prev = $.trim($( "#comment" ).val());
if (_prev.length > 0){
_prev += "\n\n";
}
$( "#comment" ).val(_prev + _output.join("\n"));
$( "#comment" ).focus();
}
);
};
function showTab(){
$('#pr-tabs a[href="#request_diff"]').tab('show')
}
{% if pull_request %}
function show_merge_status(){
function process_response(res) {
$('#spinner').hide();
$('#merge_dropdown_btn').removeClass("disabled");
$('#merge_dropdown_btn span.fa').removeClass("fa-spin");
if (res.code == 'FFORWARD'){
$('#merge_dropdown_btn').toggleClass("btn-outline-secondary btn-success");
$('#merge_dropdown_btn span.fa').toggleClass("fa-circle-o-notch fa-check");
$('#merge_btn').addClass("btn-success");
$('#merge-alert .alert').addClass("alert-success");
$('#merge-alert-message').text(res.message);
$('#merge-alert #rebase_btn').hide();
$('#merge-alert div.small').show();
$('#merge_btn').show();
}
else if (res.code == 'MERGE') {
$('#merge_dropdown_btn').toggleClass("btn-outline-secondary btn-warning");
$('#merge_dropdown_btn span.fa').toggleClass("fa-circle-o-notch fa-check");
$('#merge_btn').addClass("btn-warning");
$('#merge-alert .alert').addClass("alert-warning");
$('#merge-alert-message').text(res.message);
$('#merge-alert div.small').show();
$('#merge_btn').show();
}
else if (res.code == 'NEEDSREBASE') {
$('#merge_dropdown_btn').toggleClass("btn-outline-secondary btn-warning");
$('#merge_dropdown_btn span.fa').toggleClass("fa-circle-o-notch fa-times");
$('#merge_btn').hide();
$('#merge-alert .alert').addClass("alert-warning");
$('#merge-alert-message').text(res.message);
$('#merge-alert div.small').hide();
}
else if (res.code == 'CONFLICTS') {
$('#merge_dropdown_btn').toggleClass("btn-outline-secondary btn-danger");
$('#merge_dropdown_btn span.fa').toggleClass("fa-circle-o-notch fa-times");
$('#merge_btn').hide();
$('#merge-alert .alert').addClass("alert-danger");
$('#merge-alert-message').text(res.message);
$('#merge-alert div.small').hide();
$('#merge-alert #rebase_btn').hide();
}
else if (res.code == 'NO_CHANGE') {
$('#merge_btn').hide();
$('#merge_dropdown_btn span.fa').toggleClass("fa-circle-o-notch fa-times");
$('#merge-alert .alert').addClass("alert-secondary");
$('#merge-alert-message').text(res.message);
$('#merge-alert div.small').hide();
$('#merge-alert #rebase_btn').hide();
}
};
$('#spinner').show();
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
$.ajax({
url: '{{ url_for("internal_ns.mergeable_request_pull") }}' ,
beforeSend: function(){sleep(8000); return true;},
type: 'POST',
data: {
requestid: "{{ pull_request.uid }}",
csrf_token: "{{ mergeform.csrf_token.current_token }}",
},
dataType: 'json',
success: function(res) {
process_response(res)
},
error: function(res) {
process_response(res.responseJSON);
$('#merge_btn').attr("disabled", "disabled");
}
});
return false;
}
{% endif %}
$(document).ready(function() {
$('#merge_btn').click(function() {
return confirm('Confirm merging this pull-request');
});
$('.trigger-ci-btn').click(function() {
$('#ci_pr_comment').val($(this).attr("data-comment"));
$('#ci_pr_trigger_form').submit();
});
$('.inline_comment_link_btn').click(function() { showTab() });
$('.delete_comment_btn').click(function() {
return confirm('Do you really want to remove this comment?');
});
$('#rebase_btn').click(function(){
var _conf = confirm('Confirm rebasing this pull-request');
if (_conf === false){
return false;
}
$('#merge_dropdown_btn span.fa').removeClass(
"fa-circle-o-notch fa-times fa-check").addClass(
"fa-circle-o-notch fa-fw");
$('#merge_btn').removeClass("btn-success btn-warning btn-danger");
$('#merge-alert .alert').removeClass("alert-success alert-warning alert-danger");
$('#merge_dropdown_btn').addClass("disabled");
$('#merge_dropdown_btn').removeClass(
"btn-outline-secondary btn-danger btn-warning btn-success").addClass(
"btn btn-outline-secondary btn-sm disabled dropdown-toggle");
$('#merge_dropdown_btn span.fa').addClass("fa-spin");
$.ajax({
url: '{{ url_for('api_ns.api_pull_request_rebase',
repo=repo.name,
username=username,
namespace=repo.namespace,
requestid=requestid)
}}' ,
type: 'POST',
data: {
csrf_token: "{{ mergeform.csrf_token.current_token }}",
},
dataType: 'json',
success: function(res) {
show_merge_status()
},
error: function(res) {
$('#merge_dropdown_btn').removeClass("disabled");
$('#merge_dropdown_btn span.fa').removeClass("fa-spin");
$('#merge_dropdown_btn').toggleClass("btn-outline-secondary btn-danger");
$('#merge_dropdown_btn span.fa').toggleClass("fa-circle-o-notch fa-times");
$('#merge_btn').hide();
$('#merge-alert #rebase_btn').hide();
$('#merge-alert .alert').addClass("alert-danger");
$('#merge-alert-message').text('Failed to rebase this PR');
$('#merge-alert div.small').hide();
}
});
});
$( ".commit_msg_txt" ).hide();
$( ".commit_msg_btn" ).click(function() {
var msgid = $( this ).attr('data-id');
$( '#commit_msg_' + msgid).toggle();
});
var folder = '{{url_for("static", filename="emoji/png/") }}?version={{ g.version}}';
var json_url = '{{ url_for("static", filename="vendor/emojione/emoji_strategy.json") }}?version={{ g.version}}';
var branchselect = $('#branch_select').selectize({
create: false,
sortField: 'text',
allowEmptyOption: false,
onChange: function(value) {
if (value != ""){
var sel = $('#branch_select');
var final_url = "{{ url_for('ui_ns.new_request_pull',
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace, repo=repo.name,
branch_from=branch_from, branch_to='--', project_to=project_to) }}";
final_url = final_url.replace('--', sel.val());
window.location.href = final_url;
}
}
});
var branchselect = $('#branch_from_select').selectize({
create: false,
sortField: 'text',
allowEmptyOption: false,
onChange: function(value) {
if (value != ""){
var sel = $('#branch_from_select');
var final_url = "{{ url_for('ui_ns.new_request_pull',
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace, repo=repo.name,
branch_from='--', branch_to=branch_to, project_to=project_to) }}";
final_url = final_url.replace('--', sel.val());
console.log(final_url);
//return false;
window.location.href = final_url;
}
}
});
$('.form_pr_drop_comment').submit(function() {
return try_async_comment($(this), null);
});
$('.form_pr_add_comment').submit(function() {
return try_async_comment($(this), false);
})
{% if pull_request %}
{# These lines are only for existing pull-requests, not new ones #}
emoji_complete(json_url, folder);
$('#local_pull_info_btn').click(function(){
var _el = $('#local_pull_info');
if (! _el.is(':visible')){
_el.show();
$('#local_pull_info_btn').html('<span class="fa fa-arrow-circle-up fa-fw fa-1x">');
} else {
_el.hide();
$('#local_pull_info_btn').html('<span class="fa fa-arrow-circle-down fa-fw fa-1x">');
}
return false;
});
$('#close_pr').click(function(){
return window.confirm("Are you sure you want to close this requested pull?");
});
$('#reopen_pr').click(function(){
return window.confirm("Are you sure you want to reopen this requested pull?");
});
{% if g.authenticated %}
$( ".code_table tr" ).hover(
function() {
$( this ).find( ".prc_img" ).show().width(13);
}, function() {
$( this ).find( ".prc_img" ).hide();
}
);
$( ".prc" ).click(
function() {
var disabled = $('.prc').attr('disabled');
if (disabled === true || disabled == "disabled") {
return false;
}
$(".prc").attr("disabled","disabled");
var row = $( this ).attr('data-row');
var commit = $( this ).attr('data-commit');
var filename = $( this ).attr('data-filename');
var tree_id = $( this ).attr('data-tree');
var url = "{{ url_for(
'ui_ns.pull_request_add_comment',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=requestid, commit='', filename='', row='') }}".slice(0, -2);
url = url + commit + '/' + filename + '/' + row
if (tree_id) {
url += '?tree_id=' + tree_id;
}
var rowid = $(this).prev().find('a').attr('id');
var table = $( this ).parent().parent();
var nextid = rowid.replace('_' + row, '_' + (Number(row) + 1));
var next_row = table.find('#' + nextid).parent().parent();
{# If we're at the last row, we won't be able to find the next_row
therefore we need to add it manually #}
if (next_row.length == 0) {
table.find("tr:last").after(
'<tr><td><a id="' + nextid + '"></a></td></tr>');
next_row = table.find('#' + nextid).parent().parent();
}
if (next_row.prev().find('.pr_comment_form').length == 0){
$.get( url , function( data ) {
next_row.before(
'<tr><td></td><td colspan="2" class="pr_comment_form"> \
<div class="card m-x-1"><div class="card-block">'
+ data + '</div></div></td></tr>' );
cancel_edit_btn();
$(".prc").removeAttr("disabled");
emoji_complete(json_url, folder);
});
} else {
next_row.prev().find('.pr_comment_form').parent().remove();
$(".prc").removeAttr("disabled");
}
}
);
setup_edit_btns();
setup_reply_btns();
$(".comment_body").each(function(ind, obj) {
var source = $(obj).html();
var preview = emojione.toImage(source);
$(obj).html(preview);
});
$(".pr_comment").each(function(ind, obj) {
var source = $(obj).html();
var preview = emojione.toImage(source);
$(obj).html(preview);
});
{% endif %}
{% if pull_request.status == 'Open' %}
show_merge_status()
{% endif %}
{% endif %}
});
{% if g.authenticated and pull_request %}
$('#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+"*"
},
function( data ) {
callback( data.users.map(function(x) { return { user: x }; }) );
}
);
}
});
$( ".editmetadatatoggle" ).click(
function() {
$( ".issue-metadata-form" ).toggle();
$( ".issue-metadata-display" ).toggle();
}
);
function set_ui_for_comment(setting){
if (setting == false) {
$(document.body).find('input[type="submit"]').removeAttr("disabled");
document.body.style.cursor = 'default';
} else {
$(document.body).find('input[type="submit"]').attr("disabled", "disabled");
document.body.style.cursor = 'wait';
}
}
$("#merge_pr_form").submit( function() {
set_ui_for_comment(true);
var _c = $("#comment");
if (_c.val()) {
$('<input />').attr('type', 'hidden')
.attr('name', "comment")
.attr('value', _c.val())
.appendTo(this);
}
return true;
});
function try_async_comment(form, inline) {
set_ui_for_comment(true);
var _data = $(form).serialize();
var btn = $(document.activeElement);
if (btn[0].name == 'drop_comment'){
_data += '&drop_comment=' + btn[0].value;
set_ui_for_comment(false);
return true;
}
var _url = form.attr("action");
if (_url.indexOf('?') != -1){
_url += "&js=1";
} else {
_url += "?js=1";
}
/* Keep some variable in memory before sending them in case the SSE is down */
var _update = false;
var _comment = inline ? $(form).find('#inline-comment').val() : $(form).find('#comment').val();
var _comment_id = null;
if (!_comment && form.update_comment) {
_update = true;
_comment_id = $(form.edit_comment).val();
_comment = $(form).find('#update_comment').val();
}
var _commit_id = null;
var _line = null;
var _token = "{{ mergeform.csrf_token.current_token }}";
var _base_url = _url.split('?')[0];
if (!_base_url.match(/comment$/)){
_commit_id = _url.split('/comment/')[1];
_commit_id = _commit_id.split('/')[0];
items = _url.split('/');
_line = items[items.length -1];
}
$.post( _url, $(form).serialize() )
.done(function(data) {
if(data == 'ok') {
$('#comment').val('');
$('#preview').html('');
$('#previewinmarkdown').addClass('inactive');
$('#previewinmarkdown').removeClass('active');
$('#preview').hide();
$('#comment').show();
/* We have submitted the comment correctly */
var item = $('.pr_comment_form').closest('tr');
if (!$(item.parent().children()[1]).is(':visible')){
$(item.parent().children()[1]).show()
}
item.remove();
if (!sse) {
if (!_comment){
// Make the browser submit the form sync
form.submit();
}
console.log('no sse, adding the comment manually');
$.ajax({
url: "{{ url_for('ui_ns.markdown_preview') }}" ,
type: 'POST',
data: {
content: _comment,
csrf_token: _token,
},
dataType: 'html',
success: function(res) {
var _comment = emojione.toImage(res);
if (_update) {
var data = {
comment_updated: _comment,
comment_user: "{{ g.fas_user.username }}",
comment_date: Date.now(),
comment_id: _comment_id,
avatar_url: "{{ g.fas_user.email | avatar_url(16) }}",
}
} else {
var data = {
comment_added: _comment,
comment_user: "{{ g.fas_user.username }}",
comment_date: Date.now(),
avatar_url: "{{ g.fas_user.email | avatar_url(16) }}",
commit_id: _commit_id,
line: _line,
}
}
process_event(
data,
"{{ request.uid }}",
"{{ g.fas_user.username if g.authenticated or '' }}");
set_ui_for_comment(false);
setup_reply_btns()
return false;
}
});
return false;
} else {
set_ui_for_comment(false);
}
} else {
// Make the browser submit the form sync
form.submit();
}
})
.fail(function() {
// Make the browser submit the form sync
form.submit();
})
return false;
};
$(".add_comment_form").submit(function(event) {
return try_async_comment(this, true);
})
{% endif %}
</script>
<script type="text/javascript" nonce="{{ g.nonce }}">
var cur_hash = null;
function color_tags() {
$(".badge-tag").each(function(ind, obj) {
$(obj).css('background-color', $(obj).attr('data-bg-color'));
});
}
function highlight_comment() {
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;
};
function updateHighlight(onload) {
var cls = "highlighted-line";
$('.' + cls).removeClass(cls)
if (location.hash === '') {
// Display comments when the hash is removed.
$('#pr-tabs .nav-item a.nav-link, #pr-wrapper .tab-pane').removeClass('active');
$('#comments, [href="#comments"]').addClass('active');
return
}
if (location.hash.indexOf("comment-") > -1) {
highlight_comment();
} else {
if (onload) {
// Hide all tabs, and then show the one pointed to by the hash.
// This is neccessary to handle 'Back' button presses in the browser,
// which otherwise break the tabs view .
$('#pr-tabs .nav-item a.nav-link').removeClass('active');
$('#pr-wrapper .tab-pane').removeClass('active');
// When the hash points to 'Files Changed' tab, or a highlight.
if (location.hash.indexOf("request_diff") > -1 ||
location.hash.indexOf("_") === 1 ||
location.hash.indexOf("c-") === 1) {
$('[href="#request_diff"]').addClass('active');
$('#request_diff').addClass('active');
}
// When the hash points to 'Commits' tab.
else if (location.hash.indexOf("commit_list") > -1) {
$('[href="#commit_list"]').addClass('active');
$('#commit_list').addClass('active');
}
// If neither, then show the 'Comments' tab by default.
else {
$('#comments').addClass('active');
$('[href="#comments"]').addClass('active');
}
}
var file = parseInt(location.hash.substr(2).split('__')[0], 10);
var lines = location.hash.split('__')[1].split('-').map(function (x) { return parseInt(x, 10) });
for (var i = lines[lines.length - 1]; i >= lines[0]; i--) {
$('#' + '_' + file + '__' + i).closest('tr').addClass(cls);
}
}
}
$(document).ready(function () {
color_tags();
{% if g.authenticated and pull_request %}
function set_up_subcribed() {
$("#subcribe-btn").click(function(){
var _url = "{{ url_for(
'api_ns.api_subscribe_pull_request',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
requestid=pull_request.id
) }}";
var _btn = $("#subcribe-btn");
var _data = {};
if (_btn.text() == 'Unsubscribe'){
_data.status = false;
} else {
_data.status = true;
}
console.log(_data);
$.post( _url, _data ).done(
function(data) {
var _btn = $("#subcribe-btn");
var _countlabel = $("#subscribers-count")
var _count = parseInt(_countlabel.text())
if (_btn.text() == 'Subscribe'){
_btn.text('Unsubscribe');
_countlabel.text(_count+1)
var _html = '<a href="/user/' + data.user + '"'
+ 'title="'+data.user+'" id="sub-avatar-'+data.user+'">'
+ '<img src="'+data.avatar_url+'" class="pb-1"></a>';
$('#subscribers_list').prepend(_html);
} else {
_btn.text('Subscribe');
_countlabel.text(_count-1);
$('#sub-avatar-'+data.user).remove();
}
return false;
}
)
return false;
});
};
set_up_subcribed();
{% endif %}
updateHighlight(true)
{% if form or pull_request %}
$( "#preview" ).hide();
$( "#previewinmarkdown" ).click(
function(event, ui) {
{% if form %}
var _el = $( "#initial_comment" );
var _token = "{{ form.csrf_token.current_token }}";
{% else %}
var _el = $( "#comment" );
var _token = "{{ mergeform.csrf_token.current_token }}";
{% endif %}
var _text = _el.val();
var _url = "{{ url_for('ui_ns.markdown_preview') }}";
$.ajax({
url: _url ,
type: 'POST',
data: {
content: _text,
csrf_token: _token,
},
dataType: 'html',
success: function(res) {
var preview = emojione.toImage(res);
$( "#preview" ).html(preview);
$( "#previewinmarkdown" ).addClass("active");
$( "#editinmarkdown" ).removeClass("active");
_el.hide();
$( "#preview" ).show();
},
error: function() {
alert('Unable to generate preview!'+error);
}
});
return false;
}
);
$( "#editinmarkdown" ).click(
function(event, ui) {
{% if form %}
var _el = $( "#initial_comment" );
var _token = "{{ form.csrf_token.current_token }}";
{% else %}
var _el = $( "#comment" );
var _token = "{{ mergeform.csrf_token.current_token }}";
{% endif %}
$( "#editinmarkdown" ).addClass("active");
$( "#previewinmarkdown" ).removeClass("active");
_el.show();
$( "#preview" ).hide();
}
);
{% endif %}
$.get("{{ url_for('api_ns.api_users') }}", {
pattern: '*'
}).done(function(resp) {
var userConfig = {
at: '@',
data: resp['mention'],
insertTpl: '@${username}',
displayTpl: "<li><img src=\"${image}\"> ${username} <small>${name}</small></li>",
searchKey: "username"
}
$("#comment").atwho(userConfig);
$("#initial_comment").atwho(userConfig);
});
$.when(
{%- if g.issues_enabled %}
$.get("{{ url_for('api_ns.api_view_issues',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
status='all') }}"),
{%- else %}
{},
{%- endif %}
{%- if repo.settings.get('pull_requests', True) %}
$.get("{{ url_for('api_ns.api_pull_request_views',
repo=repo.name,
username=repo.user.user if repo.is_fork else None,
namespace=repo.namespace,
status='all') }}")
{%- else %}
{}
{%- endif %}
).done(function(issuesResp, prResp) {
// 0 is the api response
var issuesAndPrs = [];
if (typeof issuesResp[0] !== 'undefined') {
issuesAndPrs = issuesAndPrs.concat(issuesResp[0]['issues']);
}
if (typeof prResp[0] !== 'undefined') {
issuesAndPrs = issuesAndPrs.concat(prResp[0]['requests']);
}
var data = $.map(issuesAndPrs, function(ticket, idx) {
return {
name: ticket.id.toString(),
title: $('<div>').text(ticket.title).html()
}
});
var issueAndPrConfig = {
at: '#',
data: data,
insertTpl: '#${name}',
displayTpl: "<li>#${name}<small> ${title}</small></li>",
}
$("#comment").atwho(issueAndPrConfig);
$("#initial_comment").atwho(issueAndPrConfig);
});
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: false,
labelField: "item",
valueField: "item",
searchField: ["item"],
});
} );
$(window).on('hashchange', updateHighlight);
var selected = [];
$("[data-line-number]").click(function (ev) {
var line = $(this).attr('data-line-number');
var file = $(this).attr('data-file-number');
if (ev.shiftKey) {
selected = selected.slice(-1).concat(line);
} else {
selected = [line];
}
var hash = '_' + file + '__' + selected[0];
if (selected.length === 2) {
hash = '_' + file + '__' + Math.min(selected[0], selected[1]) + '-' + Math.max(selected[0], selected[1]);
}
window.location.hash = hash;
return false;
});
// Update hash links in the addressbar according to which tab is clicked
// on the PR page.
$(document).on('click', '#pr-tabs a', function() {
if ($(this).text().trim() == 'Comments' || $(this).text().trim() == 'Patch'){
window.location.hash = '';
} else {
window.location.hash = $(this).attr('href');
}
});
// Show an icon to open the changed file, when the user hovers over the
// @@ -x,y +x,y @@ line in the diff. Clicking this icon opens the file (at the
// relevant line number) in a new tab.
$(document).on("mouseenter", "td.cell2", function(){
$(this).find("a.open_changed_file_icon_wrap").css('visibility', 'visible');
});
$(document).on("mouseleave", "td.cell2", function() {
$(this).find("a.open_changed_file_icon_wrap").css('visibility', 'hidden');
});
{% if g.authenticated and (g.repo_user or pull_request.user.user == g.fas_user.username or open_access) %}
function take_issue(){
var _url = "{{ url_for('api_ns.api_pull_request_assign',
repo=repo.name, namespace=repo.namespace, username=username,
requestid=requestid) }}";
var _data = {assignee: "{{ g.fas_user.username }}"};
$.post (_url, _data ).done(
function(data) {
var _user_url = '\n<div class="ml-2"><div class="mt-1">{{g.fas_user.username| avatar(size=24) | safe}} '
+ '<a href="{{ url_for("ui_ns.request_pulls", repo=repo.name, username=username, namespace=repo.namespace) }}'
+ '?assignee={{ g.fas_user.username }}">'
+ '{{ g.fas_user.username }}</a>'
+ ' — <a class="pointer" id="drop-btn" title="drop the assignment of this pull-request">Drop</a></div></div>';
$('#assignee_plain').html(_user_url);
$('#assignee').val("{{ g.fas_user.username }}");
setup_btn_take_drop();
}
).fail(function() {
alert( "An error occured, could not assign this pull-request to you." );
})
return false;
}
{% endif %}
{% if g.authenticated and (
g.repo_user
or pull_request.user.user == g.fas_user.username
or pull_request.assignee.user == g.fas_user.username) %}
function drop_issue(){
var _url = "{{ url_for('api_ns.api_pull_request_assign',
repo=repo.name, namespace=repo.namespace, username=username,
requestid=requestid) }}";
var _data = {assignee: ""};
$.post( _url, _data ).done(
function(data) {
var _user_url = '<div class="ml-2">\n<span class="text-muted">None</span>'
+ ' — <a class="pointer" id="take-btn" title="assign this pull-request to you">Take</a></div>';
$('#assignee_plain').html(_user_url);
$('#assignee').val("");
setup_btn_take_drop();
}
).fail(function() {
alert( "An error occured, could not drop the current assignee." );
})
return false;
}
{% endif %}
function setup_btn_take_drop(){
{% if g.authenticated and g.repo_user %}
$("#take-btn").click(take_issue)
{% endif %}
{% if g.authenticated and (
g.repo_user
or pull_request.user.user == g.fas_user.username
or pull_request.assignee.user == g.fas_user.username) %}
$("#drop-btn").click(drop_issue);
{% endif %}
}
{% if g.authenticated and (
g.repo_user
or pull_request.user.user == g.fas_user.username
or pull_request.assignee.user == g.fas_user.username) %}
setup_btn_take_drop();
{% endif %}
</script>
<script type="text/javascript" nonce="{{ g.nonce }}">
var source = null;
var sse = true;
{% if config['EVENTSOURCE_SOURCE'] and pull_request %}
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);
process_event(
data,
"{{ request.uid }}",
"{{ g.fas_user.username if g.authenticated or '' }}");
setup_edit_btns();
setup_reply_btns();
}, false);
{% else %}
sse = false;
{% endif %}
</script>
{% if repo.quick_replies %}
<script type="text/javascript" src="{{ url_for('static', filename='quick_reply.js') }}?version={{ g.version}}"></script>
{% endif %}
<script type="text/javascript" src="{{ url_for('static', filename='reactions.js') }}?version={{ g.version}}"></script>
{% endblock %}