fustrate-rails 0.4.1 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/config/initializers/jbuilder.rb +13 -0
  3. data/config/initializers/renderers.rb +40 -0
  4. data/config/initializers/sanitize.rb +112 -0
  5. data/config/rubocop/default.yml +96 -0
  6. data/config/rubocop/rails.yml +22 -0
  7. data/lib/fustrate/rails/concerns/clean_attributes.rb +49 -0
  8. data/lib/fustrate/rails/concerns/model.rb +48 -0
  9. data/lib/fustrate/rails/concerns/sanitize_html.rb +34 -0
  10. data/lib/fustrate/rails/engine.rb +14 -7
  11. data/lib/fustrate/rails/services/base.rb +46 -0
  12. data/lib/fustrate/rails/services/generate_csv.rb +35 -0
  13. data/lib/fustrate/rails/services/generate_excel.rb +32 -0
  14. data/lib/fustrate/rails/services/log_edit.rb +132 -0
  15. data/lib/fustrate/rails/spec_helper.rb +62 -0
  16. data/lib/fustrate/rails/version.rb +5 -1
  17. data/lib/fustrate-rails.rb +5 -2
  18. metadata +44 -140
  19. data/vendor/assets/javascripts/awesomplete.js +0 -402
  20. data/vendor/assets/javascripts/fustrate/_module.coffee +0 -140
  21. data/vendor/assets/javascripts/fustrate/components/_module.coffee +0 -3
  22. data/vendor/assets/javascripts/fustrate/components/alert_box.coffee +0 -10
  23. data/vendor/assets/javascripts/fustrate/components/autocomplete.coffee +0 -161
  24. data/vendor/assets/javascripts/fustrate/components/disclosure.coffee +0 -12
  25. data/vendor/assets/javascripts/fustrate/components/drop_zone.coffee +0 -9
  26. data/vendor/assets/javascripts/fustrate/components/dropdown.coffee +0 -48
  27. data/vendor/assets/javascripts/fustrate/components/file_picker.coffee +0 -11
  28. data/vendor/assets/javascripts/fustrate/components/flash.coffee +0 -31
  29. data/vendor/assets/javascripts/fustrate/components/modal.coffee +0 -273
  30. data/vendor/assets/javascripts/fustrate/components/pagination.coffee +0 -84
  31. data/vendor/assets/javascripts/fustrate/components/tabs.coffee +0 -28
  32. data/vendor/assets/javascripts/fustrate/components/tooltip.coffee +0 -72
  33. data/vendor/assets/javascripts/fustrate/generic_form.coffee +0 -30
  34. data/vendor/assets/javascripts/fustrate/generic_page.coffee +0 -40
  35. data/vendor/assets/javascripts/fustrate/generic_table.coffee +0 -57
  36. data/vendor/assets/javascripts/fustrate/listenable.coffee +0 -25
  37. data/vendor/assets/javascripts/fustrate/object.coffee +0 -21
  38. data/vendor/assets/javascripts/fustrate/record.coffee +0 -23
  39. data/vendor/assets/javascripts/fustrate.coffee +0 -6
  40. data/vendor/assets/stylesheets/_fustrate.sass +0 -7
  41. data/vendor/assets/stylesheets/awesomplete.sass +0 -76
  42. data/vendor/assets/stylesheets/fustrate/_colors.sass +0 -12
  43. data/vendor/assets/stylesheets/fustrate/_settings.sass +0 -20
  44. data/vendor/assets/stylesheets/fustrate/components/_components.sass +0 -36
  45. data/vendor/assets/stylesheets/fustrate/components/_functions.sass +0 -41
  46. data/vendor/assets/stylesheets/fustrate/components/alerts.sass +0 -86
  47. data/vendor/assets/stylesheets/fustrate/components/buttons.sass +0 -99
  48. data/vendor/assets/stylesheets/fustrate/components/disclosures.sass +0 -23
  49. data/vendor/assets/stylesheets/fustrate/components/dropdowns.sass +0 -36
  50. data/vendor/assets/stylesheets/fustrate/components/flash.sass +0 -38
  51. data/vendor/assets/stylesheets/fustrate/components/forms.sass +0 -195
  52. data/vendor/assets/stylesheets/fustrate/components/grid.sass +0 -196
  53. data/vendor/assets/stylesheets/fustrate/components/labels.sass +0 -64
  54. data/vendor/assets/stylesheets/fustrate/components/modals.sass +0 -167
  55. data/vendor/assets/stylesheets/fustrate/components/pagination.sass +0 -69
  56. data/vendor/assets/stylesheets/fustrate/components/panels.sass +0 -67
  57. data/vendor/assets/stylesheets/fustrate/components/popovers.sass +0 -19
  58. data/vendor/assets/stylesheets/fustrate/components/tables.sass +0 -62
  59. data/vendor/assets/stylesheets/fustrate/components/tabs.sass +0 -44
  60. data/vendor/assets/stylesheets/fustrate/components/tooltips.sass +0 -28
  61. data/vendor/assets/stylesheets/fustrate/components/typography.sass +0 -391
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) Steven Hoffman
4
+ # All rights reserved.
5
+
6
+ module Fustrate
7
+ module Rails
8
+ module Services
9
+ module LogEdit
10
+ IGNORE_COLUMNS = %w[id created_at updated_at].freeze
11
+ RENAME_COLUMNS = {}.freeze
12
+
13
+ attr_reader :subject, :force, :note, :user
14
+
15
+ def call(subject, force: false, note: nil, user: nil)
16
+ # Make sure any before_validation callbacks are run
17
+ subject.validate
18
+
19
+ @subject = subject
20
+ @force = force
21
+ @note = note
22
+ @user = user || ::Current.user
23
+
24
+ process_changes
25
+
26
+ self.class::RENAME_COLUMNS.each do |from, to|
27
+ changes[to] = changes.delete(from) if changes[from]
28
+ end
29
+
30
+ record_edit
31
+ end
32
+
33
+ protected
34
+
35
+ def changes
36
+ @changes ||= subject.changes.except(*self.class::IGNORE_COLUMNS)
37
+ end
38
+
39
+ def record_edit
40
+ clean_changes!
41
+
42
+ return if changes.empty? && !force
43
+
44
+ subject.log_edits_on.edits.new(
45
+ user:,
46
+ note:,
47
+ reason: ::Current.params[:reason],
48
+ pretty_changes: changes,
49
+ raw_changes:
50
+ )
51
+ end
52
+
53
+ # Get rid of changes from nil to '' and whatnot
54
+ def clean_changes! = changes.delete_if { |_, values| values.all?(&:blank?) || values.first == values.last }
55
+
56
+ def raw_changes = subject.changes
57
+
58
+ def process_changes
59
+ process_timestamps(:datetime, '%-m/%-d/%y %-I:%M %p')
60
+ process_timestamps(:date, '%-m/%-d/%y')
61
+ process_timestamps(:time, '%-I:%M %p')
62
+
63
+ process_boolean_columns
64
+ process_relations
65
+ end
66
+
67
+ def process_timestamps(type, time_format)
68
+ columns_of_type(type).each do |column_name|
69
+ changes[column_name].map! { _1&.strftime(time_format) }
70
+ end
71
+ end
72
+
73
+ def process_boolean_columns
74
+ columns_of_type(:boolean).each do |column_name|
75
+ changes[column_name] = changes[column_name][1] ? %w[No Yes] : %w[Yes No]
76
+ end
77
+ end
78
+
79
+ def columns_of_type(type) = Array(columns[type]).select { changes[_1] }
80
+
81
+ def process_relations
82
+ subject.class.reflect_on_all_associations.each do |relation|
83
+ if relation.options[:polymorphic]
84
+ process_polymorphic_relation(relation.name)
85
+ elsif relation.is_a?(::ActiveRecord::Reflection::BelongsToReflection)
86
+ process_belongs_to_relation(relation.name)
87
+ end
88
+ end
89
+ end
90
+
91
+ def process_polymorphic_relation(name)
92
+ return unless changes["#{name}_id"] || changes["#{name}_type"]
93
+
94
+ changes.delete("#{name}_id")
95
+ changes.delete("#{name}_type")
96
+
97
+ changes[name] = [find_old_polymorphic_record(name), subject.__send__(name)&.to_s]
98
+ end
99
+
100
+ def find_old_polymorphic_record(name)
101
+ # The type, and in rare cases the ID, may not have actually changed
102
+ old_id = subject.__send__(:"#{name}_id_in_database")
103
+ old_type = subject.__send__(:"#{name}_type_in_database").presence
104
+
105
+ ::Object.const_get(old_type).find(old_id)&.to_s if old_type
106
+ end
107
+
108
+ def columns
109
+ # .reject { _1.name.match?(/_(?:type|id)\z/) }
110
+ @columns ||= subject.class.columns
111
+ .reject { self.class::IGNORE_COLUMNS.include? _1.name }
112
+ .group_by { _1.sql_type_metadata.type }
113
+ .transform_values { |cols| cols.map { _1.name.to_sym } }
114
+ end
115
+
116
+ def process_belongs_to_relation(name)
117
+ return unless changes["#{name}_id"]
118
+
119
+ new_value = subject.__send__(name)
120
+
121
+ old_value_id = changes.delete("#{name}_id").first
122
+
123
+ # If we're removing the value, new_value.class will be nil, so we need to use reflection.
124
+ changes[name] = [
125
+ (subject.class.reflect_on_association(name).klass.find(old_value_id)&.to_s if old_value_id),
126
+ new_value&.to_s
127
+ ]
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) Steven Hoffman
4
+ # All rights reserved.
5
+
6
+ module Fustrate
7
+ module Rails
8
+ module SpecHelper
9
+ include ::ActiveSupport::Testing::TimeHelpers
10
+
11
+ def accept(mime)
12
+ request.accept = mime['/'] ? mime : ::Mime::Type.lookup_by_extension(mime)
13
+ end
14
+
15
+ # Just helps to shorten some absurdly long error message keys
16
+ def error_t(model, attribute, key)
17
+ key = "attributes.#{attribute}.#{key}" if attribute
18
+
19
+ ::I18n.t "activerecord.errors.models.#{model.model_name.i18n_key}.#{key}"
20
+ end
21
+
22
+ def double_list(name, count, **stubs) = ::Array.new(count) { instance_double(name, stubs) }
23
+
24
+ def data_from_file(name, **interpolations)
25
+ ::Dir.glob(::Rails.root.join('spec', 'data', "#{name}.*")) do |filename|
26
+ case ::File.extname filename
27
+ when '.yml', '.yaml'
28
+ return yaml_data_from_file(filename, **interpolations)
29
+ else
30
+ raise ::ArgumentError, "Could not parse unknown file type #{::File.extname filename}"
31
+ end
32
+ end
33
+ end
34
+
35
+ def image_file(filename, type = 'image/jpeg')
36
+ ::Rack::Test::UploadedFile.new ::Rails.root.join('spec', 'files', filename), type
37
+ end
38
+
39
+ def pdf_file(filename)
40
+ ::Rack::Test::UploadedFile.new ::Rails.root.join('spec', 'files', filename), 'application/pdf'
41
+ end
42
+
43
+ # A few cron scripts use `puts` and clog up STDOUT.
44
+ def stfu
45
+ orig_stdout = $stdout.clone
46
+ $stdout.reopen ::File.new('/dev/null', 'w')
47
+ yield
48
+ rescue ::StandardError => e
49
+ $stdout.reopen orig_stdout
50
+ raise e
51
+ ensure
52
+ $stdout.reopen orig_stdout
53
+ end
54
+
55
+ protected
56
+
57
+ def yaml_data_from_file(filename, **) = ::YAML.safe_load read_with_interpolations(filename, **), aliases: true
58
+
59
+ def read_with_interpolations(filename, **interpolations) = ::File.read(filename) % interpolations
60
+ end
61
+ end
62
+ end
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
3
+ # Copyright (c) Steven Hoffman
4
+ # All rights reserved.
5
+
2
6
  module Fustrate
