diff --git a/app/javascript/vue/tasks/nomenclature/filter/components/FilterView.vue b/app/javascript/vue/tasks/nomenclature/filter/components/FilterView.vue index d7fc2622bb..79d6f9409a 100644 --- a/app/javascript/vue/tasks/nomenclature/filter/components/FilterView.vue +++ b/app/javascript/vue/tasks/nomenclature/filter/components/FilterView.vue @@ -108,18 +108,19 @@ const WITH_PARAMS = [ 'data_attributes', 'data_depictions', 'depictions', + 'leaves', // 'Descendants' 'etymology', 'global_identifiers', - 'leaves', + 'not_specified', // 'Incomplete combination relationships' + 'latinized', 'local_identifiers', 'nomenclature_date', - 'not_specified', 'notes', 'origin_citation', 'original_combination', 'otus', 'tags', - 'type_metadata', + 'type_metadata', // 'Type information' 'verbatim_name' ] diff --git a/lib/queries/taxon_name/filter.rb b/lib/queries/taxon_name/filter.rb index 99f2beefb0..f56063b345 100644 --- a/lib/queries/taxon_name/filter.rb +++ b/lib/queries/taxon_name/filter.rb @@ -24,6 +24,7 @@ class Filter < Query::Filter :descendants_max_depth, :epithet_only, :etymology, + :latinized, :leaves, :name, :name_exact, @@ -264,6 +265,15 @@ class Filter < Query::Filter # if 'false' then return only names with descendents attr_accessor :leaves + # @return [Boolean, nil] + # &latinized=<"true"|"false"> + # if 'true' then return only genus group names with gender and species + # group names with part of speech + # if 'false' then return only genus group names without gender and + # species group names without part of speech + # if nil, ignore + attr_accessor :latinized + # @return [String, nil] # &taxon_name_type= attr_accessor :taxon_name_type @@ -314,6 +324,7 @@ def initialize(query_params) @descendants_max_depth = params[:descendants_max_depth] @etymology = boolean_param(params, :etymology) @epithet_only = params[:epithet_only] + @latinized = boolean_param(params, :latinized) @geo_json = params[:geo_json] @leaves = boolean_param(params, :leaves) @name = params[:name] @@ -562,6 +573,37 @@ def leaves_facet leaves ? ::TaxonName.leaves : ::TaxonName.not_leaves end + # @return Scope + def latinized_facet + return nil if latinized.nil? + + tnc = ::TaxonNameClassification.arel_table + if latinized == true + # Note the query here does not restrict to genus/species groups - a + # genus whose rank is changed to subfamily can retain its gender, + # e.g., and we want to include those here. + ::TaxonName.where( + ::TaxonNameClassification.where( + tnc[:taxon_name_id].eq(table[:id]).and( + tnc[:type].in(LATINIZED_TAXON_NAME_CLASSIFICATION_NAMES) + ) + ).arel.exists + ) + else + ::TaxonName + .where( + table[:rank_class].in(GENUS_AND_SPECIES_RANK_NAMES) + ) + .where.not( + ::TaxonNameClassification.where( + tnc[:taxon_name_id].eq(table[:id]).and( + tnc[:type].in(LATINIZED_TAXON_NAME_CLASSIFICATION_NAMES) + ) + ).arel.exists + ) + end + end + # @return Scope # wrapped in descendant_facet! def taxon_name_relationship_facet(hsh) @@ -844,12 +886,13 @@ def merge_clauses combination_taxon_name_id_facet, combinations_facet, descendant_facet, + latinized_facet, leaves_facet, not_specified_facet, original_combination_facet, otu_id_facet, - taxon_name_author_id_facet, otus_facet, + taxon_name_author_id_facet, taxon_name_classification_facet, taxon_name_relationship_type_facet, type_metadata_facet, diff --git a/spec/lib/queries/taxon_name/filter_spec.rb b/spec/lib/queries/taxon_name/filter_spec.rb index 3a9d6d3ebc..5e1d805d3d 100644 --- a/spec/lib/queries/taxon_name/filter_spec.rb +++ b/spec/lib/queries/taxon_name/filter_spec.rb @@ -121,6 +121,39 @@ expect(query.all.map(&:id)).to contain_exactly(genus.id, root.id) end + context '#latinized' do + let!(:fem_genus) { + g = Protonym.create!(name: 'Rosa', + rank_class: Ranks.lookup(:iczn, 'genus'), parent: root) + TaxonNameClassification::Latinized::Gender::Feminine.create!(taxon_name: g) + g + } + + let!(:fem_species) { + s = Protonym.create!( + name: 'blanda', + rank_class: Ranks.lookup(:iczn, 'species'), + parent: fem_genus + ) + TaxonNameClassification::Latinized::PartOfSpeech::Adjective.create!(taxon_name: s) + s + } + + specify '#latinized true' do + query.latinized = true + expect(query.all.map(&:id)).to contain_exactly( + fem_genus.id, fem_species.id + ) + end + + specify '#latinized false' do + query.latinized = false + expect(query.all.map(&:id)).to contain_exactly( + genus.id, original_genus.id, species.id + ) + end + end + specify "#nomenclature_group 1" do query.nomenclature_group = "Species" expect(query.all.map(&:id)).to contain_exactly(species.id)