fixes to conform html spec
[qcg-portal.git] / qcg / templates / qcg / jobs.html
index c7ae855..1b37616 100644 (file)
@@ -1,23 +1,16 @@
 {% extends 'qcg/base.html' %}
-
-{% load staticfiles %}
+{% load staticfiles bootstrap3 query_string qcg_utils %}
 
 {% block extra_css %}
     <link href="{% static 'qcg/treegrid/css/jquery.treegrid.css' %}" rel="stylesheet">
-
-    <style>
-        .treegrid-expander {
-            opacity: 0.5;
-        }
-
-        .treegrid-expander:hover {
-            opacity: 1;
-        }
-    </style>
+    <link href="{% static 'qcg/daterangepicker/daterangepicker-bs3.css' %}" rel="stylesheet" />
 {% endblock %}
 
 {% block extra_js %}
     <script src="{% static 'qcg/treegrid/js/jquery.treegrid.js' %}"></script>
+    <script src="{% static 'qcg/moment/moment.min.js' %}"></script>
+    <script src="{% static 'qcg/daterangepicker/daterangepicker.js' %}"></script>
+    <script src="{% static 'qcg/cookie/jquery.cookie.min.js' %}"></script>
 
     <script>
         $(function() {
                 }
             });
 
+            $('input[name="submission"],input[name="finish"]').daterangepicker({
+                opens: 'center',
+                format: 'DD.MM.YYYY',
+                ranges: {
+                    'Dzisiaj': [moment(), moment()],
+                    'Wczoraj': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
+                    'Ostatnie 7 dni': [moment().subtract(6, 'days'), moment()],
+                    'Ostatnie 30 dni': [moment().subtract(29, 'days'), moment()]
+                },
+                locale: {
+                    applyLabel: 'OK',
+                    cancelLabel: 'Anuluj',
+                    fromLabel: 'Od',
+                    toLabel: 'Do',
+                    weekLabel: 'T',
+                    customRangeLabel: 'Zakres',
+                    daysOfWeek: moment.weekdaysMin(),
+                    monthNames: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'],
+                    firstDay: 1
+                }
+            });
+
+            $('#select-all-columns').click(function() {
+                $('#id_columns').find('.checkbox input').prop('checked', true);
+            });
 
+            $('#default-columns').click(function() {
+                $('#select-all-columns').click();
+                $('#id_columns_0').prop('checked', false);
+            });
+
+            $('#columns-form').submit(function(e) {
+                e.preventDefault();
+                $.cookie.raw = true;
+                $.cookie('columns', $(this).serialize(), {path: location.pathname});
+                location.reload();
+            });
         });
     </script>
 {% endblock %}
 
 {% block container %}
+    <form action="." class="pull-right">
+        {% get_params_as_hidden 'host' 'purged' 'submission' 'finish' %}
+        <div class="btn-toolbar" role="toolbar">
+            <div class="btn-group" role="group">
+                <div class="input-group">
+                    <input type="search" name="keywords" value="{{ filters.keywords.value|default:'' }}"
+                           maxlength="500" class="form-control" placeholder="Wyszukaj frazę">
+                    <span class="input-group-btn">
+                        <button class="btn btn-default" type="submit" title="Szukaj">
+                            <span class="glyphicon glyphicon-search"></span>
+                        </button>
+                    </span>
+                </div>
+            </div>
+            <div class="btn-group" data-toggle="buttons">
+                <label class="btn btn-default{% if checked_status.0 %} active{% endif %}" title="Aktywne">
+                    <input name="status" value="0" type="checkbox" {% if checked_status.0 %}checked{% endif %} onchange="this.form.submit()">
+                    <span class="glyphicon glyphicon-hourglass" aria-hidden="true"></span>
+                </label>
+                <label class="btn btn-default{% if checked_status.1 %} active{% endif %}" title="Zakończone">
+                    <input name="status" value="1" type="checkbox" {% if checked_status.1 %}checked{% endif %} onchange="this.form.submit()">
+                    <span class="glyphicon glyphicon-saved" aria-hidden="true"></span>
+                </label>
+                <label class="btn btn-default{% if checked_status.2 %} active{% endif %}" title="Niepowodzenia">
+                    <input name="status" value="2" type="checkbox" {% if checked_status.2 %}checked{% endif %} onchange="this.form.submit()">
+                    <span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
+                </label>
+            </div>
+            <div class="btn-group" role="group">
+                <a href="#advanced" data-toggle="modal" class="btn btn-default" title="Filtry zaawansowane">
+                    <span class="glyphicon glyphicon-option-horizontal"></span>
+                </a>
+            </div>
+            <div class="btn-group" role="group">
+                <a href="#columns" data-toggle="modal" class="btn btn-default" title="Kolumny">
+                    <span class="glyphicon glyphicon-list"></span>
+                </a>
+            </div>
+        </div>
+    </form>
+
     <h1 class="page-header">
         {% block title %}Lista zadań{% endblock %}
     </h1>
 