3
7
  module Rails
4
- VERSION = '0.4.1'.freeze
8
+ VERSION = '0.10.1'
5
9
  end
6
10
  end
@@ -1,4 +1,7 @@
1
- require 'coffee-script'
2
- require 'sass'
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) Steven Hoffman
4
+ # All rights reserved.
5
+
3
6
  require 'fustrate/rails/engine'
4
7
  require 'fustrate/rails/version'
metadata CHANGED
@@ -1,193 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fustrate-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Hoffman
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-25 00:00:00.000000000 Z
11
+ date: 2024-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: coffee-script
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.4'
19
+ version: '7.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.4'
26
+ version: '7.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: sass
28
+ name: jbuilder
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.4'
33
+ version: '2.11'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '3.4'
40
+ version: '2.11'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: railties
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '4'
48
- - - "<"
49
- - !ruby/object:Gem::Version
50
- version: '5.2'
51
- type: :runtime
52
- prerelease: false
53
- version_requirements: !ruby/object:Gem::Requirement
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: '4'
58
- - - "<"
59
- - !ruby/object:Gem::Version
60
- version: '5.2'
61
- - !ruby/object:Gem::Dependency
62
- name: bourbon
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: '0'
68
- type: :runtime
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: '0'
75
- - !ruby/object:Gem::Dependency
76
- name: font-awesome-rails
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: '0'
47
+ version: '7.1'
82
48
  type: :runtime
