web47core 0.9.0 → 0.9.6

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: b16d9b0b72656026fc126f56d58ca8b1a8e99843feeec96e6892ac139bb4870e
4
- data.tar.gz: 624d9b7f27b76d83a1962bb9bed017c766c61323ba507626ed8c56baaf2a9166
3
+ metadata.gz: 331b65fbd9561ea834ab58be8f8a541ed8a25879649d7fda6f52a4f2fa7213b1
4
+ data.tar.gz: cffa42c73158759ef60ed79a1f93f8dab010ed670b56c4c687c2a218cfd903d5
5
5
  SHA512:
6
- metadata.gz: d835b86f996ed2b6d3871f9a3a57e1226f2603592990ec42104a769350ab896c9dec7de884cd3ccca6f7cd1bda8164d64447da910c690c6a75d711c925a4319c
7
- data.tar.gz: 05da6cc82d68d43c244933dcd10db0ce6be3bb5f915b57325b35cff8d6c89e8f5121e1debb0f626b7312efd3d9ac107872eb3a512e1e03be7226c0971b8d72d9
6
+ metadata.gz: 1a45eed2e90bc93d1330df86e0d5e0ecbb83fe1868f697ec5b55835fbe72fa373498167e0784068d4f415d2d3e8465022cfe5372d7989d563146fa43181083c2
7
+ data.tar.gz: 3b8b1d55228cbe1344db41315addca98a47b0cf32e15fe9cb34b6efd3ecd3cb4bf8d6344fb04de677cc2286e771bfee305fc511499bded3713d15734c100af0f
@@ -10,6 +10,30 @@ module CoreFormHelper
10
10
  form.render_form(&block)
11
11
  end
12
12
 
13
+ #
14
+ # Text area
15
+ #
16
+ def form_text_area(model, field, options = {})
17
+ classes = options[:classes] || %w[s12]
18
+ value = model.send(field)
19
+ # options[:value] = value
20
+ # options[:disabled] ||= false
21
+ # tag_options = {class: []} # text_field_options(model, field, options)
22
+ # tag_options[:class] += ['materialize-textarea']
23
+ content_tag(:div, class: (%w[input-field col] + classes).join(' ')) do
24
+ concat(text_area(model, field, value, options))
25
+ concat(form_label_tag(model, field, value, options))
26
+ end
27
+ end
28
+
29
+ def text_area(model, field, value, options = {})
30
+ tag_options = text_field_options(model, field, options)
31
+ tag_options[:class] += ['materialize-textarea']
32
+ content_tag(:textarea, tag_options) do
33
+ concat(value)
34
+ end
35
+ end
36
+
13
37
  #
14
38
  # Text field
15
39
  #
@@ -18,6 +42,7 @@ module CoreFormHelper
18
42
  value = model.send(field)
19
43
  options[:type] = :text
20
44
  options[:value] = value
45
+ options[:disabled] ||= false
21
46
  tag_options = text_field_options(model, field, options)
22
47
  content_tag(:div, class: (%w[input-field col] + classes).join(' ')) do
23
48
  concat(tag(:input, tag_options))
@@ -30,6 +55,7 @@ module CoreFormHelper
30
55
  value = model.send(field)
31
56
  options[:value] = value.strftime('%d %B, %Y') if value.present?
32
57
  options[:type] = :text
58
+ options[:disabled] ||= false
33
59
  tag_options = text_field_options(model, field, options)
34
60
  tag_options[:class] = options[:date_picker_type] || 'simple-date-picker'
35
61
  content_tag(:div, class: (%w[input-field col] + classes).join(' ')) do
@@ -38,6 +64,23 @@ module CoreFormHelper
38
64
  end
39
65
  end
40
66
 
67
+ #
68
+ # Time picker field
69
+ #
70
+ def form_time_field(model, field, options = {})
71
+ classes = options[:classes] || %w[s12 m6 l4 xl3]
72
+ value = model.send(field)
73
+ options[:value] = value
74
+ options[:type] = :text
75
+ options[:disabled] ||= false
76
+ tag_options = text_field_options(model, field, options)
77
+ tag_options[:class] = options[:time_picker_type] || 'time-picker'
78
+ content_tag(:div, class: (%w[input-field col] + classes).join(' ')) do
79
+ concat(tag(:input, tag_options))
80
+ concat(form_label_tag(model, field, value, options))
81
+ end
82
+ end
83
+
41
84
  #
