abyme 0.2.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/abyme/version.rb CHANGED
@@ -1,9 +1,11 @@
1
+ # :nocov:
1
2
  module Abyme
2
3
  module VERSION
3
4
  MAJOR = 0
4
- MINOR = 2
5
- PATCH = 1
5
+ MINOR = 5
6
+ PATCH = 0
6
7
 
7
8
  STRING = [MAJOR, MINOR, PATCH].join(".")
8
9
  end
9
10
  end
11
+ # :nocov:
@@ -1,28 +1,106 @@
1
+ require_relative "abyme_builder"
2
+
1
3
  module Abyme
2
4
  module ViewHelpers
3
5
 
4
- def abymize(association, form, options = {}, &block)
6
+ # ABYME_FOR
7
+
8
+ # this helper will generate the top level wrapper markup
9
+ # with the bare minimum html attributes (data-controller="abyme")
10
+ # it takes the Symbolized name of the association (plural) and the form object
11
+ # then you can pass a hash of options (see exemple below)
12
+ # if no block given it will generate a default markup for
13
+ # #persisted_records_for, #new_records_for & #add_associated_record methods
14
+ # if a block is given it will instanciate a new AbymeBuilder and pass to it
15
+ # the name of the association, the form object and the lookup_context
16
+
17
+ # == Options
18
+
19
+ # - limit (Integer)
20
+ # you can set a limit for the new association fields to display
21
+
22
+ # - min_count (Integer)
23
+ # set the default number of blank fields to display
24
+
25
+ # - partial (String)
26
+ # to customize the partial path by default #abyme_for will expect
27
+ # a partial to bbe present in views/abyme
28
+
29
+ # - Exemple
30
+
31
+ # <%= abyme_for(:tasks, f, limit: 3) do |abyme| %>
32
+ # ...
33
+ # <% end %>
34
+
35
+ # will output this html
36
+
37
+ # <div data-controller="abyme" data-limit="3" id="abyme--tasks">
38
+ # ...
39
+ # </div>
40
+
41
+ def abyme_for(association, form, options = {}, &block)
5
42
  content_tag(:div, data: { controller: 'abyme', limit: options[:limit], min_count: options[:min_count] }, id: "abyme--#{association}") do
6
43
  if block_given?
7
44
  yield(Abyme::AbymeBuilder.new(
8
- association: association, form: form, lookup_context: self.lookup_context, partial: options[:partial]
45
+ association: association, form: form, context: self, partial: options[:partial]
9
46
  )
10
47
  )
11
48
  else
12
49
  model = association.to_s.singularize.classify.constantize
13
50
  concat(persisted_records_for(association, form, options))
14
51
  concat(new_records_for(association, form, options))
15
- concat(add_association(content: options[:button_text] || "Add #{model}"))
52
+ concat(add_associated_record(content: options[:button_text] || "Add #{model}"))
16
53
  end
17
54
  end
18
55
  end
19
56
 
57
+ # NEW_RECORDS_FOR
58
+
59
+ # this helper is call by the AbymeBuilder #new_records instance method
60
+ # it generates the html markup for new associations fields
61
+ # it takes the association (Symbol) and the form object
62
+ # then a hash of options.
63
+
64
+ # - Exemple
65
+ # <%= abyme_for(:tasks, f) do |abyme| %>
66
+ # <%= abyme.new_records %>
67
+ # ...
68
+ # <% end %>
69
+
70
+ # will output this html
71
+
72
+ # <div data-target="abyme.associations" data-association="tasks" data-abyme-position="end">
73
+ # <template class="abyme--task_template" data-target="abyme.template">
74
+ # <div data-target="abyme.fields abyme.newFields" class="abyme--fields task-fields">
75
+ # ... partial html goes here
76
+ # </div>
77
+ # </template>
78
+ # ... new rendered fields goes here
79
+ # </div>
80
+
81
+ # == Options
82
+ # - position (:start, :end)
83
+ # allows you to specify whether new fields added dynamically
84
+ # should go at the top or at the bottom
85
+ # :end is the default value
86
+
87
+ # - partial (String)
88
+ # to customize the partial path by default #abyme_for will expect
89
+ # a partial to bbe present in views/abyme
90
+
91
+ # - fields_html (Hash)
92
+ # allows you to pass any html attributes to each fields wrapper
93
+
94
+ # - wrapper_html (Hash)
95
+ # allows you to pass any html attributes to the the html element
96
+ # wrapping all the fields
97
+
20
98
  def new_records_for(association, form, options = {}, &block)
