render_turbo_stream 0.1.8 → 0.1.11

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: 93ea378b3fcabb60e509afd570ae79057abaa7934aaa704a3e6f3017557bdc3b
4
- data.tar.gz: 14c6460671e43085d8927ea3cf95faba112be455a154239aa1624f53a032a03d
3
+ metadata.gz: fbc78913dcbad95c4f8de2b0188ab6eff2db1ac2390590a491427af071f2fa55
4
+ data.tar.gz: c2d381f27a631862490811f5c140f91245370ad3b1b82e3ba41771707adae732
5
5
  SHA512:
6
- metadata.gz: 1595c9345ff6e72ac7e101d47ddb614e8132b9cce2a81ecb6ea193c33ee96d0176bc45b240492bee89cddf736d3320c0f8577fa6459a681f75a0fe87dca30aca
7
- data.tar.gz: 701ba29b3c926f4926213df8e2175582ed0d276cab6f469b33d830ae9039784cd97bd6cbad6d024e1619df7ff0f9df28d6f4ab65ab9867045f24cbbeda47ea1b
6
+ metadata.gz: 5873014fd22b2b1d4d2ded650f37bdc5f6e865ada01608c82ad2c891199c1e342bb6e7a4d94319c6e92c0cfea196fb19230cdebc931915fb2b2e420cc3ab1653
7
+ data.tar.gz: 854105573f8b7a5b8f34ac031d93c4e0a01eb2f5b4263a1495cfac17d53a391431c0ec5a339a5666e4ec8340d029218c2914501fba1a65869508185661d0eab9
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # RenderTurboStream
2
2
 
3
- Creating a gem currently is not possible because of [rails issue](https://github.com/rails/rails/issues/47954)
3
+ The machine gun for your turbo-stream partials.
4
4
 
5
- So, applying this idea is currently only possible by copy and paste a method and a view, see below.
5
+ Creating a gem from this is in work, see [rails issue](https://github.com/rails/rails/issues/47954)
6
6
 
7
- Working consistently by turbo_stream means: shooting a lot of partials to the html which always needs the same attributes: ID, partial and maybe some locals. This gem is a attempt to serialize that, especially for `update` and `create` action.
7
+ Defining templates like `update.turbo_stream.haml` annoyed me.
8
8
 
9
- Logic is better placed inside the controller, instead of the view and it's boring to write always the same `ifs` inside the `update.turbo_stream.haml`. So this gem holds a `.turbo_stream.html.erb` view that loops through all the partials that should be rendered.
9
+ Working consistently by turbo_stream means: shooting many partials to the frontend which always needs the same attributes: ID, partial and maybe some locals. This gem serializes that: Partials can be steered directly from the controller.
10
10
 
11
- In 90% of cases you have just define your partials, like `_form.haml` and steer them from the controller directly, without a `.turbo_stream.haml` view.
11
+ Currently it is only possible by copy and paste the code, see below.
12
12
 
13
13
  ## Installation
14
14
 
@@ -24,36 +24,74 @@ The corresponding partials for flashes could look [like this](https://gitlab.com
24
24
 
25
25
  ## Usage
26
26
 
27
+ `turbo_stream_save` is a special method for streamline `update` or `create` functions for `turbo_stream`, which could look like so:
28
+
27
29
  ```ruby
28
30
  def create
29
31
  @customer = Customer.new(customer_params)
30
32
 
31
- render_turbo_stream(
33
+ turbo_stream_save(
32
34
  @customer.save,
33
- redirect_on_success_to: edit_customer_path(@customer),
34
- id: 'customer-form-wrapper',
35
- partial: 'customer_form',
35
+ redirect_on_success_to: edit_customer_path(@customer)
36
36
  )
37
37
 
38
38
  end
39
39
  ```
40
40
 
41
- and its done!
41
+ This sets a status, generates a flash message and performs `stream_partials`, which could result like that:
42
+
43
+ ```ruby
44
+ stream_partials(
45
+ [
46
+ {
47
+ id: 'form',
48
+ partial: 'form'
49
+ },
50
+ {
51
+ id: 'flash-wrapper',
52
+ partial: 'layouts/flashes',
53
+ action: :prepend
54
+ }
55
+ ]
56
+ )
57
+ ```
42
58
 
43
- in 90% use cases it should be enough and not necessary writing any code inside `update.turbo_stream.haml` or `create.turbo_stream.haml`
59
+ The `stream_partial` method is nothing else than a singular of `stream_partials`
60
+
61
+ ```ruby
62
+ stream_partial(
63
+ id,
64
+ partial: nil, #=> default: id.gsub('-','_')
65
+ locals: {},
66
+ action: nil #=> default: :replace
67
+ )
68
+ ```
44
69
 
45
70
  ## Testing
46
71
 
47
- Testing by regular `rspec` request specs the controller is rendering classic html templates, not turbo_stream. For that html templates are rendered, but only with hints so that your test can check which action is done.
72
+ For system testing you need capybara.
48
73
 
49
- It has 3 cases of output with its resulting status codes which can be checked by rspec:
74
+ For enabling request specs:
75
+ If `request.format` is not `turbo_stream` the method responds as `json` with status:
50
76
 
51
77
  Success and redirection: `302`
52
-
53
78
  Success without redirection: `200`
54
-
55
79
  Save Action failed: `422` `:unprocessable_entity`
56
80
 
81
+ Testing the `response.body` by rspec could look like this:
82
+
83
+ ```ruby
84
+ it 'update failed' do
85
+ a = FactoryBot.create(:article)
86
+ patch article_path(a, params: invalid_params)
87
+ expect(response.status).to eq(422)
88
+ h = JSON.parse(response.body)
89
+ expect(h['form']['partial']).to eq('articles/form')
90
+ expect(h['flash-box']['partial']).to eq('layouts/flash')
91
+ expect(h.keys.length).to eq(2)
92
+ end
93
+ ```
94
+
57
95
  ## Parameters
58
96
 
59
97
  `save_action` (first parameter, boolean) true if successful
@@ -84,7 +122,7 @@ Save Action failed: `422` `:unprocessable_entity`
84
122
 
85
123
  gem `turbo_power` (is included, used for redirection)
86
124
 
87
- **Translations used**
125
+ **Translations**
88
126
 
89
127
  `activerecord.success.successfully_created`
90
128
 
@@ -94,6 +132,8 @@ gem `turbo_power` (is included, used for redirection)
94
132
 
95
133
  `activerecord.errors.messages.could_not_update`
96
134
 
135
+ example value: `"%<model_name>s successfully created"`
136
+
97
137
  .. and Model Name Translations
98
138
 
99
139
  **Flash configuration**
@@ -0,0 +1,4 @@
1
+ module RenderTurboStream
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,52 @@
1
+ <% error = false %>
2
+ <% control = [] %>
3
+ <% local_assigns[:streams].each do |s| %>
4
+ <% ctl = { partial: s[:partial], id: s[:id] } %>
5
+ <% info = { id: s[:id], partial: s[:partial], locals: s[:locals] } %>
6
+
7
+ <% if !s[:id] %>
8
+ <% Rails.logger.error(" ERROR RENDER TURBO STREAM => MISSING ID => #{s}") %>
9
+ <% error = true %>
10
+
11
+ <% elsif !s[:partial].present? %>
12
+ <% Rails.logger.error(" ERROR RENDER TURBO STREAM => MISSING PARTIAL => #{s}") %>
13
+ <% error = true %>
14
+ <% ctl[:partial] = nil %>
15
+
16
+ <% elsif s[:action].to_sym == :replace %>
17
+ <% ctl[:action] = :replace %>
18
+ <% Rails.logger.debug(" • render-turbo-stream REPLACE => #{info}") %>
19
+ <%= turbo_stream.replace s[:id] do %>
20
+ <%= render s[:partial], locals: s[:locals] %>
21
+ <% end %>
22
+
23
+ <% elsif s[:action].to_sym == :prepend %>
24
+ <% ctl[:action] = :prepend %>
25
+ <% Rails.logger.debug(" • render-turbo-stream PREPEND => #{info}") %>
26
+ <%= turbo_stream.prepend s[:id] do %>
27
+ <%= render s[:partial], locals: s[:locals] %>
28
+ <% end %>
29
+
30
+ <% elsif s[:action].to_sym == :append %>
31
+ <% ctl[:action] = :append %>
32
+ <% Rails.logger.debug(" • render-turbo-stream APPEND => #{info}") %>
33
+ <%= turbo_stream.prepend s[:id] do %>
34
+ <%= render s[:partial], locals: s[:locals] %>
35
+ <% end %>
36
+
37
+ <% else %>
38
+ <% ctl[:action] = :UNKNOWN %>
39
+ <% Rails.logger.fatal(" ERROR render-turbo-stream => UNKNOWN ACTION => #{s}") %>
40
+ <% error = true %>
41
+ <% end %>
42
+
43
+ <% control.push(ctl) %>
44
+
45
+ <% end %>
46
+
47
+ <% if error %>
48
+ <% Rails.logger.error(" RENDER TURBO STREAM HAD ERRORS, REPEATING WHOLE ARRAY: ") %>
49
+ <% control.each do |c| %>
50
+ <% Rails.logger.error(" #{c}") %>
51
+ <% end %>
52
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= turbo_stream.redirect_to local_assigns[:url] %>
@@ -0,0 +1,5 @@
1
+ module RenderTurboStream
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace RenderTurboStream
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module RenderTurboStream
2
- VERSION = "0.1.8"
2
+ VERSION = "0.1.11"
3
3
  end
@@ -1,12 +1,162 @@
1
1
  require "render_turbo_stream/version"
2
2
  require "render_turbo_stream/railtie"
3
+ require 'render_turbo_stream/engine'
3
4
 
4
5
  module RenderTurboStream
5
- # Your code goes here...
6
- def testmethod
7
- render template: 'layouts/render', layout: false
8
- respond_to do |format|
9
- format.turbo_stream { render template: 'layouts/render', layout: false }
6
+
7
+ def turbo_stream_save(
8
+ save_action,
9
+ redirect_on_success_to: nil,
10
+ object: nil,
11
+ id: 'form', # if nil: no partial is rendered
12
+ partial: nil, # default: same like ID
13
+ action: 'replace',
14
+ locals: {},
15
+ streams_on_success: [
16
+ {
17
+ id: nil,
18
+ partial: 'form',
19
+ locals: {},
20
+ action: 'replace'
21
+ }
22
+ ],
23
+ streams_on_error: [
24
+ {
25
+ id: nil,
26
+ partial: 'form',
27
+ locals: {},
28
+ action: 'replace'
29
+ }
30
+ ],
31
+ add_flash_alerts: [], #=> array of strings
32
+ add_flash_notices: [], #=> array of strings
33
+ flashes_on_success: [], #=> array of strings
34
+ flashes_on_error: [] #=> array of strings
35
+ )
36
+
37
+ unless object
38
+ object = eval("@#{controller_name.classify.underscore}")
39
+ end
40
+
41
+ #== Streams / Partials
42
+
43
+ streams = [(id ? { id: id, partial: partial, locals: locals, action: action } : nil)]
44
+
45
+ if save_action
46
+ response.status = 200
47
+ streams += streams_on_success.select { |s| s[:id].present? }
48
+ else
49
+ response.status = :unprocessable_entity
50
+ streams += streams_on_error.select { |s| s[:id].present? }
51
+ end
52
+
53
+ #== FLASHES
54
+
55
+ model_name = object.model_name.human
56
+ if save_action
57
+ flash_notices = if flashes_on_success.present?
58
+ flashes_on_success
59
+ elsif action_name == 'create'
60
+ [format(I18n.t('activerecord.success.successfully_created'), model_name: model_name)]
61
+ elsif action_name == 'update'
62
+ [format(I18n.t('activerecord.success.successfully_updated'), model_name: model_name)]
63
+ end
64
+ flash_alerts = []
65
+ else
66
+ flash_alerts = if flashes_on_error.present?
67
+ flashes_on_error
68
+ elsif action_name == 'create'
69
+ [format(I18n.t('activerecord.errors.messages.could_not_create'), model_name: model_name)]
70
+ elsif action_name == 'update'
71
+ [format(I18n.t('activerecord.errors.messages.could_not_update'), model_name: model_name)]
72
+ end
73
+ flash_notices = []
74
+ end
75
+ flash_notices += add_flash_notices
76
+ flash_alerts += add_flash_alerts
77
+ _flash_id = Rails.configuration.x.render_turbo_stream.flash_id
78
+ flash_id = (_flash_id ? _flash_id : "ERROR, MISSING CONFIG => config.x.render_turbo_stream.flash_id")
79
+ flash_partial = Rails.configuration.x.render_turbo_stream.flash_partial
80
+ flash_action = Rails.configuration.x.render_turbo_stream.flash_action
81
+ flash_notices.each do |notice|
82
+ # inside the flash partial has to be a loop that handles all theese flashes
83
+ flash_stream = {
84
+ id: flash_id,
85
+ partial: flash_partial,
86
+ action: flash_action,
87
+ locals: { success: true, message: notice }
88
+ }
89
+ streams.push(flash_stream)
90
+ end
91
+ flash_alerts.each do |alert|
92
+ # inside the flash partial has to be a loop that handles all theese flashes
93
+ flash_stream = {
94
+ id: flash_id,
95
+ partial: flash_partial,
96
+ action: flash_action,
97
+ locals: { success: false, message: alert }
98
+ }
99
+ streams.push(flash_stream)
10
100
  end
101
+
102
+ #== render
103
+
104
+ if save_action && redirect_on_success_to.present?
105
+ response.status = 302
106
+ flash[:alert] = flash_alerts
107
+ flash[:notice] = flash_notices
108
+ if request.format.to_sym == :turbo_stream
109
+ render template: 'render_turbo_stream_redirect', locals: { url: redirect_on_success_to }, layout: false
110
+ else
111
+ render json: { redirected_to: redirect_on_success_to }
112
+ end
113
+ else
114
+ flash.now[:alert] = flash_alerts
115
+ flash.now[:notice] = flash_notices
116
+ stream_partials(streams)
117
+ end
118
+ end
119
+
120
+ def stream_partials(array)
121
+
122
+ ary = []
123
+ array.dup.each do |props|
124
+ part = (props[:partial].present? ? props[:partial] : props[:id]).gsub('-', '_')
125
+ partial = (part.to_s.include?('/') ? part : [controller_path, part].join('/'))
126
+ r = props
127
+ r[:action] = (props[:action].present? ? props[:action] : :replace)
128
+ r[:partial] = partial
129
+ ary.push(r)
130
+ end
131
+
132
+ if request.format.to_sym == :turbo_stream
133
+ render template: 'render_turbo_stream_partials', locals: { streams: ary }, layout: false
134
+ else
135
+ check = {}
136
+ ary.each do |a|
137
+ b = a.dup
138
+ b.delete(:id)
139
+ check[a[:id]] = b
140
+ end
141
+ render json: check
142
+ end
143
+ end
144
+
145
+ def stream_partial(
146
+ id,
147
+ partial: nil, #=> default: id
148
+ action: :replace,
149
+ locals: {}
150
+ )
151
+ stream_partials(
152
+ [
153
+ {
154
+ id: id,
155
+ partial: partial,
156
+ action: action,
157
+ locals: locals
158
+ }
159
+ ]
160
+ )
11
161
  end
12
162
  end
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: 0.1.8
4
+ version: 0.1.11
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-15 00:00:00.000000000 Z
11
+ date: 2023-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,7 +24,7 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 7.0.4.3
27
- description: 'NOT USABLE AS GEM see: Homepage / README'
27
+ description: Coming soon
28
28
  email:
29
29
  - christian@sedlmair.ch
30
30
  executables: []
@@ -33,15 +33,19 @@ extra_rdoc_files: []
33
33
  files:
34
34
  - README.md
35
35
  - Rakefile
36
+ - app/controllers/render_turbo_stream/application_controller.rb
37
+ - app/views/render_turbo_stream_partials.turbo_stream.erb
38
+ - app/views/render_turbo_stream_redirect.turbo_stream.erb
36
39
  - lib/render_turbo_stream.rb
40
+ - lib/render_turbo_stream/engine.rb
37
41
  - lib/render_turbo_stream/railtie.rb
38
42
  - lib/render_turbo_stream/version.rb
39
43
  - lib/tasks/render_turbo_stream_tasks.rake
40
- homepage: https://gitlab.com/sedl/render-turbo-stream
44
+ homepage: https://gitlab.com/sedl/renderturbostream
41
45
  licenses:
42
46
  - MIT
43
47
  metadata:
44
- homepage_uri: https://gitlab.com/sedl/render-turbo-stream
48
+ homepage_uri: https://gitlab.com/sedl/renderturbostream
45
49
  source_code_uri: https://gitlab.com/sedl/renderturbostream
46
50
  changelog_uri: https://gitlab.com/sedl/renderturbostream
47
51
  post_install_message:
@@ -62,5 +66,5 @@ requirements: []
62
66
  rubygems_version: 3.4.12
63
67
  signing_key:
64
68
  specification_version: 4
65
- summary: 'NOT USABLE AS GEM see: Homepage / README'
69
+ summary: Coming soon
66
70
  test_files: []