83
49
  prerelease: false
84
50
  version_requirements: !ruby/object:Gem::Requirement
85
51
  requirements:
86
- - - ">="
52
+ - - "~>"
87
53
  - !ruby/object:Gem::Version
88
- version: '0'
54
+ version: '7.1'
89
55
  - !ruby/object:Gem::Dependency
90
- name: js-routes
56
+ name: sanitize
91
57
  requirement: !ruby/object:Gem::Requirement
92
58
  requirements:
93
- - - ">="
59
+ - - "~>"
94
60
  - !ruby/object:Gem::Version
95
- version: '0'
61
+ version: '6.1'
96
62
  type: :runtime
97
63
  prerelease: false
98
64
  version_requirements: !ruby/object:Gem::Requirement
99
65
  requirements:
100
- - - ">="
66
+ - - "~>"
101
67
  - !ruby/object:Gem::Version
102
- version: '0'
103
- - !ruby/object:Gem::Dependency
104
- name: modernizr-rails
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
- type: :runtime
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: '0'
117
- - !ruby/object:Gem::Dependency
118
- name: momentjs-rails
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - ">="
122
- - !ruby/object:Gem::Version
123
- version: '0'
124
- type: :runtime
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - ">="
129
- - !ruby/object:Gem::Version
130
- version: '0'
131
- description: |2
132
- A coffeescript/sass library that encapsulates common code that I use on
133
- multiple projects. It was originally based on Foundation 5, but nearly
134
- everything has been changed.
135
- email:
68
+ version: '6.1'
69
+ description:
70
+ email:
136
71
  executables: []
