From b79cfb75e75ea215015f16c9da7a3edf90a4ebcd Mon Sep 17 00:00:00 2001 From: Grovkillen Date: Tue, 11 Nov 2025 06:52:50 +0100 Subject: [PATCH 1/5] Update init.rb The plugin is "redmine_or_filters" (with an S) everywhere but here and at least on Redmine 6.0 that is not ok. --- init.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.rb b/init.rb index 8733963..a6a6e44 100644 --- a/init.rb +++ b/init.rb @@ -1,4 +1,4 @@ -Redmine::Plugin.register :redmine_or_filter do +Redmine::Plugin.register :redmine_or_filters do name 'Redmine or filter' author 'Alexey Smirnov' description 'This is a plugin for Redmine which adds OR filters. Development based on discussion https://www.redmine.org/issues/4939' @@ -10,4 +10,4 @@ require_dependency File.dirname(__FILE__) + '/lib/queries_helper_patch' require_dependency File.dirname(__FILE__) + '/lib/issue_query_patch' -require_dependency File.dirname(__FILE__) + '/lib/query_patch' \ No newline at end of file +require_dependency File.dirname(__FILE__) + '/lib/query_patch' From d839bf1340a1a86d74140e4c11752f0191ad6042 Mon Sep 17 00:00:00 2001 From: Grovkillen Date: Tue, 11 Nov 2025 07:04:14 +0100 Subject: [PATCH 2/5] Update query_patch.rb Make query respect the current project --- lib/query_patch.rb | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/query_patch.rb b/lib/query_patch.rb index e52ec5a..1e4f731 100644 --- a/lib/query_patch.rb +++ b/lib/query_patch.rb @@ -12,9 +12,16 @@ def statement or_any_op = "" or_all_op = "" - #the AND filter start first - filters_clauses = and_clauses + # the AND filter starts first + filters_clauses = and_clauses + # small helper to safely join parts with an operator and always wrap in () + join_group = lambda do |parts, op, fallback = " AND "| + parts = parts.reject(&:blank?) + return nil if parts.empty? + joined = parts.join(op.present? ? op : fallback) + "(#{joined})" + end filters.each_key do |field| next if field == "subproject_id" @@ -91,28 +98,31 @@ def statement filters_clauses.reject!(&:blank?) and_clauses.reject!(&:blank?) and_statement = and_clauses.any? ? and_clauses.join(" AND ") : nil - all_and_statement = ["#{project_statement}", "#{and_statement}"].reject(&:blank?) + + # Always keep the project_statement inside the base (AND) group + all_and_statement = [project_statement, and_statement].reject(&:blank?) all_and_statement = all_and_statement.any? ? all_and_statement.join(" AND ") : nil + all_and_statement = "(#{all_and_statement})" if all_and_statement.present? - # finish the traditional part. Now extended part - # add the and_any first + # Extended part + # 1) and_any (OR between its items, then combined with base using AND/AND NOT) and_any_clauses.reject!(&:blank?) - and_any_statement = and_any_clauses.any? ? "("+ and_any_clauses.join(" OR ") +")" : nil - full_statement_ext_1 = ["#{all_and_statement}", "#{and_any_statement}"].reject(&:blank?) - full_statement_ext_1 = full_statement_ext_1.any? ? full_statement_ext_1.join(and_any_op) : nil + and_any_statement = and_any_clauses.any? ? "(" + and_any_clauses.join(" OR ") + ")" : nil + full_statement_ext_1 = [all_and_statement, and_any_statement] + full_statement_ext_1 = join_group.call(full_statement_ext_1.compact, and_any_op, " AND ") - # then add the or_all + # 2) or_all (AND between its items, then OR/OR NOT with the previous group) or_all_clauses.reject!(&:blank?) - or_all_statement = or_all_clauses.any? ? "("+ or_all_clauses.join(" AND ") +")" : nil - full_statement_ext_2 = ["#{full_statement_ext_1}", "#{or_all_statement}"].reject(&:blank?) - full_statement_ext_2 = full_statement_ext_2.any? ? full_statement_ext_2.join(or_all_op) : nil + or_all_statement = or_all_clauses.any? ? "(" + or_all_clauses.join(" AND ") + ")" : nil + full_statement_ext_2 = [full_statement_ext_1, or_all_statement] + full_statement_ext_2 = join_group.call(full_statement_ext_2.compact, or_all_op, " AND ") - # then add the or_any + # 3) or_any (OR between its items, then OR/OR NOT with the previous group) or_any_clauses.reject!(&:blank?) - or_any_statement = or_any_clauses.any? ? "("+ or_any_clauses.join(" OR ") +")" : nil - filters_clauses.any? ? filters_clauses.join(' AND ') : nil - full_statement = ["#{full_statement_ext_2}", "#{or_any_statement}"].reject(&:blank?) - full_statement = full_statement.any? ? full_statement.join(or_any_op) : nil + or_any_statement = or_any_clauses.any? ? "(" + or_any_clauses.join(" OR ") + ")" : nil + full_statement = [full_statement_ext_2, or_any_statement] + full_statement = join_group.call(full_statement.compact, or_any_op, " AND ") + Rails.logger.info "STATEMENT #{full_statement}" return full_statement end @@ -436,4 +446,4 @@ def sql_for_match_operators(field, operator, value, db_table, db_field, is_custo Query.operators.store("match", :label_match) Query.operators.store("!match", :label_not_match) -Query.send(:prepend, QueryPatch) \ No newline at end of file +Query.send(:prepend, QueryPatch) From 3d0c7351a5de02333359df5a8f16ace1f9e7021d Mon Sep 17 00:00:00 2001 From: Grovkillen Date: Tue, 11 Nov 2025 07:11:25 +0100 Subject: [PATCH 3/5] Swedish translations --- config/locales/sv.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 config/locales/sv.yml diff --git a/config/locales/sv.yml b/config/locales/sv.yml new file mode 100644 index 0000000..0cef7ed --- /dev/null +++ b/config/locales/sv.yml @@ -0,0 +1,7 @@ +sv: + label_orfilter: "Eller-filter" + label_orfilter_and_any: "OCH någon av följande" + label_orfilter_or_any: "Eller någon av följande" + label_orfilter_or_all: "Eller alla följande" + label_match: "träff" + label_not_match: "ingen träff" \ No newline at end of file From 5fb075866d6905eca56e9f994f1b64160d8d0709 Mon Sep 17 00:00:00 2001 From: Grovkillen Date: Tue, 11 Nov 2025 07:24:16 +0100 Subject: [PATCH 4/5] Update query_patch.rb Now I think the active project is respected. --- lib/query_patch.rb | 56 ++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/lib/query_patch.rb b/lib/query_patch.rb index 1e4f731..4fa956d 100644 --- a/lib/query_patch.rb +++ b/lib/query_patch.rb @@ -4,24 +4,25 @@ def statement # filters clauses filters_clauses = [] - and_clauses=[] - and_any_clauses=[] - or_any_clauses=[] - or_all_clauses=[] - and_any_op = "" - or_any_op = "" - or_all_op = "" + and_clauses=[] + and_any_clauses=[] + or_any_clauses=[] + or_all_clauses=[] + and_any_op = "" + or_any_op = "" + or_all_op = "" - # the AND filter starts first - filters_clauses = and_clauses + #the AND filter start first + filters_clauses = and_clauses - # small helper to safely join parts with an operator and always wrap in () + # helper: join non-blank parts with op, wrap in () join_group = lambda do |parts, op, fallback = " AND "| parts = parts.reject(&:blank?) return nil if parts.empty? joined = parts.join(op.present? ? op : fallback) "(#{joined})" end + filters.each_key do |field| next if field == "subproject_id" @@ -89,39 +90,40 @@ def statement filters_clauses << c.custom_field.visibility_by_project_condition end - # filters_clauses << project_statement - # filters_clauses.reject!(&:blank?) - - # filters_clauses.any? ? filters_clauses.join(' AND ') : nil - - #now start build the full statement, project filter is allways AND + # Build base AND statement (WITHOUT project_statement here) filters_clauses.reject!(&:blank?) and_clauses.reject!(&:blank?) and_statement = and_clauses.any? ? and_clauses.join(" AND ") : nil - # Always keep the project_statement inside the base (AND) group - all_and_statement = [project_statement, and_statement].reject(&:blank?) - all_and_statement = all_and_statement.any? ? all_and_statement.join(" AND ") : nil - all_and_statement = "(#{all_and_statement})" if all_and_statement.present? - # Extended part - # 1) and_any (OR between its items, then combined with base using AND/AND NOT) + # 1) and_any (OR-join inom grupp, sedan kopplas med AND/AND NOT) and_any_clauses.reject!(&:blank?) and_any_statement = and_any_clauses.any? ? "(" + and_any_clauses.join(" OR ") + ")" : nil - full_statement_ext_1 = [all_and_statement, and_any_statement] + full_statement_ext_1 = [and_statement, and_any_statement] full_statement_ext_1 = join_group.call(full_statement_ext_1.compact, and_any_op, " AND ") - # 2) or_all (AND between its items, then OR/OR NOT with the previous group) + # 2) or_all (AND-join inom grupp, kopplas med OR/OR NOT) or_all_clauses.reject!(&:blank?) or_all_statement = or_all_clauses.any? ? "(" + or_all_clauses.join(" AND ") + ")" : nil full_statement_ext_2 = [full_statement_ext_1, or_all_statement] full_statement_ext_2 = join_group.call(full_statement_ext_2.compact, or_all_op, " AND ") - # 3) or_any (OR between its items, then OR/OR NOT with the previous group) + # 3) or_any (OR-join inom grupp, kopplas med OR/OR NOT) or_any_clauses.reject!(&:blank?) or_any_statement = or_any_clauses.any? ? "(" + or_any_clauses.join(" OR ") + ")" : nil - full_statement = [full_statement_ext_2, or_any_statement] - full_statement = join_group.call(full_statement.compact, or_any_op, " AND ") + core_statement = [full_statement_ext_2, or_any_statement] + core_statement = join_group.call(core_statement.compact, or_any_op, " AND ") + + # FINAL: alltid AND:a in project_statement runt hela core_statement + if project_statement.present? + if core_statement.present? + full_statement = "#{project_statement} AND #{core_statement}" + else + full_statement = project_statement + end + else + full_statement = core_statement + end Rails.logger.info "STATEMENT #{full_statement}" return full_statement From 7e22938e25f82c7711f416b5ea4aacce19701b3f Mon Sep 17 00:00:00 2001 From: Grovkillen Date: Tue, 11 Nov 2025 07:49:43 +0100 Subject: [PATCH 5/5] Update query_patch.rb Sorry for the Swedish comments, translated them to English --- lib/query_patch.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/query_patch.rb b/lib/query_patch.rb index 4fa956d..77c0bb9 100644 --- a/lib/query_patch.rb +++ b/lib/query_patch.rb @@ -96,25 +96,25 @@ def statement and_statement = and_clauses.any? ? and_clauses.join(" AND ") : nil # Extended part - # 1) and_any (OR-join inom grupp, sedan kopplas med AND/AND NOT) + # 1) and_any (OR-join within group, attach to AND/AND NOT) and_any_clauses.reject!(&:blank?) and_any_statement = and_any_clauses.any? ? "(" + and_any_clauses.join(" OR ") + ")" : nil full_statement_ext_1 = [and_statement, and_any_statement] full_statement_ext_1 = join_group.call(full_statement_ext_1.compact, and_any_op, " AND ") - # 2) or_all (AND-join inom grupp, kopplas med OR/OR NOT) + # 2) or_all (AND-join within group, attach to OR/OR NOT) or_all_clauses.reject!(&:blank?) or_all_statement = or_all_clauses.any? ? "(" + or_all_clauses.join(" AND ") + ")" : nil full_statement_ext_2 = [full_statement_ext_1, or_all_statement] full_statement_ext_2 = join_group.call(full_statement_ext_2.compact, or_all_op, " AND ") - # 3) or_any (OR-join inom grupp, kopplas med OR/OR NOT) + # 3) or_any (OR-join within group, attach to OR/OR NOT) or_any_clauses.reject!(&:blank?) or_any_statement = or_any_clauses.any? ? "(" + or_any_clauses.join(" OR ") + ")" : nil core_statement = [full_statement_ext_2, or_any_statement] core_statement = join_group.call(core_statement.compact, or_any_op, " AND ") - # FINAL: alltid AND:a in project_statement runt hela core_statement + # FINAL: always add AND for project_statement enclosing core_statement if project_statement.present? if core_statement.present? full_statement = "#{project_statement} AND #{core_statement}"