command_deck 0.1.2 → 0.2.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +30 -0
- data/CONTRIBUTING.md +63 -0
- data/README.md +55 -47
- data/lib/command_deck/base_panel.rb +40 -0
- data/lib/command_deck/engine.rb +18 -5
- data/lib/command_deck/registry.rb +0 -4
- data/lib/command_deck/version.rb +1 -1
- data/lib/command_deck.rb +17 -4
- data/public/img/demo.gif +0 -0
- metadata +23 -8
- data/lib/command_deck/railtie.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d7607e2931f95aa4dfd89508fce37ab2d9b769c4e5463692d9a6d1a8e420861
|
4
|
+
data.tar.gz: 8efb1447f274e41cb071524d92e2e718349fe0b90dd32124db4e6daa60fcfb8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ded56cf9f23174bdc5406d70ec1bf66788706708aae8edc84c8af9f87882f6ec6bd728b62c5f511eb9139776822a6a8645d9548b71145920bd6f073c9d3079e6
|
7
|
+
data.tar.gz: 20bcfcca9de31c7da07fb6b36630bd6dd7b1151cc1eda6c89d45332b55c5ff2a1169a8a774fa57e7128fe034719983d6c1c0f6c86e831fb504682012b5aa9ef9
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,35 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## [0.2.0] - 2025-10-09
|
4
|
+
|
5
|
+
### Breaking Changes
|
6
|
+
|
7
|
+
- Panels must now be defined as classes inheriting from `CommandDeck::BasePanel`
|
8
|
+
- Panel files define `Panels::*` constants (not `CommandDeck::Panels::*`)
|
9
|
+
- Middleware is no longer automatically injected (must be added manually in `config/application.rb`)
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Full Rails autoloading and Zeitwerk compatibility
|
14
|
+
- Proper class-based panel architecture
|
15
|
+
- Automatic panel registration via `BasePanel.inherited` hook
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- Consolidated Railtie into Engine for simpler initialization
|
20
|
+
- Panels namespace changed: `app/command_deck/panels/global.rb` → `Panels::Global`
|
21
|
+
- Cleaner, self-documenting code architecture
|
22
|
+
|
23
|
+
### Fixed
|
24
|
+
|
25
|
+
- Middleware stack freezing conflicts with other gems (Bullet, etc.)
|
26
|
+
- CI/test environment compatibility
|
27
|
+
- Zeitwerk constant resolution errors
|
28
|
+
|
29
|
+
## [0.1.3] - 2025-09-23
|
30
|
+
|
31
|
+
- Unchilenizes the README file
|
32
|
+
|
3
33
|
## [0.1.2] - 2025-09-11
|
4
34
|
|
5
35
|
### Added
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Contributing to Command Deck
|
2
|
+
|
3
|
+
Thank you for considering contributing to Command Deck!
|
4
|
+
|
5
|
+
## Development Setup
|
6
|
+
|
7
|
+
```bash
|
8
|
+
git clone https://github.com/crow-rojas/command_deck.git
|
9
|
+
cd command_deck
|
10
|
+
bundle install
|
11
|
+
```
|
12
|
+
|
13
|
+
## Running Tests
|
14
|
+
|
15
|
+
```bash
|
16
|
+
bundle exec rake test
|
17
|
+
```
|
18
|
+
|
19
|
+
## Code Style
|
20
|
+
|
21
|
+
We use RuboCop for code style enforcement:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
bundle exec rubocop
|
25
|
+
```
|
26
|
+
|
27
|
+
Fix auto-correctable issues:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
bundle exec rubocop -A
|
31
|
+
```
|
32
|
+
|
33
|
+
## Making Changes
|
34
|
+
|
35
|
+
1. Fork the repository
|
36
|
+
2. Create a feature branch (`git checkout -b my-feature`)
|
37
|
+
3. Make your changes
|
38
|
+
4. Add tests for new functionality
|
39
|
+
5. Ensure all tests pass
|
40
|
+
6. Run RuboCop and fix any offenses
|
41
|
+
7. Commit your changes (`git commit -am 'Add feature'`)
|
42
|
+
8. Push to your branch (`git push origin my-feature`)
|
43
|
+
9. Create a Pull Request
|
44
|
+
|
45
|
+
## Pull Request Guidelines
|
46
|
+
|
47
|
+
- Keep changes focused and atomic
|
48
|
+
- Update CHANGELOG.md with your changes
|
49
|
+
- Update README.md if adding new features
|
50
|
+
- Ensure backward compatibility when possible
|
51
|
+
- Add tests for bug fixes and new features
|
52
|
+
- Follow existing code style
|
53
|
+
|
54
|
+
## Reporting Issues
|
55
|
+
|
56
|
+
- Use the GitHub issue tracker
|
57
|
+
- Include Ruby and Rails versions
|
58
|
+
- Provide steps to reproduce
|
59
|
+
- Include relevant code samples
|
60
|
+
|
61
|
+
## Questions?
|
62
|
+
|
63
|
+
Feel free to open an issue for questions or discussions.
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Command Deck
|
2
2
|
|
3
|
-
|
3
|
+
Convenient, unobtrusive, dev-oriented Rails engine that allows you to run custom actions and quick admin tasks through a floating panel without opening the Rails console.
|
4
4
|
|
5
|
-
|
5
|
+
Define panels/tabs/actions with a minimal class-based DSL. Each action can declare parameters (text, boolean, number, selector), run Ruby code, and return a JSON result shown in the UI.
|
6
|
+
|
7
|
+

