diff options
-rw-r--r-- | .rubocop.yml | 15 | ||||
-rw-r--r-- | .rubocop_todo.yml | 36 | ||||
-rw-r--r-- | Gemfile | 4 | ||||
-rw-r--r-- | app/assets/stylesheets/application.css | 48 | ||||
-rw-r--r-- | app/assets/stylesheets/responsive.css | 18 | ||||
-rw-r--r-- | app/helpers/application_helper.rb | 2 | ||||
-rw-r--r-- | app/helpers/projects_helper.rb | 4 | ||||
-rw-r--r-- | app/helpers/queries_helper.rb | 2 | ||||
-rw-r--r-- | app/helpers/reactions_helper.rb | 2 | ||||
-rw-r--r-- | app/models/issue.rb | 2 | ||||
-rw-r--r-- | app/models/user_preference.rb | 2 | ||||
-rw-r--r-- | config/settings.yml | 2 | ||||
-rw-r--r-- | db/migrate/017_create_settings.rb | 1 | ||||
-rw-r--r-- | test/helpers/application_helper_test.rb | 8 | ||||
-rw-r--r-- | test/system/reactions_test.rb | 6 | ||||
-rw-r--r-- | test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb | 2 | ||||
-rw-r--r-- | test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb | 12 | ||||
-rw-r--r-- | test/unit/member_test.rb | 2 | ||||
-rw-r--r-- | test/unit/setting_test.rb | 4 |
19 files changed, 108 insertions, 64 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index 3e5f0569f..77857c9cd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -114,7 +114,10 @@ Naming/VariableNumber: Naming/BinaryOperatorParameterName: Enabled: false -Naming/PredicateName: +Naming/PredicateMethod: + Enabled: false + +Naming/PredicatePrefix: Enabled: false Performance/CollectionLiteralInLoop: @@ -166,6 +169,13 @@ Rails/FindEach: Rails/HelperInstanceVariable: Enabled: false +Rails/Output: + Exclude: + - 'config/routes.rb' + - 'lib/redmine/diff.rb' + - 'lib/redmine/diff_table.rb' + - 'test/unit/lib/redmine/scm/adapters/*.rb' + Rails/Pluck: Exclude: # `pluck` is not available in Gemfile @@ -214,6 +224,9 @@ Style/BlockDelimiters: - 'lib/redmine/string_array_diff/diff.rb' - 'lib/redmine/string_array_diff/diffable.rb' +Style/EmptyStringInsideInterpolation: + Enabled: false + Style/FetchEnvVar: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 3fffc0833..1aafe4925 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 20 --no-offense-counts --no-auto-gen-timestamp` -# using RuboCop version 1.75.2. +# using RuboCop version 1.76.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -220,9 +220,6 @@ Lint/ParenthesesAsGroupedExpression: - 'test/unit/attachment_test.rb' - 'test/unit/lib/redmine/export/pdf_test.rb' -Lint/ShadowingOuterLocalVariable: - Enabled: false - # Configuration parameters: AllowComments, AllowNil. Lint/SuppressedException: Exclude: @@ -331,7 +328,7 @@ Naming/VariableNumber: - 'test/unit/project_test.rb' # Configuration parameters: Severity, Include. -# Include: app/models/**/*.rb +# Include: **/app/models/**/*.rb Rails/ActiveRecordOverride: Exclude: - 'app/models/email_address.rb' @@ -402,7 +399,7 @@ Rails/EagerEvaluationLogMessage: - 'app/controllers/application_controller.rb' # Configuration parameters: Include. -# Include: app/**/*.rb, config/**/*.rb, lib/**/*.rb +# Include: **/app/**/*.rb, **/config/**/*.rb, **/lib/**/*.rb Rails/Exit: Exclude: - 'config/environment.rb' @@ -410,7 +407,7 @@ Rails/Exit: - 'config/routes.rb' # Configuration parameters: Include. -# Include: app/models/**/*.rb +# Include: **/app/models/**/*.rb Rails/HasAndBelongsToMany: Exclude: - 'app/models/changeset.rb' @@ -425,7 +422,7 @@ Rails/HasAndBelongsToMany: - 'app/models/user.rb' # Configuration parameters: Include. -# Include: app/models/**/*.rb +# Include: **/app/models/**/*.rb Rails/HasManyOrHasOneDependent: Exclude: - 'app/models/auth_source.rb' @@ -459,7 +456,7 @@ Rails/I18nLocaleTexts: - 'app/models/mailer.rb' # Configuration parameters: IgnoreScopes, Include. -# Include: app/models/**/*.rb +# Include: **/app/models/**/*.rb Rails/InverseOf: Exclude: - 'app/models/board.rb' @@ -483,7 +480,7 @@ Rails/InverseOf: - 'app/models/wiki_page.rb' # Configuration parameters: Include. -# Include: app/controllers/**/*.rb, app/mailers/**/*.rb +# Include: **/app/controllers/**/*.rb, **/app/mailers/**/*.rb Rails/LexicallyScopedActionFilter: Exclude: - 'app/controllers/projects_controller.rb' @@ -495,7 +492,7 @@ Rails/LinkToBlank: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Include. -# Include: config/routes.rb, config/routes/**/*.rb +# Include: **/config/routes.rb, **/config/routes/**/*.rb Rails/MatchRoute: Exclude: - 'config/routes.rb' @@ -504,15 +501,6 @@ Rails/MatchRoute: Rails/NegateInclude: Enabled: false -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: Include. -# Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb -Rails/Output: - Exclude: - - 'config/routes.rb' - - 'lib/redmine/diff.rb' - - 'lib/redmine/diff_table.rb' - Rails/OutputSafety: Enabled: false @@ -541,7 +529,7 @@ Rails/Present: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Include. -# Include: app/models/**/*.rb +# Include: **/app/models/**/*.rb Rails/ReadWriteAttribute: Exclude: - 'app/models/auth_source_ldap.rb' @@ -600,7 +588,7 @@ Rails/TimeZone: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Include. -# Include: app/models/**/*.rb +# Include: **/app/models/**/*.rb Rails/Validation: Enabled: false @@ -708,8 +696,8 @@ Style/CaseLikeIf: # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules. # SupportedStyles: nested, compact -# SupportedStylesForClasses: , nested, compact -# SupportedStylesForModules: , nested, compact +# SupportedStylesForClasses: ~, nested, compact +# SupportedStylesForModules: ~, nested, compact Style/ClassAndModuleChildren: Enabled: false @@ -111,9 +111,9 @@ group :test do gem "capybara", ">= 3.39" gem 'selenium-webdriver', '>= 4.11.0' # RuboCop - gem 'rubocop', '~> 1.75.2', require: false + gem 'rubocop', '~> 1.76.0', require: false gem 'rubocop-performance', '~> 1.25.0', require: false - gem 'rubocop-rails', '~> 2.31.0', require: false + gem 'rubocop-rails', '~> 2.32.0', require: false gem 'bundle-audit', require: false end diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 5a1546899..4e894c1f5 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -364,6 +364,9 @@ table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; } table.list tr.overdue td.due_date { color: #c22; } table.list thead.related-issues th { background-color: inherit; font-size: 11px; border: none; } #role-permissions-trackers table.list th {white-space:normal;} +table.list div.wiki p { + margin: 0; +} .table-list-cell {display: table-cell; vertical-align: top; padding:2px; } .table-list div.buttons {width: 15%;} @@ -922,7 +925,11 @@ ul.projects div.description ul li {list-style-type:initial;} background-image: none; padding-left: 0; } -#projects-index ul.projects div.root svg { +#projects-index ul.projects .icon-bookmarked-project svg, +#projects-index ul.projects .my-project svg { + margin-left: 4px; +} +#projects-index ul.projects div.root .icon-bookmarked-project svg, #projects-index ul.projects div.root .my-project svg { stroke-width: 2; margin-bottom: 10px; } @@ -933,13 +940,15 @@ ul.projects div.description ul li {list-style-type:initial;} background-image: none; padding-left: 0; } -#projects-index a.project ~ svg, table.projects tr.project td.name svg { - margin-left: 4px; -} -#projects-index li p { +#projects-index div.wiki p { margin-top: 0px; } +table.projects td.name .icon-bookmarked-project svg, +table.projects td.name .my-project svg { + margin-left: 4px; +} + #notified-projects>ul, #tracker_project_ids>ul, #custom_field_project_ids>ul {max-height:250px; overflow-y:auto;} ul.subprojects {list-style: none; display: inline-block; padding: 0; margin: 0;} @@ -1151,10 +1160,26 @@ span.required {color: #bb0000;} .attachments_fields .icon-attachment, #existing-attachments .icon-attachment {background-image: none; padding-left: 0} .attachments_fields input.filename, #existing-attachments .filename {border:0; width:250px; color:#555; background-color:inherit; } .tabular input.filename {max-width:75% !important;} -.attachments_fields input.filename {height:1.8em;padding-right: 0;} -.attachments_fields .ajax-waiting input.filename {background:url(/hourglass.png) no-repeat 0px 50%;} -.attachments_fields .ajax-loading input.filename {background:url(/loading.gif) no-repeat 0px 50%;} .attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; } +.attachments_fields input.filename { + height:1.8em; + padding-left: 3px; + padding-right: 0; +} +.attachments_fields .ajax-waiting { + padding-left: 16px; + background:url(/hourglass.png) no-repeat 0px 50%; +} +.attachments_fields .ajax-waiting .svg-attachment { + display: none; +} +.attachments_fields .ajax-loading { + padding-left: 16px; + background: url(/loading.gif) no-repeat 0px 50%; +} +.attachments_fields .ajax-loading .svg-attachment { + display: none; +} a.remove-upload:hover {text-decoration:none !important;} .existing-attachment.deleted .filename {text-decoration:line-through; color:#999 !important;} @@ -2135,13 +2160,6 @@ color: #555; text-shadow: 1px 1px 0 #fff; img.filecontent.image {background-image: url(/transparent.png);} /* Reaction styles */ -.reaction-button.reacted .icon-svg { - fill: #126fa7; - stroke: none; -} -.reaction-button.reacted:hover .icon-svg { - fill: #c61a1a; -} .reaction-button:hover, .reaction-button:active { text-decoration: none; } diff --git a/app/assets/stylesheets/responsive.css b/app/assets/stylesheets/responsive.css index 867c41e9b..b3e8bddd8 100644 --- a/app/assets/stylesheets/responsive.css +++ b/app/assets/stylesheets/responsive.css @@ -385,7 +385,7 @@ list-style: none; } - .flyout-menu #watchers { + .flyout-menu #watchers, .flyout-menu .queries { display: -webkit-flex; display: -webkit-box; display: flex; @@ -402,11 +402,11 @@ order: 3; } - .flyout-menu #watchers h3 { + #sidebar-wrapper { margin-left: -8px; } - .flyout-menu #watchers ul li { + .flyout-menu #watchers ul li, .flyout-menu ul.queries li { display: -webkit-flex; display: -webkit-box; display: flex; @@ -418,6 +418,16 @@ -webkit-align-items: center; -webkit-box-align: center; align-items: center; + border-top: 1px solid rgba(255,255,255,.1); + } + + .flyout-menu #watchers ul li a, .flyout-menu ul.queries li a { + border-top: none; + } + + .flyout-menu ul.queries li a.icon-clear-query { + flex-shrink: 0; + padding-right: 8px; } .flyout-menu ul li a { @@ -440,7 +450,7 @@ color: white; } - .flyout-menu .icon svg { + .flyout-menu .icon svg, .flyout-menu .icon-only svg { stroke: white; } diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 99a760c1d..285528422 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -518,6 +518,8 @@ module ApplicationHelper def render_flash_messages s = +'' flash.each do |k, v| + next unless v.is_a?(String) + s << content_tag('div', notice_icon(k) + v.html_safe, :class => "flash #{k}", :id => "flash_#{k}") end s.html_safe diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 01a5452f7..bae1c4e3a 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -80,8 +80,8 @@ module ProjectsHelper classes += %w(icon icon-bookmarked-project) if bookmarked_project_ids.include?(project.id) s = link_to_project(project, {}, :class => classes.uniq.join(' ')) - s << sprite_icon('user', l(:label_my_projects), icon_only: true) if User.current.member_of?(project) - s << sprite_icon('bookmarked', l(:label_my_bookmarks), icon_only: true) if bookmarked_project_ids.include?(project.id) + s << tag.span(sprite_icon('user', l(:label_my_projects), icon_only: true), class: 'icon-only icon-user my-project') if User.current.member_of?(project) + s << tag.span(sprite_icon('bookmarked', l(:label_my_bookmarks), icon_only: true), class: 'icon-only icon-bookmarked-project') if bookmarked_project_ids.include?(project.id) if project.description.present? s << content_tag('div', textilizable(project.short_description, :project => project), :class => 'wiki description') end diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index ca7168f27..3aef7083a 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -169,7 +169,7 @@ module QueriesHelper group_name = format_object(group) end group_name ||= "" - group_count = result_count_by_group ? result_count_by_group[group] : nil + group_count = result_count_by_group&.[](group) group_totals = totals_by_group.map {|column, t| total_tag(column, t[group] || 0)}.join(" ").html_safe end end diff --git a/app/helpers/reactions_helper.rb b/app/helpers/reactions_helper.rb index 97943e71c..e02e1c9f9 100644 --- a/app/helpers/reactions_helper.rb +++ b/app/helpers/reactions_helper.rb @@ -52,7 +52,7 @@ module ReactionsHelper def reaction_button_reacted(object, reaction, count, tooltip) reaction_button_wrapper object do link_to( - sprite_icon('thumb-up-filled', count.nonzero?), + sprite_icon('thumb-up-filled', count.nonzero?, style: :filled), reaction_path(reaction, object_type: object.class.name, object_id: object), remote: true, method: :delete, class: ['icon', 'reaction-button', 'reacted'], diff --git a/app/models/issue.rb b/app/models/issue.rb index bfef3533a..576840843 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1175,7 +1175,7 @@ class Issue < ApplicationRecord if leaf? spent_hours else - self_and_descendants.joins(:time_entries).sum("#{TimeEntry.table_name}.hours").to_f || 0.0 + self_and_descendants.joins(:time_entries).sum("#{TimeEntry.table_name}.hours").to_f end end diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index 8b19d9a5a..e1842b131 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -73,7 +73,7 @@ class UserPreference < ApplicationRecord if has_attribute? attr_name super else - others ? others[attr_name] : nil + others&.[](attr_name) end end diff --git a/config/settings.yml b/config/settings.yml index cda40fa38..b1217fc0a 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -362,6 +362,6 @@ timelog_accept_closed_issues: show_status_changes_in_mail_subject: default: 1 wiki_tablesort_enabled: - default: 1 + default: 0 reactions_enabled: default: 1 diff --git a/db/migrate/017_create_settings.rb b/db/migrate/017_create_settings.rb index 5768ca24c..f86a1c2c3 100644 --- a/db/migrate/017_create_settings.rb +++ b/db/migrate/017_create_settings.rb @@ -8,6 +8,7 @@ class CreateSettings < ActiveRecord::Migration[4.2] # Persist default settings for new installations Setting.create!(name: 'default_notification_option', value: Setting.default_notification_option) Setting.create!(name: 'text_formatting', value: Setting.text_formatting) + Setting.create!(name: 'wiki_tablesort_enabled', value: Setting.wiki_tablesort_enabled) end def self.down diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index c9ec72467..2e2e8b933 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -2403,6 +2403,14 @@ class ApplicationHelperTest < Redmine::HelperTest assert_equal expected, format_activity_description(text) end + def test_render_flash_messages_should_ignore_non_string_values + flash[:array_value] = ['1', '2'] + flash[:hash_value] = { foo: 'bar' } + + result = render_flash_messages + assert_equal '', result + end + private def wiki_links_with_special_characters diff --git a/test/system/reactions_test.rb b/test/system/reactions_test.rb index cd3e2e871..96dd4cf81 100644 --- a/test/system/reactions_test.rb +++ b/test/system/reactions_test.rb @@ -129,7 +129,7 @@ class ReactionsSystemTest < ApplicationSystemTestCase within('#change-1') do assert_selector 'a.reaction-button' - assert_no_selector 'a.icon-comment' + assert_no_selector 'a.icon-quote' assert_no_selector 'span.drdn' end within("#change-#{journal_without_notes.id}") do @@ -143,14 +143,14 @@ class ReactionsSystemTest < ApplicationSystemTestCase within('#change-1') do assert_selector 'a.reaction-button' - assert_selector 'a.icon-comment' + assert_selector 'a.icon-quote' assert_selector 'span.drdn' end within("#change-#{journal_without_notes.id}") do assert_selector 'a.reaction-button' assert_selector 'span.drdn' - assert_no_selector 'a.icon-comment' + assert_no_selector 'a.icon-quote' end end diff --git a/test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb b/test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb index d267abbf9..bb0c5d450 100644 --- a/test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb @@ -226,7 +226,7 @@ class Redmine::WikiFormatting::CommonMark::FormatterTest < ActionView::TestCase text = STR_WITH_PRE.join("\n\n") replacement = "New text" - assert_equal [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"), + assert_equal [STR_WITH_PRE[0..1], "New text"].join("\n\n"), @formatter.new(text).update_section(3, replacement) end diff --git a/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb b/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb index 32280cfdf..678d4c6b2 100644 --- a/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb @@ -466,19 +466,19 @@ class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase replacement = "New text" assert_equal( - [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"), + [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement) ) assert_equal( - [STR_WITHOUT_PRE[0..1], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), + [STR_WITHOUT_PRE[0..1], replacement, STR_WITHOUT_PRE[4]].join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(3, replacement) ) assert_equal( - [STR_WITHOUT_PRE[0..2], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), + [STR_WITHOUT_PRE[0..2], replacement, STR_WITHOUT_PRE[4]].join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(5, replacement) ) assert_equal( - [STR_WITHOUT_PRE[0..3], replacement].flatten.join("\n\n"), + [STR_WITHOUT_PRE[0..3], replacement].join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(6, replacement) ) assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(0, replacement) @@ -488,7 +488,7 @@ class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase def test_update_section_with_hash_should_update_the_requested_section replacement = "New text" assert_equal( - [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"), + [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE). update_section(2, replacement, ActiveSupport::Digest.hexdigest(STR_WITHOUT_PRE[1])) ) @@ -552,7 +552,7 @@ class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase text = STR_WITH_PRE.join("\n\n") replacement = "New text" assert_equal( - [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"), + [STR_WITH_PRE[0..1], "New text"].join("\n\n"), @formatter.new(text).update_section(3, replacement) ) end diff --git a/test/unit/member_test.rb b/test/unit/member_test.rb index 42fba4783..df9088027 100644 --- a/test/unit/member_test.rb +++ b/test/unit/member_test.rb @@ -108,7 +108,7 @@ class MemberTest < ActiveSupport::TestCase assert !member.save assert_include I18n.translate('activerecord.errors.messages.empty'), member.errors[:role] assert_equal 'Rôle doit être renseigné(e)', - [member.errors.full_messages].flatten.join + [member.errors.full_messages].join end def test_validate_member_role diff --git a/test/unit/setting_test.rb b/test/unit/setting_test.rb index 4ae07cebb..cbfabbb02 100644 --- a/test/unit/setting_test.rb +++ b/test/unit/setting_test.rb @@ -147,4 +147,8 @@ class SettingTest < ActiveSupport::TestCase def test_default_text_formatting_for_new_installations_is_common_mark assert_equal 'common_mark', Setting.text_formatting end + + def test_default_wiki_tablesort_enabled_for_new_installations_is_disabled + assert_equal "0", Setting.wiki_tablesort_enabled + end end |