Ticket #7026: query_column_reorder_6737.diff
| File query_column_reorder_6737.diff, 8.1 kB (added by hyugaricdeau@…, 5 months ago) |
|---|
-
trac/ticket/query.py
41 41 INavigationContributor, Chrome 42 42 from trac.wiki.api import IWikiSyntaxProvider, parse_args 43 43 from trac.wiki.macros import WikiMacroBase # TODO: should be moved in .api 44 from trac.config import Option 44 from trac.config import Option 45 45 46 46 class QuerySyntaxError(Exception): 47 47 """Exception raised when a ticket query cannot be parsed from a string.""" … … 94 94 for filter_ in filters: 95 95 filter_ = filter_.split('=') 96 96 if len(filter_) != 2: 97 raise QuerySyntaxError('Query filter requires field and ' 97 raise QuerySyntaxError('Query filter requires field and ' 98 98 'constraints separated by a "="') 99 99 field,values = filter_ 100 100 if not field: … … 253 253 # the default columns, in the same order. That keeps the query url 254 254 # shorter in the common case where we just want the default columns. 255 255 if cols == self.get_default_columns(): 256 cols = None 256 cols = {} 257 constraints = self.constraints.copy() 258 constraints.update(dict(('col' + str(idx), col) 259 for idx, col in enumerate(cols))) 257 260 return href.query(report=id, 258 261 order=order, desc=desc and 1 or None, 259 262 group=self.group or None, 260 263 groupdesc=self.groupdesc and 1 or None, 261 col=cols,262 264 row=self.rows, 263 format=format, ** self.constraints)265 format=format, **constraints) 264 266 265 267 def to_string(self): 266 268 """Return a user readable and editable representation of the query. … … 620 622 if val.endswith('$USER'): 621 623 del constraints[field] 622 624 623 cols = req.args.get('col') 624 if isinstance(cols, basestring): 625 cols = [cols] 625 cols = self._get_ordered_cols(req) 626 626 # Since we don't show 'id' as an option to the user, 627 627 # we need to re-insert it here. 628 628 if cols and 'id' not in cols: … … 637 637 rows, 638 638 req.args.get('limit')) 639 639 640 for idx, col in enumerate(cols): 641 if 'up_' + col in req.args: 642 query.cols[idx] = cols[idx-1] 643 query.cols[idx-1] = col 644 req.redirect(query.get_href(req.href)) 645 elif 'down_' + col in req.args: 646 query.cols[idx] = cols[idx+1] 647 query.cols[idx+1] = col 648 req.redirect(query.get_href(req.href)) 649 640 650 if 'update' in req.args: 641 651 # Reset session vars 642 652 for var in ('query_constraints', 'query_time', 'query_tickets'): … … 659 669 return self.display_html(req, query) 660 670 661 671 # Internal methods 672 def _get_ordered_cols(self, req): 673 return [item[1] for item in 674 sorted([item for item in req.args.iteritems() 675 if re.match(r'^col\d+', item[0])], 676 key=lambda x: (len(x[0]) < 4, int(x[0][3:])))] 662 677 663 678 def _get_constraints(self, req): 664 679 constraints = {} … … 779 794 data.setdefault('description', None) 780 795 data['title'] = title 781 796 782 data['all_columns'] = query.get_all_columns() 797 all_columns = query.get_all_columns() 798 ordered_cols = self._get_ordered_cols(req) 799 all_columns.sort(key=lambda x: (not x in ordered_cols, 800 x in ordered_cols and 801 ordered_cols.index(x))) 802 data['all_columns'] = all_columns 783 803 # Don't allow the user to remove the id column 784 804 data['all_columns'].remove('id') 785 805 data['all_textareas'] = query.get_all_textareas() -
trac/ticket/templates/query.html
136 136 <fieldset id="columns"> 137 137 <legend>Columns</legend> 138 138 <div> 139 <py:for each="column in all_columns"> 140 <label> 141 <input type="checkbox" name="col" value="$column" 142 checked="${any([(value == column) for value in col]) 143 and 'checked' or None}" /> 144 ${labels.get(column, column or 'none')} 145 </label> 146 </py:for> 139 <table> 140 <tbody> 141 <tr py:for="idx, column in enumerate(all_columns)"> 142 <td> 143 <input type="checkbox" name="col${idx+1}" value="$column" 144 checked="${any([(value == column) for value in col]) 145 and 'selected' or None}" /> 146 </td> 147 <td>${labels.get(column, column or 'none')}</td> 148 <td> 149 <input type="submit" name="up_${column}" value="Up" 150 disabled="${not idx or None}" /> 151 <input type="submit" name="down_${column}" value="Down" 152 disabled="${idx == len(all_columns)-1 or None}" /> 153 </td> 154 </tr> 155 </tbody> 156 </table> 147 157 </div> 148 158 </fieldset> 149 159 -
trac/htdocs/js/query.js
273 273 } 274 274 select.selectedIndex = 0; 275 275 } 276 277 $("input[@name^='up_']").click(function() { 278 var row = $(this).parents('tr'); 279 if (row.prev().length) { 280 var prev = row.prev(); 281 if (!row.next().length) { 282 prev.find("input[@name^='down_']").attr("disabled", true); 283 } 284 prev.find("input[@name^='up_']").attr("disabled", false); 285 var row_check = row.find("input[@type='checkbox']"); 286 var prev_check = prev.find("input[@type='checkbox']"); 287 var temp = row_check.attr("name"); 288 row_check.attr("name", prev_check.attr("name")); 289 prev_check.attr("name", temp); 290 row.insertBefore(row.prev()); 291 if (!row.prev().length) { 292 $(this).attr("disabled", true); 293 } 294 row.find("input[@name^='down_']").attr("disabled", false); 295 } 296 return false; 297 }); 298 $("input[@name^='down_']").click(function() { 299 var row = $(this).parents('tr'); 300 if (row.next().length) { 301 var next = row.next(); 302 if (!row.prev().length) { 303 next.find("input[@name^='up_']").attr("disabled", true); 304 } 305 next.find("input[@name^='down_']").attr("disabled", false); 306 var row_check = row.find("input[@type='checkbox']"); 307 var next_check = next.find("input[@type='checkbox']"); 308 var temp = row_check.attr("name"); 309 row_check.attr("name", next_check.attr("name")); 310 next_check.attr("name", temp); 311 row.insertAfter(row.next()); 312 if (!row.next().length) { 313 $(this).attr("disabled", true); 314 } 315 row.find("input[@name^='up_']").attr("disabled", false); 316 } 317 return false; 318 }); 276 319 } 277 278 })(jQuery); 279 No newline at end of file 320 })(jQuery); -
trac/htdocs/css/report.css
41 41 #filters td.filter label { padding-right: 1em } 42 42 #filters td.actions { text-align: right; white-space: nowrap } 43 43 44 #columns div { 45 height: 15em; 46 overflow: -moz-scrollbars-vertical; 47 overflow-x: hidden; 48 overflow-y: scroll; 49 } 50 44 51 #columns div label { 45 52 display: block; 46 53 float: left;