21
99
  options[:wrapper_html] ||= {}
22
100
 
23
101
  wrapper_default = {
24
102
  data: {
25
- target: 'abyme.associations',
103
+ abyme_target: 'associations',
26
104
  association: association,
27
105
  abyme_position: options[:position] || :end
28
106
  }
@@ -31,25 +109,69 @@ module Abyme
31
109
  fields_default = { data: { target: 'abyme.fields abyme.newFields' } }
32
110
 
33
111
  content_tag(:div, build_attributes(wrapper_default, options[:wrapper_html])) do
34
- content_tag(:template, class: "abyme--#{association.to_s.singularize}_template", data: { target: 'abyme.template' }) do
112
+ content_tag(:template, class: "abyme--#{association.to_s.singularize}_template", data: { abyme_target: 'template' }) do
35
113
  form.fields_for association, association.to_s.classify.constantize.new, child_index: 'NEW_RECORD' do |f|
36
114
  content_tag(:div, build_attributes(fields_default, basic_fields_markup(options[:fields_html], association))) do
37
115
  # Here, if a block is passed, we're passing the association fields to it, rather than the form itself
38
- block_given? ? yield(f) : render(options[:partial] || "abyme/#{association.to_s.singularize}_fields", f: f)
116
+ # block_given? ? yield(f) : render(options[:partial] || "abyme/#{association.to_s.singularize}_fields", f: f)
117
+ block_given? ? yield(f) : render_association_partial(association, f, options[:partial])
39
118
  end
40
119
  end
41
120
  end
42
121
  end
43
122
  end
123
+
124
+ # PERSISTED_RECORDS_FOR
125
+
126
+ # this helper is call by the AbymeBuilder #records instance method
127
+ # it generates the html markup for persisted associations fields
128
+ # it takes the association (Symbol) and the form object
129
+ # then a hash of options.
130
+
131
+ # - Exemple
132
+ # <%= abyme_for(:tasks, f) do |abyme| %>
133
+ # <%= abyme.records %>
134
+ # ...
135
+ # <% end %>
136
+
137
+ # will output this html
138
+
139
+ # <div>
140
+ # <div data-target="abyme.fields" class="abyme--fields task-fields">
141
+ # ... partial html goes here
142
+ # </div>
143
+ # </div>
144
+
145
+ # == Options
146
+ # - collection (Active Record Collection)
147
+ # allows you to pass an AR collection
148
+ # by default every associated records will be present
149
+
150
+ # - order (Hash)
151
+ # allows you to order the collection
152
+ # ex: order: { created_at: :desc }
153
+
154
+ # - partial (String)
155
+ # to customize the partial path by default #abyme_for will expect
156
+ # a partial to bbe present in views/abyme
157
+
158
+ # - fields_html (Hash)
159
+ # allows you to pass any html attributes to each fields wrapper
160
+
161
+ # - wrapper_html (Hash)
162
+ # allows you to pass any html attributes to the the html element
163
+ # wrapping all the fields
44
164
 
45
165
  def persisted_records_for(association, form, options = {})
46
166
  records = options[:collection] || form.object.send(association)
47
167
  options[:wrapper_html] ||= {}
48
- fields_default = { data: { target: 'abyme.fields' } }
168
+ fields_default = { data: { abyme_target: 'fields' } }
49
169
 
50
170
  if options[:order].present?
51
171
  records = records.order(options[:order])
52
- # Get invalid records
172
+ # by calling the order method on the AR collection
173
+ # we get rid of the records with errors
174
+ # so we have to get them back with the 2 lines below
53
175
  invalids = form.object.send(association).reject(&:persisted?)
54
176
  records = records.to_a.concat(invalids) if invalids.any?
55
177
  end
@@ -57,28 +179,51 @@ module Abyme
57
179
  content_tag(:div, options[:wrapper_html]) do
58
180
  form.fields_for(association, records) do |f|
59
181
  content_tag(:div, build_attributes(fields_default, basic_fields_markup(options[:fields_html], association))) do
60
- block_given? ? yield(f) : render(options[:partial] || "abyme/#{association.to_s.singularize}_fields", f: f)
61
- endg
182
+ block_given? ? yield(f) : render_association_partial(association, f, options[:partial])
183
+ end
62
184
  end
63
185
  end
64
186
  end
187
+
188
+ # ADD & REMOVE ASSOCIATION
189
+
190
+ # these helpers will call the #create_button method
191
+ # to generate the buttons for add and remove associations
192
+ # with the right action and a default content text for each button
65
193
 
66
- def add_association(options = {}, &block)
194
+ def add_associated_record(options = {}, &block)
67
195
  action = 'click->abyme#add_association'
196
+ options[:content] ||= 'Add Association'
68
197
  create_button(action, options, &block)
69
198
  end
70
199
 
71
- def remove_association(options = {}, &block)
200
+ def remove_associated_record(options = {}, &block)
72
201
  action = 'click->abyme#remove_association'
202
+ options[:content] ||= 'Remove Association'
73
203
  create_button(action, options, &block)
74
204
  end
75
205
 
76
206
  private
207
+
208
+ # CREATE_BUTTON
209
+
210
+ # this helper is call by either add_associated_record or remove_associated_record
211
+ # by default it will generate a button tag.
212
+
213
+ # == Options
214
+ # - content (String)
215
+ # allows you to set the button text
216
+
217
+ # - tag (Symbol)
218
+ # allows you to set the html tag of your choosing
219
+ # default if :button
220
+
221
+ # - html (Hash)
222
+ # to pass any html attributes you want.
77
223
 
78
224
  def create_button(action, options, &block)
79
225
  options[:html] ||= {}
80
226
  options[:tag] ||= :button
81
- options[:content] ||= 'Add Association'
82
227
 
83
228
  if block_given?
84
229
  content_tag(options[:tag], { data: { action: action } }.merge(options[:html])) do
@@ -89,6 +234,11 @@ module Abyme
89
234
  end
90
235
  end
91
236
 
237
+ # BASIC_FIELDS_MARKUP
238
+
239
+ # generates the default html classes for fields
240
+ # add optional classes if present
241
+
92
242
  def basic_fields_markup(html, association = nil)
93
243
  if html && html[:class]
94
244
  html[:class] = "abyme--fields #{association.to_s.singularize}-fields #{html[:class]}"
@@ -99,17 +249,33 @@ module Abyme
99
249
  html
100
250
  end
101
251
 
252
+ # BUILD_ATTRIBUTES
253
+
254
+ # add optionals html attributes without overwritting
255
+ # the default or already present ones
256
+
102
257
  def build_attributes(default, attr)
103
- # ADD NEW DATA ATTRIBUTES VALUES TO THE DEFAULT ONES (ONLY VALUES)
258
+ # Add new data attributes values to the default ones (only values)
104
259
  if attr[:data]
105
260
  default[:data].each do |key, value|
106
261
  default[:data][key] = "#{value} #{attr[:data][key]}".strip
107
262
  end
108
- # ADD NEW DATA ATTRIBUTES (KEYS & VALUES)
263
+ # Add new data attributes (keys & values)
109
264
  default[:data] = default[:data].merge(attr[:data].reject { |key, _| default[:data][key] })
110
265
  end
111
- # MERGE THE DATA ATTRIBUTES TO THE HASH OF HTML ATTRIBUTES
266
+ # Merge data attributes to the hash of html attributes
112
267
  default.merge(attr.reject { |key, _| key == :data })
113
268
  end
269
+
270
+ # RENDER PARTIAL
271
+
272
+ # renders a partial based on the passed path, or will expect a partial to be found in the views/abyme directory.
273
+
274
+ def render_association_partial(association, form, partial = nil, context = nil)
275
+ partial_path = partial ||"abyme/#{association.to_s.singularize}_fields"
276
+ context ||= self
277
+ context.render(partial: partial_path, locals: {f: form})
278
+ end
279
+
114
280
  end
115
281
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abyme",
3
- "version": "0.1.2",
3
+ "version": "0.2.5",
4
4
  "description": "JS companion to abyme gem",
5
5
  "main": "javascript/index.js",
6
6
  "files": [
@@ -20,6 +20,6 @@
20
20
  "homepage": "https://github.com/bear-in-mind/abyme",
21
21
  "bugs": "https://github.com/bear-in-mind/abyme/issues",
22
22
  "dependencies": {
23
- "stimulus": "^1.1.1"
23
+ "stimulus": "^2.0.0"
24
24
  }
25
25
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abyme
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Romain Sanson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-10-15 00:00:00.000000000 Z
12
+ date: 2021-02-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -40,19 +40,187 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  version: '13.0'
42
42
  - !ruby/object:Gem::Dependency
43
- name: rspec
43
+ name: rspec-rails
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - "~>"
46
+ - - ">="
47
47
  - !ruby/object:Gem::Version
48
- version: '3.0'
48
+ version: '0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - "~>"
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rails-controller-testing
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: database_cleaner-active_record
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: capybara
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: webdrivers
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: generator_spec
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: sqlite3
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: rails
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: pry-rails
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ - !ruby/object:Gem::Dependency
169
+ name: web-console
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ type: :development
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ - !ruby/object:Gem::Dependency
183
+ name: puma
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ type: :development
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ - !ruby/object:Gem::Dependency
197
+ name: simplecov
198
+ requirement: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ type: :development
204
+ prerelease: false
205
+ version_requirements: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - ">="
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
210
+ - !ruby/object:Gem::Dependency
211
+ name: simplecov-lcov
212
+ requirement: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ type: :development
218
+ prerelease: false
219
+ version_requirements: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
54
222
  - !ruby/object:Gem::Version
55
- version: '3.0'
223
+ version: '0'
56
224
  description:
57
225
  email:
58
226
  - louis.sommer@hey.com
@@ -61,9 +229,11 @@ extensions: []
61
229
  extra_rdoc_files: []
62
230
  files:
63
231
  - ".DS_Store"
232
+ - ".github/workflows/build.yml"
64
233
  - ".gitignore"
65
234
  - ".rspec"
66
- - ".travis.yml"
235
+ - ".simplecov"
236
+ - CHANGELOG.md
67
237
  - Gemfile
68
238
  - Gemfile.lock
69
239
  - LICENSE.txt
@@ -71,19 +241,20 @@ files:
71
241
  - Rakefile
72
242
  - abyme.gemspec
73
243
  - bin/console
244
+ - bin/rails
74
245
  - bin/setup
75
246
  - javascript/abyme_controller.js
76
247
  - javascript/index.js
77
248
  - lib/.DS_Store
78
249
  - lib/abyme.rb
79
250
  - lib/abyme/abyme_builder.rb
251
+ - lib/abyme/action_view_extensions/builder.rb
252
+ - lib/abyme/controller.rb
80
253
  - lib/abyme/engine.rb
81
254
  - lib/abyme/model.rb
82
255
  - lib/abyme/version.rb
83
256
  - lib/abyme/view_helpers.rb
84
- - lib/generators/.DS_Store
85
- - lib/generators/abyme/install_generator.rb
86
- - lib/generators/abyme/templates/abyme_controller.js
257
+ - node_modules/.yarn-integrity
87
258
  - package.json
88
259
  - yarn-error.log
89
260
  - yarn.lock