137
72
  extensions: []
138
73
  extra_rdoc_files: []
139
74
  files:
75
+ - config/initializers/jbuilder.rb
76
+ - config/initializers/renderers.rb
77
+ - config/initializers/sanitize.rb
78
+ - config/rubocop/default.yml
79
+ - config/rubocop/rails.yml
140
80
  - lib/fustrate-rails.rb
81
+ - lib/fustrate/rails/concerns/clean_attributes.rb
82
+ - lib/fustrate/rails/concerns/model.rb
83
+ - lib/fustrate/rails/concerns/sanitize_html.rb
141
84
  - lib/fustrate/rails/engine.rb
85
+ - lib/fustrate/rails/services/base.rb
86
+ - lib/fustrate/rails/services/generate_csv.rb
87
+ - lib/fustrate/rails/services/generate_excel.rb
88
+ - lib/fustrate/rails/services/log_edit.rb
89
+ - lib/fustrate/rails/spec_helper.rb
142
90
  - lib/fustrate/rails/version.rb
143
- - vendor/assets/javascripts/awesomplete.js
144
- - vendor/assets/javascripts/fustrate.coffee
145
- - vendor/assets/javascripts/fustrate/_module.coffee
146
- - vendor/assets/javascripts/fustrate/components/_module.coffee
147
- - vendor/assets/javascripts/fustrate/components/alert_box.coffee
148
- - vendor/assets/javascripts/fustrate/components/autocomplete.coffee
149
- - vendor/assets/javascripts/fustrate/components/disclosure.coffee
150
- - vendor/assets/javascripts/fustrate/components/drop_zone.coffee
151
- - vendor/assets/javascripts/fustrate/components/dropdown.coffee
152
- - vendor/assets/javascripts/fustrate/components/file_picker.coffee
153
- - vendor/assets/javascripts/fustrate/components/flash.coffee
154
- - vendor/assets/javascripts/fustrate/components/modal.coffee
155
- - vendor/assets/javascripts/fustrate/components/pagination.coffee
156
- - vendor/assets/javascripts/fustrate/components/tabs.coffee
157
- - vendor/assets/javascripts/fustrate/components/tooltip.coffee
158
- - vendor/assets/javascripts/fustrate/generic_form.coffee
159
- - vendor/assets/javascripts/fustrate/generic_page.coffee
160
- - vendor/assets/javascripts/fustrate/generic_table.coffee
161
- - vendor/assets/javascripts/fustrate/listenable.coffee
162
- - vendor/assets/javascripts/fustrate/object.coffee
163
- - vendor/assets/javascripts/fustrate/record.coffee
164
- - vendor/assets/stylesheets/_fustrate.sass
165
- - vendor/assets/stylesheets/awesomplete.sass
166
- - vendor/assets/stylesheets/fustrate/_colors.sass
167
- - vendor/assets/stylesheets/fustrate/_settings.sass
168
- - vendor/assets/stylesheets/fustrate/components/_components.sass
169
- - vendor/assets/stylesheets/fustrate/components/_functions.sass
170
- - vendor/assets/stylesheets/fustrate/components/alerts.sass
171
- - vendor/assets/stylesheets/fustrate/components/buttons.sass
172
- - vendor/assets/stylesheets/fustrate/components/disclosures.sass
173
- - vendor/assets/stylesheets/fustrate/components/dropdowns.sass
174
- - vendor/assets/stylesheets/fustrate/components/flash.sass
175
- - vendor/assets/stylesheets/fustrate/components/forms.sass
176
- - vendor/assets/stylesheets/fustrate/components/grid.sass
177
- - vendor/assets/stylesheets/fustrate/components/labels.sass
178
- - vendor/assets/stylesheets/fustrate/components/modals.sass
179
- - vendor/assets/stylesheets/fustrate/components/pagination.sass
180
- - vendor/assets/stylesheets/fustrate/components/panels.sass
181
- - vendor/assets/stylesheets/fustrate/components/popovers.sass
182
- - vendor/assets/stylesheets/fustrate/components/tables.sass
183
- - vendor/assets/stylesheets/fustrate/components/tabs.sass
184
- - vendor/assets/stylesheets/fustrate/components/tooltips.sass
185
- - vendor/assets/stylesheets/fustrate/components/typography.sass
186
91
  homepage: https://github.com/fustrate/fustrate-rails
187
92
  licenses:
188
93
  - MIT
189
- metadata: {}
190
- post_install_message:
94
+ metadata:
95
+ rubygems_mfa_required: 'true'
96
+ post_install_message:
191
97
  rdoc_options: []
192
98
  require_paths:
193
99
  - lib
@@ -195,17 +101,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
195
101
  requirements:
196
102
  - - ">="
197
103
  - !ruby/object:Gem::Version
198
- version: '0'
104
+ version: 3.3.0
199
105
  required_rubygems_version: !ruby/object:Gem::Requirement
200
106
  requirements:
201
107
  - - ">="
202
108
  - !ruby/object:Gem::Version
203
109
  version: '0'
204
110
  requirements: []
205
- rubyforge_project:
206
- rubygems_version: 2.6.8
207
- signing_key:
111
+ rubygems_version: 3.5.5
112
+ signing_key:
208
113
  specification_version: 4
209
- summary: JS/CSS framework customized to my preferences, long ago based on Foundation
210
- 5. Needs an actual name.
114
+ summary: A few useful services and initializers.
211
115
  test_files: []