diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 38a28237c2..d2f1fa8a3c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -131,6 +131,8 @@ Lint/UnneededSplatExpansion: # ExcludedMethods: refine Metrics/BlockLength: Max: 1081 + Exclude: + - 'spec/integration/actions/index_spec.rb' # Offense count: 7 Naming/AccessorMethodName: diff --git a/app/assets/javascripts/rails_admin/ra.filter-box.js b/app/assets/javascripts/rails_admin/ra.filter-box.js index c6a41f2462..7ddd32976c 100644 --- a/app/assets/javascripts/rails_admin/ra.filter-box.js +++ b/app/assets/javascripts/rails_admin/ra.filter-box.js @@ -11,6 +11,7 @@ var field_value = options['value']; var field_operator = options['operator']; var select_options = options['select_options']; + var required = options['required']; var index = options['index']; var value_name = 'f[' + field_name + '][' + index + '][v]'; var operator_name = 'f[' + field_name + '][' + index + '][o]'; @@ -24,9 +25,13 @@ .append('') .append($('').prop('selected', field_value == "true").text(RailsAdmin.I18n.t("true"))) .append($('').prop('selected', field_value == "false").text(RailsAdmin.I18n.t("false"))) - .append('') - .append($('').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present"))) - .append($('').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank"))); + if (!required) { + control.append([ + '', + $('').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present")), + $('').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank")) + ]) + } break; case 'date': additional_control = @@ -56,9 +61,13 @@ .append($('').prop('selected', field_operator == "yesterday").text(RailsAdmin.I18n.t("yesterday"))) .append($('').prop('selected', field_operator == "this_week").text(RailsAdmin.I18n.t("this_week"))) .append($('').prop('selected', field_operator == "last_week").text(RailsAdmin.I18n.t("last_week"))) - .append('') - .append($('').prop('selected', field_operator == "_not_null").text(RailsAdmin.I18n.t("is_present"))) - .append($('').prop('selected', field_operator == "_null").text(RailsAdmin.I18n.t("is_blank"))); + if (!required) { + control.append([ + '', + $('').prop('selected', field_operator == "_not_null").text(RailsAdmin.I18n.t("is_present")), + $('').prop('selected', field_operator == "_null").text(RailsAdmin.I18n.t("is_blank")) + ]) + } additional_control = additional_control || $('') .css('display', (!field_operator || field_operator == "default") ? 'inline-block' : 'none') @@ -84,10 +93,14 @@ .prop('name', multiple_values ? undefined : value_name) .data('name', value_name) .append('') - .append($('').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present"))) - .append($('').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank"))) - .append('') - .append(select_options) + if (!required) { + control.append([ + $('').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present")), + $('').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank")), + '' + ]) + } + control.append(select_options) .add( $('') .css('display', multiple_values ? 'inline-block' : 'none') @@ -111,9 +124,13 @@ .append($('').prop('selected', field_operator == "is").text(RailsAdmin.I18n.t("is_exactly"))) .append($('').prop('selected', field_operator == "starts_with").text(RailsAdmin.I18n.t("starts_with"))) .append($('').prop('selected', field_operator == "ends_with").text(RailsAdmin.I18n.t("ends_with"))) - .append('') - .append($('').prop('selected', field_operator == "_present").text(RailsAdmin.I18n.t("is_present"))) - .append($('').prop('selected', field_operator == "_blank").text(RailsAdmin.I18n.t("is_blank"))); + if (!required) { + control.append([ + '', + $('').prop('selected', field_operator == "_present").text(RailsAdmin.I18n.t("is_present")), + $('').prop('selected', field_operator == "_blank").text(RailsAdmin.I18n.t("is_blank")) + ]) + } additional_control = $('') .css('display', field_operator == "_present" || field_operator == "_blank" ? 'none' : 'inline-block') .prop('name', value_name) @@ -126,9 +143,13 @@ .prop('name', operator_name) .append($('').prop('selected', field_operator == "default").text(RailsAdmin.I18n.t("number"))) .append($('').prop('selected', field_operator == "between").text(RailsAdmin.I18n.t("between_and_"))) - .append('') - .append($('').prop('selected', field_operator == "_not_null").text(RailsAdmin.I18n.t("is_present"))) - .append($('').prop('selected', field_operator == "_null").text(RailsAdmin.I18n.t("is_blank"))); + if (!required) { + control.append([ + '', + $('').prop('selected', field_operator == "_not_null").text(RailsAdmin.I18n.t("is_present")), + $('').prop('selected', field_operator == "_null").text(RailsAdmin.I18n.t("is_blank")) + ]) + } additional_control = $('') .css('display', (!field_operator || field_operator == "default") ? 'inline-block' : 'none') @@ -193,6 +214,7 @@ value: $(this).data('field-value'), operator: $(this).data('field-operator'), select_options: $(this).data('field-options'), + required: $(this).data('field-required'), index: $.now().toString().slice(6,11), datetimepicker_format: $(this).data('field-datetimepicker-format') }); diff --git a/app/helpers/rails_admin/main_helper.rb b/app/helpers/rails_admin/main_helper.rb index a6162c9b1f..402797ea0a 100644 --- a/app/helpers/rails_admin/main_helper.rb +++ b/app/helpers/rails_admin/main_helper.rb @@ -77,6 +77,7 @@ def ordered_filter_options options[:value] = filter_hash['v'] options[:label] = field.label options[:operator] = filter_hash['o'] + options[:required] = field.required options end if ordered_filters end diff --git a/app/views/rails_admin/main/index.html.haml b/app/views/rails_admin/main/index.html.haml index df1f5f420c..5e7597ff4f 100644 --- a/app/views/rails_admin/main/index.html.haml +++ b/app/views/rails_admin/main/index.html.haml @@ -35,7 +35,7 @@ - else - '' %li - %a{href: '#', :"data-field-label" => field.label, :"data-field-name" => field.name, :"data-field-options" => field_options.html_safe, :"data-field-type" => field.type, :"data-field-value" => "", :"data-field-datetimepicker-format" => (field.try(:parser) && field.parser.to_momentjs)}= capitalize_first_letter(field.label) + %a{href: '#', :"data-field-label" => field.label, :"data-field-name" => field.name, :"data-field-options" => field_options.html_safe, :"data-field-required" => field.required.to_s, :"data-field-type" => field.type, :"data-field-value" => "", :"data-field-datetimepicker-format" => (field.try(:parser) && field.parser.to_momentjs)}= capitalize_first_letter(field.label) %style - properties.select{ |p| p.column_width.present? }.each do |property| diff --git a/spec/integration/actions/index_spec.rb b/spec/integration/actions/index_spec.rb index 4eadf32979..19f2331d37 100644 --- a/spec/integration/actions/index_spec.rb +++ b/spec/integration/actions/index_spec.rb @@ -59,6 +59,27 @@ @comment = FactoryBot.create(:comment, commentable: @players[2]) end + it 'hides redundant filter options for required fields', js: true do + RailsAdmin.config Player do + list do + field :name do + required true + end + field :team + end + end + + visit index_path(model_name: 'player', f: {name: {'1' => {v: ''}}, team: {'2' => {v: ''}}}) + + within(:select, name: 'f[name][1][o]') do + expect(page.all('option').map(&:value)).to_not include('_present', '_blank') + end + + within(:select, name: 'f[team][2][o]') do + expect(page.all('option').map(&:value)).to include('_present', '_blank') + end + end + it 'allows to query on any attribute' do RailsAdmin.config Player do list do @@ -294,6 +315,7 @@ type: 'string', value: '', operator: nil, + required: true, }, { index: 2, @@ -302,6 +324,7 @@ type: 'belongs_to_association', value: '', operator: nil, + required: false, }, ] end