|
6
8
|
|
7
9
|
## Installation
|
8
10
|
|
@@ -11,79 +13,88 @@ Add the gem to your application:
|
|
11
13
|
```ruby
|
12
14
|
# Gemfile (development only recommended)
|
13
15
|
group :development do
|
14
|
-
gem
|
16
|
+
gem 'command_deck'
|
15
17
|
end
|
16
18
|
```
|
17
19
|
|
18
|
-
Mount the engine
|
20
|
+
Mount the engine:
|
19
21
|
|
20
22
|
```ruby
|
21
23
|
# config/routes.rb
|
22
|
-
if Rails.env.development?
|
23
|
-
mount CommandDeck::Engine => "/command_deck"
|
24
|
-
end
|
24
|
+
mount CommandDeck::Engine => '/command_deck' if Rails.env.development?
|
25
25
|
```
|
26
26
|
|
27
|
-
|
27
|
+
Add middleware to inject the floating panel:
|
28
28
|
|
29
|
-
|
29
|
+
```ruby
|
30
|
+
# config/application.rb
|
30
31
|
|
31
|
-
|
32
|
+
module YourApp
|
33
|
+
class Application < Rails::Application
|
34
|
+
# ... other config ...
|
35
|
+
|
36
|
+
config.middleware.insert_after ActionDispatch::DebugExceptions, CommandDeck::Middleware if Rails.env.development?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
32
40
|
|
33
|
-
|
34
|
-
CommandDeck.panel "Utilities" do
|
35
|
-
tab "Demo" do
|
36
|
-
action "Greet", key: "utils.greet" do
|
37
|
-
param :name, :string, label: "Your name", required: true
|
41
|
+
## Define actions
|
38
42
|
|
39
|
-
|
40
|
-
{ message: "Hello, #{p[:name]}!" }
|
41
|
-
end
|
42
|
-
end
|
43
|
+
Create panel classes in `app/command_deck/panels/*.rb`:
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
45
|
+
```ruby
|
46
|
+
# app/command_deck/panels/utilities.rb
|
47
|
+
module Panels
|
48
|
+
class Utilities < CommandDeck::BasePanel
|
49
|
+
panel 'Utilities' do
|
50
|
+
tab 'Demo' do
|
51
|
+
action 'Greet', key: 'utils.greet' do
|
52
|
+
param :name, :string, label: 'Your name', required: true
|
53
|
+
|
54
|
+
perform do |p, _ctx|
|
55
|
+
{ message: "Hello, #{p[:name]}!" }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
action 'Pick a Color', key: 'utils.color' do
|
60
|
+
# You can pass simple arrays, pairs, or hashes as choices
|
61
|
+
param :color, :selector,
|
62
|
+
options: [
|
63
|
+
['Red', 'red'],
|
64
|
+
['Green', 'green'],
|
65
|
+
['Blue', 'blue']
|
66
|
+
],
|
67
|
+
include_blank: true
|
68
|
+
|
69
|
+
perform do |p, _ctx|
|
70
|
+
{ chosen: p[:color] }
|
71
|
+
end
|
72
|
+
end
|
56
73
|
end
|
57
74
|
end
|
58
75
|
end
|
59
76
|
end
|
60
77
|
```
|
61
78
|
|
62
|
-
This
|
79
|
+
This creates a panel with a tab and two actions. File path matches constant: `app/command_deck/panels/utilities.rb` → `Panels::Utilities`
|
63
80
|
|
64
81
|

|
65
82
|
|
66
83
|
## DSL API
|
67
84
|
|
68
|
-
|
69
|
-
|
70
|
-
```ruby
|
71
|
-
CommandDeck.panel(title, owner: nil, group: nil, key: nil) { ... }
|
72
|
-
```
|
73
|
-
|
74
|
-
Inside a panel, define tabs:
|
85
|
+
Panels inherit from `CommandDeck::BasePanel`. Define tabs within a panel:
|
75
86
|
|
76
87
|
```ruby
|
77
88
|
tab(title) { ... }
|
78
89
|
```
|
79
90
|
|
80
|
-
|
91
|
+
Define actions within a tab:
|
81
92
|
|
82
93
|
```ruby
|
83
94
|
action(title, key:) { ... }
|
84
95
|
```
|
85
96
|
|
86
|
-
|
97
|
+
Declare params and execution logic within an action:
|
87
98
|
|
88
99
|
```ruby
|
89
100
|
param(name, type, **opts)
|
@@ -110,17 +121,14 @@ Selector-specific options:
|
|
110
121
|
- `return:` `:value` (default), `:label`, or `:both` (`{ label:, value: }`).
|
111
122
|
- Choice shapes accepted:
|
112
123
|
- Values: `%w[a b c]`
|
113
|
-
- Pairs: `[[
|
124
|
+
- Pairs: `[['Label A', 'a'], ['Label B', 'b']]`
|
114
125
|
- Objects: `{ label:, value:, meta?: { ... } }`
|
115
126
|
|
116
|
-
|
117
|
-
|
118
|
-
- The block `perform { |params, ctx| ... }` receives your coerced params and a context hash (reserved for future use).
|
119
|
-
- Return any object serializable to JSON (Hash recommended) to show it in the UI.
|
127
|
+
The `perform` block receives coerced params and a context hash. Return any JSON-serializable object (Hash recommended).
|
120
128
|
|
121
129
|
## Security
|
122
130
|
|
123
|
-
|
131
|
+
Intended for development only. **DO NOT ENABLE IN PRODUCTION**.
|
124
132
|
|
125
133
|
## Development
|
126
134
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CommandDeck
|
4
|
+
# Base class for panel definitions.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# module Panels
|
8
|
+
# class Global < CommandDeck::BasePanel
|
9
|
+
# panel "Global Tools" do
|
10
|
+
# tab "Update" do
|
11
|
+
# action "Do Something", key: "global.do_something" do
|
12
|
+
# perform { |params, ctx| { ok: true } }
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
class BasePanel
|
19
|
+
class << self
|
20
|
+
def panel(title, **opts, &block)
|
21
|
+
@panel_definition = { title: title, opts: opts, block: block }
|
22
|
+
end
|
23
|
+
|
24
|
+
def register!
|
25
|
+
return unless @panel_definition
|
26
|
+
|
27
|
+
Registry.panel(
|
28
|
+
@panel_definition[:title],
|
29
|
+
**@panel_definition[:opts],
|
30
|
+
&@panel_definition[:block]
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def inherited(subclass)
|
35
|
+
super
|
36
|
+
CommandDeck.register_panel_class(subclass)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/command_deck/engine.rb
CHANGED
@@ -8,8 +8,12 @@ module CommandDeck
|
|
8
8
|
class Engine < ::Rails::Engine
|
9
9
|
isolate_namespace CommandDeck
|
10
10
|
|
11
|
+
initializer "command_deck.add_autoload_paths", before: :set_autoload_paths do |app|
|
12
|
+
panels_path = Rails.root.join("app/command_deck")
|
13
|
+
app.config.autoload_paths << panels_path.to_s if panels_path.exist?
|
14
|
+
end
|
15
|
+
|
11
16
|
initializer "command_deck.mount_point" do
|
12
|
-
# Default mount point. If the host app has a relative_url_root, respect it.
|
13
17
|
mp = "/command_deck"
|
14
18
|
if defined?(Rails) && Rails.application.config.respond_to?(:relative_url_root)
|
15
19
|
root = Rails.application.config.relative_url_root
|
@@ -18,11 +22,20 @@ module CommandDeck
|
|
18
22
|
CommandDeck::Middleware.mount_point = mp
|
19
23
|
end
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
config.to_prepare do
|
26
|
+
next unless Rails.env.development?
|
27
|
+
|
28
|
+
CommandDeck::Registry.clear!
|
29
|
+
|
30
|
+
if defined?(Panels)
|
31
|
+
Panels.constants.each do |const_name|
|
32
|
+
Panels.const_get(const_name)
|
33
|
+
rescue NameError => e
|
34
|
+
Rails.logger.warn "[CommandDeck] Could not load panel: #{e.message}"
|
35
|
+
end
|
25
36
|
end
|
37
|
+
|
38
|
+
CommandDeck.register_all_panels!
|
26
39
|
end
|
27
40
|
end
|
28
41
|
end
|
data/lib/command_deck/version.rb
CHANGED
data/lib/command_deck.rb
CHANGED
@@ -3,12 +3,25 @@
|
|
3
3
|
require_relative "command_deck/version"
|
4
4
|
require "command_deck/registry"
|
5
5
|
require "command_deck/executor"
|
6
|
+
require "command_deck/base_panel"
|
6
7
|
|
8
|
+
# Main module of the Command Deck gem
|
7
9
|
module CommandDeck
|
8
10
|
class Error < StandardError; end
|
9
|
-
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
class << self
|
13
|
+
def panel_classes
|
14
|
+
@panel_classes ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def register_panel_class(klass)
|
18
|
+
panel_classes << klass unless panel_classes.include?(klass)
|
19
|
+
end
|
20
|
+
|
21
|
+
def register_all_panels!
|
22
|
+
panel_classes.each(&:register!)
|
23
|
+
end
|
24
|
+
end
|
14
25
|
end
|
26
|
+
|
27
|
+
require "command_deck/engine" if defined?(Rails)
|
data/public/img/demo.gif
ADDED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: command_deck
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- crowrojas
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -17,6 +17,9 @@ dependencies:
|
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '7.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '9.0'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -24,6 +27,9 @@ dependencies:
|
|
24
27
|
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '7.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '9.0'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: railties
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -31,6 +37,9 @@ dependencies:
|
|
31
37
|
- - ">="
|
32
38
|
- !ruby/object:Gem::Version
|
33
39
|
version: '7.0'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '9.0'
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -38,8 +47,13 @@ dependencies:
|
|
38
47
|
- - ">="
|
39
48
|
- !ruby/object:Gem::Version
|
40
49
|
version: '7.0'
|
41
|
-
|
42
|
-
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '9.0'
|
53
|
+
description: |
|
54
|
+
Command Deck is a Rails engine that provides a floating panel UI for running custom admin
|
55
|
+
actions and tasks without opening the Rails console. Define panels/tabs/actions with a
|
56
|
+
class-based DSL.
|
43
57
|
email:
|
44
58
|
- cristobal.rojasbrito@gmail.com
|
45
59
|
executables: []
|
@@ -49,6 +63,7 @@ files:
|
|
49
63
|
- ".rubocop.yml"
|
50
64
|
- CHANGELOG.md
|
51
65
|
- CODE_OF_CONDUCT.md
|
66
|
+
- CONTRIBUTING.md
|
52
67
|
- LICENSE.txt
|
53
68
|
- README.md
|
54
69
|
- Rakefile
|
@@ -74,13 +89,14 @@ files:
|
|
74
89
|
- lib/command_deck/assets/js/ui/overlay/theme_manager.js
|
75
90
|
- lib/command_deck/assets/js/ui/panel_selector.js
|
76
91
|
- lib/command_deck/assets/js/ui/settings_dropdown.js
|
92
|
+
- lib/command_deck/base_panel.rb
|
77
93
|
- lib/command_deck/engine.rb
|
78
94
|
- lib/command_deck/executor.rb
|
79
95
|
- lib/command_deck/injector.rb
|
80
96
|
- lib/command_deck/middleware.rb
|
81
|
-
- lib/command_deck/railtie.rb
|
82
97
|
- lib/command_deck/registry.rb
|
83
98
|
- lib/command_deck/version.rb
|
99
|
+
- public/img/demo.gif
|
84
100
|
- public/img/demo.png
|
85
101
|
- sig/command_deck.rbs
|
86
102
|
homepage: https://github.com/crow-rojas/command_deck
|
@@ -89,7 +105,7 @@ licenses:
|
|
89
105
|
metadata:
|
90
106
|
allowed_push_host: https://rubygems.org
|
91
107
|
homepage_uri: https://github.com/crow-rojas/command_deck
|
92
|
-
source_code_uri: https://github.com/crow-rojas/command_deck
|
108
|
+
source_code_uri: https://github.com/crow-rojas/command_deck/tree/master
|
93
109
|
changelog_uri: https://github.com/crow-rojas/command_deck/blob/master/CHANGELOG.md
|
94
110
|
rubygems_mfa_required: 'true'
|
95
111
|
post_install_message:
|
@@ -110,6 +126,5 @@ requirements: []
|
|
110
126
|
rubygems_version: 3.5.22
|
111
127
|
signing_key:
|
112
128
|
specification_version: 4
|
113
|
-
summary:
|
114
|
-
Rails app.
|
129
|
+
summary: Dev-oriented floating panel for running custom actions in Rails apps
|
115
130
|
test_files: []
|
data/lib/command_deck/railtie.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rails/railtie"
|
4
|
-
|
5
|
-
module CommandDeck
|
6
|
-
# Rails engine for Command Deck
|
7
|
-
class Railtie < ::Rails::Railtie
|
8
|
-
initializer "command_deck.load_panels", after: :load_config_initializers do
|
9
|
-
path = Rails.root.join("app/command_deck")
|
10
|
-
Dir[path.join("**/*.rb")].each { |f| load f } if Dir.exist?(path)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|