plutonium 0.15.4 → 0.15.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/app/assets/plutonium.css +1 -1
- data/app/assets/plutonium.ico +0 -0
- data/app/assets/plutonium.png +0 -0
- data/app/views/components/table_search_input/table_search_input_component.html.erb +3 -3
- data/app/views/resource/_resource_table.html.erb +0 -321
- data/docs/.vitepress/config.ts +61 -0
- data/docs/.vitepress/theme/custom.css +61 -0
- data/docs/.vitepress/theme/index.ts +4 -0
- data/docs/api-examples.md +49 -0
- data/docs/guide/getting-started/authorization.md +296 -0
- data/docs/guide/getting-started/core-concepts.md +432 -0
- data/docs/guide/getting-started/index.md +18 -0
- data/docs/guide/getting-started/installation.md +269 -0
- data/docs/guide/getting-started/resources.md +254 -0
- data/docs/guide/what-is-plutonium.md +211 -0
- data/docs/index.md +43 -0
- data/docs/markdown-examples.md +85 -0
- data/docs/public/android-chrome-192x192.png +0 -0
- data/docs/public/android-chrome-512x512.png +0 -0
- data/docs/public/apple-touch-icon.png +0 -0
- data/docs/public/favicon-16x16.png +0 -0
- data/docs/public/favicon-32x32.png +0 -0
- data/docs/public/favicon.ico +0 -0
- data/docs/public/plutonium.png +0 -0
- data/docs/public/site.webmanifest +1 -0
- data/docs/public/templates/plutonium.rb +21 -0
- data/lib/generators/pu/core/assets/assets_generator.rb +2 -3
- data/lib/generators/pu/core/assets/templates/tailwind.config.js +2 -2
- data/lib/generators/pu/core/install/install_generator.rb +9 -1
- data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +0 -1
- data/lib/plutonium/core/controllers/authorizable.rb +1 -1
- data/lib/plutonium/definition/base.rb +8 -0
- data/lib/plutonium/definition/defineable_props.rb +1 -1
- data/lib/plutonium/definition/presentable.rb +71 -0
- data/lib/plutonium/interaction/README.md +1 -1
- data/lib/plutonium/interaction/base.rb +6 -6
- data/lib/plutonium/lib/deep_freezer.rb +31 -0
- data/lib/plutonium/query/adhoc_block.rb +19 -0
- data/lib/plutonium/query/base.rb +29 -0
- data/lib/plutonium/query/filter.rb +12 -0
- data/lib/plutonium/query/filters/text.rb +77 -0
- data/lib/plutonium/query/model_scope.rb +19 -0
- data/lib/plutonium/railtie.rb +0 -10
- data/lib/plutonium/resource/controller.rb +0 -3
- data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +26 -0
- data/lib/plutonium/resource/controllers/crud_actions.rb +3 -6
- data/lib/plutonium/resource/controllers/defineable.rb +0 -2
- data/lib/plutonium/resource/controllers/queryable.rb +36 -20
- data/lib/plutonium/resource/policy.rb +5 -6
- data/lib/plutonium/resource/query_object.rb +61 -147
- data/lib/plutonium/resource/register.rb +3 -0
- data/lib/plutonium/{refinements/parameter_refinements.rb → support/parameters.rb} +5 -7
- data/lib/plutonium/ui/action_button.rb +34 -19
- data/lib/plutonium/ui/component/methods.rb +1 -1
- data/lib/plutonium/ui/display/resource.rb +19 -15
- data/lib/plutonium/ui/form/query.rb +171 -0
- data/lib/plutonium/ui/form/resource.rb +22 -17
- data/lib/plutonium/ui/table/components/scopes_bar.rb +1 -1
- data/lib/plutonium/ui/table/components/search_bar.rb +6 -139
- data/lib/plutonium/ui/table/resource.rb +10 -9
- data/lib/plutonium/version.rb +1 -1
- data/package-lock.json +5769 -1853
- data/package.json +11 -5
- data/src/js/core.js +0 -1
- data/tailwind.options.js +89 -11
- metadata +37 -13
- data/app/assets/plutonium-original.png +0 -0
- data/app/assets/plutonium-white.png +0 -0
- data/lib/plutonium/interaction/concerns/presentable.rb +0 -73
- data/public/plutonium-assets/fonts/bootstrap-icons.woff +0 -0
- data/public/plutonium-assets/fonts/bootstrap-icons.woff2 +0 -0
- /data/{templates → docs/public/templates}/base.rb +0 -0
@@ -0,0 +1,211 @@
|
|
1
|
+
# What is Plutonium?
|
2
|
+
|
3
|
+
Plutonium is a Rapid Application Development (RAD) toolkit that extends Rails with powerful conventions, patterns, and tools to accelerate application development while maintaining flexibility and maintainability.
|
4
|
+
|
5
|
+
It acts as a higher-level abstraction on top of Rails, providing ready-to-use solutions for common application needs while preserving Rails' elegance.
|
6
|
+
|
7
|
+
## Core Architecture
|
8
|
+
|
9
|
+
### Rails-Native Design
|
10
|
+
|
11
|
+
Plutonium integrates seamlessly with Rails, extending its conventions rather than replacing them:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
# Plutonium controllers inherit from your ApplicationController
|
15
|
+
class ResourceController < ApplicationController
|
16
|
+
include Plutonium::Resource::Controller
|
17
|
+
end
|
18
|
+
|
19
|
+
# Plutonium controllers are Rails controllers
|
20
|
+
class ProductsController < ResourceController
|
21
|
+
# Enhanced with resource capabilities
|
22
|
+
def custom_action
|
23
|
+
# Regular Rails code works just fine
|
24
|
+
respond_to do |format|
|
25
|
+
format.html
|
26
|
+
format.json
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
### Resource-Oriented Architecture
|
33
|
+
|
34
|
+
Resources are the building blocks of Plutonium applications:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
class ProductDefinition < ResourceDefinition
|
38
|
+
# Declarative field definitions
|
39
|
+
field :name, as: :string
|
40
|
+
field :description, as: :markdown
|
41
|
+
field :price_cents, as: :money
|
42
|
+
|
43
|
+
# Resource-level search
|
44
|
+
search do |scope, query|
|
45
|
+
scope.where("name LIKE ?", "%#{query}%")
|
46
|
+
end
|
47
|
+
|
48
|
+
# Business actions
|
49
|
+
action :publish, interaction: PublishProduct
|
50
|
+
action :archive, interaction: ArchiveProduct
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
### Modular by Design
|
55
|
+
|
56
|
+
Plutonium's packaging system helps organize code into focused, reusable modules:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
# Generate different types of packages
|
60
|
+
rails generate pu:pkg:portal admin
|
61
|
+
rails generate pu:pkg:package inventory
|
62
|
+
|
63
|
+
# Packages are isolated and focused
|
64
|
+
module AdminPortal
|
65
|
+
class Engine < Rails::Engine
|
66
|
+
include Plutonium::Portal::Engine
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
AdminPortal::Engine.routes.draw do
|
71
|
+
register_resource ::Product
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
### Progressive Enhancement
|
76
|
+
|
77
|
+
Built on modern web technologies like Hotwire, delivering rich interactivity without sacrificing simplicity:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
class PublishProduct < ResourceInteraction
|
81
|
+
attribute :schedule_for, :datetime
|
82
|
+
attribute :notify_users, :boolean
|
83
|
+
|
84
|
+
def execute
|
85
|
+
resource.publish!(schedule_for:)
|
86
|
+
notify_users! if notify_users
|
87
|
+
|
88
|
+
success(resource)
|
89
|
+
.with_message("Product scheduled for publishing")
|
90
|
+
.with_render_response(NotificationComponent.new)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
## Use Cases
|
96
|
+
|
97
|
+
### Business Applications
|
98
|
+
|
99
|
+
::: details Enterprise Resource Planning (ERP)
|
100
|
+
```ruby
|
101
|
+
class InvoiceDefinition < ResourceDefinition
|
102
|
+
# Rich field handling
|
103
|
+
field :line_items, as: :nested, limit: 20
|
104
|
+
field :attachments, as: :document, multiple: true
|
105
|
+
|
106
|
+
# Business actions
|
107
|
+
action :submit_for_approval, interaction: SubmitForApproval
|
108
|
+
action :approve, interaction: ApproveInvoice
|
109
|
+
action :reject, interaction: RejectInvoice
|
110
|
+
|
111
|
+
# Workflow states
|
112
|
+
scope :draft
|
113
|
+
scope :pending_approval
|
114
|
+
scope :approved
|
115
|
+
end
|
116
|
+
```
|
117
|
+
:::
|
118
|
+
|
119
|
+
::: details Multi-tenant SaaS
|
120
|
+
```ruby
|
121
|
+
module CustomerPortal
|
122
|
+
class Engine < Rails::Engine
|
123
|
+
include Plutonium::Package::Engine
|
124
|
+
# Automatic tenant isolation
|
125
|
+
scope_to_entity Organization
|
126
|
+
end
|
127
|
+
end
|
128
|
+
```
|
129
|
+
:::
|
130
|
+
|
131
|
+
### Administrative Systems
|
132
|
+
|
133
|
+
::: details Back-office Applications
|
134
|
+
```ruby
|
135
|
+
class OrderDefinition < ResourceDefinition
|
136
|
+
# Advanced filtering
|
137
|
+
filter :status, with: SelectFilter, choices: Order.statuses
|
138
|
+
filter :created_at, with: DateRangeFilter
|
139
|
+
|
140
|
+
# Bulk actions
|
141
|
+
action :process_batch, interaction: ProcessPendingOrders
|
142
|
+
action :export_to_csv, interaction: ExportOrders
|
143
|
+
|
144
|
+
# Complex displays
|
145
|
+
display :summary do |field|
|
146
|
+
OrderSummaryComponent.new(field)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
```
|
150
|
+
:::
|
151
|
+
|
152
|
+
::: details Content Management
|
153
|
+
```ruby
|
154
|
+
class ArticleDefinition < ResourceDefinition
|
155
|
+
field :content, as: :markdown
|
156
|
+
field :featured_image, as: :image
|
157
|
+
|
158
|
+
# Publishing workflow
|
159
|
+
action :publish, interaction: PublishArticle
|
160
|
+
action :schedule, interaction: ScheduleArticle
|
161
|
+
|
162
|
+
# Content organization
|
163
|
+
scope :draft
|
164
|
+
scope :published
|
165
|
+
scope :scheduled
|
166
|
+
end
|
167
|
+
```
|
168
|
+
:::
|
169
|
+
|
170
|
+
## Key Benefits
|
171
|
+
|
172
|
+
### Accelerated Development
|
173
|
+
- Pre-built components for common functionality
|
174
|
+
- Smart generators for boilerplate code
|
175
|
+
- Convention-based resource handling
|
176
|
+
- Integrated authentication and authorization
|
177
|
+
|
178
|
+
### Maintainable Architecture
|
179
|
+
- Clear separation of concerns through packages
|
180
|
+
- Consistent patterns across the application
|
181
|
+
- Deep Rails integration
|
182
|
+
- Progressive enhancement
|
183
|
+
|
184
|
+
### Enterprise Ready
|
185
|
+
- Flexible and robust access control
|
186
|
+
- Multi-tenancy support
|
187
|
+
- Extensible component system
|
188
|
+
- Mobile-friendly by default
|
189
|
+
|
190
|
+
## Best For
|
191
|
+
|
192
|
+
::: tip IDEAL USE CASES
|
193
|
+
- Complex business applications
|
194
|
+
- Multi-tenant SaaS platforms
|
195
|
+
- Administrative systems
|
196
|
+
- Content management systems
|
197
|
+
- Resource management systems
|
198
|
+
:::
|
199
|
+
|
200
|
+
::: warning MIGHT NOT BE THE BEST FIT
|
201
|
+
- Simple blogs or brochure sites
|
202
|
+
- Basic CRUD applications
|
203
|
+
- Pure API-only services
|
204
|
+
:::
|
205
|
+
|
206
|
+
## Prerequisites
|
207
|
+
|
208
|
+
- Ruby 3.2.2 or higher
|
209
|
+
- Rails 7.1 or higher
|
210
|
+
- Node.js and Yarn
|
211
|
+
- Basic understanding of Ruby on Rails
|
data/docs/index.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
---
|
2
|
+
# https://vitepress.dev/reference/default-theme-home-page
|
3
|
+
layout: home
|
4
|
+
|
5
|
+
hero:
|
6
|
+
name: Plutonium RADKit
|
7
|
+
tagline: The Ultimate Rapid Application Development Toolkit (RADKit) for Rails
|
8
|
+
image:
|
9
|
+
src: /plutonium.png
|
10
|
+
alt: Plutonium
|
11
|
+
actions:
|
12
|
+
- theme: brand
|
13
|
+
text: Get started
|
14
|
+
link: /guide/getting-started/
|
15
|
+
- theme: alt
|
16
|
+
text: Learn more
|
17
|
+
link: /guide/what-is-plutonium
|
18
|
+
|
19
|
+
features:
|
20
|
+
- title: Pro-Grade CRUD UI
|
21
|
+
details: Stunning, modern interface with rich field types to build powerful admin panels in minutes
|
22
|
+
|
23
|
+
- title: Intelligent Fields
|
24
|
+
details: Zero-config field detection that matches your Rails models out of the box
|
25
|
+
|
26
|
+
- title: Seamless Authentication
|
27
|
+
details: Use your existing auth or our Rodauth integration - get setup in seconds
|
28
|
+
|
29
|
+
- title: Enterprise Authorization
|
30
|
+
details: Industrial-strength access control powered by Action Policy's proven framework
|
31
|
+
|
32
|
+
- title: Built-in Multitenancy
|
33
|
+
details: Row-level multitenancy that just works - perfect for SaaS and enterprise apps
|
34
|
+
|
35
|
+
- title: Advanced Nested Resources
|
36
|
+
details: Complex resource relationships made simple with zero extra configuration
|
37
|
+
|
38
|
+
- title: Custom Actions
|
39
|
+
details: Extend your admin panel with incredibly simple custom actions and workflows
|
40
|
+
|
41
|
+
- title: Complete Builder Control
|
42
|
+
details: Total flexibility to customize every aspect of your admin UI with elegant builder APIs
|
43
|
+
---
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Markdown Extension Examples
|
2
|
+
|
3
|
+
This page demonstrates some of the built-in markdown extensions provided by VitePress.
|
4
|
+
|
5
|
+
## Syntax Highlighting
|
6
|
+
|
7
|
+
VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting:
|
8
|
+
|
9
|
+
**Input**
|
10
|
+
|
11
|
+
````md
|
12
|
+
```js{4}
|
13
|
+
export default {
|
14
|
+
data () {
|
15
|
+
return {
|
16
|
+
msg: 'Highlighted!'
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
```
|
21
|
+
````
|
22
|
+
|
23
|
+
**Output**
|
24
|
+
|
25
|
+
```js{4}
|
26
|
+
export default {
|
27
|
+
data () {
|
28
|
+
return {
|
29
|
+
msg: 'Highlighted!'
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
```
|
34
|
+
|
35
|
+
## Custom Containers
|
36
|
+
|
37
|
+
**Input**
|
38
|
+
|
39
|
+
```md
|
40
|
+
::: info
|
41
|
+
This is an info box.
|
42
|
+
:::
|
43
|
+
|
44
|
+
::: tip
|
45
|
+
This is a tip.
|
46
|
+
:::
|
47
|
+
|
48
|
+
::: warning
|
49
|
+
This is a warning.
|
50
|
+
:::
|
51
|
+
|
52
|
+
::: danger
|
53
|
+
This is a dangerous warning.
|
54
|
+
:::
|
55
|
+
|
56
|
+
::: details
|
57
|
+
This is a details block.
|
58
|
+
:::
|
59
|
+
```
|
60
|
+
|
61
|
+
**Output**
|
62
|
+
|
63
|
+
::: info
|
64
|
+
This is an info box.
|
65
|
+
:::
|
66
|
+
|
67
|
+
::: tip
|
68
|
+
This is a tip.
|
69
|
+
:::
|
70
|
+
|
71
|
+
::: warning
|
72
|
+
This is a warning.
|
73
|
+
:::
|
74
|
+
|
75
|
+
::: danger
|
76
|
+
This is a dangerous warning.
|
77
|
+
:::
|
78
|
+
|
79
|
+
::: details
|
80
|
+
This is a details block.
|
81
|
+
:::
|
82
|
+
|
83
|
+
## More
|
84
|
+
|
85
|
+
Check out the documentation for the [full list of markdown extensions](https://vitepress.dev/guide/markdown).
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
after_bundle do
|
2
|
+
# We just installed Rails, let's create a commit
|
3
|
+
git add: "."
|
4
|
+
git commit: %( -m 'initial commit' )
|
5
|
+
|
6
|
+
# Run the base install
|
7
|
+
rails_command "app:template LOCATION=https://radioactive-labs.github.io/plutonium-core/templates/base.rb"
|
8
|
+
|
9
|
+
# Add development tools
|
10
|
+
generate "pu:gem:dotenv"
|
11
|
+
git add: "."
|
12
|
+
git commit: %( -m 'add dotenv' )
|
13
|
+
|
14
|
+
generate "pu:gem:annotate"
|
15
|
+
git add: "."
|
16
|
+
git commit: %( -m 'add annotate' )
|
17
|
+
|
18
|
+
generate "pu:core:assets"
|
19
|
+
git add: "."
|
20
|
+
git commit: %( -m 'integrate assets' )
|
21
|
+
end
|
@@ -22,12 +22,11 @@ module Pu
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def copy_tailwind_config
|
25
|
-
copy_file "tailwind.config.js"
|
25
|
+
copy_file "tailwind.config.js", force: true
|
26
26
|
end
|
27
27
|
|
28
28
|
def install_dependencies
|
29
|
-
|
30
|
-
`yarn add flowbite @tailwindcss/forms`
|
29
|
+
run "npm install @radioactive-labs/plutonium flowbite @tailwindcss/forms"
|
31
30
|
end
|
32
31
|
|
33
32
|
def configure_application
|
@@ -9,12 +9,12 @@ module.exports = {
|
|
9
9
|
].concat(plutoniumTailwindConfig.plugins.map((plugin) => require(plugin))),
|
10
10
|
theme: plutoniumTailwindConfig.theme,
|
11
11
|
content: [
|
12
|
+
`${__dirname}/app/**/*.rb`,
|
12
13
|
`${__dirname}/app/views/**/*.html.erb`,
|
13
14
|
`${__dirname}/app/helpers/**/*.rb`,
|
14
15
|
`${__dirname}/app/assets/stylesheets/**/*.css`,
|
15
16
|
`${__dirname}/app/javascript/**/*.js`,
|
16
|
-
`${__dirname}/app
|
17
|
-
`${__dirname}/packages/**/app/plutonium/**/*.rb`,
|
17
|
+
`${__dirname}/packages/**/app/**/*.rb`,
|
18
18
|
`${__dirname}/packages/**/app/views/**/*.html.erb`,
|
19
19
|
].concat(plutoniumTailwindConfig.content),
|
20
20
|
}
|
@@ -15,6 +15,7 @@ module Pu
|
|
15
15
|
setup_packages
|
16
16
|
setup_app
|
17
17
|
eject_views
|
18
|
+
setup_active_record
|
18
19
|
rescue => e
|
19
20
|
exception "#{self.class} failed:", e
|
20
21
|
end
|
@@ -25,7 +26,6 @@ module Pu
|
|
25
26
|
copy_file "config/packages.rb"
|
26
27
|
create_file "packages/.keep"
|
27
28
|
insert_into_file "config/application.rb", "\nrequire_relative \"packages\"\n", after: /Bundler\.require.*\n/
|
28
|
-
# insert_into_file "config/application.rb", indent("Plutonium.configure_rails config\n\n", 4), after: /.*< Rails::Application\n/
|
29
29
|
end
|
30
30
|
|
31
31
|
def setup_app
|
@@ -38,6 +38,14 @@ module Pu
|
|
38
38
|
force: options[:force],
|
39
39
|
skip: options[:skip]
|
40
40
|
end
|
41
|
+
|
42
|
+
def setup_active_record
|
43
|
+
inject_into_class(
|
44
|
+
"app/models/application_record.rb",
|
45
|
+
"ApplicationRecord",
|
46
|
+
" include Plutonium::Resource::Record\n"
|
47
|
+
)
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
end
|
@@ -9,7 +9,7 @@ module Plutonium
|
|
9
9
|
|
10
10
|
included do
|
11
11
|
authorize :user, through: :current_user
|
12
|
-
authorize :
|
12
|
+
authorize :entity_scope, through: :entity_scope_for_authorize
|
13
13
|
|
14
14
|
helper_method :policy_for, :authorized_resource_scope
|
15
15
|
end
|
@@ -46,6 +46,10 @@ module Plutonium
|
|
46
46
|
|
47
47
|
class Display < Plutonium::UI::Display::Resource; end
|
48
48
|
|
49
|
+
class QueryForm < Plutonium::UI::Form::Query; end
|
50
|
+
|
51
|
+
class TextFilter < Plutonium::Query::Filters::Text; end
|
52
|
+
|
49
53
|
# fields
|
50
54
|
defineable_props :field, :input, :display, :column
|
51
55
|
|
@@ -94,6 +98,10 @@ module Plutonium
|
|
94
98
|
def detail_class
|
95
99
|
self.class::Display
|
96
100
|
end
|
101
|
+
|
102
|
+
def query_form
|
103
|
+
self.class::QueryForm
|
104
|
+
end
|
97
105
|
end
|
98
106
|
end
|
99
107
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module Definition
|
3
|
+
# Provides presentation-related functionality for interactions.
|
4
|
+
#
|
5
|
+
# This module allows interactions to define metadata such as labels, icons,
|
6
|
+
# and descriptions, which can be used for UI generation or documentation.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class MyInteraction < Plutonium::Interaction::Base
|
10
|
+
# include Plutonium::Definition::Presentable
|
11
|
+
#
|
12
|
+
# presents label: "My Interaction",
|
13
|
+
# icon: "star",
|
14
|
+
# description: "Does something awesome"
|
15
|
+
#
|
16
|
+
# # ... rest of the interaction
|
17
|
+
# end
|
18
|
+
module Presentable
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
included do
|
22
|
+
class_attribute :presentation_metadata, default: {}
|
23
|
+
end
|
24
|
+
|
25
|
+
class_methods do
|
26
|
+
# Defines presentation metadata for the interaction.
|
27
|
+
#
|
28
|
+
# @param options [Hash] The presentation options.
|
29
|
+
# @option options [String] :label The label for the interaction.
|
30
|
+
# @option options [String] :icon The icon for the interaction.
|
31
|
+
# @option options [String] :description The description of the interaction.
|
32
|
+
def presents(**options)
|
33
|
+
self.presentation_metadata = options
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the label for the interaction.
|
37
|
+
#
|
38
|
+
# @return [String] The label defined in the presentation metadata or a default generated from the class name.
|
39
|
+
def label
|
40
|
+
presentation_metadata[:label] || name.demodulize.titleize
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the icon for the interaction.
|
44
|
+
#
|
45
|
+
# @return [String, nil] The icon defined in the presentation metadata.
|
46
|
+
def icon
|
47
|
+
presentation_metadata[:icon]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the description for the interaction.
|
51
|
+
#
|
52
|
+
# @return [String, nil] The description defined in the presentation metadata.
|
53
|
+
def description
|
54
|
+
presentation_metadata[:description]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def label
|
59
|
+
self.class.label
|
60
|
+
end
|
61
|
+
|
62
|
+
def icon
|
63
|
+
self.class.icon
|
64
|
+
end
|
65
|
+
|
66
|
+
def description
|
67
|
+
self.class.description
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -252,7 +252,7 @@ The `Presentable` concern allows you to add metadata to your interactions, which
|
|
252
252
|
|
253
253
|
```ruby
|
254
254
|
class MyInteraction < Plutonium::Interaction::Base
|
255
|
-
include Plutonium::
|
255
|
+
include Plutonium::Definition::Presentable
|
256
256
|
|
257
257
|
presents label: "My Interaction",
|
258
258
|
icon: Phlex::TablerIcons::Activate,
|
@@ -22,10 +22,10 @@ module Plutonium
|
|
22
22
|
class Base
|
23
23
|
include ActiveModel::Model
|
24
24
|
include ActiveModel::Attributes
|
25
|
-
include Concerns::Presentable
|
26
25
|
include Plutonium::Definition::DefineableProps
|
27
26
|
include Plutonium::Definition::ConfigAttr
|
28
|
-
|
27
|
+
include Plutonium::Definition::Presentable
|
28
|
+
# include Plutonium::Interaction::Concerns::WorkflowDSL
|
29
29
|
|
30
30
|
class Form < Plutonium::UI::Form::Interaction; end
|
31
31
|
|
@@ -44,6 +44,10 @@ module Plutonium
|
|
44
44
|
self::Form.new(instance || new)
|
45
45
|
end
|
46
46
|
|
47
|
+
def build_form
|
48
|
+
self.class.build_form(self)
|
49
|
+
end
|
50
|
+
|
47
51
|
# Executes the interaction.
|
48
52
|
#
|
49
53
|
# @return [Plutonium::Interaction::Outcome] The result of the interaction.
|
@@ -60,10 +64,6 @@ module Plutonium
|
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
63
|
-
def build_form
|
64
|
-
self.class.build_form(self)
|
65
|
-
end
|
66
|
-
|
67
67
|
private
|
68
68
|
|
69
69
|
# Implement the main logic of the interaction.
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module Lib
|
5
|
+
class DeepFreezer
|
6
|
+
def self.freeze(object)
|
7
|
+
# Recursive calling #deep_freeze for enumerable objects.
|
8
|
+
if object.respond_to? :each
|
9
|
+
if object.instance_of?(Hash)
|
10
|
+
object.each { |key, val| freeze(val) }
|
11
|
+
else
|
12
|
+
object.each { |val| freeze(val) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# # Freezing of all instance variable values.
|
17
|
+
# object.instance_variables.each do |var|
|
18
|
+
# frozen_val = instance_variable_get(var)
|
19
|
+
# frozen_val.deep_freeze
|
20
|
+
# instance_variable_set(var, frozen_val)
|
21
|
+
# end
|
22
|
+
|
23
|
+
if object.frozen?
|
24
|
+
object
|
25
|
+
else
|
26
|
+
object.freeze
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module Query
|
3
|
+
class AdhocBlock < Base
|
4
|
+
attr_reader :body
|
5
|
+
|
6
|
+
# Initializes a AdhocBlock with a given block of code.
|
7
|
+
#
|
8
|
+
# @param body [Proc] The block of code for the query.
|
9
|
+
def initialize(body)
|
10
|
+
super()
|
11
|
+
@body = body
|
12
|
+
end
|
13
|
+
|
14
|
+
def apply(scope, **)
|
15
|
+
body.call(scope, **)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module Query
|
3
|
+
class Base
|
4
|
+
include Plutonium::Definition::DefineableProps
|
5
|
+
include Plutonium::Definition::ConfigAttr
|
6
|
+
include Plutonium::Definition::Presentable
|
7
|
+
|
8
|
+
defineable_props :field, :input
|
9
|
+
|
10
|
+
# Applies a parameterized query to modify the given scope.
|
11
|
+
#
|
12
|
+
# @param scope [Object] The initial scope that will be filtered, sorted, or otherwise modified
|
13
|
+
# by applying this query. This is typically an ActiveRecord::Relation or similar query object.
|
14
|
+
#
|
15
|
+
# @param params [Hash] Optional parameters that configure how the query is applied.
|
16
|
+
# The specific parameters accepted depend on the implementing class.
|
17
|
+
#
|
18
|
+
# @return [Object] The modified scope with this query's conditions applied. Returns the same
|
19
|
+
# type as the input scope parameter.
|
20
|
+
#
|
21
|
+
# @example Basic usage
|
22
|
+
# query.apply(User.all, status: 'active')
|
23
|
+
#
|
24
|
+
def apply(scope, **params)
|
25
|
+
raise NotImplementedError, "#{self.class}#apply(scope, **params)"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|