Merge remote-tracking branch 'origin/release/13.4' into dev

This commit is contained in:
ulferts
2024-03-21 10:41:19 +01:00
5216 changed files with 69671 additions and 72506 deletions
-3
View File
@@ -5,6 +5,3 @@
21a696ef9b170e14ad2daf53364a4c2113822c2f
# Update copyright information for 2023
c795874f7f281297bbd3bad2fdb58b24cb4ce624
# switch to double quotes
5c72ea0046a6b5230bf456f55a296ed6fd579535
9e4934cd0a468f46d8f0fc0f11ebc2d4216f789c
+10 -21
View File
@@ -12,7 +12,7 @@ on:
inputs:
tag:
description: "The tag to release. Note that this happens by default on the tag push. Only run this action when something went wrong!"
required: false
required: true
permissions:
contents: read # to fetch code (actions/checkout)
@@ -23,7 +23,7 @@ env:
jobs:
build:
if: github.repository == 'opf/openproject'
runs-on: runs-on,runner=8cpu-linux,family=m7i+m7a,run-id=${{ github.run_id }}
runs-on: [ self-hosted, aws, ubuntu22, x64, 2XL ]
strategy:
matrix:
include:
@@ -45,31 +45,21 @@ jobs:
run: |
if [[ ${{ github.event_name }} == 'push' ]]; then
TAG_REF=${GITHUB_REF#refs/tags/}
CHECKOUT_REF=$GITHUB_REF
elif [[ ${{ github.event_name }} == 'schedule' ]]; then
TAG_REF=dev
CHECKOUT_REF=refs/heads/dev
elif [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then
TAG_REF=${{ inputs.tag }}
CHECKOUT_REF=${{ inputs.tag }}
else
echo "Unsupported event"
exit 1
fi
if [ -z "$TAG_REF" ] || [ -z "$CHECKOUT_REF" ]; then
echo "No TAG_REF or CHECKOUT_REF set. Aborting"
exit 1
fi
VERSION=${TAG_REF#v}
echo "Version: $VERSION"
echo "::set-output name=version::$VERSION"
echo "::set-output name=checkout_ref::$CHECKOUT_REF"
- name: Checkout
- name: Checkout current release
if: ${{ github.event_name == 'push' }}
uses: actions/checkout@v3
- name: Checkout specific version
if: ${{ github.event_name != 'push' }}
with:
ref: ${{ steps.extract_version.outputs.checkout_ref }}
uses: actions/checkout@v4
ref: ${{ inputs.tag }}
uses: actions/checkout@v3
- name: Prepare docker files
run: |
cp ./docker/prod/Dockerfile ./Dockerfile
@@ -92,7 +82,6 @@ jobs:
images: |
${{ env.REGISTRY_IMAGE }}
- name: Build image
id: build
uses: docker/build-push-action@v4
with:
context: .
@@ -115,7 +104,7 @@ jobs:
-e SUPERVISORD_LOG_LEVEL=debug \
-e OPENPROJECT_LOGIN__REQUIRED=false \
-e OPENPROJECT_HTTPS=false \
${{ steps.build.outputs.imageid }}
${{ fromJSON(steps.meta.outputs.json).tags[0] }}
sleep 60
+3 -2
View File
@@ -415,9 +415,10 @@ Style/SpecialGlobalVars:
# For the record: using single quotes does NOT have any performance advantages.
# Even if it did, this would be a silly argument.
#
# Quote away.
# Ideally we would just use double quotes everywhere but since that would result
# in innumerable rubocop offenses we will just disable this. Quote away.
Style/StringLiterals:
EnforcedStyle: double_quotes
Enabled: false
Style/TrivialAccessors:
Enabled: false
+169 -168
View File
@@ -26,361 +26,362 @@
# See COPYRIGHT and LICENSE files for more details.
#++
source "https://rubygems.org"
source 'https://rubygems.org'
# TODO: Once packager.io and heroku buildpacks support bundler 2.4.22,
# then we can use the new bundler syntax `ruby file: '.ruby-version'`.
# https://github.com/heroku/heroku-buildpack-ruby/issues/1408#issuecomment-1841596215
ruby File.read(".ruby-version").strip
ruby File.read('.ruby-version').strip
gem "actionpack-xml_parser", "~> 2.0.0"
gem "activemodel-serializers-xml", "~> 1.0.1"
gem "activerecord-import", "~> 1.6.0"
gem "activerecord-session_store", "~> 2.1.0"
gem "ox"
gem "rails", "~> 7.1.3"
gem "responders", "~> 3.0"
gem 'actionpack-xml_parser', '~> 2.0.0'
gem 'activemodel-serializers-xml', '~> 1.0.1'
gem 'activerecord-import', '~> 1.5.0'
gem 'activerecord-session_store', '~> 2.1.0'
gem 'ox'
gem 'rails', '~> 7.1.3'
gem 'responders', '~> 3.0'
gem "ffi", "~> 1.15"
gem 'ffi', '~> 1.15'
gem "rdoc", ">= 2.4.2"
gem 'rdoc', '>= 2.4.2'
gem "doorkeeper", "~> 5.6.6"
gem 'doorkeeper', '~> 5.6.6'
# Maintain our own omniauth due to relative URL root issues
# see upstream PR: https://github.com/omniauth/omniauth/pull/903
gem "omniauth", git: "https://github.com/opf/omniauth", ref: "fe862f986b2e846e291784d2caa3d90a658c67f0"
gem "request_store", "~> 1.6.0"
gem 'omniauth', git: 'https://github.com/opf/omniauth', ref: 'fe862f986b2e846e291784d2caa3d90a658c67f0'
gem 'request_store', '~> 1.6.0'
gem "warden", "~> 1.2"
gem "warden-basic_auth", "~> 0.2.1"
gem 'warden', '~> 1.2'
gem 'warden-basic_auth', '~> 0.2.1'
gem "will_paginate", "~> 4.0.0"
gem 'will_paginate', '~> 4.0.0'
gem "friendly_id", "~> 5.5.0"
gem 'friendly_id', '~> 5.5.0'
gem "acts_as_list", "~> 1.1.0"
gem "acts_as_tree", "~> 2.9.0"
gem "awesome_nested_set", "~> 3.6.0"
gem "closure_tree", "~> 7.4.0"
gem "rubytree", "~> 2.0.0"
gem 'acts_as_list', '~> 1.1.0'
gem 'acts_as_tree', '~> 2.9.0'
gem 'awesome_nested_set', '~> 3.6.0'
gem 'closure_tree', '~> 7.4.0'
gem 'rubytree', '~> 2.0.0'
# Only used in down migrations now.
# Is to be removed once the referencing migrations have been squashed.
gem "typed_dag", "~> 2.0.2", require: false
gem 'typed_dag', '~> 2.0.2', require: false
gem "addressable", "~> 2.8.0"
gem 'addressable', '~> 2.8.0'
# Remove whitespace from model input
gem "auto_strip_attributes", "~> 2.5"
gem 'auto_strip_attributes', '~> 2.5'
# Provide timezone info for TZInfo used by AR
gem "tzinfo-data", "~> 1.2024.1"
gem 'tzinfo-data', '~> 1.2024.1'
# to generate html-diffs (e.g. for wiki comparison)
gem "htmldiff"
gem 'htmldiff'
# Generate url slugs with #to_url and other string niceties
gem "stringex", "~> 2.8.5"
gem 'stringex', '~> 2.8.5'
# CommonMark markdown parser with GFM extension
gem "commonmarker", "~> 1.0.3"
gem 'commonmarker', '~> 1.0.3'
# HTML pipeline for transformations on text formatter output
# such as sanitization or additional features
gem "html-pipeline", "~> 2.14.0"
gem 'html-pipeline', '~> 2.14.0'
# Tasklist parsing and renderer
gem "deckar01-task_list", "~> 2.3.1"
gem 'deckar01-task_list', '~> 2.3.1'
# Requires escape-utils for faster escaping
gem "escape_utils", "~> 1.3"
gem 'escape_utils', '~> 1.3'
# Syntax highlighting used in html-pipeline with rouge
gem "rouge", "~> 4.2.0"
gem 'rouge', '~> 4.2.0'
# HTML sanitization used for html-pipeline
gem "sanitize", "~> 6.1.0"
gem 'sanitize', '~> 6.1.0'
# HTML autolinking for mails and urls (replaces autolink)
gem "rinku", "~> 2.0.4", require: %w[rinku rails_rinku]
gem 'rinku', '~> 2.0.4', require: %w[rinku rails_rinku]
# Version parsing with semver
gem "semantic", "~> 1.6.1"
gem 'semantic', '~> 1.6.1'
# generates SVG Graphs
# used for statistics on svn repositories
gem "svg-graph", "~> 2.2.0"
gem 'svg-graph', '~> 2.2.0'
gem "date_validator", "~> 0.12.0"
gem "email_validator", "~> 2.2.3"
gem "json_schemer", "~> 2.2.0"
gem "ruby-duration", "~> 3.2.0"
gem 'date_validator', '~> 0.12.0'
gem 'email_validator', '~> 2.2.3'
gem 'json_schemer', '~> 2.1.0'
gem 'ruby-duration', '~> 3.2.0'
# `config/initializers/mail_starttls_patch.rb` has also been patched to
# fix STARTTLS handling until https://github.com/mikel/mail/pull/1536 is
# released.
gem "mail", "= 2.8.1"
gem 'mail', '= 2.8.1'
# provide compatible filesystem information for available storage
gem "sys-filesystem", "~> 1.4.0", require: false
gem 'sys-filesystem', '~> 1.4.0', require: false
gem "bcrypt", "~> 3.1.6"
gem 'bcrypt', '~> 3.1.6'
gem "multi_json", "~> 1.15.0"
gem "oj", "~> 3.16.0"
gem 'multi_json', '~> 1.15.0'
gem 'oj', '~> 3.16.0'
gem "daemons"
gem "good_job", "= 3.26.2" # update should be done manually in sync with saas-openproject version.
gem 'daemons'
gem 'delayed_cron_job', '~> 0.9.0'
gem 'delayed_job_active_record', '~> 4.1.5'
gem "rack-protection", "~> 3.2.0"
gem 'rack-protection', '~> 3.2.0'
# Rack::Attack is a rack middleware to protect your web app from bad clients.
# It allows whitelisting, blacklisting, throttling, and tracking based
# on arbitrary properties of the request.
# https://github.com/kickstarter/rack-attack
gem "rack-attack", "~> 6.7.0"
gem 'rack-attack', '~> 6.7.0'
# CSP headers
gem "secure_headers", "~> 6.5.0"
gem 'secure_headers', '~> 6.5.0'
# Browser detection for incompatibility checks
gem "browser", "~> 5.3.0"
gem 'browser', '~> 5.3.0'
# Providing health checks
gem "okcomputer", "~> 1.18.1"
gem 'okcomputer', '~> 1.18.1'
gem "gon", "~> 6.4.0"
gem 'gon', '~> 6.4.0'
# Lograge to provide sane and non-verbose logging
gem "lograge", "~> 0.14.0"
gem 'lograge', '~> 0.14.0'
# Structured warnings to selectively disable them in production
gem "structured_warnings", "~> 0.4.0"
gem 'structured_warnings', '~> 0.4.0'
# catch exceptions and send them to any airbrake compatible backend
# don't require by default, instead load on-demand when actually configured
gem "airbrake", "~> 13.0.0", require: false
gem 'airbrake', '~> 13.0.0', require: false
gem "md_to_pdf", git: "https://github.com/opf/md-to-pdf", ref: "8f14736a88ad0064d2a97be108fe7061ffbcee91"
gem "prawn", "~> 2.4"
gem 'md_to_pdf', git: 'https://github.com/opf/md-to-pdf', ref: '8f14736a88ad0064d2a97be108fe7061ffbcee91'
gem 'prawn', '~> 2.4'
# prawn implicitly depends on matrix gem no longer in ruby core with 3.1
gem "matrix", "~> 0.4.2"
gem 'matrix', '~> 0.4.2'
gem "meta-tags", "~> 2.20.0"
gem 'meta-tags', '~> 2.20.0'
gem "paper_trail", "~> 15.1.0"
gem 'paper_trail', '~> 15.1.0'
gem "clamav-client", github: "honestica/clamav-client", ref: "29e78ae94307cb34e79ddd29c5da79752239d8b7"
gem 'clamav-client', github: 'honestica/clamav-client', ref: '29e78ae94307cb34e79ddd29c5da79752239d8b7'
group :production do
# we use dalli as standard memcache client
# requires memcached 1.4+
gem "dalli", "~> 3.2.0"
gem "redis", "~> 5.1.0"
gem 'dalli', '~> 3.2.0'
gem 'redis', '~> 5.1.0'
end
gem "i18n-js", "~> 4.2.3"
gem "rails-i18n", "~> 7.0.0"
gem 'i18n-js', '~> 4.2.3'
gem 'rails-i18n', '~> 7.0.0'
gem "sprockets", "~> 3.7.2" # lock sprockets below 4.0
gem "sprockets-rails", "~> 3.4.2"
gem 'sprockets', '~> 3.7.2' # lock sprockets below 4.0
gem 'sprockets-rails', '~> 3.4.2'
gem "puma", "~> 6.4"
gem "puma-plugin-statsd", "~> 2.0"
gem "rack-timeout", "~> 0.6.3", require: "rack/timeout/base"
gem 'puma', '~> 6.4'
gem 'puma-plugin-statsd', '~> 2.0'
gem 'rack-timeout', '~> 0.6.3', require: 'rack/timeout/base'
gem "nokogiri", "~> 1.16.0"
gem 'nokogiri', '~> 1.16.0'
gem "carrierwave", "~> 1.3.1"
gem "carrierwave_direct", "~> 2.1.0"
gem "fog-aws"
gem 'carrierwave', '~> 1.3.1'
gem 'carrierwave_direct', '~> 2.1.0'
gem 'fog-aws'
gem "aws-sdk-core", "~> 3.107"
gem 'aws-sdk-core', '~> 3.107'
# File upload via fog + screenshots on travis
gem "aws-sdk-s3", "~> 1.91"
gem 'aws-sdk-s3', '~> 1.91'
gem "openproject-token", "~> 4.0"
gem 'openproject-token', '~> 4.0'
gem "plaintext", "~> 0.3.2"
gem 'plaintext', '~> 0.3.2'
gem "ruby-progressbar", "~> 1.13.0", require: false
gem 'ruby-progressbar', '~> 1.13.0', require: false
gem "mini_magick", "~> 4.12.0", require: false
gem 'mini_magick', '~> 4.12.0', require: false
gem "validate_url"
gem 'validate_url'
# Storages support code
gem "dry-container"
gem 'dry-container'
# ActiveRecord extension which adds typecasting to store accessors
gem "store_attribute", "~> 1.0"
gem 'store_attribute', '~> 1.0'
# Appsignal integration
gem "appsignal", "~> 3.0", require: false
gem 'appsignal', '~> 3.0', require: false
gem "view_component"
gem 'view_component'
# Lookbook
gem "lookbook", "~> 2.2.1"
gem 'lookbook', '~> 2.2.1'
# Require factory_bot for usage with openproject plugins testing
gem "factory_bot", "~> 6.4.0", require: false
gem 'factory_bot', '~> 6.4.0', require: false
# require factory_bot_rails for convenience in core development
gem "factory_bot_rails", "~> 6.4.0", require: false
gem 'factory_bot_rails', '~> 6.4.0', require: false
gem "turbo-rails", "~> 2.0.0"
gem 'turbo-rails', '~> 2.0.0'
gem "httpx"
gem 'httpx'
group :test do
gem "launchy", "~> 3.0.0"
gem "rack-test", "~> 2.1.0"
gem "shoulda-context", "~> 2.0"
gem 'launchy', '~> 3.0.0'
gem 'rack-test', '~> 2.1.0'
gem 'shoulda-context', '~> 2.0'
# Test prof provides factories from code
# and other niceties
gem "test-prof", "~> 1.3.0"
gem "turbo_tests", github: "crohr/turbo_tests", ref: "fix/runtime-info"
gem 'test-prof', '~> 1.3.0'
gem 'turbo_tests', github: 'crohr/turbo_tests', ref: 'fix/runtime-info'
gem "rack_session_access"
gem "rspec", "~> 3.13.0"
gem 'rack_session_access'
gem 'rspec', '~> 3.13.0'
# also add to development group, so 'spec' rake task gets loaded
gem "rspec-rails", "~> 6.1.0", group: :development
gem 'rspec-rails', '~> 6.1.0', group: :development
# Retry failures within the same environment
gem "retriable", "~> 3.1.1"
gem "rspec-retry", "~> 0.6.1"
gem 'retriable', '~> 3.1.1'
gem 'rspec-retry', '~> 0.6.1'
# Accessibility tests
gem "axe-core-rspec"
gem 'axe-core-rspec'
# Modify ENV
gem "climate_control"
gem 'climate_control'
# XML comparison tests
gem "compare-xml", "~> 0.66", require: false
gem 'compare-xml', '~> 0.66', require: false
# PDF Export tests
gem "pdf-inspector", "~> 1.2"
gem 'pdf-inspector', '~> 1.2'
# brings back testing for 'assigns' and 'assert_template' extracted in rails 5
gem "rails-controller-testing", "~> 1.0.2"
gem 'rails-controller-testing', '~> 1.0.2'
gem "capybara", "~> 3.40.0"
gem "capybara_accessible_selectors", git: "https://github.com/citizensadvice/capybara_accessible_selectors", branch: "main"
gem "capybara-screenshot", "~> 1.0.17"
gem "cuprite", "~> 0.15.0"
gem "selenium-devtools"
gem "selenium-webdriver", "~> 4.18.0"
gem 'capybara', '~> 3.40.0'
gem 'capybara_accessible_selectors', git: 'https://github.com/citizensadvice/capybara_accessible_selectors', branch: 'main'
gem 'capybara-screenshot', '~> 1.0.17'
gem 'cuprite', '~> 0.15.0'
gem 'selenium-devtools'
gem 'selenium-webdriver', '~> 4.18.0'
gem "fuubar", "~> 2.5.0"
gem "timecop", "~> 0.9.0"
gem 'fuubar', '~> 2.5.0'
gem 'timecop', '~> 0.9.0'
# Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.
gem "vcr"
gem 'vcr'
# Mock backend requests (for ruby tests)
gem "webmock", "~> 3.12", require: false
gem 'webmock', '~> 3.12', require: false
# Mock selenium requests through proxy (for feature tests)
gem "puffing-billy", "~> 4.0.0"
gem "table_print", "~> 1.5.6"
gem 'puffing-billy', '~> 4.0.0'
gem 'table_print', '~> 1.5.6'
gem "equivalent-xml", "~> 0.6"
gem "json_spec", "~> 1.1.4"
gem "shoulda-matchers", "~> 6.0", require: nil
gem 'equivalent-xml', '~> 0.6'
gem 'json_spec', '~> 1.1.4'
gem 'shoulda-matchers', '~> 6.0', require: nil
gem "parallel_tests", "~> 4.0"
gem 'parallel_tests', '~> 4.0'
end
group :ldap do
gem "net-ldap", "~> 0.19.0"
gem 'net-ldap', '~> 0.19.0'
end
group :development do
gem "listen", "~> 3.9.0" # Use for event-based reloaders
gem 'listen', '~> 3.9.0' # Use for event-based reloaders
gem "letter_opener"
gem 'letter_opener'
gem "spring"
gem "spring-commands-rspec"
gem "spring-commands-rubocop"
gem 'spring'
gem 'spring-commands-rspec'
gem 'spring-commands-rubocop'
gem "colored2"
gem 'colored2'
# git hooks manager
gem "lefthook", require: false
gem 'lefthook', require: false
end
group :development, :test do
gem "dotenv-rails"
gem 'dotenv-rails'
# Tracing and profiling gems
gem "flamegraph", require: false
gem "rack-mini-profiler", require: false
gem "ruby-prof", require: false
gem "stackprof", require: false
gem 'flamegraph', require: false
gem 'rack-mini-profiler', require: false
gem 'ruby-prof', require: false
gem 'stackprof', require: false
# REPL with debug commands
gem "debug"
gem 'debug'
gem "pry-byebug", "~> 3.10.0", platforms: [:mri]
gem "pry-doc"
gem "pry-rails", "~> 0.3.6"
gem "pry-rescue", "~> 1.6.0"
gem 'pry-byebug', '~> 3.10.0', platforms: [:mri]
gem 'pry-doc'
gem 'pry-rails', '~> 0.3.6'
gem 'pry-rescue', '~> 1.6.0'
# ruby linting
gem "rubocop", require: false
gem "rubocop-inflector", require: false
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false
gem "rubocop-rspec", require: false
gem 'rubocop', require: false
gem 'rubocop-inflector', require: false
gem 'rubocop-performance', require: false
gem 'rubocop-rails', require: false
gem 'rubocop-rspec', require: false
# erb linting
gem "erb_lint", require: false
gem "erblint-github", require: false
gem 'erb_lint', require: false
gem 'erblint-github', require: false
# Brakeman scanner
gem "brakeman", "~> 6.1.0"
gem 'brakeman', '~> 6.1.0'
# i18n-tasks helps find and manage missing and unused translations.
gem "i18n-tasks", "~> 1.0.13"
gem 'i18n-tasks', '~> 1.0.13'
end
gem "bootsnap", "~> 1.18.0", require: false
gem 'bootsnap', '~> 1.18.0', require: false
# API gems
gem "grape", "~> 2.0.0"
gem "grape_logging", "~> 1.8.4"
gem "roar", "~> 1.2.0"
gem 'grape', '~> 2.0.0'
gem 'grape_logging', '~> 1.8.4'
gem 'roar', '~> 1.2.0'
# CORS for API
gem "rack-cors", "~> 2.0.2"
gem 'rack-cors', '~> 2.0.2'
# Gmail API
gem "google-apis-gmail_v1", require: false
gem "googleauth", require: false
gem 'google-apis-gmail_v1', require: false
gem 'googleauth', require: false
# Required for contracts
gem "disposable", "~> 0.6.2"
gem 'disposable', '~> 0.6.2'
platforms :mri, :mingw, :x64_mingw do
group :postgres do
gem "pg", "~> 1.5.0"
gem 'pg', '~> 1.5.0'
end
# Support application loading when no database exists yet.
gem "activerecord-nulldb-adapter", "~> 1.0.0"
gem 'activerecord-nulldb-adapter', '~> 1.0.0'
# Have application level locks on the database to have a mutex shared between workers/hosts.
# We e.g. employ this to safeguard the creation of journals.
gem "with_advisory_lock", "~> 5.1.0"
gem 'with_advisory_lock', '~> 5.1.0'
end
# Load Gemfile.modules explicitly to allow dependabot to work
eval_gemfile "./Gemfile.modules"
eval_gemfile './Gemfile.modules'
# Load Gemfile.local, Gemfile.plugins and custom Gemfiles
gemfiles = Dir.glob File.expand_path("{Gemfile.plugins,Gemfile.local}", __dir__)
gemfiles << ENV["CUSTOM_PLUGIN_GEMFILE"] unless ENV["CUSTOM_PLUGIN_GEMFILE"].nil?
gemfiles = Dir.glob File.expand_path('{Gemfile.plugins,Gemfile.local}', __dir__)
gemfiles << ENV['CUSTOM_PLUGIN_GEMFILE'] unless ENV['CUSTOM_PLUGIN_GEMFILE'].nil?
gemfiles.each do |file|
# We use send to allow dependabot to function
# don't use eval_gemfile(file) here as it will break dependabot!
send(:eval_gemfile, file) if File.readable?(file)
end
gem "openproject-octicons", "~>19.8.0"
gem "openproject-octicons_helper", "~>19.8.0"
gem "openproject-primer_view_components", "~>0.23.0"
gem 'openproject-octicons', '~>19.8.0'
gem 'openproject-octicons_helper', '~>19.8.0'
gem 'openproject-primer_view_components', '~>0.23.0'
+46 -47
View File
@@ -299,7 +299,7 @@ GEM
activemodel (= 7.1.3.2)
activesupport (= 7.1.3.2)
timeout (>= 0.4.0)
activerecord-import (1.6.0)
activerecord-import (1.5.1)
activerecord (>= 4.2)
activerecord-nulldb-adapter (1.0.1)
activerecord (>= 5.2.0, < 7.2)
@@ -349,16 +349,16 @@ GEM
activerecord (>= 4.0.0, < 7.2)
awrence (1.2.1)
aws-eventstream (1.3.0)
aws-partitions (1.899.0)
aws-sdk-core (3.191.4)
aws-partitions (1.895.0)
aws-sdk-core (3.191.3)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.78.0)
aws-sdk-kms (1.77.0)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.146.0)
aws-sdk-s3 (1.143.0)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8)
@@ -380,14 +380,14 @@ GEM
thread_safe (~> 0.3, >= 0.3.1)
base64 (0.2.0)
bcrypt (3.1.20)
better_html (2.1.1)
better_html (2.0.2)
actionview (>= 6.0)
activesupport (>= 6.0)
ast (~> 2.0)
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bigdecimal (3.1.7)
bigdecimal (3.1.6)
bindata (2.5.0)
bootsnap (1.18.3)
msgpack (~> 1.2)
@@ -459,6 +459,13 @@ GEM
deckar01-task_list (2.3.4)
html-pipeline (~> 2.0)
declarative (0.0.20)
delayed_cron_job (0.9.0)
fugit (>= 1.5)
delayed_job (4.1.11)
activesupport (>= 3.0, < 8.0)
delayed_job_active_record (4.1.8)
activerecord (>= 3.0, < 8.0)
delayed_job (>= 3.0, < 5)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.5.1)
@@ -514,11 +521,11 @@ GEM
erblint-github (1.0.1)
erubi (1.12.0)
escape_utils (1.3.0)
et-orbi (1.2.9)
et-orbi (1.2.7)
tzinfo
eventmachine (1.2.7)
eventmachine_httpserver (0.2.1)
excon (0.110.0)
excon (0.109.0)
factory_bot (6.4.6)
activesupport (>= 5.0.0)
factory_bot_rails (6.4.3)
@@ -538,7 +545,7 @@ GEM
websocket-driver (>= 0.6, < 0.8)
ffi (1.16.3)
flamegraph (0.9.5)
fog-aws (3.22.0)
fog-aws (3.21.0)
fog-core (~> 2.1)
fog-json (~> 1.1)
fog-xml (~> 0.1)
@@ -557,7 +564,7 @@ GEM
friendly_id (5.5.1)
activerecord (>= 4.0.0)
front_matter_parser (1.0.1)
fugit (1.10.1)
fugit (1.9.0)
et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4)
fuubar (2.5.1)
@@ -571,14 +578,7 @@ GEM
i18n (>= 0.7)
multi_json
request_store (>= 1.0)
good_job (3.26.2)
activejob (>= 6.0.0)
activerecord (>= 6.0.0)
concurrent-ruby (>= 1.0.2)
fugit (>= 1.1)
railties (>= 6.0.0)
thor (>= 0.14.1)
google-apis-core (0.14.1)
google-apis-core (0.14.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 1.9)
httpclient (>= 2.8.1, < 3.a)
@@ -624,7 +624,7 @@ GEM
httpclient (2.8.3)
httpx (1.2.3)
http-2-next (>= 1.0.3)
i18n (1.14.4)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
i18n-js (4.2.3)
glob (>= 0.4.0)
@@ -646,7 +646,7 @@ GEM
ice_nine (0.11.2)
interception (0.5)
io-console (0.7.2)
irb (1.12.0)
irb (1.11.2)
rdoc
reline (>= 0.4.2)
iso8601 (0.13.0)
@@ -659,11 +659,9 @@ GEM
bindata
faraday (~> 2.0)
faraday-follow_redirects
json-schema (4.2.0)
json-schema (4.1.1)
addressable (>= 2.8)
json_schemer (2.2.1)
base64
bigdecimal
json_schemer (2.1.1)
hana (~> 1.3)
regexp_parser (~> 2.0)
simpleidn (~> 0.2)
@@ -678,7 +676,7 @@ GEM
launchy (3.0.0)
addressable (~> 2.8)
childprocess (~> 5.0)
lefthook (1.6.7)
lefthook (1.6.5)
letter_opener (1.0.0)
launchy (>= 2.0.4)
listen (3.9.0)
@@ -696,7 +694,7 @@ GEM
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
lookbook (2.2.2)
lookbook (2.2.1)
activemodel
css_parser
htmlbeautifier (~> 1.3)
@@ -706,7 +704,7 @@ GEM
redcarpet (~> 3.5)
rouge (>= 3.26, < 5.0)
view_component (>= 2.0)
yard (~> 0.9)
yard (~> 0.9.25)
zeitwerk (~> 2.5)
mail (2.8.1)
mini_mime (>= 0.1.1)
@@ -722,11 +720,11 @@ GEM
method_source (1.0.0)
mime-types (3.5.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2024.0305)
mime-types-data (3.2024.0206)
mini_magick (4.12.0)
mini_mime (1.1.5)
mini_portile2 (2.8.5)
minitest (5.22.3)
minitest (5.22.2)
msgpack (1.7.2)
multi_json (1.15.0)
mustermann (3.0.0)
@@ -747,7 +745,7 @@ GEM
net-smtp (0.4.0.1)
net-protocol
nio4r (2.7.0)
nokogiri (1.16.3)
nokogiri (1.16.2)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oj (3.16.3)
@@ -901,7 +899,7 @@ GEM
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
rails-i18n (7.0.9)
rails-i18n (7.0.8)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (7.1.3.2)
@@ -925,7 +923,7 @@ GEM
redcarpet (3.6.0)
redis (5.1.0)
redis-client (>= 0.17.0)
redis-client (0.21.0)
redis-client (0.20.0)
connection_pool
regexp_parser (2.9.0)
reline (0.4.3)
@@ -945,7 +943,7 @@ GEM
roar (1.2.0)
representable (~> 3.1)
rotp (6.3.0)
rouge (4.2.1)
rouge (4.2.0)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
@@ -958,18 +956,18 @@ GEM
rspec-mocks (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (6.1.2)
rspec-rails (6.1.1)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-core (~> 3.12)
rspec-expectations (~> 3.12)
rspec-mocks (~> 3.12)
rspec-support (~> 3.12)
rspec-retry (0.6.2)
rspec-core (> 3.3)
rspec-support (3.13.1)
rubocop (1.62.1)
rubocop (1.62.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
@@ -980,7 +978,7 @@ GEM
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.2)
rubocop-ast (1.31.1)
parser (>= 3.3.0.4)
rubocop-capybara (2.20.0)
rubocop (~> 1.41)
@@ -1032,7 +1030,7 @@ GEM
websocket (~> 1.0)
semantic (1.6.1)
shoulda-context (2.0.0)
shoulda-matchers (6.2.0)
shoulda-matchers (6.1.0)
activesupport (>= 5.2.0)
signet (0.19.0)
addressable (~> 2.8)
@@ -1075,7 +1073,7 @@ GEM
table_print (1.5.7)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
test-prof (1.3.2)
test-prof (1.3.1)
text-hyphen (1.5.0)
thor (1.3.1)
thread_safe (0.3.6)
@@ -1088,7 +1086,7 @@ GEM
trailblazer-option (0.1.2)
ttfunk (1.8.0)
bigdecimal (~> 3.1)
turbo-rails (2.0.5)
turbo-rails (2.0.4)
actionpack (>= 6.0.0)
activejob (>= 6.0.0)
railties (>= 6.0.0)
@@ -1160,7 +1158,7 @@ PLATFORMS
DEPENDENCIES
actionpack-xml_parser (~> 2.0.0)
activemodel-serializers-xml (~> 1.0.1)
activerecord-import (~> 1.6.0)
activerecord-import (~> 1.5.0)
activerecord-nulldb-adapter (~> 1.0.0)
activerecord-session_store (~> 2.1.0)
acts_as_list (~> 1.1.0)
@@ -1197,6 +1195,8 @@ DEPENDENCIES
date_validator (~> 0.12.0)
debug
deckar01-task_list (~> 2.3.1)
delayed_cron_job (~> 0.9.0)
delayed_job_active_record (~> 4.1.5)
disposable (~> 0.6.2)
doorkeeper (~> 5.6.6)
dotenv-rails
@@ -1214,7 +1214,6 @@ DEPENDENCIES
friendly_id (~> 5.5.0)
fuubar (~> 2.5.0)
gon (~> 6.4.0)
good_job (= 3.26.2)
google-apis-gmail_v1
googleauth
grape (~> 2.0.0)
@@ -1225,7 +1224,7 @@ DEPENDENCIES
httpx
i18n-js (~> 4.2.3)
i18n-tasks (~> 1.0.13)
json_schemer (~> 2.2.0)
json_schemer (~> 2.1.0)
json_spec (~> 1.1.4)
ladle
launchy (~> 3.0.0)
+1 -1
View File
@@ -1,3 +1,3 @@
web: bundle exec rails server -p 3000 -b ${HOST:="127.0.0.1"} --environment ${RAILS_ENV:="development"}
angular: npm run serve
worker: bundle exec good_job start
worker: bundle exec rake jobs:work
+1 -1
View File
@@ -2,7 +2,7 @@
![GitHub release (latest by date)](https://img.shields.io/github/v/release/opf/openproject)
![GitHub commit activity](https://img.shields.io/github/commit-activity/m/opf/openproject)
![GitHub branch checks state](https://img.shields.io/github/checks-status/opf/openproject/dev)
[![Github Tests](https://github.com/opf/openproject/actions/workflows/test-core.yml/badge.svg?branch=dev)](https://github.com/opf/openproject/actions/workflows/test-core.yml)
[![GitHub Tests](https://github.com/opf/openproject/actions/workflows/test-core.yml/badge.svg?branch=dev)](https://github.com/opf/openproject/actions/workflows/test-core.yml)
OpenProject is a web-based project management software. Its key features are:
+2 -2
View File
@@ -30,9 +30,9 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path("config/application", __dir__)
require File.expand_path('config/application', __dir__)
Rails.application.load_rake_tasks
Rake::Task[:default].clear
task default: "test:suite:run"
task default: 'test:suite:run'
+1 -1
View File
@@ -29,7 +29,7 @@
#++
class Activities::DaysComponent < ViewComponent::Base
def initialize(events:, current_project: nil, display_user: true, header_tag: "h3", activity_page: nil)
def initialize(events:, current_project: nil, display_user: true, header_tag: 'h3', activity_page: nil)
super()
@events = events
@current_project = current_project
+5 -5
View File
@@ -33,7 +33,7 @@ class AddButtonComponent < ApplicationComponent
options :current_project
def render?
raise "Implement the conditions for which the component should render or not"
raise 'Implement the conditions for which the component should render or not'
end
def dynamic_path
@@ -45,7 +45,7 @@ class AddButtonComponent < ApplicationComponent
end
def li_css_class
"toolbar-item"
'toolbar-item'
end
def title
@@ -55,7 +55,7 @@ class AddButtonComponent < ApplicationComponent
def label
content_tag(:span,
label_text,
class: "button--text")
class: 'button--text')
end
def aria_label
@@ -71,10 +71,10 @@ class AddButtonComponent < ApplicationComponent
end
def link_css_class
"button -primary"
'button -alt-highlight'
end
def icon
helpers.op_icon("button--icon icon-add")
helpers.op_icon('button--icon icon-add')
end
end
@@ -45,7 +45,7 @@ module Admin
delegate :filename, to: :attachment
def attached_to
description = attachment.description.present? ? "(#{attachment.description})" : ""
description = attachment.description.present? ? "(#{attachment.description})" : ''
text = "#{container_name} #{attachment.container_id} #{description}"
case container
when Message
@@ -83,9 +83,9 @@ module Admin
def delete_link
helpers.link_to(
helpers.op_icon("icon icon-delete"),
{ controller: "/admin/attachments/quarantined_attachments", action: :destroy, id: model },
title: I18n.t("antivirus_scan.quarantined_attachments.delete"),
helpers.op_icon('icon icon-delete'),
{ controller: '/admin/attachments/quarantined_attachments', action: :destroy, id: model },
title: I18n.t('antivirus_scan.quarantined_attachments.delete'),
method: :delete,
data: { confirm: I18n.t(:text_are_you_sure), disable_with: I18n.t(:label_loading) }
)
@@ -44,10 +44,10 @@ module Admin
def headers
[
["filename", { caption: Attachment.human_attribute_name(:filename) }],
["attached_to", { caption: I18n.t("antivirus_scan.quarantined_attachments.container") }],
["author", { caption: Attachment.human_attribute_name(:author) }],
["created_at", { caption: Attachment.human_attribute_name(:created_at) }]
['filename', { caption: Attachment.human_attribute_name(:filename) }],
['attached_to', { caption: I18n.t('antivirus_scan.quarantined_attachments.container') }],
['author', { caption: Attachment.human_attribute_name(:author) }],
['created_at', { caption: Attachment.human_attribute_name(:created_at) }]
]
end
end
@@ -41,7 +41,7 @@ module CustomActions
delegate :description, to: :action
def sort
helpers.reorder_links("custom_action", { action: "update", id: action }, method: :put)
helpers.reorder_links('custom_action', { action: 'update', id: action }, method: :put)
end
def button_links
@@ -53,7 +53,7 @@ module CustomActions
def edit_link
link_to(
helpers.op_icon("icon icon-edit"),
helpers.op_icon('icon icon-edit'),
helpers.edit_custom_action_path(action),
title: t(:button_edit)
)
@@ -61,7 +61,7 @@ module CustomActions
def delete_link
link_to(
helpers.op_icon("icon icon-delete"),
helpers.op_icon('icon icon-delete'),
helpers.custom_action_path(action),
method: :delete,
data: { confirm: I18n.t(:text_are_you_sure) },
@@ -36,18 +36,18 @@ module CustomActions
def headers
[
["name", { caption: CustomAction.human_attribute_name(:name) }],
["description", { caption: CustomAction.human_attribute_name(:description) }],
["sort", { caption: I18n.t(:label_sort) }]
['name', { caption: CustomAction.human_attribute_name(:name) }],
['description', { caption: CustomAction.human_attribute_name(:description) }],
['sort', { caption: I18n.t(:label_sort) }]
]
end
def inline_create_link
link_to new_custom_action_path,
aria: { label: t("custom_actions.new") },
class: "wp-inline-create--add-link",
title: t("custom_actions.new") do
helpers.op_icon("icon icon-add")
aria: { label: t('custom_actions.new') },
class: 'wp-inline-create--add-link',
title: t('custom_actions.new') do
helpers.op_icon('icon icon-add')
end
end
end
+2 -2
View File
@@ -51,7 +51,7 @@ module Enumerations
end
def sort
helpers.reorder_links("enumeration", { action: "move", id: enumeration }, method: :post)
helpers.reorder_links('enumeration', { action: 'move', id: enumeration }, method: :post)
end
def button_links
@@ -62,7 +62,7 @@ module Enumerations
def delete_link
helpers.link_to(
helpers.op_icon("icon icon-delete"),
helpers.op_icon('icon icon-delete'),
helpers.enumeration_path(enumeration),
method: :delete,
data: { confirm: I18n.t(:text_are_you_sure) },
@@ -44,13 +44,13 @@ module Enumerations
def headers
[
["name", { caption: Enumeration.human_attribute_name(:name) }],
["is_default", { caption: Enumeration.human_attribute_name(:is_default) }],
["active", { caption: Enumeration.human_attribute_name(:active) }],
["sort", { caption: I18n.t(:label_sort) }]
['name', { caption: Enumeration.human_attribute_name(:name) }],
['is_default', { caption: Enumeration.human_attribute_name(:is_default) }],
['active', { caption: Enumeration.human_attribute_name(:active) }],
['sort', { caption: I18n.t(:label_sort) }]
].tap do |default|
if with_colors
default.insert 3, ["color", { caption: Enumeration.human_attribute_name(:color) }]
default.insert 3, ['color', { caption: Enumeration.human_attribute_name(:color) }]
end
end
end
@@ -62,10 +62,10 @@ module Enumerations
def inline_create_link
link_to new_enumeration_path(type: rows.name),
aria: { label: t(:label_enumeration_new) },
class: "wp-inline-create--add-link",
data: { "test-selector": "create-enumeration-#{rows.name.underscore.dasherize}" },
class: 'wp-inline-create--add-link',
data: { 'test-selector': "create-enumeration-#{rows.name.underscore.dasherize}" },
title: t(:label_enumeration_new) do
helpers.op_icon("icon icon-add")
helpers.op_icon('icon icon-add')
end
end
end
+1 -1
View File
@@ -123,7 +123,7 @@
</div>
</li>
<li class="advanced-filters--controls">
<%= submit_tag t('button_apply'), class: 'button -small -primary', name: nil %>
<%= submit_tag t('button_apply'), class: 'button -small -highlight', name: nil %>
</li>
</ul>
<% unless EnterpriseToken.allows_to?(:custom_fields_in_projects_list)%>
@@ -105,7 +105,7 @@ See COPYRIGHT and LICENSE files for more details.
<%= text_field_tag 'name', params[:name], class: 'simple-filters--filter-value' %>
</li>
<li class="simple-filters--controls">
<%= submit_tag t(:button_apply), class: 'button -primary -small', name: nil %>
<%= submit_tag t(:button_apply), class: 'button -highlight -small', name: nil %>
<%= link_to t(:button_clear), clear_url, class: 'button -small -with-icon icon-undo' %>
</li>
</ul>
@@ -52,25 +52,25 @@ class IndividualPrincipalBaseFilterComponent < ApplicationComponent
def filter_name(query, name)
if name.present?
query.where(:any_name_attribute, "~", name)
query.where(:any_name_attribute, '~', name)
end
end
def filter_group(query, group_id)
if group_id.present?
query.where(:group, "=", group_id)
query.where(:group, '=', group_id)
end
end
def filter_role(query, role_id)
if role_id.present?
query.where(:role_id, "=", role_id)
query.where(:role_id, '=', role_id)
end
end
def filter_project(query, project_id)
if project_id.present?
query.where(:project_id, "=", project_id)
query.where(:project_id, '=', project_id)
end
end
@@ -33,7 +33,7 @@ module LdapAuthSources
def name
content = link_to model.name, edit_ldap_auth_source_path(model)
if model.seeded_from_env?
content += helpers.op_icon("icon icon-info2", title: I18n.t(:label_seeded_from_env_warning))
content += helpers.op_icon('icon icon-info2', title: I18n.t(:label_seeded_from_env_warning))
end
content
@@ -54,17 +54,17 @@ module LdapAuthSources
end
def test_link
link_to t(:button_test), { controller: "ldap_auth_sources", action: "test_connection", id: model }
link_to t(:button_test), { controller: 'ldap_auth_sources', action: 'test_connection', id: model }
end
def delete_link
return if users > 0
link_to I18n.t(:button_delete),
{ controller: "ldap_auth_sources", id: model.id, action: :destroy },
{ controller: 'ldap_auth_sources', id: model.id, action: :destroy },
method: :delete,
data: { confirm: I18n.t(:text_are_you_sure) },
class: "icon icon-delete",
class: 'icon icon-delete',
title: I18n.t(:button_delete)
end
end
@@ -46,17 +46,17 @@ module LdapAuthSources
def inline_create_link
link_to(new_ldap_auth_source_path,
class: "budget-add-row wp-inline-create--add-link",
class: 'budget-add-row wp-inline-create--add-link',
title: I18n.t(:label_ldap_auth_source_new)) do
helpers.op_icon("icon icon-add")
helpers.op_icon('icon icon-add')
end
end
def headers
[
["name", { caption: LdapAuthSource.human_attribute_name("name") }],
["host", { caption: LdapAuthSource.human_attribute_name("host") }],
["users", { caption: I18n.t(:label_user_plural) }]
['name', { caption: LdapAuthSource.human_attribute_name('name') }],
['host', { caption: LdapAuthSource.human_attribute_name('host') }],
['users', { caption: I18n.t(:label_user_plural) }]
]
end
end
@@ -41,20 +41,20 @@ class Members::IndexPageHeaderComponent < ApplicationComponent
def add_button_data_attributes
attributes = {
"members-form-target": "addMemberButton",
action: "members-form#showAddMemberForm",
"test-selector": "member-add-button"
'members-form-target': 'addMemberButton',
action: 'members-form#showAddMemberForm',
'test-selector': 'member-add-button'
}
attributes["trigger-initially"] = "true" if params[:show_add_members]
attributes['trigger-initially'] = "true" if params[:show_add_members]
attributes
end
def filter_button_data_attributes
{
"members-form-target": "filterMemberButton",
action: "members-form#toggleMemberFilter"
'members-form-target': 'filterMemberButton',
action: 'members-form#toggleMemberFilter'
}
end
end
@@ -48,7 +48,7 @@ See COPYRIGHT and LICENSE files for more details.
</p>
<p>
<%= f.submit t(:button_change), class: "button -primary -small" %>
<%= f.submit t(:button_change), class: "button -highlight -small" %>
<%= link_to t(:button_cancel),
'#',
data: {
@@ -41,7 +41,7 @@ module Members
id: "#{row.roles_css_id}-form",
class: row.toggle_item_class_name,
style: "display:none",
data: { "members-form-target": "membershipEditForm" }
data: { 'members-form-target': 'membershipEditForm' }
}
end
+13 -13
View File
@@ -30,7 +30,7 @@
module Members
class UserFilterComponent < ::UserFilterComponent
ALL_SHARED_FILTER_KEY = "all"
ALL_SHARED_FILTER_KEY = 'all'
def initially_visible?
false
@@ -52,12 +52,12 @@ module Members
# Adapts the user filter counts to count members as opposed to users.
def extra_user_status_options
{
all: status_members_query("all").count,
blocked: status_members_query("blocked").count,
active: status_members_query("active").count,
invited: status_members_query("invited").count,
registered: status_members_query("registered").count,
locked: status_members_query("locked").count
all: status_members_query('all').count,
blocked: status_members_query('blocked').count,
active: status_members_query('active').count,
invited: status_members_query('invited').count,
registered: status_members_query('registered').count,
locked: status_members_query('locked').count
}
end
@@ -89,7 +89,7 @@ module Members
.order(builtin: :asc)
.map { |role| [mapped_shared_role_name(role), role.id] }
share_options.unshift([I18n.t("members.filters.all_shares"), ALL_SHARED_FILTER_KEY])
share_options.unshift([I18n.t('members.filters.all_shares'), ALL_SHARED_FILTER_KEY])
end
def builtin_share_roles
@@ -103,11 +103,11 @@ module Members
def mapped_shared_role_name(role)
case role.builtin
when Role::BUILTIN_WORK_PACKAGE_VIEWER
I18n.t("work_package.sharing.permissions.view")
I18n.t('work_package.sharing.permissions.view')
when Role::BUILTIN_WORK_PACKAGE_COMMENTER
I18n.t("work_package.sharing.permissions.comment")
I18n.t('work_package.sharing.permissions.comment')
when Role::BUILTIN_WORK_PACKAGE_EDITOR
I18n.t("work_package.sharing.permissions.edit")
I18n.t('work_package.sharing.permissions.edit')
else
role.name
end
@@ -121,9 +121,9 @@ module Members
.where(builtin: builtin_share_roles)
.pluck(:id)
query.where(:role_id, "=", ids.uniq)
query.where(:role_id, '=', ids.uniq)
elsif role_id.to_i > 0
query.where(:role_id, "=", role_id.to_i)
query.where(:role_id, '=', role_id.to_i)
end
end
@@ -47,20 +47,20 @@ module OAuth
def confidential
if application.confidential?
helpers.op_icon "icon icon-checkmark"
helpers.op_icon 'icon icon-checkmark'
end
end
def redirect_uri
urls = application.redirect_uri.split("\n")
safe_join urls, "<br/>".html_safe
safe_join urls, '<br/>'.html_safe
end
def client_credentials
if user_id = application.client_credentials_user_id
helpers.link_to_user User.find(user_id)
else
"-"
'-'
end
end
@@ -51,10 +51,10 @@ module OAuth
def inline_create_link
link_to new_oauth_application_path,
aria: { label: t("oauth.application.new") },
class: "wp-inline-create--add-link",
title: t("oauth.application.new") do
helpers.op_icon("icon icon-add")
aria: { label: t('oauth.application.new') },
class: 'wp-inline-create--add-link',
title: t('oauth.application.new') do
helpers.op_icon('icon icon-add')
end
end
@@ -64,11 +64,11 @@ module OAuth
def headers
[
["name", { caption: ::Doorkeeper::Application.human_attribute_name(:name) }],
["owner", { caption: ::Doorkeeper::Application.human_attribute_name(:owner) }],
["client_credentials", { caption: I18n.t("oauth.client_credentials") }],
["redirect_uri", { caption: ::Doorkeeper::Application.human_attribute_name(:redirect_uri) }],
["confidential", { caption: ::Doorkeeper::Application.human_attribute_name(:confidential) }]
['name', { caption: ::Doorkeeper::Application.human_attribute_name(:name) }],
['owner', { caption: ::Doorkeeper::Application.human_attribute_name(:owner) }],
['client_credentials', { caption: I18n.t('oauth.client_credentials') }],
['redirect_uri', { caption: ::Doorkeeper::Application.human_attribute_name(:redirect_uri) }],
['confidential', { caption: ::Doorkeeper::Application.human_attribute_name(:confidential) }]
]
end
end
@@ -32,7 +32,7 @@ module OpenProject
VALID_TYPES = %i[seconds minutes hours days weeks months years].freeze
attr_reader :duration, :abbreviated, :separator
def initialize(duration, type = :seconds, separator: ", ", abbreviated: false, **args)
def initialize(duration, type = :seconds, separator: ', ', abbreviated: false, **args)
super
@duration = parse_duration(duration, type)
@@ -40,7 +40,7 @@ module PlaceholderUsers
# Filter for active placeholders
# to skip to-be-deleted users
query.where(:status, "=", :active)
query.where(:status, '=', :active)
end
end
@@ -47,10 +47,10 @@ module PlaceholderUsers
def delete_link
if helpers.can_delete_placeholder_user?(placeholder_user, User.current)
link_to deletion_info_placeholder_user_path(placeholder_user) do
helpers.tooltip_tag I18n.t("placeholder_users.delete_tooltip"), icon: "icon-delete"
helpers.tooltip_tag I18n.t('placeholder_users.delete_tooltip'), icon: 'icon-delete'
end
else
helpers.tooltip_tag I18n.t("placeholder_users.right_to_manage_members_missing"), icon: "icon-help2"
helpers.tooltip_tag I18n.t('placeholder_users.right_to_manage_members_missing'), icon: 'icon-help2'
end
end
@@ -43,7 +43,7 @@ module PlaceholderUsers
def header_options(name)
options = { caption: PlaceholderUser.human_attribute_name(name) }
options[:default_order] = "desc" if desc_by_default.include? name
options[:default_order] = 'desc' if desc_by_default.include? name
options
end
@@ -29,9 +29,9 @@
# ++
class Projects::ConfigureViewModalComponent < ApplicationComponent
MODAL_ID = "op-project-list-configure-dialog"
COLUMN_FORM_ID = "op-project-list-configure-columns-form"
COLUMN_HTML_NAME = "columns"
MODAL_ID = 'op-project-list-configure-dialog'
COLUMN_FORM_ID = 'op-project-list-configure-columns-form'
COLUMN_HTML_NAME = 'columns'
options :query
@@ -29,7 +29,7 @@
# ++
class Projects::DeleteListModalComponent < ApplicationComponent # rubocop:disable OpenProject/AddPreviewForViewComponent
MODAL_ID = "op-project-list-delete-dialog"
MODAL_ID = 'op-project-list-delete-dialog'
options :query
end
@@ -29,7 +29,7 @@
# ++
class Projects::ExportListModalComponent < ApplicationComponent # rubocop:disable OpenProject/AddPreviewForViewComponent
MODAL_ID = "op-project-list-export-dialog"
MODAL_ID = 'op-project-list-export-dialog'
options :query
end
+27 -27
View File
@@ -39,7 +39,7 @@ module Projects
# Hierarchy cell is just a placeholder
def hierarchy
""
''
end
def column_value(column)
@@ -56,10 +56,10 @@ module Projects
cf = column.custom_field
custom_value = project.formatted_custom_value_for(cf)
if cf.field_format == "text" && custom_value.present?
if cf.field_format == 'text' && custom_value.present?
render OpenProject::Common::AttributeComponent.new("dialog-#{project.id}-cf-#{cf.id}", cf.name, custom_value.html_safe) # rubocop:disable Rails/OutputSafety
elsif custom_value.is_a?(Array)
safe_join(Array(custom_value).compact_blank, ", ")
safe_join(Array(custom_value).compact_blank, ', ')
else
custom_value
end
@@ -74,20 +74,20 @@ module Projects
end
def required_disk_space
return "" unless project.required_disk_space.to_i > 0
return '' unless project.required_disk_space.to_i > 0
number_to_human_size(project.required_disk_space, precision: 2)
end
def name
content = content_tag(:i, "", class: "projects-table--hierarchy-icon")
content = content_tag(:i, '', class: "projects-table--hierarchy-icon")
if project.archived?
content << " "
content << content_tag(:span, I18n.t("project.archive.archived"), class: "archived-label")
content << ' '
content << content_tag(:span, I18n.t('project.archive.archived'), class: 'archived-label')
end
content << " "
content << ' '
content << helpers.link_to_project(project, {}, {}, false)
content
end
@@ -95,13 +95,13 @@ module Projects
def project_status
return nil unless user_can_view_project?
content = "".html_safe
content = ''.html_safe
status_code = project.status_code
if status_code
classes = helpers.project_status_css_class(status_code)
content << content_tag(:span, "", class: "project-status--bulb -inline #{classes}")
content << content_tag(:span, '', class: "project-status--bulb -inline #{classes}")
content << content_tag(:span, helpers.project_status_name(status_code), class: "project-status--name #{classes}")
end
@@ -113,7 +113,7 @@ module Projects
if project.status_explanation.present? && project.status_explanation
render OpenProject::Common::AttributeComponent.new("dialog-#{project.id}-status-explanation",
I18n.t("activerecord.attributes.project.status_explanation"),
I18n.t('activerecord.attributes.project.status_explanation'),
project.status_explanation)
end
end
@@ -123,7 +123,7 @@ module Projects
if project.description.present?
render OpenProject::Common::AttributeComponent.new("dialog-#{project.id}-description",
I18n.t("activerecord.attributes.project.description"),
I18n.t('activerecord.attributes.project.description'),
project.description)
end
end
@@ -149,11 +149,11 @@ module Projects
end
def project_css_classes
s = " project ".html_safe
s = ' project '.html_safe
s << " root" if project.root?
s << " child" if project.child?
s << (project.leaf? ? " leaf" : " parent")
s << ' root' if project.root?
s << ' child' if project.child?
s << (project.leaf? ? ' leaf' : ' parent')
s
end
@@ -169,7 +169,7 @@ module Projects
"project-long-text-container"
elsif custom_field_column?(column)
cf = column.custom_field
formattable = cf.field_format == "text" ? " project-long-text-container" : ""
formattable = cf.field_format == 'text' ? ' project-long-text-container' : ''
"format-#{cf.field_format}#{formattable}"
end
end
@@ -188,17 +188,17 @@ module Projects
if User.current.allowed_in_project?(:add_subprojects, project)
[t(:label_subproject_new),
new_project_path(parent_id: project.id),
{ class: "icon-context icon-add",
{ class: 'icon-context icon-add',
title: t(:label_subproject_new) }]
end
end
def more_menu_settings_item
if User.current.allowed_in_project?({ controller: "/projects/settings/general", action: "show", project_id: project.id },
if User.current.allowed_in_project?({ controller: '/projects/settings/general', action: 'show', project_id: project.id },
project)
[t(:label_project_settings),
project_settings_general_path(project),
{ class: "icon-context icon-settings",
{ class: 'icon-context icon-settings',
title: t(:label_project_settings) }]
end
end
@@ -207,8 +207,8 @@ module Projects
if User.current.allowed_in_project?(:view_project_activity, project)
[
t(:label_project_activity),
project_activity_index_path(project, event_types: ["project_attributes"]),
{ class: "icon-context icon-checkmark",
project_activity_index_path(project, event_types: ['project_attributes']),
{ class: 'icon-context icon-checkmark',
title: t(:label_project_activity) }
]
end
@@ -218,9 +218,9 @@ module Projects
if User.current.allowed_in_project?(:archive_project, project) && project.active?
[t(:button_archive),
project_archive_path(project, status: params[:status]),
{ data: { confirm: t("project.archive.are_you_sure", name: project.name) },
{ data: { confirm: t('project.archive.are_you_sure', name: project.name) },
method: :post,
class: "icon-context icon-locked",
class: 'icon-context icon-locked',
title: t(:button_archive) }]
end
end
@@ -230,7 +230,7 @@ module Projects
[t(:button_unarchive),
project_archive_path(project, status: params[:status]),
{ method: :delete,
class: "icon-context icon-unlocked",
class: 'icon-context icon-unlocked',
title: t(:button_unarchive) }]
end
end
@@ -239,7 +239,7 @@ module Projects
if User.current.allowed_in_project?(:copy_projects, project) && !project.archived?
[t(:button_copy),
copy_project_path(project),
{ class: "icon-context icon-copy",
{ class: 'icon-context icon-copy',
title: t(:button_copy) }]
end
end
@@ -248,7 +248,7 @@ module Projects
if User.current.admin
[t(:button_delete),
confirm_destroy_project_path(project),
{ class: "icon-context icon-delete",
{ class: 'icon-context icon-delete',
title: t(:button_delete) }]
end
end
+6 -6
View File
@@ -48,7 +48,7 @@ module Projects
end
def table_id
"project-table"
'project-table'
end
##
@@ -80,13 +80,13 @@ module Projects
def deactivate_class_on_lft_sort
if sorted_by_lft?
"spot-link_inactive"
'spot-link_inactive'
end
end
def href_only_when_not_sort_lft
unless sorted_by_lft?
projects_path(sortBy: JSON::dump([["lft", "asc"]]))
projects_path(sortBy: JSON::dump([['lft', 'asc']]))
end
end
@@ -96,9 +96,9 @@ module Projects
data:
{
controller: "params-from-query",
"application-target": "dynamic",
"params-from-query-allowed-value": '["query_id"]',
"params-from-query-all-anchors-value": "true"
'application-target': "dynamic",
'params-from-query-allowed-value': '["query_id"]',
'params-from-query-all-anchors-value': "true"
}
}
end
+1 -1
View File
@@ -70,7 +70,7 @@ class RowComponent < ApplicationComponent
def checkmark(condition)
if condition
helpers.op_icon "icon icon-checkmark"
helpers.op_icon 'icon icon-checkmark'
end
end
end
@@ -79,7 +79,7 @@ module Settings
private
def time_zone_option(canonical_zone, zones)
zone_names = zones.map(&:name).join(", ")
zone_names = zones.map(&:name).join(', ')
[
"(UTC#{ActiveSupport::TimeZone.seconds_to_utc_offset(canonical_zone.base_utc_offset)}) #{zone_names}",
canonical_zone.identifier
+3 -3
View File
@@ -59,8 +59,8 @@ module Statuses
end
def sort
helpers.reorder_links "status",
{ action: "update", id: status },
helpers.reorder_links 'status',
{ action: 'update', id: status },
method: :patch
end
@@ -72,7 +72,7 @@ module Statuses
def delete_link
link_to(
helpers.op_icon("icon icon-delete"),
helpers.op_icon('icon icon-delete'),
status_path(status),
method: :delete,
data: { confirm: I18n.t(:text_are_you_sure) },
+2 -2
View File
@@ -45,9 +45,9 @@ module Statuses
def inline_create_link
link_to new_status_path,
aria: { label: t(:label_work_package_status_new) },
class: "wp-inline-create--add-link",
class: 'wp-inline-create--add-link',
title: t(:label_work_package_status_new) do
helpers.op_icon("icon icon-add")
helpers.op_icon('icon icon-add')
end
end
+1 -1
View File
@@ -174,7 +174,7 @@ class TableComponent < ApplicationComponent
end
def initial_order
initial_sort_correlation.join(" ")
initial_sort_correlation.join(' ')
end
def paginated?
+8 -8
View File
@@ -35,20 +35,20 @@ class UserFilterComponent < IndividualPrincipalBaseFilterComponent
# or the default status to be filtered by (all)
# if no status is given.
def status_param(params)
params[:status].presence || "all"
params[:status].presence || 'all'
end
def filter_status(query, status)
return unless status && status != "all"
return unless status && status != 'all'
case status
when "blocked"
query.where(:blocked, "=", :blocked)
when "active"
query.where(:status, "=", status.to_sym)
query.where(:blocked, "!", :blocked)
when 'blocked'
query.where(:blocked, '=', :blocked)
when 'active'
query.where(:status, '=', status.to_sym)
query.where(:blocked, '!', :blocked)
else
query.where(:status, "=", status.to_sym)
query.where(:status, '=', status.to_sym)
end
end
@@ -45,22 +45,22 @@ module Users
def is_current # rubocop:disable Naming/PredicateName
if current?
helpers.op_icon "icon-yes"
helpers.op_icon 'icon-yes'
end
end
def device
token_data[:platform] || I18n.t("users.sessions.unknown_os")
token_data[:platform] || I18n.t('users.sessions.unknown_os')
end
def browser
name = token_data[:browser] || "unknown browser"
name = token_data[:browser] || 'unknown browser'
version = token_data[:browser_version]
"#{name} #{version ? "(Version #{version})" : ''}"
end
def platform
token_data[:platform] || "unknown platform"
token_data[:platform] || 'unknown platform'
end
def expires_on
@@ -76,9 +76,9 @@ module Users
return if current?
link_to(
helpers.op_icon("icon icon-delete"),
{ controller: "/my/auto_login_tokens", action: "destroy", id: token.id },
class: "button--link",
helpers.op_icon('icon icon-delete'),
{ controller: '/my/auto_login_tokens', action: 'destroy', id: token.id },
class: 'button--link',
role: :button,
method: :delete,
data: { confirm: I18n.t(:text_are_you_sure), disable_with: I18n.t(:label_loading) },
@@ -41,10 +41,10 @@ module Users
def headers
[
[:is_current, { caption: I18n.t("users.sessions.current") }],
[:browser, { caption: I18n.t("users.sessions.browser") }],
[:device, { caption: I18n.t("users.sessions.device") }],
[:expires_on, { caption: I18n.t("attributes.expires_at") }]
[:is_current, { caption: I18n.t('users.sessions.current') }],
[:browser, { caption: I18n.t('users.sessions.browser') }],
[:device, { caption: I18n.t('users.sessions.device') }],
[:expires_on, { caption: I18n.t('attributes.expires_at') }]
]
end
end
+1 -1
View File
@@ -32,7 +32,7 @@ module Users
include AvatarHelper
include OpPrimer::ComponentHelpers
def initialize(user:, show_name: true, link: true, size: "default", classes: "", title: nil, name_classes: "")
def initialize(user:, show_name: true, link: true, size: 'default', classes: '', title: nil, name_classes: '')
super
@user = user
@@ -48,27 +48,27 @@ module Users
def is_current # rubocop:disable Naming/PredicateName
if current?
helpers.op_icon "icon-yes"
helpers.op_icon 'icon-yes'
end
end
def device
session_data[:platform] || I18n.t("users.sessions.unknown_os")
session_data[:platform] || I18n.t('users.sessions.unknown_os')
end
def browser
name = session_data[:browser] || "unknown browser"
name = session_data[:browser] || 'unknown browser'
version = session_data[:browser_version]
"#{name} #{version ? "(Version #{version})" : ''}"
end
def platform
session_data[:platform] || "unknown platform"
session_data[:platform] || 'unknown platform'
end
def updated_at
if current?
I18n.t("users.sessions.current")
I18n.t('users.sessions.current')
else
helpers.format_time session.updated_at
end
@@ -82,9 +82,9 @@ module Users
return if current?
link_to(
helpers.op_icon("icon icon-delete"),
{ controller: "/my/sessions", action: "destroy", id: session },
class: "button--link",
helpers.op_icon('icon icon-delete'),
{ controller: '/my/sessions', action: 'destroy', id: session },
class: 'button--link',
role: :button,
method: :delete,
data: { confirm: I18n.t(:text_are_you_sure), disable_with: I18n.t(:label_loading) },
@@ -41,10 +41,10 @@ module Users
def headers
[
[:is_current, { caption: I18n.t("users.sessions.current") }],
[:browser, { caption: I18n.t("users.sessions.browser") }],
[:device, { caption: I18n.t("users.sessions.device") }],
[:updated_at, { caption: I18n.t("attributes.updated_at") }]
[:is_current, { caption: I18n.t('users.sessions.current') }],
[:browser, { caption: I18n.t('users.sessions.browser') }],
[:device, { caption: I18n.t('users.sessions.device') }],
[:updated_at, { caption: I18n.t('attributes.updated_at') }]
]
end
end
+1 -1
View File
@@ -46,7 +46,7 @@ module Users
def header_options(name)
options = { caption: User.human_attribute_name(name) }
options[:default_order] = "desc" if desc_by_default.include? name
options[:default_order] = 'desc' if desc_by_default.include? name
options
end
+9 -9
View File
@@ -75,11 +75,11 @@ module Versions
end
def wiki_page
return "" if wiki_page_title.blank? || version.project.wiki.nil?
return '' if wiki_page_title.blank? || version.project.wiki.nil?
helpers.link_to_if_authorized(wiki_page_title,
controller: "/wiki",
action: "show",
controller: '/wiki',
action: 'show',
project_id: version.project,
id: wiki_page_title) || h(wiki_page_title)
end
@@ -97,20 +97,20 @@ module Versions
def edit_link
return unless version.project == table.project
helpers.link_to_if_authorized "",
{ controller: "/versions", action: "edit", id: version },
class: "icon icon-edit",
helpers.link_to_if_authorized '',
{ controller: '/versions', action: 'edit', id: version },
class: 'icon icon-edit',
title: t(:button_edit)
end
def delete_link
return unless version.project == table.project
helpers.link_to_if_authorized "",
{ controller: "/versions", action: "destroy", id: version },
helpers.link_to_if_authorized '',
{ controller: '/versions', action: 'destroy', id: version },
data: { confirm: t(:text_are_you_sure) },
method: :delete,
class: "icon icon-delete",
class: 'icon icon-delete',
title: t(:button_delete)
end
+1 -1
View File
@@ -49,7 +49,7 @@ module Versions
end
def wiki_page_header_options
["wiki_page_title", { caption: WikiPage.model_name.human }]
['wiki_page_title', { caption: WikiPage.model_name.human }]
end
end
end
@@ -34,15 +34,15 @@ module WorkPackages
module DisplayableRoles
def options
[
{ label: I18n.t("work_package.sharing.permissions.edit"),
{ label: I18n.t('work_package.sharing.permissions.edit'),
value: Role::BUILTIN_WORK_PACKAGE_EDITOR,
description: I18n.t("work_package.sharing.permissions.edit_description") },
{ label: I18n.t("work_package.sharing.permissions.comment"),
description: I18n.t('work_package.sharing.permissions.edit_description') },
{ label: I18n.t('work_package.sharing.permissions.comment'),
value: Role::BUILTIN_WORK_PACKAGE_COMMENTER,
description: I18n.t("work_package.sharing.permissions.comment_description") },
{ label: I18n.t("work_package.sharing.permissions.view"),
description: I18n.t('work_package.sharing.permissions.comment_description') },
{ label: I18n.t('work_package.sharing.permissions.view'),
value: Role::BUILTIN_WORK_PACKAGE_VIEWER,
description: I18n.t("work_package.sharing.permissions.view_description") }
description: I18n.t('work_package.sharing.permissions.view_description') }
]
end
end
@@ -55,39 +55,39 @@ module WorkPackages
end
def insert_target_modifier_id
"op-share-wp-active-shares"
'op-share-wp-active-shares'
end
def blankslate_config
@blankslate_config ||= {}.tap do |config|
if params[:filters].blank?
config[:icon] = :people
config[:heading_text] = I18n.t("work_package.sharing.text_empty_state_header")
config[:description_text] = I18n.t("work_package.sharing.text_empty_state_description")
config[:heading_text] = I18n.t('work_package.sharing.text_empty_state_header')
config[:description_text] = I18n.t('work_package.sharing.text_empty_state_description')
else
config[:icon] = :search
config[:heading_text] = I18n.t("work_package.sharing.text_empty_search_header")
config[:description_text] = I18n.t("work_package.sharing.text_empty_search_description")
config[:heading_text] = I18n.t('work_package.sharing.text_empty_search_header')
config[:description_text] = I18n.t('work_package.sharing.text_empty_search_description')
end
end
end
def type_filter_options
[
{ label: I18n.t("work_package.sharing.filter.project_member"),
value: { principal_type: "User", project_member: true } },
{ label: I18n.t("work_package.sharing.filter.not_project_member"),
value: { principal_type: "User", project_member: false } },
{ label: I18n.t("work_package.sharing.filter.project_group"),
value: { principal_type: "Group", project_member: true } },
{ label: I18n.t("work_package.sharing.filter.not_project_group"),
value: { principal_type: "Group", project_member: false } }
{ label: I18n.t('work_package.sharing.filter.project_member'),
value: { principal_type: 'User', project_member: true } },
{ label: I18n.t('work_package.sharing.filter.not_project_member'),
value: { principal_type: 'User', project_member: false } },
{ label: I18n.t('work_package.sharing.filter.project_group'),
value: { principal_type: 'Group', project_member: true } },
{ label: I18n.t('work_package.sharing.filter.not_project_group'),
value: { principal_type: 'Group', project_member: false } }
]
end
def type_filter_option_active?(_option)
principal_type_filter_value = current_filter_value(params[:filters], "principal_type")
project_member_filter_value = current_filter_value(params[:filters], "also_project_member")
principal_type_filter_value = current_filter_value(params[:filters], 'principal_type')
project_member_filter_value = current_filter_value(params[:filters], 'also_project_member')
return false if principal_type_filter_value.nil? || project_member_filter_value.nil?
@@ -100,7 +100,7 @@ module WorkPackages
end
def role_filter_option_active?(_option)
role_filter_value = current_filter_value(params[:filters], "role_id")
role_filter_value = current_filter_value(params[:filters], 'role_id')
return false if role_filter_value.nil?
@@ -122,7 +122,7 @@ module WorkPackages
end
def apply_role_filter(_option)
current_role_filter_value = current_filter_value(params[:filters], "role_id")
current_role_filter_value = current_filter_value(params[:filters], 'role_id')
filter = []
if _option.nil? && current_role_filter_value.present?
@@ -141,8 +141,8 @@ module WorkPackages
end
def apply_type_filter(_option)
current_type_filter_value = current_filter_value(params[:filters], "principal_type")
current_member_filter_value = current_filter_value(params[:filters], "also_project_member")
current_type_filter_value = current_filter_value(params[:filters], 'principal_type')
current_member_filter_value = current_filter_value(params[:filters], 'also_project_member')
filter = []
if _option.nil? && current_type_filter_value.present? && current_member_filter_value.present?
@@ -173,7 +173,7 @@ module WorkPackages
return nil if filters.nil?
given_filters = JSON.parse(filters).find { |key| key.key?(filter_key) }
given_filters ? given_filters[filter_key]["values"].first : nil
given_filters ? given_filters[filter_key]['values'].first : nil
end
end
end
@@ -54,7 +54,7 @@ module WorkPackages
end
def wrapper_uniq_by
share.id || @system_arguments.dig(:data, :"test-selector")
share.id || @system_arguments.dig(:data, :'test-selector')
end
private
@@ -77,8 +77,8 @@ module WorkPackages
def form_inputs(role_id)
[].tap do |inputs|
inputs << { name: "role_ids[]", value: role_id }
inputs << { name: "filters", value: params[:filters] } if params[:filters]
inputs << { name: 'role_ids[]', value: role_id }
inputs << { name: 'filters', value: params[:filters] } if params[:filters]
end
end
end
@@ -60,9 +60,9 @@ module WorkPackages
def grid_css_classes
if sharing_manageable?
"op-share-wp-modal-body--user-row_manageable"
'op-share-wp-modal-body--user-row_manageable'
else
"op-share-wp-modal-body--user-row"
'op-share-wp-modal-body--user-row'
end
end
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "model_contract"
require 'model_contract'
module Attachments
module ValidateReplacements
@@ -49,9 +49,9 @@ module Authentication
end
def validate_auth_hash_not_expired
return unless auth_hash["timestamp"]
return unless auth_hash['timestamp']
if auth_hash["timestamp"] < Time.now - 30.minutes
if auth_hash['timestamp'] < Time.now - 30.minutes
errors.add(:base, I18n.t(:error_omniauth_registration_timed_out))
end
end
@@ -32,9 +32,9 @@ module AssignableCustomFieldValues
included do
def assignable_custom_field_values(custom_field)
case custom_field.field_format
when "list"
when 'list'
custom_field.possible_values
when "version"
when 'version'
assignable_versions(only_open: !custom_field.allow_non_open_versions?)
end
end
+1 -1
View File
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "model_contract"
require 'model_contract'
# Contract for create (c) and update (u)
module CustomActions
+1 -1
View File
@@ -36,7 +36,7 @@ module Groups
def type_is_group
unless model.type == Group.name
errors.add(:type, "Type and class mismatch")
errors.add(:type, 'Type and class mismatch')
end
end
end
+1 -1
View File
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require_relative "base_contract"
require_relative 'base_contract'
##
# Model contract for AR records that
@@ -39,7 +39,7 @@ module PlaceholderUsers
def type_is_placeholder_user
unless model.type == PlaceholderUser.name
errors.add(:type, "Type and class mismatch")
errors.add(:type, 'Type and class mismatch')
end
end
end
@@ -28,11 +28,6 @@
module Projects
class CreateContract < BaseContract
include AdminWritableTimestamps
# Projects update their updated_at timestamp due to awesome_nested_set
# so allowing writing here would be useless.
allow_writable_timestamps :created_at
private
def validate_user_allowed_to_manage
+1 -1
View File
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "queries/base_contract"
require 'queries/base_contract'
module Queries
class CopyContract < BaseContract
@@ -1,6 +1,6 @@
# frozen_string_literal: true
require "queries/create_contract"
require 'queries/create_contract'
module Queries
class GlobalCreateContract < CreateContract
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "queries/base_contract"
require 'queries/base_contract'
module Queries
class ICalSharingContract < BaseContract
+1 -1
View File
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "queries/base_contract"
require 'queries/base_contract'
module Queries
class UpdateContract < BaseContract
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "queries/base_contract"
require 'queries/base_contract'
module Queries
class UpdateFormContract < BaseContract
+1 -1
View File
@@ -57,7 +57,7 @@ module Relations
def validate_nodes_relatable
if (model.from_id_changed? || model.to_id_changed?) &&
WorkPackage.relatable(model.from, model.relation_type, ignored_relation: model).where(id: model.to_id).empty?
errors.add :base, I18n.t(:"activerecord.errors.messages.circular_dependency")
errors.add :base, I18n.t(:'activerecord.errors.messages.circular_dependency')
end
end
+1 -1
View File
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "relations/base_contract"
require 'relations/base_contract'
module Relations
class CreateContract < BaseContract
@@ -42,7 +42,7 @@ module Settings
end
def unique_job
WorkPackages::ApplyWorkingDaysChangeJob.new.check_concurrency do
if WorkPackages::ApplyWorkingDaysChangeJob.scheduled?
errors.add :base, :previous_working_day_changes_unprocessed
end
end
+2 -2
View File
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "model_contract"
require 'model_contract'
module Types
class BaseContract < ::ModelContract
@@ -93,7 +93,7 @@ module Types
if key.is_a?(String) && valid_attributes.exclude?(key)
errors.add(
:attribute_groups,
I18n.t("activerecord.errors.models.type.attributes.attribute_groups.attribute_unknown_name",
I18n.t('activerecord.errors.models.type.attributes.attribute_groups.attribute_unknown_name',
attribute: key)
)
end
@@ -81,7 +81,7 @@ module UserPreferences
if time_zones.length == 1
time_zones.first
else
time_zones.detect { |tz| tz.tzinfo.name.include?(tz.name.tr(" ", "_")) }
time_zones.detect { |tz| tz.tzinfo.name.include?(tz.name.tr(' ', '_')) }
end
end
end
@@ -109,7 +109,7 @@ module UserPreferences
end
def full_hour_reminder_time
unless model.daily_reminders[:times].all? { |time| time.end_with?("00:00+00:00") }
unless model.daily_reminders[:times].all? { |time| time.end_with?('00:00+00:00') }
errors.add :daily_reminders, :full_hour
end
end
+1 -1
View File
@@ -64,7 +64,7 @@ module Users
def reduce_writable_attributes(attributes)
super.tap do |writable|
writable << "password" if password_writable?
writable << 'password' if password_writable?
end
end
+1 -1
View File
@@ -76,7 +76,7 @@ module Users
def type_is_user
unless model.type == User.name
errors.add(:type, "Type and class mismatch")
errors.add(:type, 'Type and class mismatch')
end
end
end
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "work_packages/create_contract"
require 'work_packages/create_contract'
# Can be used to copy all of a project's work packages. As the
# work packages can be old, some of the validations that would
@@ -26,16 +26,14 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "work_packages/base_contract"
require 'work_packages/base_contract'
module WorkPackages
class CreateContract < BaseContract
include AdminWritableTimestamps
allow_writable_timestamps
attribute :author_id,
writable: -> { default_attributes_admin_writable? }
writable: false do
errors.add :author_id, :invalid if model.author != user
end
attribute :status_id,
# Overriding permission from WP base contract to ignore change_work_package_status for creation,
# because we don't require that permission for writable status during WP creation.
@@ -64,7 +62,7 @@ module WorkPackages
def attributes_changed_by_user
# lock version is initialized by AR itself
super - ["lock_version"]
super - ['lock_version']
end
end
end
+15 -15
View File
@@ -42,7 +42,7 @@ class AccountController < ApplicationController
before_action :check_auth_source_sso_failure, only: :auth_source_sso_failed
before_action :check_internal_login_enabled, only: :internal_login
layout "no_menu"
layout 'no_menu'
# Login request and validation
def login
@@ -58,7 +58,7 @@ class AccountController < ApplicationController
end
def internal_login
render "account/login"
render 'account/login'
end
# Log out current user and redirect to welcome page
@@ -88,12 +88,12 @@ class AccountController < ApplicationController
if call.success?
@token.destroy
redirect_to action: "login"
redirect_to action: 'login'
return
end
end
render template: "account/password_recovery"
render template: 'account/password_recovery'
elsif request.post?
mail = params[:mail]
user = User.find_by_mail(mail) if mail.present?
@@ -120,7 +120,7 @@ class AccountController < ApplicationController
if token.save
UserMailer.password_lost(token).deliver_later
flash[:notice] = I18n.t(:notice_account_lost_email_sent)
redirect_to action: "login", back_url: home_url
redirect_to action: 'login', back_url: home_url
nil
end
end
@@ -235,7 +235,7 @@ class AccountController < ApplicationController
if omniauth_direct_login?
direct_login user
elsif OpenProject::Configuration.disable_password_login?
flash[:notice] = I18n.t("account.omniauth_login")
flash[:notice] = I18n.t('account.omniauth_login')
redirect_to signin_path
else
@@ -249,7 +249,7 @@ class AccountController < ApplicationController
ldap_auth_source_id: user.ldap_auth_source_id
}
flash[:notice] = I18n.t("account.auth_source_login", login: user.login).html_safe
flash[:notice] = I18n.t('account.auth_source_login', login: user.login).html_safe
redirect_to signin_path(username: user.login)
end
@@ -283,7 +283,7 @@ class AccountController < ApplicationController
flash.now[:error] = I18n.t(:error_auth_source_sso_failed, value: failure[:login]) +
": " + String(flash.now[:error])
render action: "login", back_url: failure[:back_url]
render action: 'login', back_url: failure[:back_url]
end
private
@@ -470,11 +470,11 @@ class AccountController < ApplicationController
def onthefly_creation_failed(user, auth_source_options = {})
@user = user
session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
render action: "register"
render action: 'register'
end
def self_registration_disabled
flash[:error] = I18n.t("account.error_self_registration_disabled")
flash[:error] = I18n.t('account.error_self_registration_disabled')
redirect_to signin_url
end
@@ -489,18 +489,18 @@ class AccountController < ApplicationController
# Log an attempt to log in to an account in "registered" state and show a flash message.
def account_not_activated(flash_now: true)
flash_error_message(log_reason: "NOT ACTIVATED", flash_now:) do
flash_error_message(log_reason: 'NOT ACTIVATED', flash_now:) do
if Setting::SelfRegistration.by_email?
"account.error_inactive_activation_by_mail"
'account.error_inactive_activation_by_mail'
else
"account.error_inactive_manual_activation"
'account.error_inactive_manual_activation'
end
end
end
def invited_account_not_activated(_user)
flash_error_message(log_reason: "invited, NOT ACTIVATED", flash_now: false) do
"account.error_inactive_activation_by_mail"
flash_error_message(log_reason: 'invited, NOT ACTIVATED', flash_now: false) do
'account.error_inactive_activation_by_mail'
end
end
+3 -3
View File
@@ -75,7 +75,7 @@ class ActivitiesController < ApplicationController
end
def verify_activities_module_activated
render_403 if @project && !@project.module_enabled?("activity")
render_403 if @project && !@project.module_enabled?('activity')
end
def determine_date_range
@@ -101,7 +101,7 @@ class ActivitiesController < ApplicationController
elsif params[:with_subprojects].nil?
session[:activity][:with_subprojects]
else
params[:with_subprojects] == "1"
params[:with_subprojects] == '1'
end
end
@@ -136,7 +136,7 @@ class ActivitiesController < ApplicationController
end
def set_current_activity_page
@activity_page = @project ? "projects/#{@project.identifier}" : "all"
@activity_page = @project ? "projects/#{@project.identifier}" : 'all'
end
def set_session
@@ -29,7 +29,7 @@
module Admin
module Attachments
class QuarantinedAttachmentsController < ApplicationController
layout "admin"
layout 'admin'
before_action :require_admin
before_action :find_quarantined_attachments
@@ -45,14 +45,14 @@ module Admin
create_journal(container,
User.system,
I18n.t("antivirus_scan.deleted_by_admin", filename: @attachment.filename))
I18n.t('antivirus_scan.deleted_by_admin', filename: @attachment.filename))
flash[:notice] = t(:notice_successful_delete)
redirect_to action: :index
end
def default_breadcrumb
t("antivirus_scan.quarantined_attachments.title")
t('antivirus_scan.quarantined_attachments.title')
end
def show_local_breadcrumb
@@ -37,7 +37,7 @@ module Admin::Settings
end
def default_breadcrumb
t(:"menus.admin.aggregation")
t(:'menus.admin.aggregation')
end
def show_local_breadcrumb
@@ -31,7 +31,7 @@ module Admin::Settings
menu_item :attachments_settings
def default_breadcrumb
t(:"attributes.attachments")
t(:'attributes.attachments')
end
def settings_params
@@ -48,7 +48,7 @@ module Admin::Settings
if start_of_week.present? ^ start_of_year.present?
flash[:error] = I18n.t(
"settings.date_format.first_date_of_week_and_year_set",
'settings.date_format.first_date_of_week_and_year_set',
first_week_setting_name: I18n.t(:setting_first_week_of_year),
day_of_week_setting_name: I18n.t(:setting_start_of_week)
)
@@ -39,7 +39,7 @@ module Admin::Settings
end
def default_breadcrumb
t(:"menus.admin.mail_notification")
t(:'menus.admin.mail_notification')
end
def show_local_breadcrumb
@@ -47,7 +47,7 @@ module Admin::Settings
def settings_params
super.tap do |settings|
if settings["consent_required"] == "1" && params["toggle_consent_time"] == "1"
if settings["consent_required"] == '1' && params['toggle_consent_time'] == '1'
settings["consent_time"] = Time.zone.now.iso8601
end
end
@@ -34,7 +34,7 @@ module Admin::Settings
before_action :check_clamav, only: %i[update], if: -> { scan_enabled? }
def default_breadcrumb
t("settings.antivirus.title")
t('settings.antivirus.title')
end
def av_form
@@ -52,7 +52,7 @@ module Admin::Settings
private
def require_ee
render("upsale") unless EnterpriseToken.allows_to?(:virus_scanning)
render('upsale') unless EnterpriseToken.allows_to?(:virus_scanning)
end
def mark_unscanned_attachments
@@ -60,7 +60,7 @@ module Admin::Settings
end
def check_clamav
return if params.dig(:settings, :antivirus_scan_mode) == "disabled"
return if params.dig(:settings, :antivirus_scan_mode) == 'disabled'
service = ::Attachments::ClamAVService.new(params[:settings][:antivirus_scan_mode].to_sym,
params[:settings][:antivirus_scan_target])
@@ -68,12 +68,12 @@ module Admin::Settings
service.ping
rescue StandardError => e
Rails.logger.error { "Failed to check availability of ClamAV: #{e.message}" }
flash[:error] = t(:"settings.antivirus.clamav_ping_failed")
flash[:error] = t(:'settings.antivirus.clamav_ping_failed')
redirect_to action: :show
end
def scan_enabled?
Setting.antivirus_scan_mode != :disabled || params.dig(:settings, :antivirus_scan_mode) != "disabled"
Setting.antivirus_scan_mode != :disabled || params.dig(:settings, :antivirus_scan_mode) != 'disabled'
end
def success_callback(_call)
@@ -87,7 +87,7 @@ module Admin::Settings
end
def rescan_files
flash[:notice] = t("settings.antivirus.remaining_rescanned_files",
flash[:notice] = t('settings.antivirus.remaining_rescanned_files',
file_count: t(:label_x_files, count: Attachment.status_uploaded.count))
Attachment.status_uploaded.update_all(status: :rescan)
@@ -96,8 +96,8 @@ module Admin::Settings
end
def remaining_quarantine_warning
flash[:info] = t("settings.antivirus.remaining_quarantined_files_html",
link: helpers.link_to(t("antivirus_scan.quarantined_attachments.title"),
flash[:info] = t('settings.antivirus.remaining_quarantined_files_html',
link: helpers.link_to(t('antivirus_scan.quarantined_attachments.title'),
admin_quarantined_attachments_path),
file_count: t(:label_x_files, count: Attachment.status_quarantined.count))
redirect_to action: :show
@@ -37,7 +37,7 @@ module Admin::Settings
def failure_callback(call)
@modified_non_working_days = modified_non_working_days_for(call.result)
flash[:error] = call.message || I18n.t(:notice_internal_server_error)
render action: "show"
render action: 'show'
end
protected
+3 -3
View File
@@ -28,7 +28,7 @@
module Admin
class SettingsController < ApplicationController
layout "admin"
layout 'admin'
before_action :require_admin
before_action :find_plugin, only: %i[show_plugin update_plugin]
@@ -99,12 +99,12 @@ module Admin
def success_callback(_call)
flash[:notice] = t(:notice_successful_update)
redirect_to action: "show", tab: params[:tab]
redirect_to action: 'show', tab: params[:tab]
end
def failure_callback(call)
flash[:error] = call.message || I18n.t(:notice_internal_server_error)
redirect_to action: "show", tab: params[:tab]
redirect_to action: 'show', tab: params[:tab]
end
end
end
+14 -14
View File
@@ -25,10 +25,10 @@
#
# See COPYRIGHT and LICENSE files for more details.
#++
require "open3"
require 'open3'
class AdminController < ApplicationController
layout "admin"
layout 'admin'
before_action :require_admin, except: %i[index]
before_action :authorize_global, only: %i[index]
@@ -53,11 +53,11 @@ class AdminController < ApplicationController
end
def projects
redirect_to controller: "projects", action: "index"
redirect_to controller: 'projects', action: 'index'
end
def plugins
@plugins = Redmine::Plugin.not_bundled.sort
@plugins = Redmine::Plugin.all.sort
end
def test_email
@@ -91,9 +91,9 @@ class AdminController < ApplicationController
def default_breadcrumb
case params[:action]
when "plugins"
when 'plugins'
t(:label_plugins)
when "info"
when 'info'
t(:label_information)
end
end
@@ -111,12 +111,12 @@ class AdminController < ApplicationController
def plaintext_extraction_checks
if OpenProject::Database.allows_tsv?
[
[:"extraction.available.pdftotext", Plaintext::PdfHandler.available?],
[:"extraction.available.unrtf", Plaintext::RtfHandler.available?],
[:"extraction.available.catdoc", Plaintext::DocHandler.available?],
[:"extraction.available.xls2csv", Plaintext::XlsHandler.available?],
[:"extraction.available.catppt", Plaintext::PptHandler.available?],
[:"extraction.available.tesseract", Plaintext::ImageHandler.available?]
[:'extraction.available.pdftotext', Plaintext::PdfHandler.available?],
[:'extraction.available.unrtf', Plaintext::RtfHandler.available?],
[:'extraction.available.catdoc', Plaintext::DocHandler.available?],
[:'extraction.available.xls2csv', Plaintext::XlsHandler.available?],
[:'extraction.available.catppt', Plaintext::PptHandler.available?],
[:'extraction.available.tesseract', Plaintext::ImageHandler.available?]
]
else
[]
@@ -124,11 +124,11 @@ class AdminController < ApplicationController
end
def image_conversion_checks
[[:"image_conversion.imagemagick", image_conversion_libs_available?]]
[[:'image_conversion.imagemagick', image_conversion_libs_available?]]
end
def image_conversion_libs_available?
Open3.capture2e("convert", "-version").first.include?("ImageMagick")
Open3.capture2e('convert', '-version').first.include?('ImageMagick')
rescue StandardError
false
end
+2 -2
View File
@@ -32,13 +32,13 @@ class AngularController < ApplicationController
def empty_layout
# Frontend will handle rendering
# but we will need to render with layout
render html: "", layout: "angular/angular"
render html: '', layout: 'angular/angular'
end
def notifications_layout
# Frontend will handle rendering
# but we will need to render with notification specific layout
render html: "", layout: "angular/notifications"
render html: '', layout: 'angular/notifications'
end
def login_back_url_params
+3 -3
View File
@@ -1,5 +1,5 @@
class AnnouncementsController < ApplicationController
layout "admin"
layout 'admin'
before_action :require_admin
@@ -15,7 +15,7 @@ class AnnouncementsController < ApplicationController
flash[:notice] = t(:notice_successful_update)
end
redirect_to action: "edit"
redirect_to action: 'edit'
end
private
@@ -29,6 +29,6 @@ class AnnouncementsController < ApplicationController
end
def announcement_params
params.require(:announcement).permit("text", "show_until", "active")
params.require(:announcement).permit('text', 'show_until', 'active')
end
end
+30 -30
View File
@@ -26,10 +26,10 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "uri"
require "cgi"
require 'uri'
require 'cgi'
require "doorkeeper/dashboard_helper"
require 'doorkeeper/dashboard_helper'
class ApplicationController < ActionController::Base
class_attribute :_model_object
@@ -51,7 +51,7 @@ class ApplicationController < ActionController::Base
include AdditionalUrlHelpers
include OpenProjectErrorHelper
layout "base"
layout 'base'
protect_from_forgery
# CSRF protection prevents two things. It prevents an attacker from using a
@@ -74,7 +74,7 @@ class ApplicationController < ActionController::Base
# Thus, we show an error message unless the request probably is an API
# request.
def handle_unverified_request
cookies.delete(OpenProject::Configuration["autologin_cookie_name"])
cookies.delete(OpenProject::Configuration['autologin_cookie_name'])
self.logged_user = nil
# Don't render an error message for requests that appear to be API requests.
@@ -105,7 +105,7 @@ class ApplicationController < ActionController::Base
# Check whether user have cookies enabled, otherwise they'll only be
# greeted with the CSRF error upon login.
message = I18n.t(:error_token_authenticity)
message << (" " + I18n.t(:error_cookie_missing)) if openproject_cookie_missing?
message << (' ' + I18n.t(:error_cookie_missing)) if openproject_cookie_missing?
log_csrf_failure
@@ -148,7 +148,7 @@ class ApplicationController < ActionController::Base
def default_url_options(_options = {})
{
layout: params["layout"],
layout: params['layout'],
protocol: Setting.protocol
}
end
@@ -159,7 +159,7 @@ class ApplicationController < ActionController::Base
# https://websecuritytool.codeplex.com/wikipage?title=Checks#http-cache-control-header-no-store
# http://stackoverflow.com/questions/711418/how-to-prevent-browser-page-caching-in-rails
def set_cache_buster
if OpenProject::Configuration["disable_browser_cache"]
if OpenProject::Configuration['disable_browser_cache']
response.cache_control.merge!(
max_age: 0,
public: false,
@@ -179,7 +179,7 @@ class ApplicationController < ActionController::Base
# Checks if the session cookie is missing.
# This is useful only on a second request
def openproject_cookie_missing?
request.cookies[OpenProject::Configuration["session_cookie_name"]].nil?
request.cookies[OpenProject::Configuration['session_cookie_name']].nil?
end
helper_method :openproject_cookie_missing?
@@ -187,8 +187,8 @@ class ApplicationController < ActionController::Base
##
# Create CSRF issue
def log_csrf_failure
message = "CSRF validation error"
message << " (No session cookie present)" if openproject_cookie_missing?
message = 'CSRF validation error'
message << ' (No session cookie present)' if openproject_cookie_missing?
op_handle_error message, reference: :csrf_validation_failed
end
@@ -208,7 +208,7 @@ class ApplicationController < ActionController::Base
# replaces all invalid characters with #
def escape_for_logging(string)
# only allow numbers, ASCII letters, space and the following characters: @.-"'!?=/
string.gsub(/[^0-9a-zA-Z@._\-"'!?=\/ ]{1}/, "#")
string.gsub(/[^0-9a-zA-Z@._\-"'!?=\/ ]{1}/, '#')
end
def reset_i18n_fallbacks
@@ -228,7 +228,7 @@ class ApplicationController < ActionController::Base
user = RequestStore[:current_user] ||
(session[:authenticated_user_id].present? && User.find_by(id: session[:authenticated_user_id])) ||
User.anonymous
SetLocalizationService.new(user, request.env["HTTP_ACCEPT_LANGUAGE"]).call
SetLocalizationService.new(user, request.env['HTTP_ACCEPT_LANGUAGE']).call
end
def deny_access(not_found: false)
@@ -413,7 +413,7 @@ class ApplicationController < ActionController::Base
associated = find_belongs_to_chained_objects(associations, model_object)
associated.each do |a|
instance_variable_set("@" + a.class.to_s.downcase, a)
instance_variable_set('@' + a.class.to_s.downcase, a)
end
rescue ActiveRecord::RecordNotFound
render_404
@@ -452,7 +452,7 @@ class ApplicationController < ActionController::Base
def find_work_packages
@work_packages = WorkPackage.includes(:project)
.where(id: params[:work_package_id] || params[:ids])
.order("id ASC")
.order('id ASC')
fail ActiveRecord::RecordNotFound if @work_packages.empty?
@projects = @work_packages.filter_map(&:project).uniq
@@ -479,7 +479,7 @@ class ApplicationController < ActionController::Base
end
def back_url
params[:back_url] || request.env["HTTP_REFERER"]
params[:back_url] || request.env['HTTP_REFERER']
end
def redirect_back_or_default(default, use_escaped = true)
@@ -497,7 +497,7 @@ class ApplicationController < ActionController::Base
#
# @return [boolean, string] name of the layout to use or false for no layout
def use_layout
request.xhr? ? false : "no_menu"
request.xhr? ? false : 'no_menu'
end
def render_feed(items, options = {})
@@ -505,7 +505,7 @@ class ApplicationController < ActionController::Base
@items = @items.sort { |x, y| y.event_datetime <=> x.event_datetime }
@items = @items.slice(0, Setting.feeds_limit.to_i)
@title = options[:title] || Setting.app_title
render template: "common/feed", layout: false, content_type: "application/atom+xml"
render template: 'common/feed', layout: false, content_type: 'application/atom+xml'
end
def self.accept_key_auth(*actions)
@@ -519,7 +519,7 @@ class ApplicationController < ActionController::Base
# Returns a string that can be used as filename value in Content-Disposition header
def filename_for_content_disposition(name)
%r{(MSIE|Trident)}.match?(request.env["HTTP_USER_AGENT"]) ? ERB::Util.url_encode(name) : name
%r{(MSIE|Trident)}.match?(request.env['HTTP_USER_AGENT']) ? ERB::Util.url_encode(name) : name
end
def api_request?
@@ -534,8 +534,8 @@ class ApplicationController < ActionController::Base
def api_key_from_request
if params[:key].present?
params[:key]
elsif request.headers["X-OpenProject-API-Key"].present?
request.headers["X-OpenProject-API-Key"]
elsif request.headers['X-OpenProject-API-Key'].present?
request.headers['X-OpenProject-API-Key']
end
end
@@ -550,10 +550,10 @@ class ApplicationController < ActionController::Base
def render_validation_errors(object)
options = { status: :unprocessable_entity, layout: false }
errors = case params[:format]
when "xml"
when 'xml'
{ xml: object.errors }
when "json"
{ json: { "errors" => object.errors } } # ActiveResource client compliance
when 'json'
{ json: { 'errors' => object.errors } } # ActiveResource client compliance
else
fail "Unknown format #{params[:format]} in #render_validation_errors"
end
@@ -566,7 +566,7 @@ class ApplicationController < ActionController::Base
def default_template(action_name = self.action_name)
if api_request?
begin
return view_paths.find_template(default_template_name(action_name), "api")
return view_paths.find_template(default_template_name(action_name), 'api')
rescue ::ActionView::MissingTemplate
# the api template was not found
# fallback to the default behaviour
@@ -584,7 +584,7 @@ class ApplicationController < ActionController::Base
def default_breadcrumb
label = "label_#{controller_name.singularize}"
I18n.t(label + "_plural",
I18n.t(label + '_plural',
default: label.to_sym)
end
@@ -607,8 +607,8 @@ class ApplicationController < ActionController::Base
if session_expired?
self.logged_user = nil
flash[:warning] = I18n.t("notice_forced_logout", ttl_time: Setting.session_ttl)
redirect_to(controller: "/account", action: "login", back_url: login_back_url)
flash[:warning] = I18n.t('notice_forced_logout', ttl_time: Setting.session_ttl)
redirect_to(controller: '/account', action: 'login', back_url: login_back_url)
end
session[:updated_at] = Time.now
end
@@ -623,7 +623,7 @@ class ApplicationController < ActionController::Base
def stop_if_feeds_disabled
if feed_request? && !Setting.feeds_enabled?
render_404(message: I18n.t("label_disabled"))
render_404(message: I18n.t('label_disabled'))
end
end
@@ -649,7 +649,7 @@ class ApplicationController < ActionController::Base
else
url_params = params.permit(:action, :id, :project_id, :controller)
unless url_params[:controller].to_s.starts_with?("/")
unless url_params[:controller].to_s.starts_with?('/')
url_params[:controller] = "/#{url_params[:controller]}"
end
@@ -27,7 +27,7 @@
#++
class AttributeHelpTextsController < ApplicationController
layout "admin"
layout 'admin'
menu_item :attribute_help_texts
before_action :authorize_global
@@ -56,8 +56,8 @@ class AttributeHelpTextsController < ApplicationController
redirect_to attribute_help_texts_path(tab: call.result.attribute_scope)
else
@attribute_help_text = call.result
flash[:error] = call.message || I18n.t("notice_internal_server_error")
render action: "new"
flash[:error] = call.message || I18n.t('notice_internal_server_error')
render action: 'new'
end
end
@@ -70,8 +70,8 @@ class AttributeHelpTextsController < ApplicationController
flash[:notice] = t(:notice_successful_update)
redirect_to attribute_help_texts_path(tab: @attribute_help_text.attribute_scope)
else
flash[:error] = call.message || I18n.t("notice_internal_server_error")
render action: "edit"
flash[:error] = call.message || I18n.t('notice_internal_server_error')
render action: 'edit'
end
end
@@ -88,10 +88,10 @@ class AttributeHelpTextsController < ApplicationController
protected
def default_breadcrumb
if action_name == "index"
t("attribute_help_texts.label_plural")
if action_name == 'index'
t('attribute_help_texts.label_plural')
else
ActionController::Base.helpers.link_to(t("attribute_help_texts.label_plural"), attribute_help_texts_path)
ActionController::Base.helpers.link_to(t('attribute_help_texts.label_plural'), attribute_help_texts_path)
end
end
@@ -122,7 +122,7 @@ class AttributeHelpTextsController < ApplicationController
end
def find_type_scope
name = params.fetch(:name, "WorkPackage")
name = params.fetch(:name, 'WorkPackage')
submodule = AttributeHelpText.available_types.find { |mod| mod == name }
if submodule.nil?
+2 -2
View File
@@ -70,7 +70,7 @@ class CategoriesController < ApplicationController
flash[:notice] = I18n.t(:notice_successful_update)
redirect_to project_settings_categories_path(@project)
else
render action: "edit"
render action: 'edit'
end
end
@@ -82,7 +82,7 @@ class CategoriesController < ApplicationController
redirect_to project_settings_categories_path(@project)
return
elsif params[:todo]
reassign_to = @project.categories.find_by(id: params[:reassign_to_id]) if params[:todo] == "reassign"
reassign_to = @project.categories.find_by(id: params[:reassign_to_id]) if params[:todo] == 'reassign'
@category.destroy(reassign_to)
redirect_to project_settings_categories_path(@project)
return
+4 -4
View File
@@ -29,7 +29,7 @@
class ColorsController < ApplicationController
before_action :require_admin_unless_readonly_api_request
layout "admin"
layout 'admin'
menu_item :colors
@@ -68,7 +68,7 @@ class ColorsController < ApplicationController
redirect_to colors_path
else
flash.now[:error] = I18n.t(:error_color_could_not_be_saved)
render action: "new"
render action: 'new'
end
end
@@ -80,7 +80,7 @@ class ColorsController < ApplicationController
redirect_to colors_path
else
flash.now[:error] = I18n.t(:error_color_could_not_be_saved)
render action: "edit"
render action: 'edit'
end
end
@@ -102,7 +102,7 @@ class ColorsController < ApplicationController
protected
def default_breadcrumb
if action_name == "index"
if action_name == 'index'
t(:label_color_plural)
else
ActionController::Base.helpers.link_to(t(:label_color_plural), colors_path)
@@ -65,7 +65,7 @@ module Accounts::AuthenticationStages
else
flash[:error] = I18n.t(
:notice_auth_stage_wrong_stage,
expected: stage || "(none)",
expected: stage || '(none)',
actual: params[:stage]
)
@@ -119,7 +119,7 @@ module Accounts::AuthenticationStages
session[:back_url] ||= params[:back_url]
# Remember the autologin cookie decision
session[:autologin_requested] = params[:autologin] == "1"
session[:autologin_requested] = params[:autologin] == '1'
stages
end
@@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
require "uri"
require 'uri'
##
# Intended to be used by the AccountController to handle omniauth logins
@@ -47,10 +47,10 @@ module Accounts::OmniauthLogin
end
def omniauth_login
params[:back_url] = request.env["omniauth.origin"] if remember_back_url?
params[:back_url] = request.env['omniauth.origin'] if remember_back_url?
# Extract auth info and perform check / login or activate user
auth_hash = request.env["omniauth.auth"]
auth_hash = request.env['omniauth.auth']
handle_omniauth_authentication(auth_hash)
end
@@ -75,7 +75,7 @@ module Accounts::OmniauthLogin
# Avoid remembering the back_url if we're coming from the login page
def remember_back_url?
provided_back_url = request.env["omniauth.origin"]
provided_back_url = request.env['omniauth.origin']
return if provided_back_url.blank?
account_routes = /\/(login|account)/
@@ -84,7 +84,7 @@ module Accounts::OmniauthLogin
def show_error(error)
flash[:error] = error
redirect_to action: "login"
redirect_to action: 'login'
end
def register_via_omniauth(session, user_attributes)
@@ -93,7 +93,7 @@ module Accounts::OmniauthLogin
def handle_omniauth_authentication(auth_hash, user_params: nil)
call = ::Authentication::OmniauthService
.new(strategy: request.env["omniauth.strategy"], auth_hash:, controller: self)
.new(strategy: request.env['omniauth.strategy'], auth_hash:, controller: self)
.call(user_params)
if call.success?
@@ -34,7 +34,7 @@ module Accounts::UserConsent
def consent
if user_consent_required? && consenting_user&.consent_expired?
render "account/consent"
render 'account/consent'
else
consent_finished
end
@@ -51,12 +51,12 @@ module Accounts::UserConsent
end
def decline_consent
message = I18n.t("consent.decline_warning_message") + "\n"
message = I18n.t('consent.decline_warning_message') + "\n"
message <<
if Setting.consent_decline_mail.present?
I18n.t("consent.contact_this_mail_address", mail_address: Setting.consent_decline_mail)
I18n.t('consent.contact_this_mail_address', mail_address: Setting.consent_decline_mail)
else
I18n.t("consent.contact_your_administrator")
I18n.t('consent.contact_your_administrator')
end
flash[:error] = message
@@ -77,7 +77,7 @@ module Accounts::UserConsent
end
def reject_consent!
flash[:error] = I18n.t("consent.failure_message")
flash[:error] = I18n.t('consent.failure_message')
redirect_to authentication_stage_failure_path :consent
end
end
@@ -70,7 +70,7 @@ module Accounts::UserPasswordChange
return
end
flash_error_message(log_reason: "invalid credentials", flash_now:) do
flash_error_message(log_reason: 'invalid credentials', flash_now:) do
if Setting.brute_force_block_after_failed_logins.to_i > 0
:notice_account_invalid_credentials_or_blocked
else
@@ -83,7 +83,7 @@ module Accounts::UserPasswordChange
flash[:error] = message unless message.nil?
@user = user
@username = user.login
render "my/password", locals: { show_user_name: }
render 'my/password', locals: { show_user_name: }
end
##
@@ -91,15 +91,15 @@ module Accounts::UserPasswordChange
def redirect_if_password_change_not_allowed(user)
if user and not user.change_password_allowed?
logger.warn "Password change for user '#{user}' forced, but user is not allowed " +
"to change password"
'to change password'
flash[:error] = I18n.t(:notice_can_t_change_password)
redirect_to action: "login"
redirect_to action: 'login'
return true
end
false
end
def flash_error_message(log_reason: "", flash_now: true)
def flash_error_message(log_reason: '', flash_now: true)
flash_hash = flash_now ? flash.now : flash
logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} " \
+1 -1
View File
@@ -103,7 +103,7 @@ module AuthSourceSSO
def extract_from_header(value)
if header_secret.present?
valid_secret = value.end_with?(":#{header_secret}")
login = value.gsub(/:#{Regexp.escape(header_secret)}\z/, "")
login = value.gsub(/:#{Regexp.escape(header_secret)}\z/, '')
[login, valid_secret]
else
+1 -1
View File
@@ -36,7 +36,7 @@ module Layout
elsif @project
true
else
"no_menu"
'no_menu'
end
end

Some files were not shown because too many files have changed in this diff Show More