activeadmin_favorites 0.1.3 → 0.1.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +8 -0
- data/app/assets/controllers/activeadmin_favorites/personalization_controller.js +7 -6
- data/app/assets/stylesheets/activeadmin_favorites/personalization_menu.css +145 -0
- data/app/views/active_admin/favorites/_lens_catalog_data.html.erb +1 -1
- data/app/views/active_admin/favorites/_personalization_trigger.html.erb +40 -16
- data/lib/activeadmin/favorites/engine.rb +8 -0
- data/lib/activeadmin/favorites/version.rb +1 -1
- data/lib/activeadmin/favorites/view_paths.rb +48 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ff5b3c593b66aca8d7ebe1bdf1997d8eef0241f5a959aaeb2df486069c220d75
|
|
4
|
+
data.tar.gz: b2f7a9c06c263889b6949c51eb03c4fb6f8257685c4f2eb7430e2268fcb28125
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d65424d28f1f81b94602c44b2f0fd0051c7bd38e9887fcb66beb63295b64ad25a72b2ccf0e45bd18991c4ce1ce8561ef7b5908ddb428e66beb04f5accf308ace
|
|
7
|
+
data.tar.gz: 8f5b9d04b0f105e46c4fb7d88b520472d26fbe699bebd4d38a4c663d839e9545ea3cd6599e4085b663b03142740a964fd89b3ea689010d65a5b576930ad6dd16
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.1.5 (2026-10-26)
|
|
4
|
+
|
|
5
|
+
- Keep personalization menu actions in view while a long catalog scrolls.
|
|
6
|
+
- Add `activeadmin_favorites/personalization_menu.css` for hosts to import into the ActiveAdmin stylesheet.
|
|
7
|
+
|
|
8
|
+
## 0.1.4 (2026-10-26)
|
|
9
|
+
|
|
10
|
+
- Fix column and panel personalization so the lens catalog on index and show pages parses in the browser.
|
|
11
|
+
|
|
3
12
|
## 0.1.3 (2026-10-13)
|
|
4
13
|
|
|
5
14
|
- Fix favorites index kind tabs so they render as links instead of raw kind list text.
|
data/README.md
CHANGED
|
@@ -59,6 +59,14 @@ end
|
|
|
59
59
|
|
|
60
60
|
When using ActionPolicy, add `save_lens_favorite?` and `reset?` to `ActiveAdmin::PagePolicy` (or equivalent) so the view lens preference page actions authorize correctly.
|
|
61
61
|
|
|
62
|
+
### Stylesheet
|
|
63
|
+
|
|
64
|
+
Import the personalization menu stylesheet into the ActiveAdmin CSS entrypoint so the cogwheel dropdown can scroll the catalog while keeping action buttons in view:
|
|
65
|
+
|
|
66
|
+
```css
|
|
67
|
+
@import "activeadmin_favorites/personalization_menu.css";
|
|
68
|
+
```
|
|
69
|
+
|
|
62
70
|
### Locales
|
|
63
71
|
|
|
64
72
|
English ships with the gem. Copy `config/locales/activeadmin_favorites.host.yml.example` into your locale files and translate `active_admin.favorites` keys.
|
|
@@ -58,7 +58,8 @@ export default class extends Controller {
|
|
|
58
58
|
|
|
59
59
|
const groups = Object.keys(grouped)
|
|
60
60
|
if (groups.length === 0) {
|
|
61
|
-
this.catalogGroupsTarget.innerHTML =
|
|
61
|
+
this.catalogGroupsTarget.innerHTML =
|
|
62
|
+
`<p class="favorites-personalization-menu__empty">${this.escapeHtml(this.emptyCatalogLabelValue)}</p>`
|
|
62
63
|
return
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -70,11 +71,11 @@ export default class extends Controller {
|
|
|
70
71
|
const entryId = this.escapeHtml(entry.id)
|
|
71
72
|
return `
|
|
72
73
|
<li>
|
|
73
|
-
<label class="
|
|
74
|
+
<label class="favorites-personalization-menu__item">
|
|
74
75
|
<input
|
|
75
76
|
type="checkbox"
|
|
76
77
|
checked
|
|
77
|
-
class="
|
|
78
|
+
class="favorites-personalization-menu__checkbox"
|
|
78
79
|
data-group="${entryGroup}"
|
|
79
80
|
data-entry-id="${entryId}"
|
|
80
81
|
data-${this.identifier}-target="visibilityCheckbox"
|
|
@@ -86,9 +87,9 @@ export default class extends Controller {
|
|
|
86
87
|
}).join("")
|
|
87
88
|
|
|
88
89
|
return `
|
|
89
|
-
<div class="
|
|
90
|
-
<h4 class="
|
|
91
|
-
<ul class="
|
|
90
|
+
<div class="favorites-personalization-menu__group">
|
|
91
|
+
<h4 class="favorites-personalization-menu__group-title">${label}</h4>
|
|
92
|
+
<ul class="favorites-personalization-menu__list">${items}</ul>
|
|
92
93
|
</div>
|
|
93
94
|
`
|
|
94
95
|
}).join("")
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/* Catalog scrolls; action buttons stay visible inside the menu. */
|
|
2
|
+
.favorites-personalization-menu__body {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
max-height: min(70vh, calc(100dvh - 5rem));
|
|
6
|
+
padding: 0.625rem 0.75rem;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.favorites-personalization-menu__title {
|
|
10
|
+
flex-shrink: 0;
|
|
11
|
+
margin: 0 0 0.5rem;
|
|
12
|
+
font-size: 0.8125rem;
|
|
13
|
+
font-weight: 600;
|
|
14
|
+
line-height: 1.25;
|
|
15
|
+
color: var(--color-gray-800, #1f2937);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.dark .favorites-personalization-menu__title {
|
|
19
|
+
color: var(--color-gray-100, #f3f4f6);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.favorites-personalization-menu__catalog {
|
|
23
|
+
flex: 1 1 auto;
|
|
24
|
+
min-height: 0;
|
|
25
|
+
overflow-x: hidden;
|
|
26
|
+
overflow-y: auto;
|
|
27
|
+
overscroll-behavior: contain;
|
|
28
|
+
padding-right: 0.125rem;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.favorites-personalization-menu__empty {
|
|
32
|
+
margin: 0;
|
|
33
|
+
font-size: 0.75rem;
|
|
34
|
+
line-height: 1.35;
|
|
35
|
+
color: var(--color-gray-500, #6b7280);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.favorites-personalization-menu__group {
|
|
39
|
+
margin-bottom: 0.5rem;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.favorites-personalization-menu__group:last-child {
|
|
43
|
+
margin-bottom: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.favorites-personalization-menu__group-title {
|
|
47
|
+
margin: 0 0 0.25rem;
|
|
48
|
+
font-size: 0.625rem;
|
|
49
|
+
font-weight: 600;
|
|
50
|
+
letter-spacing: 0.04em;
|
|
51
|
+
text-transform: uppercase;
|
|
52
|
+
color: var(--color-gray-500, #6b7280);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.favorites-personalization-menu__list {
|
|
56
|
+
margin: 0;
|
|
57
|
+
padding: 0;
|
|
58
|
+
list-style: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.favorites-personalization-menu__list > li + li {
|
|
62
|
+
margin-top: 0.125rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.favorites-personalization-menu__item {
|
|
66
|
+
display: inline-flex;
|
|
67
|
+
align-items: flex-start;
|
|
68
|
+
gap: 0.375rem;
|
|
69
|
+
font-size: 0.75rem;
|
|
70
|
+
line-height: 1.3;
|
|
71
|
+
color: var(--color-gray-800, #1f2937);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.dark .favorites-personalization-menu__item {
|
|
75
|
+
color: var(--color-gray-100, #f3f4f6);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.favorites-personalization-menu__checkbox {
|
|
79
|
+
margin-top: 0.1rem;
|
|
80
|
+
border-radius: 0.25rem;
|
|
81
|
+
border-color: var(--color-gray-300, #d1d5db);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.favorites-personalization-menu__actions {
|
|
85
|
+
flex-shrink: 0;
|
|
86
|
+
display: grid;
|
|
87
|
+
grid-template-columns: 1fr 1fr;
|
|
88
|
+
gap: 0.375rem;
|
|
89
|
+
margin-top: 0.5rem;
|
|
90
|
+
padding-top: 0.5rem;
|
|
91
|
+
border-top: 1px solid var(--color-gray-200, #e5e7eb);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.dark .favorites-personalization-menu__actions {
|
|
95
|
+
border-top-color: var(--color-gray-700, #374151);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.favorites-personalization-menu__action {
|
|
99
|
+
display: inline-flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: center;
|
|
102
|
+
min-height: 1.75rem;
|
|
103
|
+
padding: 0.25rem 0.5rem;
|
|
104
|
+
border: 1px solid var(--color-gray-300, #d1d5db);
|
|
105
|
+
border-radius: 0.375rem;
|
|
106
|
+
background: var(--color-gray-50, #f9fafb);
|
|
107
|
+
color: var(--color-gray-800, #1f2937);
|
|
108
|
+
font-size: 0.6875rem;
|
|
109
|
+
font-weight: 500;
|
|
110
|
+
line-height: 1.2;
|
|
111
|
+
text-align: center;
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.favorites-personalization-menu__action:hover {
|
|
116
|
+
background: var(--color-gray-100, #f3f4f6);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.dark .favorites-personalization-menu__action {
|
|
120
|
+
border-color: var(--color-gray-600, #4b5563);
|
|
121
|
+
background: var(--color-gray-900, #111827);
|
|
122
|
+
color: var(--color-gray-100, #f3f4f6);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.dark .favorites-personalization-menu__action:hover {
|
|
126
|
+
background: var(--color-gray-800, #1f2937);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.favorites-personalization-menu__action--wide,
|
|
130
|
+
.favorites-personalization-menu__link {
|
|
131
|
+
grid-column: 1 / -1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.favorites-personalization-menu__link {
|
|
135
|
+
display: block;
|
|
136
|
+
padding-top: 0.125rem;
|
|
137
|
+
font-size: 0.6875rem;
|
|
138
|
+
text-align: center;
|
|
139
|
+
color: var(--color-blue-500, #3b82f6);
|
|
140
|
+
text-decoration: none;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.favorites-personalization-menu__link:hover {
|
|
144
|
+
text-decoration: underline;
|
|
145
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
resource_key = active_admin_config.resource_name.route_key
|
|
5
5
|
hidden = layout.layout.fetch("hidden", {})
|
|
6
6
|
catalog_element_id = "favorites-lens-catalog-#{resource_key}-#{action_name}"
|
|
7
|
+
menu_id = "personalization-menu-#{resource_key}-#{action_name}"
|
|
7
8
|
%>
|
|
8
9
|
<div
|
|
9
10
|
class="relative"
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
type="button"
|
|
31
32
|
class="action-item-button inline-flex items-center gap-2"
|
|
32
33
|
aria-label="<%= t("active_admin.favorites.personalize_page") %>"
|
|
33
|
-
data-dropdown-toggle="
|
|
34
|
+
data-dropdown-toggle="<%= menu_id %>"
|
|
34
35
|
data-dropdown-offset-distance="3"
|
|
35
36
|
data-dropdown-placement="bottom-end"
|
|
36
37
|
data-action="click-><%= stimulus_controller %>#prepareMenu"
|
|
@@ -43,27 +44,50 @@
|
|
|
43
44
|
</button>
|
|
44
45
|
|
|
45
46
|
<div
|
|
46
|
-
id="
|
|
47
|
-
class="z-50 hidden w-
|
|
47
|
+
id="<%= menu_id %>"
|
|
48
|
+
class="favorites-personalization-menu z-50 hidden w-72 max-w-[calc(100vw-2rem)] overflow-hidden rounded-md bg-white shadow-lg ring-1 ring-black/5 dark:bg-gray-800 dark:ring-white/10"
|
|
48
49
|
role="region"
|
|
49
50
|
aria-label="<%= t("active_admin.favorites.personalization_region") %>"
|
|
50
51
|
data-<%= stimulus_controller %>-target="menu"
|
|
51
52
|
>
|
|
52
|
-
<
|
|
53
|
+
<div class="favorites-personalization-menu__body">
|
|
54
|
+
<h3 class="favorites-personalization-menu__title">
|
|
55
|
+
<%= t("active_admin.favorites.personalization_region") %>
|
|
56
|
+
</h3>
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
<div
|
|
59
|
+
class="favorites-personalization-menu__catalog"
|
|
60
|
+
data-<%= stimulus_controller %>-target="catalogGroups"
|
|
61
|
+
></div>
|
|
55
62
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
<div class="favorites-personalization-menu__actions">
|
|
64
|
+
<button
|
|
65
|
+
type="button"
|
|
66
|
+
class="favorites-personalization-menu__action"
|
|
67
|
+
data-action="<%= stimulus_controller %>#saveDefault"
|
|
68
|
+
>
|
|
69
|
+
<%= t("active_admin.favorites.save_default") %>
|
|
70
|
+
</button>
|
|
71
|
+
<button
|
|
72
|
+
type="button"
|
|
73
|
+
class="favorites-personalization-menu__action"
|
|
74
|
+
data-action="<%= stimulus_controller %>#resetDefault"
|
|
75
|
+
>
|
|
76
|
+
<%= t("active_admin.favorites.reset_default") %>
|
|
77
|
+
</button>
|
|
78
|
+
<button
|
|
79
|
+
type="button"
|
|
80
|
+
class="favorites-personalization-menu__action favorites-personalization-menu__action--wide"
|
|
81
|
+
data-action="<%= stimulus_controller %>#saveLensFavorite"
|
|
82
|
+
>
|
|
83
|
+
<%= t("active_admin.favorites.save_lens_favorite") %>
|
|
84
|
+
</button>
|
|
85
|
+
<%=
|
|
86
|
+
link_to t("active_admin.favorites.menu"),
|
|
87
|
+
admin_favorites_path,
|
|
88
|
+
class: "favorites-personalization-menu__link"
|
|
89
|
+
%>
|
|
90
|
+
</div>
|
|
67
91
|
</div>
|
|
68
92
|
</div>
|
|
69
93
|
</div>
|
|
@@ -16,6 +16,7 @@ module ActiveAdmin
|
|
|
16
16
|
require "activeadmin/favorites/view_lens/catalog"
|
|
17
17
|
require "activeadmin/favorites/view_lens/patches"
|
|
18
18
|
require "activeadmin/favorites/view_lens/resource_dsl"
|
|
19
|
+
require "activeadmin/favorites/view_paths"
|
|
19
20
|
require "activeadmin/favorites/install"
|
|
20
21
|
require "activeadmin/favorites/register_favorites"
|
|
21
22
|
require "activeadmin/favorites/register_view_lens_preferences"
|
|
@@ -28,6 +29,7 @@ module ActiveAdmin
|
|
|
28
29
|
next unless app.config.respond_to?(:assets)
|
|
29
30
|
|
|
30
31
|
app.config.assets.precompile << "activeadmin_favorites/personalization_controller.js"
|
|
32
|
+
app.config.assets.precompile << "activeadmin_favorites/personalization_menu.css"
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
initializer "activeadmin_favorites.importmap", after: :importmap do
|
|
@@ -62,7 +64,13 @@ module ActiveAdmin
|
|
|
62
64
|
end
|
|
63
65
|
end
|
|
64
66
|
|
|
67
|
+
config.after_initialize do
|
|
68
|
+
ActiveAdmin::Favorites::ViewPaths.install!
|
|
69
|
+
end
|
|
70
|
+
|
|
65
71
|
config.to_prepare do
|
|
72
|
+
ActiveAdmin::Favorites::ViewPaths.install!
|
|
73
|
+
|
|
66
74
|
next unless defined?(ActiveAdmin::ResourceController)
|
|
67
75
|
|
|
68
76
|
ActiveAdmin::Favorites::Favorite.define_favorites_user_association!
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveAdmin
|
|
4
|
+
module Favorites
|
|
5
|
+
# Place this engine's views ahead of ActiveAdmin's so resource index/show
|
|
6
|
+
# overrides (catalog injection) win, while the host app/views path stays first.
|
|
7
|
+
module ViewPaths
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def prefer_over_active_admin!(view_paths)
|
|
11
|
+
path_strings = view_paths.to_a.map { |path| path.to_s }
|
|
12
|
+
reordered = reorder_path_strings(path_strings)
|
|
13
|
+
return view_paths if reordered.equal?(path_strings)
|
|
14
|
+
|
|
15
|
+
ActionView::PathSet.new(reordered)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def install!
|
|
19
|
+
return unless defined?(ActionController::Base)
|
|
20
|
+
|
|
21
|
+
ActionController::Base.view_paths = prefer_over_active_admin!(
|
|
22
|
+
ActionController::Base.view_paths
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def reorder_path_strings(path_strings)
|
|
27
|
+
favorites_root = Engine.root.join("app/views").to_s
|
|
28
|
+
return path_strings unless path_strings.include?(favorites_root)
|
|
29
|
+
|
|
30
|
+
active_admin_root = path_strings.find do |path|
|
|
31
|
+
path.match?(%r{/gems/activeadmin-[^/]+/app/views\z})
|
|
32
|
+
end
|
|
33
|
+
return path_strings unless active_admin_root
|
|
34
|
+
|
|
35
|
+
favorites_index = path_strings.index(favorites_root)
|
|
36
|
+
active_admin_index = path_strings.index(active_admin_root)
|
|
37
|
+
return path_strings if favorites_index < active_admin_index
|
|
38
|
+
|
|
39
|
+
moved = path_strings.dup
|
|
40
|
+
moved.delete_at(favorites_index)
|
|
41
|
+
moved.insert(moved.index(active_admin_root), favorites_root)
|
|
42
|
+
moved
|
|
43
|
+
end
|
|
44
|
+
module_function :reorder_path_strings
|
|
45
|
+
private_class_method :reorder_path_strings
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activeadmin_favorites
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
@@ -340,6 +340,7 @@ files:
|
|
|
340
340
|
- SECURITY.md
|
|
341
341
|
- activeadmin_favorites.gemspec
|
|
342
342
|
- app/assets/controllers/activeadmin_favorites/personalization_controller.js
|
|
343
|
+
- app/assets/stylesheets/activeadmin_favorites/personalization_menu.css
|
|
343
344
|
- app/models/active_admin/favorites.rb
|
|
344
345
|
- app/models/active_admin/favorites/application_record.rb
|
|
345
346
|
- app/models/active_admin/favorites/combined_favorite.rb
|
|
@@ -381,6 +382,7 @@ files:
|
|
|
381
382
|
- lib/activeadmin/favorites/view_lens/current.rb
|
|
382
383
|
- lib/activeadmin/favorites/view_lens/patches.rb
|
|
383
384
|
- lib/activeadmin/favorites/view_lens/resource_dsl.rb
|
|
385
|
+
- lib/activeadmin/favorites/view_paths.rb
|
|
384
386
|
- lib/activeadmin_favorites.rb
|
|
385
387
|
- lib/generators/activeadmin_favorites/install/templates/favorite_policy.rb
|
|
386
388
|
- lib/generators/activeadmin_favorites/install/templates/initializer.rb
|