compony 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8fa06e0cecacc05de1b6567e29594a44fcbfed063d0268e08de239432c51a7f2
4
- data.tar.gz: 24ec1426a6259b2cc3b1ddbd0127d8878a46701a0d7b2003bf5668eddf1eb8a0
3
+ metadata.gz: 5e3590a5ce07d22e7d483af2c98c972e9c64403e43084560e193bb6382215844
4
+ data.tar.gz: 054e3c2ef26650cdf404b0615f74dc12f0a610728e9b9b1446a90a4c91952365
5
5
  SHA512:
6
- metadata.gz: 66fc9fe7beb64285bc2f21a945d1596c24206072b0fd64172a3eea2130754363f11d980b9159b0ebc1702be72526eb2ce8e613d17ece625ac377eeb0698ee876
7
- data.tar.gz: fce5758f4f812d6ba053cf085c807ffecbce5163ed676d529d00aaa36257478a3887f60d3d6bc1ec0294151144edb6d63dc415f82c8fa6b7727fc4f84be34a97
6
+ metadata.gz: 90139644b0d2f3dd9adbff42e42bcdecae69d93676e5c4527795bd89a81103f5eabab4fd846fb3ad5e32b3463b0303b5e860f65d31939c0438f2e211bd28b4f6
7
+ data.tar.gz: a9c0714b201b1df42f0996e1a965de71ed6c6738cf8a6e0e332883a1b97f9dcdb876d89a138965c63db957e6b99bf54bdba7cbfc6a977b68c94f0b98dba496f5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ # 0.0.7
2
+
3
+ - Fix `standalone_access_permitted_for?` check for buttons pointing to non-get verbs
4
+
5
+ # 0.0.6
6
+
7
+ - Fix a bug that breaks hidden fields of type reference
8
+ - Add dynamic method "field" to model mixin
9
+ - Tolerate and skip actions that do not define buttons, allows for dynamic action skipping
10
+ - Fix `value_for` for boolean fields when they are nil
11
+ - BREAKING: Rename `on_created` to `on_created_respond`, `on_updated` to `on_updated_respond`, and `on_destroyed` to `on_destroyed_respond`
12
+ - New hooks `on_created`, `on_updated`, and `on_destroyed` are called before their `_respond` counterpart
13
+ - Fix a bug in Attachment Field
14
+ - Support overriding simpleform name by providing `name:` as an argument to field.simpleform_input
15
+ - In ModelField Anchormodel, tolerate "value" as input_html key and infer correct constant, allow form.object to be missing
16
+
1
17
  # 0.0.5
2
18
 
3
19
  - Fix row bug for Email field type
@@ -8,6 +24,10 @@
8
24
  - Make fields point to the correct `model_class` in case of STI
9
25
  - Support hidden Anchormodel fields
10
26
 
27
+ ## KNOWN BUGS
28
+
29
+ - Breaks hidden fields of type reference
30
+
11
31
  # 0.0.4
12
32
 
13
33
  - Unscope the namespace of resourceful components
data/compony.gemspec CHANGED
@@ -2,19 +2,19 @@
2
2
  # This file is auto-generated via: 'rake gemspec'.
