1 | <% _=n_ %> |
---|
2 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
---|
3 | |
---|
4 | <html> |
---|
5 | |
---|
6 | <head> |
---|
7 | <title>${_('Galaxy History')}</title> |
---|
8 | |
---|
9 | ## This is now only necessary for tests |
---|
10 | %if bool( [ data for data in history.active_datasets if data.state in ['running', 'queued', '', None ] ] ): |
---|
11 | <!-- running: do not change this comment, used by TwillTestCase.wait --> |
---|
12 | %endif |
---|
13 | |
---|
14 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
---|
15 | <meta http-equiv="Pragma" content="no-cache"> |
---|
16 | |
---|
17 | ${h.css( "base", "history", "autocomplete_tagging" )} |
---|
18 | ${h.js( "jquery", "jquery.tipsy", "galaxy.base", "json2", "class", "jquery.jstore", "jquery.autocomplete", "autocomplete_tagging" )} |
---|
19 | |
---|
20 | <script type="text/javascript"> |
---|
21 | |
---|
22 | <% TERMINAL_STATES = ["ok", "error", "empty", "deleted", "discarded", "failed_metadata"] %> |
---|
23 | TERMINAL_STATES = ${ h.to_json_string(TERMINAL_STATES) }; |
---|
24 | |
---|
25 | $(function() { |
---|
26 | var historywrapper = $("div.historyItemWrapper"); |
---|
27 | init_history_items(historywrapper); |
---|
28 | historywrapper.each( function() { |
---|
29 | // Delete link |
---|
30 | $(this).find( "div.historyItemButtons > .delete" ).each( function() { |
---|
31 | var data_id = this.id.split( "-" )[1]; |
---|
32 | $(this).click( function() { |
---|
33 | $( '#historyItem-' + data_id + "> div.historyItemTitleBar" ).addClass( "spinner" ); |
---|
34 | $.ajax({ |
---|
35 | url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ), |
---|
36 | error: function() { alert( "Delete failed" ); }, |
---|
37 | success: function(msg) { |
---|
38 | if (msg === "OK") { |
---|
39 | %if show_deleted: |
---|
40 | var to_update = {}; |
---|
41 | to_update[data_id] = "none"; |
---|
42 | updater( to_update ); |
---|
43 | %else: |
---|
44 | $( "#historyItem-" + data_id ).fadeOut( "fast", function() { |
---|
45 | $( "#historyItemContainer-" + data_id ).remove(); |
---|
46 | if ( $( "div.historyItemContainer" ).length < 1 ) { |
---|
47 | $( "#emptyHistoryMessage" ).show(); |
---|
48 | } |
---|
49 | }); |
---|
50 | %endif |
---|
51 | $(".tipsy").remove(); |
---|
52 | } else { |
---|
53 | alert( "Delete failed" ); |
---|
54 | } |
---|
55 | } |
---|
56 | }); |
---|
57 | return false; |
---|
58 | }); |
---|
59 | }); |
---|
60 | // Undelete link |
---|
61 | $(this).find( "a.historyItemUndelete" ).each( function() { |
---|
62 | var data_id = this.id.split( "-" )[1]; |
---|
63 | $(this).click( function() { |
---|
64 | $( '#historyItem-' + data_id + " > div.historyItemTitleBar" ).addClass( "spinner" ); |
---|
65 | $.ajax({ |
---|
66 | url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ), |
---|
67 | error: function() { alert( "Undelete failed" ) }, |
---|
68 | success: function() { |
---|
69 | var to_update = {}; |
---|
70 | to_update[data_id] = "none"; |
---|
71 | updater( to_update ); |
---|
72 | } |
---|
73 | }); |
---|
74 | return false; |
---|
75 | }); |
---|
76 | }); |
---|
77 | |
---|
78 | // Tag handling. |
---|
79 | $(this).find( "a.icon-button.tags").each( function() { |
---|
80 | // Use links parameters but custom URL as ajax URL. |
---|
81 | $(this).click( function() { |
---|
82 | // Get tag area, tag element. |
---|
83 | var history_item = $(this).parents(".historyItem"); |
---|
84 | var tag_area = history_item.find(".tag-area"); |
---|
85 | var tag_elt = history_item.find(".tag-elt"); |
---|
86 | |
---|
87 | // Show or hide tag area; if showing tag area and it's empty, fill it. |
---|
88 | if ( tag_area.is( ":hidden" ) ) { |
---|
89 | if (!tag_elt.html()) { |
---|
90 | // Need to fill tag element. |
---|
91 | var href_parms = $(this).attr("href").split("?")[1]; |
---|
92 | var ajax_url = "${h.url_for( controller='tag', action='get_tagging_elt_async' )}?" + href_parms; |
---|
93 | $.ajax({ |
---|
94 | url: ajax_url, |
---|
95 | error: function() { alert( "Tagging failed" ) }, |
---|
96 | success: function(tag_elt_html) { |
---|
97 | tag_elt.html(tag_elt_html); |
---|
98 | tag_elt.find(".tooltip").tipsy( { gravity: 's' } ); |
---|
99 | tag_area.slideDown("fast"); |
---|
100 | } |
---|
101 | }); |
---|
102 | } else { |
---|
103 | // Tag element is filled; show. |
---|
104 | tag_area.slideDown("fast"); |
---|
105 | } |
---|
106 | } else { |
---|
107 | // Hide. |
---|
108 | tag_area.slideUp("fast"); |
---|
109 | } |
---|
110 | return false; |
---|
111 | }); |
---|
112 | }); |
---|
113 | |
---|
114 | // Annotation handling. |
---|
115 | $(this).find( "a.icon-button.annotate").each( function() { |
---|
116 | // Use links parameters but custom URL as ajax URL. |
---|
117 | $(this).click( function() { |
---|
118 | // Get tag area, tag element. |
---|
119 | var history_item = $(this).parents(".historyItem"); |
---|
120 | var annotation_area = history_item.find(".annotation-area"); |
---|
121 | var annotation_elt = history_item.find(".annotation-elt"); |
---|
122 | |
---|
123 | // Show or hide annotation area; if showing annotation area and it's empty, fill it. |
---|
124 | if ( annotation_area.is( ":hidden" ) ) { |
---|
125 | if (!annotation_elt.html()) { |
---|
126 | // Need to fill annotation element. |
---|
127 | var href_parms = $(this).attr("href").split("?")[1]; |
---|
128 | var ajax_url = "${h.url_for( controller='dataset', action='get_annotation_async' )}?" + href_parms; |
---|
129 | $.ajax({ |
---|
130 | url: ajax_url, |
---|
131 | error: function() { alert( "Annotations failed" ) }, |
---|
132 | success: function(annotation) { |
---|
133 | if (annotation == "") { |
---|
134 | annotation = "<em>Describe or add notes to dataset</em>"; |
---|
135 | } |
---|
136 | annotation_elt.html(annotation); |
---|
137 | annotation_area.find(".tooltip").tipsy( { gravity: 's' } ); |
---|
138 | async_save_text( |
---|
139 | annotation_elt.attr("id"), annotation_elt.attr("id"), |
---|
140 | "${h.url_for( controller="/dataset", action="annotate_async")}?" + href_parms, |
---|
141 | "new_annotation", 18, true, 4); |
---|
142 | annotation_area.slideDown("fast"); |
---|
143 | } |
---|
144 | }); |
---|
145 | } else { |
---|
146 | // Annotation element is filled; show. |
---|
147 | annotation_area.slideDown("fast"); |
---|
148 | } |
---|
149 | } else { |
---|
150 | // Hide. |
---|
151 | annotation_area.slideUp("fast"); |
---|
152 | } |
---|
153 | return false; |
---|
154 | }); |
---|
155 | }); |
---|
156 | }); |
---|
157 | |
---|
158 | // Trackster links |
---|
159 | function init_trackster_links() { |
---|
160 | $("a.trackster").live( "click", function() { |
---|
161 | var link = $(this), |
---|
162 | hid = link.attr("id").split("_")[1]; // visualize_{id} |
---|
163 | |
---|
164 | $.ajax({ |
---|
165 | url: "${h.url_for( controller='tracks', action='list_tracks' )}", |
---|
166 | data: {'hid': hid}, |
---|
167 | error: function() { alert( "Visualization error" ); }, |
---|
168 | success: function(html) { |
---|
169 | show_modal("Add Track — Select Dataset(s)", html, { |
---|
170 | "New Browser": function() { |
---|
171 | hide_modal(); |
---|
172 | }, |
---|
173 | "Insert": function() { |
---|
174 | hide_modal(); |
---|
175 | }, |
---|
176 | "Cancel": function() { |
---|
177 | hide_modal(); |
---|
178 | } |
---|
179 | }); |
---|
180 | } |
---|
181 | }); |
---|
182 | }); |
---|
183 | } |
---|
184 | |
---|
185 | init_trackster_links(); |
---|
186 | |
---|
187 | // History rename functionality. |
---|
188 | async_save_text("history-name-container", "history-name", "${h.url_for( controller="/history", action="rename_async", id=trans.security.encode_id(history.id) )}", "new_name", 18); |
---|
189 | |
---|
190 | // History tagging functionality. |
---|
191 | var historyTagArea = $('#history-tag-area'); |
---|
192 | $('#history-tag').click( function() { |
---|
193 | if ( historyTagArea.is( ":hidden" ) ) { |
---|
194 | historyTagArea.slideDown("fast"); |
---|
195 | } else { |
---|
196 | historyTagArea.slideUp("fast"); |
---|
197 | } |
---|
198 | return false; |
---|
199 | }); |
---|
200 | |
---|
201 | // History annotation functionality. |
---|
202 | var historyAnnotationArea = $('#history-annotation-area'); |
---|
203 | $('#history-annotate').click( function() { |
---|
204 | if ( historyAnnotationArea.is( ":hidden" ) ) { |
---|
205 | historyAnnotationArea.slideDown("fast"); |
---|
206 | } else { |
---|
207 | historyAnnotationArea.slideUp("fast"); |
---|
208 | } |
---|
209 | return false; |
---|
210 | }); |
---|
211 | async_save_text("history-annotation-container", "history-annotation", "${h.url_for( controller="/history", action="annotate_async", id=trans.security.encode_id(history.id) )}", "new_annotation", 18, true, 4); |
---|
212 | |
---|
213 | // Updater |
---|
214 | updater( |
---|
215 | ${ h.to_json_string( dict([(data.id, data.state) for data in reversed( datasets ) if data.visible and data.state not in TERMINAL_STATES]) ) } |
---|
216 | ); |
---|
217 | |
---|
218 | // Navigate to a dataset. |
---|
219 | %if hda_id: |
---|
220 | self.location = "#${hda_id}"; |
---|
221 | %endif |
---|
222 | }); |
---|
223 | |
---|
224 | // Looks for changes in dataset state using an async request. Keeps |
---|
225 | // calling itself (via setTimeout) until all datasets are in a terminal |
---|
226 | // state. |
---|
227 | var updater = function ( tracked_datasets ) { |
---|
228 | // Check if there are any items left to track |
---|
229 | var empty = true; |
---|
230 | for ( i in tracked_datasets ) { |
---|
231 | empty = false; |
---|
232 | break; |
---|
233 | } |
---|
234 | if ( !empty ) { |
---|
235 | setTimeout( function() { updater_callback( tracked_datasets ) }, 4000 ); |
---|
236 | } |
---|
237 | }; |
---|
238 | var updater_callback = function ( tracked_datasets ) { |
---|
239 | // Build request data |
---|
240 | var ids = [], |
---|
241 | states = [], |
---|
242 | force_history_refresh = false; |
---|
243 | |
---|
244 | $.each( tracked_datasets, function ( id, state ) { |
---|
245 | ids.push( id ); |
---|
246 | states.push( state ); |
---|
247 | }); |
---|
248 | // Make ajax call |
---|
249 | $.ajax( { |
---|
250 | type: "POST", |
---|
251 | url: "${h.url_for( controller='root', action='history_item_updates' )}", |
---|
252 | dataType: "json", |
---|
253 | data: { ids: ids.join( "," ), states: states.join( "," ) }, |
---|
254 | success : function ( data ) { |
---|
255 | $.each( data, function( id, val ) { |
---|
256 | // Replace HTML |
---|
257 | var container = $("#historyItemContainer-" + id); |
---|
258 | container.html( val.html ); |
---|
259 | init_history_items( $("div.historyItemWrapper"), "noinit" ); |
---|
260 | // If new state is terminal, stop tracking |
---|
261 | if (TERMINAL_STATES.indexOf(val.state) !== -1) { |
---|
262 | if ( val.force_history_refresh ){ |
---|
263 | force_history_refresh = true; |
---|
264 | } |
---|
265 | delete tracked_datasets[ parseInt(id) ]; |
---|
266 | } else { |
---|
267 | tracked_datasets[ parseInt(id) ] = val.state; |
---|
268 | } |
---|
269 | }); |
---|
270 | if ( force_history_refresh ) { |
---|
271 | parent.frames.galaxy_history.location.reload(); |
---|
272 | } else { |
---|
273 | // Keep going (if there are still any items to track) |
---|
274 | updater( tracked_datasets ); |
---|
275 | } |
---|
276 | }, |
---|
277 | error: function() { |
---|
278 | // Just retry, like the old method, should try to be smarter |
---|
279 | updater( tracked_datasets ); |
---|
280 | } |
---|
281 | }); |
---|
282 | }; |
---|
283 | |
---|
284 | </script> |
---|
285 | |
---|
286 | <style> |
---|
287 | .historyItemBody { |
---|
288 | display: none; |
---|
289 | } |
---|
290 | div.form-row { |
---|
291 | padding: 5px 5px 5px 0px; |
---|
292 | } |
---|
293 | #top-links { |
---|
294 | margin-bottom: 15px; |
---|
295 | } |
---|
296 | #history-name-container { |
---|
297 | display: inline-block; |
---|
298 | color: gray; |
---|
299 | font-weight: bold; |
---|
300 | } |
---|
301 | .editable-text { |
---|
302 | border: solid transparent 1px; |
---|
303 | padding: 3px; |
---|
304 | margin: -4px; |
---|
305 | } |
---|
306 | </style> |
---|
307 | |
---|
308 | <noscript> |
---|
309 | <style> |
---|
310 | .historyItemBody { |
---|
311 | display: block; |
---|
312 | } |
---|
313 | </style> |
---|
314 | </noscript> |
---|
315 | |
---|
316 | </head> |
---|
317 | |
---|
318 | <body class="historyPage"> |
---|
319 | <div id="top-links" class="historyLinks"> |
---|
320 | |
---|
321 | <a title="${_('refresh')}" class="icon-button arrow-circle tooltip" href="${h.url_for('history', show_deleted=show_deleted)}"></a> |
---|
322 | <a title='${_('collapse all')}' class='icon-button toggle tooltip' href='#' style="display: none;"></a> |
---|
323 | |
---|
324 | %if trans.get_user(): |
---|
325 | <div style="width: 40px; float: right; white-space: nowrap;"> |
---|
326 | <a id="history-tag" title="Edit history tags" class="icon-button tags tooltip" target="galaxy_main" href="${h.url_for( controller='history', action='tag' )}"></a> |
---|
327 | <a id="history-annotate" title="Edit history annotation" class="icon-button annotate tooltip" target="galaxy_main" href="${h.url_for( controller='history', action='annotate' )}"></a> |
---|
328 | </div> |
---|
329 | %endif |
---|
330 | |
---|
331 | </div> |
---|
332 | |
---|
333 | <div style="clear: both;"></div> |
---|
334 | |
---|
335 | %if show_deleted: |
---|
336 | <div class="historyLinks"> |
---|
337 | <a href="${h.url_for('history', show_deleted=False)}">${_('hide deleted')}</a> |
---|
338 | </div> |
---|
339 | %endif |
---|
340 | |
---|
341 | %if show_hidden: |
---|
342 | <div class="historyLinks"> |
---|
343 | <a href="${h.url_for('history', show_hidden=False)}">${_('hide hidden')}</a> |
---|
344 | </div> |
---|
345 | %endif |
---|
346 | |
---|
347 | <div id="history-name-area" class="historyLinks"> |
---|
348 | |
---|
349 | %if trans.get_user(): |
---|
350 | <div id="history-name-container"> |
---|
351 | <div id="history-name" class="tooltip editable-text" title="Click to rename history">${history.get_display_name() | h}</div> |
---|
352 | </div> |
---|
353 | %endif |
---|
354 | |
---|
355 | </div> |
---|
356 | |
---|
357 | %if history.deleted: |
---|
358 | <div class="warningmessagesmall"> |
---|
359 | ${_('You are currently viewing a deleted history!')} |
---|
360 | </div> |
---|
361 | <p></p> |
---|
362 | %endif |
---|
363 | |
---|
364 | <%namespace file="../tagging_common.mako" import="render_individual_tagging_element" /> |
---|
365 | <%namespace file="history_common.mako" import="render_dataset" /> |
---|
366 | |
---|
367 | %if trans.get_user() is not None: |
---|
368 | <div style="margin: 0px 5px 10px 5px"> |
---|
369 | ## Tagging elt. |
---|
370 | <div id="history-tag-area" style="display: none"> |
---|
371 | <b>Tags:</b> |
---|
372 | ${render_individual_tagging_element(user=trans.get_user(), tagged_item=history, elt_context="history.mako", use_toggle_link=False, input_size="20")} |
---|
373 | </div> |
---|
374 | |
---|
375 | ## Annotation elt. |
---|
376 | <div id="history-annotation-area" style="display: none"> |
---|
377 | <b>Annotation / Notes:</b> |
---|
378 | <div id="history-annotation-container"> |
---|
379 | <div id="history-annotation" class="tooltip editable-text" title="Click to edit annotation"> |
---|
380 | %if annotation: |
---|
381 | ${h.to_unicode( annotation ) | h} |
---|
382 | %else: |
---|
383 | <em>Describe or add notes to history</em> |
---|
384 | %endif |
---|
385 | </div> |
---|
386 | </div> |
---|
387 | </div> |
---|
388 | |
---|
389 | </div> |
---|
390 | %endif |
---|
391 | |
---|
392 | %if not datasets: |
---|
393 | |
---|
394 | <div class="infomessagesmall" id="emptyHistoryMessage"> |
---|
395 | |
---|
396 | %else: |
---|
397 | |
---|
398 | ## Render requested datasets, ordered from newest to oldest |
---|
399 | %for data in reversed( datasets ): |
---|
400 | %if data.visible or show_hidden: |
---|
401 | <div class="historyItemContainer" id="historyItemContainer-${data.id}"> |
---|
402 | ${render_dataset( data, data.hid, show_deleted_on_refresh = show_deleted, for_editing = True )} |
---|
403 | </div> |
---|
404 | %endif |
---|
405 | %endfor |
---|
406 | |
---|
407 | <div class="infomessagesmall" id="emptyHistoryMessage" style="display:none;"> |
---|
408 | %endif |
---|
409 | ${_("Your history is empty. Click 'Get Data' on the left pane to start")} |
---|
410 | </div> |
---|
411 | |
---|
412 | </body> |
---|
413 | </html> |
---|