render_turbo_stream 1.3.3 → 1.4.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: b32041ebda04bf085c6199ba1e29e5274f9fa86c2a210c7ee6a32e9937721037
4
- data.tar.gz: 32b05f420b1ce6c6733615f2be5059a265ee58bf2c55269363aa14e0d0f41c2e
3
+ metadata.gz: 395968d08aa5420fbd50bb63bccb641098503d33002a36a1a9f753b52caaae2b
4
+ data.tar.gz: 537a3ed1c128c26df63083c545c7ba53c02167c30a38a69adf08261bbb27e069
5
5
  SHA512:
6
- metadata.gz: bfdd0158be7131cdd05e7527b7005b40d90621d9a95919955bdeb58dd0e75cb41d5e7799ad43626f05d690a814600f267b9476e25e3a5b7400be6a8d36a481dd
7
- data.tar.gz: f04d228c519cd617ff53e7292144673eaaf610e879f87fc4a95a6902e487bffab7a84bd0bbff3068a94f138b2c32a17ea91872e45f117c133f1f846029cf3ede
6
+ metadata.gz: a793feeaa175a29b27bd2811f6248de5e5e913224f455547b6fdb5cd1707e36f76d3e2b23824cd3c4a2c7197a5c25e50f99800c355ed0b55c76bae78f127586a
7
+ data.tar.gz: 0d0294aed7dc3c57e580d34a939145c3ccd423a434da2bfad40d8daf7a769b3e4efece554d814a4f533f0eb21fb1efcdba4d223a6fc701106434635bd2e58a32
data/README.md CHANGED
@@ -6,6 +6,8 @@ Working consistently with turbo_stream means shooting lots of partials from the
6
6
 
7
7
  And build it dynamically: Most [turbo_power](https://github.com/marcoroth/turbo_power) commands, such as adding a css class to an html element or pushing a state to the browser history, work directly from the controller. Since turbo allows it, custom javascript functions are also possible.
8
8
 
9
+ ATTENTION: This plugin is in a early state.
10
+
9
11
  An overview of how we design a rails-7 application with turbo
10
12
  is [published on dev.to](https://dev.to/chmich/rails-7-vite-wrapping-up-1pia).
11
13
 
@@ -34,11 +36,6 @@ RSpec.configure do |config|
34
36
  end
35
37
  ```
36
38
 
37
- **Redirection and more**
38
-
39
- For redirection to work, you must follow the installation steps
40
- from [turbo_power](https://github.com/marcoroth/turbo_power).
41
-
42
39
  **Flash**
43
40
 
44
41
  Required Configurations for Flash Partial
@@ -51,16 +48,37 @@ config.x.render_turbo_stream.flash_action = 'prepend'
51
48
 
52
49
  The corresponding partials for flashes could look [like this](https://gitlab.com/sedl/renderturbostream/-/wikis/flashes)
53
50
 
51
+ **Translations**
52
+
53
+ ```
54
+ activerecord.success.successfully_created
55
+ activerecord.success.successfully_updated
56
+ activerecord.errors.messages.could_not_create
57
+ activerecord.errors.messages.could_not_update
58
+ ```
59
+
60
+ example value: `"%<model_name>s successfully created"`
61
+
62
+ Model name translations, see: Rails Docs.
63
+
64
+ **Turbo power**
65
+
66
+ To get redirection and many other options working, you need to follow the installation steps from [turbo_power](https://github.com/marcoroth/turbo_power).
67
+
68
+ **Turbo itself**
69
+
70
+ A comprehensive tutorial on turbo and how to check that it is working properly can be found at [hotrails.dev](https://www.hotrails.dev/turbo-rails).
71
+
54
72
  ## Usage
55
73
 
56
- `turbo_stream_save` is a special method for streamlining `update' or `create' functions with `turbo_stream'. A controller action for update might look like this:
74
+ `turbo_stream_save` is a special method for streamlining `update` or `create` functions with `turbo_stream`. A controller action for update might look like this:
57
75
 
58
76
  ```ruby
59
77
 
60
78
  def update
61
79
  turbo_stream_save(
62
80
  @customer.update(customer_params),
63
- redirect_on_success_to: edit_customer_path(@customer)
81
+ redirect_on_success_to: edit_customer_path(@customer),
64
82
  )
65
83
  end
66
84
  ```
@@ -72,7 +90,7 @@ render_turbo_stream(
72
90
  [
73
91
  {
74
92
  id: 'form',
75
- partial: 'form'
93
+ partial: 'customers/form'
76
94
  },
77
95
  {
78
96
  id: 'flash-wrapper',
@@ -96,7 +114,7 @@ stream_partial(
96
114
 
97
115
  **locals**: The hash for locals goes through a `symbolize_keys`, so you need to use locals in used partials like this: `locals[:message]`.
98
116
 
99
- ## More options
117
+ **More options**
100
118
 
101
119
  `render_turbo_stream` interprets a hash as a partial to be sent by `turbo_stream` and an array as a command to be sent. This allows you to perform most actions from e.g. [turbo_power](https://github.com/marcoroth/turbo_power). An example of adding a css class to an html element and updating the browser history would look like this:
102
120
 
@@ -111,12 +129,45 @@ render_turbo_stream(
111
129
  :add_css_class,
112
130
  '#colored-element',
113
131
  'red'
132
+ ],
133
+ [
134
+
114
135
  ]
115
136
  ]
116
137
  )
117
138
  ```
118
139
 
119
- which is done under the hood, for the array: `= turbo_stream.send args.first, *(args[1..-1])`
140
+ Under the hood, inside a `*.turbo_stream.erb` template, it does the following: `= turbo_stream.send args.first, *(args[1..-1])`
141
+
142
+ **Parameters for turbo_stream_save**
143
+
144
+ save_action,
145
+ redirect_on_success_to: nil,
146
+ object: nil, # object used in save_action, example: @customer
147
+ id: 'form', # if nil: no partial is rendered
148
+ partial: nil, # example: 'customers/form' default: "#{controller_path}/#{id}"
149
+ action: 'replace', # options: append, prepend
150
+ locals: {}, # locals used by the partial
151
+ streams_on_success: [
152
+ {
153
+ id: nil,
154
+ partial: 'form',
155
+ locals: {},
156
+ action: 'replace'
157
+ }
158
+ ], # additional partials that should be rendered if save_action succeeded
159
+ streams_on_error: [
160
+ {
161
+ id: nil,
162
+ partial: 'form',
163
+ locals: {},
164
+ action: 'replace'
165
+ }
166
+ ], # additional partials that should be rendered if save_action failed
167
+ add_flash_alerts: [], #=> array of strings
168
+ add_flash_notices: [], #=> array of strings
169
+ flashes_on_success: [], #=> array of strings
170
+ flashes_on_error: [] #=> array of strings
120
171
 
121
172
 
122
173
  ## Testing Scenarios
@@ -126,7 +177,7 @@ For system testing there is Capybara. Its the only way to check if frontend and
126
177
  If the request format is not `turbo_stream`, which is the case on request specs, the method responds in a special html
127
178
  that contains the medadata that is interesting for our tests and is parsed by included test helpers.
128
179
 
129
- There is a helper for writing the test: In the debugger, within the test, check the output of `partials_log`.
180
+ There is a helper for writing the test: In the debugger, within the test, check the output of `streams_log`.
130
181
 
131
182
  Test scenarios are:
132
183
 
@@ -141,7 +192,7 @@ For rspec there is a special helper, for a successful save action:
141
192
  ```ruby
142
193
  it 'update failed' do
143
194
  patch article_path(article, params: valid_params)
144
- expect_successful_saved('form', 'flash-box')
195
+ expect_successful_saved('customer-form', 'flash-box')
145
196
  # expects response.status 200
146
197
  # Make sure that the responses point to exactly these 2 IDs ('form' and 'flash-box').
147
198
  # Make sure that each ID is responded to exactly once.
@@ -160,13 +211,13 @@ end
160
211
 
161
212
  For checking a little more inside the partial responses, but with a simple syntax that checks for a one-time response from a specific partial and may be sufficient for most cases:
162
213
  ```ruby
163
- expect(partials_count).to eq(2)
164
- # Check the total number of responding partials, in most cases it will be one form and one flash.
214
+ expect(stream_targets_count).to eq(2)
215
+ # Check the total number of targeted html-ids, in most cases it will be one form and one flash.
165
216
 
166
- expect(partial_response('form')).to eq(true)
167
- # Make sure that the form part (controller_path is not checked) has responded exactly once.
217
+ expect(stream_response('customer-form')).to eq(true)
218
+ # Make sure that the id «customer-form» is targeted exactly once.
168
219
 
169
- expect(partial_response('articles/form', id: 'form', css: '.field_with_errors', include_string: 'Title')).to eq(true)
220
+ expect(stream_response('customer-form', css: '.field_with_errors', include_string: 'Title')).to eq(true)
170
221
  # Check the content inside at least one in any of the elements that match the given css and check the id that turbo has pointed to..
171
222
  ```
172
223
 
@@ -175,21 +226,21 @@ expect(partial_response('articles/form', id: 'form', css: '.field_with_errors',
175
226
  Consider a controller action that should respond in 2 flashes:
176
227
 
177
228
  ```ruby
178
- expect(partials_count).to eq(1)
229
+ expect(stream_targets_count).to eq(1)
179
230
 
180
231
  expect(
181
- partial_response_count('flash', total: 2) do |p|
232
+ stream_target_response_count('flash-box', total: 2) do |p|
182
233
  p.css('.callout.success').inner_html.include?('All perfect')
183
234
  end
184
235
  ).to eq(1)
185
236
 
186
237
  expect(
187
- partial_response_count('layouts/flash', id: 'flash-box', total: 2) do |p|
238
+ stream_target_response_count('flash-box', total: 2) do |p|
188
239
  p.css('.callout.alert').inner_html.include?('Something went wrong')
189
240
  end
190
241
  ).to eq(1)
191
242
  ```
192
- `partial_response_count` always returns the number of matched responses.
243
+ `stream_target_response_count` always returns the number of matched responses.
193
244
 
194
245
  Possible matchers can be found at [Nokogiri](https://nokogiri.org/tutorials/searching_a_xml_html_document.html). That should be enough for this level. For more detailed testing of partials, there are view tests. And many of the partials are regularly accessed in two ways, for example a `form': it is pushed by turbo_stream as well as by calling edit_customer_path.
195
246
 
@@ -198,54 +249,6 @@ P.S.:
198
249
  Testing the plugin itself: There is a [quick-and-dirty app](https://gitlab.com/sedl/renderturbostream_railsapp) which
199
250
  includes the plugin and has tests done by rspec/request and capybara.
200
251
 
201
- ## Parameters for turbo_stream_save
202
-
203
- save_action,
204
- redirect_on_success_to: nil,
205
- object: nil, # object used in save_action, example: @customer
206
- id: 'form', # if nil: no partial is rendered
207
- partial: nil, # example: 'customers/form' default: "#{controller_path}/#{id}"
208
- action: 'replace', # options: append, prepend
209
- locals: {}, # locals used by the partial
210
- streams_on_success: [
211
- {
212
- id: nil,
213
- partial: 'form',
214
- locals: {},
215
- action: 'replace'
216
- }
217
- ], # additional partials that should be rendered if save_action succeeded
218
- streams_on_error: [
219
- {
220
- id: nil,
221
- partial: 'form',
222
- locals: {},
223
- action: 'replace'
224
- }
225
- ], # additional partials that should be rendered if save_action failed
226
- add_flash_alerts: [], #=> array of strings
227
- add_flash_notices: [], #=> array of strings
228
- flashes_on_success: [], #=> array of strings
229
- flashes_on_error: [] #=> array of strings
230
-
231
- ## Requirements
232
-
233
- gem `turbo_power` (is included, used for redirection)
234
-
235
- **Translations**
236
-
237
- `activerecord.success.successfully_created`
238
-
239
- `activerecord.success.successfully_updated`
240
-
241
- `activerecord.errors.messages.could_not_create`
242
-
243
- `activerecord.errors.messages.could_not_update`
244
-
245
- example value: `"%<model_name>s successfully created"`
246
-
247
- .. and Model Name Translations
248
-
249
252
  ## Contributing
250
253
 
251
254
  Contribution welcome.
@@ -0,0 +1,49 @@
1
+ <% error = false %>
2
+ <% control = [] %>
3
+ <% streams = local_assigns[:streams] %>
4
+ <% streams.each do |args| %>
5
+
6
+
7
+ <% if args.is_a?(Array) %>
8
+
9
+ <% ctl = "turbo_stream.#{args.first}, #{args[1..-1].join(', ')}" %>
10
+
11
+ <% if args.last.is_a?(Proc) %>
12
+ <% Rails.logger.error(" RENDER TURBO STREAM BLOCK => #{ctl}") %>
13
+ <%#= turbo_stream.replace 'form' do %>
14
+ <%#= render partial: 'articles/form' %>
15
+ <%# end %>
16
+ <%= turbo_stream.send args.first, *(args[1..-2]) { args.last.call } %>
17
+ <% else %>
18
+ <% Rails.logger.error(" RENDER TURBO POWER => #{ctl}") %>
19
+ <%= turbo_stream.send args.first, *(args[1..-1]) %>
20
+ <% end %>
21
+
22
+ <% else %>
23
+ <% ctl = { partial: args[:partial], id: args[:id], action: args[:action] } %>
24
+ <% info = { id: args[:id], partial: args[:partial], locals: args[:locals] } %>
25
+ <% if !args[:action].present? %>
26
+ <% Rails.logger.error(" ERROR RENDER TURBO STREAM => MISSING ACTION => #{args}") %>
27
+ <% error = true %>
28
+
29
+ <% elsif args[:action].present? %>
30
+ <% Rails.logger.debug(" • render-turbo-stream #{args[:action].upcase} => #{info}") %>
31
+ <%= turbo_stream.send args[:action].to_sym, args[:id] do %>
32
+ <%= render args[:partial], locals: args[:locals]&.symbolize_keys %>
33
+ <% end %>
34
+
35
+ <% else %>
36
+ <% Rails.logger.error(" ERROR RENDER TURBO STREAM => NOTHING DONE! => #{args}") %>
37
+ <% end %>
38
+ <% end %>
39
+
40
+ <% control.push(ctl) %>
41
+
42
+ <% end %>
43
+
44
+ <% if error %>
45
+ <% Rails.logger.error(" RENDER TURBO STREAM HAD ERRORS, REPEATING WHOLE ARRAY: ") %>
46
+ <% control.each do |c| %>
47
+ <% Rails.logger.error(" #{c}") %>
48
+ <% end %>
49
+ <% end %>
@@ -6,6 +6,7 @@
6
6
  <% rendered_partials.push({ command: "turbo_stream.#{s.first}, #{s[1..-1].join(', ')}", method: s.first, attributes: s[1..-1] }) %>
7
7
  <% else %>
8
8
  <% html = (render s[:partial], locals: s[:locals]&.symbolize_keys, formats: [:html]) %>
9
+ <% s.delete(:partial) %>
9
10
  <% rendered_partials.push({ html_response: html }.merge(s)) %>
10
11
  <% end %>
11
12
 
@@ -2,16 +2,8 @@ module RenderTurboStream
2
2
  module Test
3
3
  module RequestHelpers
4
4
 
5
- # count of rendered partials
6
- # count rendering different partials (example: «customer/form»)
7
- # doesnt check how often a specific partial is rendered
8
-
9
- def partials_count
10
- RenderTurboStream::Libs.partials_count(response)
11
- end
12
-
13
5
  # log as helper for the developer to see which flash is set and which partials are rendered to wich ids
14
- def partials_log
6
+ def streams_log
15
7
  all_responses = RenderTurboStream::Libs.all_responses(response)
16
8
  r = []
17
9
  if response.status == 302
@@ -48,12 +40,12 @@ module RenderTurboStream
48
40
  url
49
41
  end
50
42
 
51
- def partial_response_count(partial, id: nil, total: 1, &block)
52
- RenderTurboStream::Libs.partial_response_count(response, partial, id, total, &block)
43
+ def stream_target_response_count(id, total: 1, &block)
44
+ RenderTurboStream::Libs.stream_target_response_count(response, id, total, &block)
53
45
  end
54
46
 
55
- def partial_response(partial, id: nil, css: nil, include_string: nil)
56
- c = partial_response_count(partial, id: id, total: 1) do |r|
47
+ def stream_response(id, css: nil, include_string: nil)
48
+ c = stream_target_response_count(id, total: 1) do |r|
57
49
  if css && include_string
58
50
  r.css(css).inner_html.include?(include_string)
59
51
  elsif include_string
@@ -67,8 +59,12 @@ module RenderTurboStream
67
59
  c == 1
68
60
  end
69
61
 
70
- def partial_ids
71
- RenderTurboStream::Libs.partial_ids(response)
62
+ def stream_targets
63
+ RenderTurboStream::Libs.stream_targets(response)
64
+ end
65
+
66
+ def stream_targets_count
67
+ stream_targets.length
72
68
  end
73
69
  end
74
70
  end
@@ -1,3 +1,3 @@
1
1
  module RenderTurboStream
2
- VERSION = "1.3.3"
2
+ VERSION = "1.4.1"
3
3
  end
@@ -126,12 +126,12 @@ module RenderTurboStream
126
126
  response.status = 302
127
127
  flash[:alert] = flash_alerts
128
128
  flash[:notice] = flash_notices
129
- render_turbo_stream([
130
- [
131
- :redirect_to,
132
- redirect_on_success_to
133
- ]
134
- ])
129
+ render_turbo_stream([
130
+ [
131
+ :redirect_to,
132
+ redirect_on_success_to
133
+ ]
134
+ ])
135
135
  else
136
136
  flash.now[:alert] = flash_alerts
137
137
  flash.now[:notice] = flash_notices
@@ -191,40 +191,20 @@ module RenderTurboStream
191
191
 
192
192
  # if partial is one word, its checked against the last behind the slash, example: 'articles/form' matches 'form'
193
193
 
194
- def self.select_responses(response, partial, id)
194
+ def self.select_responses(response, id)
195
195
  all = all_responses(response)
196
196
 
197
197
  all.select do |a|
198
- partial_matched = if !partial.present?
199
- false
200
- elsif partial.include?('/')
201
- a['partial'] == partial
202
- else
203
- a['partial'].split('/').last == partial
204
- end
205
- id_matched = if !id.present?
206
- false
207
- else
208
- a['id'] == id
209
- end
210
- partial_matched && (id.present? ? id_matched : true)
211
- end
212
-
213
- end
214
-
215
- def self.partials_count(response)
216
- all = all_responses(response)
217
- part = []
218
- all.each do |p|
219
- _p = p['partial']
220
- unless part.include?(_p)
221
- part.push(_p)
198
+ if id.present?
199
+ a['id'] == id
200
+ else
201
+ false
222
202
  end
223
203
  end
224
- part.length
204
+
225
205
  end
226
206
 
227
- def self.partial_ids(response)
207
+ def self.stream_targets(response)
228
208
  all = all_responses(response)
229
209
  ids = []
230
210
  all.each do |p|
@@ -236,8 +216,8 @@ module RenderTurboStream
236
216
  ids
237
217
  end
238
218
 
239
- def self.partial_response_count(response, partial, id, total, &block)
240
- responses = select_responses(response, partial, id)
219
+ def self.stream_target_response_count(response, id, total, &block)
220
+ responses = select_responses(response, id)
241
221
 
242
222
  if total && responses.count != total
243
223
  false
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: render_turbo_stream
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - christian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-23 00:00:00.000000000 Z
11
+ date: 2023-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -38,6 +38,7 @@ files:
38
38
  - README.md
39
39
  - Rakefile
40
40
  - app/controllers/render_turbo_stream/application_controller.rb
41
+ - app/views/_render_turbo_stream.turbo_stream.erb
41
42
  - app/views/render_turbo_stream.html.erb
42
43
  - app/views/render_turbo_stream.turbo_stream.erb
43
44
  - lib/render_turbo_stream.rb