3
3
 
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: compony 0.0.5 ruby lib
5
+ # stub: compony 0.0.7 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "compony".freeze
9
- s.version = "0.0.5"
9
+ s.version = "0.0.7"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Sandro Kalbermatter".freeze, "contributors".freeze]
14
- s.date = "2023-06-20"
14
+ s.date = "2023-09-18"
15
15
  s.files = [".gitignore".freeze, ".ruby-version".freeze, ".yardopts".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "Gemfile.lock".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "app/controllers/compony_controller.rb".freeze, "compony.gemspec".freeze, "config/locales/de.yml".freeze, "config/locales/en.yml".freeze, "config/routes.rb".freeze, "doc/resourceful_lifecycle.graphml".freeze, "doc/resourceful_lifecycle.pdf".freeze, "lib/compony.rb".freeze, "lib/compony/component.rb".freeze, "lib/compony/component_mixins/default/labelling.rb".freeze, "lib/compony/component_mixins/default/standalone.rb".freeze, "lib/compony/component_mixins/default/standalone/resourceful_verb_dsl.rb".freeze, "lib/compony/component_mixins/default/standalone/standalone_dsl.rb".freeze, "lib/compony/component_mixins/default/standalone/verb_dsl.rb".freeze, "lib/compony/component_mixins/resourceful.rb".freeze, "lib/compony/components/button.rb".freeze, "lib/compony/components/destroy.rb".freeze, "lib/compony/components/edit.rb".freeze, "lib/compony/components/form.rb".freeze, "lib/compony/components/new.rb".freeze, "lib/compony/components/with_form.rb".freeze, "lib/compony/controller_mixin.rb".freeze, "lib/compony/engine.rb".freeze, "lib/compony/method_accessible_hash.rb".freeze, "lib/compony/model_fields/anchormodel.rb".freeze, "lib/compony/model_fields/association.rb".freeze, "lib/compony/model_fields/attachment.rb".freeze, "lib/compony/model_fields/base.rb".freeze, "lib/compony/model_fields/boolean.rb".freeze, "lib/compony/model_fields/currency.rb".freeze, "lib/compony/model_fields/date.rb".freeze, "lib/compony/model_fields/datetime.rb".freeze, "lib/compony/model_fields/decimal.rb".freeze, "lib/compony/model_fields/email.rb".freeze, "lib/compony/model_fields/float.rb".freeze, "lib/compony/model_fields/integer.rb".freeze, "lib/compony/model_fields/phone.rb".freeze, "lib/compony/model_fields/rich_text.rb".freeze, "lib/compony/model_fields/string.rb".freeze, "lib/compony/model_fields/text.rb".freeze, "lib/compony/model_fields/time.rb".freeze, "lib/compony/model_fields/url.rb".freeze, "lib/compony/model_mixin.rb".freeze, "lib/compony/request_context.rb".freeze, "lib/compony/version.rb".freeze, "lib/compony/view_helpers.rb".freeze, "lib/generators/component/USAGE".freeze, "lib/generators/component/component_generator.rb".freeze, "lib/generators/component/templates/component.rb.erb".freeze, "lib/generators/component/templates/destroy.rb.erb".freeze, "lib/generators/component/templates/edit.rb.erb".freeze, "lib/generators/component/templates/form.rb.erb".freeze, "lib/generators/component/templates/new.rb.erb".freeze, "lib/generators/components/USAGE".freeze, "lib/generators/components/components_generator.rb".freeze]
16
16
  s.required_ruby_version = Gem::Requirement.new(">= 3.0.0".freeze)
17
- s.rubygems_version = "3.4.13".freeze
17
+ s.rubygems_version = "3.4.19".freeze
18
18
  s.summary = "Needs summary".freeze
19
19
 
20
20
  s.specification_version = 4
@@ -206,7 +206,9 @@ module Compony
206
206
  button_htmls = @actions.map do |action|
207
207
  next if @skipped_actions.include?(action.name)
208
208
  Compony.with_button_defaults(feasibility_action: action.name.to_sym) do
209
- h.content_tag(:div, action.block.call.render(controller), class: action_class)
209
+ action_button = action.block.call
210
+ next unless action_button
211
+ h.content_tag(:div, action_button.render(controller), class: action_class)
210
212
  end
211
213
  end
212
214
  next h.safe_join button_htmls
@@ -75,7 +75,8 @@ module Compony
75
75
  # - when called standalone (via request to the component), the load data step must be completed
76
76
  # - when called to check for permission only, e.g. to display a button to it, initialize the component by passing the :data keyword to `new`
77
77
  # By default, this checks the authorization to access the main standalone entrypoint (with name `nil`) and HTTP verb GET.
78
- def standalone_access_permitted_for?(controller, standalone_name: nil, verb: :get)
78
+ def standalone_access_permitted_for?(controller, standalone_name: nil, verb: nil)
79
+ verb ||= :get
79
80
  standalone_name = standalone_name&.to_sym
80
81
  verb = verb.to_sym
81
82
  standalone_config = standalone_configs[standalone_name] || fail("#{inspect} does not provide the standalone config #{standalone_config.inspect}.")
