compony 0.5.2 → 0.5.4
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 +15 -0
- data/Gemfile.lock +6 -6
- data/README.md +38 -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 +9 -5
- data/doc/Compony/Components/Destroy.html +1 -1
- data/doc/Compony/Components/Edit.html +1 -1
- data/doc/Compony/Components/Form.html +289 -135
- 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 +25 -25
- 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 +30 -12
- data/doc/Compony.html +4 -4
- data/doc/ComponyController.html +1 -1
- data/doc/_index.html +1 -1
- data/doc/file.README.html +39 -1
- data/doc/index.html +39 -1
- data/doc/method_list.html +65 -41
- data/doc/top-level-namespace.html +1 -1
- data/lib/compony/component_mixins/default/standalone/standalone_dsl.rb +18 -10
- data/lib/compony/components/button.rb +5 -3
- data/lib/compony/components/form.rb +57 -32
- data/lib/compony/model_mixin.rb +19 -13
- data/lib/compony/view_helpers.rb +12 -4
- data/lib/compony.rb +3 -3
- metadata +3 -9
@@ -7,7 +7,7 @@ module Compony
|
|
7
7
|
|
8
8
|
# path: If given a block, it will be evaluated in the helpers context when rendering
|
9
9
|
# enabled: If given a block, it will be evaluated in the helpers context when rendering
|
10
|
-
def initialize(*, label: nil, path: nil, method: nil, type: nil, enabled: nil, visible: nil, title: nil, **, &)
|
10
|
+
def initialize(*, label: nil, path: nil, method: nil, type: nil, enabled: nil, visible: nil, title: nil, button_params: nil, value: nil, **, &)
|
11
11
|
@label = label || Compony.button_defaults[:label]
|
12
12
|
@type = type&.to_sym || Compony.button_defaults[:type] || :button
|
13
13
|
@path = path || Compony.button_defaults[:path] || 'javascript:void(0)'
|
@@ -23,6 +23,8 @@ module Compony
|
|
23
23
|
@visible = Compony.button_defaults[:visible] if @visible.nil?
|
24
24
|
@visible = true if @visible.nil?
|
25
25
|
@title = title || Compony.button_defaults[:title]
|
26
|
+
@button_params = button_params
|
27
|
+
@value = value
|
26
28
|
|
27
29
|
fail "Unsupported button type #{@type}, use on of: #{SUPPORTED_TYPES.inspect}" unless SUPPORTED_TYPES.include?(@type)
|
28
30
|
|
@@ -47,9 +49,9 @@ module Compony
|
|
47
49
|
if @visible
|
48
50
|
case @type
|
49
51
|
when :button
|
50
|
-
concat button_to(@label, @path, method: @method, disabled: !@enabled, title: @title)
|
52
|
+
concat button_to(@label, @path, method: @method, disabled: !@enabled, title: @title, params: @button_params)
|
51
53
|
when :submit
|
52
|
-
concat button_tag(@label, type: :submit, disabled: !@enabled, title: @title)
|
54
|
+
concat button_tag(@label, type: :submit, disabled: !@enabled, title: @title, value: @value)
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
@@ -3,9 +3,10 @@ module Compony
|
|
3
3
|
# @api description
|
4
4
|
# This component is used for the _form partial in the Rails paradigm.
|
5
5
|
class Form < Component
|
6
|
-
def initialize(*args, cancancan_action: :missing, **kwargs)
|
6
|
+
def initialize(*args, cancancan_action: :missing, disabled: false, **kwargs)
|
7
7
|
@schema_lines_for_data = [] # Array of procs taking data returning a Schemacop proc
|
8
8
|
@cancancan_action = cancancan_action
|
9
|
+
@form_disabled = disabled
|
9
10
|
super
|
10
11
|
end
|
11
12
|
|
@@ -35,7 +36,8 @@ module Compony
|
|
35
36
|
end
|
36
37
|
|
37
38
|
content do
|
38
|
-
|
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|
|
39
41
|
component.with_simpleform(f, controller) do
|
40
42
|
instance_exec(&form_fields)
|
41
43
|
div class: 'compony-form-buttons' do
|
@@ -94,30 +96,38 @@ module Compony
|
|
94
96
|
|
95
97
|
# Called inside the form_fields block. This makes the method `field` available in the block.
|
96
98
|
# See also notes for `with_simpleform`.
|
97
|
-
|
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)
|
98
101
|
fail("The `field` method may only be called inside `form_fields` for #{inspect}.") unless @simpleform
|
99
|
-
name = name.to_sym
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
103
|
+
if multilang
|
104
|
+
I18n.available_locales.map { |locale| field("#{name}_#{locale}", **input_opts) }
|
105
|
+
else
|
106
|
+
name = name.to_sym
|
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
|
105
116
|
end
|
106
|
-
return
|
107
|
-
end
|
108
117
|
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
112
121
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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)
|
119
130
|
end
|
120
|
-
return model_field.simpleform_input(@simpleform, self, **input_opts)
|
121
131
|
end
|
122
132
|
end
|
123
133
|
|
@@ -155,6 +165,16 @@ module Compony
|
|
155
165
|
Compony::ModelFields::Anchormodel.collect(...)
|
156
166
|
end
|
157
167
|
|
168
|
+
# DSL method, disables all inputs
|
169
|
+
def disable!
|
170
|
+
@form_disabled = true
|
171
|
+
end
|
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
|
+
|
158
178
|
protected
|
159
179
|
|
160
180
|
# DSL method, adds a new line to the schema whitelisting a single param inside the schema's wrapper
|
@@ -165,19 +185,24 @@ module Compony
|
|
165
185
|
|
166
186
|
# DSL method, adds a new field to the schema whitelisting a single field of data_class
|
167
187
|
# This auto-generates the correct schema line for the field.
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
#
|
174
|
-
|
175
|
-
|
176
|
-
|
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
|
177
203
|
end
|
178
|
-
next
|
204
|
+
next field.schema_line
|
179
205
|
end
|
180
|
-
next field.schema_line
|
181
206
|
end
|
182
207
|
end
|
183
208
|
|
@@ -190,7 +215,7 @@ module Compony
|
|
190
215
|
# Check per-field authorization
|
191
216
|
unless @cancancan_action.nil? || controller.current_ability.can?(:set_password, data)
|
192
217
|
Rails.logger.debug do
|
193
|
-
"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}."
|
194
219
|
end
|
195
220
|
next nil
|
196
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.
|
data/lib/compony/view_helpers.rb
CHANGED
@@ -19,11 +19,19 @@ module Compony
|
|
19
19
|
# @param link_args [Array] Positional arguments that will be passed to the Rails `link_to` helper
|
20
20
|
# @param label_opts [Hash] Options hash that will be passed to the label method (see {Compony::ComponentMixins::Default::Labelling#label})
|
21
21
|
# @param link_kwargs [Hash] Named arguments that will be passed to the Rails `link_to` helper
|
22
|
-
def compony_link(
|
22
|
+
def compony_link(comp_name_or_cst_or_class, model_or_family_name_or_cst = nil, *link_args, label_opts: {}, params: {}, standalone_name: nil, **link_kwargs)
|
23
23
|
model = model_or_family_name_or_cst.respond_to?(:model_name) ? model_or_family_name_or_cst : nil
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
if comp_name_or_cst_or_class.is_a?(Class) && (comp_name_or_cst_or_class <= Compony::Component)
|
25
|
+
target_comp_instance = comp_name_or_cst_or_class.new(data: model)
|
26
|
+
else
|
27
|
+
target_comp_instance = Compony.comp_class_for!(comp_name_or_cst_or_class, model_or_family_name_or_cst).new(data: model)
|
28
|
+
end
|
29
|
+
return unless target_comp_instance.standalone_access_permitted_for?(self, standalone_name:)
|
30
|
+
return helpers.link_to(
|
31
|
+
target_comp_instance.label(model, **label_opts),
|
32
|
+
Compony.path(target_comp_instance.comp_name, target_comp_instance.family_name, model, standalone_name:, **params),
|
33
|
+
*link_args, **link_kwargs
|
34
|
+
)
|
27
35
|
end
|
28
36
|
|
29
37
|
# Given a component and a family/model, this instanciates and renders a button component.
|
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
|
@@ -198,7 +198,7 @@ module Compony
|
|
198
198
|
color: target_comp_instance.color,
|
199
199
|
path: Compony.path(target_comp_instance.comp_name, target_comp_instance.family_name, model, standalone_name:, **params),
|
200
200
|
method:,
|
201
|
-
visible: ->(controller) { target_comp_instance.standalone_access_permitted_for?(controller, verb: method) }
|
201
|
+
visible: ->(controller) { target_comp_instance.standalone_access_permitted_for?(controller, standalone_name:, verb: method) }
|
202
202
|
}
|
203
203
|
if feasibility_target
|
204
204
|
options.merge!({
|
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.4
|
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-02-14 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
|