compony 0.5.3 → 0.5.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/.gitignore +3 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +6 -6
- data/README.md +36 -0
- data/VERSION +1 -1
- data/app/controllers/compony_controller.rb +4 -0
- data/compony.gemspec +4 -4
- data/doc/ComponentGenerator.html +1 -1
- data/doc/Components.html +1 -1
- data/doc/ComponentsGenerator.html +1 -1
- data/doc/Compony/Component.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Labelling.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html +96 -27
- data/doc/Compony/ComponentMixins/Default/Standalone/VerbDsl.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone.html +1 -1
- data/doc/Compony/ComponentMixins/Default.html +1 -1
- data/doc/Compony/ComponentMixins/Resourceful.html +1 -1
- data/doc/Compony/ComponentMixins.html +1 -1
- data/doc/Compony/Components/Button.html +1 -1
- data/doc/Compony/Components/Destroy.html +1 -1
- data/doc/Compony/Components/Edit.html +1 -1
- data/doc/Compony/Components/Form.html +210 -127
- data/doc/Compony/Components/New.html +1 -1
- data/doc/Compony/Components/WithForm.html +1 -1
- data/doc/Compony/Components.html +1 -1
- data/doc/Compony/ControllerMixin.html +1 -1
- data/doc/Compony/Engine.html +1 -1
- data/doc/Compony/MethodAccessibleHash.html +1 -1
- data/doc/Compony/ModelFields/Anchormodel.html +1 -1
- data/doc/Compony/ModelFields/Association.html +1 -1
- data/doc/Compony/ModelFields/Attachment.html +1 -1
- data/doc/Compony/ModelFields/Base.html +1 -1
- data/doc/Compony/ModelFields/Boolean.html +1 -1
- data/doc/Compony/ModelFields/Color.html +1 -1
- data/doc/Compony/ModelFields/Currency.html +1 -1
- data/doc/Compony/ModelFields/Date.html +1 -1
- data/doc/Compony/ModelFields/Datetime.html +1 -1
- data/doc/Compony/ModelFields/Decimal.html +1 -1
- data/doc/Compony/ModelFields/Email.html +1 -1
- data/doc/Compony/ModelFields/Float.html +1 -1
- data/doc/Compony/ModelFields/Integer.html +1 -1
- data/doc/Compony/ModelFields/Percentage.html +1 -1
- data/doc/Compony/ModelFields/Phone.html +1 -1
- data/doc/Compony/ModelFields/RichText.html +1 -1
- data/doc/Compony/ModelFields/String.html +1 -1
- data/doc/Compony/ModelFields/Text.html +1 -1
- data/doc/Compony/ModelFields/Time.html +1 -1
- data/doc/Compony/ModelFields/Url.html +1 -1
- data/doc/Compony/ModelFields.html +1 -1
- data/doc/Compony/ModelMixin.html +29 -29
- data/doc/Compony/NaturalOrdering.html +1 -1
- data/doc/Compony/RequestContext.html +1 -1
- data/doc/Compony/Version.html +1 -1
- data/doc/Compony/ViewHelpers.html +1 -1
- data/doc/Compony.html +3 -3
- data/doc/ComponyController.html +1 -1
- data/doc/_index.html +1 -1
- data/doc/file.README.html +42 -7
- data/doc/index.html +42 -7
- data/doc/method_list.html +112 -96
- data/doc/top-level-namespace.html +1 -1
- data/lib/compony/component_mixins/default/standalone/standalone_dsl.rb +18 -10
- data/lib/compony/components/form.rb +49 -32
- data/lib/compony/model_mixin.rb +24 -14
- data/lib/compony.rb +2 -2
- metadata +3 -9
@@ -102,7 +102,7 @@
|
|
102
102
|
</div>
|
103
103
|
|
104
104
|
<div id="footer">
|
105
|
-
Generated on
|
105
|
+
Generated on Mon Apr 7 13:00:52 2025 by
|
106
106
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
107
107
|
0.9.37 (ruby-3.3.5).
|
108
108
|
</div>
|
@@ -17,6 +17,7 @@ module Compony
|
|
17
17
|
@scope_args = scope_args
|
18
18
|
@verbs = {}
|
19
19
|
@skip_authentication = false
|
20
|
+
@skip_forgery_protection = false
|
20
21
|
@layout = true # can be overriden by false or a string
|
21
22
|
end
|
22
23
|
|
@@ -25,16 +26,17 @@ module Compony
|
|
25
26
|
evaluate(&block)
|
26
27
|
@component = block.binding.eval('self') # Fetches the component holding this DSL call (via the block)
|
27
28
|
return {
|
28
|
-
name:
|
29
|
-
path:
|
30
|
-
constraints:
|
31
|
-
scope:
|
32
|
-
scope_args:
|
33
|
-
verbs:
|
34
|
-
rails_action_name:
|
35
|
-
path_helper_name:
|
36
|
-
skip_authentication:
|
37
|
-
|
29
|
+
name: @name,
|
30
|
+
path: @path,
|
31
|
+
constraints: @constraints,
|
32
|
+
scope: @scope,
|
33
|
+
scope_args: @scope_args,
|
34
|
+
verbs: @verbs,
|
35
|
+
rails_action_name: Compony.rails_action_name(comp_name, family_name, @name),
|
36
|
+
path_helper_name: Compony.path_helper_name(comp_name, family_name, @name),
|
37
|
+
skip_authentication: @skip_authentication,
|
38
|
+
skip_forgery_protection: @skip_forgery_protection,
|
39
|
+
layout: @layout
|
38
40
|
}.compact
|
39
41
|
end
|
40
42
|
|
@@ -65,6 +67,12 @@ module Compony
|
|
65
67
|
@skip_authentication = true
|
66
68
|
end
|
67
69
|
|
70
|
+
# DSL
|
71
|
+
# Defines that for this component, no forgery protection (CSRF) should be performed.
|
72
|
+
def skip_forgery_protection!
|
73
|
+
@skip_forgery_protection = true
|
74
|
+
end
|
75
|
+
|
68
76
|
# DSL
|
69
77
|
# Speficies the Rails layout (under `app/views/layouts`) that should be used to render this component.
|
70
78
|
# Defaults to Rails' default (`layouts/application`) if the method is never called.
|
@@ -36,7 +36,8 @@ module Compony
|
|
36
36
|
end
|
37
37
|
|
38
38
|
content do
|
39
|
-
|
39
|
+
form_params = { method: @comp_opts[:submit_verb], url: @submit_path }.merge(@form_params || {})
|
40
|
+
form_html = simple_form_for(data, **form_params) do |f|
|
40
41
|
component.with_simpleform(f, controller) do
|
41
42
|
instance_exec(&form_fields)
|
42
43
|
div class: 'compony-form-buttons' do
|
@@ -95,32 +96,38 @@ module Compony
|
|
95
96
|
|
96
97
|
# Called inside the form_fields block. This makes the method `field` available in the block.
|
97
98
|
# See also notes for `with_simpleform`.
|
98
|
-
|
99
|
+
# If multilang is true, a suffixed field is generated for every available locale (useful with gem "mobility"). Render the array as you wish.
|
100
|
+
def field(name, multilang: false, **input_opts)
|
99
101
|
fail("The `field` method may only be called inside `form_fields` for #{inspect}.") unless @simpleform
|
100
|
-
name = name.to_sym
|
101
102
|
|
102
|
-
|
103
|
+
if multilang
|
104
|
+
I18n.available_locales.map { |locale| field("#{name}_#{locale}", **input_opts) }
|
105
|
+
else
|
106
|
+
name = name.to_sym
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
+
input_opts.merge!(disabled: true) if @form_disabled
|
109
|
+
|
110
|
+
# Check per-field authorization
|
111
|
+
if @cancancan_action.present? && @controller.current_ability.permitted_attributes(@cancancan_action, @simpleform.object).exclude?(name)
|
112
|
+
Rails.logger.debug do
|
113
|
+
"Skipping form field #{name.inspect} because the current user is not allowed to perform #{@cancancan_action.inspect} on #{@simpleform.object}."
|
114
|
+
end
|
115
|
+
return
|
108
116
|
end
|
109
|
-
return
|
110
|
-
end
|
111
117
|
|
112
|
-
|
113
|
-
|
114
|
-
|
118
|
+
hidden = input_opts.delete(:hidden)
|
119
|
+
model_field = @simpleform.object.fields[name]
|
120
|
+
fail("Field #{name.inspect} is not defined on #{@simpleform.object.inspect} but was requested in #{inspect}.") unless model_field
|
115
121
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
+
if hidden
|
123
|
+
return model_field.simpleform_input_hidden(@simpleform, self, **input_opts)
|
124
|
+
else
|
125
|
+
unless @focus_given || @skip_autofocus
|
126
|
+
input_opts[:autofocus] = true unless input_opts.key? :autofocus
|
127
|
+
@focus_given = true
|
128
|
+
end
|
129
|
+
return model_field.simpleform_input(@simpleform, self, **input_opts)
|
122
130
|
end
|
123
|
-
return model_field.simpleform_input(@simpleform, self, **input_opts)
|
124
131
|
end
|
125
132
|
end
|
126
133
|
|
@@ -163,6 +170,11 @@ module Compony
|
|
163
170
|
@form_disabled = true
|
164
171
|
end
|
165
172
|
|
173
|
+
# DSL method, allows to customize parameters given to simple_form_for
|
174
|
+
def form_params(**new_form_params)
|
175
|
+
@form_params = new_form_params
|
176
|
+
end
|
177
|
+
|
166
178
|
protected
|
167
179
|
|
168
180
|
# DSL method, adds a new line to the schema whitelisting a single param inside the schema's wrapper
|
@@ -173,19 +185,24 @@ module Compony
|
|
173
185
|
|
174
186
|
# DSL method, adds a new field to the schema whitelisting a single field of data_class
|
175
187
|
# This auto-generates the correct schema line for the field.
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
#
|
182
|
-
|
183
|
-
|
184
|
-
|
188
|
+
# If multilang is true, a suffixed field is generated for every available locale (useful with gem "mobility")
|
189
|
+
def schema_field(field_name, multilang: false)
|
190
|
+
if multilang
|
191
|
+
I18n.available_locales.each { |locale| schema_field("#{field_name}_#{locale}") }
|
192
|
+
else
|
193
|
+
# This runs upon component setup.
|
194
|
+
@schema_lines_for_data << proc do |data, controller|
|
195
|
+
# This runs within a request context.
|
196
|
+
field = data.class.fields[field_name.to_sym] || fail("No field #{field_name.to_sym.inspect} found for #{data.inspect} in #{inspect}.")
|
197
|
+
# Check per-field authorization
|
198
|
+
if @cancancan_action.present? && controller.current_ability.permitted_attributes(@cancancan_action.to_sym, data).exclude?(field.name.to_sym)
|
199
|
+
Rails.logger.debug do
|
200
|
+
"Skipping form schema_field #{field_name.inspect} because the current user is not allowed to perform #{@cancancan_action.inspect} on #{data}."
|
201
|
+
end
|
202
|
+
next nil
|
185
203
|
end
|
186
|
-
next
|
204
|
+
next field.schema_line
|
187
205
|
end
|
188
|
-
next field.schema_line
|
189
206
|
end
|
190
207
|
end
|
191
208
|
|
@@ -198,7 +215,7 @@ module Compony
|
|
198
215
|
# Check per-field authorization
|
199
216
|
unless @cancancan_action.nil? || controller.current_ability.can?(:set_password, data)
|
200
217
|
Rails.logger.debug do
|
201
|
-
"Skipping form schema_pw_field #{
|
218
|
+
"Skipping form schema_pw_field #{field_name.inspect} because the current user is not allowed to perform :set_password on #{data}."
|
202
219
|
end
|
203
220
|
next nil
|
204
221
|
end
|
data/lib/compony/model_mixin.rb
CHANGED
@@ -19,21 +19,27 @@ module Compony
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# DSL method, defines a new field which will be translated and can be added to field groups
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
if defined?(ActiveType) && self <= ActiveType::Object && !include?(ActiveModel::Attributes)
|
28
|
-
fail "Please add `include ActiveModel::Attributes` at the top of the class #{self}, as attributes cannot be registered otherwise with ActiveType."
|
29
|
-
end
|
30
|
-
# Register the field as an attribute
|
31
|
-
if defined?(ActiveType) && self <= ActiveType::Object
|
32
|
-
ar_attribute(name)
|
22
|
+
# If multilang is true, a suffixed field is generated for every available locale, along with a non-suffixed virtual field (useful with gem "mobility")
|
23
|
+
def field(name, type, multilang: false, **extra_attrs)
|
24
|
+
if multilang
|
25
|
+
field(name, type, virtual: true, **extra_attrs)
|
26
|
+
I18n.available_locales.each { |locale| field("#{name}_#{locale}", type, **extra_attrs) }
|
33
27
|
else
|
34
|
-
|
28
|
+
name = name.to_sym
|
29
|
+
self.fields = fields.dup
|
30
|
+
field = Compony.model_field_class_for(type.to_s.camelize).new(name, self, **extra_attrs)
|
31
|
+
# Handle the case where ActiveType would interfere with attribute registration
|
32
|
+
if defined?(ActiveType) && self <= ActiveType::Object && !include?(ActiveModel::Attributes)
|
33
|
+
fail "Please add `include ActiveModel::Attributes` at the top of the class #{self}, as attributes cannot be registered otherwise with ActiveType."
|
34
|
+
end
|
35
|
+
# Register the field as an attribute
|
36
|
+
if defined?(ActiveType) && self <= ActiveType::Object
|
37
|
+
ar_attribute(name)
|
38
|
+
else
|
39
|
+
attribute(name)
|
40
|
+
end
|
41
|
+
fields[name] = field
|
35
42
|
end
|
36
|
-
fields[name] = field
|
37
43
|
end
|
38
44
|
|
39
45
|
# DSL method, sets the containing model.
|
@@ -66,7 +72,11 @@ module Compony
|
|
66
72
|
# Add a prevention that reflects the `has_many` `dependent' properties. Avoids that users can press buttons that will result in a failed destroy.
|
67
73
|
reflect_on_all_associations.select { |assoc| %i[restrict_with_exception restrict_with_error].include? assoc.options[:dependent] }.each do |assoc|
|
68
74
|
prevent(:destroy, I18n.t('compony.feasibility.has_dependent_models', dependent_class: I18n.t(assoc.klass.model_name.plural.humanize))) do
|
69
|
-
|
75
|
+
if assoc.is_a? ActiveRecord::Reflection::HasOneReflection
|
76
|
+
!public_send(assoc.name).nil?
|
77
|
+
else
|
78
|
+
public_send(assoc.name).any?
|
79
|
+
end
|
70
80
|
end
|
71
81
|
end
|
72
82
|
self.autodetect_feasibilities_completed = true
|
data/lib/compony.rb
CHANGED
@@ -79,13 +79,13 @@ module Compony
|
|
79
79
|
end
|
80
80
|
|
81
81
|
# Getter for content_before_root_comp_block
|
82
|
-
# @see Compony#content_before_root_comp
|
82
|
+
# @see Compony#content_before_root_comp=
|
83
83
|
def self.content_before_root_comp_block
|
84
84
|
@content_before_root_comp_block
|
85
85
|
end
|
86
86
|
|
87
87
|
# Getter for content_after_root_comp_block
|
88
|
-
# @see Compony#content_after_root_comp
|
88
|
+
# @see Compony#content_after_root_comp=
|
89
89
|
def self.content_after_root_comp_block
|
90
90
|
@content_after_root_comp_block
|
91
91
|
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: compony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sandro Kalbermatter
|
8
8
|
- contributors
|
9
|
-
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2025-04-07 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: yard
|
@@ -165,8 +164,6 @@ dependencies:
|
|
165
164
|
- - "~>"
|
166
165
|
- !ruby/object:Gem::Version
|
167
166
|
version: 3.6.1
|
168
|
-
description:
|
169
|
-
email:
|
170
167
|
executables: []
|
171
168
|
extensions: []
|
172
169
|
extra_rdoc_files: []
|
@@ -312,10 +309,8 @@ files:
|
|
312
309
|
- lib/generators/components/USAGE
|
313
310
|
- lib/generators/components/components_generator.rb
|
314
311
|
- logo.svg
|
315
|
-
homepage:
|
316
312
|
licenses: []
|
317
313
|
metadata: {}
|
318
|
-
post_install_message:
|
319
314
|
rdoc_options: []
|
320
315
|
require_paths:
|
321
316
|
- lib
|
@@ -330,8 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
330
325
|
- !ruby/object:Gem::Version
|
331
326
|
version: '0'
|
332
327
|
requirements: []
|
333
|
-
rubygems_version: 3.
|
334
|
-
signing_key:
|
328
|
+
rubygems_version: 3.6.3
|
335
329
|
specification_version: 4
|
336
330
|
summary: Compony is a Gem that allows you to write your Rails application in component-style
|
337
331
|
fashion. It combines a controller action and route along \ with its view into a
|