@@ -15,7 +15,8 @@ module Compony
15
15
  authorize { can?(:destroy, @data) }
16
16
  store_data # This enables the global store_data block defined below for this path and verb.
17
17
  respond do
18
- evaluate_with_backfire(&@on_destroyed_block)
18
+ evaluate_with_backfire(&@on_destroyed_block) if @on_destroyed_block
19
+ evaluate_with_backfire(&@on_destroyed_respond_block)
19
20
  end
20
21
  end
21
22
  end
@@ -51,7 +52,7 @@ module Compony
51
52
  @data.destroy!
52
53
  end
53
54
 
54
- on_destroyed do
55
+ on_destroyed_respond do
55
56
  flash.notice = I18n.t('compony.components.destroy.data_was_destroyed', data_label: @data.label)
56
57
  redirect_to evaluate_with_backfire(&@on_destroyed_redirect_path_block), status: :see_other # 303: force GET
57
58
  end
@@ -62,10 +63,16 @@ module Compony
62
63
  end
63
64
 
64
65
  # DSL method
66
+ # Sets a block that is evaluated with backfire in the successful case after storing, but before responding.
65
67
  def on_destroyed(&block)
66
68
  @on_destroyed_block = block
67
69
  end
68
70
 
71
+ # DSL method
72
+ def on_destroyed_respond(&block)
73
+ @on_destroyed_respond_block = block
74
+ end
75
+
69
76
  # DSL method
70
77
  def on_destroyed_redirect_path(&block)
71
78
  @on_destroyed_redirect_path_block = block
@@ -17,7 +17,8 @@ module Compony
17
17
  store_data # This enables the global store_data block defined below for this path and verb.
18
18
  respond do
19
19
  if @update_succeeded
20
- evaluate_with_backfire(&@on_updated_block)
20
+ evaluate_with_backfire(&@on_updated_block) if @on_updated_block
21
+ evaluate_with_backfire(&@on_updated_respond_block)
21
22
  else
22
23
  evaluate_with_backfire(&@on_update_failed_block)
23
24
  end
@@ -56,7 +57,7 @@ module Compony
56
57
  @update_succeeded = @data.save
57
58
  end
58
59
 
59
- on_updated do
60
+ on_updated_respond do
60
61
  flash.notice = I18n.t('compony.components.edit.data_was_updated', data_label: data.label)
61
62
  redirect_to evaluate_with_backfire(&@on_updated_redirect_path_block)
62
63
  end
@@ -76,10 +77,16 @@ module Compony
76
77
  end
77
78
 
78
79
  # DSL method
80
+ # Sets a block that is evaluated with backfire in the successful case after storing, but before responding.
79
81
  def on_updated(&block)
80
82
  @on_updated_block = block
81
83
  end
82
84
 
85
+ # DSL method
86
+ def on_updated_respond(&block)
87
+ @on_updated_respond_block = block
88
+ end
89
+
83
90
  # DSL method
84
91
  def on_updated_redirect_path(&block)
85
92
  @on_updated_redirect_path_block = block
@@ -19,9 +19,10 @@ module Compony
19
19
  store_data # This enables the global store_data block defined below for this path and verb.
20
20
  respond do
21
21
  if @create_succeeded
22
- evaluate_with_backfire(&@on_created_block)
22
+ evaluate_with_backfire(&@on_created_block) if @on_created_block
23
+ evaluate_with_backfire(&@on_created_respond_block)
23
24
  else
24
- evaluate_with_backfire(&@on_create_failed_block)
25
+ evaluate_with_backfire(&@on_create_failed_respond_block)
25
26
  end
26
27
  end
27
28
  end
@@ -55,7 +56,7 @@ module Compony
55
56
  @create_succeeded = @data.save
56
57
  end
57
58
 
58
- on_created do
59
+ on_created_respond do
59
60
  flash.notice = I18n.t('compony.components.new.data_was_created', data_label: data.label)
60
61
  redirect_to evaluate_with_backfire(&@on_created_redirect_path_block)
61
62
  end
@@ -68,25 +69,31 @@ module Compony
68
69
  end
