compony 0.2.0 → 0.2.1

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: 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