activeadmin_favorites 0.1.4 → 0.1.6
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 +10 -0
- data/README.md +16 -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/_html_head.html.erb +14 -0
- data/app/views/active_admin/favorites/_personalization_trigger.html.erb +40 -16
- data/lib/activeadmin/favorites/engine.rb +1 -0
- data/lib/activeadmin/favorites/version.rb +1 -1
- data/lib/activeadmin/favorites.rb +9 -0
- data/sig/activeadmin/favorites.rbs +3 -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: 1d95f2a47f409353aaaa307098bf24dc0b94abc2bf116f47101259a81f8e481a
|
|
4
|
+
data.tar.gz: 9842f18c72d0e9fbe731b934a5d58c0eae9633eb0438849a57b8d09c10b87aaf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52d6fd9962c311fcee1f14c98211478337761a916eb074e83ebb641063370eb16c8b81ad921f45d59af4c8ad0b4e328fa83c6b52e9ef6423fa823ce660d1c9a5
|
|
7
|
+
data.tar.gz: ba88cae3210e174538ec0dd397f7085f451093e9b86c364219d4ba2453302917fbb0c7d6918843a2d83abffb8a7ea11a1dc765811f2cd160ab70188dded4dbec
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.1.6 (2026-10-27)
|
|
4
|
+
|
|
5
|
+
- Link the personalization menu stylesheet from Active Admin's HTML head so hosts no longer need a Tailwind `@import` of the Propshaft path.
|
|
6
|
+
- Document `ActiveAdmin::Favorites.personalization_menu_stylesheet_path` for hosts that concatenate the plain CSS into a Tailwind CLI entry.
|
|
7
|
+
|
|
8
|
+
## 0.1.5 (2026-10-26)
|
|
9
|
+
|
|
10
|
+
- Keep personalization menu actions in view while a long catalog scrolls.
|
|
11
|
+
- Add `activeadmin_favorites/personalization_menu.css` for hosts to import into the ActiveAdmin stylesheet.
|
|
12
|
+
|
|
3
13
|
## 0.1.4 (2026-10-26)
|
|
4
14
|
|
|
5
15
|
- Fix column and panel personalization so the lens catalog on index and show pages parses in the browser.
|
data/README.md
CHANGED
|
@@ -59,6 +59,22 @@ 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
|
+
The engine links `activeadmin_favorites/personalization_menu` from Active Admin's HTML head so the cogwheel dropdown can scroll the catalog while keeping action buttons in view. The file is plain CSS served through Propshaft; it does not need Tailwind processing.
|
|
65
|
+
|
|
66
|
+
If the host overrides `active_admin/_html_head`, add the link there:
|
|
67
|
+
|
|
68
|
+
```erb
|
|
69
|
+
<%= stylesheet_link_tag "activeadmin_favorites/personalization_menu" %>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Do not bare-`@import` that Propshaft logical path into an Active Admin CSS entry that Tailwind CLI compiles from a generated `tmp` file. Tailwind resolves imports from the input file directory, not through Propshaft. Hosts that must fold the rules into one built stylesheet can concatenate the absolute file instead:
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
File.read(ActiveAdmin::Favorites.personalization_menu_stylesheet_path)
|
|
76
|
+
```
|
|
77
|
+
|
|
62
78
|
### Locales
|
|
63
79
|
|
|
64
80
|
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
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<%= stylesheet_link_tag "active_admin" %>
|
|
2
|
+
<%= stylesheet_link_tag ActiveAdmin::Favorites::PERSONALIZATION_MENU_STYLESHEET %>
|
|
3
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
4
|
+
<%= csrf_meta_tags %>
|
|
5
|
+
<%= csp_meta_tag %>
|
|
6
|
+
<% # On page load or when changing themes, best to add inline in `head` to avoid FOUC %>
|
|
7
|
+
<%= javascript_tag nonce: true do %>
|
|
8
|
+
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
|
9
|
+
document.documentElement.classList.add('dark')
|
|
10
|
+
} else {
|
|
11
|
+
document.documentElement.classList.remove('dark')
|
|
12
|
+
}
|
|
13
|
+
<% end %>
|
|
14
|
+
<%= javascript_importmap_tags "active_admin", importmap: ActiveAdmin.importmap %>
|
|
@@ -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>
|
|
@@ -29,6 +29,7 @@ module ActiveAdmin
|
|
|
29
29
|
next unless app.config.respond_to?(:assets)
|
|
30
30
|
|
|
31
31
|
app.config.assets.precompile << "activeadmin_favorites/personalization_controller.js"
|
|
32
|
+
app.config.assets.precompile << "activeadmin_favorites/personalization_menu.css"
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
initializer "activeadmin_favorites.importmap", after: :importmap do
|
|
@@ -5,6 +5,8 @@ require "activeadmin/favorites/configuration"
|
|
|
5
5
|
|
|
6
6
|
module ActiveAdmin
|
|
7
7
|
module Favorites
|
|
8
|
+
PERSONALIZATION_MENU_STYLESHEET = "activeadmin_favorites/personalization_menu"
|
|
9
|
+
|
|
8
10
|
class << self
|
|
9
11
|
def config
|
|
10
12
|
@config ||= Configuration.new
|
|
@@ -14,6 +16,13 @@ module ActiveAdmin
|
|
|
14
16
|
yield config
|
|
15
17
|
end
|
|
16
18
|
|
|
19
|
+
# Absolute path to the plain CSS file Propshaft serves. Hosts that
|
|
20
|
+
# concatenate into a Tailwind CLI entry can File.read this path; do not
|
|
21
|
+
# bare-@import the Propshaft logical path from a tmp Tailwind input.
|
|
22
|
+
def personalization_menu_stylesheet_path
|
|
23
|
+
Engine.root.join("app/assets/stylesheets/#{PERSONALIZATION_MENU_STYLESHEET}.css")
|
|
24
|
+
end
|
|
25
|
+
|
|
17
26
|
def install!
|
|
18
27
|
require "activeadmin/favorites/install"
|
|
19
28
|
Install.call
|
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.6
|
|
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
|
|
@@ -354,6 +355,7 @@ files:
|
|
|
354
355
|
- app/models/active_admin/favorites/lens_favorite.rb
|
|
355
356
|
- app/models/active_admin/favorites/view_lens/layout.rb
|
|
356
357
|
- app/models/active_admin/favorites/view_lens_default.rb
|
|
358
|
+
- app/views/active_admin/_html_head.html.erb
|
|
357
359
|
- app/views/active_admin/favorites/_lens_catalog_data.html.erb
|
|
358
360
|
- app/views/active_admin/favorites/_macro_fields.html.erb
|
|
359
361
|
- app/views/active_admin/favorites/_personalization_trigger.html.erb
|