69
70
  end
70
71
 
71
- on_create_failed do
72
+ on_create_failed_respond do
72
73
  Rails.logger.warn(@data&.errors&.full_messages)
73
74
  render_standalone(controller, status: :unprocessable_entity)
74
75
  end
75
76
  end
76
77
 
77
78
  # DSL method
79
+ # Sets a block that is evaluated with backfire in the successful case after storing, but before responding.
78
80
  def on_created(&block)
79
81
  @on_created_block = block
80
82
  end
81
83
 
84
+ # DSL method
85
+ def on_created_respond(&block)
86
+ @on_created_respond_block = block
87
+ end
88
+
82
89
  # DSL method
83
90
  def on_created_redirect_path(&block)
84
91
  @on_created_redirect_path_block = block
85
92
  end
86
93
 
87
94
  # DSL method
88
- def on_create_failed(&block)
89
- @on_create_failed_block = block
95
+ def on_create_failed_respond(&block)
96
+ @on_create_failed_respond_block = block
90
97
  end
91
98
  end
92
99
  end
@@ -10,25 +10,34 @@ module Compony
10
10
  return transform_and_join(data.send(@name), controller:) { |el| el&.label }
11
11
  end
12
12
 
13
- def simpleform_input(form, _component, **input_opts)
14
- selected_cst = form.object.send(@name)
13
+ def simpleform_input(form, _component, name: nil, **input_opts)
15
14
  anchormodel_attribute = @model_class.anchormodel_attributes[@name]
16
15
  anchormodel_class = anchormodel_attribute.anchormodel_class
16
+ input_opts[:input_html] ||= {}
17
+ # Attempt to read selected key from html input options "value", as the caller might not know that this is a select.
18
+ selected_key = input_opts[:input_html].delete(:value) # can also be both nil or blank
19
+ if selected_key.blank? && form.object
20
+ # No selected key override present and a model is present, use the model to find out what to select
21
+ selected_cst = form.object.send(@name)
22
+ selected_key = selected_cst&.key || anchormodel_class.all.first
23
+ end
17
24
  opts = {
18
25
  collection: self.class.collect(anchormodel_class.all),
19
26
  label_method: :first,
20
27
  value_method: :second,
21
- selected: selected_cst&.key || anchormodel_class.all.first,
28
+ selected: selected_key,
22
29
  include_blank: anchormodel_attribute.optional
23
30
  }.merge(input_opts)
24
- return form.input @name, **opts
31
+ return form.input name || @name, **opts
25
32
  end
26
33
 
27
- def simpleform_input_hidden(form, _component, **input_opts)
28
- selected_cst = form.object.send(@name)
29
- input_opts[:input_html] ||= {}
30
- input_opts[:input_html][:value] = selected_cst.is_a?(::Anchormodel) ? selected_cst.key : selected_cst
31
- return form.input @name, as: :hidden, **input_opts
34
+ def simpleform_input_hidden(form, _component, name: nil, **input_opts)
35
+ if form.object
36
+ selected_cst = form.object.send(@name)
37
+ input_opts[:input_html] ||= {}
38
+ input_opts[:input_html][:value] = selected_cst.is_a?(::Anchormodel) ? selected_cst.key : selected_cst
39
+ end
40
+ return form.input name || @name, as: :hidden, **input_opts
32
41
  end
33
42
  end
34
43
  end
@@ -32,8 +32,12 @@ module Compony
32
32
  end
33
33
  end
34
34
 
35
- def simpleform_input(form, _component, **input_opts)
36
- return form.association @name, **input_opts
35
+ def simpleform_input(form, _component, name: nil, **input_opts)
36
+ return form.association name || @name, **input_opts
37
+ end
38
+
39
+ def simpleform_input_hidden(form, _component, name: nil, **input_opts)
40
+ return form.input name || @schema_key, as: :hidden, **input_opts
37
41
  end
38
42
 
39
43
  protected
@@ -11,9 +11,9 @@ module Compony
11
11
  end
12
12
  end
13
13
 
