rails_omnibar 1.3.2 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/tests.yml +1 -1
- data/CHANGELOG.md +17 -0
- data/Gemfile +14 -0
- data/README.md +101 -30
- data/Rakefile +1 -4
- data/app/controllers/rails_omnibar/base_controller.rb +3 -0
- data/app/controllers/rails_omnibar/html_controller.rb +5 -0
- data/app/controllers/rails_omnibar/queries_controller.rb +3 -3
- data/config/routes.rb +1 -0
- data/javascript/compiled.js +1 -1
- data/javascript/src/icon.tsx +3 -3
- data/lib/rails_omnibar/command/base.rb +3 -10
- data/lib/rails_omnibar/command/search.rb +9 -5
- data/lib/rails_omnibar/commands.rb +23 -3
- data/lib/rails_omnibar/config.rb +31 -0
- data/lib/rails_omnibar/item/help.rb +0 -1
- data/lib/rails_omnibar/item/webadmin.rb +45 -0
- data/lib/rails_omnibar/items.rb +3 -3
- data/lib/rails_omnibar/rendering.rb +7 -2
- data/lib/rails_omnibar/version.rb +1 -1
- data/lib/rails_omnibar.rb +3 -7
- data/rails_omnibar.gemspec +0 -8
- data/spec/lib/rails_omnibar/config_spec.rb +10 -1
- data/spec/rails_helper.rb +0 -4
- data/spec/support/factories.rb +2 -0
- data/spec/system/rails_omnibar_spec.rb +41 -2
- data/spec/templates/app_template.rb +40 -0
- data/spec/{my_omnibar_template.rb → templates/my_omnibar_template.rb} +3 -1
- data/spec/templates/other_omnibar_template.rb +11 -0
- data/spec/templates/user_resource_template.rb +5 -0
- metadata +13 -105
- data/spec/app_template.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21f584d48006f4dd826813762553d863b7519ff09687c31be568479088314255
|
4
|
+
data.tar.gz: f8341d39b57397f66f334e417fe2920453494eeec017bf304426e4929e7b4488
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa03433d73eb577524f195e3ce9491c2e832c5ccd8995df017fef33b1652d98ca56e76bab0586c3286b3e8c764d0cbbc228bc004b943b83d93a90b5a75cc3c0b
|
7
|
+
data.tar.gz: 8c3192eafac7ea537f5c8924943eb742002ef4bf4bf2388986468ad595c43324c4bbf1b042a80f58cf8cc7f67981ee123485dcf150c7f740788a46750a4649ac
|
data/.github/workflows/tests.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [1.5.0] - 2024-01-25
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- `RailsOmnibar::add_webadmin_items`
|
12
|
+
|
13
|
+
## [1.4.0] - 2023-01-31
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
- `RailsOmnibar::auth=` for fine-grained authorization
|
18
|
+
- `RailsOmnibar::html_url` for rendering in SPAs
|
19
|
+
|
20
|
+
### Fixed
|
21
|
+
|
22
|
+
- double execution of commands / queries
|
23
|
+
|
7
24
|
## [1.3.2] - 2023-01-27
|
8
25
|
|
9
26
|
### Fixed
|
data/Gemfile
CHANGED
@@ -2,3 +2,17 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in rails_omnibar.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'activeadmin', '~> 3.0' # to test activeadmin integration
|
8
|
+
gem 'capybara', '~> 3.0'
|
9
|
+
gem 'csv' # needed for activeadmin, standalone on Ruby >= 3.4
|
10
|
+
gem 'devise', '~> 4.8' # to test auth feature
|
11
|
+
gem 'factory_bot_rails', '~> 6.0'
|
12
|
+
gem 'puma', '~> 6.0'
|
13
|
+
gem 'rake', '~> 13.0'
|
14
|
+
gem 'rspec-rails', '~> 5.0'
|
15
|
+
gem 'sqlite3', '>= 1.3.6'
|
16
|
+
gem 'sprockets-rails', '~> 3.4' # for activeadmin
|
17
|
+
gem 'webdrivers', '~> 5.0'
|
18
|
+
end
|
data/README.md
CHANGED
@@ -15,17 +15,11 @@ Add `rails_omnibar` to your bundle and add the following line to your `config/ro
|
|
15
15
|
mount RailsOmnibar::Engine => '/rails_omnibar'
|
16
16
|
```
|
17
17
|
|
18
|
-
You can pick any path.
|
18
|
+
You can pick any path. See [Authorization](#authorization) for limiting access to the engine.
|
19
19
|
|
20
|
-
|
20
|
+
## Configuration
|
21
21
|
|
22
|
-
|
23
|
-
authenticate :user, ->(user){ user.superadmin? } do
|
24
|
-
mount RailsOmnibar::Engine => '/rails_omnibar'
|
25
|
-
end
|
26
|
-
```
|
27
|
-
|
28
|
-
### Configuration
|
22
|
+
### Basic Usage
|
29
23
|
|
30
24
|
```ruby
|
31
25
|
# app/lib/omnibar.rb
|
@@ -52,6 +46,7 @@ Omnibar = RailsOmnibar.configure do |c|
|
|
52
46
|
next unless name = route.name[/^backoffice_(.+)/, 1]
|
53
47
|
|
54
48
|
# items can have icons
|
49
|
+
# arrows, cloud, cog, dev, document, home, question, search, sparkle, user, wallet, x
|
55
50
|
c.add_item(title: name.humanize, url: route.format({}), icon: :cog)
|
56
51
|
end
|
57
52
|
|
@@ -97,61 +92,130 @@ Render it somewhere. E.g. `app/views/layouts/application.html.erb`:
|
|
97
92
|
<%= Omnibar.render %>
|
98
93
|
```
|
99
94
|
|
95
|
+
If you have a fully decoupled frontend, use `Omnibar.html_url` instead, fetch the omnibar HTML from there, and inject it.
|
96
|
+
|
97
|
+
### Authorization
|
98
|
+
|
99
|
+
You can limit access to commands (e.g. search commands). This will not limit access to plain items.
|
100
|
+
|
101
|
+
#### Option 1: globally limit engine access
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
authenticate :user, ->(user){ user.superadmin? } do
|
105
|
+
mount RailsOmnibar::Engine => '/rails_omnibar'
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
#### Option 2: use `RailsOmnibar::auth=`
|
110
|
+
|
111
|
+
This is useful for fine-grained authorization, e.g. if there is more than one omnibar or multiple permission levels.
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
# the auth proc is executed in the controller context by default,
|
115
|
+
# but can also take the controller and omnibar as arguments
|
116
|
+
MyOmnibar.auth = ->{ user_signed_in? }
|
117
|
+
MyOmnibar.auth = ->(controller, omnibar:) do
|
118
|
+
controller.user_signed_in? && omnibar.is_a?(NormalUserOmnibar)
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
100
122
|
### Using multiple different omnibars
|
101
123
|
|
102
124
|
```ruby
|
103
|
-
|
104
|
-
|
125
|
+
BaseOmnibar = Class.new(RailsOmnibar)
|
126
|
+
BaseOmnibar.configure do |c|
|
127
|
+
c.add_item(
|
128
|
+
title: 'Log in',
|
129
|
+
url: Rails.application.routes.url_helpers.log_in_url
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
UserOmnibar = Class.new(RailsOmnibar)
|
134
|
+
UserOmnibar.configure do |c|
|
135
|
+
c.auth = ->{ user_signed_in? }
|
136
|
+
c.add_item(
|
137
|
+
title: 'Log out',
|
138
|
+
url: Rails.application.routes.url_helpers.log_out_url
|
139
|
+
)
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
143
|
+
Then, in some layout:
|
105
144
|
|
106
|
-
|
107
|
-
|
145
|
+
```erb
|
146
|
+
<%= (user_signed_in? ? UserOmnibar : BaseOmnibar).render %>
|
108
147
|
```
|
109
148
|
|
110
149
|
### Other options and usage patterns
|
111
150
|
|
151
|
+
#### Adding multiple items at once
|
152
|
+
|
112
153
|
```ruby
|
113
|
-
# Add multiple items
|
114
154
|
MyOmnibar.add_items(
|
115
155
|
*MyRecord.all.map { |rec| { title: rec.title, url: url_for(rec) } }
|
116
156
|
)
|
157
|
+
```
|
158
|
+
|
159
|
+
#### Adding all ActiveAdmin or RailsAdmin index routes as searchable items
|
160
|
+
|
161
|
+
Simply call `::add_webadmin_items` and use the `modal` mode.
|
117
162
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
title = res.menu_item&.label.presence || next
|
123
|
-
MyOmnibar.add_item(title: title, url: index)
|
163
|
+
```ruby
|
164
|
+
MyOmnibar.configure do |c|
|
165
|
+
c.add_webadmin_items
|
166
|
+
c.modal = true
|
124
167
|
end
|
168
|
+
```
|
125
169
|
|
126
|
-
|
170
|
+
##### To render in ActiveAdmin
|
171
|
+
|
172
|
+
```ruby
|
127
173
|
module AddOmnibar
|
128
174
|
def build_page(...)
|
129
175
|
within(super) { text_node(MyOmnibar.render) }
|
130
176
|
end
|
131
177
|
end
|
132
178
|
ActiveAdmin::Views::Pages::Base.prepend(AddOmnibar)
|
179
|
+
```
|
180
|
+
|
181
|
+
##### To render in RailsAdmin
|
182
|
+
|
183
|
+
Add `MyOmnibar.render` to `app/views/layouts/rails_admin/application.*`.
|
133
184
|
|
134
|
-
|
185
|
+
#### Adding all index routes as searchable items
|
186
|
+
|
187
|
+
```ruby
|
135
188
|
Rails.application.routes.routes.each do |route|
|
136
189
|
next unless route.defaults.values_at(:action, :format) == ['index', nil]
|
137
190
|
MyOmnibar.add_item(title: route.name.humanize, url: route.format({}))
|
138
191
|
end
|
192
|
+
```
|
193
|
+
|
194
|
+
#### Custom record lookup and rendering
|
139
195
|
|
140
|
-
|
196
|
+
```ruby
|
141
197
|
MyOmnibar.add_record_search(
|
142
198
|
pattern: /^U(\d+)/,
|
143
199
|
example: 'U123',
|
144
200
|
model: User,
|
145
|
-
finder: ->(id)
|
146
|
-
itemizer: ->(user)
|
201
|
+
finder: ->(id) { User.find_by(admin: true, id: id) },
|
202
|
+
itemizer: ->(user) do
|
203
|
+
{ title: "Admin #{user.name}", url: admin_url(user), icon: :user }
|
204
|
+
end
|
147
205
|
)
|
206
|
+
```
|
148
207
|
|
149
|
-
|
208
|
+
#### Custom search, plus mapping to multiple results
|
209
|
+
|
210
|
+
```ruby
|
150
211
|
MyOmnibar.add_search(
|
151
212
|
description: 'Google',
|
152
213
|
pattern: /^g (.+)/,
|
153
214
|
example: 'g kittens',
|
154
|
-
|
215
|
+
# omnibar: and controller: keyword args are provided to command procs
|
216
|
+
finder: ->(value, omnibar:) do
|
217
|
+
Google.search(value, limit: omnibar.max_results)
|
218
|
+
end,
|
155
219
|
itemizer: ->(res) do
|
156
220
|
[
|
157
221
|
{ title: res.title, url: res.url },
|
@@ -159,14 +223,21 @@ MyOmnibar.add_search(
|
|
159
223
|
]
|
160
224
|
end,
|
161
225
|
)
|
226
|
+
```
|
227
|
+
|
228
|
+
#### Completely custom command
|
162
229
|
|
163
|
-
|
230
|
+
```ruby
|
164
231
|
MyOmnibar.add_command(
|
165
232
|
description: 'Get count of a DB table',
|
166
233
|
pattern: /COUNT (.+)/i,
|
167
234
|
example: 'COUNT users',
|
168
|
-
resolver: ->(value,
|
169
|
-
|
235
|
+
resolver: ->(value, controller:) do
|
236
|
+
if controller.current_user.client?
|
237
|
+
{ title: (value.classify.constantize.count * 2).to_s }
|
238
|
+
else
|
239
|
+
{ title: value.classify.constantize.count.to_s }
|
240
|
+
end
|
170
241
|
rescue => e
|
171
242
|
{ title: e.message }
|
172
243
|
end,
|
data/Rakefile
CHANGED
@@ -16,14 +16,12 @@ task :generate_spec_app do
|
|
16
16
|
sh 'rm -rf spec/dummy'
|
17
17
|
sh *%w[
|
18
18
|
rails new spec/dummy
|
19
|
-
--template=spec/app_template.rb
|
19
|
+
--template=spec/templates/app_template.rb
|
20
20
|
--skip-action-cable
|
21
21
|
--skip-action-mailbox
|
22
|
-
--skip-action-mailer
|
23
22
|
--skip-action-text
|
24
23
|
--skip-active-job
|
25
24
|
--skip-active-storage
|
26
|
-
--skip-asset-pipeline
|
27
25
|
--skip-bootsnap
|
28
26
|
--skip-bundle
|
29
27
|
--skip-git
|
@@ -33,7 +31,6 @@ task :generate_spec_app do
|
|
33
31
|
--skip-keeps
|
34
32
|
--skip-listen
|
35
33
|
--skip-spring
|
36
|
-
--skip-sprockets
|
37
34
|
--skip-system-test
|
38
35
|
--skip-test
|
39
36
|
--skip-turbolinks
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class RailsOmnibar::QueriesController < RailsOmnibar::BaseController
|
2
2
|
def show
|
3
|
-
|
4
|
-
|
5
|
-
render json: omnibar.handle(params[:q])
|
3
|
+
return head :forbidden unless omnibar.authorize(self)
|
4
|
+
|
5
|
+
render json: omnibar.handle(params[:q], self)
|
6
6
|
end
|
7
7
|
end
|