{#-
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
-#}
{% extends g.theme.master %}
{% import 'allura:templates/jinja_master/lib.html' as lib with context %}
{% do g.register_app_css('css/tracker.css') %}

{% block title %}{{c.project.name}} / {{c.app.config.options.mount_label}} / Search{% endblock %}

{% block header %}Search {{c.app.config.options.mount_point}}: {{q}}{% endblock %}

{% block head %}
    {% if 'q=' in request.query_string %}
    <meta name="robots" content="noindex, follow">
    {% endif %}
    <link rel="alternate" type="application/rss+xml" title="RSS" href="feed.rss"/>
    <link rel="alternate" type="application/atom+xml" title="Atom" href="feed.atom"/>
    {{ lib.canonical_tag(page) }}
    {{ lib.pagination_meta_tags(request, page, count, limit) }}

{% endblock %}

{% block actions %}
  {{ lib.maximize_content_button() }}
  {% set feed_url = tg.url(c.app.url+'search_feed/', dict(q=q, limit=limit, sort=sort)) %}
  {{ g.icons['feed'].render(href=feed_url, rel='nofollow') }}
{% if allow_edit and count != 0 %}
  {% set bulk_edit_url = tg.url(c.app.url+'edit/', dict(q=q, limit=limit, sort=sort, page=page, filter=filter)) %}
  {{ g.icons['edit'].render(href=bulk_edit_url, title='Bulk Edit') }}
{% endif %}
{% if allow_move and count != 0 %}
  {% set bulk_move_url = tg.url(c.app.url+'move/', dict(q=q, limit=limit, sort=sort, page=page, filter=filter)) %}
  {{ g.icons['move'].render(href=bulk_move_url, title='Bulk Move', show_title=True) }}
{% endif %}
{% endblock %}

{% if q and h.has_access(c.app, 'save_searches') %}
  {% block edit_box %}
    <div class="editbox" style="display:none">
      {{c.bin_form.display(
        value=dict(summary=q,terms=q,sort=sort,_id=bin and bin._id or None),
        action=c.project.url()+'admin/'+c.app.config.options.mount_point+'/bins/save_bin'
      )}}
    </div>
  {% endblock %}
{% endif %}

{% block content %}
{%if h.has_access(c.app, 'delete') and c.app.globals.has_deleted_tickets()%}
<p>
    {%if deleted%}
    <a href="{{tg.url('', dict(q=q, page=page, limit=limit, sort=sort, deleted=False))}}">Hide deleted tickets</a>
    {%else%}
    <a  href="{{tg.url('', dict(q=q, page=page, limit=limit, sort=sort, deleted=True))}}">Show deleted tickets</a>
    {%endif%}
</p>
{%endif%}
{% if help_msg %}
  <div id="search-ticket-help-msg" class="grid-19 info">{{g.markdown.convert(help_msg)}}</div>
{% endif %}
<div class="grid-19">
{% if bin %}
  <input type="text" id="bin_summary" value="{{bin.summary}}" style="width: 125px; float: left; margin-right: .5em">
{% endif %}
<form method="GET">
  <input type="text" name="q" value="{{q}}" style="width: 280px; float: left; margin-right: .5em" id="bin_terms">
  {% if bin and h.has_access(c.app, 'save_searches') %}
    <input type="button" value="Update Search" id="save_search"/>
  {% endif %}
  <input type="submit" value="Search"/>
</form>
{{ g.icons['help'].render(
    show_title=True,
    target='_blank',
    href=tg.url(c.app.url + 'search_help/'),
    rel='nofollow',
    extra_css='btn search_help_modal') }}

</div>
<div style="clear:both"></div>
{{c.ticket_search_results.display(solr_error=solr_error,
  count=count,
  limit=limit,
  query=q,
  filter=filter,
  tickets=tickets,
  sortable_custom_fields=sortable_custom_fields,
  columns=columns,
  page=page,
  sort=sort)}}

{% endblock %}

{% block extra_js %}

{% if q and h.has_access(c.app, 'save_searches') %}
    <script type="text/javascript">
      $('#save_search').click(function(){
        $('div.editbox input[name=summary]').val($('#bin_summary').val());
        $('div.editbox input[name=terms]').val($('#bin_terms').val());
        $('div.editbox form').submit();
      });
      $('#cancel_new_bin').click(function(){
        $('div.editbox').hide();
      });

    </script>
{% endif %}

{% endblock %}