14
- def simpleform_input(form, _component, accept: nil, **input_opts)
14
+ def simpleform_input(form, _component, name: nil, accept: nil, **input_opts)
15
15
  input_opts.merge!(input_html: { accept: }) if accept
16
- return form.input(:proof_photo, **input_opts)
16
+ return form.input(name || @name, **input_opts)
17
17
  end
18
18
  end
19
19
  end
@@ -17,7 +17,7 @@ module Compony
17
17
  def initialize(name, model_class, **extra_attrs)
18
18
  @name = name.to_sym
19
19
  @model_class = model_class
20
- @schema_key = name
20
+ @schema_key = name.to_sym
21
21
  @extra_attrs = extra_attrs
22
22
  end
23
23
 
@@ -42,14 +42,14 @@ module Compony
42
42
 
43
43
  # Used in form helper.
44
44
  # Given a simpleform instance, returns the corresponding input to be supplied to the view.
45
- def simpleform_input(form, _component, **input_opts)
46
- return form.input @name, **input_opts
45
+ def simpleform_input(form, _component, name: nil, **input_opts)
46
+ return form.input name || @name, **input_opts
47
47
  end
48
48
 
49
49
  # Used in form helper
50
50
  # Given a simpleform instance, returns a suitable hidden input for thetype
51
- def simpleform_input_hidden(form, _component, **input_opts)
52
- return form.input @name, as: :hidden, **input_opts
51
+ def simpleform_input_hidden(form, _component, name: nil, **input_opts)
52
+ return form.input name || @name, as: :hidden, **input_opts
53
53
  end
54
54
 
55
55
  protected
@@ -2,7 +2,7 @@ module Compony
2
2
  module ModelFields
3
3
  class Boolean < Base
4
4
  def value_for(data, controller: nil, **_)
5
- return transform_and_join(data.send(@name), controller:) { |el| I18n.t("compony.boolean.#{el}") }
5
+ return transform_and_join(data.send(@name), controller:) { |el| el.nil? ? nil : I18n.t("compony.boolean.#{el}") }
6
6
  end
7
7
  end
8
8
  end
@@ -1,8 +1,8 @@
1
1
  module Compony
2
2
  module ModelFields
3
3
  class RichText < Base
4
- def simpleform_input(form, _component, **input_opts)
5
- return form.input @name, **input_opts.merge(as: :rich_text_area)
4
+ def simpleform_input(form, _component, name: nil, **input_opts)
5
+ return form.input name || @name, **input_opts.merge(as: :rich_text_area)
6
6
  end
7
7
  end
8
8
  end
@@ -91,5 +91,10 @@ module Compony
91
91
  text += '.' if text.present?
92
92
  return text
93
93
  end
94
+
95
+ # Calls value_for on the desired field. Do not confuse with the static method field.
96
+ def field(field_name, controller)
97
+ fields[field_name.to_sym].value_for(self, controller:)
98
+ end
94
99
  end
95
100
  end
@@ -2,7 +2,7 @@ module Compony
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- PATCH = 5
5
+ PATCH = 7
6
6
 
7
7
  EDGE = false
8
8
 
data/lib/compony.rb CHANGED
@@ -145,6 +145,7 @@ module Compony
145
145
  params: nil,
146
146
  feasibility_action: nil,
147
147
  feasibility_target: nil,
148
+ method: nil,
148
149
  **override_kwargs)
149
150
  label_opts ||= button_defaults[:label_opts] || {}
150
151
  params ||= button_defaults[:params] || {}
@@ -157,7 +158,8 @@ module Compony
157
158
  icon: target_comp_instance.icon,
158
159
  color: target_comp_instance.color,
159
160
  path: Compony.path(target_comp_instance.comp_name, target_comp_instance.family_name, model, **params),
160
- visible: ->(controller) { target_comp_instance.standalone_access_permitted_for?(controller) }
161
+ method:,
162
+ visible: ->(controller) { target_comp_instance.standalone_access_permitted_for?(controller, verb: method) }
161
163
  }
162
164
  if feasibility_target
163
165
  options.merge!({
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compony
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Kalbermatter
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-06-20 00:00:00.000000000 Z
12
+ date: 2023-09-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard