Project

General

Profile

Feature #15029 ยป redmine_add_relation_filters.patch

Arthur Andersen, 2013-10-28 15:16

View differences:

app/controllers/issues_controller.rb
1

  
1 2
# Redmine - project management software
2 3
# Copyright (C) 2006-2013  Jean-Philippe Lang
3 4
#
app/models/issue_query.rb
66 66
    versions = []
67 67
    categories = []
68 68
    issue_custom_fields = []
69
    
69

  
70 70
    if project
71 71
      principals += project.principals.sort
72 72
      unless project.leaf?
......
389 389
        op = (operator == "!p" ? 'NOT IN' : 'IN')
390 390
        comp = (operator == "=!p" ? '<>' : '=')
391 391
        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})"
392
      when "!|c", "*&o"
393
        op = (operator == "!|c" ? 'NOT IN' : 'IN')
394
        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_false}))"
392 395
      end
393 396

  
394 397
    if relation_options[:sym] == field && !options[:reverse]
app/models/query.rb
159 159
    "!~"  => :label_not_contains,
160 160
    "=p"  => :label_any_issues_in_project,
161 161
    "=!p" => :label_any_issues_not_in_project,
162
    "!p"  => :label_no_issues_in_project
162
    "!p"  => :label_no_issues_in_project,
163
    "*&o" => :label_any_open_issues,
164
    "!|c" => :label_none_or_closed_issues
163 165
  }
164 166

  
165 167
  class_attribute :operators_by_filter_type
......
174 176
    :text => [  "~", "!~", "!*", "*" ],
175 177
    :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
176 178
    :float => [ "=", ">=", "<=", "><", "!*", "*" ],
177
    :relation => ["=", "=p", "=!p", "!p", "!*", "*"]
179
    :relation => ["=", "=p", "=!p", "!p", "*&o", "!|c", "!*", "*"]
178 180
  }
179 181

  
180 182
  class_attribute :available_columns
......
233 235
          # filter requires one or more values
234 236
          (values_for(field) and !values_for(field).first.blank?) or
235 237
          # filter doesn't require any value
236
          ["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y"].include? operator_for(field)
238
          ["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "*&o", "!|c"].include? operator_for(field)
237 239
    end if filters
238 240
  end
239 241

  
config/locales/en-GB.yml
1065 1065
  permission_view_private_notes: View private notes
1066 1066
  permission_set_notes_private: Set notes as private
1067 1067
  label_no_issues_in_project: no issues in project
1068
  label_any_open_issues: any open issues
1069
  label_none_or_closed_issues: none or closed issues
1068 1070
  label_any: all
1069 1071
  label_last_n_weeks: last %{count} weeks
1070 1072
  setting_cross_project_subtasks: Allow cross-project subtasks
config/locales/en.yml
683 683
  label_any_issues_in_project: any issues in project
684 684
  label_any_issues_not_in_project: any issues not in project
685 685
  label_no_issues_in_project: no issues in project
686
  label_any_open_issues: any open issues
687
  label_none_or_closed_issues: none or closed issues
686 688
  label_day_plural: days
687 689
  label_repository: Repository
688 690
  label_repository_new: New repository
public/javascripts/application.js
251 251
    case "y":
252 252
    case "o":
253 253
    case "c":
254
    case "!|c":
255
    case "*&o":
254 256
      enableValues(field, []);
255 257
      break;
256 258
    case "><":
......
551 553
function setupAjaxIndicator() {
552 554

  
553 555
  $('#ajax-indicator').bind('ajaxSend', function(event, xhr, settings) {
554
  
556

  
555 557
    if ($('.ajax-loading').length === 0 && settings.contentType != 'application/octet-stream') {
556 558
      $('#ajax-indicator').show();
557 559
    }
558 560
  });
559
  
561

  
560 562
  $('#ajax-indicator').bind('ajaxStop', function() {
561 563
    $('#ajax-indicator').hide();
562 564
  });
    (1-1/1)