42
85
  # Password field
43
86
  #
@@ -80,7 +123,13 @@ module CoreFormHelper
80
123
  #
81
124
  def form_select_tag(model, field, options = {})
82
125
  form_name = form_field_name(model, field, options)
83
- content_tag(:select, id: form_name, name: form_name, class: options[:input_classes]) do
126
+ select_content = {
127
+ id: form_name,
128
+ name: form_name,
129
+ class: options[:input_classes],
130
+ disabled: options[:disabled]
131
+ }
132
+ content_tag(:select, select_content) do
84
133
  form_select_option_key_values(model.send(field), options).each do |value|
85
134
  concat(content_tag(:option, value: value[:key], selected: value[:selected]) do
86
135
  concat(value[:value])
@@ -96,15 +145,16 @@ module CoreFormHelper
96
145
  select_options << { key: '', value: options[:prompt], selected: false } if options[:prompt].present?
97
146
  options[:options].each do |option_value|
98
147
  option_value[:display_name] = option_value.display_name if option_value.respond_to?(:display_name)
148
+ option_value[:display_name] = option_value.user_display_name if option_value.respond_to?(:user_display_name)
99
149
  select_options << case option_value
100
150
  when String, Integer
101
151
  { key: option_value,
102
152
  value: option_value,
103
153
  selected: value.eql?(option_value) }
104
154
  when Array
105
- { key: option_value.first,
106
- value: option_value.last,
107
- selected: value.to_s.eql?(option_value.first.to_s) }
155
+ { key: option_value.last,
156
+ value: option_value.first,
157
+ selected: value.to_s.eql?(option_value.last.to_s) }
108
158
  when Hash
109
159
  { key: option_value[:key],
110
160
  value: option_value[:value],
@@ -164,6 +214,20 @@ module CoreFormHelper
164
214
  end
165
215
  end
166
216
 
217
+ #
218
+ # File field
219
+ #
220
+ def form_file(model, field, file_types = '.xlsx', classes = %w[s12 m6 l4 xl3])
221
+ form_name = form_field_name(model, field)
222
+ form_id = "#{model.class.to_s.underscore}_#{field}"
223
+ value = model.send(field)
224
+ file_tag = tag(:input, id: form_id, name: form_name, type: :file, accept: file_types)
225
+ content_tag(:div, class: (%w[input-field col] + classes).join(' ')) do
226
+ concat(file_tag)
227
+ concat(form_label_tag(model, field, value))
228
+ end
229
+ end
230
+
167
231
  #
168
232
  # get the label for field
169
233
  #
@@ -5,12 +5,22 @@
5
5
  #
6
6
  module CoreLinkHelper
7
7
  #
8
- # Create a copy tag for data to be copied to the clipboard
8
+ # Generate a download link with the download icon
9
+ #
10
+ def download_tag(url, options = {})
11
+ content_tag(:a, href: url) do
12
+ concat(materialize_icon(options[:download_icon_name] || 'cloud_download'))
13
+ end
14
+ end
15
+
16
+ #
17
+ # Setup the text as copy text
9
18
  #
10
19
  def copy_tag(copy_text, options = {})
11
20
  content_tag(:p, class: 'stack-tight') do
12
- concat(copy_text)
21
+ concat(content_tag(:span) { copy_text })
13
22
  concat(copy_text_tag(copy_text, options))
23
+ concat(download_tag(options[:download_url], options)) if options[:download_url].present?
14
24
  end
15
25
  end
16
26
 
@@ -34,11 +44,21 @@ module CoreLinkHelper
34
44
  constrainWidth: false,
35
45
  gutter: 28,
36
46
  alignment: 'right' }
37
- content_tag(:a, class: 'dropdown-button', data: datum) do
47
+ content_tag(:a, class: 'dropdown-trigger', data: datum) do
38
48
  concat(materialize_icon(icon_name))
39
49
  end
40
50
  end
41
51
 
52
+ #
53
+ # Add a favorite tag
54
+ #
55
+ def favorite_tag(favorite)
56
+ content_tag(:i,
57
+ class: 'material-icons pointer favorite',
58
+ id: favorite.id.to_s,
59
+ type: favorite.favorite_type) { concat('favorite_border') }
60
+ end
61
+
42
62
  #
43
63
  # Add a material icon by name
44
64
  #
@@ -52,7 +72,7 @@ module CoreLinkHelper
52
72
  # Generic link tag
53
73
  #
54
74
  def link_tag(title, path, options = {})
55
- content_tag(:a, href: path) do
75
+ content_tag(:a, href: path, class: options[:class]) do
56
76
  concat(content_tag(:i, class: 'material-icons left') { options[:icon_name] }) if options[:icon_name].present?
57
77
  concat(title)
58
78
  end
@@ -71,14 +91,15 @@ module CoreLinkHelper
71
91
  end
72
92
 
73
93
  #
74
- # Edit an thingy
94
+ # Edit a thingy
75
95
  #
76
96
  def edit_link_tag(obj, path, options = {})
77
97
  return unless can? :edit, obj
78
98
 
99
+ icon = options[:icon] || 'edit'
79
100
  content_tag(:a, href: path) do
80
101
  concat(content_tag(:i, class: 'material-icons') do
81
- 'edit'
102
+ icon
82
103
  end)
83
104
  concat(options[:label]) if options[:label].present?
84
105
  end
@@ -136,9 +157,10 @@ module CoreLinkHelper
136
157
  def info_link_tag(obj, path, options = {})
137
158
  return unless can? :read, obj
138
159
 
139
- content_tag(:a, href: path, class: options[:link_classes]) do
160
+ icon = options[:icon] || 'info'
161
+ content_tag(:a, href: path) do
140
162
  concat(content_tag(:i, class: 'material-icons') do
141
- 'info'
163
+ icon
142
164
  end)
143
165
  concat(options[:label]) if options[:label].present?
144
166
  end
@@ -149,6 +171,7 @@ module CoreLinkHelper
149
171
  #
150
172
  def action_list_tag(condition, path, options = {})
151
173
  return unless condition
174
+
152
175
  raise('Label Required') if options[:label].blank?
153
176
 
154
177
  content_tag(:li) do
@@ -162,7 +185,9 @@ module CoreLinkHelper
162
185
  def action_link_tag(condition, path, options = {})
163
186
  return unless condition
164
187
 
165
- content_tag(:a, href: path, class: options[:link_classes]) do
188
+ confirmation = options[:confirmation] || t('links.action_confirmation')
189
+ confirmation_required = options[:confirmation].present? ? { confirm: confirmation } : {}
190
+ content_tag(:a, href: path, class: options[:classes], data: confirmation_required) do
166
191
  concat(content_tag(:i, class: 'material-icons') do
167
192
  options[:icon_name] || 'info'
168
193
  end)
@@ -174,7 +199,7 @@ module CoreLinkHelper
174
199
  # Delete a thingy in a pull down list
175
200
  #
176
201
  def delete_list_tag(obj, path, options = {})
177
- return unless can? :delete, obj
202
+ return unless can? :destroy, obj
178
203
 
179
204
  options[:label] ||= I18n.t('ui_form.actions.delete')
180
205
  content_tag(:li) do
@@ -186,7 +211,7 @@ module CoreLinkHelper
186
211
  # Delete an thingy
187
212
  #
188
213
  def delete_link_tag(obj, path, options = {})
189
- return unless can? :delete, obj
214
+ return unless can? :destroy, obj
190
215
 
191
216
  data = { method: :delete,
192
217
  confirm: options[:confirm] || t('links.deletion_confirmation', name: obj.class.to_s.underscore.humanize) }
@@ -198,6 +223,111 @@ module CoreLinkHelper
198
223
  end
199
224
  end
200
225
 
226
+ #
227
+ # Create a thingy in a pull-down list
228
+ #
229
+ def create_list_tag(obj, path, options = {})
230
+ return unless can? :create, obj
231
+
232
+ options[:label] ||= I18n.t('ui_form.actions.create')
233
+ content_tag(:li) do
234
+ create_link_tag(obj, path, options)
235
+ end
236
+ end
237
+
238
+ #
239
+ # Create a thingy
240
+ #
241
+ def create_link_tag(obj, path, options = {})
242
+ return unless can? :create, obj
243
+
244
+ confirmation = options[:confirmation] || t('links.action_confirmation', name: obj.class.to_s.underscore.humanize)
245
+ content_tag(:a, href: path, data: { confirm: confirmation }) do
246
+ concat(content_tag(:i, class: 'material-icons') do
247
+ options[:icon_name] || 'add'
248
+ end)
249
+ concat(options[:label]) if options[:label].present?
250
+ end
251
+ end
252
+
253
+ #
254
+ # Send notification in a pull down list
255
+ #
256
+ def notification_list_tag(obj, path, options = {})
257
+ return unless can? :manage, obj
258
+
259
+ options[:label] ||= I18n.t('customer_account_users.index.reset_password')
260
+ content_tag(:li) do
261
+ notification_link_tag(obj, path, options)
262
+ end
263
+ end
264
+
265
+ #
266
+ # Send notification
267
+ #
268
+ def notification_link_tag(obj, path, options = {})
269
+ return unless can? :manage, obj
270
+
271
+ content_tag(:a, href: path) do
272
+ concat(content_tag(:i, class: 'material-icons') do
273
+ options[:icon_name] || 'email'
274
+ end)
275
+ concat(options[:label]) if options[:label].present?
276
+ end
277
+ end
278
+
279
+ #
280
+ # Promote a publishable kb object in a pull down list
281
+ #
282
+ def promote_list_tag(obj, path, options = {})
283
+ return unless can? :promote, obj
284
+
285
+ options[:label] ||= I18n.t('links.promote')
286
+ content_tag(:li) do
287
+ promote_link_tag(obj, path, options)
288
+ end
289
+ end
290
+
291
+ #
292
+ # Promote a publishable kb object
293
+ #
294
+ def promote_link_tag(obj, path, options = {})
295
+ return unless can? :promote, obj
296
+
297
+ content_tag(:a, href: path) do
298
+ concat(content_tag(:i, class: 'material-icons') do
299
+ 'file_upload'
300
+ end)
301
+ concat(options[:label]) if options[:label].present?
302
+ end
303
+ end
304
+
305
+ #
306
+ # Demote a publishable kb object in a pull down list
307
+ #
308
+ def demote_list_tag(obj, path, options = {})
309
+ return unless can? :demote, obj
310
+
311
+ options[:label] ||= I18n.t('links.demote')
312
+ content_tag(:li) do
313
+ demote_link_tag(obj, path, options)
314
+ end
315
+ end
316
+
317
+ #
318
+ # Demote a publishable kb object
319
+ #
320
+ def demote_link_tag(obj, path, options = {})
321
+ return unless can? :demote, obj
322
+
323
+ content_tag(:a, href: path) do
324
+ concat(content_tag(:i, class: 'material-icons') do
325
+ 'file_download'
326
+ end)
327
+ concat(options[:label]) if options[:label].present?
328
+ end
329
+ end
330
+
201
331
  #
202
332
  # Edit a page
203
333
  #
@@ -214,36 +344,58 @@ module CoreLinkHelper
214
344
  #
215
345
  # Add a thingy
216
346
  #
217
- def add_link_tag(klass, path)
218
- return unless can?(:manage, klass)
347
+ def add_link_tag(klass, path, options = {})
348
+ return unless can?(:create, klass)
219
349
 
220
350
  content_tag(:div, class: 'fixed-action-btn horizontal') do
221
- concat(content_tag(:a, href: path, class: 'btn-floating btn-large right', style: 'padding: 0;margin: 0px 15px') do
222
- concat(content_tag(:i, class: 'material-icons') { 'add' })
223
- end)
351
+ concat(add_link_button(path, options))
352
+ end
353
+ end
354
+
355
+ #
356
+ # Add the `Add` button
357
+ #
358
+ def add_link_button(path, options)
359
+ options[:title] ||= t('ui_form.actions.add')
360
+ options[:icon] ||= 'add'
361
+ content_tag(:a,
362
+ href: path,
363
+ class: 'btn-floating btn-large right',
364
+ style: 'padding: 0;margin: 0px 15px',
365
+ title: options[:title]) do
366
+ concat(content_tag(:i, class: 'material-icons') { options[:icon] })
224
367
  end
225
368
  end
226
369
 
227
370
  #
228
371
  # Form cancel button
229
372
  #
230
- def form_cancel_button_tag(path)
373
+ def form_cancel_button_tag(path, name = 'cancel')
231
374
  options = { class: 'btn-large waves-effect waves-light secondary', href: path }
232
375
  content_tag(:a, options) do
233
- concat(t('ui_form.actions.cancel'))
376
+ concat(t("ui_form.actions.#{name}"))
234
377
  end
235
378
  end
236
379
 
237
380
  #
238
381
  # Form submit button
239
382
  #
240
- def form_submit_button_tag(obj)
241
- return unless can? :update, obj
383
+ def form_submit_button_tag(condition = true, options = {})
384
+ return unless condition
242
385
 
243
- options = { class: 'btn-large waves-effect waves-light', type: :submit }
244
- content_tag(:button, options) do
245
- concat(t('ui_form.actions.save'))
246
- concat(content_tag(:i, class: 'material-icons right') { 'save' })
386
+ tag_options = { class: 'btn-large waves-effect waves-light', type: :submit }
387
+ if options[:action].present?
388
+ tag_options[:name] = options[:name] || 'button_action'
389
+ tag_options[:value] = options[:action]
390
+ end
391
+ tag_options[:class] += ' disabled' if options[:disabled]
392
+ tag_options[:class] += ' disabled' if options[:disabled]
393
+
394
+ button_text = options[:text] || t('ui_form.actions.save')
395
+ button_icon = options[:icon] || 'save'
396
+ content_tag(:button, tag_options) do
397
+ concat(button_text)
398
+ concat(content_tag(:i, class: 'material-icons right') { button_icon })
247
399
  end
248
400
  end
249
401
  end
@@ -27,5 +27,16 @@ module Cron
27
27
  email.from_template('support_ticket_notification', params)
28
28
  email.send_notification
29
29
  end
30
+
31
+ #
32
+ # Sends support a notification if something goes awry
33
+ #
34
+ def notify_job_failure(error, event)
35
+ message = { job_name: self.class.to_s.titleize,
36
+ event: event,
37
+ error_message: error.message,
38
+ stack_trace: error.backtrace }
39
+ SlackNotification.say message, to: SystemConfiguration.slack_support_channel, template: :job_failure
40
+ end
30
41
  end
31
42
  end
@@ -16,7 +16,7 @@ module SearchAble
16
16
  #
17
17
  # Call backs
18
18
  #
19
- before_validation :update_search_and_sort_text
19
+ before_save :update_search_and_sort_text
20
20
  end
21
21
  end
22
22
 
@@ -31,7 +31,7 @@ module SearchAble
31
31
  #
32
32
  module ClassMethods
33
33
  def matching_search_text(search_text = nil)
34
- (search_text.blank? ? all : where(search_text: /#{search_text.downcase}/)).order(sort_order)
34
+ (search_text.blank? ? all : where(search_text: /#{search_text.downcase}/)).order([:sort_text, 1])
35
35
  end
36
36
 
37
37
  def sort_order
@@ -22,8 +22,8 @@ module StandardModel
22
22
  #
23
23
  # Relationships
24
24
  #
25
- belongs_to :last_modified_by, polymorphic: true, dependent: :nullify, optional: true
26
- belongs_to :created_by, polymorphic: true, dependent: :nullify, optional: true
25
+ belongs_to :last_modified_by, polymorphic: true, optional: true
26
+ belongs_to :created_by, polymorphic: true, optional: true
27
27
  has_many Web47core::Config.audit_model_log_symbol, dependent: :nullify, inverse_of: :model
28
28
  #
29
29
  # Callbacks
@@ -57,14 +57,41 @@ module StandardModel
57
57
  #
58
58
  # Return the complete list of key names that would appear in the form.
59
59
  #
60
- def allowed_param_names(filter_names = [])
60
+ def allowed_param_names(filter_names = [], include_relationships = true)
61
61
  # Always filter out the mongoid reserved items
62
- filter_names += %w[created_at updated_at _type _id]
63
- field_names(filter_names)
62
+ filter_names += %w[created_at updated_at _type _id search_text sort_text]
63
+ associations = many_to_many_associations
64
+ # filter out the relationship names so we don't have dups
65
+ associations.each { |association| filter_names << association.keys.first }
66
+ names = field_names(filter_names)
67
+ names += associations if include_relationships
68
+ names.delete_if { |name| filter_names.include?(name) }
64
69
  rescue StandardError
65
70
  attribute_names.delete_if { |name| filter_names.include?(name) }
66
71
  end
67
72
 
73
+ #
74
+ # Return a collection of many to many associations. We basically
75
+ # need to turn the current value returned by attribute names
76
+ #
77
+ # relationship_ids
78
+ #
79
+ # to
80
+ #
81
+ # { relationship_ids => [] }
82
+ #
83
+ # Telling the permit command to accept the value as an array of items.
84
+ #
85
+ def many_to_many_associations
86
+ associations = []
87
+ reflect_on_all_associations.each do |association|
88
+ next unless association.macro == :has_and_belongs_to_many
89
+
90
+ associations << { association.key => [] }
91
+ end
92
+ associations
93
+ end
94
+
68
95
  #
69
96
  # allow the model to filter out a name if they want to, meaning the model
70
97
  # can return a subset of attribute names
@@ -89,8 +116,12 @@ module StandardModel
89
116
  #
90
117
  def find_or_create_by_and_log!(user, attributes)
91
118
  model = find_or_initialize_by(attributes)
92
- log_change(user, model, attributes) if model.new_record? && model.valid?
93
- model.save!
119
+ if model.new_record?
120
+ model.last_modified_by = user
121
+ model.created_by = user
122
+ model.save!
123
+ log_change(user, model, attributes)
124
+ end
94
125
  model
95
126
  end
96
127
 
@@ -98,7 +129,7 @@ module StandardModel
98
129
  # Record the creation with this user
99
130
  #
100
131
  def create_and_log(user, attributes)
101
- model = create(attributes)
132
+ model = new(attributes)
102
133
  model.last_modified_by = user
103
134
  model.created_by = user
104
135
  model.save
@@ -110,7 +141,7 @@ module StandardModel
110
141
  # Record the creation with this user
111
142
  #
112
143
  def create_and_log!(user, attributes)
113
- model = create!(attributes)
144
+ model = new(attributes)
114
145
  model.last_modified_by = user
115
146
  model.created_by = user
116
147
  model.save!
@@ -175,7 +206,7 @@ module StandardModel
175
206
  #
176
207
  # record a change for the object instance
177
208
  #
178
- def log_change(user, changes, action)
209
+ def log_change(user, changes, action = nil)
179
210
  Web47core::Config.audit_model_log_class.create!(Web47core::Config.audit_model => user,
180
211
  model: self,
181
212
  action: action,
@@ -190,7 +221,7 @@ module StandardModel
190
221
  # Safely get the display name of who last modified this object
191
222
  #
192
223
  def last_modified_by_display_name
193
- last_modified_by.name
224
+ last_modified_by.display_name
194
225
  rescue StandardError
195
226
  "#{last_modified_by_name} (#{last_modified_by_email}) - deleted"
196
227
  end
@@ -199,7 +230,7 @@ module StandardModel
199
230
  # Safely get the display name of who created this object
200
231
  #
201
232
  def created_by_display_name
202
- created_by.name
233
+ created_by.display_name
203
234
  rescue StandardError
204
235
  "#{created_by_name} (#{created_by_email}) - deleted"
205
236
  end
@@ -27,6 +27,16 @@ module TimeZoneAble
27
27
  TZInfo::Timezone.all_identifiers
28
28
  end
29
29
 
30
+ #
31
+ # Return the given time in the localized time for this object
32
+ #
33
+ def local_date(date, format = :medium, default = 'N/A')
34
+ tz = TZInfo::Timezone.get(time_zone || 'GMT')
35
+ date.present? ? I18n.l(date.in_time_zone(tz).to_date, format: format) : default
36
+ rescue StandardError
37
+ default
38
+ end
39
+
30
40
  #
31
41
  # Return the given time in the localized time for this object
32
42
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Web47core
4
- VERSION = '0.9.0'
4
+ VERSION = '0.9.6'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web47core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Schroeder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-10 00:00:00.000000000 Z
11
+ date: 2020-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport