common_core_js 0.1.1 → 0.3.4

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.generators +8 -0
  3. data/.gitignore +16 -0
  4. data/.rakeTasks +7 -0
  5. data/Gemfile +15 -0
  6. data/Gemfile.lock +175 -0
  7. data/LICENSE +2 -2
  8. data/README.md +147 -34
  9. data/app/assets/images/common_core_js/.keep +0 -0
  10. data/app/assets/stylesheets/common_core_js/common_core.scss +43 -0
  11. data/app/helpers/common_core_js/application_helper.rb +76 -0
  12. data/app/views/common/_common_create.js.erb +1 -1
  13. data/bin/rails +14 -0
  14. data/common_core_js.gemspec +70 -0
  15. data/lib/common_core_js.rb +20 -0
  16. data/lib/common_core_js/engine.rb +3 -1
  17. data/lib/common_core_js/version.rb +1 -1
  18. data/lib/generators/common_core/USAGE +2 -4
  19. data/lib/generators/common_core/install_generator.rb +22 -0
  20. data/lib/generators/common_core/scaffold_generator.rb +329 -30
  21. data/lib/generators/common_core/templates/_edit.haml +1 -1
  22. data/lib/generators/common_core/templates/_errors.haml +5 -0
  23. data/lib/generators/common_core/templates/_flash_notices.haml +7 -0
  24. data/lib/generators/common_core/templates/_form.haml +1 -0
  25. data/lib/generators/common_core/templates/_line.haml +5 -0
  26. data/lib/generators/common_core/templates/_list.haml +1 -1
  27. data/lib/generators/common_core/templates/_new.haml +1 -1
  28. data/lib/generators/common_core/templates/all.haml +5 -0
  29. data/lib/generators/common_core/templates/common_core.js +52 -0
  30. data/lib/generators/common_core/templates/common_core.scss +5 -0
  31. data/lib/generators/common_core/templates/controller.rb +6 -7
  32. data/lib/generators/common_core/templates/controller_spec.rb +110 -0
  33. data/lib/generators/common_core/templates/edit.js.erb +1 -1
  34. data/lib/generators/common_core/templates/update.js.erb +1 -1
  35. data/lib/tasks/common_core_js_tasks.rake +7 -4
  36. metadata +102 -41
File without changes
@@ -0,0 +1,43 @@
1
+
2
+ [data-role='close-button'] {
3
+ position: absolute;
4
+ top: 0;
5
+ right: 0;
6
+ }
7
+
8
+
9
+ i {
10
+ cursor: pointer;
11
+ }
12
+
13
+
14
+ .show-area{
15
+ span.content {
16
+ background-color: #ddd;
17
+ padding: 0px 6px;
18
+ display: inline-block;
19
+ }
20
+ }
21
+
22
+
23
+ td.paginate{
24
+ position: relative;
25
+ }
26
+
27
+ nav.pagination {
28
+ display: block;
29
+ text-align: right;
30
+ right: 0;
31
+ top: 0;
32
+
33
+ font-size: 1.1em;
34
+
35
+ span {
36
+ margin: 0 2px;
37
+ }
38
+ span.page.current {
39
+ color: black;
40
+ text-decoration: underline;
41
+
42
+ }
43
+ }
@@ -1,4 +1,80 @@
1
1
  module CommonCoreJs
2
2
  module ApplicationHelper
3
+
4
+ def datetime_field_localized(form_object, field_name, value, label, timezone = nil )
5
+ res = form_object.label(label,
6
+ field_name,
7
+ class: 'small form-text text-muted')
8
+
9
+ res << form_object.text_field(field_name, class: 'form-control',
10
+ type: 'datetime-local',
11
+ value: date_to_current_timezone(value, timezone))
12
+
13
+ res << human_timezone(Time.now, timezone)
14
+ res
15
+ end
16
+
17
+
18
+ def date_field_localized(form_object, field_name, value, label, timezone = nil )
19
+ res = form_object.label(label,
20
+ field_name,
21
+ class: 'small form-text text-muted')
22
+
23
+ res << form_object.text_field(field_name, class: 'form-control',
24
+ type: 'date',
25
+ value: value )
26
+
27
+ res
28
+ end
29
+
30
+ def time_field_localized(form_object, field_name, value, label, timezone = nil )
31
+ res = form_object.label(label,
32
+ field_name,
33
+ class: 'small form-text text-muted')
34
+
35
+ res << form_object.text_field(field_name, class: 'form-control',
36
+ type: 'time',
37
+ value: date_to_current_timezone(value, timezone))
38
+
39
+ res << human_timezone(Time.now, timezone)
40
+ res
41
+ end
42
+
43
+ def current_timezone
44
+ if method(:current_user)
45
+ if current_user.try(:timezone)
46
+ Time.now.in_time_zone(current_user.timezone).strftime("%z").to_i/100
47
+ else
48
+ Time.now.strftime("%z").to_i/100
49
+ end
50
+ else
51
+ raise "no method current_user is available or it does not implement timezone; please implement/override the method current_timezone"
52
+ end
53
+ end
54
+
55
+ def human_timezone(time_string, timezone)
56
+ time = time_string.in_time_zone(timezone)
57
+
58
+ if time.zone.match?(/^\w/)
59
+ time.zone
60
+ else
61
+ time.formatted_offset
62
+ end
63
+ end
64
+
65
+ def date_to_current_timezone(date, timezone = nil)
66
+ # if the timezone is nil, use the server date'
67
+ if timezone.nil?
68
+ timezone = Time.now.strftime("%z").to_i/100
69
+ end
70
+
71
+ return nil if date.nil?
72
+
73
+ begin
74
+ return date.in_time_zone(timezone).strftime("%Y-%m-%dT%H:%M")
75
+ rescue
76
+ return nil
77
+ end
78
+ end
3
79
  end
4
80
  end
@@ -8,7 +8,7 @@
8
8
 
9
9
  <% if object.errors.any? %>
10
10
  $(".flash-notices").html("<%= j render 'layouts/flash_notices' %>");
11
- $("<%= (scope + " ") if controller.common_scope %> .new-<%=singular%>-form").html("<%= j render(partial: '#{controller.namespace}errors', locals: {resource: object}) %>")
11
+ $("<%= (scope + " ") if controller.common_scope %> .new-<%=singular%>-form").html('<%= j render(partial: "#{controller.namespace}errors", locals: {resource: object}) %>')
12
12
  $("<%= (scope + " ") if controller.common_scope %> .new-<%=singular%>-form").append("<%= j render(partial: "new", locals: { singular.to_sym => object}) %><i class='fa fa-times-circle fa-2x' data-name='<%=singular%>' data-role='close-button' />").slideDown();
13
13
  <% else %>
14
14
  $("<%= (scope + " ") if controller.common_scope %> .new-<%=singular%>-form").slideUp();
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('..', __dir__)
6
+ ENGINE_PATH = File.expand_path('../lib/common_core_js/engine', __dir__)
7
+ APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
8
+
9
+ # Set up gems listed in the Gemfile.
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
11
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
12
+
13
+ require 'rails/all'
14
+ require 'rails/engine/commands'
@@ -0,0 +1,70 @@
1
+ $:.push File.expand_path("lib", __dir__)
2
+
3
+ # Maintain your gem's version:
4
+ require "common_core_js/version"
5
+ require 'byebug'
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "common_core_js"
9
+ spec.version = CommonCoreJs::VERSION
10
+ spec.license = 'MIT'
11
+ spec.date = '2020-06-28'
12
+ spec.summary = "A gem build scaffolding."
13
+ spec.description = "Simple, plug & play Rails scaffolding with really simple Javascript"
14
+ spec.authors = ["Jason Fleetwood-Boldt"]
15
+ spec.email = 'jason.fb@datatravels.com'
16
+
17
+
18
+
19
+
20
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
21
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
22
+ if spec.respond_to?(:metadata)
23
+ spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
24
+ else
25
+ raise "RubyGems 2.0 or newer is required to protect against " \
26
+ "public gem pushes."
27
+ end
28
+
29
+ # spec.files = Dir["{app,config,db,lib,vendor}/**/*", "LICENSE", "Rakefile", "README.md"]
30
+
31
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
+ end
34
+
35
+ spec.add_dependency "rails"
36
+ spec.homepage = 'https://blog.jasonfleetwoodboldt.com/common-core-js/'
37
+ spec.metadata = { "source_code_uri" => "https://github.com/jasonfb/common_core_js",
38
+ "documentation_uri" => "https://github.com/jasonfb/common_core_js",
39
+ "homepage_uri" => 'https://blog.jasonfleetwoodboldt.com/common-core-js/',
40
+ "mailing_list_uri" => 'https://blog.jasonfleetwoodboldt.com/#sfba-form2-container'
41
+ }
42
+
43
+ spec.add_runtime_dependency('kaminari')
44
+ spec.add_runtime_dependency('haml-rails')
45
+ spec.add_runtime_dependency "sass-rails"
46
+
47
+ spec.add_runtime_dependency 'bootsnap'
48
+ spec.add_runtime_dependency 'bootstrap'
49
+ spec.add_runtime_dependency 'font-awesome-rails'
50
+ spec.add_dependency 'ffaker'
51
+
52
+ spec.post_install_message = <<~MSG
53
+ ---------------------------------------------
54
+ Welcome to Common Core
55
+
56
+ rails generate common_score:scaffold Thing
57
+
58
+ * Build plug-and-play scaffolding mixing HAML with jQuery-based Javascript
59
+ * Automatically Reads Your Models (make them before building your scaffolding!)
60
+ * Excellent for CRUD, lists with pagination, searching, sorting.
61
+ * Wonderful for prototyping.
62
+ * Plays nicely with Devise, Kaminari, Haml-Rails, Rspec.
63
+ * Create specs autoamatically along with the controllers.
64
+ * Nest your routes model-by-model for built-in poor man's authentication
65
+ * Throw the scaffolding away when your app is ready to graduate to its next phase.
66
+
67
+ see README for complete instructions.
68
+ ---------------------------------------------
69
+ MSG
70
+ end
@@ -6,4 +6,24 @@ require 'haml-rails'
6
6
 
7
7
  module CommonCoreJs
8
8
  # Your code goes here...
9
+ #
10
+ module ControllerHelpers
11
+ def modify_date_inputs_on_params(modified_params, authenticated_user = nil)
12
+ use_timezone = authenticated_user.timezone || Time.now.strftime("%z")
13
+
14
+ modified_params = modified_params.tap do |params|
15
+ params.keys.each{|k|
16
+ if k.ends_with?("_at") || k.ends_with?("_date")
17
+
18
+ begin
19
+ params[k] = DateTime.strptime("#{params[k]} #{use_timezone}", '%Y-%m-%dT%H:%M %z')
20
+ rescue StandardError
21
+
22
+ end
23
+ end
24
+ }
25
+ end
26
+ modified_params
27
+ end
28
+ end
9
29
  end
@@ -1,5 +1,7 @@
1
1
  module CommonCoreJs
2
2
  class Engine < ::Rails::Engine
3
- isolate_namespace CommonCoreJs
3
+ # isolate_namespace CommonCoreJs
4
+
5
+
4
6
  end
5
7
  end
@@ -1,3 +1,3 @@
1
1
  module CommonCoreJs
2
- VERSION = '0.1.1'
2
+ VERSION = '0.3.4'
3
3
  end
@@ -1,8 +1,6 @@
1
1
  Description:
2
- Explain the generator
2
+ Generate a controller, view files, and spec
3
3
 
4
4
  Example:
5
- rails generate common_core_scaffold Thing
5
+ rails generate common_core:scaffold Thing
6
6
 
7
- This will create:
8
- what/will/it/create
@@ -0,0 +1,22 @@
1
+ require 'rails/generators/erb/scaffold/scaffold_generator'
2
+ require 'ffaker'
3
+
4
+ module CommonCore
5
+ class InstallGenerator < Rails::Generators::Base
6
+ hook_for :form_builder, :as => :scaffold
7
+
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+
11
+ def initialize(*args) #:nodoc:
12
+ super
13
+ copy_file "common_core.js", "app/javascript/common_core.js"
14
+ copy_file "common_core.scss", "app/assets/stylesheets/common_core.scss"
15
+ copy_file "_flash_notices.haml", "app/views/layouts/_flash_notices.haml"
16
+
17
+ end
18
+ end
19
+ end
20
+
21
+
22
+
@@ -1,15 +1,46 @@
1
1
  require 'rails/generators/erb/scaffold/scaffold_generator'
2
+ require 'ffaker'
3
+
4
+
2
5
 
3
6
  module CommonCore
4
- class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
7
+
8
+ module GeneratorHelper
9
+ def text_area_output(col, field_length)
10
+ lines = field_length % 40
11
+ if lines > 5
12
+ lines = 5
13
+ end
14
+
15
+ ".row
16
+ %div{class: \"form-group col-md-4 \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
17
+ = f.text_area :#{col.to_s}, class: 'form-control', cols: 40, rows: '#{lines}'
18
+ %label.form-text
19
+ #{col.to_s.humanize}\n"
20
+ end
5
21
 
6
22
 
23
+
24
+ def field_output(col, type = nil, width)
25
+ ".row
26
+ %div{class: \"form-group col-md-4 \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
27
+ = f.text_field :#{col.to_s}, value: @#{singular}.#{col.to_s}, size: #{width}, class: 'form-control', type: '#{type}'
28
+ %label.form-text
29
+ #{col.to_s.humanize}\n"
30
+ end
31
+ end
32
+
33
+
34
+ class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
7
35
  hook_for :form_builder, :as => :scaffold
8
36
 
9
37
  source_root File.expand_path('templates', __dir__)
10
38
  attr_accessor :path, :singular, :plural, :singular_class, :nest_with
11
39
 
12
40
 
41
+ include GeneratorHelper
42
+
43
+
13
44
  def initialize(*meta_args) #:nodoc:
14
45
  super
15
46
 
@@ -20,21 +51,12 @@ module CommonCore
20
51
  exit
21
52
  end
22
53
 
23
- begin
24
- @columns = object.columns.map(&:name).map(&:to_sym).reject{|x| x==:updated_at || x==:created_at || x==:id}
25
- rescue StandardError => e
26
- puts "Ooops... it looks like is an object for #{class_name}. Please create the database table with fields first. "
27
- exit
28
- end
54
+
29
55
 
30
56
  args = meta_args[0]
31
57
  @singular = args[0].tableize.singularize # should be in form hello_world
32
58
 
33
59
 
34
-
35
-
36
-
37
-
38
60
  @plural = @singular + "s" # supply to override; leave blank to use default
39
61
  @singular_class = @singular.titleize.gsub(" ", "")
40
62
  @nest = nil
@@ -61,8 +83,18 @@ module CommonCore
61
83
  end
62
84
  end
63
85
 
86
+ auth_assoc = @auth.gsub("current_","")
87
+ auth_assoc_field = auth_assoc + "_id"
64
88
 
65
89
 
90
+ begin
91
+ @columns = object.columns.map(&:name).map(&:to_sym).reject{|field| field==:updated_at ||
92
+ field==:created_at || field==:id || field == auth_assoc_field.to_sym }
93
+ rescue StandardError => e
94
+ puts "Ooops... it looks like is an object for #{class_name}. Please create the database table with fields first. "
95
+ exit
96
+ end
97
+
66
98
  flags = meta_args[1]
67
99
  flags.each do |f|
68
100
  case (f)
@@ -70,10 +102,17 @@ module CommonCore
70
102
  @auth = nil
71
103
  when "--with-index"
72
104
  @with_index = true
105
+ when "--specs-only"
106
+ @specs_only = true
107
+ when "--no-specs"
108
+ @no_specs = true
73
109
  end
74
110
  end
75
111
 
76
-
112
+ if @specs_only && @no_specs
113
+ puts "oops… you seem to have specified both the --specs-only flag and --no-specs flags. this doesn't make any sense, so I am aborting. sorry."
114
+ exit
115
+ end
77
116
 
78
117
  if @auth_identifier.nil? && !@auth.nil?
79
118
  @auth_identifier = @auth.gsub("current_", "")
@@ -86,7 +125,6 @@ module CommonCore
86
125
  @nested_args.each do |a|
87
126
  @nested_args_plural[a] = a + "s"
88
127
  end
89
-
90
128
  end
91
129
  end
92
130
 
@@ -99,20 +137,77 @@ module CommonCore
99
137
  end
100
138
 
101
139
  def copy_controller_and_spec_files
102
-
103
140
  @default_colspan = @columns.size
104
- template "controller.rb", File.join("app/controllers", "#{plural}_controller.rb")
105
- # template "index", File.join("app/views", "app/views/#{self.name.downcase}/index")
106
141
 
107
- end
142
+ unless @specs_only
143
+ template "controller.rb", File.join("app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
144
+ end
145
+
146
+ unless @no_specs
147
+ template "controller_spec.rb", File.join("spec/controllers#{namespace_with_dash}", "#{plural}_controller_spec.rb")
148
+ end
108
149
 
150
+ template "_errors.haml", File.join("app/views#{namespace_with_dash}", "_errors.haml")
151
+ end
109
152
 
110
153
  def list_column_headings
111
154
  @columns.map(&:to_s).map{|col_name| ' %th{:scope => "col"} ' + col_name.humanize}.join("\r")
112
155
  end
113
156
 
157
+ def columns_spec_with_sample_data
158
+ @columns.map { |c|
159
+ if eval("#{singular_class}.columns_hash['#{c}']").nil?
160
+ byebug
161
+ end
162
+ type = eval("#{singular_class}.columns_hash['#{c}']").type
163
+ random_data = case type
164
+ when :integer
165
+ rand(1...1000)
166
+ when :string
167
+ FFaker::AnimalUS.common_name
168
+ when :text
169
+ FFaker::AnimalUS.common_name
170
+ when :datetime
171
+ Time.now + rand(1..5).days
172
+ end
173
+ c.to_s + ": '" + random_data.to_s + "'"
174
+ }.join(", ")
175
+ end
176
+
177
+ def object_parent_mapping_as_argument_for_specs
178
+ if @nested_args.any?
179
+ ", " + @nested_args.last + ": " + @nested_args.last
180
+ elsif @auth
181
+ ", #{@auth_identifier}: #{@auth}"
182
+ end
183
+ end
184
+
185
+ def objest_nest_factory_setup
186
+ res = ""
187
+ if @auth
188
+ last_parent = ", #{@auth_identifier}: #{@auth}"
189
+ end
190
+
191
+ @nested_args.each do |arg|
192
+ res << " let(:#{arg}) {create(:#{arg} #{last_parent} )}\n"
193
+ last_parent = ", #{arg}: #{arg}"
194
+ end
195
+ res
196
+ end
197
+
198
+
199
+ def objest_nest_params_by_id_for_specs
200
+ @nested_args.map{|arg|
201
+ "#{arg}_id: #{arg}.id"
202
+ }.join(",\n ")
203
+ end
204
+
205
+
114
206
  def controller_class_name
115
- plural.titleize.gsub(" ", "") + "Controller"
207
+ res = ""
208
+ res << @namespace.titleize + "::" if @namespace
209
+ res << plural.titleize.gsub(" ", "") + "Controller"
210
+ res
116
211
  end
117
212
 
118
213
  def singular_name
@@ -128,20 +223,26 @@ module CommonCore
128
223
  end
129
224
 
130
225
 
131
- def path_helper
226
+ def path_helper_singular
132
227
  "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{singular}_path"
133
228
  end
134
229
 
230
+ def path_helper_plural
231
+ "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{plural}_path"
232
+ end
135
233
 
136
234
  def path_arity
137
- (nested_objects_arity + ", " if @nested_args) + "@" + singular
235
+ res = ""
236
+ if @nested_args.any?
237
+ res << nested_objects_arity + ", "
238
+ end
239
+ res << "@" + singular
138
240
  end
139
241
 
140
242
  def line_path_partial
141
- "#{@namespace+"/" if @namespace}#{singular}/line"
243
+ "#{@namespace+"/" if @namespace}#{plural}/line"
142
244
  end
143
245
 
144
-
145
246
  def nested_assignments
146
247
  @nested_args.map{|a| "#{a}: @#{a}"}.join(", ") #metaprgramming into Ruby hash
147
248
  end
@@ -166,13 +267,26 @@ module CommonCore
166
267
  end
167
268
  end
168
269
 
270
+
271
+ def all_objects_root
272
+ if @auth
273
+ if @nested_args.none?
274
+ @auth + ".#{plural}"
275
+ else
276
+ "@" + @nested_args.last + ".#{plural}"
277
+ end
278
+ else
279
+ @singular_class + ".all"
280
+ end
281
+ end
282
+
169
283
  def any_nested?
170
284
  @nested_args.any?
171
285
  end
172
286
 
173
287
  def all_objects_variable
174
288
  # needs the authenticated root user
175
- "#{@auth}#{'.' + @nested_args.map{|a| "#{@nested_args_plural[a]}.find(@#{a})"}.join('.') + "." if @nested_args}#{plural}"
289
+ "#{@auth}.#{ @nested_args.map{|a| "#{@nested_args_plural[a]}.find(@#{a})"}.join('.') + "." if @nested_args.any?}#{plural}"
176
290
  end
177
291
 
178
292
  def auth_object
@@ -180,29 +294,49 @@ module CommonCore
180
294
  end
181
295
 
182
296
  def copy_view_files
297
+ return if @specs_only
183
298
  js_views.each do |view|
184
299
  formats.each do |format|
185
-
186
300
  filename = cc_filename_with_extensions(view, ["js","erb"])
187
- template filename, File.join("app/views", controller_file_path, filename)
301
+ template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
188
302
  end
189
303
  end
190
304
 
305
+
191
306
  haml_views.each do |view|
192
307
  formats.each do |format|
193
-
194
308
  filename = cc_filename_with_extensions(view, "haml")
195
- template filename, File.join("app/views", controller_file_path, filename)
309
+ template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
196
310
  end
197
311
  end
198
312
  end
199
313
 
314
+ def namespace_with_dash
315
+ if @namespace
316
+ "/#{@namespace}"
317
+ else
318
+ ""
319
+ end
320
+ end
321
+
322
+ def namespace_with_trailing_dash
323
+ if @namespace
324
+ "#{@namespace}/"
325
+ else
326
+ ""
327
+ end
328
+ end
329
+
200
330
  def js_views
201
331
  %w(index create destroy edit new update)
202
332
  end
203
333
 
204
334
  def haml_views
205
- %w(_edit _form _line _list _new)
335
+ res = %w(_edit _form _line _list _new)
336
+ if @with_index
337
+ res << 'all'
338
+ end
339
+ res
206
340
  end
207
341
 
208
342
 
@@ -214,11 +348,11 @@ module CommonCore
214
348
  def create_merge_params
215
349
  if @auth
216
350
  "#{@auth_identifier}: #{@auth}"
351
+ else
352
+ ""
217
353
  end
218
354
  end
219
355
 
220
-
221
-
222
356
  def model_has_strings?
223
357
  false
224
358
  end
@@ -228,6 +362,171 @@ module CommonCore
228
362
  []
229
363
  end
230
364
 
365
+ def all_form_fields
366
+ res = @columns.map { |col|
367
+
368
+
369
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
370
+ limit = eval("#{singular_class}.columns_hash['#{col}']").limit
371
+ sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
372
+
373
+ case type
374
+ when :integer
375
+ # look for a belongs_to on this object
376
+ if col.to_s.ends_with?("_id")
377
+ # guess the association name label
378
+
379
+
380
+ assoc_name = col.to_s.gsub("_id","")
381
+ assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
382
+ if assoc.nil?
383
+ puts "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
384
+ exit
385
+ end
386
+
387
+ if assoc.active_record.column_names.include?("name")
388
+ display_column = "name"
389
+ elsif assoc.active_record.column_names.include?("to_label")
390
+ display_column = "to_label"
391
+ elsif assoc.active_record.column_names.include?("full_name")
392
+ display_column = "full_name"
393
+ elsif assoc.active_record.column_names.include?("display_name")
394
+ display_column = "display_name"
395
+ elsif assoc.active_record.column_names.include?("email")
396
+ display_column = "email"
397
+ end
398
+
399
+ ".row
400
+ %div{class: \"form-group col-md-4 \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{assoc_name.to_s})}\"}
401
+ = f.collection_select(:#{col.to_s}, #{assoc_name.titleize}.all, :id, :#{display_column}, {prompt: true, selected: @#{singular}.#{col.to_s} }, class: 'form-control')
402
+ %label.small.form-text.text-muted
403
+ #{col.to_s.humanize}"
404
+
405
+ else
406
+ ".row
407
+ %div{class: \"form-group col-md-4 \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
408
+ = f.text_field :#{col.to_s}, value: @#{singular}.#{col.to_s}, class: 'form-control', size: 4, type: 'number'
409
+ %label.form-text
410
+ #{col.to_s.humanize}\n"
411
+ end
412
+ when :string
413
+ limit ||= 40
414
+ if limit < 50
415
+ field_output(col, nil, limit)
416
+ else
417
+ text_area_output(col, limit)
418
+ end
419
+
420
+ when :text
421
+ limit ||= 40
422
+ if limit < 50
423
+ field_output(col, nil, limit)
424
+ else
425
+ text_area_output(col, limit)
426
+ end
427
+
428
+ when :datetime
429
+ ".row
430
+ %div{class: \"form-group col-md-4 \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
431
+ = datetime_field_localized(f, :#{col.to_s}, @#{singular}.#{col.to_s}, '#{col.to_s.humanize}', #{@auth}.timezone)"
432
+ when :date
433
+ ".row
434
+ %div{class: \"form-group col-md-4 \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
435
+ = date_field_localized(f, :#{col.to_s}, @#{singular}.#{col.to_s}, '#{col.to_s.humanize}', #{@auth}.timezone)"
436
+ when :time
437
+ ".row
438
+ %div{class: \"form-group col-md-4 \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
439
+ = time_field_localized(f, :#{col.to_s}, @#{singular}.#{col.to_s}, '#{col.to_s.humanize}', #{@auth}.timezone)"
440
+
441
+ end
442
+
443
+ }.join("\n")
444
+ return res
445
+ end
446
+
447
+
448
+ def all_line_fields
449
+ res = "%tr{'data-id': #{singular}.id, 'data-edit': 'false'}\n"
450
+
451
+ res << @columns.map { |col|
452
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
453
+ limit = eval("#{singular_class}.columns_hash['#{col}']").limit
454
+ sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
455
+
456
+ case type
457
+ when :integer
458
+ # look for a belongs_to on this object
459
+ if col.to_s.ends_with?("_id")
460
+
461
+ assoc_name = col.to_s.gsub("_id","")
462
+
463
+
464
+ assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
465
+
466
+ if assoc.nil?
467
+ puts "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
468
+ exit
469
+ end
470
+
471
+ if assoc.active_record.column_names.include?("name")
472
+ display_column = "name"
473
+ elsif assoc.active_record.column_names.include?("to_label")
474
+ display_column = "to_label"
475
+ elsif assoc.active_record.column_names.include?("full_name")
476
+ display_column = "full_name"
477
+ elsif assoc.active_record.column_names.include?("display_name")
478
+ display_column = "display_name"
479
+ elsif assoc.active_record.column_names.include?("email")
480
+ display_column = "email"
481
+ else
482
+ puts "cant find any column to use as label for #{assoc.name.to_s}; any of name, to_labe, full_name, display_name, or email"
483
+ end
484
+
485
+ " %td
486
+ = #{singular}.#{assoc.name.to_s}.#{display_column}"
487
+
488
+ else
489
+ " %td
490
+ = #{singular}.#{col}"
491
+ end
492
+ when :string
493
+ width = (limit && limit < 40) ? limit : (40)
494
+ " %td
495
+ = #{singular}.#{col}"
496
+ when :text
497
+ " %td
498
+ = #{singular}.#{col}"
499
+ when :datetime
500
+ " %td
501
+ - unless #{singular}.#{col}.nil?
502
+ = #{singular}.#{col}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ') + human_timezone(Time.now, current_timezone)
503
+ - else
504
+ %span.alert-danger
505
+ MISSING
506
+ "
507
+ when :date
508
+ " %td
509
+ - unless #{singular}.#{col}.nil?
510
+ = #{singular}.#{col}
511
+ - else
512
+ %span.alert-danger
513
+ MISSING
514
+ "
515
+ when :time
516
+ " %td
517
+ - unless #{singular}.#{col}.nil?
518
+ = #{singular}.#{col}.in_time_zone(current_timezone).strftime('%l:%M %p ') + human_timezone(Time.now, current_timezone)
519
+ - else
520
+ %span.alert-danger
521
+ MISSING
522
+ "
523
+
524
+ end
525
+ }.join("\n")
526
+ return res
527
+ end
528
+
529
+
231
530
 
232
531
  private # thor does something fancy like sending the class all of its own methods during some strange run sequence
233
532
  # does not like public methods