-{#    <form class="row form-inline">#}
-{#        <div class="col-md-9 col-md-offset-1">#}
-{#            <div class="form-group">#}
-{#                <label class="sr-only" for="search">Szukaj w opisie lub uwagach</label>#}
-{#                <input type="text" class="form-control" id="search" placeholder="Szukaj w opisie lub uwagach">#}
-{#            </div>#}
-{#            <div class="form-group">#}
-{#                <label class="sr-only" for="status">Status</label>#}
-{#                <select class="form-control" id="status">#}
-{#                  <option>Wybierz stan</option>#}
-{#                  <option>PENDING</option>#}
-{#                  <option>RUNNING</option>#}
-{#                  <option>FAILED</option>#}
-{#                  <option>FINISHED</option>#}
-{#                </select>#}
-{#            </div>#}
-{#            <div class="form-group">#}
-{#                <label class="sr-only" for="cluster">Klaster</label>#}
-{#                <select class="form-control" id="cluster">#}
-{#                  <option>Wybierz klaster</option>#}
-{#                  <option>Inula</option>#}
-{#                  <option>Galera</option>#}
-{#                  <option>Hydra</option>#}
-{#                  <option>Zeus</option>#}
-{#                </select>#}
-{#            </div>#}
-{#        </div>#}
-{#        <div class="col-md-1">#}
-{#            <button type="submit" class="btn btn-default">Filtruj</button>#}
-{#        </div>#}
-{#    </form>#}
-{##}
-{#    <hr />#}
+    {% if selected_filters %}
+        <div class="row">
+            <div class="col-md-offset-1 col-md-10">
+                <a href="." class="pull-right"><span class="text-muted small">Wyczyść wszystkie filtry</span></a>
+                <strong>Wybrane filtry:</strong>
+                {% for label, param, val in selected_filters %}
+                    <span class="label label-primary">{{ label }}&nbsp;<a href=".{% query_string param-=val %}" style="color: white"><span class="glyphicon glyphicon-remove"></span></a></span>
+                {% endfor %}
+            </div>
+        </div>
 
+        <hr>
+    {% endif %}
 
     <nav class="text-center" style="margin-bottom: 15px">
-        <form action="{{ request.path }}" method="get" class="form-inline" role="form" style="display: inline-block">
+        <form action="." method="get" class="form-inline" role="form" style="display: inline-block">
             <div class="input-group input-group-sm">
                 <span class="input-group-btn">
                     {% if page.has_previous %}
-                        <a href="{{ request.path }}?page={{ page.previous_page_number }}" class="btn btn-default">
+                        <a href="{% query_string "page"=page.previous_page_number %}" class="btn btn-default">
                     {% else %}
                         <a href="#" class="btn btn-default disabled">
                     {% endif %}
                 <input type="text" class="form-control text-center" id="page" name="page" value="{{ page.number }}" style="width: 50px">
                 <span class="input-group-btn">
                     {% if page.has_next %}
-                        <a href="{{ request.path }}?page={{ page.next_page_number }}" class="btn btn-default">
+                        <a href="{% query_string "page"=page.next_page_number %}" class="btn btn-default">
                     {% else %}
                         <a href="#" class="btn btn-default disabled">
                     {% endif %}
             </div>
         </form>
         &nbsp;z&nbsp;
-        <a href="{{ request.path }}?page={{ num_pages }}">{{ num_pages }}</a>
+        <a href="{% query_string "page"=num_pages %}">{{ num_pages }}</a>
     </nav>
 
     <table class="table table-hover tree">
         <thead>
             <tr>
-                <th style="width: 80px"></th>
-                <th>Opis</th>
-                <th>Wysłane</th>
-                <th>Start</th>
-                <th>Koniec</th>
-                <th>Status</th>
-                <th>Host</th>
+                <th{% if columns.JOB_ID not in displayed %} style="width: 80px"{% endif %}></th>
+                {% if columns.DESCRIPTION in displayed %}<th>Opis</th>{% endif %}
+                {% if columns.SUBMISSION in displayed %}<th>Wysłane</th>{% endif %}
+                {% if columns.START in displayed %}<th>Start</th>{% endif %}
+                {% if columns.END in displayed %}<th>Koniec</th>{% endif %}
+                {% if columns.STATUS in displayed %}<th>Status</th>{% endif %}
+                {% if columns.HOST in displayed %}<th>Host</th>{% endif %}
+                <th></th>
 {#                <th>Uwagi</th>#}
             </tr>
         </thead>
                             <td>
                                 <a href="{{ task.get_absolute_url }}">
                                     <span class="glyphicon glyphicon-file" aria-hidden="true"></span>
-{#                                    {{ task }}#}
+                                    {% if columns.JOB_ID in displayed %}{{ task }}{% endif %}
                                 </a>
+                                {% if not task.purged %}
+                                    <small class="text-muted" title="Istnieje katalog roboczy">
+                                        <span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span>
+                                    </small>
+                                {% endif %}
                             </td>
-                            <td>{{ task.note }}</td>
-                            <td>{{ task.submission_time|timesince }} temu</td>
-                            <td>{{ task.start_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>
-                            <td>{{ task.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>
-                            <td>{{ task.get_status_display }}</td>
-                            <td>{{ task.short_host_names|join:', ' }}</td>
+                            {% if columns.DESCRIPTION in displayed %}<td>{{ task.note }}</td>{% endif %}
+                            {% if columns.SUBMISSION in displayed %}<td>{{ task.submission_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
+                            {% if columns.START in displayed %}<td>{{ task.start_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
+                            {% if columns.END in displayed %}<td>{{ task.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
+                            {% if columns.STATUS in displayed %}<td>{{ task.get_status_display }}</td>{% endif %}
+                            {% if columns.HOST in displayed %}<td>{{ task.short_host_names|join:', ' }}</td>{% endif %}
+                            <td><a href="{{ task.get_absolute_url }}">szczegóły&nbsp;&rsaquo;</a></td>
                         </tr>
                     {% endwith %}
                 {% else %}
                         <td>
                             <a href="{{ job.grouper.get_absolute_url }}">
                                 <span class="glyphicon glyphicon-folder-close" aria-hidden="true"></span>
-{#                                {{ job.grouper }}#}
+                                {% if columns.JOB_ID in displayed %}{{ job.grouper }}{% endif %}
                             </a>
+                            {% if not job.grouper.purged %}
+                                <span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span>
+                            {% endif %}
                         </td>
-                        <td>{{ job.grouper.note }}</td>
-                        <td>{{ job.grouper.submission_time|timesince  }} temu</td>
-                        <td>-</td>
-                        <td>{{ job.grouper.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>
-                        <td>{{ job.grouper.get_status_display }}</td>
-                        <td>-</td>
+                        {% if columns.DESCRIPTION in displayed %}<td>{{ job.grouper.note }}</td>{% endif %}
+                        {% if columns.SUBMISSION in displayed %}<td>{{ job.grouper.submission_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
+                        {% if columns.START in displayed %}<td>-</td>{% endif %}
+                        {% if columns.END in displayed %}<td>{{ job.grouper.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
+                        {% if columns.STATUS in displayed %}<td>{{ job.grouper.get_status_display }}</td>{% endif %}
+                        {% if columns.HOST in displayed %}<td>-</td>{% endif %}
+                        <td><a href="{{ job.grouper.get_absolute_url }}">szczegóły&nbsp;&rsaquo;</a></td>
                     </tr>
 
                     {% for task in job.list %}
                             <td>
                                 <a href="{{ task.get_absolute_url }}">
                                     <span class="glyphicon glyphicon-file" aria-hidden="true"></span>
-{#                                    {{ task }}#}
+                                    {% if columns.JOB_ID in displayed %}{{ task }}{% endif %}
                                 </a>
+                                {% if not task.purged %}
+                                    <span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span>
+                                {% endif %}
                             </td>
-                            <td>{{ task.note }}</td>
-                            <td>{{ task.submission_time|timesince  }} temu</td>
-                            <td>{{ task.start_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>
-                            <td>{{ task.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>
-                            <td>{{ task.get_status_display }}</td>
-                            <td>{{ task.short_host_names|join:', ' }}</td>
+                            {% if columns.DESCRIPTION in displayed %}<td>{{ task.note }}</td>{% endif %}
+                            {% if columns.SUBMISSION in displayed %}<td>{{ task.submission_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
+                            {% if columns.START in displayed %}<td>{{ task.start_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
+                            {% if columns.END in displayed %}<td>{{ task.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
+                            {% if columns.STATUS in displayed %}<td>{{ task.get_status_display }}</td>{% endif %}
+                            {% if columns.HOST in displayed %}<td>{{ task.short_host_names|join:', ' }}</td>{% endif %}
+                            <td><a href="{{ task.get_absolute_url }}">szczegóły&nbsp;&rsaquo;</a></td>
                         </tr>
                     {% endfor %}
                 {% endifequal %}
         </tbody>
     </table>
 
+    {% if not page %}
+        <div class="alert alert-info">
+            <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
+            Brak zadań spełniających wybrane kryteria
+        </div>
+    {% endif %}
+
     <nav class="text-center">
         <ul class="pagination">
             {% if page.has_previous %}
                 <li>
-                    <a href="{{ request.path }}?page={{ page.previous_page_number }}" aria-label="Previous">
+                    <a href="{% query_string "page"=page.previous_page_number %}" aria-label="Previous">
                     <span aria-hidden="true"><span class="glyphicon glyphicon-chevron-left"></span>&nbsp;poprzednia</span>
                 </a>
             {% endif %}
             </li>
 
             <li{% ifequal page.number 1 %} class="active"{% endifequal %}>
-                <a href="{{ request.path }}?page=1">1</a>
+                <a href="{% query_string "page"=1 %}">1</a>
             </li>
 
             {% if pages_range.0 > 2 %}
 
             {% for num in pages_range %}
                 <li{% ifequal page.number num %} class="active"{% endifequal %}>
-                    <a href="{{ request.path }}?page={{ num }}">{{ num }}</a>
+                    <a href="{% query_string "page"=num %}">{{ num }}</a>
                 </li>
             {% endfor %}
 
             <li class="disabled"><span aria-hidden="true"><strong>z</strong></span></li>
-            <li><a href="{{ request.path }}?page={{ num_pages }}">{{ num_pages }}</a></li>
+            <li><a href="{% query_string "page"=num_pages %}">{{ num_pages }}</a></li>
 
             {% if page.has_next %}
                 <li>
-                    <a href="{{ request.path }}?page={{ page.next_page_number }}" aria-label="Next">
+                    <a href="{% query_string "page"=page.next_page_number %}" aria-label="Next">
                     <span aria-hidden="true">następna&nbsp;<span class="glyphicon glyphicon-chevron-right"></span></span>
                 </a>
             {% endif %}
         </ul>
     </nav>
 
+    <!-- Modal -->
+    <div class="modal fade" id="advanced" tabindex="-1" role="dialog" aria-labelledby="filters-modal-label" aria-hidden="true">
+        <div class="modal-dialog modal-lg">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title" id="filters-modal-label">Filtry zaawansowane</h4>
+                </div>
+                <div class="modal-body">
+                    <form id="advanced-form" action="." class="form-horizontal">
+                        {% bootstrap_field filters.keywords layout='horizontal' bound_css_class=' ' %}
+                        <div class="form-group">
+                            <label class="col-sm-3 col-md-4 control-label">Status</label>
+                            <div class="col-sm-9 col-md-6">
+                                <div class="btn-group" data-toggle="buttons">
+                                    {% for choice in filters.status %}
+                                        <label class="btn btn-default{% if choice.is_checked %} active{% endif %}">
+                                            <input type="checkbox" name="{{ choice.name }}" value="{{ choice.choice_value }}"
+                                                   {% if choice.is_checked %}checked{% endif %}> {{ choice.choice_label }}
+                                        </label>
+                                    {% endfor %}
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="form-group">
+                            <label class="col-sm-3 col-md-4 control-label">Host</label>
+                            <div class="col-sm-9 col-md-6">
+                                <div class="btn-group" data-toggle="buttons">
+                                    {% for choice in filters.host %}
+                                        <label class="btn btn-default{% if choice.is_checked %} active{% endif %}">
+                                            <input type="checkbox" name="{{ choice.name }}" value="{{ choice.choice_value }}"
+                                                   {% if choice.is_checked %}checked{% endif %}> {{ choice.choice_label }}
+                                        </label>
+                                    {% endfor %}
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="form-group">
+                            <label class="col-sm-3 col-md-4 control-label">Istniejący katalog roboczy?</label>
+                            <div class="col-sm-9 col-md-6">
+                                <div class="btn-group" data-toggle="buttons">
+                                    {% for choice in filters.purged %}
+                                        <label class="btn btn-default{% if choice.is_checked %} active{% endif %}">
+                                            <input type="radio" name="{{ choice.name }}" value="{{ choice.choice_value }}"
+                                                   {% if choice.is_checked %}checked{% endif %}> {{ choice.choice_label }}
+                                        </label>
+                                    {% endfor %}
+                                </div>
+                            </div>
+                        </div>
+
+                        {% bootstrap_field filters.submission layout='horizontal' bound_css_class=' ' %}
+                        {% bootstrap_field filters.finish layout='horizontal' bound_css_class=' ' %}
+                    </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
+                    <a href="." class="btn btn-warning">Wyczyść filtry</a>
+                    <button type="submit" class="btn btn-primary" form="advanced-form">Filtruj</button>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    {# Column selection modal #}
+    <div class="modal fade" id="columns" tabindex="-1" role="dialog" aria-labelledby="columns-modal-label" aria-hidden="true">
+        <div class="modal-dialog">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title" id="columns-modal-label">Wybór kolumn</h4>
+                </div>
+                <div class="modal-body">
+                    <form id="columns-form" action=".">
+                        {% bootstrap_field columns.columns %}
+                    </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
+                    <a id="select-all-columns" class="btn btn-success">Wybierz wszystkie</a>
+                    <a id="default-columns" class="btn btn-warning">Domyślne</a>
+                    <button type="submit" class="btn btn-primary" form="columns-form">Zapisz</button>
+                </div>
+            </div>
+        </div>
+    </div>
+
 {% endblock container %}