compony 0.2.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f23cc54f00a7ceb09e6e5ce344ac957dfd22863ae54fbb8bfee47663aface5a9
4
- data.tar.gz: 78ab3342c2ab352d18e841696324497b0c7891f06d74dda0ad28e8998c5e18ac
3
+ metadata.gz: d8c73b93a2181fc65daa7d813741776da0426bb8f17bdfee660d8e94626f1676
4
+ data.tar.gz: 70715489017a96b9fd638a75c48666fc8157971af5b6f15f80a202ce774c14e2
5
5
  SHA512:
6
- metadata.gz: 6e2d696881f150e9f6b3c43522412670eecd87aae908a9bcd4be9184de74cc4e444df32c4b0965623c61065a38f483e4a9db5e4d26920cb54d8aaeaf393ad714
7
- data.tar.gz: 79bdb5b40c32265f2c6ab6eb2ab421ad0ca48b13d1eb6dd5b64d8217e60e7b9fb9a424fe34c33896f8cc32ce6d1cd88d2ad0d532f40422370f40e0cd0440256f
6
+ metadata.gz: 3f18b01d899380afbcba59880d0ef3bf827228ca410f67bcd2a8d70900cf32004442e4ae60cce6a6a2ca00801225cc8f760e0988e3a1903bda7969263ded700d
7
+ data.tar.gz: 0f9896f5d968a90f20c4c2323a41b205915a57f05b10cdb80d3968192b4af9c700635f22ed1057c5ba4850449c8d6f6c796c61f6f774418c2620a13e5fda0505
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ # 0.2.1
2
+
3
+ - Fix a bug where the app crashed on HEAD verb
4
+ - Show more details about failing authorization block
5
+ - Implement `submit_path` DSL call for WithForm
6
+ - Add French translation
7
+ - Implement `skip_autofocus` in Form
8
+ - Allow partial override of standalone verb configs. Example:
9
+ ```ruby
10
+ verb :get do
11
+ authorize { true }
12
+ end
13
+ verb :post do
14
+ authorize { true }
15
+ # Parent class implements more logic here, which will no longer be overwritten by calling `verb :post`.
16
+ end
17
+ ```
18
+
1
19
  # 0.2.0
2
20
 
3
21
  - Cleanup old code
@@ -15,7 +15,9 @@ class ComponyController < ApplicationController
15
15
 
16
16
  # Define controller action for each standalone config
17
17
  define_method(standalone_config.rails_action_name) do
18
- verb_config = standalone_config.verbs[request.raw_request_method.downcase.to_sym]
18
+ translated_verb = request.raw_request_method.downcase.to_sym
19
+ translated_verb = :get if translated_verb == :head # Rails transparently converts HEAD to GET, so we must do the same for fetching the config.
20
+ verb_config = standalone_config.verbs[translated_verb]
19
21
  Compony.comp_class_for!(comp_cst, family_cst).new.on_standalone_access(verb_config, self)
20
22
  end
21
23
 
data/compony.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
  # This file is auto-generated via: 'rake gemspec'.
3
3
 
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: compony 0.2.0 ruby lib
5
+ # stub: compony 0.2.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "compony".freeze
9
- s.version = "0.2.0".freeze
9
+ s.version = "0.2.1".freeze
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-12-05"
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/color.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/percentage.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]
14
+ s.date = "2024-01-22"
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/locales/fr.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/color.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/percentage.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
17
  s.rubygems_version = "3.4.22".freeze
18
18
  s.summary = "Needs summary".freeze
@@ -0,0 +1,33 @@
1
+ fr:
2
+ compony:
3
+ cancel: 'Annuler'
4
+ filtered: '[Filtré]' # Not translated as this appears in log
5
+ boolean:
6
+ true: 'Oui'
7
+ false: 'Non'
8
+ feasibility:
9
+ has_dependent_models: 'il existe des %{dependent_class} dépendants'
10
+ model_fields:
11
+ attachment:
12
+ download: 'Télécharger'
13
+ components:
14
+ form:
15
+ submit: 'Envoyer'
16
+ cancel: 'Annuler'
17
+ edit:
18
+ label:
19
+ long: 'Modifier %{data_label}'
20
+ short: 'Modifier'
21
+ data_was_updated: '%{data_label} a été enregistré.'
22
+ new:
23
+ label:
24
+ long: 'Créer %{data_class}'
25
+ short: 'Nouveau'
26
+ data_was_created: '%{data_label} a été créé.'
27
+ destroy:
28
+ label:
29
+ long: 'Supprimer %{data_label}'
30
+ short: 'Supprimer'
31
+ confirm_question: 'Voulez-vous vraiment supprimer %{data_label} ?'
32
+ confirm_button: 'Oui, supprimer'
33
+ data_was_destroyed: '%{data_label} a été supprimé.'
@@ -14,7 +14,7 @@ module Compony
14
14
  end
15
15
 
16
16
  # For internal usage only, processes the block and returns a config hash.
17
- def to_conf(&)
17
+ def to_conf(provide_defaults:, &)
18
18
  return super.deep_merge({
19
19
  load_data_block: @load_data_block,
20
20
  assign_attributes_block: @assign_attributes_block,
@@ -4,11 +4,13 @@ module Compony
4
4
  module Standalone
5
5
  # @api description
6
6
  # Wrapper and DSL helper for component's standalone config
7
+ # Pass `provide_defaults` true if this is the first standalone DSL of a component. Pass false if it is a subsequent one (e.g. if subclassed comp)
7
8
  class StandaloneDsl < Dslblend::Base
8
- def initialize(component, name = nil, path: nil)
9
+ def initialize(component, name = nil, provide_defaults:, path: nil)
9
10
  super()
10
11
  @component = component
11
12
  @name = name&.to_sym
13
+ @provide_defaults = provide_defaults
12
14
  @path = path
13
15
  @verbs = {}
14
16
  @skip_authentication = false
@@ -38,8 +40,17 @@ module Compony
38
40
  def verb(verb, *args, **nargs, &)
39
41
  verb = verb.to_sym
40
42
  verb_dsl_class = @component.resourceful? ? ResourcefulVerbDsl : VerbDsl
41
- @verbs[verb] ||= Compony::MethodAccessibleHash.new
42
- @verbs[verb].deep_merge! verb_dsl_class.new(@component, verb, *args, **nargs).to_conf(&)
43
+ if @verbs[verb]
44
+ @verbs[verb].deep_merge! verb_dsl_class.new(@component, verb, *args, **nargs).to_conf(provide_defaults: false, &)
45
+ else
46
+ # Note about provide_defaults:
47
+ # - We must pass false if this is the second time `standalone` was called for this component -> see @provide_defaults
48
+ # - We musst pass false if this is the second time `verb` was called for this component -> handled by the if statement (other branch)
49
+ # - We must pass true otherwise (handled by this branch)
50
+ @verbs[verb] = Compony::MethodAccessibleHash.new(
51
+ verb_dsl_class.new(@component, verb, *args, **nargs).to_conf(provide_defaults: @provide_defaults, &)
52
+ )
53
+ end
43
54
  end
44
55
 
45
56
  # DSL
@@ -17,18 +17,19 @@ module Compony
17
17
 
18
18
  @component = component
19
19
  @verb = verb
20
- @respond_blocks = { nil => proc { render_standalone(controller) } } # default format
20
+ @respond_blocks = {}
21
21
  @authorize_block = nil
22
22
  end
23
23
 
24
24
  # For internal usage only, processes the block and returns a config hash.
25
- def to_conf(&)
25
+ def to_conf(provide_defaults:, &)
26
26
  evaluate(&) if block_given?
27
- return {
27
+ base_config = provide_defaults ? default_config : {}
28
+ return base_config.deep_merge({
28
29
  verb: @verb,
29
- authorize_block: @authorize_block || proc { can?(comp_name.to_sym, family_name.to_sym) },
30
+ authorize_block: @authorize_block,
30
31
  respond_blocks: @respond_blocks
31
- }.compact
32
+ }.compact)
32
33
  end
33
34
 
34
35
  protected
@@ -45,6 +46,14 @@ module Compony
45
46
  def respond(format = nil, &block)
46
47
  @respond_blocks[format&.to_sym] = block
47
48
  end
49
+
50
+ # Internal, do not use
51
+ def default_config
52
+ return {
53
+ authorize_block: proc { can?(comp_name.to_sym, family_name.to_sym) },
54
+ respond_blocks: { nil => proc { render_standalone(controller) } }
55
+ }
56
+ end
48
57
  end
49
58
  end
50
59
  end
@@ -57,7 +57,7 @@ module Compony
57
57
  end
58
58
 
59
59
  # TODO: Make much prettier, providing message, action, subject and conditions
60
- fail CanCan::AccessDenied, inspect unless request_context.evaluate(&verb_config.authorize_block)
60
+ fail CanCan::AccessDenied, [inspect, verb_config.authorize_block.inspect].join(', ') unless request_context.evaluate(&verb_config.authorize_block)
61
61
 
62
62
  if verb_config.store_data_block
63
63
  request_context.evaluate_with_backfire(&verb_config.store_data_block)
@@ -107,8 +107,11 @@ module Compony
107
107
  def standalone(name = nil, *args, **nargs, &block)
108
108
  block = proc {} unless block_given? # If called without a block, must default to an empty block to provide a binding to the DSL.
109
109
  name = name&.to_sym # nil name is the most common case
110
- @standalone_configs[name] ||= Compony::MethodAccessibleHash.new
111
- @standalone_configs[name].deep_merge! StandaloneDsl.new(self, name, *args, **nargs).to_conf(&block)
110
+ if @standalone_configs[name]
111
+ @standalone_configs[name].deep_merge! StandaloneDsl.new(self, name, *args, provide_defaults: false, **nargs).to_conf(&block)
112
+ else
113
+ @standalone_configs[name] = Compony::MethodAccessibleHash.new(StandaloneDsl.new(self, name, *args, provide_defaults: true, **nargs).to_conf(&block))
114
+ end
112
115
  end
113
116
 
114
117
  # Undoes previous standalone calls
@@ -86,7 +86,7 @@ module Compony
86
86
  if hidden
87
87
  return model_field.simpleform_input_hidden(@simpleform, self, **input_opts)
88
88
  else
89
- unless @focus_given
89
+ unless @focus_given || @skip_autofocus
90
90
  input_opts[:autofocus] = true unless input_opts.key? :autofocus
91
91
  @focus_given = true
92
92
  end
@@ -136,6 +136,11 @@ module Compony
136
136
  fail 'schema requires a block to be given'
137
137
  end
138
138
  end
139
+
140
+ # DSL method, skips adding autofocus to the first field
141
+ def skip_autofocus
142
+ @skip_autofocus = true
143
+ end
139
144
  end
140
145
  end
141
146
  end
@@ -4,6 +4,11 @@ module Compony
4
4
  # This component is destined to take a sub-component that is a form component.
5
5
  # It can be called via :get or via `submit_verb` depending on whether its form should be shown or submitted.
6
6
  class WithForm < Component
7
+ def initialize(...)
8
+ @submit_path_block = ->(controller) { controller.helpers.send("#{Compony.path_helper_name(comp_name, family_name)}_path") }
9
+ super
10
+ end
11
+
7
12
  # Returns an instance of the form component responsible for rendering the form.
8
13
  # Feel free to override this in subclasses.
9
14
  def form_comp
@@ -11,7 +16,7 @@ module Compony
11
16
  self,
12
17
  submit_verb:,
13
18
  # If applicable, Rails adds the route keys automatically, thus, e.g. :id does not need to be passed here, as it comes from the request.
14
- submit_path: ->(controller) { controller.helpers.send("#{Compony.path_helper_name(comp_name, family_name)}_path") }
19
+ submit_path: @submit_path_block
15
20
  )
16
21
  end
17
22
 
@@ -32,6 +37,13 @@ module Compony
32
37
  def form_comp_class(new_form_comp_class = nil)
33
38
  @form_comp_class ||= new_form_comp_class
34
39
  end
40
+
41
+ # DSL method
42
+ # Overrides the submit path which would otherwise default to this component
43
+ # This takes a block that will be called and given a controller
44
+ def submit_path(&new_submit_path_block)
45
+ @submit_path_block = new_submit_path_block
46
+ end
35
47
  end
36
48
  end
37
49
  end
@@ -2,7 +2,7 @@ module Compony
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- PATCH = 0
5
+ PATCH = 1
6
6
 
7
7
  EDGE = false
8
8
 
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.2.0
4
+ version: 0.2.1
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-12-05 00:00:00.000000000 Z
12
+ date: 2024-01-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard
@@ -184,6 +184,7 @@ files:
184
184
  - compony.gemspec
185
185
  - config/locales/de.yml
186
186
  - config/locales/en.yml
187
+ - config/locales/fr.yml
187
188
  - config/routes.rb
188
189
  - doc/resourceful_lifecycle.graphml
189
190
  - doc/resourceful_lifecycle.pdf