activeadmin_favorites 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +17 -0
  3. data/CODE_OF_CONDUCT.md +31 -0
  4. data/CONTRIBUTING.md +29 -0
  5. data/GOVERNANCE.md +29 -0
  6. data/LICENSE.md +21 -0
  7. data/README.md +146 -0
  8. data/SECURITY.md +27 -0
  9. data/activeadmin_favorites.gemspec +68 -0
  10. data/app/assets/controllers/activeadmin_favorites/personalization_controller.js +199 -0
  11. data/app/models/active_admin/favorites/application_record.rb +9 -0
  12. data/app/models/active_admin/favorites/combined_favorite.rb +9 -0
  13. data/app/models/active_admin/favorites/favorite/macro_builder.rb +43 -0
  14. data/app/models/active_admin/favorites/favorite/macro_catalog.rb +118 -0
  15. data/app/models/active_admin/favorites/favorite/macro_resolver.rb +86 -0
  16. data/app/models/active_admin/favorites/favorite/macro_validator.rb +87 -0
  17. data/app/models/active_admin/favorites/favorite/query_params.rb +41 -0
  18. data/app/models/active_admin/favorites/favorite/range_detector.rb +54 -0
  19. data/app/models/active_admin/favorites/favorite.rb +339 -0
  20. data/app/models/active_admin/favorites/filters_favorite.rb +8 -0
  21. data/app/models/active_admin/favorites/lens_favorite.rb +9 -0
  22. data/app/models/active_admin/favorites/view_lens/layout.rb +86 -0
  23. data/app/models/active_admin/favorites/view_lens_default.rb +40 -0
  24. data/app/models/active_admin/favorites.rb +6 -0
  25. data/app/views/active_admin/favorites/_lens_catalog_data.html.erb +9 -0
  26. data/app/views/active_admin/favorites/_macro_fields.html.erb +53 -0
  27. data/app/views/active_admin/favorites/_personalization_trigger.html.erb +69 -0
  28. data/app/views/active_admin/resource/index.html.arb +99 -0
  29. data/app/views/active_admin/resource/show.html.arb +13 -0
  30. data/config/locales/activeadmin_favorites.en.yml +60 -0
  31. data/config/locales/activeadmin_favorites.host.yml.example +17 -0
  32. data/config/polyrun_coverage.yml +8 -0
  33. data/db/migrate/20260709100000_create_active_admin_view_lens_defaults.rb +24 -0
  34. data/db/migrate/20260709130000_create_admin_favorites.rb +33 -0
  35. data/lib/activeadmin/favorites/configuration.rb +31 -0
  36. data/lib/activeadmin/favorites/engine.rb +75 -0
  37. data/lib/activeadmin/favorites/hash_coercion.rb +34 -0
  38. data/lib/activeadmin/favorites/install.rb +121 -0
  39. data/lib/activeadmin/favorites/migration_helpers.rb +34 -0
  40. data/lib/activeadmin/favorites/migration_support.rb +19 -0
  41. data/lib/activeadmin/favorites/register_favorites.rb +272 -0
  42. data/lib/activeadmin/favorites/register_view_lens_preferences.rb +98 -0
  43. data/lib/activeadmin/favorites/user_record.rb +26 -0
  44. data/lib/activeadmin/favorites/version.rb +7 -0
  45. data/lib/activeadmin/favorites/view_lens/applicator.rb +150 -0
  46. data/lib/activeadmin/favorites/view_lens/catalog.rb +108 -0
  47. data/lib/activeadmin/favorites/view_lens/current.rb +28 -0
  48. data/lib/activeadmin/favorites/view_lens/patches.rb +95 -0
  49. data/lib/activeadmin/favorites/view_lens/resource_dsl.rb +44 -0
  50. data/lib/activeadmin/favorites/view_lens.rb +8 -0
  51. data/lib/activeadmin/favorites.rb +30 -0
  52. data/lib/activeadmin_favorites.rb +5 -0
  53. data/lib/generators/activeadmin_favorites/install/templates/favorite_policy.rb +56 -0
  54. data/lib/generators/activeadmin_favorites/install/templates/initializer.rb +16 -0
  55. data/lib/generators/activeadmin_favorites/install/templates/locale.en.yml +60 -0
  56. data/lib/generators/activeadmin_favorites/install_generator.rb +37 -0
  57. data/lib/tasks/activeadmin_favorites_tasks.rake +39 -0
  58. data/sig/activeadmin/favorites.rbs +5 -0
  59. metadata +418 -0
@@ -0,0 +1,99 @@
1
+ def wrap_with_batch_action_form(&block)
2
+ if active_admin_config.batch_actions.any?
3
+ insert_tag(ActiveAdmin::BatchActions::BatchActionForm, &block)
4
+ batch_actions_to_display.each do |batch_action|
5
+ if batch_action.partial.present?
6
+ render(batch_action.partial)
7
+ end
8
+ end
9
+ else
10
+ block.call
11
+ end
12
+ end
13
+
14
+ def build_collection
15
+ if collection_empty?(collection)
16
+ if params[:q] || params[:scope]
17
+ render("active_admin/resource/index_empty_results")
18
+ else
19
+ render("active_admin/resource/index_blank_slate")
20
+ end
21
+ else
22
+ render_index
23
+ end
24
+ end
25
+
26
+ def build_table_tools
27
+ if any_table_tools?
28
+ div class: "index-data-table-toolbar" do
29
+ render "batch_actions_dropdown"
30
+ build_scopes
31
+ build_index_list
32
+ end
33
+ end
34
+ end
35
+
36
+ def any_table_tools?
37
+ active_admin_config.batch_actions.any? ||
38
+ active_admin_config.scopes.any? ||
39
+ active_admin_config.page_presenters[:index].try(:size).try(:>, 1)
40
+ end
41
+
42
+ def build_scopes
43
+ if active_admin_config.scopes.any?
44
+ scope_options = {scope_count: page_presenter.fetch(:scope_count, true)}
45
+ insert_tag(ActiveAdmin::Views::Scopes, active_admin_config.scopes, scope_options)
46
+ end
47
+ end
48
+
49
+ def build_index_list
50
+ indexes = active_admin_config.page_presenters[:index]
51
+
52
+ if indexes.is_a?(Hash) && indexes.length > 1
53
+ index_classes = []
54
+ active_admin_config.page_presenters[:index].each do |type, page_presenter|
55
+ index_classes << find_index_renderer_class(page_presenter[:as])
56
+ end
57
+
58
+ insert_tag(ActiveAdmin::Views::IndexList, index_classes)
59
+ end
60
+ end
61
+
62
+ # Returns the actual class for rendering the main content on the index
63
+ # page. To set this, use the :as option in the page_presenter block.
64
+ def find_index_renderer_class(klass)
65
+ if klass.is_a?(Class)
66
+ klass
67
+ else
68
+ ::ActiveAdmin::Views.const_get("IndexAs" + klass.to_s.camelcase)
69
+ end
70
+ end
71
+
72
+ def render_index
73
+ renderer_class = find_index_renderer_class(page_presenter[:as])
74
+
75
+ paginator = page_presenter.fetch(:paginator, true)
76
+ download_links = page_presenter.fetch(:download_links, active_admin_config.namespace.download_links)
77
+ pagination_total = page_presenter.fetch(:pagination_total, true)
78
+ per_page = page_presenter.fetch(:per_page, active_admin_config.per_page)
79
+
80
+ paginated_collection(
81
+ collection, entry_name: active_admin_config.resource_label,
82
+ entries_name: active_admin_config.plural_resource_label(count: collection_size),
83
+ download_links: download_links,
84
+ paginator: paginator,
85
+ per_page: per_page,
86
+ pagination_total: pagination_total
87
+ ) do
88
+ insert_tag(renderer_class, page_presenter, collection)
89
+ end
90
+ end
91
+
92
+ div class: "main-content-container" do
93
+ wrap_with_batch_action_form do
94
+ build_table_tools
95
+ build_collection
96
+ end
97
+ end
98
+
99
+ render partial: "active_admin/favorites/lens_catalog_data", locals: {action_name: "index", render_context: self}
@@ -0,0 +1,13 @@
1
+ def attributes_table(*args, &block)
2
+ attributes_table_for resource, *args, &block
3
+ end
4
+
5
+ div class: "main-content-container" do
6
+ if page_presenter.block
7
+ instance_exec resource, &page_presenter.block
8
+ else
9
+ render "show_default"
10
+ end
11
+ end
12
+
13
+ render partial: "active_admin/favorites/lens_catalog_data", locals: {action_name: "show", render_context: self}
@@ -0,0 +1,60 @@
1
+ en:
2
+ active_admin:
3
+ favorites:
4
+ add_favorite: Add to favorites
5
+ advanced_macros: Advanced macros
6
+ created: Favorite saved
7
+ creator_column: Creator
8
+ edit_favorite: Edit favorite
9
+ filters_column: Filters
10
+ form_panel: Favorite details
11
+ macros_hint: Choose shortcut templates to keep date filters up to date when you open this favorite.
12
+ macros_json_hint: JSON array of macro objects. Use only when templates are not enough.
13
+ macros_json_invalid: Macros JSON is invalid
14
+ macros_panel: Dynamic filters
15
+ menu: Favorites
16
+ no_detected_ranges: No date range filters detected in the current view. Use advanced macros if needed.
17
+ open: Open
18
+ published: Published for everyone
19
+ updated: Favorite updated
20
+ use_advanced_macros: Edit macros as JSON
21
+ use_dynamic_range: Use dynamic range
22
+ visibility:
23
+ mine: Only me
24
+ published: "Published (%{time})"
25
+ visibility_column: Visibility
26
+ macro_templates:
27
+ previous_calendar_month: Previous calendar month
28
+ current_calendar_month: Current calendar month
29
+ previous_calendar_day: Previous day
30
+ current_calendar_day: Today
31
+ rolling_last_7_days: Last 7 days
32
+ rolling_last_30_days: Last 30 days
33
+ previous_fiscal_year: Previous fiscal year (Apr–Mar)
34
+ current_fiscal_year_to_date: Current fiscal year to date (Apr–Mar)
35
+ personalize_page: Personalize page
36
+ personalization_region: Page personalization
37
+ save_default: Save as my default
38
+ reset_default: Reset to defaults
39
+ save_lens_favorite: Save lens as favorite
40
+ include_layout: Include current page layout
41
+ lens_summary: Page layout
42
+ lens_created: Lens favorite saved
43
+ combined_created: Combined favorite saved
44
+ layout_saved: Page layout saved
45
+ layout_reset: Page layout reset
46
+ kind_column: Type
47
+ kind_navigation: Favorite types
48
+ no_personalization_items: No personalization options are available on this page.
49
+ kinds:
50
+ all: All
51
+ filters: Filters
52
+ lens: Lens
53
+ combined: Combined
54
+ groups:
55
+ columns: Columns
56
+ filters: Filters
57
+ action_items: Actions
58
+ panels: Panels
59
+ show_rows: Rows
60
+ block_column: Custom column %{position}
@@ -0,0 +1,17 @@
1
+ # Copy these keys into your host locale files (for example config/locales/activeadmin_favorites.fi.yml).
2
+ # The gem loads English from config/locales/activeadmin_favorites.en.yml automatically.
3
+ #
4
+ # Merge active_admin.favorites into each locale you support.
5
+
6
+ en:
7
+ active_admin:
8
+ favorites:
9
+ add_to_favorites: Add to favorites
10
+ personalize_page: Personalize page
11
+ hub_title: Favorites
12
+ filters_tab: Filters
13
+ lens_tab: Layout
14
+ combined_tab: Combined
15
+ save_lens_favorite: Save lens as favorite
16
+ lens_created: Layout favorite saved
17
+ combined_created: Combined favorite saved
@@ -0,0 +1,8 @@
1
+ track_under:
2
+ - lib
3
+ - app
4
+ minimum_line_percent: 50
5
+ report_formats:
6
+ - html
7
+ - cobertura
8
+ - console
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateActiveAdminViewLensDefaults < ActiveRecord::Migration[7.2]
4
+ include ActiveAdmin::Favorites::MigrationSupport
5
+
6
+ def change
7
+ json_type = favorites_json_column_type
8
+ user_foreign_key = favorites_user_foreign_key
9
+
10
+ create_table :active_admin_view_lens_defaults do |t|
11
+ t.bigint user_foreign_key, null: false
12
+ t.string :resource_key, null: false
13
+ t.string :action, null: false
14
+ t.public_send(json_type, :layout, null: false, default: {})
15
+
16
+ t.timestamps
17
+ end
18
+
19
+ add_index :active_admin_view_lens_defaults,
20
+ [user_foreign_key, :resource_key, :action],
21
+ unique: true,
22
+ name: "index_view_lens_defaults_on_user_resource_action"
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateAdminFavorites < ActiveRecord::Migration[7.2]
4
+ include ActiveAdmin::Favorites::MigrationSupport
5
+
6
+ def change
7
+ json_type = favorites_json_column_type
8
+ user_foreign_key = favorites_user_foreign_key
9
+
10
+ create_table :admin_favorites do |t|
11
+ t.string :type, null: false
12
+ t.bigint user_foreign_key, null: false
13
+ t.string :name, null: false
14
+ t.text :note
15
+ t.string :resource_key, null: false
16
+ t.string :path, null: false
17
+ t.text :query_string
18
+ t.boolean :published, null: false, default: false
19
+ t.datetime :published_at
20
+ t.public_send(json_type, :macros, null: false, default: [])
21
+ t.integer :macros_version, null: false, default: 1
22
+ t.string :action
23
+ t.public_send(json_type, :layout)
24
+
25
+ t.timestamps
26
+ end
27
+
28
+ add_index :admin_favorites, [user_foreign_key, :path, :query_string, :type],
29
+ unique: true,
30
+ name: "index_admin_favorites_on_user_path_query_and_type"
31
+ add_index :admin_favorites, :type
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAdmin
4
+ module Favorites
5
+ class Configuration
6
+ attr_accessor :user_class,
7
+ :user_foreign_key,
8
+ :user_association_name,
9
+ :user_label_method,
10
+ :current_user_method,
11
+ :stimulus_controller,
12
+ :namespace_name,
13
+ :table_name
14
+
15
+ def initialize
16
+ @user_class = "User"
17
+ @user_foreign_key = :user_id
18
+ @user_association_name = :user
19
+ @user_label_method = :email
20
+ @current_user_method = :current_user
21
+ @stimulus_controller = "activeadmin-favorites--personalization"
22
+ @namespace_name = :admin
23
+ @table_name = "admin_favorites"
24
+ end
25
+
26
+ def namespace_path_prefix
27
+ "/#{namespace_name}/"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAdmin
4
+ module Favorites
5
+ class Engine < ::Rails::Engine
6
+ engine_name "activeadmin_favorites"
7
+
8
+ initializer "activeadmin_favorites.load_lib" do
9
+ require "activeadmin/favorites/migration_helpers"
10
+ require "activeadmin/favorites/migration_support"
11
+ require "activeadmin/favorites/view_lens/current"
12
+ require "activeadmin/favorites/user_record"
13
+ require "activeadmin/favorites/view_lens"
14
+ require "activeadmin/favorites/hash_coercion"
15
+ require "activeadmin/favorites/view_lens/applicator"
16
+ require "activeadmin/favorites/view_lens/catalog"
17
+ require "activeadmin/favorites/view_lens/patches"
18
+ require "activeadmin/favorites/view_lens/resource_dsl"
19
+ require "activeadmin/favorites/install"
20
+ require "activeadmin/favorites/register_favorites"
21
+ require "activeadmin/favorites/register_view_lens_preferences"
22
+ end
23
+
24
+ initializer "activeadmin_favorites.assets" do |app|
25
+ assets_path = root.join("app/assets")
26
+ app.config.importmap.cache_sweepers << assets_path.join("controllers") if app.config.respond_to?(:importmap)
27
+
28
+ next unless app.config.respond_to?(:assets)
29
+
30
+ app.config.assets.precompile << "activeadmin_favorites/personalization_controller.js"
31
+ end
32
+
33
+ initializer "activeadmin_favorites.importmap", after: :importmap do
34
+ pin_controller = proc do |importmap|
35
+ importmap.pin "controllers/activeadmin_favorites/personalization_controller",
36
+ to: "activeadmin_favorites/personalization_controller.js"
37
+ end
38
+
39
+ application_importmap = Rails.application.importmap if Rails.application.respond_to?(:importmap)
40
+ application_importmap&.draw(&pin_controller)
41
+ ActiveAdmin.importmap.draw(&pin_controller) if defined?(ActiveAdmin) && ActiveAdmin.respond_to?(:importmap)
42
+ end
43
+
44
+ initializer "activeadmin_favorites.i18n" do
45
+ I18n.load_path << root.join("config/locales/activeadmin_favorites.en.yml")
46
+ end
47
+
48
+ initializer "activeadmin_favorites.append_migrations" do |app|
49
+ ActiveAdmin::Favorites::MigrationHelpers.append_engine_migrations!(app)
50
+ end
51
+
52
+ rake_tasks do
53
+ load root.join("lib/tasks/activeadmin_favorites_tasks.rake")
54
+ end
55
+
56
+ initializer "activeadmin_favorites.after_load", after: :load_config_initializers do
57
+ next unless defined?(ActiveAdmin) && ActiveAdmin.respond_to?(:after_load)
58
+
59
+ ActiveAdmin.after_load do
60
+ ActiveAdmin::Favorites.register_resources!
61
+ ActiveAdmin::Favorites.install!
62
+ end
63
+ end
64
+
65
+ config.to_prepare do
66
+ next unless defined?(ActiveAdmin::ResourceController)
67
+
68
+ ActiveAdmin::Favorites::Favorite.define_favorites_user_association!
69
+ ActiveAdmin::Favorites::ViewLensDefault.define_favorites_user_association!
70
+ ActiveAdmin::Favorites.register_resources!
71
+ ActiveAdmin::Favorites.install!
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAdmin
4
+ module Favorites
5
+ module HashCoercion
6
+ module_function
7
+
8
+ def deep_stringify(value, default: {})
9
+ case value
10
+ when Hash
11
+ value.deep_stringify_keys
12
+ when ActionController::Parameters
13
+ value.to_unsafe_h.deep_stringify_keys
14
+ else
15
+ return default unless value.respond_to?(:to_h)
16
+
17
+ hash = value.to_h
18
+ hash.is_a?(Hash) ? hash.deep_stringify_keys : default
19
+ end
20
+ end
21
+
22
+ def assignment_values(assignments)
23
+ case assignments
24
+ when ActionController::Parameters
25
+ assignments.to_unsafe_h.values
26
+ when Hash
27
+ assignments.values
28
+ else
29
+ Array(assignments)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAdmin
4
+ module Favorites
5
+ module Install
6
+ FILTER_FAVOURITE_ACTION = :save_filter_favorite
7
+ PERSONALIZE_ACTION = :personalize_page
8
+
9
+ module_function
10
+
11
+ def call
12
+ install_controller_methods!
13
+ install_action_items!
14
+ configure_favorites_resource!
15
+ ViewLens::InstallPatches.call
16
+ end
17
+
18
+ def configure_favorites_resource!
19
+ resource = ActiveAdmin.application.namespace(ActiveAdmin::Favorites.config.namespace_name)
20
+ .resources.find { |config| config.resource_class == Favorite }
21
+ return unless resource
22
+
23
+ resource.instance_variable_set(:@batch_actions, {}) if resource.instance_variable_get(:@batch_actions).nil?
24
+
25
+ if resource.respond_to?(:batch_actions=)
26
+ resource.batch_actions = false
27
+ else
28
+ resource.instance_variable_set(:@batch_actions_enabled, false)
29
+ end
30
+ end
31
+
32
+ def install_controller_methods!
33
+ return unless defined?(ActiveAdmin::ResourceController)
34
+
35
+ controller = ActiveAdmin::ResourceController
36
+ return if controller.included_modules.include?(ViewLens::ControllerMethods)
37
+
38
+ controller.include(ViewLens::ControllerMethods)
39
+ end
40
+
41
+ def install_action_items!
42
+ ActiveAdmin.application.namespaces.each do |namespace|
43
+ namespace.resources.each do |config|
44
+ next if config.is_a?(ActiveAdmin::Page)
45
+ next unless config.controller.action_methods.include?("index")
46
+ next if config.resource_class == Favorite
47
+
48
+ install_filter_favorite_action_item!(config)
49
+ install_personalize_action_item!(config)
50
+ install_show_personalize_action_item!(config)
51
+ end
52
+ end
53
+ end
54
+
55
+ def install_filter_favorite_action_item!(config)
56
+ return if config.action_items.any? { |item| item.name == FILTER_FAVOURITE_ACTION }
57
+
58
+ config.add_action_item(FILTER_FAVOURITE_ACTION, only: :index, priority: 5) do
59
+ sanitized_query = Favorite.sanitize_query_string(request.query_string)
60
+ user = send(ActiveAdmin::Favorites.config.current_user_method)
61
+
62
+ if sanitized_query.blank?
63
+ label = I18n.t("active_admin.favorites.add_favorite")
64
+ destination = new_admin_favorite_path(
65
+ path: request.path,
66
+ query_string: sanitized_query,
67
+ resource_key: active_admin_config.resource_name.route_key,
68
+ action_name: "index"
69
+ )
70
+ else
71
+ lookup = {
72
+ path: request.path,
73
+ query_string: sanitized_query
74
+ }
75
+ lookup[ActiveAdmin::Favorites.config.user_foreign_key] = user.id
76
+ owned_existing = Favorite.filters_kind.find_by(lookup)
77
+
78
+ label = if owned_existing
79
+ I18n.t("active_admin.favorites.edit_favorite")
80
+ else
81
+ I18n.t("active_admin.favorites.add_favorite")
82
+ end
83
+
84
+ destination = if owned_existing
85
+ edit_admin_favorite_path(owned_existing)
86
+ else
87
+ new_admin_favorite_path(
88
+ path: request.path,
89
+ query_string: sanitized_query,
90
+ resource_key: active_admin_config.resource_name.route_key,
91
+ action_name: "index"
92
+ )
93
+ end
94
+ end
95
+
96
+ link_to label, destination, class: "action-item-button"
97
+ end
98
+ end
99
+
100
+ def install_personalize_action_item!(config)
101
+ return unless config.controller.action_methods.include?("index")
102
+ return if config.action_items.any? { |item| item.name == :"#{PERSONALIZE_ACTION}_index" }
103
+
104
+ config.add_action_item(:"#{PERSONALIZE_ACTION}_index", only: :index, priority: 1) do
105
+ render partial: "active_admin/favorites/personalization_trigger",
106
+ locals: {action_name: "index"}
107
+ end
108
+ end
109
+
110
+ def install_show_personalize_action_item!(config)
111
+ return unless config.controller.action_methods.include?("show")
112
+ return if config.action_items.any? { |item| item.name == :"#{PERSONALIZE_ACTION}_show" }
113
+
114
+ config.add_action_item(:"#{PERSONALIZE_ACTION}_show", only: :show, priority: 1) do
115
+ render partial: "active_admin/favorites/personalization_trigger",
116
+ locals: {action_name: "show"}
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAdmin
4
+ module Favorites
5
+ module MigrationHelpers
6
+ module_function
7
+
8
+ def engine_migration_paths
9
+ root = ActiveAdmin::Favorites::Engine.root
10
+ Dir[root.join("db/migrate/*.rb")].sort
11
+ end
12
+
13
+ def host_migration_versions(app_root)
14
+ Dir[app_root.join("db/migrate/*.rb")].map { |path| File.basename(path).split("_", 2).first }
15
+ end
16
+
17
+ def append_engine_migrations!(app)
18
+ return if app.root.to_s.start_with?(ActiveAdmin::Favorites::Engine.root.to_s)
19
+
20
+ host_versions = host_migration_versions(app.root)
21
+ paths = app.config.paths["db/migrate"]
22
+ return if paths.frozen?
23
+
24
+ engine_migration_paths.each do |migration_path|
25
+ version = File.basename(migration_path).split("_", 2).first
26
+ next if host_versions.include?(version)
27
+ next if paths.include?(migration_path)
28
+
29
+ paths << migration_path
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAdmin
4
+ module Favorites
5
+ module MigrationSupport
6
+ def favorites_user_foreign_key
7
+ ActiveAdmin::Favorites.config.user_foreign_key
8
+ end
9
+
10
+ def favorites_json_column_type
11
+ postgresql_adapter? ? :jsonb : :json
12
+ end
13
+
14
+ def postgresql_adapter?
15
+ connection.adapter_name.match?(/postgresql/i)
16
+ end
17
+ end
18
+ end
19
+ end