compony 0.3.0 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +10 -0
- data/VERSION +1 -1
- data/compony.gemspec +3 -3
- data/doc/ComponentGenerator.html +1 -1
- data/doc/Components.html +1 -1
- data/doc/ComponentsGenerator.html +1 -1
- data/doc/Compony/Component.html +244 -56
- 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 +1 -1
- 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 +2 -2
- data/doc/Compony/Components/Destroy.html +14 -14
- data/doc/Compony/Components/Edit.html +18 -18
- data/doc/Compony/Components/Form.html +86 -86
- data/doc/Compony/Components/New.html +14 -14
- data/doc/Compony/Components/WithForm.html +2 -2
- 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 +1 -1
- data/doc/Compony/NaturalOrdering.html +14 -6
- data/doc/Compony/RequestContext.html +16 -4
- data/doc/Compony/Version.html +1 -1
- data/doc/Compony/ViewHelpers.html +1 -1
- data/doc/Compony.html +1 -1
- data/doc/ComponyController.html +1 -1
- data/doc/_index.html +1 -1
- data/doc/file.README.html +10 -1
- data/doc/index.html +10 -1
- data/doc/method_list.html +16 -0
- data/doc/top-level-namespace.html +1 -1
- data/lib/compony/component.rb +25 -2
- data/lib/compony/components/destroy.rb +9 -1
- data/lib/compony/components/edit.rb +4 -0
- data/lib/compony/components/form.rb +16 -5
- data/lib/compony/components/new.rb +1 -0
- data/lib/compony/natural_ordering.rb +6 -2
- data/lib/compony/request_context.rb +8 -2
- metadata +2 -2
data/doc/file.README.html
CHANGED
@@ -555,6 +555,15 @@
|
|
555
555
|
<pre class="code ruby"><code class="ruby"><div class="card card-body"><h1>Hello</h1><p>Welcome to my site.</p></div>
|
556
556
|
</code></pre>
|
557
557
|
|
558
|
+
<h5 id="label-Removing+content+blocks">Removing content blocks</h5>
|
559
|
+
|
560
|
+
<p>If a component’s parent class defines a content block that is undesired in a subclass component, the content block can be removed as follows:</p>
|
561
|
+
|
562
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
|
563
|
+
<span class='id identifier rubyid_remove_content'>remove_content</span> <span class='symbol'>:some_content_defined_in_parent</span> <span class='comment'># This component will now behave as if this content block was never declared in its parent.
|
564
|
+
</span><span class='kw'>end</span>
|
565
|
+
</code></pre>
|
566
|
+
|
558
567
|
<h4 id="label-Redirecting+away+-2F+Intercepting+rendering">Redirecting away / Intercepting rendering</h4>
|
559
568
|
|
560
569
|
<p>Immediately before the <code>content</code> block(s) are evaluated, another chain of blocks is evaluated if present: <code>before_render</code>. If on of these blocks creates a reponse body in the Rails controller, the subsequent <code>before_render</code> blocks and all <code>content</code> blocks are skipped.</p>
|
@@ -1612,7 +1621,7 @@ my_button = Compony.button(:index, :users, enabled: -> { |controller| control
|
|
1612
1621
|
</div></div>
|
1613
1622
|
|
1614
1623
|
<div id="footer">
|
1615
|
-
Generated on
|
1624
|
+
Generated on Sat Jun 1 14:22:42 2024 by
|
1616
1625
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
1617
1626
|
0.9.34 (ruby-3.2.2).
|
1618
1627
|
</div>
|
data/doc/index.html
CHANGED
@@ -555,6 +555,15 @@
|
|
555
555
|
<pre class="code ruby"><code class="ruby"><div class="card card-body"><h1>Hello</h1><p>Welcome to my site.</p></div>
|
556
556
|
</code></pre>
|
557
557
|
|
558
|
+
<h5 id="label-Removing+content+blocks">Removing content blocks</h5>
|
559
|
+
|
560
|
+
<p>If a component’s parent class defines a content block that is undesired in a subclass component, the content block can be removed as follows:</p>
|
561
|
+
|
562
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
|
563
|
+
<span class='id identifier rubyid_remove_content'>remove_content</span> <span class='symbol'>:some_content_defined_in_parent</span> <span class='comment'># This component will now behave as if this content block was never declared in its parent.
|
564
|
+
</span><span class='kw'>end</span>
|
565
|
+
</code></pre>
|
566
|
+
|
558
567
|
<h4 id="label-Redirecting+away+-2F+Intercepting+rendering">Redirecting away / Intercepting rendering</h4>
|
559
568
|
|
560
569
|
<p>Immediately before the <code>content</code> block(s) are evaluated, another chain of blocks is evaluated if present: <code>before_render</code>. If on of these blocks creates a reponse body in the Rails controller, the subsequent <code>before_render</code> blocks and all <code>content</code> blocks are skipped.</p>
|
@@ -1612,7 +1621,7 @@ my_button = Compony.button(:index, :users, enabled: -> { |controller| control
|
|
1612
1621
|
</div></div>
|
1613
1622
|
|
1614
1623
|
<div id="footer">
|
1615
|
-
Generated on
|
1624
|
+
Generated on Sat Jun 1 14:22:41 2024 by
|
1616
1625
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
1617
1626
|
0.9.34 (ruby-3.2.2).
|
1618
1627
|
</div>
|
data/doc/method_list.html
CHANGED
@@ -932,6 +932,22 @@
|
|
932
932
|
</li>
|
933
933
|
|
934
934
|
|
935
|
+
<li class="even ">
|
936
|
+
<div class="item">
|
937
|
+
<span class='object_link'><a href="Compony/Component.html#remove_content-instance_method" title="Compony::Component#remove_content (method)">#remove_content</a></span>
|
938
|
+
<small>Compony::Component</small>
|
939
|
+
</div>
|
940
|
+
</li>
|
941
|
+
|
942
|
+
|
943
|
+
<li class="odd ">
|
944
|
+
<div class="item">
|
945
|
+
<span class='object_link'><a href="Compony/Component.html#remove_content!-instance_method" title="Compony::Component#remove_content! (method)">#remove_content!</a></span>
|
946
|
+
<small>Compony::Component</small>
|
947
|
+
</div>
|
948
|
+
</li>
|
949
|
+
|
950
|
+
|
935
951
|
<li class="even ">
|
936
952
|
<div class="item">
|
937
953
|
<span class='object_link'><a href="Compony/Component.html#render-instance_method" title="Compony::Component#render (method)">#render</a></span>
|
@@ -102,7 +102,7 @@
|
|
102
102
|
</div>
|
103
103
|
|
104
104
|
<div id="footer">
|
105
|
-
Generated on
|
105
|
+
Generated on Sat Jun 1 14:22:42 2024 by
|
106
106
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
107
107
|
0.9.34 (ruby-3.2.2).
|
108
108
|
</div>
|
data/lib/compony/component.rb
CHANGED
@@ -130,8 +130,31 @@ module Compony
|
|
130
130
|
# @param [Hash] kwargs If hidden is true, the content will not be rendered by default, allowing you to nest it in another content block.
|
131
131
|
# @param [Proc] block The block that should be run as part of the content pipeline. Will run in the component's context. You can use Dyny here.
|
132
132
|
def content(name = :main, before: nil, **kwargs, &block)
|
133
|
-
|
134
|
-
@content_blocks.
|
133
|
+
# A block is required here, but if this is an override (e.g. to hide another content block), we can tolerate the missing block.
|
134
|
+
if !block_given? && @content_blocks.find { |b| b.name == name }.nil?
|
135
|
+
fail("`content` expects a block in #{inspect}.")
|
136
|
+
end
|
137
|
+
@content_blocks.natural_push(name, block || :missing, before:, **kwargs)
|
138
|
+
end
|
139
|
+
|
140
|
+
# DSL method
|
141
|
+
# Removes a content block. Use this in subclasses if a content block defined in the parent should be removed from the child.
|
142
|
+
# @param [Symbol,String] name Name of the content block that should be removed
|
143
|
+
def remove_content(name)
|
144
|
+
existing_index = @content_blocks.find_index { |el| el.name == name.to_sym }
|
145
|
+
if existing_index.nil?
|
146
|
+
return false
|
147
|
+
else
|
148
|
+
@content_blocks.delete_at(existing_index)
|
149
|
+
return true
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# DSL method
|
154
|
+
# Removes a content block and fails if the content block was not found.
|
155
|
+
# @param [Symbol,String] name Name of the content block that should be removed
|
156
|
+
def remove_content!(name)
|
157
|
+
remove_content(name) || fail("Content block #{name.inspect} not found for removal in #{inspect}.")
|
135
158
|
end
|
136
159
|
|
137
160
|
# Renders the component using the controller passsed to it and returns it as a string.
|
@@ -26,8 +26,11 @@ module Compony
|
|
26
26
|
icon { :trash }
|
27
27
|
color { :danger }
|
28
28
|
|
29
|
-
content do
|
29
|
+
content :confirm_question, hidden: true do
|
30
30
|
div I18n.t('compony.components.destroy.confirm_question', data_label: @data.label)
|
31
|
+
end
|
32
|
+
|
33
|
+
content :confirm_button, hidden: true do
|
31
34
|
div do
|
32
35
|
concat compony_button(comp_cst,
|
33
36
|
@data,
|
@@ -36,6 +39,11 @@ module Compony
|
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
42
|
+
content do
|
43
|
+
content :confirm_question
|
44
|
+
content :confirm_button
|
45
|
+
end
|
46
|
+
|
39
47
|
action :back_to_owner do
|
40
48
|
next if data_class.owner_model_attr.blank?
|
41
49
|
Compony.button(:show, @data.send(data_class.owner_model_attr), icon: :xmark, color: :secondary, label: I18n.t('compony.cancel'))
|
@@ -35,6 +35,10 @@ module Compony
|
|
35
35
|
Compony.button(:show, @data.send(data_class.owner_model_attr), icon: :xmark, color: :secondary, label: I18n.t('compony.cancel'))
|
36
36
|
end
|
37
37
|
|
38
|
+
content :label do
|
39
|
+
h2 component.label
|
40
|
+
end
|
41
|
+
|
38
42
|
content do
|
39
43
|
concat form_comp.render(controller, data: @data)
|
40
44
|
end
|
@@ -13,19 +13,30 @@ module Compony
|
|
13
13
|
# Make sure the error message is going to be nice if form_fields were not implemented
|
14
14
|
fail "#{component.inspect} requires config.form_fields do ..." if @form_fields.nil?
|
15
15
|
|
16
|
-
#
|
17
|
-
@submit_button = Compony.button_component_class.new(
|
18
|
-
label: @submit_label || I18n.t('compony.components.form.submit'), icon: 'arrow-right', type: :submit
|
19
|
-
).render(controller)
|
16
|
+
# Calculate paths
|
20
17
|
@submit_path = @comp_opts[:submit_path]
|
21
18
|
@submit_path = @submit_path.call(controller) if @submit_path.respond_to?(:call)
|
22
19
|
end
|
23
20
|
|
21
|
+
# Override this to provide a custom submit button
|
22
|
+
content :submit_button, hidden: true do
|
23
|
+
concat Compony.button_component_class.new(
|
24
|
+
label: @submit_label || I18n.t('compony.components.form.submit'), icon: 'arrow-right', type: :submit
|
25
|
+
).render(controller)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Override this to provide additional submit buttons.
|
29
|
+
content :buttons, hidden: true do
|
30
|
+
content(:submit_button)
|
31
|
+
end
|
32
|
+
|
24
33
|
content do
|
25
34
|
form_html = simple_form_for(data, method: @comp_opts[:submit_verb], url: @submit_path) do |f|
|
26
35
|
component.with_simpleform(f) do
|
27
36
|
instance_exec(&form_fields)
|
28
|
-
div
|
37
|
+
div class: 'compony-form-buttons' do
|
38
|
+
content(:buttons)
|
39
|
+
end
|
29
40
|
end
|
30
41
|
end
|
31
42
|
concat form_html
|
@@ -15,21 +15,25 @@ module Compony
|
|
15
15
|
# collection.map(&:payload) # --> a_new_payload, b_payload, c_payload, d_payload
|
16
16
|
# ```
|
17
17
|
class NaturalOrdering < Array
|
18
|
-
def natural_push(name, payload, before: nil, **kwargs)
|
18
|
+
def natural_push(name, payload = :missing, before: nil, **kwargs)
|
19
19
|
name = name.to_sym
|
20
20
|
before_name = before&.to_sym
|
21
21
|
old_kwargs = {}
|
22
|
+
old_payload = nil
|
22
23
|
|
23
24
|
# Fetch existing element if any
|
24
25
|
existing_index = find_index { |el| el.name == name }
|
25
26
|
if existing_index.present?
|
26
27
|
# Copy all non-mentionned kwargs from the element we are about to overwrite
|
27
28
|
old_kwargs = self[existing_index].except(:name, :payload)
|
29
|
+
old_payload = self[existing_index].payload
|
28
30
|
|
29
31
|
# Replacing an existing element with a before: directive - must delete before calculating indices
|
30
32
|
if before_name.present?
|
31
33
|
delete_at(existing_index)
|
32
34
|
end
|
35
|
+
elsif payload == :missing
|
36
|
+
fail("Cannot insert new element #{name} without a payload (payload can only omitted if overriding another element) in #{inspect}.")
|
33
37
|
end
|
34
38
|
|
35
39
|
# Fetch before element
|
@@ -38,7 +42,7 @@ module Compony
|
|
38
42
|
end
|
39
43
|
|
40
44
|
# Create the element to insert
|
41
|
-
element = MethodAccessibleHash.new(name:, payload
|
45
|
+
element = MethodAccessibleHash.new(name:, payload: payload == :missing ? old_payload : payload, **old_kwargs.merge(kwargs))
|
42
46
|
|
43
47
|
# Insert new element
|
44
48
|
if before_index.present?
|
@@ -46,8 +46,14 @@ module Compony
|
|
46
46
|
def content(name)
|
47
47
|
name = name.to_sym
|
48
48
|
content_block = component.content_blocks.find { |el| el.name == name } || fail("Content block #{name.inspect} not found in #{component.inspect}.")
|
49
|
-
#
|
50
|
-
concat
|
49
|
+
# We have to clear Rails' output_buffer to prevent double rendering of blocks. To achieve this, a fresh render context is instanciated.
|
50
|
+
concat controller.render_to_string(
|
51
|
+
type: :dyny,
|
52
|
+
locals: { render_component: component, render_controller: controller, render_locals: local_assigns, render_block: content_block },
|
53
|
+
inline: <<~RUBY
|
54
|
+
Compony::RequestContext.new(render_component, render_controller, helpers: self, locals: local_assigns).evaluate_with_backfire(&render_block.payload)
|
55
|
+
RUBY
|
56
|
+
)
|
51
57
|
end
|
52
58
|
end
|
53
59
|
end
|
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.3.
|
4
|
+
version: 0.3.2
|
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: 2024-
|
12
|
+
date: 2024-06-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yard
|