c2e14800ee884ae34ba3c327021abb1974c5cff1
[qcg-portal.git] / qcg / templates / qcg / jobs.html
1 {% extends 'qcg/base.html' %}
2 {% load staticfiles bootstrap3 query_string qcg_utils %}
3
4 {% block extra_css %}
5     <link href="{% static 'qcg/treegrid/css/jquery.treegrid.css' %}" rel="stylesheet">
6     <link href="{% static 'qcg/daterangepicker/daterangepicker-bs3.css' %}" rel="stylesheet" />
7 {% endblock %}
8
9 {% block extra_js %}
10     <script src="{% static 'qcg/treegrid/js/jquery.treegrid.js' %}"></script>
11     <script src="{% static 'qcg/moment/moment.min.js' %}"></script>
12     <script src="{% static 'qcg/daterangepicker/daterangepicker.js' %}"></script>
13     <script src="{% static 'qcg/cookie/jquery.cookie.min.js' %}"></script>
14
15     <script>
16         $(function() {
17             $('.tree').treegrid({
18                 initialState: 'collapsed',
19                 expanderExpandedClass: 'glyphicon glyphicon-chevron-down small',
20                 expanderCollapsedClass: 'glyphicon glyphicon-chevron-right small',
21                 onChange: function() {
22                     $(this).find('.glyphicon-folder-open,.glyphicon-folder-close')
23                             .toggleClass('glyphicon-folder-open').toggleClass('glyphicon-folder-close');
24                 }
25             });
26
27             $('input[name="submission"],input[name="finish"]').daterangepicker({
28                 opens: 'center',
29                 format: 'DD.MM.YYYY',
30                 ranges: {
31                     'Dzisiaj': [moment(), moment()],
32                     'Wczoraj': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
33                     'Ostatnie 7 dni': [moment().subtract(6, 'days'), moment()],
34                     'Ostatnie 30 dni': [moment().subtract(29, 'days'), moment()]
35                 },
36                 locale: {
37                     applyLabel: 'OK',
38                     cancelLabel: 'Anuluj',
39                     fromLabel: 'Od',
40                     toLabel: 'Do',
41                     weekLabel: 'T',
42                     customRangeLabel: 'Zakres',
43                     daysOfWeek: moment.weekdaysMin(),
44                     monthNames: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'],
45                     firstDay: 1
46                 }
47             });
48
49             $('#select-all-columns').click(function() {
50                 $('#id_columns').find('.checkbox input').prop('checked', true);
51             });
52
53             $('#default-columns').click(function() {
54                 $('#select-all-columns').click();
55                 $('#id_columns_0').prop('checked', false);
56             });
57
58             $('#columns-form').submit(function(e) {
59                 e.preventDefault();
60                 $.cookie.raw = true;
61                 $.cookie('columns', $(this).serialize(), {path: location.pathname});
62                 location.reload();
63             });
64         });
65     </script>
66 {% endblock %}
67
68 {% block container %}
69     <form action="." class="pull-right">
70         {% get_params_as_hidden 'host' 'submission' 'finish' %}
71         <div class="btn-toolbar" role="toolbar">
72             <div class="btn-group" role="group">
73                 <div class="input-group">
74                     <input type="search" name="keywords" value="{{ filters.keywords.value|default:'' }}"
75                            maxlength="500" class="form-control" placeholder="Wyszukaj frazę">
76                     <span class="input-group-btn">
77                         <button class="btn btn-default" type="submit" title="Szukaj">
78                             <span class="glyphicon glyphicon-search"></span>
79                         </button>
80                     </span>
81                 </div>
82             </div>
83             <div class="btn-group" data-toggle="buttons">
84                 <label class="btn btn-default{% if checked_status.0 %} active{% endif %}" title="Aktywne">
85                     <input name="status" value="0" type="checkbox" {% if checked_status.0 %}checked{% endif %} onchange="this.form.submit()">
86                     <span class="glyphicon glyphicon-hourglass" aria-hidden="true"></span>
87                 </label>
88                 <label class="btn btn-default{% if checked_status.1 %} active{% endif %}" title="Zakończone">
89                     <input name="status" value="1" type="checkbox" {% if checked_status.1 %}checked{% endif %} onchange="this.form.submit()">
90                     <span class="glyphicon glyphicon-saved" aria-hidden="true"></span>
91                 </label>
92                 <label class="btn btn-default{% if checked_status.2 %} active{% endif %}" title="Niepowodzenia">
93                     <input name="status" value="2" type="checkbox" {% if checked_status.2 %}checked{% endif %} onchange="this.form.submit()">
94                     <span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
95                 </label>
96             </div>
97             <div class="btn-group" role="group">
98                 <a href="#advanced" data-toggle="modal" class="btn btn-default" title="Filtry zaawansowane">
99                     <span class="glyphicon glyphicon-option-horizontal"></span>
100                 </a>
101             </div>
102             <div class="btn-group" role="group">
103                 <a href="#columns" data-toggle="modal" class="btn btn-default" title="Kolumny">
104                     <span class="glyphicon glyphicon-list"></span>
105                 </a>
106             </div>
107         </div>
108     </form>
109
110     <h1 class="page-header">
111         {% block title %}Lista zadań{% endblock %}
112     </h1>
113
114     {% if selected_filters %}
115         <div class="row">
116             <div class="col-md-offset-1 col-md-10">
117                 <a href="." class="pull-right"><span class="text-muted small">Wyczyść wszystkie filtry</span></a>
118                 <strong>Wybrane filtry:</strong>
119                 {% for label, param, val in selected_filters %}
120                     <span class="label label-primary">{{ label }}&nbsp;<a href=".{% query_string param-=val %}" style="color: white"><span class="glyphicon glyphicon-remove"></span></a></span>
121                 {% endfor %}
122             </div>
123         </div>
124
125         <hr>
126     {% endif %}
127
128     <nav class="text-center" style="margin-bottom: 15px">
129         <form action="." method="get" class="form-inline" role="form" style="display: inline-block">
130             <div class="input-group input-group-sm">
131                 <span class="input-group-btn">
132                     {% if page.has_previous %}
133                         <a href="{% query_string "page"=page.previous_page_number %}" class="btn btn-default">
134                     {% else %}
135                         <a href="#" class="btn btn-default disabled">
136                     {% endif %}
137                         <span class="glyphicon glyphicon-chevron-left"></span>
138                     </a>
139                 </span>
140                 <label class="sr-only" for="page">Strona</label>
141                 <input type="text" class="form-control text-center" id="page" name="page" value="{{ page.number }}" style="width: 50px">
142                 <span class="input-group-btn">
143                     {% if page.has_next %}
144                         <a href="{% query_string "page"=page.next_page_number %}" class="btn btn-default">
145                     {% else %}
146                         <a href="#" class="btn btn-default disabled">
147                     {% endif %}
148                         <span class="glyphicon glyphicon-chevron-right"></span>
149                     </a>
150                 </span>
151             </div>
152         </form>
153         &nbsp;z&nbsp;
154         <a href="{% query_string "page"=num_pages %}">{{ num_pages }}</a>
155     </nav>
156
157     <table class="table table-hover tree">
158         <thead>
159             <tr>
160                 <th{% if columns.JOB_ID not in displayed %} style="width: 80px"{% endif %}></th>
161                 {% if columns.DESCRIPTION in displayed %}<th>Opis</th>{% endif %}
162                 {% if columns.SUBMISSION in displayed %}<th>Wysłane</th>{% endif %}
163                 {% if columns.START in displayed %}<th>Start</th>{% endif %}
164                 {% if columns.END in displayed %}<th>Koniec</th>{% endif %}
165                 {% if columns.STATUS in displayed %}<th>Status</th>{% endif %}
166                 {% if columns.HOST in displayed %}<th>Host</th>{% endif %}
167                 <th></th>
168 {#                <th>Uwagi</th>#}
169             </tr>
170         </thead>
171         <tbody>
172             {% regroup page by job as jobs %}
173
174             {% for job in jobs %}
175                 {% ifequal job.list|length 1 %}
176                     {% with job.list.0 as task %}
177                         <tr class="treegrid-{{ forloop.counter }}">
178                             <td>
179                                 <a href="{{ task.get_absolute_url }}">
180                                     <span class="glyphicon glyphicon-file" aria-hidden="true"></span>
181                                     {% if columns.JOB_ID in displayed %}{{ task }}{% endif %}
182                                 </a>
183                                 {% if not task.purged %}
184                                     <small class="text-muted" title="Istnieje katalog roboczy">
185                                         <span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span>
186                                     </small>
187                                 {% endif %}
188                             </td>
189                             {% if columns.DESCRIPTION in displayed %}<td>{{ task.note }}</td>{% endif %}
190                             {% if columns.SUBMISSION in displayed %}<td>{{ task.submission_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
191                             {% if columns.START in displayed %}<td>{{ task.start_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
192                             {% if columns.END in displayed %}<td>{{ task.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
193                             {% if columns.STATUS in displayed %}<td>{{ task.get_status_display }}</td>{% endif %}
194                             {% if columns.HOST in displayed %}<td>{{ task.short_host_names|join:', ' }}</td>{% endif %}
195                             <td><a href="{{ task.get_absolute_url }}">szczegóły&nbsp;&rsaquo;</a></td>
196                         </tr>
197                     {% endwith %}
198                 {% else %}
199                     <tr class="treegrid-{{ forloop.counter }}">
200                         <td>
201                             <a href="{{ job.grouper.get_absolute_url }}">
202                                 <span class="glyphicon glyphicon-folder-close" aria-hidden="true"></span>
203                                 {% if columns.JOB_ID in displayed %}{{ job.grouper }}{% endif %}
204                             </a>
205                             {% if not job.grouper.purged %}
206                                 <span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span>
207                             {% endif %}
208                         </td>
209                         {% if columns.DESCRIPTION in displayed %}<td>{{ job.grouper.note }}</td>{% endif %}
210                         {% if columns.SUBMISSION in displayed %}<td>{{ job.grouper.submission_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
211                         {% if columns.START in displayed %}<td>-</td>{% endif %}
212                         {% if columns.END in displayed %}<td>{{ job.grouper.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
213                         {% if columns.STATUS in displayed %}<td>{{ job.grouper.get_status_display }}</td>{% endif %}
214                         {% if columns.HOST in displayed %}<td>-</td>{% endif %}
215                         <td><a href="{{ job.grouper.get_absolute_url }}">szczegóły&nbsp;&rsaquo;</a></td>
216                     </tr>
217
218                     {% for task in job.list %}
219                         <tr class="treegrid-{{ forloop.parentloop.counter }}-{{ forloop.counter }} treegrid-parent-{{ forloop.parentloop.counter }}">
220                             <td>
221                                 <a href="{{ task.get_absolute_url }}">
222                                     <span class="glyphicon glyphicon-file" aria-hidden="true"></span>
223                                     {% if columns.JOB_ID in displayed %}{{ task }}{% endif %}
224                                 </a>
225                                 {% if not task.purged %}
226                                     <span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span>
227                                 {% endif %}
228                             </td>
229                             {% if columns.DESCRIPTION in displayed %}<td>{{ task.note }}</td>{% endif %}
230                             {% if columns.SUBMISSION in displayed %}<td>{{ task.submission_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
231                             {% if columns.START in displayed %}<td>{{ task.start_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
232                             {% if columns.END in displayed %}<td>{{ task.finish_time|date:"CUSTOM_DATETIME_FORMAT" }}</td>{% endif %}
233                             {% if columns.STATUS in displayed %}<td>{{ task.get_status_display }}</td>{% endif %}
234                             {% if columns.HOST in displayed %}<td>{{ task.short_host_names|join:', ' }}</td>{% endif %}
235                             <td><a href="{{ task.get_absolute_url }}">szczegóły&nbsp;&rsaquo;</a></td>
236                         </tr>
237                     {% endfor %}
238                 {% endifequal %}
239             {% endfor %}
240         </tbody>
241     </table>
242
243     {% if not page %}
244         <div class="alert alert-info">
245             <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
246             Brak zadań spełniających wybrane kryteria
247         </div>
248     {% endif %}
249
250     <nav class="text-center">
251         <ul class="pagination">
252             {% if page.has_previous %}
253                 <li>
254                     <a href="{% query_string "page"=page.previous_page_number %}" aria-label="Previous">
255                     <span aria-hidden="true"><span class="glyphicon glyphicon-chevron-left"></span>&nbsp;poprzednia</span>
256                 </a>
257             {% endif %}
258             </li>
259
260             <li{% ifequal page.number 1 %} class="active"{% endifequal %}>
261                 <a href="{% query_string "page"=1 %}">1</a>
262             </li>
263
264             {% if pages_range.0 > 2 %}
265                 <li class="disabled"><span aria-hidden="true"><strong>&hellip;</strong></span></li>
266             {% endif %}
267
268             {% for num in pages_range %}
269                 <li{% ifequal page.number num %} class="active"{% endifequal %}>
270                     <a href="{% query_string "page"=num %}">{{ num }}</a>
271                 </li>
272             {% endfor %}
273
274             <li class="disabled"><span aria-hidden="true"><strong>z</strong></span></li>
275             <li><a href="{% query_string "page"=num_pages %}">{{ num_pages }}</a></li>
276
277             {% if page.has_next %}
278                 <li>
279                     <a href="{% query_string "page"=page.next_page_number %}" aria-label="Next">
280                     <span aria-hidden="true">następna&nbsp;<span class="glyphicon glyphicon-chevron-right"></span></span>
281                 </a>
282             {% endif %}
283             </li>
284         </ul>
285     </nav>
286
287     <!-- Modal -->
288     <div class="modal fade" id="advanced" tabindex="-1" role="dialog" aria-labelledby="modal-label" aria-hidden="true">
289         <div class="modal-dialog modal-lg">
290             <div class="modal-content">
291                 <div class="modal-header">
292                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
293                     <h4 class="modal-title" id="modal-label">Filtry zaawansowane</h4>
294                 </div>
295                 <div class="modal-body">
296                     <form id="advanced-form" action="." class="form-horizontal">
297                         {% bootstrap_field filters.keywords layout='horizontal' bound_css_class=' ' %}
298                         <div class="form-group">
299                             <label class="col-sm-3 col-md-4 control-label">Status</label>
300                             <div class="col-sm-9 col-md-6">
301                                 <div class="btn-group" data-toggle="buttons">
302                                     {% for choice in filters.status %}
303                                         <label class="btn btn-default{% if choice.is_checked %} active{% endif %}">
304                                             <input type="checkbox" name="{{ choice.name }}" value="{{ choice.choice_value }}"
305                                                    {% if choice.is_checked %}checked{% endif %}> {{ choice.choice_label }}
306                                         </label>
307                                     {% endfor %}
308                                 </div>
309                             </div>
310                         </div>
311
312                         <div class="form-group">
313                             <label class="col-sm-3 col-md-4 control-label">Host</label>
314                             <div class="col-sm-9 col-md-6">
315                                 <div class="btn-group" data-toggle="buttons">
316                                     {% for choice in filters.host %}
317                                         <label class="btn btn-default{% if choice.is_checked %} active{% endif %}">
318                                             <input type="checkbox" name="{{ choice.name }}" value="{{ choice.choice_value }}"
319                                                    {% if choice.is_checked %}checked{% endif %}> {{ choice.choice_label }}
320                                         </label>
321                                     {% endfor %}
322                                 </div>
323                             </div>
324                         </div>
325                         {% bootstrap_field filters.submission layout='horizontal' bound_css_class=' ' %}
326                         {% bootstrap_field filters.finish layout='horizontal' bound_css_class=' ' %}
327                     </form>
328                 </div>
329                 <div class="modal-footer">
330                     <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
331                     <a href="." class="btn btn-warning">Wyczyść filtry</a>
332                     <button type="submit" class="btn btn-primary" form="advanced-form">Filtruj</button>
333                 </div>
334             </div>
335         </div>
336     </div>
337
338     {# Column selection modal #}
339     <div class="modal fade" id="columns" tabindex="-1" role="dialog" aria-labelledby="modal-label" aria-hidden="true">
340         <div class="modal-dialog">
341             <div class="modal-content">
342                 <div class="modal-header">
343                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
344                     <h4 class="modal-title" id="modal-label">Wybór kolumn</h4>
345                 </div>
346                 <div class="modal-body">
347                     <form id="columns-form" action=".">
348                         {% bootstrap_field columns.columns %}
349                     </form>
350                 </div>
351                 <div class="modal-footer">
352                     <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
353                     <a id="select-all-columns" class="btn btn-success">Wybierz wszystkie</a>
354                     <a id="default-columns" class="btn btn-warning">Domyślne</a>
355                     <button type="submit" class="btn btn-primary" form="columns-form">Zapisz</button>
356                 </div>
357             </div>
358         </div>
359     </div>
360
361 {% endblock container %}