| 1 | // analyze UX |
|---|
| 2 | var get_analyze = function(report){ |
|---|
| 3 | jQuery.ajax({ |
|---|
| 4 | 'type': "GET", |
|---|
| 5 | 'url': get_url()+'/analyzeajax/list', |
|---|
| 6 | 'data': {'report':report}, |
|---|
| 7 | 'success': function(analyses){ |
|---|
| 8 | ask_analyze(analyses); |
|---|
| 9 | }, |
|---|
| 10 | 'error': function(r,status){ |
|---|
| 11 | alert("Error detected:\n\n"+r.responseText); |
|---|
| 12 | window.location.reload(); |
|---|
| 13 | } |
|---|
| 14 | }); |
|---|
| 15 | } |
|---|
| 16 | |
|---|
| 17 | var ask_analyze = function(analyses){ |
|---|
| 18 | var id = "ask-analysis"; |
|---|
| 19 | if (!jQuery('#'+id).length) { |
|---|
| 20 | var form = '<div id="'+id+'" title="Analyze">' |
|---|
| 21 | + ' <p>Select an analysis:</p>' |
|---|
| 22 | + ' <form>' |
|---|
| 23 | + ' <fieldset>'; |
|---|
| 24 | for (var i=0; i!=analyses.length; i++){ |
|---|
| 25 | var analysis = analyses[i]; |
|---|
| 26 | form +=' <input type="radio" name="analysis" id="'+analysis.path+'" value="'+analysis.num+'">'+analysis.title+'</input><br/>'; |
|---|
| 27 | } |
|---|
| 28 | form +=' <input type="radio" name="analysis" id="all" value="0" checked="checked">All (until an issue is fixed)</input>' |
|---|
| 29 | + ' </fieldset>' |
|---|
| 30 | + ' </form>' |
|---|
| 31 | + '</div>'; |
|---|
| 32 | jQuery('#main').append(form); |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | jQuery('#'+id).dialog({ |
|---|
| 36 | autoOpen: true, |
|---|
| 37 | height: 300, |
|---|
| 38 | width: 400, |
|---|
| 39 | modal: true, |
|---|
| 40 | buttons: { |
|---|
| 41 | Ok: function() { |
|---|
| 42 | // extract which analysis to perform |
|---|
| 43 | var selection = jQuery('#'+id+' input:radio[name=analysis]:checked'); |
|---|
| 44 | var num = parseInt(selection.val()); |
|---|
| 45 | var path = selection.attr('id'); |
|---|
| 46 | var next = []; |
|---|
| 47 | |
|---|
| 48 | // check for all analyses |
|---|
| 49 | if (path == 'all'){ |
|---|
| 50 | jQuery('#'+id+' input:radio[name=analysis][id!=all]').each(function(i,e){ |
|---|
| 51 | var analysis = new Object(); |
|---|
| 52 | analysis.num = parseInt(jQuery(e).val()); |
|---|
| 53 | analysis.path = jQuery(e).attr('id'); |
|---|
| 54 | next.push(analysis); |
|---|
| 55 | }); |
|---|
| 56 | |
|---|
| 57 | next.reverse(); // unshift() not available in IE |
|---|
| 58 | analysis = next.pop(); |
|---|
| 59 | num = analysis.num; |
|---|
| 60 | path = analysis.path; |
|---|
| 61 | } |
|---|
| 62 | |
|---|
| 63 | jQuery(this).dialog("destroy"); |
|---|
| 64 | collect_rows(0, num, path, next, ''); |
|---|
| 65 | }, |
|---|
| 66 | Cancel: function() { |
|---|
| 67 | jQuery(this).dialog("destroy"); |
|---|
| 68 | } |
|---|
| 69 | }, |
|---|
| 70 | close: function() { |
|---|
| 71 | jQuery(this).dialog("destroy"); |
|---|
| 72 | } |
|---|
| 73 | }); |
|---|
| 74 | jQuery('.ui-dialog :button:first').focus(); |
|---|
| 75 | } |
|---|
| 76 | |
|---|
| 77 | // rows shizzle |
|---|
| 78 | var collect_rows = function(index, num, path, next, refresh){ |
|---|
| 79 | var rows = get_rows(index, num); |
|---|
| 80 | if (rows == -1) // bogus row found so skip |
|---|
| 81 | collect_rows(index+1, num, path, next, refresh); |
|---|
| 82 | else if (rows) // good rows so check em! |
|---|
| 83 | check_rows(rows, path, next, refresh); |
|---|
| 84 | else |
|---|
| 85 | if (refresh.length) { |
|---|
| 86 | jQuery('#analyzebutton').get(0).scrollIntoView(false); |
|---|
| 87 | var this_report = get_report(); |
|---|
| 88 | var next_report = get_report(refresh); |
|---|
| 89 | if (next_report == this_report) |
|---|
| 90 | var which = "this report"; |
|---|
| 91 | else |
|---|
| 92 | var which = "report "+next_report; |
|---|
| 93 | var box = '<div id="refresh" title="Done!">' |
|---|
| 94 | + ' <p>Refreshing '+which+' in case fixes changed results..</p>' |
|---|
| 95 | + '</div>'; |
|---|
| 96 | jQuery('#main').append(box); |
|---|
| 97 | jQuery('#refresh').dialog({ |
|---|
| 98 | autoOpen:true, |
|---|
| 99 | modal:true, |
|---|
| 100 | height:160, |
|---|
| 101 | width:400, |
|---|
| 102 | buttons: { |
|---|
| 103 | OK:function(){ |
|---|
| 104 | if (next_report != this_report) |
|---|
| 105 | window.open(get_url()+'/report/'+refresh,"analyze"); |
|---|
| 106 | window.location.reload(); |
|---|
| 107 | } |
|---|
| 108 | }, |
|---|
| 109 | close: function(){ |
|---|
| 110 | jQuery(this).dialog("destroy"); |
|---|
| 111 | jQuery('#refresh').remove(); |
|---|
| 112 | } |
|---|
| 113 | }); |
|---|
| 114 | } else if (next.length) { |
|---|
| 115 | var analysis = next.pop(); |
|---|
| 116 | collect_rows(0, analysis.num, analysis.path, next, ''); |
|---|
| 117 | } else { |
|---|
| 118 | jQuery('#analyzebutton').get(0).scrollIntoView(false); |
|---|
| 119 | var box = '<div id="done" title="Done!">' |
|---|
| 120 | + ' <p>No fixes made.</p>' |
|---|
| 121 | + '</div>'; |
|---|
| 122 | jQuery('#main').append(box); |
|---|
| 123 | jQuery('#done').dialog({ |
|---|
| 124 | autoOpen:true, |
|---|
| 125 | modal:true, |
|---|
| 126 | height:160, |
|---|
| 127 | width:300, |
|---|
| 128 | buttons: { |
|---|
| 129 | OK: function(){ |
|---|
| 130 | jQuery(this).dialog("destroy"); |
|---|
| 131 | jQuery('#done').remove(); |
|---|
| 132 | } |
|---|
| 133 | }, |
|---|
| 134 | close: function(){ |
|---|
| 135 | jQuery(this).dialog("destroy"); |
|---|
| 136 | jQuery('#refresh').remove(); |
|---|
| 137 | } |
|---|
| 138 | }); |
|---|
| 139 | } |
|---|
| 140 | } |
|---|
| 141 | |
|---|
| 142 | var check_rows = function(rows, path, next, refresh){ |
|---|
| 143 | color_rows(rows, 'yellow'); |
|---|
| 144 | jQuery.ajax({ |
|---|
| 145 | 'type': "GET", |
|---|
| 146 | 'url': get_url()+'/analyzeajax/'+path, |
|---|
| 147 | 'data': get_params(rows), |
|---|
| 148 | 'success': function(issue){ |
|---|
| 149 | if (issue.exists) |
|---|
| 150 | ask_issue(rows, path, next, refresh, issue); |
|---|
| 151 | else { |
|---|
| 152 | color_rows(rows); |
|---|
| 153 | collect_rows(rows[0].index+1, rows.length, path, next, refresh); |
|---|
| 154 | } |
|---|
| 155 | }, |
|---|
| 156 | 'error': function(r,status){ |
|---|
| 157 | color_rows(rows, 'red'); |
|---|
| 158 | alert("Error detected:\n\n"+r.responseText); |
|---|
| 159 | window.location.reload(); |
|---|
| 160 | } |
|---|
| 161 | }); |
|---|
| 162 | } |
|---|
| 163 | |
|---|
| 164 | var get_rows = function(index, num){ |
|---|
| 165 | var rows = new Array(num); |
|---|
| 166 | for (var i=0; i!=num; i++){ |
|---|
| 167 | rows[i] = get_row(index+i); |
|---|
| 168 | if (rows[i] == null) |
|---|
| 169 | return null; |
|---|
| 170 | else if (rows[i] == -1) |
|---|
| 171 | return -1; |
|---|
| 172 | } |
|---|
| 173 | return rows; |
|---|
| 174 | } |
|---|
| 175 | |
|---|
| 176 | var color_rows = function(rows, color, duration){ |
|---|
| 177 | for (var i=0; i!=rows.length; i++){ |
|---|
| 178 | var tr = get_tr(rows[i].index); |
|---|
| 179 | if (color == null) |
|---|
| 180 | tr.css('backgroundColor', rows[i].color); |
|---|
| 181 | else if (duration == null) { |
|---|
| 182 | tr.css('backgroundColor', color); |
|---|
| 183 | tr.get(0).scrollIntoView(false); |
|---|
| 184 | } |
|---|
| 185 | else { |
|---|
| 186 | var row = rows[i]; |
|---|
| 187 | tr.css('backgroundColor', row.color); |
|---|
| 188 | tr.show("highlight", {color:color}, duration, function(){ |
|---|
| 189 | tr.css('backgroundColor', row.color); |
|---|
| 190 | }); |
|---|
| 191 | } |
|---|
| 192 | } |
|---|
| 193 | } |
|---|
| 194 | |
|---|
| 195 | var get_row = function(index){ |
|---|
| 196 | var row = new Object(); |
|---|
| 197 | var tr = get_tr(index); |
|---|
| 198 | if (!tr.length) |
|---|
| 199 | return null; |
|---|
| 200 | |
|---|
| 201 | // get the ticket id (assumes has class of ticket) |
|---|
| 202 | row.id = parseInt(tr.find('td.ticket').text().replace(/[^\d]/g,'')); |
|---|
| 203 | if (isNaN(row.id)) |
|---|
| 204 | return -1; |
|---|
| 205 | |
|---|
| 206 | // get indexes (overall and in group) |
|---|
| 207 | row.index = index; |
|---|
| 208 | row.group_index = tr.prevAll().length; |
|---|
| 209 | |
|---|
| 210 | // get field name and value of first column (may help some analyses) |
|---|
| 211 | var col1 = tr.find('td:first'); |
|---|
| 212 | row.col1_field = col1.attr('class'); |
|---|
| 213 | row.col1_value = jQuery.trim(col1.text()); |
|---|
| 214 | |
|---|
| 215 | // cache row's background color |
|---|
| 216 | row.color = tr.css('backgroundColor'); |
|---|
| 217 | |
|---|
| 218 | return row; |
|---|
| 219 | } |
|---|
| 220 | |
|---|
| 221 | |
|---|
| 222 | // issue UX |
|---|
| 223 | var ask_issue = function(rows, path, next, refresh, issue){ |
|---|
| 224 | var id = "ask-issue"; |
|---|
| 225 | var form = '<div id="'+id+'" title="'+issue.title+'">' |
|---|
| 226 | + ' <p>Issue: <strong>'+issue.label+'</strong></p>' |
|---|
| 227 | + ' <p>Select a solution:</p>' |
|---|
| 228 | + ' <form>' |
|---|
| 229 | + ' <fieldset>'; |
|---|
| 230 | for (var i=0; i!=issue.solutions.length; i++){ |
|---|
| 231 | if (issue.solutions[i].disabled) |
|---|
| 232 | form +=' <input type="radio" name="solution" value="'+i+'" disabled="disabled" /><span class="disabled">'+issue.solutions[i].name+' <em>(not permitted)</em></span><br/>' |
|---|
| 233 | else |
|---|
| 234 | form +=' <input type="radio" name="solution" value="'+i+'" /><span>'+issue.solutions[i].name+'</span><br/>' |
|---|
| 235 | } |
|---|
| 236 | form +=' <input type="radio" name="solution" value="-1" checked="checked">Skip this issue</input>' |
|---|
| 237 | + ' </fieldset>' |
|---|
| 238 | + ' </form>' |
|---|
| 239 | + '</div>'; |
|---|
| 240 | jQuery('#main').append(form); |
|---|
| 241 | |
|---|
| 242 | jQuery('#'+id).dialog({ |
|---|
| 243 | autoOpen: true, |
|---|
| 244 | height: 300, |
|---|
| 245 | width: 650, |
|---|
| 246 | modal: true, |
|---|
| 247 | buttons: { |
|---|
| 248 | Ok: function() { |
|---|
| 249 | // extract which analysis to perform |
|---|
| 250 | var selection = jQuery('#'+id+' input:radio[name=solution]:checked'); |
|---|
| 251 | var i = parseInt(selection.val()); |
|---|
| 252 | jQuery(this).dialog("destroy"); |
|---|
| 253 | jQuery('#'+id).remove(); |
|---|
| 254 | if (i == -1) { |
|---|
| 255 | color_rows(rows); |
|---|
| 256 | collect_rows(rows[0].index + 1, rows.length, path, next, refresh); |
|---|
| 257 | } |
|---|
| 258 | else { |
|---|
| 259 | refresh = refresh || issue.refresh; |
|---|
| 260 | fix_issue(rows, path, next, issue.solutions[i].data, refresh); |
|---|
| 261 | } |
|---|
| 262 | }, |
|---|
| 263 | Cancel: function() { |
|---|
| 264 | jQuery(this).dialog("destroy"); |
|---|
| 265 | jQuery('#'+id).remove(); |
|---|
| 266 | color_rows(rows); |
|---|
| 267 | } |
|---|
| 268 | }, |
|---|
| 269 | close: function() { |
|---|
| 270 | jQuery(this).dialog("destroy"); |
|---|
| 271 | jQuery('#'+id).remove(); |
|---|
| 272 | color_rows(rows); |
|---|
| 273 | } |
|---|
| 274 | }); |
|---|
| 275 | jQuery('.ui-dialog :button:first').focus(); |
|---|
| 276 | } |
|---|
| 277 | |
|---|
| 278 | var fix_issue = function(rows, path, next, data, refresh){ |
|---|
| 279 | jQuery.ajax({ |
|---|
| 280 | 'type': "GET", |
|---|
| 281 | 'url': get_url()+'/analyzeajax/'+path+'/fix', |
|---|
| 282 | 'data': {'data': data}, |
|---|
| 283 | 'success': function(){ |
|---|
| 284 | color_rows(rows, 'green', 1000); |
|---|
| 285 | collect_rows(rows[0].index+rows.length, rows.length, path, next, refresh); |
|---|
| 286 | }, |
|---|
| 287 | 'error': function(r,status){ |
|---|
| 288 | color_rows(rows, 'red'); |
|---|
| 289 | alert("Error detected:\n\n"+r.responseText); |
|---|
| 290 | window.location.reload(); |
|---|
| 291 | } |
|---|
| 292 | }); |
|---|
| 293 | } |
|---|
| 294 | |
|---|
| 295 | |
|---|
| 296 | // utils |
|---|
| 297 | var get_tr = function(index){ |
|---|
| 298 | return jQuery('table.listing.tickets tbody tr:has(td):eq('+index+')'); |
|---|
| 299 | } |
|---|
| 300 | |
|---|
| 301 | var get_url = function(){ |
|---|
| 302 | return jQuery('link[rel="search"]').attr('href').replace(/\/search/, ''); |
|---|
| 303 | } |
|---|
| 304 | |
|---|
| 305 | var get_report = function(text, include_params){ |
|---|
| 306 | if (text) |
|---|
| 307 | return text.match(/^[1-9][0-9]*/); |
|---|
| 308 | else { |
|---|
| 309 | if (include_params) |
|---|
| 310 | var re = /\/report\/(.*)/; |
|---|
| 311 | else |
|---|
| 312 | var re = /\/report\/([1-9][0-9]*)/; |
|---|
| 313 | var url = window.location.toString().match(re)[1]; |
|---|
| 314 | return url; |
|---|
| 315 | } |
|---|
| 316 | } |
|---|
| 317 | |
|---|
| 318 | var get_params = function(rows){ |
|---|
| 319 | var params = []; |
|---|
| 320 | for (var i=0; i!=rows.length; i++){ |
|---|
| 321 | var param = jQuery.param(rows[i]).replace(/=/g,(i+1)+'='); // FIXME: will be wrong when there's an = inside a value |
|---|
| 322 | params.push(param); |
|---|
| 323 | } |
|---|
| 324 | return params.join('&'); |
|---|
| 325 | } |
|---|