diff --git a/.editorconfig b/.editorconfig index 9b411022ae0..7f864d6081e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -350,10 +350,7 @@ ij_json_spaces_within_brackets = false ij_json_wrap_long_lines = false [{rcov,spec,rake,rails,spork,capfile,gemfile,rakefile,guardfile,isolate,vagrantfile,Puppetfile,*.jbuilder,*.rbw,*.gemspec,*.thor,*.ru,*.rb,*.rake}] -indent_size = 2 -tab_width = 2 trim_trailing_whitespace=true -ij_continuation_indent_size = 2 ij_ruby_align_group_field_declarations = false ij_ruby_align_multiline_parameters = true ij_ruby_blank_lines_around_method = 1 @@ -364,7 +361,6 @@ ij_ruby_indent_protected_methods = false ij_ruby_indent_public_methods = false ij_ruby_indent_when_cases = false ij_ruby_keep_blank_lines_in_declarations = 2 -ij_ruby_keep_indents_on_empty_lines = false ij_ruby_keep_line_breaks = true ij_ruby_parentheses_around_method_arguments = true ij_ruby_spaces_around_hashrocket = true diff --git a/.erb-lint.yml b/.erb_lint.yml similarity index 75% rename from .erb-lint.yml rename to .erb_lint.yml index 7dc513d45ec..10d4e18ac6d 100644 --- a/.erb-lint.yml +++ b/.erb_lint.yml @@ -15,6 +15,12 @@ linters: rubocop_config: inherit_from: - .rubocop.yml + Layout/CommentIndentation: + Enabled: false + Layout/FirstArgumentIndentation: + EnforcedStyle: consistent + Layout/FirstMethodArgumentLineBreak: + Enabled: true Layout/InitialIndentation: Enabled: false Layout/LeadingEmptyLines: @@ -25,11 +31,13 @@ linters: Enabled: false Layout/TrailingWhitespace: Enabled: false - Naming/FileName: - Enabled: false - Style/FrozenStringLiteralComment: - Enabled: false Lint/UselessAssignment: Enabled: false - Rails/OutputSafety: + Naming/FileName: + Enabled: false + Rails/OutputSafety: + Enabled: true + Style/FrozenStringLiteralComment: + Enabled: false + Style/RedundantConstantBase: Enabled: false diff --git a/.erb-linters/erblint-github.rb b/.erb_linters/erblint-github.rb similarity index 100% rename from .erb-linters/erblint-github.rb rename to .erb_linters/erblint-github.rb diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a3cf31fc013..252b588506a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -21,6 +21,10 @@ updates: target-branch: "dev" open-pull-requests-limit: 3 versioning-strategy: lockfile-only + groups: + aws-gems: + patterns: + - "aws-*" - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 07c1674cb33..cf49d653a94 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -53,9 +53,13 @@ jobs: VERSION=${TAG_REF#v} echo "Version: $VERSION" + echo "Checkout REF: $CHECKOUT_REF" echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "checkout_ref=$CHECKOUT_REF" >> "$GITHUB_OUTPUT" - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ steps.extract_version.outputs.checkout_ref }} - name: Cache NPM uses: runs-on/cache@v4 with: @@ -136,9 +140,9 @@ jobs: runner: runner=4cpu-linux-x64 steps: - name: Checkout + uses: actions/checkout@v4 with: ref: ${{ needs.setup.outputs.checkout_ref }} - uses: actions/checkout@v4 - name: Prepare docker files run: | cp ./docker/prod/Dockerfile ./Dockerfile @@ -186,6 +190,16 @@ jobs: type=semver,pattern={{version}},value=${{ needs.setup.outputs.version }} images: | ${{ env.REGISTRY_IMAGE }} + - name: Restore vendor/bundle + id: restore-vendor-bundle + uses: actions/cache/restore@v4 + with: + path: | + vendor/bundle + key: ${{ matrix.platform }}-vendor-bundle-${{ github.ref }} + - name: Include vendor/bundle in this build (so we can use it from the cache above) + run: | + sed -i 's/vendor\/bundle//g' .dockerignore - name: Build image id: build uses: docker/build-push-action@v6 @@ -195,12 +209,35 @@ jobs: target: ${{ matrix.target }} build-args: | BIM_SUPPORT=${{ matrix.bim_support }} + BUILDKIT_PROGRESS=plain pull: true load: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }} cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max + - name: Extract vendor/bundle from container + run: | + docker create --name bundle ${{ steps.build.outputs.imageid }} + if [ -d vendor/bundle ]; then + mv vendor/bundle vendor/bundle.bak + fi + docker cp bundle:/app/vendor/bundle vendor/bundle + docker rm bundle + - name: Save vendor/bundle + id: save-vendor-bundle + uses: actions/cache/save@v4 + with: + path: | + vendor/bundle + key: ${{ steps.restore-vendor-bundle.outputs.cache-primary-key }} + - name: Restore pre-build vendor/bundle to prevent 2nd build from scratch during push + run: | + rm -rf vendor/bundle + + if [ -d vendor/bundle.bak ]; then + mv vendor/bundle.bak vendor/bundle + fi - name: Test # We only test the native container. If that fails the builds for the others # will be cancelled as well. @@ -315,7 +352,7 @@ jobs: needs: [setup, build, merge] permissions: contents: none - if: ${{ github.repository == 'opf/openproject' && inputs.tag != '' }} + if: ${{ github.repository == 'opf/openproject' }} runs-on: ubuntu-latest steps: - name: Trigger Helm charts release diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 85171d8123a..ae765ec999b 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -7,6 +7,7 @@ on: - release/* paths: - 'docs/**' + - 'config/static_links.yml' permissions: contents: read diff --git a/.github/workflows/email-notification.yml b/.github/workflows/email-notification.yml index 9e9799ad1ff..10f8a3cf022 100644 --- a/.github/workflows/email-notification.yml +++ b/.github/workflows/email-notification.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Send mail - uses: dawidd6/action-send-mail@v3 + uses: dawidd6/action-send-mail@v4 with: subject: ${{ inputs.subject }} body: ${{ inputs.body }} diff --git a/.github/workflows/eslint-core.yml b/.github/workflows/eslint-core.yml index 9c24db41635..9d02166efc8 100644 --- a/.github/workflows/eslint-core.yml +++ b/.github/workflows/eslint-core.yml @@ -19,7 +19,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: '18.13' + node-version: '20.9' cache: npm cache-dependency-path: frontend/package-lock.json - uses: reviewdog/action-eslint@v1 diff --git a/.github/workflows/pullpreview.yml b/.github/workflows/pullpreview.yml index 23364897f05..aba0a76f525 100644 --- a/.github/workflows/pullpreview.yml +++ b/.github/workflows/pullpreview.yml @@ -33,7 +33,6 @@ jobs: echo "OPENPROJECT_FEATURE__SHOW__CHANGES__ACTIVE=true" >> .env.pullpreview echo "OPENPROJECT_LOOKBOOK__ENABLED=true" >> .env.pullpreview echo "OPENPROJECT_HSTS=false" >> .env.pullpreview - echo "OPENPROJECT_FEATURE_PRIMERIZED_WORK_PACKAGE_ACTIVITIES_ACTIVE=true" >> .env.pullpreview echo "OPENPROJECT_NOTIFICATIONS_POLLING_INTERVAL=10000" >> .env.pullpreview - name: Boot as BIM edition if: contains(github.ref, 'bim/') || contains(github.head_ref, 'bim/') diff --git a/.github/workflows/rubocop-core.yml b/.github/workflows/rubocop-core.yml index 32a1b04da2c..dc827243e43 100644 --- a/.github/workflows/rubocop-core.yml +++ b/.github/workflows/rubocop-core.yml @@ -10,9 +10,12 @@ jobs: name: rubocop runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: ruby/setup-ruby@v1 - - uses: reviewdog/action-rubocop@v2 + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + - name: Run Rubocop + uses: reviewdog/action-rubocop@v2 with: github_token: ${{ secrets.github_token }} rubocop_version: gemfile @@ -26,3 +29,11 @@ jobs: rubocop-rspec_rails:gemfile reporter: github-pr-check only_changed: true + - name: Install erb_lint + run: gem install -N erb_lint erblint-github + - name: Run erb-lint + uses: tk0miya/action-erblint@v1 + with: + github_token: ${{ secrets.github_token }} + reporter: github-pr-check + fail_on_error: true diff --git a/.github/workflows/test-frontend-unit.yml b/.github/workflows/test-frontend-unit.yml new file mode 100644 index 00000000000..a8002d46aa3 --- /dev/null +++ b/.github/workflows/test-frontend-unit.yml @@ -0,0 +1,54 @@ +name: "Frontend test suite" + +on: + workflow_dispatch: + push: + branches: + - dev + - release/* + paths: + - '**/frontend/**/*.ts' + - '**/frontend/**/*.js' + - '**/frontend/**/*.json' + + pull_request: + types: [opened, reopened, synchronize] + paths: + - '**/frontend/**/*.ts' + - '**/frontend/**/*.js' + - '**/frontend/**/*.json' + +permissions: + contents: read + +defaults: + run: + working-directory: ./frontend + +jobs: + units: + name: Units + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-node@v4 + with: + node-version: '20.9' + cache: npm + cache-dependency-path: frontend/package-lock.json + + - name: Install Dependencies + id: npm-i + run: npm i + + - name: Register plugins + id: npm-run-ci-plugins-register-frontend + run: npm run ci:plugins:register_frontend + + - name: Test (Angular) + id: npm-test + run: npm test -- --code-coverage diff --git a/.github/workflows/version-check.yml b/.github/workflows/version-check.yml index a29d660332e..65cf0186a54 100644 --- a/.github/workflows/version-check.yml +++ b/.github/workflows/version-check.yml @@ -2,7 +2,7 @@ name: Check work package version on: pull_request: - types: [labeled, synchronize] + types: [labeled, synchronize, ready_for_review] permissions: contents: read # to fetch code (actions/checkout) @@ -10,7 +10,7 @@ permissions: jobs: version-check: - if: contains(github.event.pull_request.labels.*.name, 'needs review') + if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index 0a27bf8e565..a677a999f57 100644 --- a/.gitignore +++ b/.gitignore @@ -134,6 +134,8 @@ structure.sql lefthook-local.yml .rubocop-local.yml +/.lefthook-local/ + frontend/package-lock.json # Testing and nextcloud infrastructure diff --git a/.pkgr.yml b/.pkgr.yml index 62354658845..9c2820aaed0 100644 --- a/.pkgr.yml +++ b/.pkgr.yml @@ -21,7 +21,7 @@ targets: <<: *debian ubuntu-22.04: <<: *debian - centos-8: ¢os8 + centos-9: env: - NODE_ENV=production - NPM_CONFIG_PRODUCTION=false @@ -30,11 +30,6 @@ targets: - ImageMagick - unzip - poppler-utils - centos-9: - <<: *centos8 - env: - - NODE_ENV=production - - NPM_CONFIG_PRODUCTION=false sles-15: build_dependencies: - sqlite3-devel diff --git a/.rubocop.yml b/.rubocop.yml index d45f3c613d7..688262ff852 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,17 +1,18 @@ require: - rubocop-openproject - - rubocop-rails - - rubocop-rspec - rubocop-rspec_rails - rubocop-capybara - rubocop-factory_bot - - rubocop-performance - ./config/initializers/inflections.rb -<% if File.exist?('.rubocop-local.yml') %> +plugins: + - rubocop-rails + - rubocop-rspec + - rubocop-performance + +# A rubocop-local.yml file can be added to customized the styles inherit_from: - - .rubocop-local.yml -<% end %> + - .rubocop-local*.yml inherit_mode: merge: @@ -19,12 +20,18 @@ inherit_mode: - Exclude AllCops: - TargetRubyVersion: 3.3 + TargetRubyVersion: 3.4 # Enable any new cops in new versions by default NewCops: enable Exclude: - '**/node_modules/**/*' +# Disable it as it is deprecated +# From https://docs.rubocop.org/rubocop-capybara/cops_capybara.html#capybaraclicklinkorbuttonstyle +# "This cop is deprecated. We plan to remove this in the next major version update to 3.0." +Capybara/ClickLinkOrButtonStyle: + Enabled: false + FactoryBot/ConsistentParenthesesStyle: Enabled: false @@ -326,9 +333,6 @@ Style/ColonMethodCall: Style/CommentAnnotation: Enabled: false -Style/PreferredHashMethods: - Enabled: false - Style/Documentation: Enabled: false @@ -341,6 +345,9 @@ Style/EachWithObject: Style/EmptyLiteral: Enabled: false +Style/EndlessMethod: + Enabled: true + Style/EvenOdd: Enabled: false @@ -401,6 +408,9 @@ Style/PercentLiteralDelimiters: Style/PerlBackrefs: Enabled: false +Style/PreferredHashMethods: + Enabled: false + Style/Proc: Enabled: false @@ -453,7 +463,8 @@ Style/WordArray: Enabled: false Style/FrozenStringLiteralComment: - Enabled: false + Enabled: true + EnforcedStyle: always_true Style/NumericLiterals: Enabled: false diff --git a/.ruby-version b/.ruby-version index 9c25013dbb8..4d9d11cf505 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.6 +3.4.2 diff --git a/Gemfile b/Gemfile index 9168ac5dacc..e9a61ccde2c 100644 --- a/Gemfile +++ b/Gemfile @@ -36,7 +36,7 @@ ruby File.read(File.expand_path(".ruby-version", __dir__)).strip gem "actionpack-xml_parser", "~> 2.0.0" gem "activemodel-serializers-xml", "~> 1.0.1" -gem "activerecord-import", "~> 1.7.0" +gem "activerecord-import", "~> 2.1.0" gem "activerecord-session_store", "~> 2.1.0" gem "ox" gem "rails", "~> 7.2.2" @@ -46,7 +46,7 @@ gem "ffi", "~> 1.15" gem "rdoc", ">= 2.4.2" -gem "doorkeeper", "~> 5.7.0" +gem "doorkeeper", "~> 5.8.0" # 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" @@ -74,7 +74,7 @@ gem "addressable", "~> 2.8.0" gem "auto_strip_attributes", "~> 2.5" # Provide timezone info for TZInfo used by AR -gem "tzinfo-data", "~> 1.2024.1" +gem "tzinfo-data", "~> 1.2025.1" # to generate html-diffs (e.g. for wiki comparison) gem "htmldiff" @@ -83,7 +83,7 @@ gem "htmldiff" gem "stringex", "~> 2.8.5" # CommonMark markdown parser with GFM extension -gem "commonmarker", "~> 1.1.3" +gem "commonmarker", "~> 2.0.2" # HTML pipeline for transformations on text formatter output # such as sanitization or additional features @@ -93,9 +93,9 @@ gem "deckar01-task_list", "~> 2.3.1" # Requires escape-utils for faster escaping gem "escape_utils", "~> 1.3" # Syntax highlighting used in html-pipeline with rouge -gem "rouge", "~> 4.4.0" +gem "rouge", "~> 4.5.1" # HTML sanitization used for html-pipeline -gem "sanitize", "~> 6.1.0" +gem "sanitize", "~> 7.0.0" # HTML autolinking for mails and urls (replaces autolink) gem "rinku", "~> 2.0.4", require: %w[rinku rails_rinku] # Version parsing with semver @@ -107,7 +107,7 @@ gem "svg-graph", "~> 2.2.0" gem "date_validator", "~> 0.12.0" gem "email_validator", "~> 2.2.3" -gem "json_schemer", "~> 2.3.0" +gem "json_schemer", "~> 2.4.0" gem "ruby-duration", "~> 3.2.0" # `config/initializers/mail_starttls_patch.rb` has also been patched to @@ -126,7 +126,7 @@ 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 "good_job", "= 3.99.1" # update should be done manually in sync with saas-openproject version. gem "rack-protection", "~> 3.2.0" @@ -137,10 +137,10 @@ gem "rack-protection", "~> 3.2.0" gem "rack-attack", "~> 6.7.0" # CSP headers -gem "secure_headers", "~> 7.0.0" +gem "secure_headers", "~> 7.1.0" # Browser detection for incompatibility checks -gem "browser", "~> 6.0.0" +gem "browser", "~> 6.2.0" # Providing health checks gem "okcomputer", "~> 1.18.1" @@ -158,7 +158,7 @@ gem "structured_warnings", "~> 0.4.0" gem "airbrake", "~> 13.0.0", require: false gem "markly", "~> 0.10" # another markdown parser like commonmarker, but with AST support used in PDF export -gem "md_to_pdf", git: "https://github.com/opf/md-to-pdf", ref: "fe05b4f8bae8fd46f4fa93b8e0adee6295ef7388" +gem "md_to_pdf", git: "https://github.com/opf/md-to-pdf", ref: "66893683b94a5fe8f1dc9a60600773307209cdd2" gem "prawn", "~> 2.4" gem "ttfunk", "~> 1.7.0" # remove after https://github.com/prawnpdf/prawn/issues/1346 resolved. @@ -167,10 +167,13 @@ gem "matrix", "~> 0.4.2" gem "meta-tags", "~> 2.22.0" -gem "paper_trail", "~> 15.2.0" +gem "paper_trail", "~> 16.0.0" gem "op-clamav-client", "~> 3.4", require: "clamav" +# Recurring meeting events definition +gem "ice_cube", "~> 0.17.0" + group :production do # we use dalli as standard memcache client # requires memcached 1.4+ @@ -184,14 +187,11 @@ gem "rails-i18n", "~> 7.0.0" gem "sprockets", "~> 3.7.2" # lock sprockets below 4.0 gem "sprockets-rails", "~> 3.5.1" -# waiting for a release of puma to fix an issue with current rackup update -# see https://github.com/puma/puma/pull/3532 -# gem "puma", "~> 6.4" -gem "puma", github: "puma/puma", branch: "master" +gem "puma", "~> 6.5" gem "puma-plugin-statsd", "~> 2.0" gem "rack-timeout", "~> 0.7.0", require: "rack/timeout/base" -gem "nokogiri", "~> 1.16.0" +gem "nokogiri", "~> 1.18.1" gem "carrierwave", "~> 1.3.4" gem "carrierwave_direct", "~> 2.1.0" @@ -207,7 +207,7 @@ gem "plaintext", "~> 0.3.2" gem "ruby-progressbar", "~> 1.13.0", require: false -gem "mini_magick", "~> 5.0.1", require: false +gem "mini_magick", "~> 5.1.2", require: false gem "validate_url" @@ -218,7 +218,7 @@ gem "dry-monads" gem "dry-validation" # ActiveRecord extension which adds typecasting to store accessors -gem "store_attribute", "~> 1.0" +gem "store_attribute", "~> 2.0" # Appsignal integration gem "appsignal", "~> 3.10.0", require: false @@ -232,14 +232,19 @@ gem "factory_bot", "~> 6.5.0", require: false # require factory_bot_rails for convenience in core development gem "factory_bot_rails", "~> 6.4.4", require: false -gem "turbo_power", "~> 0.6.2" +gem "turbo_power", "~> 0.7.0" gem "turbo-rails", "~> 2.0.0" -gem "httpx" +# There is a problem with version 1.4.0. Do not update until you're sure there is no infinite hang +# happenning in failing tests when WebMock or VCR stub cannot be found. +gem "httpx", "~> 1.3.4" + +# Brings actual deep freezing to most ruby objects +gem "ice_nine" group :test do - gem "launchy", "~> 3.0.0" - gem "rack-test", "~> 2.1.0" + gem "launchy", "~> 3.1.0" + gem "rack-test", "~> 2.2.0" gem "shoulda-context", "~> 2.0" # Test prof provides factories from code @@ -250,7 +255,7 @@ group :test do gem "rack_session_access" gem "rspec", "~> 3.13.0" # also add to development group, so 'spec' rake task gets loaded - gem "rspec-rails", "~> 7.0.0", group: :development + gem "rspec-rails", "~> 7.1.0", group: :development # Retry failures within the same environment gem "retriable", "~> 3.1.1" @@ -272,9 +277,10 @@ group :test do 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_accessible_selectors", git: "https://github.com/citizensadvice/capybara_accessible_selectors", tag: "v0.12.0" gem "capybara-screenshot", "~> 1.0.17" gem "cuprite", "~> 0.15.0" + gem "ferrum", github: "toy/ferrum", ref: "mouse-events-buttons-property-0.15" gem "rspec-wait" gem "selenium-devtools" gem "selenium-webdriver", "~> 4.20" @@ -330,11 +336,11 @@ group :development, :test do # Output a stack trace anytime, useful when a process is stuck gem "rbtrace" - # REPL with debug commands - gem "debug" + # REPL with debug commands, Debug changed to byebug due to the issue below + # https://github.com/puma/puma/issues/2835#issuecomment-2302133927 + gem "byebug" gem "pry-byebug", "~> 3.10.0", platforms: [:mri] - gem "pry-doc" gem "pry-rails", "~> 0.3.6" gem "pry-rescue", "~> 1.6.0" @@ -353,7 +359,7 @@ group :development, :test do gem "erblint-github", require: false # Brakeman scanner - gem "brakeman", "~> 6.2.0" + gem "brakeman", "~> 7.0.0" # i18n-tasks helps find and manage missing and unused translations. gem "i18n-tasks", "~> 1.0.13", require: false @@ -401,6 +407,6 @@ gemfiles.each do |file| send(:eval_gemfile, file) if File.readable?(file) end -gem "openproject-octicons", "~>19.19.0" -gem "openproject-octicons_helper", "~>19.19.0" -gem "openproject-primer_view_components", "~>0.49.1" +gem "openproject-octicons", "~>19.20.0 " +gem "openproject-octicons_helper", "~>19.20.0 " +gem "openproject-primer_view_components", "~>0.56.0" diff --git a/Gemfile.lock b/Gemfile.lock index 0ecf57b76d8..f735525ac3b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,23 +1,25 @@ GIT remote: https://github.com/citizensadvice/capybara_accessible_selectors revision: 347bbe06cb420416855e80bb4e3a3016b2d5872c - branch: main + tag: v0.12.0 specs: capybara_accessible_selectors (0.11.0) capybara (~> 3.36) GIT remote: https://github.com/opf/md-to-pdf - revision: fe05b4f8bae8fd46f4fa93b8e0adee6295ef7388 - ref: fe05b4f8bae8fd46f4fa93b8e0adee6295ef7388 + revision: 66893683b94a5fe8f1dc9a60600773307209cdd2 + ref: 66893683b94a5fe8f1dc9a60600773307209cdd2 specs: - md_to_pdf (0.1.2) + md_to_pdf (0.2.0) + base64 (~> 0.2) + bigdecimal (~> 3.1) color_conversion (~> 0.1) front_matter_parser (~> 1.0) json-schema (~> 4.3) markly (~> 0.10) matrix (~> 0.4) - nokogiri (~> 1.16) + nokogiri (~> 1.18) prawn (~> 2.4) prawn-table (~> 0.2) text-hyphen (~> 1.5) @@ -33,10 +35,10 @@ GIT GIT remote: https://github.com/opf/omniauth-openid-connect.git - revision: d63f5967514d10db9ddece798dadfa2ac532cbe0 - ref: d63f5967514d10db9ddece798dadfa2ac532cbe0 + revision: 3d5fec65072fb4566fb975a9cbe401d758d22317 + ref: 3d5fec65072fb4566fb975a9cbe401d758d22317 specs: - omniauth-openid-connect (0.4.0) + omniauth-openid-connect (0.4.1) addressable (~> 2.5) omniauth (~> 1.6) openid_connect (~> 2.2.0) @@ -59,12 +61,15 @@ GIT rspec (>= 3.10) GIT - remote: https://github.com/puma/puma.git - revision: fba741b91780224a1db1c456645335b2dd7f27dd - branch: master + remote: https://github.com/toy/ferrum.git + revision: 889b29926f017530a0e087b1db0bc02747e437b1 + ref: mouse-events-buttons-property-0.15 specs: - puma (6.4.3) - nio4r (~> 2.0) + ferrum (0.15) + addressable (~> 2.5) + concurrent-ruby (~> 1.1) + webrick (~> 1.7) + websocket-driver (~> 0.7) PATH remote: modules/auth_plugins @@ -214,7 +219,7 @@ PATH remote: modules/two_factor_authentication specs: openproject-two_factor_authentication (1.0.0) - aws-sdk-sns (~> 1.88.0) + aws-sdk-sns (~> 1.94.0) messagebird-rest (~> 1.4.2) rotp (~> 6.1) webauthn (~> 3.0) @@ -233,68 +238,73 @@ PATH GEM remote: https://rubygems.org/ specs: - Ascii85 (1.1.1) - actioncable (7.2.2) - actionpack (= 7.2.2) - activesupport (= 7.2.2) + Ascii85 (2.0.1) + actioncable (7.1.5.1) + actionpack (= 7.1.5.1) + activesupport (= 7.1.5.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.2.2) - actionpack (= 7.2.2) - activejob (= 7.2.2) - activerecord (= 7.2.2) - activestorage (= 7.2.2) - activesupport (= 7.2.2) - mail (>= 2.8.0) - actionmailer (7.2.2) - actionpack (= 7.2.2) - actionview (= 7.2.2) - activejob (= 7.2.2) - activesupport (= 7.2.2) - mail (>= 2.8.0) + actionmailbox (7.1.5.1) + actionpack (= 7.1.5.1) + activejob (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) + mail (>= 2.7.1) + net-imap + net-pop + net-smtp + actionmailer (7.1.5.1) + actionpack (= 7.1.5.1) + actionview (= 7.1.5.1) + activejob (= 7.1.5.1) + activesupport (= 7.1.5.1) + mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.2) - actionpack (7.2.2) - actionview (= 7.2.2) - activesupport (= 7.2.2) + actionpack (7.1.5.1) + actionview (= 7.1.5.1) + activesupport (= 7.1.5.1) nokogiri (>= 1.8.5) racc - rack (>= 2.2.4, < 3.2) + rack (>= 2.2.4) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - useragent (~> 0.16) actionpack-xml_parser (2.0.1) actionpack (>= 5.0) railties (>= 5.0) - actiontext (7.2.2) - actionpack (= 7.2.2) - activerecord (= 7.2.2) - activestorage (= 7.2.2) - activesupport (= 7.2.2) + actiontext (7.1.5.1) + actionpack (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.2.2) - activesupport (= 7.2.2) + actionview (7.1.5.1) + activesupport (= 7.1.5.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.2.2) - activesupport (= 7.2.2) + activejob (7.1.5.1) + activesupport (= 7.1.5.1) globalid (>= 0.3.6) - activemodel (7.2.2) - activesupport (= 7.2.2) + activemodel (7.1.5.1) + activesupport (= 7.1.5.1) activemodel-serializers-xml (1.0.3) activemodel (>= 5.0.0.a) activesupport (>= 5.0.0.a) builder (~> 3.1) - activerecord (7.2.2) - activemodel (= 7.2.2) - activesupport (= 7.2.2) + activerecord (7.1.5.1) + activemodel (= 7.1.5.1) + activesupport (= 7.1.5.1) timeout (>= 0.4.0) - activerecord-import (1.7.0) + activerecord-import (2.1.0) activerecord (>= 4.2) activerecord-nulldb-adapter (1.1.1) activerecord (>= 6.0, < 8.1) @@ -305,25 +315,26 @@ GEM multi_json (~> 1.11, >= 1.11.2) rack (>= 2.0.8, < 4) railties (>= 6.1) - activestorage (7.2.2) - actionpack (= 7.2.2) - activejob (= 7.2.2) - activerecord (= 7.2.2) - activesupport (= 7.2.2) + activestorage (7.1.5.1) + actionpack (= 7.1.5.1) + activejob (= 7.1.5.1) + activerecord (= 7.1.5.1) + activesupport (= 7.1.5.1) marcel (~> 1.0) - activesupport (7.2.2) + activesupport (7.1.5.1) base64 benchmark (>= 0.3) bigdecimal - concurrent-ruby (~> 1.0, >= 1.3.1) + concurrent-ruby (~> 1.0, >= 1.0.2) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) logger (>= 1.4.2) minitest (>= 5.1) + mutex_m securerandom (>= 0.3) - tzinfo (~> 2.0, >= 2.0.5) - acts_as_list (1.2.3) + tzinfo (~> 2.0) + acts_as_list (1.2.4) activerecord (>= 6.1) activesupport (>= 6.1) acts_as_tree (2.9.1) @@ -332,7 +343,7 @@ GEM public_suffix (>= 2.0.2, < 7.0) aes_key_wrap (1.1.0) afm (0.2.2) - airbrake (13.0.4) + airbrake (13.0.5) airbrake-ruby (~> 6.0) airbrake-ruby (6.2.2) rbtree3 (~> 0.6) @@ -345,31 +356,32 @@ GEM activerecord (>= 4.0) awesome_nested_set (3.8.0) activerecord (>= 4.0.0, < 8.1) - aws-eventstream (1.3.0) - aws-partitions (1.1001.0) - aws-sdk-core (3.211.0) + aws-eventstream (1.3.1) + aws-partitions (1.1052.0) + aws-sdk-core (3.219.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) + base64 jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.95.0) - aws-sdk-core (~> 3, >= 3.210.0) + aws-sdk-kms (1.99.0) + aws-sdk-core (~> 3, >= 3.216.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.170.0) - aws-sdk-core (~> 3, >= 3.210.0) + aws-sdk-s3 (1.182.0) + aws-sdk-core (~> 3, >= 3.216.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) - aws-sdk-sns (1.88.0) - aws-sdk-core (~> 3, >= 3.207.0) + aws-sdk-sns (1.94.0) + aws-sdk-core (~> 3, >= 3.216.0) aws-sigv4 (~> 1.5) - aws-sigv4 (1.10.1) + aws-sigv4 (1.11.0) aws-eventstream (~> 1, >= 1.0.2) - axe-core-api (4.10.1) + axe-core-api (4.10.2) dumb_delegator ostruct virtus - axe-core-rspec (4.10.1) - axe-core-api (= 4.10.1) + axe-core-rspec (4.10.2) + axe-core-api (= 4.10.2) dumb_delegator ostruct virtus @@ -387,13 +399,13 @@ GEM erubi (~> 1.4) parser (>= 2.4) smart_properties - bigdecimal (3.1.8) + bigdecimal (3.1.9) bindata (2.5.0) bootsnap (1.18.4) msgpack (~> 1.2) - brakeman (6.2.2) + brakeman (7.0.0) racc - browser (6.0.0) + browser (6.2.0) builder (3.3.0) byebug (11.1.3) capybara (3.40.0) @@ -428,13 +440,17 @@ GEM coercible (1.0.0) descendants_tracker (~> 0.0.1) color_conversion (0.1.2) - colored2 (4.0.0) - commonmarker (1.1.5) + colored2 (4.0.3) + commonmarker (2.0.4) rb_sys (~> 0.9) + commonmarker (2.0.4-aarch64-linux) + commonmarker (2.0.4-arm64-darwin) + commonmarker (2.0.4-x86_64-darwin) + commonmarker (2.0.4-x86_64-linux) compare-xml (0.66) nokogiri (~> 1.8) - concurrent-ruby (1.3.4) - connection_pool (2.4.1) + concurrent-ruby (1.3.5) + connection_pool (2.5.0) cookiejar (0.3.4) cose (1.3.1) cbor (~> 0.5.9) @@ -443,21 +459,18 @@ GEM bigdecimal rexml crass (1.0.6) - css_parser (1.19.1) + css_parser (1.21.0) addressable - csv (3.3.0) + csv (3.3.2) cuprite (0.15.1) capybara (~> 3.0) ferrum (~> 0.15.0) daemons (1.4.1) dalli (3.2.8) - date (3.4.0) + date (3.4.1) date_validator (0.12.0) activemodel (>= 3) activesupport (>= 3) - debug (1.9.2) - irb (~> 1.10) - reline (>= 0.3.8) deckar01-task_list (2.3.4) html-pipeline (~> 2.0) declarative (0.0.20) @@ -467,56 +480,58 @@ GEM disposable (0.6.3) declarative (>= 0.0.9, < 1.0.0) representable (>= 3.1.1, < 4) - doorkeeper (5.7.1) + doorkeeper (5.8.1) railties (>= 5) - dotenv (3.1.4) - dotenv-rails (3.1.4) - dotenv (= 3.1.4) + dotenv (3.1.7) + dotenv-rails (3.1.7) + dotenv (= 3.1.7) railties (>= 6.1) drb (2.2.1) - dry-auto_inject (1.0.1) - dry-core (~> 1.0) + dry-auto_inject (1.1.0) + dry-core (~> 1.1) zeitwerk (~> 2.6) - dry-configurable (1.2.0) - dry-core (~> 1.0, < 2) + dry-configurable (1.3.0) + dry-core (~> 1.1) zeitwerk (~> 2.6) dry-container (0.11.0) concurrent-ruby (~> 1.0) - dry-core (1.0.1) + dry-core (1.1.0) concurrent-ruby (~> 1.0) + logger zeitwerk (~> 2.6) - dry-inflector (1.1.0) - dry-initializer (3.1.1) - dry-logic (1.5.0) + dry-inflector (1.2.0) + dry-initializer (3.2.0) + dry-logic (1.6.0) + bigdecimal concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 2) + dry-core (~> 1.1) zeitwerk (~> 2.6) - dry-monads (1.6.0) + dry-monads (1.7.1) concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 2) + dry-core (~> 1.1) zeitwerk (~> 2.6) - dry-schema (1.13.4) + dry-schema (1.14.0) concurrent-ruby (~> 1.0) dry-configurable (~> 1.0, >= 1.0.1) - dry-core (~> 1.0, < 2) - dry-initializer (~> 3.0) - dry-logic (>= 1.4, < 2) - dry-types (>= 1.7, < 2) + dry-core (~> 1.1) + dry-initializer (~> 3.2) + dry-logic (~> 1.5) + dry-types (~> 1.8) zeitwerk (~> 2.6) - dry-types (1.7.2) + dry-types (1.8.2) bigdecimal (~> 3.0) concurrent-ruby (~> 1.0) dry-core (~> 1.0) dry-inflector (~> 1.0) dry-logic (~> 1.4) zeitwerk (~> 2.6) - dry-validation (1.10.0) + dry-validation (1.11.1) concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 2) - dry-initializer (~> 3.0) - dry-schema (>= 1.12, < 2) + dry-core (~> 1.1) + dry-initializer (~> 3.2) + dry-schema (~> 1.14) zeitwerk (~> 2.6) - dumb_delegator (1.0.0) + dumb_delegator (1.1.0) em-http-request (1.1.7) addressable (>= 2.3.4) cookiejar (!= 0.3.1) @@ -532,7 +547,7 @@ GEM activemodel equivalent-xml (0.6.0) nokogiri (>= 1.4.3) - erb_lint (0.7.0) + erb_lint (0.9.0) activesupport better_html (>= 2.0.1) parser (>= 2.7.1.4) @@ -540,35 +555,40 @@ GEM rubocop (>= 1) smart_properties erblint-github (1.0.1) - erubi (1.13.0) + erubi (1.13.1) escape_utils (1.3.0) et-orbi (1.2.11) tzinfo eventmachine (1.2.7) eventmachine_httpserver (0.2.1) - excon (1.0.0) - factory_bot (6.5.0) - activesupport (>= 5.0.0) + excon (1.2.3) + factory_bot (6.5.1) + activesupport (>= 6.1.0) factory_bot_rails (6.4.4) factory_bot (~> 6.5) railties (>= 5.0.0) - faraday (2.12.0) - faraday-net_http (>= 2.0, < 3.4) + faraday (2.12.2) + faraday-net_http (>= 2.0, < 3.5) json logger faraday-follow_redirects (0.3.0) faraday (>= 1, < 3) - faraday-net_http (3.3.0) - net-http + faraday-net_http (3.4.0) + net-http (>= 0.5.0) fastimage (2.3.1) - ferrum (0.15) - addressable (~> 2.5) - concurrent-ruby (~> 1.1) - webrick (~> 1.7) - websocket-driver (~> 0.7) - ffi (1.17.0) + ffi (1.17.1) + ffi (1.17.1-aarch64-linux-gnu) + ffi (1.17.1-aarch64-linux-musl) + ffi (1.17.1-arm-linux-gnu) + ffi (1.17.1-arm-linux-musl) + ffi (1.17.1-arm64-darwin) + ffi (1.17.1-x86-linux-gnu) + ffi (1.17.1-x86-linux-musl) + ffi (1.17.1-x86_64-darwin) + ffi (1.17.1-x86_64-linux-gnu) + ffi (1.17.1-x86_64-linux-musl) flamegraph (0.9.5) - fog-aws (3.29.0) + fog-aws (3.30.0) base64 (~> 0.2.0) fog-core (~> 2.6) fog-json (~> 1.1) @@ -581,7 +601,7 @@ GEM fog-json (1.2.0) fog-core multi_json (~> 1.10) - fog-xml (0.1.4) + fog-xml (0.1.5) fog-core nokogiri (>= 1.5.11, < 2.0.0) formatador (1.1.0) @@ -602,14 +622,14 @@ GEM i18n (>= 0.7) multi_json request_store (>= 1.0) - good_job (3.26.2) + good_job (3.99.1) 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.15.1) + google-apis-core (0.16.0) addressable (~> 2.5, >= 2.5.1) googleauth (~> 1.9) httpclient (>= 2.8.3, < 3.a) @@ -621,9 +641,11 @@ GEM google-apis-core (>= 0.15.0, < 2.a) google-cloud-env (2.2.1) faraday (>= 1.0, < 3.a) - googleauth (1.11.2) + google-logging-utils (0.1.0) + googleauth (1.13.1) faraday (>= 1.0, < 3.a) - google-cloud-env (~> 2.1) + google-cloud-env (~> 2.2) + google-logging-utils (~> 0.1) jwt (>= 1.4, < 3.0) multi_json (~> 1.11) os (>= 0.9, < 2.0) @@ -639,10 +661,10 @@ GEM rack gravatar_image_tag (1.2.0) hana (1.3.7) - hashdiff (1.1.1) + hashdiff (1.1.2) hashery (2.1.2) hashie (3.6.0) - highline (3.1.1) + highline (3.1.2) reline html-pipeline (2.14.3) activesupport (>= 2) @@ -650,12 +672,12 @@ GEM htmlbeautifier (1.4.3) htmldiff (0.0.1) htmlentities (4.3.4) - http-2 (1.0.1) + http-2 (1.0.2) http_parser.rb (0.6.0) httpclient (2.8.3) - httpx (1.3.1) + httpx (1.3.4) http-2 (>= 1.0.0) - i18n (1.14.6) + i18n (1.14.7) concurrent-ruby (~> 1.0) i18n-js (4.2.3) glob (>= 0.4.0) @@ -676,13 +698,14 @@ GEM ice_cube (0.17.0) ice_nine (0.11.2) interception (0.5) - io-console (0.7.2) - irb (1.14.1) + io-console (0.8.0) + irb (1.15.1) + pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) iso8601 (0.13.0) jmespath (1.6.2) - json (2.7.4) + json (2.10.1) json-jwt (1.16.7) activesupport (>= 4.2) aes_key_wrap @@ -692,7 +715,7 @@ GEM faraday-follow_redirects json-schema (4.3.1) addressable (>= 2.8) - json_schemer (2.3.0) + json_schemer (2.4.0) bigdecimal hana (~> 1.3) regexp_parser (~> 2.0) @@ -700,15 +723,16 @@ GEM json_spec (1.1.5) multi_json (~> 1.0) rspec (>= 2.0, < 4.0) - jwt (2.9.3) + jwt (2.10.1) base64 ladle (1.0.1) open4 (~> 1.0) - language_server-protocol (3.17.0.3) - launchy (3.0.1) + language_server-protocol (3.17.0.4) + launchy (3.1.1) addressable (~> 2.8) childprocess (~> 5.0) - lefthook (1.8.2) + logger (~> 1.6) + lefthook (1.11.2) letter_opener (1.10.0) launchy (>= 2.2, < 4) letter_opener_web (3.0.0) @@ -716,6 +740,7 @@ GEM letter_opener (~> 1.9) railties (>= 6.1) rexml + lint_roller (1.1.0) listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -723,13 +748,13 @@ GEM omniauth (~> 1.1) omniauth-openid-connect (>= 0.2.1) rails (>= 3.2.21) - logger (1.6.1) + logger (1.6.6) lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.23.1) + loofah (2.24.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) lookbook (2.3.4) @@ -759,21 +784,23 @@ GEM mime-types (3.6.0) logger mime-types-data (~> 3.2015) - mime-types-data (3.2024.1001) - mini_magick (5.0.1) + mime-types-data (3.2025.0204) + mini_magick (5.1.2) + benchmark + logger mini_mime (1.1.5) mini_portile2 (2.8.8) - minitest (5.25.1) - msgpack (1.7.3) + minitest (5.25.4) + msgpack (1.8.0) multi_json (1.15.0) mustermann (3.0.3) ruby2_keywords (~> 0.0.1) mustermann-grape (1.1.0) mustermann (>= 1.0.0) - mutex_m (0.2.0) - net-http (0.4.1) + mutex_m (0.3.0) + net-http (0.6.0) uri - net-imap (0.5.1) + net-imap (0.5.6) date net-protocol net-ldap (0.19.0) @@ -781,16 +808,32 @@ GEM net-protocol net-protocol (0.2.2) timeout - net-smtp (0.5.0) + net-smtp (0.5.1) net-protocol nio4r (2.7.4) - nokogiri (1.16.7) + nokogiri (1.18.3) mini_portile2 (~> 2.8.2) racc (~> 1.4) - oj (3.16.6) + nokogiri (1.18.3-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.3-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.18.3-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.3-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.18.3-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.3-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.18.3-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.3-x86_64-linux-musl) + racc (~> 1.4) + oj (3.16.10) bigdecimal (>= 3.0) ostruct (>= 0.2) - okcomputer (1.18.5) + okcomputer (1.18.6) omniauth-saml (1.10.5) omniauth (~> 1.3, >= 1.3.2) ruby-saml (~> 1.17) @@ -808,39 +851,40 @@ GEM validate_email validate_url webfinger (~> 2.0) - openproject-octicons (19.19.0) - openproject-octicons_helper (19.19.0) + openproject-octicons (19.20.0) + openproject-octicons_helper (19.20.0) actionview - openproject-octicons (= 19.19.0) + openproject-octicons (= 19.20.0) railties - openproject-primer_view_components (0.49.1) + openproject-primer_view_components (0.55.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) - openproject-octicons (>= 19.17.0) + openproject-octicons (>= 19.20.0) view_component (>= 3.1, < 4.0) openproject-token (4.0.0) activemodel - openssl (3.2.0) + openssl (3.3.0) openssl-signature_algorithm (1.3.0) openssl (> 2.0) - optimist (3.1.0) + optimist (3.2.0) os (1.1.4) - ostruct (0.6.0) - ox (2.14.18) - paper_trail (15.2.0) + ostruct (0.6.1) + ox (2.14.22) + bigdecimal (>= 3.0) + paper_trail (16.0.0) activerecord (>= 6.1) request_store (~> 1.4) parallel (1.26.3) - parallel_tests (4.7.2) + parallel_tests (4.9.1) parallel - parser (3.3.5.0) + parser (3.3.7.1) ast (~> 2.4.1) racc pdf-core (0.9.0) pdf-inspector (1.3.0) pdf-reader (>= 1.0, < 3.0.a) - pdf-reader (2.12.0) - Ascii85 (~> 1.0) + pdf-reader (2.14.1) + Ascii85 (>= 1.0, < 3.0, != 2.0.0) afm (~> 0.2.1) hashery (~> 2.0) ruby-rc4 @@ -850,26 +894,27 @@ GEM activesupport (> 2.2.1) nokogiri (~> 1.10, >= 1.10.4) rubyzip (>= 1.2.0) + pp (0.6.2) + prettyprint prawn (2.4.0) pdf-core (~> 0.9.0) ttfunk (~> 1.7) prawn-table (0.2.2) prawn (>= 1.3.0, < 3.0.0) + prettyprint (0.2.0) pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) pry-byebug (3.10.1) byebug (~> 11.0) pry (>= 0.13, < 0.15) - pry-doc (1.5.0) - pry (~> 0.11) - yard (~> 0.9.11) pry-rails (0.3.11) pry (>= 0.13.0) pry-rescue (1.6.0) interception (>= 0.5) pry (>= 0.12.0) - psych (5.2.0) + psych (5.2.3) + date stringio public_suffix (6.0.1) puffing-billy (4.0.0) @@ -880,11 +925,13 @@ GEM eventmachine_httpserver http_parser.rb (~> 0.6.0) multi_json + puma (6.6.0) + nio4r (~> 2.0) puma-plugin-statsd (2.6.0) puma (>= 5.0, < 7) raabro (1.4.0) racc (1.8.1) - rack (2.2.10) + rack (2.2.11) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-cors (2.0.2) @@ -903,7 +950,7 @@ GEM rack (~> 2.2, >= 2.2.4) rack-session (1.0.2) rack (< 3) - rack-test (2.1.0) + rack-test (2.2.0) rack (>= 1.3) rack-timeout (0.7.0) rack_session_access (0.2.0) @@ -912,20 +959,20 @@ GEM rackup (1.0.1) rack (< 3) webrick - rails (7.2.2) - actioncable (= 7.2.2) - actionmailbox (= 7.2.2) - actionmailer (= 7.2.2) - actionpack (= 7.2.2) - actiontext (= 7.2.2) - actionview (= 7.2.2) - activejob (= 7.2.2) - activemodel (= 7.2.2) - activerecord (= 7.2.2) - activestorage (= 7.2.2) - activesupport (= 7.2.2) + rails (7.1.5.1) + actioncable (= 7.1.5.1) + actionmailbox (= 7.1.5.1) + actionmailer (= 7.1.5.1) + actionpack (= 7.1.5.1) + actiontext (= 7.1.5.1) + actionview (= 7.1.5.1) + activejob (= 7.1.5.1) + activemodel (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) bundler (>= 1.15.0) - railties (= 7.2.2) + railties (= 7.1.5.1) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -934,41 +981,43 @@ GEM activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.0) + rails-html-sanitizer (1.6.2) loofah (~> 2.21) - nokogiri (~> 1.14) - rails-i18n (7.0.9) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + rails-i18n (7.0.10) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.2.2) - actionpack (= 7.2.2) - activesupport (= 7.2.2) - irb (~> 1.13) + railties (7.1.5.1) + actionpack (= 7.1.5.1) + activesupport (= 7.1.5.1) + irb rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.2.1) + rake-compiler-dock (1.9.1) rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rb_sys (0.9.102) + rb_sys (0.9.110) + rake-compiler-dock (= 1.9.1) rbtrace (0.5.1) ffi (>= 1.0.6) msgpack (>= 0.4.3) optimist (>= 3.0.0) rbtree3 (0.7.1) - rdoc (6.8.0) + rdoc (6.12.0) psych (>= 4.0.0) - recaptcha (5.17.0) + recaptcha (5.19.0) redcarpet (3.6.0) redis (5.3.0) redis-client (>= 0.22.0) - redis-client (0.22.2) + redis-client (0.23.2) connection_pool - regexp_parser (2.9.2) - reline (0.5.11) + regexp_parser (2.10.0) + reline (0.6.0) io-console (~> 0.5) representable (3.2.0) declarative (< 0.1.0) @@ -980,17 +1029,17 @@ GEM actionpack (>= 5.2) railties (>= 5.2) retriable (3.1.2) - rexml (3.3.9) + rexml (3.4.1) rinku (2.0.6) roar (1.2.0) representable (~> 3.1) rotp (6.3.0) - rouge (4.4.0) + rouge (4.5.1) rspec (3.13.0) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) rspec-mocks (~> 3.13.0) - rspec-core (3.13.2) + rspec-core (3.13.3) rspec-support (~> 3.13.0) rspec-expectations (3.13.3) diff-lcs (>= 1.2.0, < 2.0) @@ -998,7 +1047,7 @@ GEM rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (7.0.1) + rspec-rails (7.1.1) actionpack (>= 7.0) activesupport (>= 7.0) railties (>= 7.0) @@ -1008,20 +1057,21 @@ GEM rspec-support (~> 3.13) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.13.1) + rspec-support (3.13.2) rspec-wait (1.0.1) rspec (>= 3.4) - rubocop (1.67.0) + rubocop (1.73.0) json (~> 2.3) - language_server-protocol (>= 3.17.0) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 2.4, < 3.0) - rubocop-ast (>= 1.32.2, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.38.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.3) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.38.1) parser (>= 3.3.1.0) rubocop-capybara (2.21.0) rubocop (~> 1.41) @@ -1029,16 +1079,19 @@ GEM rubocop (~> 1.61) rubocop-openproject (0.2.0) rubocop - rubocop-performance (1.22.1) - rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.27.0) + rubocop-performance (1.24.0) + lint_roller (~> 1.1) + rubocop (>= 1.72.1, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) + rubocop-rails (2.30.2) activesupport (>= 4.2.0) + lint_roller (~> 1.1) rack (>= 1.1) - rubocop (>= 1.52.0, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (3.2.0) - rubocop (~> 1.61) + rubocop (>= 1.72.1, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) + rubocop-rspec (3.5.0) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) rubocop-rspec_rails (2.30.0) rubocop (~> 1.61) rubocop-rspec (~> 3, >= 3.0.1) @@ -1054,19 +1107,19 @@ GEM nokogiri (>= 1.13.10) rexml ruby2_keywords (0.0.5) - rubytree (2.1.0) - json (~> 2.0, > 2.3.1) + rubytree (2.1.1) + json (~> 2.0, > 2.9) rubyzip (2.3.2) safety_net_attestation (0.4.0) jwt (~> 2.0) - sanitize (6.1.3) + sanitize (7.0.0) crass (~> 1.0.2) - nokogiri (>= 1.12.0) - secure_headers (7.0.0) - securerandom (0.3.2) - selenium-devtools (0.129.0) + nokogiri (>= 1.16.8) + secure_headers (7.1.0) + securerandom (0.4.1) + selenium-devtools (0.133.0) selenium-webdriver (~> 4.2) - selenium-webdriver (4.26.0) + selenium-webdriver (4.29.1) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) @@ -1083,7 +1136,7 @@ GEM multi_json (~> 1.10) simpleidn (0.2.3) smart_properties (1.17.0) - spreadsheet (1.3.1) + spreadsheet (1.3.3) bigdecimal ruby-ole spring (4.2.1) @@ -1100,8 +1153,8 @@ GEM activesupport (>= 6.1) sprockets (>= 3.0.0) ssrf_filter (1.0.8) - stackprof (0.2.26) - store_attribute (1.3.1) + stackprof (0.2.27) + store_attribute (2.0.0) activerecord (>= 6.1) stringex (2.8.6) stringio (3.1.2) @@ -1115,15 +1168,15 @@ GEM sys-filesystem (1.5.3) ffi (~> 1.1) table_print (1.5.7) - terminal-table (3.0.2) - unicode-display_width (>= 1.1.1, < 3) - test-prof (1.4.2) + terminal-table (4.0.0) + unicode-display_width (>= 1.1.1, < 4) + test-prof (1.4.4) text-hyphen (1.5.0) thor (1.3.2) thread_safe (0.3.6) timecop (0.9.10) - timeout (0.4.2) - tpm-key_attestation (0.12.1) + timeout (0.4.3) + tpm-key_attestation (0.14.0) bindata (~> 2.4) openssl (> 2.0) openssl-signature_algorithm (~> 1.0) @@ -1132,18 +1185,19 @@ GEM turbo-rails (2.0.11) actionpack (>= 6.0.0) railties (>= 6.0.0) - turbo_power (0.6.2) + turbo_power (0.7.0) turbo-rails (>= 1.3.0) typed_dag (2.0.2) rails (>= 5.0.4) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2024.2) + tzinfo-data (1.2025.1) tzinfo (>= 1.0.0) uber (0.1.0) - unicode-display_width (2.6.0) - uri (0.13.1) - useragent (0.16.10) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) + uri (1.0.2) validate_email (0.1.6) activemodel (>= 3.0) mail (>= 2.2.5) @@ -1152,8 +1206,8 @@ GEM public_suffix vcr (6.3.1) base64 - vernier (1.3.1) - view_component (3.20.0) + vernier (1.5.0) + view_component (3.21.0) activesupport (>= 5.2.0, < 8.1) concurrent-ruby (~> 1.0) method_source (~> 1.0) @@ -1165,25 +1219,26 @@ GEM rack (>= 2.0.9) warden-basic_auth (0.2.1) warden (~> 1.2) - webauthn (3.2.2) + webauthn (3.4.0) android_key_attestation (~> 0.3.0) bindata (~> 2.4) cbor (~> 0.5.9) cose (~> 1.1) openssl (>= 2.2) safety_net_attestation (~> 0.4.0) - tpm-key_attestation (~> 0.12.0) + tpm-key_attestation (~> 0.14.0) webfinger (2.1.3) activesupport faraday (~> 2.0) faraday-follow_redirects - webmock (3.24.0) + webmock (3.25.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.9.0) + webrick (1.9.1) websocket (1.2.11) - websocket-driver (0.7.6) + websocket-driver (0.7.7) + base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) will_paginate (4.0.1) @@ -1196,13 +1251,25 @@ GEM zeitwerk (2.7.1) PLATFORMS + aarch64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl DEPENDENCIES actionpack-xml_parser (~> 2.0.0) activemodel-serializers-xml (~> 1.0.1) - activerecord-import (~> 1.7.0) - activerecord-nulldb-adapter (~> 1.1.1) + activerecord-import (~> 2.1.0) + activerecord-nulldb-adapter (~> 1.1.0) activerecord-session_store (~> 2.1.0) acts_as_list (~> 1.2.0) acts_as_tree (~> 2.9.0) @@ -1216,9 +1283,10 @@ DEPENDENCIES axe-core-rspec bcrypt (~> 3.1.6) bootsnap (~> 1.18.0) - brakeman (~> 6.2.0) - browser (~> 6.0.0) + brakeman (~> 7.0.0) + browser (~> 6.2.0) budgets! + byebug capybara (~> 3.40.0) capybara-screenshot (~> 1.0.17) capybara_accessible_selectors! @@ -1227,7 +1295,7 @@ DEPENDENCIES climate_control closure_tree (~> 7.4.0) colored2 - commonmarker (~> 1.1.3) + commonmarker (~> 2.0.2) compare-xml (~> 0.66) costs! csv (~> 3.3) @@ -1236,10 +1304,9 @@ DEPENDENCIES dalli (~> 3.2.0) dashboards! date_validator (~> 0.12.0) - debug deckar01-task_list (~> 2.3.1) disposable (~> 0.6.2) - doorkeeper (~> 5.7.0) + doorkeeper (~> 5.8.0) dotenv-rails dry-auto_inject dry-container @@ -1252,13 +1319,14 @@ DEPENDENCIES escape_utils (~> 1.3) factory_bot (~> 6.5.0) factory_bot_rails (~> 6.4.4) + ferrum! ffi (~> 1.15) flamegraph fog-aws friendly_id (~> 5.5.0) fuubar (~> 2.5.0) gon (~> 6.4.0) - good_job (= 3.26.2) + good_job (= 3.99.1) google-apis-gmail_v1 googleauth grape (~> 2.2.0) @@ -1266,13 +1334,15 @@ DEPENDENCIES grids! html-pipeline (~> 2.14.0) htmldiff - httpx + httpx (~> 1.3.4) i18n-js (~> 4.2.3) i18n-tasks (~> 1.0.13) - json_schemer (~> 2.3.0) + ice_cube (~> 0.17.0) + ice_nine + json_schemer (~> 2.4.0) json_spec (~> 1.1.4) ladle - launchy (~> 3.0.0) + launchy (~> 3.1.0) lefthook letter_opener_web listen (~> 3.9.0) @@ -1283,11 +1353,11 @@ DEPENDENCIES matrix (~> 0.4.2) md_to_pdf! meta-tags (~> 2.22.0) - mini_magick (~> 5.0.1) + mini_magick (~> 5.1.2) multi_json (~> 1.15.0) my_page! net-ldap (~> 0.19.0) - nokogiri (~> 1.16.0) + nokogiri (~> 1.18.1) oj (~> 3.16.0) okcomputer (~> 1.18.1) omniauth! @@ -1309,10 +1379,10 @@ DEPENDENCIES openproject-job_status! openproject-ldap_groups! openproject-meeting! - openproject-octicons (~> 19.19.0) - openproject-octicons_helper (~> 19.19.0) + openproject-octicons (~> 19.20.0) + openproject-octicons_helper (~> 19.20.0) openproject-openid_connect! - openproject-primer_view_components (~> 0.49.1) + openproject-primer_view_components (~> 0.55.0) openproject-recaptcha! openproject-reporting! openproject-storages! @@ -1323,27 +1393,26 @@ DEPENDENCIES openproject-xls_export! overviews! ox - paper_trail (~> 15.2.0) + paper_trail (~> 16.0.0) parallel_tests (~> 4.0) pdf-inspector (~> 1.2) pg (~> 1.5.0) plaintext (~> 0.3.2) prawn (~> 2.4) pry-byebug (~> 3.10.0) - pry-doc pry-rails (~> 0.3.6) pry-rescue (~> 1.6.0) puffing-billy (~> 4.0.0) - puma! + puma (~> 6.5) puma-plugin-statsd (~> 2.0) rack-attack (~> 6.7.0) rack-cors (~> 2.0.2) rack-mini-profiler rack-protection (~> 3.2.0) - rack-test (~> 2.1.0) + rack-test (~> 2.2.0) rack-timeout (~> 0.7.0) rack_session_access - rails (~> 7.2.2) + rails (~> 7.1.3) rails-controller-testing (~> 1.0.2) rails-i18n (~> 7.0.0) rbtrace @@ -1354,9 +1423,9 @@ DEPENDENCIES retriable (~> 3.1.1) rinku (~> 2.0.4) roar (~> 1.2.0) - rouge (~> 4.4.0) + rouge (~> 4.5.1) rspec (~> 3.13.0) - rspec-rails (~> 7.0.0) + rspec-rails (~> 7.1.0) rspec-retry (~> 0.6.1) rspec-wait rubocop @@ -1371,8 +1440,8 @@ DEPENDENCIES ruby-prof ruby-progressbar (~> 1.13.0) rubytree (~> 2.1.0) - sanitize (~> 6.1.0) - secure_headers (~> 7.0.0) + sanitize (~> 7.0.0) + secure_headers (~> 7.1.0) selenium-devtools selenium-webdriver (~> 4.20) semantic (~> 1.6.1) @@ -1384,7 +1453,7 @@ DEPENDENCIES sprockets (~> 3.7.2) sprockets-rails (~> 3.5.1) stackprof - store_attribute (~> 1.0) + store_attribute (~> 2.0) stringex (~> 2.8.5) structured_warnings (~> 0.4.0) svg-graph (~> 2.2.0) @@ -1394,10 +1463,10 @@ DEPENDENCIES timecop (~> 0.9.0) ttfunk (~> 1.7.0) turbo-rails (~> 2.0.0) - turbo_power (~> 0.6.2) + turbo_power (~> 0.7.0) turbo_tests! typed_dag (~> 2.0.2) - tzinfo-data (~> 1.2024.1) + tzinfo-data (~> 1.2025.1) validate_url vcr vernier @@ -1408,8 +1477,452 @@ DEPENDENCIES will_paginate (~> 4.0.0) with_advisory_lock (~> 5.1.0) +CHECKSUMS + Ascii85 (2.0.1) sha256=15cb5d941808543cbb9e7e6aea3c8ec3877f154c3461e8b3673e97f7ecedbe5a + actioncable (7.1.5.1) sha256=764637b5b2d97b94e412d562c177bfd16b0fd769d55c98846362f5263e8aaa0d + actionmailbox (7.1.5.1) sha256=c3c20589fe43e6fa88bba2d76a6f9805ffdd02531f4a9a4af8197d59f5a5360a + actionmailer (7.1.5.1) sha256=b213d6d880b23b093ccfef3b4f87a3d27e4666442f71b5b634b2d19e19a49759 + actionpack (7.1.5.1) sha256=2bc263d9f43f16cc3b3360f59659ab11f140577602f371f1a968e2672b38d718 + actionpack-xml_parser (2.0.1) sha256=40cb461ee99445314ab580a783fb7413580deb8b28113c9e70ecd7c1b334d5e6 + actiontext (7.1.5.1) sha256=b8e261cfad5bc6a78b3f15be5e7c7f32190041b3dc6f027a3a353b4392d2f7ec + actionview (7.1.5.1) sha256=8c559a213501798e29b50b5341a643a70bbf6fa0aa2abaf571d0efc59dc4f6aa + activejob (7.1.5.1) sha256=7633376c857f4c491d06b5a7f5d86d9f07afc595398354a3f1abe80eb7e35767 + activemodel (7.1.5.1) sha256=74727466854a7fbdfe8f2702ca3112b23877500d4926bf7e02e921ad542191f1 + activemodel-serializers-xml (1.0.3) sha256=fa1b16305e7254cc58a59c68833e3c0a593a59c8ab95d3be5aaea7cd9416c397 + activerecord (7.1.5.1) sha256=f40ad1609bf33b9ba5bdc4e16d80a77b1517153234ceb413d31d635d7b91f1e3 + activerecord-import (2.1.0) sha256=7b1bc586c4b636e125c18f533c9ac4421dd2dbac8f4865dbf576382a338c2c94 + activerecord-nulldb-adapter (1.1.1) sha256=034c91106183b954b072fba14c2786adf1a2b9e852ce04f85f823afaf03e9820 + activerecord-session_store (2.1.0) sha256=f8453b1d618d0c8744683f0808fda4c01c9a93508301316299dd1b9756662374 + activestorage (7.1.5.1) sha256=ae6b8b076858c666eaad6f896d786b67654235e861e24a83f61f1cc97b43ff63 + activesupport (7.1.5.1) sha256=9f0c482e473b9868cb3dfe3e9db549a3bd2302c02e4f595a5caac144a8c7cfb8 + acts_as_list (1.2.4) sha256=5e6ed695f1879d66ae7d8eb1625a72db215a26a9c8ec0047b866a80883ea5651 + acts_as_tree (2.9.1) sha256=b869eb10a8de38616b64ffcf9e882d3d99c8e06909c4057078a76c3b89a9a2f3 + addressable (2.8.7) sha256=462986537cf3735ab5f3c0f557f14155d778f4b43ea4f485a9deb9c8f7c58232 + aes_key_wrap (1.1.0) sha256=b935f4756b37375895db45669e79dfcdc0f7901e12d4e08974d5540c8e0776a5 + afm (0.2.2) sha256=c83e698e759ab0063331ff84ca39c4673b03318f4ddcbe8e90177dd01e4c721a + airbrake (13.0.5) sha256=901f5074c25d5ef77ed87f5bde7a28400a7324f5d7013a8a12d07e0099cc31b6 + airbrake-ruby (6.2.2) sha256=293e34fb36e763e1b6d67ab584cce7c5b6fe9eea1a70c26d8c13c0f5d7de2fbc + android_key_attestation (0.3.0) sha256=467eb01a99d2bb48ef9cf24cc13712669d7056cba5a52d009554ff037560570b + appsignal (3.10.0) sha256=2a18f3253afdf2fc2d7f9e43d5118976c05a614934abcbb29bb84000d047b61b + ast (2.4.2) sha256=1e280232e6a33754cde542bc5ef85520b74db2aac73ec14acef453784447cc12 + attr_required (1.0.2) sha256=f0ebfc56b35e874f4d0ae799066dbc1f81efefe2364ca3803dc9ea6a4de6cb99 + auto_strip_attributes (2.6.0) sha256=a7e2e0cf744de2bcd947fd68014220702bcc88c81274c1cd9ce6f7316aae39b0 + awesome_nested_set (3.8.0) sha256=469daff411d80291dbb80d1973133e498048a7afc2519c545f62d2cdebc60eda + aws-eventstream (1.3.1) sha256=4465b2add71d69a36fb1268a738d9b3d1a593c789e0286f28fad38e132d4403b + aws-partitions (1.1052.0) sha256=4dfe9876211c11433cab7fbb3e693c1837f8a89aaf634678f82d5431b2d7c829 + aws-sdk-core (3.219.0) sha256=d10c3832ece1f1de8edb7cbbcd737dd49b2789fae8744537943e86fdd822c649 + aws-sdk-kms (1.99.0) sha256=ba292fc3ffd672532aae2601fe55ff424eee78da8e23c23ba6ce4037138275a8 + aws-sdk-s3 (1.182.0) sha256=d0fc3579395cb6cb69bf6e975240ce031fc673190e74c8dddbdd6c18572b450d + aws-sdk-sns (1.94.0) sha256=6cf0b27e045a5021c6a8925957e389d0bd570cca2485f33b50745caa4fd1f06d + aws-sigv4 (1.11.0) sha256=50a8796991a862324442036ad7a395920572b84bb6cd29b945e5e1800e8da1db + axe-core-api (4.10.2) sha256=c84ea0a041380a329f38fcfbc32b3759d35b481a27a368471e93afba5aafb289 + axe-core-rspec (4.10.2) sha256=e302be5807e40eaa170f45559b2067791dfc42a58cb4400d2d6217321f12f775 + axiom-types (0.1.1) sha256=c1ff113f3de516fa195b2db7e0a9a95fd1b08475a502ff660d04507a09980383 + base64 (0.2.0) sha256=0f25e9b21a02a0cc0cea8ef92b2041035d39350946e8789c562b2d1a3da01507 + bcrypt (3.1.20) sha256=8410f8c7b3ed54a3c00cd2456bf13917d695117f033218e2483b2e40b0784099 + benchmark (0.4.0) sha256=0f12f8c495545e3710c3e4f0480f63f06b4c842cc94cec7f33a956f5180e874a + better_html (2.1.1) sha256=046c3551d1488a3f2939a7cac6fabf2bde08c32e135c91fcd683380118e5af55 + bigdecimal (3.1.9) sha256=2ffc742031521ad69c2dfc815a98e426a230a3d22aeac1995826a75dabfad8cc + bindata (2.5.0) sha256=29dccb8ba1cc9de148f24bb88930840c62db56715f0f80eccadd624d9f3d2623 + bootsnap (1.18.4) sha256=ac4c42af397f7ee15521820198daeff545e4c360d2772c601fbdc2c07d92af55 + brakeman (7.0.0) sha256=1a0122b0c70f17519a61548a53a332c0acc19e3aa10b445e15e025a4b13b8577 + browser (6.2.0) sha256=281d5295788825c9396427c292c2d2be0a5c91875c93c390fde6e5d61a5ace2d + budgets (1.0.0) + builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f + byebug (11.1.3) sha256=2485944d2bb21283c593d562f9ae1019bf80002143cc3a255aaffd4e9cf4a35b + capybara (3.40.0) sha256=42dba720578ea1ca65fd7a41d163dd368502c191804558f6e0f71b391054aeef + capybara-screenshot (1.0.26) sha256=816b9370a07752097c82a05f568aaf5d3b7f45c3db5d3aab2014071e1b3c0c77 + capybara_accessible_selectors (0.11.0) + carrierwave (1.3.4) sha256=81772dabd1830edbd7f4526d2ae2c79f974f1d48900c3f03f7ecb7c657463a21 + carrierwave_direct (2.1.0) sha256=b0d5c19c1d17a05940e488cff644a3b2946422d6d494b2174b48f6a90c5dddbf + cbor (0.5.9.8) sha256=9ee097fc58d9bc5e406d112cd2d4e112c7354ec16f8b6ff34e4732c1e44b4eb7 + cgi (0.4.1) sha256=4349e1e2025c9cc73534c52c93cffc0dafc93e0a81edc0830d851a3b2c49a430 + childprocess (5.1.0) sha256=9a8d484be2fd4096a0e90a0cd3e449a05bc3aa33f8ac9e4d6dcef6ac1455b6ec + climate_control (1.2.0) sha256=36b21896193fa8c8536fa1cd843a07cf8ddbd03aaba43665e26c53ec1bd70aa5 + closure_tree (7.4.0) sha256=e39171bbe35de3c06898c3caf2d2949bba2d379aa78fc1a03c1c63f165c1d2b5 + coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b + coercible (1.0.0) sha256=5081ad24352cc8435ce5472bc2faa30260c7ea7f2102cc6a9f167c4d9bffaadc + color_conversion (0.1.2) sha256=99bea5fa412e1527a11389975aa6ad445ff8528ebae202c11d08c45ea2b94c96 + colored2 (4.0.3) sha256=63e1038183976287efc43034f5cca17fb180b4deef207da8ba78d051cbce2b37 + commonmarker (2.0.4) sha256=3dd74c8081a46f992a1d9b7fac796583468d41dd8ea6806a84ca08ff05ae13cf + commonmarker (2.0.4-aarch64-linux) sha256=ddb421a7e97c4b5c6abdc8302492389e612501e33c550f72258f57c4a62bbfdc + commonmarker (2.0.4-arm64-darwin) sha256=39ecc81b246dbd24d6aaf83288581a364f142244d3963d10dd984e33b09d9dec + commonmarker (2.0.4-x86_64-darwin) sha256=455782dfc9af1ca92ec84ac8ac3b685b6f3d1d0ef8f0c9290070b7976e3f4acc + commonmarker (2.0.4-x86_64-linux) sha256=34043c15857f0ef45f3f55ff9b0a5ee8fac395682c373ab39275c4a2a0a03400 + compare-xml (0.66) sha256=e21aa5c0f69ef1177eced997c688fd4df989084e74a1b612257af32e1dd05319 + concurrent-ruby (1.3.5) sha256=813b3e37aca6df2a21a3b9f1d497f8cbab24a2b94cab325bffe65ee0f6cbebc6 + connection_pool (2.5.0) sha256=233b92f8d38e038c1349ccea65dd3772727d669d6d2e71f9897c8bf5cd53ebfc + cookiejar (0.3.4) sha256=11b16acfc4baf7a0f463c21a6212005e04e25f5554d4d9f24d97f3492dfda0df + cose (1.3.1) sha256=d5d4dbcd6b035d513edc4e1ab9bc10e9ce13b4011c96e3d1b8fe5e6413fd6de5 + costs (1.0.0) + crack (1.0.0) sha256=c83aefdb428cdc7b66c7f287e488c796f055c0839e6e545fec2c7047743c4a49 + crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d + css_parser (1.21.0) sha256=6753f5b8b49dd6d5c6a90f300d5a82af8399c19dbba56d886081740ec7014518 + csv (3.3.2) sha256=6ff0c135e65e485d1864dde6c1703b60d34cc9e19bed8452834a0b28a519bd4e + cuprite (0.15.1) sha256=0b3a25b2e408b345dfa0bae8bc5e7f021f913737c746edece9ca9fbb57eba259 + daemons (1.4.1) sha256=8fc76d76faec669feb5e455d72f35bd4c46dc6735e28c420afb822fac1fa9a1d + dalli (3.2.8) sha256=2e63595084d91fae2655514a02c5d4fc0f16c0799893794abe23bf628bebaaa5 + dashboards (1.0.0) + date (3.4.1) sha256=bf268e14ef7158009bfeaec40b5fa3c7271906e88b196d958a89d4b408abe64f + date_validator (0.12.0) sha256=68c9834da240347b9c17441c553a183572508617ebfbe8c020020f3192ce3058 + deckar01-task_list (2.3.4) sha256=66abdc7e009ea759732bb53867e1ea42de550e2aa03ac30a015cbf42a04c1667 + declarative (0.0.20) sha256=8021dd6cb17ab2b61233c56903d3f5a259c5cf43c80ff332d447d395b17d9ff9 + descendants_tracker (0.0.4) sha256=e9c41dd4cfbb85829a9301ea7e7c48c2a03b26f09319db230e6479ccdc780897 + diff-lcs (1.5.1) sha256=273223dfb40685548436d32b4733aa67351769c7dea621da7d9dd4813e63ddfe + disposable (0.6.3) sha256=7f2a3fb251bff6cd83f25b164043d4ec3531209b51b066ed476a9df9c2d384cc + doorkeeper (5.8.1) sha256=6d54f3c36755d8cfcb7e4f04fbcf1ff3492c816090ad78126ec8a722c292d26c + dotenv (3.1.7) sha256=c670df478675d23889e657beaca6fb423228f75ce9f052a0690c0d0daa333cf3 + dotenv-rails (3.1.7) sha256=02c07b9601ad64046e196f48f6280c2cc660b073e08b30ad5c2f78b4872e9189 + drb (2.2.1) sha256=e9d472bf785f558b96b25358bae115646da0dbfd45107ad858b0bc0d935cb340 + dry-auto_inject (1.1.0) sha256=f9276cb5d15a3ef138e1f1149e289e287f636de57ef4a6decd233542eb708f78 + dry-configurable (1.3.0) sha256=882d862858567fc1210d2549d4c090f34370fc1bb7c5c1933de3fe792e18afa8 + dry-container (0.11.0) sha256=23be9381644d47343f3bf13b082b4255994ada0bfd88e0737eaaadc99d035229 + dry-core (1.1.0) sha256=0903821a9707649a7da545a2cd88e20f3a663ab1c5288abd7f914fa7751ab195 + dry-inflector (1.2.0) sha256=22f5d0b50fd57074ae57e2ca17e3b300e57564c218269dcf82ff3e42d3f38f2e + dry-initializer (3.2.0) sha256=37d59798f912dc0a1efe14a4db4a9306989007b302dcd5f25d0a2a20c166c4e3 + dry-logic (1.6.0) sha256=da6fedbc0f90fc41f9b0cc7e6f05f5d529d1efaef6c8dcc8e0733f685745cea2 + dry-monads (1.7.1) sha256=a70628100dd88531d8de1cca1ec97108f136c647e236cca631f63f7cdbdc1fc9 + dry-schema (1.14.0) sha256=ec40615e122040597cbb2f286b237f59a8f1f558e0071250788a53c125f742a9 + dry-types (1.8.2) sha256=c84e9ada69419c727c3b12e191e0ed7d2c6d58d040d55e79ea16e0ebf8b3ec0f + dry-validation (1.11.1) sha256=70900bb5a2d911c8aab566d3e360c6bff389b8bf92ea8e04885ce51c41ff8085 + dumb_delegator (1.1.0) sha256=1ad255e5b095a2206a574c62b40c678f3d5c9151f1b3d0bae1b0463f7e40188e + em-http-request (1.1.7) sha256=16fbc72b2a6e20c804c564ac5d12e98668c6fcef8c3b1dd2387dff505f2efdab + em-socksify (0.3.3) sha256=7d8d08a7a8acc1263173433a6b5540edd80a8a36e35a066b650c929a3a3974ed + em-synchrony (1.0.6) sha256=6e7470a684d9bbc00d61d552911b65711540bd89e95c157156f5aacdd6f306ca + email_validator (2.2.4) sha256=5ab238095bec7aef9389f230e9e0c64c5081cdf91f19d6c5cecee0a93af20604 + equivalent-xml (0.6.0) sha256=8919761efa848ad0846369ff8be1f646b17e5061698c4867b09829000cc3f487 + erb_lint (0.9.0) sha256=dfb5e40ad839e8d1f0d56ca85ec9a7ac4c9cd966ec281138282f35b323ca7c31 + erblint-github (1.0.1) sha256=9f28f7dc381a0dc68a0093ef7af3424ed9d2bb2b3e39bdc8e8cba86a0d31f2d0 + erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9 + escape_utils (1.3.0) sha256=dffb7010922880ace6ceed642156c64e2a64620f27e0849f43bc4f68fd3c2c09 + et-orbi (1.2.11) sha256=d26e868cc21db88280a9ec1a50aa3da5d267eb9b2037ba7b831d6c2731f5df64 + eventmachine (1.2.7) sha256=994016e42aa041477ba9cff45cbe50de2047f25dd418eba003e84f0d16560972 + eventmachine_httpserver (0.2.1) sha256=5db5e8a23754204d43592e5fcc2160457c57c870babe6307c4e61fc95019b809 + excon (1.2.3) sha256=25bd64530f152eddbef4a2bcc2133b2fd8bf3ec102345780ba427e9bac4ba6aa + factory_bot (6.5.1) sha256=40581ea7bec0aee05514b8f4f99ed477274bdf1884c1372de5209e60322d6ca9 + factory_bot_rails (6.4.4) sha256=139e17caa2c50f098fddf5e5e1f29e8067352024e91ca1186d018b36589e5c88 + faraday (2.12.2) sha256=157339c25c7b8bcb739f5cf1207cb0cefe8fa1c65027266bcbc34c90c84b9ad6 + faraday-follow_redirects (0.3.0) sha256=d92d975635e2c7fe525dd494fcd4b9bb7f0a4a0ec0d5f4c15c729530fdb807f9 + faraday-net_http (3.4.0) sha256=a1f1e4cd6a2cf21599c8221595e27582d9936819977bbd4089a601f24c64e54a + fastimage (2.3.1) sha256=23c629f1f3e7d61bcfcc06c25b3d2418bc6bf41d2e615dbf5132c0e3b63ecce9 + ferrum (0.15) + ffi (1.17.1) sha256=26f6b0dbd1101e6ffc09d3ca640b2a21840cc52731ad8a7ded9fb89e5fb0fc39 + ffi (1.17.1-aarch64-linux-gnu) sha256=c5d22cb545a3a691d46060f1343c461d1a8d38c3fd71b96b4cbbe6906bf1fd38 + ffi (1.17.1-aarch64-linux-musl) sha256=88b9d6ae905d21142df27c94bb300042c1aae41b67291885f600eaad16326b1d + ffi (1.17.1-arm-linux-gnu) sha256=fe14f5ece94082f3b0e651a09008113281f2764e7ea95f522b64e2fe32e11504 + ffi (1.17.1-arm-linux-musl) sha256=df14927ca7bd9095148a7d1938bb762bbf189d190cf25d9547395ec7acc198a0 + ffi (1.17.1-arm64-darwin) sha256=a8e04f79d375742c54ee7f9fff4b4022b87200a4ec0eb082128d3b6559e67b4d + ffi (1.17.1-x86-linux-gnu) sha256=01411c78cb3cff3c88cf67b2a7b24534e9b1638253d88581fef44c2083f6a174 + ffi (1.17.1-x86-linux-musl) sha256=02bcc7bbcff71e021ef05f43469f7c5074ab3422e415b287001bd890c9cbb1c6 + ffi (1.17.1-x86_64-darwin) sha256=0036199c290462dd7f03bc22933644c1685b7834a21788062bd5df48c72aa7a6 + ffi (1.17.1-x86_64-linux-gnu) sha256=8c0ade2a5d19f3672bccfe3b58e016ae5f159e3e2e741c856db87fcf07c903d0 + ffi (1.17.1-x86_64-linux-musl) sha256=3a343086820c96d6fbea4a5ef807fb69105b2b8174678f103b3db210c3f78401 + flamegraph (0.9.5) sha256=a683020637ffa0e14a72640fa41babf14d926bfeaed87e31907cfd06ab2de8dc + fog-aws (3.30.0) sha256=f70b811b655fbfa2e7c59da9c3c0672af43436128cbee4bbf46ee6d78d9a5004 + fog-core (2.6.0) sha256=3fe08aa83a23cddce42f4ba412040c08f890d7ff04c175c0ee59119371245be6 + fog-json (1.2.0) sha256=dd4f5ab362dbc72b687240bba9d2dd841d5dfe888a285797533f85c03ea548fe + fog-xml (0.1.5) sha256=52b9fea10701461dd3eaf9d9839702169b418dbbf50426786b9b74fade373bd6 + formatador (1.1.0) sha256=54e23e2af4d60bb9327c7fac62b29968e4cf28cee0111f726d0bdeadc85e06d0 + friendly_id (5.5.1) sha256=e018f2b89bfc143276fee6d378a64792385cd4fddd3d4fce501f59ec19c06207 + front_matter_parser (1.0.1) sha256=bae298bda01db95788a4d6452f1670a3d198c6716c8d3727db9a95533deb7b7b + fugit (1.11.1) sha256=e89485e7be22226d8e9c6da411664d0660284b4b1c08cacb540f505907869868 + fuubar (2.5.1) sha256=b272a7804b282661c7fab583a3764f92543cb482c365ae39c685cd218fdd4880 + glob (0.4.0) sha256=893dc9e2d24abe13dda907ce0cda576f680ff382f2a6cf9e543f98ecbe29238c + globalid (1.2.1) sha256=70bf76711871f843dbba72beb8613229a49429d1866828476f9c9d6ccc327ce9 + gon (6.4.0) sha256=e3a618d659392890f1aa7db420f17c75fd7d35aeb5f8fe003697d02c4b88d2f0 + good_job (3.99.1) sha256=7d3869d8a8ee8ef7048fee5d746f41c21987b7822c20038a2f773036bef0830a + google-apis-core (0.16.0) sha256=046a2c30a5ec123b2a6bc5e64348be781ce5fcd18dd4e85982e7a6a8da9d0dcc + google-apis-gmail_v1 (0.41.0) sha256=d09102619a571213e9637efb9ca4504c54d7779b524344045e24088eb2d0f8d0 + google-cloud-env (2.2.1) sha256=3c6062aee0b5c863b83f3ce125ea7831507aadf1af7c0d384b74a116c4f649cf + google-logging-utils (0.1.0) sha256=70950b1e49314273cf2e167adb47b62af7917a4691b580da7e9be67b9205fcd5 + googleauth (1.13.1) sha256=33448ce662e40afeb3e6db5eb9f4ee712467b1701f3857ef9c0aecac8447eca0 + grape (2.2.0) sha256=42fef93c4865b077a09db05ac0372d4e3ded3143cb1026c1323b7bfa3098f6ee + grape_logging (1.8.4) sha256=efcc3e322dbd5d620a68f078733b7db043cf12680144cd03c982f14115c792d1 + gravatar_image_tag (1.2.0) sha256=eb5630fea846b711e713b934a0178fb9785f02f4eb9ced8d6faa4d537c40fdcf + grids (1.0.0) + hana (1.3.7) sha256=5425db42d651fea08859811c29d20446f16af196308162894db208cac5ce9b0d + hashdiff (1.1.2) sha256=2c30eeded6ed3dce8401d2b5b99e6963fe5f14ed85e60dd9e33c545a44b71a77 + hashery (2.1.2) sha256=d239cc2310401903f6b79d458c2bbef5bf74c46f3f974ae9c1061fb74a404862 + hashie (3.6.0) sha256=b097778abd066b5b506a07a226037b45f2f1d45f13f7ef552813b122aefb6d8d + highline (3.1.2) sha256=67cbd34d19f6ef11a7ee1d82ffab5d36dfd5b3be861f450fc1716c7125f4bb4a + html-pipeline (2.14.3) sha256=8a1d4d7128b2141913387cac0f8ba898bb6812557001acc0c2b46910f59413a0 + htmlbeautifier (1.4.3) sha256=b43d08f7e2aa6ae1b5a6f0607b4ed8954c8d4a8e85fd2336f975dda1e4db385b + htmldiff (0.0.1) sha256=a96d068c8b8ea96cca3154a61785365d83129f47f1df964c6b1666924ce113a1 + htmlentities (4.3.4) sha256=125a73c6c9f2d1b62100b7c3c401e3624441b663762afa7fe428476435a673da + http-2 (1.0.2) sha256=607004ffec28fcb5c392cccaef22d9ffe5b5575fc859ab665fb426a14cf3a83c + http_parser.rb (0.6.0) sha256=f11d0aec50ef26a7d1f991e627ac88acdb5979282aeba7a5c3be6ce0636ed196 + httpclient (2.8.3) sha256=2951e4991214464c3e92107e46438527d23048e634f3aee91c719e0bdfaebda6 + httpx (1.3.4) sha256=d90bac25b909184479af1bd95e66b0a336a11d76076342caae5809ffd7d63799 + i18n (1.14.7) sha256=ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f + i18n-js (4.2.3) sha256=ffb1a6d34afebd9ab2aff9bd86e8f2873191cbe8b9ac5c2c8efe4dfa1107ca3b + i18n-tasks (1.0.14) sha256=3ad8daef2a3268d6dc2232aad2b12941b353d884cd30fd3b418a73e7001a03ec + icalendar (2.10.3) sha256=0ebfc2672f9fa77b86b4d8c0e25e9b2319aad45a33319fed06d0be8ddd0cd485 + ice_cube (0.17.0) sha256=32deb45dda4b4acc53505c2f581f6d32b5afc04d29b9004769944a0df5a5fcbe + ice_nine (0.11.2) sha256=5d506a7d2723d5592dc121b9928e4931742730131f22a1a37649df1c1e2e63db + interception (0.5) sha256=a53818d636752a8df90d8c1bb2f7b6e13a7b828543cb02b50fbde98b849d7907 + io-console (0.8.0) sha256=cd6a9facbc69871d69b2cb8b926fc6ea7ef06f06e505e81a64f14a470fddefa2 + irb (1.15.1) sha256=d9bca745ac4207a8b728a52b98b766ca909b86ff1a504bcde3d6f8c84faae890 + iso8601 (0.13.0) sha256=298c2b15b7be5fa95a1372813d36a2257656cd8e906dfbc1f5cb409851425aa2 + jmespath (1.6.2) sha256=238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1 + json (2.10.1) sha256=ddc88ad91a1baf3f0038c174f253af3b086d30dc74db17ca4259bbde982f94dc + json-jwt (1.16.7) sha256=ccabff4c6d1a14276b23178e8bebe513ef236399b72a0b886d7ed94800d172a5 + json-schema (4.3.1) sha256=d5e68dc32b94408d0b06ad04f9382ccbb6fe5a44910e066f8547f56c471a7825 + json_schemer (2.4.0) sha256=56cb6117bb5748d925b33ad3f415b513d41d25d0bbf57fe63c0a78ff05597c24 + json_spec (1.1.5) sha256=7a77b97a92c787e2aa3fbc4a1239afc3342c781151dc98cfb81461b3b7cad10f + jwt (2.10.1) sha256=e6424ae1d813f63e761a04d6284e10e7ec531d6f701917fadcd0d9b2deaf1cc5 + ladle (1.0.1) sha256=e8586964108c798d48bf57d2a65bd5602e8e5223a176b6602a0fb36c0bda90dc + language_server-protocol (3.17.0.4) sha256=c484626478664fd13482d8180947c50a8590484b1258b99b7aedb3b69df89669 + launchy (3.1.1) sha256=72b847b5cc961589dde2c395af0108c86ff0119f42d4648d25b5440ebb10059e + lefthook (1.11.2) sha256=4bcd3c5bba4996727d96fffcf02e090f50bf672ca76677f46ba0f98a862eddc2 + letter_opener (1.10.0) sha256=2ff33f2e3b5c3c26d1959be54b395c086ca6d44826e8bf41a14ff96fdf1bdbb2 + letter_opener_web (3.0.0) sha256=3f391efe0e8b9b24becfab5537dfb17a5cf5eb532038f947daab58cb4b749860 + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + listen (3.9.0) sha256=db9e4424e0e5834480385197c139cb6b0ae0ef28cc13310cfd1ca78377d59c67 + lobby_boy (0.1.3) sha256=9460bb3c052aef158eb3f137b8f7679ca756b8e2983d140dbdc0caa85c018172 + logger (1.6.6) sha256=dd618d24e637715472732e7eed02e33cfbdf56deaad225edd0f1f89d38024017 + lograge (0.14.0) sha256=42371a75823775f166f727639f5ddce73dd149452a55fc94b90c303213dc9ae1 + loofah (2.24.0) sha256=61e6a710883abb8210887f3dc868cf3ed66594c509d9ff6987621efa6651ee1e + lookbook (2.3.4) sha256=16484c9eb514ac0c23c4b59cfd5a52697141d35056e3a9c2a22b314c1b887605 + mail (2.8.1) sha256=ec3b9fadcf2b3755c78785cb17bc9a0ca9ee9857108a64b6f5cfc9c0b5bfc9ad + marcel (1.0.4) sha256=0d5649feb64b8f19f3d3468b96c680bae9746335d02194270287868a661516a4 + markly (0.12.1) sha256=fda3a53ec29e349e9c30e34cf9da322aa260d66627f75b2d3a8ad9633e5cbab9 + matrix (0.4.2) sha256=71083ccbd67a14a43bfa78d3e4dc0f4b503b9cc18e5b4b1d686dc0f9ef7c4cc0 + md_to_pdf (0.2.0) + messagebird-rest (1.4.2) sha256=1501e16ad76c87558f20f3b26cb39d05f587b349b44b8bf8056b040e9b495301 + meta-tags (2.22.1) sha256=e5ae1febbd320d396c7226d7edb868e5d63466c14b9c8b06622a1a74e6dce354 + method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 + mime-types (3.6.0) sha256=6f71db957840ceae44211531eff3e2f7e0dd4645fefb5f535dbaeb6307ab6464 + mime-types-data (3.2025.0204) sha256=de3659d75ab211affa8e0f7579959d5b9ca60b76ff9a5abd550bf3a7d4e3f58a + mini_magick (5.1.2) sha256=2c57112a2c55d9f86b1ed7ab568b3c389a3265788ac5c1ad3e632a201b629a7e + mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef + mini_portile2 (2.8.8) sha256=8e47136cdac04ce81750bb6c09733b37895bf06962554e4b4056d78168d70a75 + minitest (5.25.4) sha256=9cf2cae25ac4dfc90c988ebc3b917f53c054978b673273da1bd20bcb0778f947 + msgpack (1.8.0) sha256=e64ce0212000d016809f5048b48eb3a65ffb169db22238fb4b72472fecb2d732 + multi_json (1.15.0) sha256=1fd04138b6e4a90017e8d1b804c039031399866ff3fbabb7822aea367c78615d + mustermann (3.0.3) sha256=d1f8e9ba2ddaed47150ddf81f6a7ea046826b64c672fbc92d83bce6b70657e88 + mustermann-grape (1.1.0) sha256=8d258a986004c8f01ce4c023c0b037c168a9ed889cf5778068ad54398fa458c5 + mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 + my_page (1.0.0) + net-http (0.6.0) sha256=9621b20c137898af9d890556848c93603716cab516dc2c89b01a38b894e259fb + net-imap (0.5.6) sha256=1ede8048ee688a14206060bf37a716d18cb6ea00855f6c9b15daee97ee51fbe5 + net-ldap (0.19.0) sha256=be2a379ccbd28fc75fb70a94af74e3a9a6866b84574247fc243e0abdd2f82f3d + net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 + net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 + net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 + nio4r (2.7.4) sha256=d95dee68e0bb251b8ff90ac3423a511e3b784124e5db7ff5f4813a220ae73ca9 + nokogiri (1.18.3) sha256=6b9fc3b14fd0cedd21f6cad8cf565123ba7401e56b5d0aec180c23cdca28fd5a + nokogiri (1.18.3-aarch64-linux-gnu) sha256=cab20305133078a8f6b60cf96311b48319175038cc7772e5ec586ff624cb7838 + nokogiri (1.18.3-aarch64-linux-musl) sha256=acb256bb3213a180b1ed84a49c06d5d4c6c1da26f33bc9681f1fece4dab09a79 + nokogiri (1.18.3-arm-linux-gnu) sha256=37b73a55e0d1e8a058a24abb16868903e81cb4773049739c532b864f87236b1b + nokogiri (1.18.3-arm-linux-musl) sha256=09407970cd13736cf87e975fae69c13e1178bab0313d07b35580ee4dd3650793 + nokogiri (1.18.3-arm64-darwin) sha256=ce088965cd424b8e752d82087dcf017069d55791f157098ed1f671d966857610 + nokogiri (1.18.3-x86_64-darwin) sha256=d729406bb5a7b1bbe7ed3c0922336dd2c46085ed444d6de2a0a4c33950a4edea + nokogiri (1.18.3-x86_64-linux-gnu) sha256=3c7ad5cee39855ed9c746065f39b584b9fd2aaff61df02d0f85ba8d671bbe497 + nokogiri (1.18.3-x86_64-linux-musl) sha256=8aaecc22c0e5f12dac613e15f9a04059c3ec859d6f98f493cc831bd88fe8e731 + oj (3.16.10) sha256=7f26bed974e331e16d579b470b0865010757f6fe6ee30ea9b67df653fbe13d7c + okcomputer (1.18.6) sha256=578eee04ad6b3a8ae8e428c39fbff3ca74d1d358f5b21734e73994bf419db092 + omniauth (1.9.0) + omniauth-openid-connect (0.4.1) + omniauth-openid_connect-providers (0.2.0) + omniauth-saml (1.10.5) sha256=946f0c6eb9266642835ad54eca1d0725f5e5cf26e18d1fd7711dabeceddfea8c + op-clamav-client (3.4.2) sha256=f28d697d11758a2ba3dc530cfdf4871a00ecd517631e8bac30dee30cd6012964 + open4 (1.3.4) sha256=a1df037310624ecc1ea1d81264b11c83e96d0c3c1c6043108d37d396dcd0f4b1 + openid_connect (2.2.1) sha256=31264e85b5a36e33dff5e31560cc176175c26f30c260d7e95af93ff0065f3101 + openproject-auth_plugins (1.0.0) + openproject-auth_saml (1.0.0) + openproject-avatars (1.0.0) + openproject-backlogs (1.0.0) + openproject-bim (1.0.0) + openproject-boards (1.0.0) + openproject-calendar (1.0.0) + openproject-documents (1.0.0) + openproject-gantt (1.0.0) + openproject-github_integration (1.0.0) + openproject-gitlab_integration (3.0.0) + openproject-job_status (1.0.0) + openproject-ldap_groups (1.0.0) + openproject-meeting (1.0.0) + openproject-octicons (19.20.0) sha256=f8a4ad2aa708505aba81b8362ddf9e4f8e992433f30a63d96f2007795c5419ec + openproject-octicons_helper (19.20.0) sha256=517f2feb3f9526d640f57b77579325abdb7218a0f81a1fcda28837873498efb0 + openproject-openid_connect (1.0.0) + openproject-primer_view_components (0.55.0) sha256=1ee4ed1ee60c41604f30f8ce074ff8929ed6c79873c394f4128614289ddac235 + openproject-recaptcha (1.0.0) + openproject-reporting (1.0.0) + openproject-storages (1.0.0) + openproject-team_planner (1.0.0) + openproject-token (4.0.0) sha256=f71cdad5632b6b7b598223b185f4928366cb6038eca1a84a6de65cf15cecd0e0 + openproject-two_factor_authentication (1.0.0) + openproject-webhooks (1.0.0) + openproject-xls_export (1.0.0) + openssl (3.3.0) sha256=ff3a573fc97ab30f69483fddc80029f91669bf36532859bd182d1836f45aee79 + openssl-signature_algorithm (1.3.0) sha256=a3b40b5e8276162d4a6e50c7c97cdaf1446f9b2c3946a6fa2c14628e0c957e80 + optimist (3.2.0) sha256=01c9e4826bbcae048f96ce079eef662564829016b08f1f1bdc024b0fb398771c + os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f + ostruct (0.6.1) sha256=09a3fb7ecc1fa4039f25418cc05ae9c82bd520472c5c6a6f515f03e4988cb817 + overviews (1.0.0) + ox (2.14.22) sha256=0bbc4a40d109e4b76295c4927b5f2d453070eb5af221e5b05ec0ff58e291c6a9 + paper_trail (16.0.0) sha256=e9b9f0fb1b8b590c8231cfa931b282ba92f90e066e393930a5e1c61ae4c5019d + parallel (1.26.3) sha256=d86babb7a2b814be9f4b81587bf0b6ce2da7d45969fab24d8ae4bf2bb4d4c7ef + parallel_tests (4.9.1) sha256=4782bf86edcce774f18f2a0dade29140b61f251b25cccaa0e1b3805dc90a84b5 + parser (3.3.7.1) sha256=7dbe61618025519024ac72402a6677ead02099587a5538e84371b76659e6aca1 + pdf-core (0.9.0) sha256=4f368b2f12b57ec979872d4bf4bd1a67e8648e0c81ab89801431d2fc89f4e0bb + pdf-inspector (1.3.0) sha256=fc107579d6f29b636e2da3d6743479b2624d9e390bf2d84beef8fd4ebe1a05bd + pdf-reader (2.14.1) sha256=b45a4521c249a394ad7ad9e691bfd46d4d00998cfc4f019e4525afb4963b411b + pg (1.5.9) sha256=761efbdf73b66516f0c26fcbe6515dc7500c3f0aa1a1b853feae245433c64fdc + plaintext (0.3.4) sha256=ef3c0853c9cbf3107642cfaaed711f5b39dc7af5f640f37ec22fef5d8c833772 + pp (0.6.2) sha256=947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff + prawn (2.4.0) sha256=82062744f7126c2d77501da253a154271790254dfa8c309b8e52e79bc5de2abd + prawn-table (0.2.2) sha256=336d46e39e003f77bf973337a958af6a68300b941c85cb22288872dc2b36addb + prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 + pry (0.14.2) sha256=c4fe54efedaca1d351280b45b8849af363184696fcac1c72e0415f9bdac4334d + pry-byebug (3.10.1) sha256=c8f975c32255bfdb29e151f5532130be64ff3d0042dc858d0907e849125581f8 + pry-rails (0.3.11) sha256=a69e28e24a34d75d1f60bcf241192a54253f8f7ef8a62cba1e75750a9653593d + pry-rescue (1.6.0) sha256=985bfd506d9866b587fd86790cf8445266a41b7f92c627fc5b21ec7d92aba6db + psych (5.2.3) sha256=84a54bb952d14604fea22d99938348814678782f58b12648fcdfa4d2fce859ee + public_suffix (6.0.1) sha256=61d44e1cab5cbbbe5b31068481cf16976dd0dc1b6b07bd95617ef8c5e3e00c6f + puffing-billy (4.0.0) sha256=0453380ad9a66d455675148ff7ab95a7544b6a239f0a91e11494affa94b7fff9 + puma (6.6.0) sha256=f25c06873eb3d5de5f0a4ebc783acc81a4ccfe580c760cfe323497798018ad87 + puma-plugin-statsd (2.6.0) sha256=c13ffe6a2fa2d3c245af673316e6d2556f5d0c151455d1934dffc96ce814ea03 + raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rack (2.2.11) sha256=424c49affa19081e9255d65d861f2d7bc7d8388edc0cb608b5e6caf1dd49bb8a + rack-attack (6.7.0) sha256=3ca47e8f66cd33b2c96af53ea4754525cd928ed3fa8da10ee6dad0277791d77c + rack-cors (2.0.2) sha256=415d4e1599891760c5dc9ef0349c7fecdf94f7c6a03e75b2e7c2b54b82adda1b + rack-mini-profiler (3.3.1) sha256=2bf0de7d5795f54581e453b248e42cc50e8d0529efac73828653a9ad2407a801 + rack-oauth2 (2.2.1) sha256=c73aa87c508043e2258f02b4fb110cacba9b37d2ccf884e22487d014a120d1a5 + rack-protection (3.2.0) sha256=3c74ba7fc59066453d61af9bcba5b6fe7a9b3dab6f445418d3b391d5ea8efbff + rack-session (1.0.2) sha256=a02115e5420b4de036839b9811e3f7967d73446a554b42aa45106af335851d76 + rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 + rack-timeout (0.7.0) sha256=757337e9793cca999bb73a61fe2a7d4280aa9eefbaf787ce3b98d860749c87d9 + rack_session_access (0.2.0) sha256=03eb98f2027429ccbbeb18556006dfb6d928b0557ad3770783b8e2f368198d6b + rackup (1.0.1) sha256=ba86604a28989fe1043bff20d819b360944ca08156406812dca6742b24b3c249 + rails (7.1.5.1) sha256=05aea2ed7b6392b41ce0fc11455de118455025a431b6ea334a7ac2b101608804 + rails-controller-testing (1.0.5) sha256=741448db59366073e86fc965ba403f881c636b79a2c39a48d0486f2607182e94 + rails-dom-testing (2.2.0) sha256=e515712e48df1f687a1d7c380fd7b07b8558faa26464474da64183a7426fa93b + rails-html-sanitizer (1.6.2) sha256=35fce2ca8242da8775c83b6ba9c1bcaad6751d9eb73c1abaa8403475ab89a560 + rails-i18n (7.0.10) sha256=efae16e0ac28c0f42e98555c8db1327d69ab02058c8b535e0933cb106dd931ca + railties (7.1.5.1) sha256=0be15562e2ded4efdc1b6c30f884b6d838c9ba49573dde042334b752b043e2fb + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + rake (13.2.1) sha256=46cb38dae65d7d74b6020a4ac9d48afed8eb8149c040eccf0523bec91907059d + rake-compiler-dock (1.9.1) sha256=e73720a29aba9c114728ce39cc0d8eef69ba61d88e7978c57bac171724cd4d53 + rb-fsevent (0.11.2) sha256=43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe + rb-inotify (0.11.1) sha256=a0a700441239b0ff18eb65e3866236cd78613d6b9f78fea1f9ac47a85e47be6e + rb_sys (0.9.110) sha256=8993fd1f49b5f6b394b49dafda77fb5c635458637f8effe508cca78ebc03427d + rbtrace (0.5.1) sha256=e8cba64d462bfb8ba102d7be2ecaacc789247d52ac587d8003549d909cb9c5dc + rbtree3 (0.7.1) sha256=ab60ead728a5491b70df4f4065e180b18dbab5319f817ce1dbf5dd906f26d8ba + rdoc (6.12.0) sha256=7d6f706e070bffa5d18a448f24076cbfb34923a99c1eab842aa18e6ca69f56e0 + recaptcha (5.19.0) sha256=b69c021a5b788da06901d2c95ab86f10a8634e6496343096cc5167f0318b2a39 + redcarpet (3.6.0) sha256=8ad1889c0355ff4c47174af14edd06d62f45a326da1da6e8a121d59bdcd2e9e9 + redis (5.3.0) sha256=6bf810c5ae889187f0c45f77db503310980310afa57cf1640d57f419ccda72b1 + redis-client (0.23.2) sha256=e33bab6682c8155cfef95e6dd296936bb9c2981a89fb578ace27a076fa2836fa + regexp_parser (2.10.0) sha256=cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61 + reline (0.6.0) sha256=57620375dcbe56ec09bac7192bfb7460c716bbf0054dc94345ecaa5438e539d2 + representable (3.2.0) sha256=cc29bf7eebc31653586849371a43ffe36c60b54b0a6365b5f7d95ec34d1ebace + request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb + responders (3.1.1) sha256=92f2a87e09028347368639cfb468f5fefa745cb0dc2377ef060db1cdd79a341a + retriable (3.1.2) sha256=0a5a5d0ca4ba61a76fb31a17ab8f7f80281beb040c329d34dfc137a1398688e0 + rexml (3.4.1) sha256=c74527a9a0a04b4ec31dbe0dc4ed6004b960af943d8db42e539edde3a871abca + rinku (2.0.6) sha256=8b60670e3143f3db2b37efa262971ce3619ec23092045498ef9f077d82828d7d + roar (1.2.0) sha256=8db4d1ca79c57a5fb746c16c0d5661d7c3e0de3d9553dc016a88d2dba2929d08 + rotp (6.3.0) sha256=75d40087e65ed0d8022c33055a6306c1c400d1c12261932533b5d6cbcd868854 + rouge (4.5.1) sha256=2ac81c6dee7019bbc6600d4c2d641d730d65c165941400ebd924259067e690dd + rspec (3.13.0) sha256=d490914ac1d5a5a64a0e1400c1d54ddd2a501324d703b8cfe83f458337bab993 + rspec-core (3.13.3) sha256=25136507f4f9cf2e8977a2851e64e438b4331646054e345998714108745cdfe4 + rspec-expectations (3.13.3) sha256=0e6b5af59b900147698ea0ff80456c4f2e69cac4394fbd392fbd1ca561f66c58 + rspec-mocks (3.13.2) sha256=2327335def0e1665325a9b617e3af9ae20272741d80ac550336309a7c59abdef + rspec-rails (7.1.1) sha256=e15dccabed211e2fd92f21330c819adcbeb1591c1d66c580d8f2d8288557e331 + rspec-retry (0.6.2) sha256=6101ba23a38809811ae3484acde4ab481c54d846ac66d5037ccb40131a60d858 + rspec-support (3.13.2) sha256=cea3a2463fd9b84b9dcc9685efd80ea701aa8f7b3decb3b3ce795ed67737dbec + rspec-wait (1.0.1) sha256=50ce9cc7cd20b8bb67b95a4ed56b59a16d4af7e86ae91b28dbf20eeaa2481d1f + rubocop (1.73.0) sha256=8a86a9030594cda8d90bd39a3b2d4f21319065b29a8ce19c843d02b5a26d648f + rubocop-ast (1.38.1) sha256=80ecbe2ac9bb26693cab9405bf72b41b85a1f909f20f021b983c32c2e7d857fe + rubocop-capybara (2.21.0) sha256=5d264efdd8b6c7081a3d4889decf1451a1cfaaec204d81534e236bc825b280ab + rubocop-factory_bot (2.26.1) sha256=8de13cd4edcee5ca800f255188167ecef8dbfc3d1fae9f15734e9d2e755392aa + rubocop-openproject (0.2.0) sha256=2300ed6b638a34a9368b458dc5fb618ae396da6a27670b50519ad1e3cea65ccb + rubocop-performance (1.24.0) sha256=e5bd39ff3e368395b9af886927cc37f5892f43db4bd6c8526594352d5b4440b5 + rubocop-rails (2.30.2) sha256=1948435c001e3e5981f90cc451b800e5386a609baf8a8ebbaf4cb310e071027a + rubocop-rspec (3.5.0) sha256=710c942fe1af884ba8eea75cbb8bdbb051929a2208880a6fc2e2dce1eed5304c + rubocop-rspec_rails (2.30.0) sha256=888112e83f9d7ef7ad2397e9d69a0b9614a4bae24f072c399804a180f80c4c46 + ruby-duration (3.2.3) sha256=eb3d13b1df85067a015a8fb2ed8f1eec842a3b721e47c9b6fd74d2f356069784 + ruby-ole (1.2.13.1) sha256=578d10dd2a797a2b35a1286c6fb2c9525f67c24791346fc8015d39f0ffa3cb72 + ruby-prof (1.7.1) sha256=026393448cf92fd24a91739bf71ccd2bfe88fe8a1401ee8afc4948a16d62ea24 + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + ruby-rc4 (0.1.5) sha256=00cc40a39d20b53f5459e7ea006a92cf584e9bc275e2a6f7aa1515510e896c03 + ruby-saml (1.17.0) sha256=0419839ba3312d255e35fe3cc7ae155e4a241fd468796caebcf61164aa01b8a9 + ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef + rubytree (2.1.1) sha256=4925016356a81730e982f1f8c3b5f8da461f18906c77d238bad4c4ba896abd41 + rubyzip (2.3.2) sha256=3f57e3935dc2255c414484fbf8d673b4909d8a6a57007ed754dde39342d2373f + safety_net_attestation (0.4.0) sha256=96be2d74e7ed26453a51894913449bea0e072f44490021545ac2d1c38b0718ce + sanitize (7.0.0) sha256=269d1b9d7326e69307723af5643ec032ff86ad616e72a3b36d301ac75a273984 + secure_headers (7.1.0) sha256=6b1f9d5f9507af2948f4636452c41c09371927836396c2185438ffdf0a731124 + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + selenium-devtools (0.133.0) sha256=aba5a5225ac38d235bbc6ebb4e0b8209e973ac7af4226e4304a1417573f73f64 + selenium-webdriver (4.29.1) sha256=0a7fe53cc4d2c515adbb89e115c6e786c64e9b98f85939d21071c6e32883a146 + semantic (1.6.1) sha256=3cdbb48f59198ebb782a3fdfb87b559e0822a311610db153bae22777a7d0c163 + shoulda-context (2.0.0) sha256=7adf45342cd800f507d2a053658cb1cce2884b616b26004d39684b912ea32c34 + shoulda-matchers (6.4.0) sha256=9055bb7f4bb342125fb860809798855c630e05ef5e75837b3168b8e6ee1608b0 + signet (0.19.0) sha256=537f3939f57f141f691e6069a97ec40f34fadafc4c7e5ba94edb06cf4350dd31 + simpleidn (0.2.3) sha256=08ce96f03fa1605286be22651ba0fc9c0b2d6272c9b27a260bc88be05b0d2c29 + smart_properties (1.17.0) sha256=f9323f8122e932341756ddec8e0ac9ec6e238408a7661508be99439ca6d6384b + spreadsheet (1.3.3) sha256=ce106829c53139eccf5033fa053d7b8b8779c900c81e562d0d4f46155c9b49f3 + spring (4.2.1) sha256=8517a24d7ac966c8e051b63a67c68cbfc026c74cc0742e19f0fba472ebe0a5ae + spring-commands-rspec (1.0.4) sha256=6202e54fa4767452e3641461a83347645af478bf45dddcca9737b43af0dd1a2c + spring-commands-rubocop (0.4.0) sha256=3e677a2c8a27ae8a986f04bfb69e66d5d55b017541e8be93bf0dc48a7f5690c1 + sprockets (3.7.5) sha256=72c20f256548f8a37fe7db41d96be86c3262fddaf4ebe9d69ec8317394fed383 + sprockets-rails (3.5.2) sha256=a9e88e6ce9f8c912d349aa5401509165ec42326baf9e942a85de4b76dbc4119e + ssrf_filter (1.0.8) sha256=03f49f54837e407d43ee93ec733a8a94dc1bcf8185647ac61606e63aaedaa0db + stackprof (0.2.27) sha256=aff6d28656c852e74cf632cc2046f849033dc1dedffe7cb8c030d61b5745e80c + store_attribute (2.0.0) sha256=3399d9baa20776ec9dcb266cff407aac82bf99791678d6266ea617703e4b0e28 + stringex (2.8.6) sha256=c7b382d2b2a47a1e1646f256df201c48d487d6296fbb289d76802f67f5e929c4 + stringio (3.1.2) sha256=204f1828f85cdb39d57cac4abc6dc44b04505a223f131587f2e20ae3729ba131 + structured_warnings (0.4.0) sha256=ff9a59278e3ad8d18f742e677b764ce374f16e52c7993c0ff7d76900e93383ad + svg-graph (2.2.2) sha256=f928866403055e6539afdfdab5f6268d108b2abc9f002e0fc51b16511809513a + swd (2.0.3) sha256=4cdbe2a4246c19f093fce22e967ec3ebdd4657d37673672e621bf0c7eb770655 + sys-filesystem (1.5.3) sha256=17b561d1be683c34bc53946461ea9d67012d8f395e7297db8c63b9018cb30ece + table_print (1.5.7) sha256=436664281f93387b882335795e16cfeeb839ad0c785ff7f9110fc0f17c68b5cb + terminal-table (4.0.0) sha256=f504793203f8251b2ea7c7068333053f0beeea26093ec9962e62ea79f94301d2 + test-prof (1.4.4) sha256=1a59513ed9d33a1f5ca17c0b89da4e70f60a91c83ec62e9a873dbb99141353ef + text-hyphen (1.5.0) sha256=c44a4533b8a554e7ff7c955e131bcccc78a0b4c56ce1d73f2c8c11f43b075a06 + thor (1.3.2) sha256=eef0293b9e24158ccad7ab383ae83534b7ad4ed99c09f96f1a6b036550abbeda + thread_safe (0.3.6) sha256=9ed7072821b51c57e8d6b7011a8e282e25aeea3a4065eab326e43f66f063b05a + timecop (0.9.10) sha256=12ba45ce57cdcf6b1043cb6cdffa6381fd89ce10d369c28a7f6f04dc1b0cd8eb + timeout (0.4.3) sha256=9509f079b2b55fe4236d79633bd75e34c1c1e7e3fb4b56cb5fda61f80a0fe30e + tpm-key_attestation (0.14.0) sha256=d05cc52b397f89c36a7307407e0e84d3ea1c7afce50e0a70b146f8ab17d2bf4b + trailblazer-option (0.1.2) sha256=20e4f12ea4e1f718c8007e7944ca21a329eee4eed9e0fa5dde6e8ad8ac4344a3 + ttfunk (1.7.0) sha256=2370ba484b1891c70bdcafd3448cfd82a32dd794802d81d720a64c15d3ef2a96 + turbo-rails (2.0.11) sha256=fc47674736372780abd2a4dc0d84bef242f5ca156a457cd7fa6308291e397fcf + turbo_power (0.7.0) sha256=ad95d147e0fa761d0023ad9ca00528c7b7ddf6bba8ca2e23755d5b21b290d967 + turbo_tests (2.2.0) + typed_dag (2.0.2) sha256=b8dc65bf8cb5461715aa64650b7c96fc2075ef29fdd94554a93896c43453828c + tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b + tzinfo-data (1.2025.1) sha256=2d8c1a501a93f26cb2e0a5019c07f1deaef76e99cca3308f5bdcda8e411fdf0b + uber (0.1.0) sha256=5beeb407ff807b5db994f82fa9ee07cfceaa561dad8af20be880bc67eba935dc + unicode-display_width (3.1.4) sha256=8caf2af1c0f2f07ec89ef9e18c7d88c2790e217c482bfc78aaa65eadd5415ac1 + unicode-emoji (4.0.4) sha256=2c2c4ef7f353e5809497126285a50b23056cc6e61b64433764a35eff6c36532a + uri (1.0.2) sha256=b303504ceb7e5905771fa7fa14b649652fa949df18b5880d69cfb12494791e27 + validate_email (0.1.6) sha256=9dfe9016d527b17a8d3a6e95e4dc50a125400eef899d13d4cc2a254393f82ee4 + validate_url (1.0.15) sha256=72fe164c0713d63a9970bd6700bea948babbfbdcec392f2342b6704042f57451 + vcr (6.3.1) sha256=37b56e157e720446a3f4d2d39919cabef8cb7b6c45936acffd2ef8229fec03ed + vernier (1.5.0) sha256=caeeb5e27d9a5a8dd94ce594d0c83e4825a08b80384f4630aa9de2bf76cd1571 + view_component (3.21.0) sha256=7f5a77bca29e7385495fad2b7c1acdcd2c581b3cd2e573a831a9808f6710df5c + virtus (2.0.0) sha256=8841dae4eb7fcc097320ba5ea516bf1839e5d056c61ee27138aa4bddd6e3d1c2 + warden (1.2.9) sha256=46684f885d35a69dbb883deabf85a222c8e427a957804719e143005df7a1efd0 + warden-basic_auth (0.2.1) sha256=bfc752e0109c0182c3e69e930284c5e1e81e7b4a354aeb2b5914ead1391f3c6e + webauthn (3.4.0) sha256=a10665f5e05eb156ba0219fd17480c57e0af4daaf83e3e33439bf958350af4c5 + webfinger (2.1.3) sha256=567a52bde77fb38ca6b67e55db755f988766ec4651c1d24916a65aa70540695c + webmock (3.25.0) sha256=573c23fc4887008c830f22da588db339ca38b6d59856fd57f5a068959474198e + webrick (1.9.1) sha256=b42d3c94f166f3fb73d87e9b359def9b5836c426fc8beacf38f2184a21b2a989 + websocket (1.2.11) sha256=b7e7a74e2410b5e85c25858b26b3322f29161e300935f70a0e0d3c35e0462737 + websocket-driver (0.7.7) sha256=056d99f2cd545712cfb1291650fde7478e4f2661dc1db6a0fa3b966231a146b4 + websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241 + will_paginate (4.0.1) sha256=107b226ebe1d393d274575956a7c472e1eefdd97d8828e01b72d425d15a875b9 + with_advisory_lock (5.1.0) sha256=0692cd82013b271c59aa5e1f603b741ab94926dbce098990fbace5dd5412fed7 + xpath (3.2.0) sha256=6dfda79d91bb3b949b947ecc5919f042ef2f399b904013eb3ef6d20dd3a4082e + yard (0.9.37) sha256=a6e910399e78e613f80ba9add9ba7c394b1a935f083cccbef82903a3d2a26992 + zeitwerk (2.7.1) sha256=0945986050e4907140895378e74df1fe882a2271ed087cc6c6d6b00d415a2756 + RUBY VERSION - ruby 3.3.6p108 + ruby 3.4.2p28 BUNDLED WITH - 2.5.23 + 2.6.4 diff --git a/Gemfile.modules b/Gemfile.modules index 1689af16358..0992e008fa9 100644 --- a/Gemfile.modules +++ b/Gemfile.modules @@ -14,7 +14,7 @@ gem 'omniauth-openid_connect-providers', gem 'omniauth-openid-connect', git: 'https://github.com/opf/omniauth-openid-connect.git', - ref: 'd63f5967514d10db9ddece798dadfa2ac532cbe0' + ref: '3d5fec65072fb4566fb975a9cbe401d758d22317' group :opf_plugins do # included so that engines can reference OpenProject::Version @@ -23,11 +23,9 @@ group :opf_plugins do gem 'openproject-auth_plugins', path: 'modules/auth_plugins' gem 'openproject-auth_saml', path: 'modules/auth_saml' gem 'openproject-openid_connect', path: 'modules/openid_connect' - gem 'openproject-documents', path: 'modules/documents' gem 'openproject-xls_export', path: 'modules/xls_export' gem 'costs', path: 'modules/costs' gem 'openproject-reporting', path: 'modules/reporting' - gem 'openproject-meeting', path: 'modules/meeting' gem "openproject-backlogs", path: 'modules/backlogs' gem 'openproject-avatars', path: 'modules/avatars' gem 'openproject-two_factor_authentication', path: 'modules/two_factor_authentication' @@ -44,10 +42,12 @@ group :opf_plugins do gem 'openproject-boards', path: 'modules/boards' gem 'overviews', path: 'modules/overviews' gem 'budgets', path: 'modules/budgets' + gem 'openproject-meeting', path: 'modules/meeting' gem 'openproject-team_planner', path: 'modules/team_planner' gem 'openproject-gantt', path: 'modules/gantt' gem 'openproject-calendar', path: 'modules/calendar' gem 'openproject-storages', path: 'modules/storages' + gem 'openproject-documents', path: 'modules/documents' gem 'openproject-bim', path: 'modules/bim' end diff --git a/README.md b/README.md index 33d6cc10ae2..4ec54a64233 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ More information and screenshots can be found on our [website](https://www.openp ## Start now with OpenProject -- **Free Trial**:[Start a 14-days free trial of OpenProject](https://start.openproject.com/). +- **Free Trial**: [Start a 14-days free trial of OpenProject](https://start.openproject.com/). - **Community Edition**, free of charge: Download OpenProject and get started with the self-hosted Community edition. If you want to run an instance of OpenProject in production (or for evaluation), refer to our in-depth [installation guides](https://www.openproject.org/download-and-installation/). - **Enterprise Edition**: Sign up for the Enterprise version, choose between cloud or on-premises and benefit from comprehensive support and Enterprise add-ons. - **Documentation**: Explore our [comprehensive documentation](https://www.openproject.org/docs/) to help you get up and running quickly. @@ -40,7 +40,7 @@ You found a bug? Please [report it](https://www.openproject.org/docs/development OpenProject is supported by its Community members, both companies and individuals. -We are always looking for new members to our Community, so if you are interested in improving OpenProject we would be glad to welcome and support you getting into the code. There are guides as well, e.g. a [Quick Start for Developers](https://www.openproject.org/development/setting-up-development-environment/), but don't hesitate to simply [contact us](https://www.openproject.org/contact) if you have questions. +We are always looking for new members to our Community, so if you are interested in improving OpenProject we would be glad to welcome and support you getting into the code. There are guides as well, e.g. a [Quick Start for Developers](https://www.openproject.org/docs/development/development-environment/), but don't hesitate to simply [contact us](https://www.openproject.org/contact) if you have questions. Working on OpenProject comes with the satisfaction of working on a widely used open source application. diff --git a/app/assets/images/lookbook/hover_card.png b/app/assets/images/lookbook/hover_card.png index 8dde8feb902..f2389dd7ded 100644 Binary files a/app/assets/images/lookbook/hover_card.png and b/app/assets/images/lookbook/hover_card.png differ diff --git a/app/assets/images/lookbook/user_hover_card.png b/app/assets/images/lookbook/user_hover_card.png new file mode 100644 index 00000000000..b225bcfad03 Binary files /dev/null and b/app/assets/images/lookbook/user_hover_card.png differ diff --git a/app/components/_index.sass b/app/components/_index.sass index a14f1dce5db..42597cf0ed8 100644 --- a/app/components/_index.sass +++ b/app/components/_index.sass @@ -2,10 +2,12 @@ @import "work_packages/activities_tab/journals/new_component" @import "work_packages/activities_tab/journals/index_component" @import "work_packages/activities_tab/journals/item_component" +@import "work_packages/activities_tab/journals/revision_component" @import "work_packages/activities_tab/journals/item_component/details" @import "work_packages/activities_tab/journals/item_component/add_reactions" @import "work_packages/activities_tab/journals/item_component/reactions" @import "shares/modal_body_component" +@import "work_packages/reminder/modal_body_component" @import "shares/invite_user_form_component" @import "work_packages/details/tab_component" @import "work_packages/progress/modal_body_component" @@ -17,3 +19,8 @@ @import "projects/row_component" @import "op_primer/border_box_table_component" @import "work_packages/exports/modal_dialog_component" +@import "work_package_relations_tab/index_component" +@import "work_package_relations_tab/relation_component" +@import "users/hover_card_component" +@import "enterprise_edition/banner_component" +@import "work_packages/types/pattern_input" diff --git a/app/components/activities/days_component.html.erb b/app/components/activities/days_component.html.erb index ced326e3a91..2faf0cb7d0d 100644 --- a/app/components/activities/days_component.html.erb +++ b/app/components/activities/days_component.html.erb @@ -29,14 +29,18 @@ See COPYRIGHT and LICENSE files for more details.
<%= helpers.truncate_formatted_text(comment) %>
@@ -40,7 +40,7 @@ See COPYRIGHT and LICENSE files for more details.
<% else %> - <%= helpers.op_icon 'icon-not-supported' %> + <%= helpers.op_icon "icon-not-supported" %> <%= model[:off_text] %><%= model[:off_description] %>
diff --git a/app/components/concerns/op_turbo/streamable.rb b/app/components/concerns/op_turbo/streamable.rb index dfad026a782..89180a56ddc 100644 --- a/app/components/concerns/op_turbo/streamable.rb +++ b/app/components/concerns/op_turbo/streamable.rb @@ -33,6 +33,8 @@ module OpTurbo # rubocop:enable OpenProject/AddPreviewForViewComponent INLINE_ACTIONS = %i[dialog flash].freeze + # Turbo allows the response method for these actions only: + ACTIONS_WITH_METHOD = %i[update replace].freeze extend ActiveSupport::Concern @@ -43,7 +45,7 @@ module OpTurbo end included do - def render_as_turbo_stream(view_context:, action: :update) + def render_as_turbo_stream(view_context:, action: :update, method: nil) case action when :update, *INLINE_ACTIONS @inner_html_only = true @@ -63,8 +65,13 @@ module OpTurbo "Wrap your component in a `component_wrapper` block in order to use turbo-stream methods" end + if method && !action.in?(ACTIONS_WITH_METHOD) + raise ArgumentError, "The #{action} action does not supports a method" + end + OpTurbo::StreamComponent.new( action:, + method:, target: wrapper_key, template: ).render_in(view_context) diff --git a/app/components/custom_fields/details_component.html.erb b/app/components/custom_fields/details_component.html.erb index c4e0409b4f2..491c3a84e1f 100644 --- a/app/components/custom_fields/details_component.html.erb +++ b/app/components/custom_fields/details_component.html.erb @@ -3,10 +3,12 @@ flex_layout do |content| if has_no_items_or_projects? content.with_row(mb: 3) do - render Primer::Alpha::Banner.new(scheme: :default, - icon: :info, - dismiss_scheme: :hide, - test_selector: "op-custom-fields--new-hierarchy-banner") do + render Primer::Alpha::Banner.new( + scheme: :default, + icon: :info, + dismiss_scheme: :hide, + test_selector: "op-custom-fields--new-hierarchy-banner" + ) do I18n.t("custom_fields.admin.notice.remember_items_and_projects") end end diff --git a/app/components/custom_fields/index_page_header_component.html.erb b/app/components/custom_fields/index_page_header_component.html.erb index f91e3f13d79..d865ec68f3f 100644 --- a/app/components/custom_fields/index_page_header_component.html.erb +++ b/app/components/custom_fields/index_page_header_component.html.erb @@ -31,12 +31,14 @@ See COPYRIGHT and LICENSE files for more details. header.with_title { I18n.t(:label_custom_field_plural) } header.with_breadcrumbs(breadcrumb_items, selected_item_font_weight: :normal) - header.with_tab_nav(label: nil, test_selector: "custom-fields--tab-nav") do |tab_nav| - @tabs.each do |tab| - tab_nav.with_tab(selected: currently_selected_tab == tab, href: tab[:path]) do |t| - t.with_text { I18n.t(tab[:label]) } + if @tabs.present? + header.with_tab_nav(label: nil, test_selector: "custom-fields--tab-nav") do |tab_nav| + @tabs.each do |tab| + tab_nav.with_tab(selected: currently_selected_tab == tab, href: tab[:path]) do |t| + t.with_text { I18n.t(tab[:label]) } + end end end - end if @tabs.present? + end end %> diff --git a/app/components/custom_fields/index_page_header_component.rb b/app/components/custom_fields/index_page_header_component.rb index bfefb5b22ec..db2f7ebeb05 100644 --- a/app/components/custom_fields/index_page_header_component.rb +++ b/app/components/custom_fields/index_page_header_component.rb @@ -39,9 +39,11 @@ class CustomFields::IndexPageHeaderComponent < ApplicationComponent end def breadcrumb_items - [{ href: admin_index_path, text: t("label_administration") }, - I18n.t("menus.breadcrumb.nested_element", section_header: t(:label_custom_field_plural), - title: I18n.t(currently_selected_tab[:label].to_s)).html_safe] + [ + { href: admin_index_path, text: t("label_administration") }, + helpers.nested_breadcrumb_element(t(:label_custom_field_plural), + I18n.t(currently_selected_tab[:label].to_s)) + ] end def currently_selected_tab diff --git a/app/components/enterprise_edition/banner_component.html.erb b/app/components/enterprise_edition/banner_component.html.erb new file mode 100644 index 00000000000..06e5ae5862c --- /dev/null +++ b/app/components/enterprise_edition/banner_component.html.erb @@ -0,0 +1,23 @@ +<%= + grid_layout("op-ee-banner", **@system_arguments) do |grid| + grid.with_area(:"icon-container") do + content_tag :div, class: "op-ee-banner--shield" do + render( + Primer::Beta::Octicon.new( + icon: "op-enterprise-addons", + size: :medium, + classes: "op-ee-banner--icon" + ) + ) + end + end + grid.with_area(:"title-container") { render(Primer::Beta::Text.new) { title } } + grid.with_area(:"description-container") { render(Primer::Beta::Text.new) { description } } + grid.with_area(:"link-container") do + render(Primer::Beta::Link.new(href: href)) do |link| + link.with_trailing_visual_icon(icon: "link-external") + link_title + end + end + end +%> diff --git a/app/components/enterprise_edition/banner_component.rb b/app/components/enterprise_edition/banner_component.rb new file mode 100644 index 00000000000..713116aed54 --- /dev/null +++ b/app/components/enterprise_edition/banner_component.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module EnterpriseEdition + # A banner indicating that a given feature requires the enterprise edition of OpenProject. + # This component uses conventional names for translation keys or URL look-ups based on the feature_key passed in. + # It will only be rendered if necessary. + class BannerComponent < ApplicationComponent + include OpPrimer::ComponentHelpers + + # @param feature_key [Symbol, NilClass] The key of the feature to show the banner for. + # @param title [String] The title of the banner. + # @param description [String] The description of the banner. + # @param href [String] The URL to link to. + # @param skip_render [Boolean] Whether to skip rendering the banner. + # @param system_arguments [Hash] <%= link_to_system_arguments_docs %> + def initialize(feature_key, + title: nil, + description: nil, + link_title: nil, + href: nil, + skip_render: !EnterpriseToken.show_banners?, + **system_arguments) + @system_arguments = system_arguments + @system_arguments[:tag] = "div" + @system_arguments[:test_selector] = "op-ee-banner-#{feature_key.to_s.tr('_', '-')}" + super + + @feature_key = feature_key + @title = title + @description = description + @link_title = link_title + @href = href + @skip_render = skip_render + end + + private + + attr_reader :skip_render, + :feature_key + + def title + @title || I18n.t("ee.upsale.#{feature_key}.title", default: I18n.t("ee.upsale.title")) + end + + def description + @description || begin + I18n.t("ee.upsale.#{feature_key}.description") + rescue StandardError + I18n.t("ee.upsale.#{feature_key}.description_html") + end + rescue I18n::MissingTranslationData => e + raise e.exception( + <<~TEXT.squish + The expected '#{I18n.locale}.ee.upsale.#{feature_key}.description' key does not exist. + Ideally, provide it in the locale file. + If that isn't applicable, a description parameter needs to be provided. + TEXT + ) + end + + def link_title + @link_title || I18n.t("ee.upsale.#{feature_key}.link_title", default: I18n.t("ee.upsale.link_title")) + end + + def href + href_value = @href || OpenProject::Static::Links.links.dig(:enterprise_docs, feature_key, :href) + + unless href_value + raise "Neither a custom href is provided nor is a value set " \ + "in OpenProject::Static::Links.enterprise_docs[#{feature_key}][:href]" + end + + href_value + end + + def render? + !skip_render + end + end +end diff --git a/app/components/enterprise_edition/banner_component.sass b/app/components/enterprise_edition/banner_component.sass new file mode 100644 index 00000000000..d8ca7bc2f19 --- /dev/null +++ b/app/components/enterprise_edition/banner_component.sass @@ -0,0 +1,68 @@ +/*! + / -- copyright + / OpenProject is an open source project management software. + / Copyright (C) 2024 the OpenProject GmbH + / + / This program is free software; you can redistribute it and/or + / modify it under the terms of the GNU General Public License version 3. + / + / OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + / Copyright (C) 2006-2013 Jean-Philippe Lang + / Copyright (C) 2010-2013 the ChiliProject Team + / + / This program is free software; you can redistribute it and/or + / modify it under the terms of the GNU General Public License + / as published by the Free Software Foundation; either version 2 + / of the License, or (at your option) any later version. + / + / This program is distributed in the hope that it will be useful, + / but WITHOUT ANY WARRANTY; without even the implied warranty of + / MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + / GNU General Public License for more details. + / + / You should have received a copy of the GNU General Public License + / along with this program; if not, write to the Free Software + / Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + / + / See COPYRIGHT and LICENSE files for more details. + / ++ + / + +$op-ee-banner--shield-width: 32px + +// This is not named op-enterprise-banner because as of now, there is still a legacy angular component that uses that block name. +.op-ee-banner + display: grid + grid-template-columns: $op-ee-banner--shield-width auto auto + grid-template-areas: "icon-container title-container" "icon-container description-container" "icon-container link-container" + grid-column-gap: 0.5rem + justify-content: left + @media screen and (min-width: $breakpoint-md) + grid-template-areas: "icon-container title-container title-container" "icon-container description-container link-container" + + &--icon-container + @extend .upsale-colored + align-self: start + justify-self: center + + &--shield + @extend .upsale-border-colored + width: $op-ee-banner--shield-width + height: 42px + border-width: 10px 5px 10px 5px + border-radius: 0 0 10px 10px + border-style: solid + display: flex + align-items: center + justify-content: center + + &--icon + width: $op-ee-banner--shield-width + height: $op-ee-banner--shield-width + + &--title-container + @extend .upsale-colored + font-weight: bold + + &--link-container + align-self: end diff --git a/app/components/enumerations/table_component.rb b/app/components/enumerations/table_component.rb index 177f8510186..ffde9e733b7 100644 --- a/app/components/enumerations/table_component.rb +++ b/app/components/enumerations/table_component.rb @@ -30,12 +30,15 @@ module Enumerations class TableComponent < ::TableComponent + attr_reader :enumeration + + def initialize(enumeration:, rows: [], **) + super(rows: rows, **) + @enumeration = enumeration + end + def columns - %i[name is_default active sort].tap do |default| - if with_colors - default.insert 3, :color - end - end + headers.map(&:first) end def sortable? @@ -43,16 +46,13 @@ module Enumerations end def headers - [ + @headers ||= [ ["name", { caption: Enumeration.human_attribute_name(:name) }], - ["is_default", { caption: Enumeration.human_attribute_name(:is_default) }], + enumeration.can_have_default_value? ? ["is_default", { caption: Enumeration.human_attribute_name(:is_default) }] : nil, ["active", { caption: Enumeration.human_attribute_name(:active) }], + with_colors ? ["color", { caption: Enumeration.human_attribute_name(:color) }] : nil, ["sort", { caption: I18n.t(:label_sort) }] - ].tap do |default| - if with_colors - default.insert 3, ["color", { caption: Enumeration.human_attribute_name(:color) }] - end - end + ].compact end def with_colors diff --git a/app/components/filter/filter_button_component.html.erb b/app/components/filter/filter_button_component.html.erb index f17a4b500bd..db2baaa23c7 100644 --- a/app/components/filter/filter_button_component.html.erb +++ b/app/components/filter/filter_button_component.html.erb @@ -1,9 +1,13 @@ <%= component_wrapper tag: "turbo-frame" do %> - <%= render(Primer::Beta::Button.new(scheme: :secondary, - disabled:, - data: { "filter--filters-form-target": "filterFormToggle", - action: "filter--filters-form#toggleDisplayFilters" }, - test_selector: "filter-component-toggle")) do |button| %> + <%= render( + Primer::Beta::Button.new( + scheme: :secondary, + disabled:, + data: { "filter--filters-form-target": "filterFormToggle", + action: "filter--filters-form#toggleDisplayFilters" }, + test_selector: "filter-component-toggle" + ) + ) do |button| %> <% button.with_trailing_visual_counter(count: filters_count, test_selector: "filters-button-counter") %> <%= t(:label_filter) %> <% end %> diff --git a/app/components/filter/filter_component.rb b/app/components/filter/filter_component.rb index 6b625627b2d..5412a4e34c2 100644 --- a/app/components/filter/filter_component.rb +++ b/app/components/filter/filter_component.rb @@ -67,18 +67,55 @@ module Filter case filter when Queries::Filters::Shared::ProjectFilter::Required, Queries::Filters::Shared::ProjectFilter::Optional - { - autocomplete_options: { - component: "opce-project-autocompleter", - resource: "projects", - filters: [ - { name: "active", operator: "=", values: ["t"] } - ] - } - } + { autocomplete_options: project_autocomplete_options } + when Queries::Filters::Shared::CustomFields::User + { autocomplete_options: user_autocomplete_options } + when Queries::Filters::Shared::CustomFields::ListOptional, + Queries::Projects::Filters::ProjectStatusFilter, + Queries::Projects::Filters::TypeFilter + { autocomplete_options: list_autocomplete_options(filter) } else {} end end + + def list_autocomplete_options(filter) + { + component: "opce-autocompleter", + items: filter.allowed_values.map { |name, id| { name:, id: } }, + model: filter.values, + bindValue: "id", + bindLabel: "name", + hideSelected: true + } + end + + def project_autocomplete_options + { + component: "opce-project-autocompleter", + resource: "projects", + filters: [ + { name: "active", operator: "=", values: ["t"] } + ] + } + end + + def user_autocomplete_options + { + component: "opce-user-autocompleter", + hideSelected: true, + defaultData: false, + placeholder: I18n.t(:label_user_search), + resource: "principals", + url: ::API::V3::Utilities::PathHelper::ApiV3Path.principals, + filters: [ + { name: "type", operator: "=", values: ["User"] }, + { name: "status", operator: "!", values: [Principal.statuses["locked"].to_s] }, + { name: "member", operator: "=", values: Project.visible.pluck(:id) } + ], + searchKey: "any_name_attribute", + focusDirectly: false + } + end end end diff --git a/app/components/groups/edit_page_header_component.html.erb b/app/components/groups/edit_page_header_component.html.erb index 62302ef4d8f..78c4ff06639 100644 --- a/app/components/groups/edit_page_header_component.html.erb +++ b/app/components/groups/edit_page_header_component.html.erb @@ -31,41 +31,47 @@ See COPYRIGHT and LICENSE files for more details. header.with_title { @group.name } header.with_breadcrumbs(breadcrumb_items) - header.with_action_button(tag: :a, - mobile_icon: :person, - mobile_label: t(:label_profile), - size: :medium, - href: show_group_path(@group), - aria: { label: I18n.t(:label_profile) }, - title: I18n.t(:label_profile)) do |button| + header.with_action_button( + tag: :a, + mobile_icon: :person, + mobile_label: t(:label_profile), + size: :medium, + href: show_group_path(@group), + aria: { label: I18n.t(:label_profile) }, + title: I18n.t(:label_profile) + ) do |button| button.with_leading_visual_icon(icon: :person) t(:label_profile) end if @current_user.admin? - header.with_action_button(tag: :a, - scheme: :danger, - mobile_icon: :trash, - mobile_label: t(:button_delete), - size: :medium, - href: group_path(@group), - aria: { label: I18n.t(:button_delete) }, - data: { - confirm: t(:text_are_you_sure), - method: :delete, - }, - title: I18n.t(:button_delete)) do |button| + header.with_action_button( + tag: :a, + scheme: :danger, + mobile_icon: :trash, + mobile_label: t(:button_delete), + size: :medium, + href: group_path(@group), + aria: { label: I18n.t(:button_delete) }, + data: { + confirm: t(:text_are_you_sure), + method: :delete + }, + title: I18n.t(:button_delete) + ) do |button| button.with_leading_visual_icon(icon: :trash) t(:button_delete) end end - header.with_tab_nav(label: nil) do |tab_nav| - @tabs.each do |tab| - tab_nav.with_tab(selected: selected_tab(@tabs) == tab, href: tab[:path]) do |t| - t.with_text { I18n.t("js.#{tab[:label]}") } + if @tabs.present? + header.with_tab_nav(label: nil) do |tab_nav| + @tabs.each do |tab| + tab_nav.with_tab(selected: selected_tab(@tabs) == tab, href: tab[:path]) do |t| + t.with_text { I18n.t("js.#{tab[:label]}") } + end end end - end if @tabs.present? + end end %> diff --git a/app/components/groups/show_page_header_component.html.erb b/app/components/groups/show_page_header_component.html.erb index f42886dfed3..e06660c8357 100644 --- a/app/components/groups/show_page_header_component.html.erb +++ b/app/components/groups/show_page_header_component.html.erb @@ -28,34 +28,38 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <%= render(Primer::OpenProject::PageHeader.new) do |header| - header.with_title(test_selector: "groups--title") { @group.name } + header.with_title(test_selector: "groups--title") { @group.name } header.with_breadcrumbs(breadcrumb_items) if @current_user.admin? - header.with_action_button(tag: :a, - mobile_icon: :pencil, - mobile_label: t(:button_edit), - size: :medium, - href: edit_group_path(@group), - aria: { label: I18n.t(:button_edit) }, - data: { "test-selector": "groups--edit-group-button" }, - title: I18n.t(:button_edit)) do |button| + header.with_action_button( + tag: :a, + mobile_icon: :pencil, + mobile_label: t(:button_edit), + size: :medium, + href: edit_group_path(@group), + aria: { label: I18n.t(:button_edit) }, + data: { "test-selector": "groups--edit-group-button" }, + title: I18n.t(:button_edit) + ) do |button| button.with_leading_visual_icon(icon: :pencil) t(:button_edit) end - header.with_action_button(tag: :a, - scheme: :danger, - mobile_icon: :trash, - mobile_label: t(:button_delete), - size: :medium, - href: group_path(@group), - aria: { label: I18n.t(:button_delete) }, - data: { - confirm: t(:text_are_you_sure), - method: :delete, - }, - title: I18n.t(:button_delete)) do |button| + header.with_action_button( + tag: :a, + scheme: :danger, + mobile_icon: :trash, + mobile_label: t(:button_delete), + size: :medium, + href: group_path(@group), + aria: { label: I18n.t(:button_delete) }, + data: { + confirm: t(:text_are_you_sure), + method: :delete + }, + title: I18n.t(:button_delete) + ) do |button| button.with_leading_visual_icon(icon: :trash) t(:button_delete) end diff --git a/app/components/individual_principal_base_filter_component.html.erb b/app/components/individual_principal_base_filter_component.html.erb index 4c7b44a7154..ac5593753ed 100644 --- a/app/components/individual_principal_base_filter_component.html.erb +++ b/app/components/individual_principal_base_filter_component.html.erb @@ -28,11 +28,11 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <%= form_tag(filter_path, method: :get) do %> - <% collapsed_class = initially_visible? ? '' : 'collapsed' %> + <% collapsed_class = initially_visible? ? "" : "collapsed" %> diff --git a/app/components/members/index_page_header_component.rb b/app/components/members/index_page_header_component.rb index c0df1b1bbd9..18bd0019258 100644 --- a/app/components/members/index_page_header_component.rb +++ b/app/components/members/index_page_header_component.rb @@ -63,7 +63,7 @@ class Members::IndexPageHeaderComponent < ApplicationComponent if @query && query_name if menu_header.present? - I18n.t("menus.breadcrumb.nested_element", section_header: menu_header, title: query_name).html_safe + helpers.nested_breadcrumb_element(menu_header, query_name) else query_name end diff --git a/app/components/members/index_sub_header_component.html.erb b/app/components/members/index_sub_header_component.html.erb index d982cdf7950..c2e2105777b 100644 --- a/app/components/members/index_sub_header_component.html.erb +++ b/app/components/members/index_sub_header_component.html.erb @@ -1,22 +1,26 @@ <%= render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_filter_button(label: I18n.t(:description_filter), - id: "filter-member-button", - aria: { label: I18n.t(:description_filter) }, - class: "toggle-member-filter-link", - data: filter_button_data_attributes) do - I18n.t(:description_filter) - end + subheader.with_filter_button( + label: I18n.t(:description_filter), + id: "filter-member-button", + aria: { label: I18n.t(:description_filter) }, + class: "toggle-member-filter-link", + data: filter_button_data_attributes + ) do + I18n.t(:description_filter) + end - subheader.with_action_button(scheme: :primary, - aria: { label: I18n.t(:button_add_member) }, - title: I18n.t(:button_add_member), - id: "add-member-button", - data: add_button_data_attributes) do |button| - button.with_leading_visual_icon(icon: :plus) - t('activerecord.models.member') - end + subheader.with_action_button( + scheme: :primary, + aria: { label: I18n.t(:button_add_member) }, + title: I18n.t(:button_add_member), + id: "add-member-button", + data: add_button_data_attributes + ) do |button| + button.with_leading_visual_icon(icon: :plus) + t("activerecord.models.member") + end - subheader.with_bottom_pane_component do - render ::Members::UserFilterComponent.new(params, **@members_filter_options) - end -end %> + subheader.with_bottom_pane_component do + render ::Members::UserFilterComponent.new(params, **@members_filter_options) + end + end %> diff --git a/app/components/members/role_form_component.html.erb b/app/components/members/role_form_component.html.erb index b0b1112f1e7..01567d6f650 100644 --- a/app/components/members/role_form_component.html.erb +++ b/app/components/members/role_form_component.html.erb @@ -43,8 +43,7 @@ See COPYRIGHT and LICENSE files for more details. member.roles.include?(role), role.name, disabled: role_disabled?(role), - no_label: true - %> + no_label: true %> <%= role %> <% end %> diff --git a/app/components/messages/show_page_header_component.html.erb b/app/components/messages/show_page_header_component.html.erb new file mode 100644 index 00000000000..7d4d670b37b --- /dev/null +++ b/app/components/messages/show_page_header_component.html.erb @@ -0,0 +1,62 @@ +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { @topic.subject } + header.with_breadcrumbs(breadcrumb_items) + + watcher_action_button(header, @topic) + + if !@topic.locked? && authorize_for("messages", "reply") + header.with_action_button( + tag: :a, + scheme: :default, + mobile_icon: :quote, + mobile_label: t(:button_quote), + size: :medium, + href: url_for({ action: "quote", id: @topic }), + aria: { label: I18n.t(:button_delete) }, + data: { action: "forum-messages#quote", test_selector: "message-quote-button" }, + title: t(:button_quote) + ) do |button| + button.with_leading_visual_icon(icon: :quote) + t(:button_quote) + end + end + + if @message.editable_by?(User.current) + header.with_action_button( + tag: :a, + scheme: :default, + mobile_icon: :pencil, + mobile_label: t(:button_edit), + size: :medium, + href: edit_topic_path(@topic), + aria: { label: t(:button_edit) }, + data: { test_selector: "message-edit-button" }, + title: t(:button_edit) + ) do |button| + button.with_leading_visual_icon(icon: :pencil) + t(:button_edit) + end + end + + if @message.destroyable_by?(User.current) + header.with_action_button( + tag: :a, + scheme: :danger, + mobile_icon: :trash, + mobile_label: t(:button_delete), + size: :medium, + href: topic_path(@topic), + aria: { label: I18n.t(:button_delete) }, + data: { + confirm: I18n.t(:text_are_you_sure), + method: :delete + }, + title: I18n.t(:button_delete) + ) do |button| + button.with_leading_visual_icon(icon: :trash) + t(:button_delete) + end + end + end +%> diff --git a/app/components/messages/show_page_header_component.rb b/app/components/messages/show_page_header_component.rb new file mode 100644 index 00000000000..23a60603459 --- /dev/null +++ b/app/components/messages/show_page_header_component.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module Messages + class ShowPageHeaderComponent < ApplicationComponent + include OpPrimer::ComponentHelpers + include ApplicationHelper + include WatchersHelper + + def initialize(topic:, message:, forum:, project:) + super + @topic = topic + @message = message + @forum = forum + @project = project + end + + def breadcrumb_items + [ + { href: project_overview_path(@project.id), text: @project.name }, + { href: project_forums_path(@project), text: t(:label_forum_plural) }, + { href: project_forum_path(@project, @forum), text: @forum.name }, + @topic.subject + ] + end + end +end diff --git a/app/components/my/access_token/access_token_created_dialog_component.html.erb b/app/components/my/access_token/access_token_created_dialog_component.html.erb index cd773f77eda..928b20ab901 100644 --- a/app/components/my/access_token/access_token_created_dialog_component.html.erb +++ b/app/components/my/access_token/access_token_created_dialog_component.html.erb @@ -28,28 +28,33 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <%= - render(Primer::OpenProject::FeedbackDialog.new( - id:, - title: nil, - size: :large - )) do |dialog| + render( + Primer::OpenProject::FeedbackDialog.new( + id:, + title: I18n.t("my.access_token.create_dialog.title"), + size: :large + ) + ) do |dialog| dialog.with_feedback_message do |message| message.with_heading(tag: :h2) { I18n.t("my.access_token.create_dialog.header", type: "API") } end - dialog.with_additional_content do + dialog.with_additional_details do flex_layout do |flex| flex.with_row(mb: 2) do render(Primer::OpenProject::InputGroup.new) do |input_group| - input_group.with_text_input(name: :openproject_api_access_token, - label: Token::API.model_name.human, - visually_hide_label: false, - value: @token_value) + input_group.with_text_input( + name: :openproject_api_access_token, + label: Token::API.model_name.human, + visually_hide_label: false, + value: @token_value + ) input_group.with_trailing_action_clipboard_copy_button( value: @token_value, aria: { - label: I18n.t('button_copy_to_clipboard') - }) + label: I18n.t("button_copy_to_clipboard") + } + ) end end flex.with_row do diff --git a/app/components/my/access_token/api_tokens_section_component.html.erb b/app/components/my/access_token/api_tokens_section_component.html.erb index cd6206d5638..181b5e8d908 100644 --- a/app/components/my/access_token/api_tokens_section_component.html.erb +++ b/app/components/my/access_token/api_tokens_section_component.html.erb @@ -47,7 +47,7 @@ See COPYRIGHT and LICENSE files for more details.- <%= t('my_account.access_tokens.api.disabled_text') %> + <%= t("my_account.access_tokens.api.disabled_text") %>
- <%= helpers.op_icon('icon-info1') %> - <%= t(:label_projects_disk_usage_information, + <%= helpers.op_icon("icon-info1") %> + <%= t( + :label_projects_disk_usage_information, count: Project.count, - used_disk_space: number_to_human_size(Project.total_projects_size, precision: 2)) %> + used_disk_space: number_to_human_size(Project.total_projects_size, precision: 2) + ) %>
diff --git a/app/components/projects/export_list_modal_component.html.erb b/app/components/projects/export_list_modal_component.html.erb index cb39f9c51b3..edc5ddc0761 100644 --- a/app/components/projects/export_list_modal_component.html.erb +++ b/app/components/projects/export_list_modal_component.html.erb @@ -1,12 +1,16 @@ -<%= render(Primer::Alpha::Dialog.new(title: t('js.label_export'), - id: MODAL_ID)) do |d| %> +<%= render( + Primer::Alpha::Dialog.new( + title: t("js.label_export"), + id: MODAL_ID + ) + ) do |d| %> <% d.with_header(variant: :large) %> <% d.with_body do %>