diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cba1105238..7cb8012e40 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,8 @@ jobs: - "3.0" - "3.1" - "3.2" - gemfile: [gemfiles/rails_7.0.gemfile] + - "3.3" + gemfile: [gemfiles/rails_7.1.gemfile] orm: [active_record] adapter: [sqlite3] asset: [webpack] @@ -32,17 +33,37 @@ jobs: orm: active_record adapter: sqlite3 asset: webpacker - - ruby: "3.0" + - ruby: "3.2" gemfile: gemfiles/rails_7.0.gemfile orm: active_record + adapter: sqlite3 + asset: sprockets + - ruby: "3.2" + gemfile: gemfiles/rails_7.1.gemfile + orm: active_record adapter: mysql2 asset: importmap - - ruby: "3.0" - gemfile: gemfiles/rails_7.0.gemfile + - ruby: "3.2" + gemfile: gemfiles/rails_7.1.gemfile orm: active_record adapter: postgresql asset: sprockets - - ruby: "3.0" + - ruby: "3.2" + gemfile: gemfiles/rails_7.1.gemfile + orm: active_record + adapter: sqlite3 + asset: vite + - ruby: "3.3" + gemfile: gemfiles/rails_7.2.gemfile + orm: active_record + adapter: sqlite3 + asset: sprockets + - ruby: "3.3" + gemfile: gemfiles/rails_8.0.gemfile + orm: active_record + adapter: sqlite3 + asset: sprockets + - ruby: "3.2" gemfile: gemfiles/composite_primary_keys.gemfile orm: active_record adapter: sqlite3 @@ -57,13 +78,23 @@ jobs: orm: mongoid adapter: sqlite3 asset: sprockets - - ruby: jruby-9.3 - gemfile: gemfiles/rails_6.1.gemfile + - ruby: "3.1" + gemfile: gemfiles/rails_7.0.gemfile + orm: mongoid + adapter: sqlite3 + asset: sprockets + - ruby: "3.2" + gemfile: gemfiles/rails_7.1.gemfile + orm: mongoid + adapter: sqlite3 + asset: sprockets + - ruby: jruby-9.4 + gemfile: gemfiles/rails_7.0.gemfile orm: active_record adapter: mysql2 asset: sprockets - - ruby: jruby-9.3 - gemfile: gemfiles/rails_6.1.gemfile + - ruby: jruby-9.4 + gemfile: gemfiles/rails_7.0.gemfile orm: mongoid adapter: sqlite3 asset: sprockets @@ -93,7 +124,7 @@ jobs: CI_ASSET: ${{ matrix.asset }} JRUBY_OPTS: --debug steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: @@ -104,15 +135,18 @@ jobs: MAKEFLAGS: make --jobs 4 BUNDLE_WITHOUT: development - name: Set up Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: "14" + node-version: "18" + - name: Install ImageMagick + run: sudo apt-get install imagemagick - name: Setup application env: BUNDLE_GEMFILE: ../../${{ matrix.gemfile }} CI_ASSET: ${{ matrix.asset }} CI_DB_ADAPTER: ${{ matrix.adapter }} RAILS_ENV: test + NODE_OPTIONS: --openssl-legacy-provider run: | yarn install cd spec/dummy_app @@ -127,7 +161,7 @@ jobs: run: bundle exec rspec - name: Coveralls Parallel if: ${{ github.repository_owner == 'railsadminteam' }} - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@v2 continue-on-error: true with: github-token: ${{ secrets.github_token }} @@ -141,7 +175,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Coveralls Finished - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.github_token }} parallel-finished: true @@ -150,9 +184,9 @@ jobs: name: Prettier runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 - name: Install dependencies run: yarn install - name: Run check @@ -162,18 +196,13 @@ jobs: name: RuboCop runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: "3.0" - - name: Cache gems - uses: actions/cache@v3 - with: - path: vendor/bundle - key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ hashFiles('Gemfile') }} - restore-keys: | - ${{ runner.os }}-gems-${{ matrix.ruby }}- + ruby-version: "3.2" + bundler-cache: true + cache-version: gems-${{ hashFiles('Gemfile') }} - name: Install dependencies run: bundle install --without development --jobs=3 --retry=3 --path=vendor/bundle - name: Run check diff --git a/.rubocop.yml b/.rubocop.yml index 28aa300c55..5c76364890 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,6 +9,7 @@ AllCops: - "node_modules/**/*" - "spec/dummy_app/bin/**/*" - "spec/dummy_app/db/schema.rb" + - "spec/dummy_app/node_modules/**/*" - "spec/dummy_app/tmp/**/*" - "vendor/bundle/**/*" NewCops: disable @@ -108,7 +109,7 @@ Metrics/BlockNesting: Metrics/ClassLength: CountComments: false - Max: 132 # TODO: Lower to 100 + Max: 201 # TODO: Lower to 100 Metrics/CyclomaticComplexity: Max: 15 # TODO: Lower to 6 @@ -201,6 +202,9 @@ Style/RaiseArgs: Style/RedundantArgument: Enabled: true +Style/RedundantParentheses: + Enabled: false + Style/RedundantSelfAssignmentBranch: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f701fb220d..447ccf2ad2 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -21,7 +21,7 @@ Lint/ReturnInVoidContext: # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. # IgnoredMethods: refine Metrics/BlockLength: - Max: 1097 + Max: 1135 # Offense count: 1 # Configuration parameters: Max, CountKeywordArgs. diff --git a/Appraisals b/Appraisals index 08b6a0a8a3..112766ead3 100644 --- a/Appraisals +++ b/Appraisals @@ -2,21 +2,15 @@ appraise 'rails-6.0' do gem 'rails', '~> 6.0.0' - gem 'sassc-rails', '~> 2.1' - gem 'devise', '~> 4.7' + gem 'psych', '~> 3.3' + gem 'turbo-rails', '< 2.0.8' group :test do - gem 'cancancan', '~> 3.0' - gem 'kt-paperclip' + gem 'cancancan', ['~> 3.0', '< 3.6'] gem 'pundit', '~> 2.1.0' - gem 'rspec-rails', '>= 4.0.0.beta2' - gem 'shrine', '~> 3.0' end group :active_record do - gem 'pg', '>= 1.0.0', platforms: :ruby - gem 'paper_trail', '>= 12.0' - platforms :jruby do gem 'activerecord-jdbcmysql-adapter', '~> 60.0' gem 'activerecord-jdbcpostgresql-adapter', '~> 60.0' @@ -25,32 +19,20 @@ appraise 'rails-6.0' do end group :mongoid do - gem 'mongoid', '~> 7.0' + gem 'cancancan-mongoid' + gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid' + gem 'database_cleaner-mongoid', '>= 2.0', require: false gem 'kaminari-mongoid' + gem 'mongoid', '~> 7.0' gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip' - gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid' - gem 'cancancan-mongoid' gem 'shrine-mongoid', '~> 1.0' end end appraise 'rails-6.1' do gem 'rails', '~> 6.1.0' - gem 'sassc-rails', '~> 2.1' - gem 'devise', '~> 4.7' - gem 'turbo-rails', platform: :jruby, github: 'hotwired/turbo-rails' - - group :test do - gem 'cancancan', '~> 3.2' - gem 'kt-paperclip' - gem 'rspec-rails', '>= 4.0.0.beta2' - gem 'shrine', '~> 3.0' - end group :active_record do - gem 'pg', '>= 1.0.0', platforms: :ruby - gem 'paper_trail', '>= 12.0' - platforms :jruby do gem 'activerecord-jdbcmysql-adapter', '~> 61.0' gem 'activerecord-jdbcpostgresql-adapter', '~> 61.0' @@ -59,11 +41,12 @@ appraise 'rails-6.1' do end group :mongoid do - gem 'mongoid', '~> 7.0' + gem 'cancancan-mongoid' + gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid' + gem 'database_cleaner-mongoid', '>= 2.0', require: false gem 'kaminari-mongoid' + gem 'mongoid', '~> 7.0' gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip' - gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid' - gem 'cancancan-mongoid' gem 'shrine-mongoid', '~> 1.0' end end @@ -71,36 +54,69 @@ end appraise 'rails-7.0' do gem 'rails', '~> 7.0.0' gem 'importmap-rails', require: false - gem 'sassc-rails', '~> 2.1' - gem 'devise', '~> 4.8' - group :test do - gem 'cancancan', '~> 3.2' - gem 'kt-paperclip' - gem 'rspec-rails', '>= 4.0.0.beta2' - gem 'shrine', '~> 3.0' + group :active_record do + platforms :ruby, :mswin, :mingw, :x64_mingw do + gem 'sqlite3', '~> 1.3' + end + + platforms :jruby do + gem 'activerecord-jdbcmysql-adapter', '~> 70.0' + gem 'activerecord-jdbcpostgresql-adapter', '~> 70.0' + gem 'activerecord-jdbcsqlite3-adapter', '~> 70.0' + end + end + + group :mongoid do + gem 'cancancan-mongoid' + gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid' + gem 'database_cleaner-mongoid', '>= 2.0', require: false + gem 'kaminari-mongoid' + gem 'mongoid', '~> 8.0' + gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip' + gem 'shrine-mongoid', '~> 1.0' end +end + +appraise 'rails-7.1' do + gem 'rails', '~> 7.1.0' + gem 'importmap-rails', require: false group :active_record do - gem 'pg', '>= 1.0.0', platforms: :ruby - gem 'paper_trail', '>= 12.0' + platforms :ruby, :mswin, :mingw, :x64_mingw do + gem 'sqlite3', '~> 1.3' + end + end + + group :mongoid do + gem 'cancancan-mongoid' + gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid' + gem 'database_cleaner-mongoid', '>= 2.0', require: false + gem 'kaminari-mongoid' + gem 'mongoid', '~> 8.0' + gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip' + gem 'shrine-mongoid', '~> 1.0' end end +appraise 'rails-7.2' do + gem 'rails', '~> 7.2.0' + gem 'importmap-rails', require: false +end + +appraise 'rails-8.0' do + gem 'rails', '~> 8.0.0' + gem 'importmap-rails', require: false +end + appraise 'composite_primary_keys' do gem 'rails', '~> 7.0.0' - gem 'sassc-rails', '~> 2.1' - gem 'devise', '~> 4.8' - - group :test do - gem 'cancancan', '~> 3.2' - gem 'kt-paperclip' - gem 'rspec-rails', '>= 4.0.0.beta2' - gem 'shrine', '~> 3.0' - end group :active_record do gem 'composite_primary_keys' - gem 'paper_trail', '>= 12.0' + + platforms :ruby, :mswin, :mingw, :x64_mingw do + gem 'sqlite3', '~> 1.3' + end end end diff --git a/CHANGELOG.md b/CHANGELOG.md index d23eb4245b..73908df705 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,118 @@ ## [Unreleased](https://github.com/railsadminteam/rails_admin/tree/HEAD) -[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.1...HEAD) +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.3.0...HEAD) + +## [3.3.0](https://github.com/railsadminteam/rails_admin/tree/v3.3.0) - 2024-12-08 + +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.2.1...v3.3.0) + +### Added + +- Rails 8.0 support ([#3702](https://github.com/railsadminteam/rails_admin/pull/3702)) + +## [3.2.1](https://github.com/railsadminteam/rails_admin/tree/v3.2.0) - 2024-10-10 + +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.2.0...v3.2.1) + +### Fixed + +- Disable Turbo's prefetch behavior globally, to prevent custom actions unintentionally triggered ([f54a102](https://github.com/railsadminteam/rails_admin/commit/f54a102c6b0a420244ef044503944574ef1dfbd2), [#3701](https://github.com/railsadminteam/rails_admin/issues/3701)) + +## [3.2.0](https://github.com/railsadminteam/rails_admin/tree/v3.2.0) - 2024-09-08 + +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.2.0.rc...v3.2.0) + +### Fixed + +- Fix polymorphic id doesn't reset properly in an edge case ([7b2ffb1](https://github.com/railsadminteam/rails_admin/commit/7b2ffb12386e06a0e6e0bace6d331fc5af989e38), [#3630](https://github.com/railsadminteam/rails_admin/pull/3630)) + +## [3.2.0.rc](https://github.com/railsadminteam/rails_admin/tree/v3.2.0.rc) - 2024-08-25 + +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.2.0.beta...v3.2.0.rc) + +### Added + +- ActiveRecord 7.1 composite primary keys support ([53b89c9](https://github.com/railsadminteam/rails_admin/commit/53b89c9161e48c0f9b4ecd5f544398c9360ea50f)) + +### Changed + +- Introduce SingularAssociation and CollectionAssociation to tidy up the view files ([876be11](https://github.com/railsadminteam/rails_admin/commit/876be11ec01237596b2f27e15239e86418ce7610)) + +### Fixed + +- Fix to show a thumbnail of all representable ActiveStorage attachments ([#3656](https://github.com/railsadminteam/rails_admin/pull/3656), [7754ac3](https://github.com/railsadminteam/rails_admin/commit/7754ac34eb8e0af7605b2e52ae0646b17e9bb0c6)) +- Fix to detect images properly in FileUpload and MultipleFileUpload field ([35c8702](https://github.com/railsadminteam/rails_admin/commit/35c8702351aa300bddcc950d36d68b80742f5011), [#3633](https://github.com/railsadminteam/rails_admin/pull/3633)) +- Fix to reset polymorphic id selection upon type change ([#3630](https://github.com/railsadminteam/rails_admin/pull/3630), [13114e5](https://github.com/railsadminteam/rails_admin/commit/13114e5629d49eab14d58df1319eb068dacedba7)) +- Lock jQuery UI version due to incompatibility with 1.14 ([5245d5b](https://github.com/railsadminteam/rails_admin/commit/5245d5bb91691d646219b5243f3f881a0144a3fd), [#3692](https://github.com/railsadminteam/rails_admin/issues/3692)) + +## [3.2.0.beta](https://github.com/railsadminteam/rails_admin/tree/v3.2.0.beta) - 2024-07-13 + +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.4...v3.2.0.beta) + +### Added + +- Allow turbo-rails 2 in gemspec ([#3671](https://github.com/railsadminteam/rails_admin/pull/3671)) +- ViteRuby integration ([#3643](https://github.com/railsadminteam/rails_admin/pull/3643), [0e12e5b](https://github.com/railsadminteam/rails_admin/commit/0e12e5b465997c14d5b7a4d500a0d4cebed21aa9)) +- Support client-side dynamic scoping ([12715f2](https://github.com/railsadminteam/rails_admin/commit/12715f2dd12d97f0676e548e4271906df424b89d), [#2934](https://github.com/railsadminteam/rails_admin/issues/2934)) +- Add support for `%-l` option to Flatpickr ([#3616](https://github.com/railsadminteam/rails_admin/pull/3616)) + +### Changed + +- Handle has_one assignment on the field level, making patched has_one getters/setters unnecessary ([91737ab](https://github.com/railsadminteam/rails_admin/commit/91737ab3c2fa22cbe08aedd28770a12704fde6c7)) + +### Fixed + +- Use require_relative to avoid modifying $LOAD_PATH in gemspec ([#3690](https://github.com/railsadminteam/rails_admin/pull/3690)) +- Tidy up trailing whitespace in gem post_install_message ([#3689](https://github.com/railsadminteam/rails_admin/pull/3689)) +- Fix enum filter breaking when pre-populated ([d62f604](https://github.com/railsadminteam/rails_admin/commit/d62f604cc8d7d1434f7dfe0c5aca3aaf3dc2547b), [#3651](https://github.com/railsadminteam/rails_admin/issues/3651)) +- Fix error on searching or sorting by ActiveStorage field ([dba6c4b](https://github.com/railsadminteam/rails_admin/commit/dba6c4b815fbe4aa4f62a13b660e865a89151838), [#3678](https://github.com/railsadminteam/rails_admin/issues/3678)) +- Fix to remove trailing slash from meta tags ([#3672](https://github.com/railsadminteam/rails_admin/pull/3672)) +- Fix default config path for ImportmapFormatter being misspelled ([#3676](https://github.com/railsadminteam/rails_admin/pull/3676)) +- Fix table names not quoted properly on sorting ([#3652](https://github.com/railsadminteam/rails_admin/pull/3652), [#1631](https://github.com/railsadminteam/rails_admin/issues/1631)) +- Fix ActiveStorage/ActionText detection less likely to cause false positives ([073b809](https://github.com/railsadminteam/rails_admin/commit/073b809853b6bc231841e3f8dd9d35875220c616), [#3659](https://github.com/railsadminteam/rails_admin/issues/3659)) +- Fix boolean fields in a Mongoid embedded document fails to be updated ([#3555](https://github.com/railsadminteam/rails_admin/pull/3555), [#3554](https://github.com/railsadminteam/rails_admin/issues/3554)) +- Fix wrongly referring to `:update_only` in nested fields ([#3649](https://github.com/railsadminteam/rails_admin/pull/3649)) +- Fix to use HTML `q` element for better localization support ([#3636](https://github.com/railsadminteam/rails_admin/pull/3636)) +- Fix `is_blank` and `is_present` filters breaking for uuid columns ([#3629](https://github.com/railsadminteam/rails_admin/pull/3629), [#3669](https://github.com/railsadminteam/rails_admin/issues/3669)) +- Fix polymorphic association target classes not set correctly in subclasses ([2a89ebc](https://github.com/railsadminteam/rails_admin/commit/2a89ebcfa96243697988f6570b9c9be19a7a01b5), [#3631](https://github.com/railsadminteam/rails_admin/issues/3631)) + +### Security + +- Validate `return_to` param using `request.base_url` to prevent arbitrary redirection ([#3627](https://github.com/railsadminteam/rails_admin/pull/3627)) + +## [3.1.4](https://github.com/railsadminteam/rails_admin/tree/v3.1.4) - 2024-07-09 + +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.3...v3.1.4) + +### Fixed + +- Fix [32f91e4](https://github.com/railsadminteam/rails_admin/commit/32f91e4b49205e44d3931c2e36d9f7273384a250) broke fields with HTML tags ([758d249](https://github.com/railsadminteam/rails_admin/commit/758d249d950062be6840f9c96e2a286e02b92a1e), [#3686](https://github.com/railsadminteam/rails_admin/issues/3686#issuecomment-2215491140)) + +## [3.1.3](https://github.com/railsadminteam/rails_admin/tree/v3.1.3) - 2024-07-06 + +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.2...v3.1.3) + +### Fixed + +- Fix bson 5.0 compatibility ([13da4f0](https://github.com/railsadminteam/rails_admin/commit/13da4f0191f5185dadecdfe9e6fc9ca808f7f73d)) +- Fix Importmap 2.0 compatibility ([bd0cf97](https://github.com/railsadminteam/rails_admin/commit/bd0cf97530d93dc66577e5d1ea0da2ebf3b57737)) + +### Security + +- Fix XSS vulnerability in the list view ([b5a287d](https://github.com/railsadminteam/rails_admin/commit/b5a287d82e2cbd1737a1a01e11ede2911cce7fef), [GHSA-8qgm-g2vv-vwvc](https://github.com/railsadminteam/rails_admin/security/advisories/GHSA-8qgm-g2vv-vwvc)) + +## [3.1.2](https://github.com/railsadminteam/rails_admin/tree/v3.1.2) - 2023-03-23 + +[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.1...v3.1.2) + +### Fixed + +- Fix install failing with importmap setup ([aca22b6](https://github.com/railsadminteam/rails_admin/commit/aca22b6ba1eca1ac618525334cf14fc946e1c99e), [#3609](https://github.com/railsadminteam/rails_admin/issues/3609)) +- Fix to show non-eager-loaded models which are explicitly configured ([87c9d5b](https://github.com/railsadminteam/rails_admin/commit/87c9d5bc5b6ffb423e72054b3cfe8f949c12c178), [#3604](https://github.com/railsadminteam/rails_admin/issues/3604)) +- Fix `rails_admin.dom_ready` event not triggered with jQuery `on` ([2ee43de](https://github.com/railsadminteam/rails_admin/commit/2ee43deb1fa8d3a9e3ea0e589c1687d684e19ad6), [33773d7](https://github.com/railsadminteam/rails_admin/commit/33773d7f8dd43eeb0f6a7c125c4bee170132e5d2), [#3600](https://github.com/railsadminteam/rails_admin/discussions/3600)) +- Restore caching in RailsAdmin::Config::Model#excluded? ([#3587](https://github.com/railsadminteam/rails_admin/pull/3587)) +- Optimize/simplify viable_models file path to class name logic ([#3589](https://github.com/railsadminteam/rails_admin/pull/3589)) ## [3.1.1](https://github.com/railsadminteam/rails_admin/tree/v3.1.1) - 2022-12-18 @@ -625,7 +736,7 @@ - Fix Syntax Error in removal of new nested entity([#2539](https://github.com/railsadminteam/rails_admin/pull/2539)) - Fix momentjs translations for '%-d' format day of the month([#2540](https://github.com/railsadminteam/rails_admin/pull/2540)) - Fix Mongoid BSON object field ([#2495](https://github.com/railsadminteam/rails_admin/issues/2495)) -- Make browser ignore validaitons of removed nested child models([#2443](https://github.com/railsadminteam/rails_admin/issues/2443), [#2490](https://github.com/railsadminteam/rails_admin/pull/2490)) +- Make browser ignore validations of removed nested child models([#2443](https://github.com/railsadminteam/rails_admin/issues/2443), [#2490](https://github.com/railsadminteam/rails_admin/pull/2490)) ## [0.8.1](https://github.com/railsadminteam/rails_admin/tree/v0.8.1) - 2015-11-24 diff --git a/Gemfile b/Gemfile index 2959f4f823..0965e94b45 100644 --- a/Gemfile +++ b/Gemfile @@ -3,20 +3,14 @@ source 'https://rubygems.org' gem 'appraisal', '>= 2.0' -gem 'devise' +gem 'devise', '~> 4.7' gem 'net-smtp', require: false gem 'rails' +gem 'sassc-rails', '~> 2.1' +gem 'turbo-rails' +gem 'vite_rails', require: false gem 'webpacker', require: false -gem 'webrick', '~> 1.7' - -group :active_record do - gem 'paper_trail' - - platforms :ruby, :mswin, :mingw, :x64_mingw do - gem 'mysql2', '>= 0.3.14' - gem 'sqlite3', '>= 1.3' - end -end +gem 'webrick' group :development, :test do gem 'pry', '>= 0.9' @@ -25,21 +19,22 @@ end group :test do gem 'cancancan', '~> 3.0' gem 'carrierwave', ['>= 2.0.0.rc', '< 3'] - gem 'cuprite' + gem 'cuprite', '!= 0.15.1' gem 'database_cleaner-active_record', '>= 2.0', require: false - gem 'database_cleaner-mongoid', '>= 2.0', require: false gem 'dragonfly', '~> 1.0' - gem 'factory_bot', '>= 4.2' + gem 'factory_bot', '>= 4.2', '!= 6.4.5' gem 'generator_spec', '>= 0.8' + gem 'kt-paperclip' gem 'launchy', '>= 2.2' gem 'mini_magick', '>= 3.4' gem 'pundit' gem 'rack-cache', require: 'rack/cache' gem 'rspec-expectations', '!= 3.8.3' - gem 'rspec-rails', '>= 2.14' + gem 'rspec-rails', '>= 4.0.0.beta2' gem 'rspec-retry' gem 'rubocop', ['~> 1.20', '!= 1.22.2'], require: false gem 'rubocop-performance', require: false + gem 'shrine', '~> 3.0' gem 'simplecov', '>= 0.9', require: false gem 'simplecov-lcov', require: false gem 'timecop', '>= 0.5' @@ -48,4 +43,14 @@ group :test do gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby] end +group :active_record do + gem 'paper_trail', '>= 12.0' + + platforms :ruby, :mswin, :mingw, :x64_mingw do + gem 'mysql2', '>= 0.3.14' + gem 'pg', '>= 1.0.0' + gem 'sqlite3', '>= 1.3.0' + end +end + gemspec diff --git a/README.md b/README.md index 421a70bea7..104726b85e 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ RailsAdmin is a Rails engine that provides an easy-to-use interface for managing - Check out [the docs][docs]. - Try the [live demo][demo]. ([Source code][dummy_app]) -[demo]: http://rails-admin-tb.herokuapp.com/ -[dummy_app]: https://github.com/bbenezech/dummy_app +[demo]: https://rails-admin.fly.dev/admin/ +[dummy_app]: https://github.com/railsadminteam/rails_admin/tree/master/spec/dummy_app [docs]: https://github.com/railsadminteam/rails_admin/wiki ## Features diff --git a/app/assets/javascripts/rails_admin/application.js.erb b/app/assets/javascripts/rails_admin/application.js.erb index c5aa0765fa..012612e82d 100644 --- a/app/assets/javascripts/rails_admin/application.js.erb +++ b/app/assets/javascripts/rails_admin/application.js.erb @@ -9,6 +9,7 @@ //= require 'rails_admin/popper' //= require 'rails_admin/bootstrap' +//= require 'rails_admin/abstract-select' //= require 'rails_admin/filter-box' //= require 'rails_admin/filtering-multiselect' //= require 'rails_admin/filtering-select' @@ -20,10 +21,10 @@ //= require 'rails_admin/ui' //= require 'rails_admin/custom/ui' -<% if defined?(ActiveStorage) %> +<% if defined?(ActiveStorage::Engine) %> //= require activestorage <% end %> -<% if defined?(ActionText) && Rails.gem_version >= Gem::Version.new('7.0') %> +<% if defined?(ActionText::Engine) && Rails.gem_version >= Gem::Version.new('7.0') %> //= require trix //= require actiontext <% end %> diff --git a/app/assets/stylesheets/rails_admin/application.scss.erb b/app/assets/stylesheets/rails_admin/application.scss.erb index 698be8c605..133163db2b 100644 --- a/app/assets/stylesheets/rails_admin/application.scss.erb +++ b/app/assets/stylesheets/rails_admin/application.scss.erb @@ -30,6 +30,6 @@ @import "rails_admin/styles/base/theming"; @import "rails_admin/custom/theming"; -<% if defined?(ActionText) && Rails.gem_version >= Gem::Version.new('7.0') %> +<% if defined?(ActionText::Engine) && Rails.gem_version >= Gem::Version.new('7.0') %> @import "trix"; <% end %> diff --git a/app/controllers/rails_admin/main_controller.rb b/app/controllers/rails_admin/main_controller.rb index 5968bb7bec..af5a69aba3 100644 --- a/app/controllers/rails_admin/main_controller.rb +++ b/app/controllers/rails_admin/main_controller.rb @@ -56,7 +56,11 @@ def respond_to_missing?(sym, include_private) end def back_or_index - params[:return_to].presence && params[:return_to].include?(request.host) && (params[:return_to] != request.fullpath) ? params[:return_to] : index_path + allowed_return_to?(params[:return_to].to_s) ? params[:return_to] : index_path + end + + def allowed_return_to?(url) + url != request.fullpath && url.start_with?(request.base_url, '/') && !url.start_with?('//') end def get_sort_hash(model_config) diff --git a/app/helpers/rails_admin/application_helper.rb b/app/helpers/rails_admin/application_helper.rb index 147fd7ca3f..fbc8de8efa 100644 --- a/app/helpers/rails_admin/application_helper.rb +++ b/app/helpers/rails_admin/application_helper.rb @@ -7,6 +7,10 @@ def authorized?(action_name, abstract_model = nil, object = nil) action(action_name, abstract_model, object).try(:authorized?) end + def current_action + params[:action].in?(%w[create new]) ? 'create' : 'update' + end + def current_action?(action, abstract_model = @abstract_model, object = @object) @action.custom_key == action.custom_key && abstract_model.try(:to_param) == @abstract_model.try(:to_param) && diff --git a/app/helpers/rails_admin/form_builder.rb b/app/helpers/rails_admin/form_builder.rb index 37cbb03e28..d52f9eb2cf 100644 --- a/app/helpers/rails_admin/form_builder.rb +++ b/app/helpers/rails_admin/form_builder.rb @@ -108,8 +108,8 @@ def dom_name(field) end def hidden_field(method, options = {}) - if method == :id - super method, {value: object.id.to_s} + if method == :id && object.id.is_a?(Array) + super method, {value: RailsAdmin.config.composite_keys_serializer.serialize(object.id)} else super end diff --git a/app/helpers/rails_admin/main_helper.rb b/app/helpers/rails_admin/main_helper.rb index d80f4e4b09..3f7540b872 100644 --- a/app/helpers/rails_admin/main_helper.rb +++ b/app/helpers/rails_admin/main_helper.rb @@ -45,7 +45,7 @@ def ordered_filter_options filter_for_field = duplet[1] filter_name = filter_for_field.keys.first filter_hash = filter_for_field.values.first - unless (field = filterable_fields.find { |f| f.name == filter_name.to_sym }) + unless (field = filterable_fields.find { |f| f.name == filter_name.to_sym }&.with({view: self})) raise "#{filter_name} is not currently filterable; filterable fields are #{filterable_fields.map(&:name).join(', ')}" end diff --git a/app/views/layouts/rails_admin/_head.html.erb b/app/views/layouts/rails_admin/_head.html.erb index d59e9d8965..43ce0096d6 100644 --- a/app/views/layouts/rails_admin/_head.html.erb +++ b/app/views/layouts/rails_admin/_head.html.erb @@ -1,7 +1,8 @@ - - - - + + + + + <%= csrf_meta_tag %> <% case RailsAdmin::config.asset_source when :webpacker %> @@ -12,6 +13,8 @@ <%= stylesheet_link_tag "rails_admin/application.css", media: :all, data: {'turbo-track': 'reload'} %> <%= javascript_include_tag "rails_admin/application.js", defer: true, data: {'turbo-track': 'reload'} %> <% end %> +<% when :vite %> + <%= vite_javascript_tag "rails_admin", defer: true, data: {'turbo-track': 'reload'} %> <% when :webpack %> <%= stylesheet_link_tag "rails_admin.css", media: :all, data: {'turbo-track': 'reload'} %> <%= javascript_include_tag "rails_admin.js", defer: true, data: {'turbo-track': 'reload'} %> @@ -19,11 +22,11 @@ <%= stylesheet_link_tag "rails_admin.css", media: :all, data: {'turbo-track': 'reload'} %> <%= javascript_inline_importmap_tag(RailsAdmin::Engine.importmap.to_json(resolver: self)) %> <%= javascript_importmap_module_preload_tags(RailsAdmin::Engine.importmap) %> - <%= javascript_importmap_shim_nonce_configuration_tag %> - <%= javascript_importmap_shim_tag %> + <%= javascript_importmap_shim_nonce_configuration_tag if respond_to? :javascript_importmap_shim_nonce_configuration_tag %> + <%= javascript_importmap_shim_tag if respond_to? :javascript_importmap_shim_tag %> <%= # Preload jQuery and make it global, unless jQuery UI fails to initialize tag.script "import jQuery from 'jquery'; window.jQuery = jQuery;".html_safe, type: "module" %> <%= javascript_import_module_tag 'rails_admin' %> <% else raise "Unknown asset_source: #{RailsAdmin::config.asset_source}" - end %> \ No newline at end of file + end %> diff --git a/app/views/rails_admin/main/_form_boolean.html.erb b/app/views/rails_admin/main/_form_boolean.html.erb index 87ae0bab16..36a5196716 100644 --- a/app/views/rails_admin/main/_form_boolean.html.erb +++ b/app/views/rails_admin/main/_form_boolean.html.erb @@ -2,9 +2,9 @@
<% {'1': [true, 'btn-outline-success'], '0': [false, 'btn-outline-danger'], '': [nil, 'btn-outline-secondary']}.each do |text, (value, btn_class)| %> <%= form.radio_button field.method_name, text, field.html_attributes.reverse_merge({ checked: field.form_value == value, required: field.required, class: 'btn-check' }) %> - + <% end %> <% end %>
<% else %> diff --git a/app/views/rails_admin/main/_form_filtering_multiselect.html.erb b/app/views/rails_admin/main/_form_filtering_multiselect.html.erb index f279c940dd..5260087bd3 100644 --- a/app/views/rails_admin/main/_form_filtering_multiselect.html.erb +++ b/app/views/rails_admin/main/_form_filtering_multiselect.html.erb @@ -1,44 +1,14 @@ <% config = field.associated_model_config - source_abstract_model = RailsAdmin.config(form.object.class).abstract_model - - selected = form.object.send(field.name) - selected_ids = selected.map{|s| s.send(field.associated_primary_key).to_s} - - current_action = params[:action].in?(['create', 'new']) ? 'create' : 'update' - - xhr = !field.associated_collection_cache_all - - collection = if xhr - selected.map { |o| [o.send(field.associated_object_label_method), o.send(field.associated_primary_key)] } - else - i = 0 - controller.list_entries(config, :index, field.associated_collection_scope, false).map { |o| [o.send(field.associated_object_label_method), o.send(field.associated_primary_key).to_s] }.sort_by {|a| [selected_ids.index(a[1]) || selected_ids.size, i+=1] } - end - - js_data = { - xhr: xhr, - :'edit-url' => (field.inline_edit && authorized?(:edit, config.abstract_model) ? edit_path(model_name: config.abstract_model.to_param, id: '__ID__') : ''), - remote_source: index_path(config.abstract_model, source_object_id: form.object.id, source_abstract_model: source_abstract_model.to_param, associated_collection: field.name, current_action: current_action, compact: true), - sortable: !!field.orderable, - removable: !!field.removable, - cacheAll: !!field.associated_collection_cache_all, - regional: { - add: t('admin.misc.add_new'), - chooseAll: t('admin.misc.chose_all'), - clearAll: t('admin.misc.clear_all'), - down: t('admin.misc.down'), - remove: t('admin.misc.remove'), - search: t('admin.misc.search'), - up: t('admin.misc.up') - } - } %> +
- <% selected_ids = (hdv = field.form_default_value).nil? ? selected_ids : hdv %> - <%= form.select field.method_name, collection, { selected: selected_ids, object: form.object }, field.html_attributes.reverse_merge({data: { filteringmultiselect: true, options: js_data.to_json }, multiple: true}) %> + <%= + form.select field.method_name, field.collection, { selected: field.form_value, object: form.object }, + field.html_attributes.reverse_merge({data: { filteringmultiselect: true, options: field.widget_options.to_json }, multiple: true}) + %>
<% if authorized?(:new, config.abstract_model) && field.inline_add %> diff --git a/app/views/rails_admin/main/_form_nested_one.html.erb b/app/views/rails_admin/main/_form_nested_one.html.erb index 976775b8b9..54906808de 100644 --- a/app/views/rails_admin/main/_form_nested_one.html.erb +++ b/app/views/rails_admin/main/_form_nested_one.html.erb @@ -4,7 +4,7 @@ - <% unless field.nested_form[:update_only] || !field.inline_add %> + <% if field.inline_add %> <%= form.link_to_add " #{wording_for(:link, :new, field.associated_model_config.abstract_model)}".html_safe, field.name, { class: 'btn btn-info', :'data-add-label' => " #{wording_for(:link, :new, field.associated_model_config.abstract_model)}".gsub("\n", "") } %> <% end %>
diff --git a/app/views/rails_admin/main/_form_polymorphic_association.html.erb b/app/views/rails_admin/main/_form_polymorphic_association.html.erb index 067bd4397a..9805a7fdfb 100644 --- a/app/views/rails_admin/main/_form_polymorphic_association.html.erb +++ b/app/views/rails_admin/main/_form_polymorphic_association.html.erb @@ -1,32 +1,23 @@ <% - type_collection = field.polymorphic_type_collection - type_column = field.association.foreign_type.to_s - selected_type = field.bindings[:object].send(type_column) - selected = field.bindings[:object].send(field.association.name) - collection = selected ? [[field.formatted_value, selected.id]] : [[]] - column_type_dom_id = form.dom_id(field).sub(field.method_name.to_s, type_column) - current_action = params[:action].in?(['create', 'new']) ? 'create' : 'update' - - default_options = { float_left: false } - - js_data = type_collection.inject({}) do |options, model| - source_abstract_model = RailsAdmin.config(form.object.class).abstract_model - options.merge(model.second.downcase.gsub('::', '-') => { - xhr: true, - remote_source: index_path(model.second.underscore, source_object_id: form.object.id, source_abstract_model: source_abstract_model.to_param, current_action: current_action, compact: true), - float_left: false - }) - end + column_type_dom_id = form.dom_id(field).sub(field.method_name.to_s, field.type_column) %>
- <% js_data.each do |model, value| %> + <% field.widget_options_for_types.each do |model, value| %>
<% end %> - <%= form.select type_column, type_collection, {include_blank: true, selected: selected_type}, class: "form-select", id: column_type_dom_id, data: { polymorphic: true, urls: field.polymorphic_type_urls.to_json }, style: "float: left; margin-right: 10px;" %> + <%= + form.select field.type_column, field.type_collection, {include_blank: true, selected: field.selected_type}, + class: "form-select", id: column_type_dom_id, data: { polymorphic: true, urls: field.type_urls.to_json }, + style: "float: left; margin-right: 10px;" + %>
- <%= form.select field.method_name, collection, {include_blank: true, selected: selected.try(:id)}, class: "form-control", data: { filteringselect: true, options: js_data[selected_type.try(:downcase)] || default_options }, placeholder: 'Search' %> + <%= + form.select field.method_name, field.collection, {include_blank: true, selected: field.selected_id}, + class: "form-control", data: { filteringselect: true, options: field.widget_options }, + placeholder: 'Search' + %>
diff --git a/app/views/rails_admin/main/delete.html.erb b/app/views/rails_admin/main/delete.html.erb index 6b08bedce8..94cfcb6130 100644 --- a/app/views/rails_admin/main/delete.html.erb +++ b/app/views/rails_admin/main/delete.html.erb @@ -1,6 +1,6 @@

<%= t("admin.form.are_you_sure_you_want_to_delete_the_object", model_name: @abstract_model.pretty_name.downcase) %> - “<%= @model_config.with(object: @object).object_label %>” + <%= @model_config.with(object: @object).object_label %> <%= t("admin.form.all_of_the_following_related_items_will_be_deleted") %>