common_core_js 0.1.1 → 0.3.0

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.
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
+ }
@@ -0,0 +1,37 @@
1
+
2
+ require("jquery")
3
+ console.log("loading common core...")
4
+ debugger
5
+ $(function(){
6
+ // always pass csrf tokens on ajax calls
7
+ $.ajaxSetup({
8
+ headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
9
+ });
10
+ });
11
+
12
+ $(document).on('turbolinks:load', function() {
13
+ $(document).ready(() => {
14
+ $("body").on("click", "[data-role='close-button']", (event) => {
15
+ var form_name;
16
+ form_name = $(event.currentTarget).data("name");
17
+ row_id = $(event.currentTarget).data("row-id");
18
+
19
+ if (row_id) {
20
+ $("table." + form_name + "-table tr[data-id=" + row_id + "][data-edit='true']").remove()
21
+ $("table." + form_name + "-table tr[data-id=" + row_id + "]:not([data-edit='true'])").fadeIn()
22
+ $("table." + form_name + "-table tr[data-id=" + row_id + "]:not([data-edit='true']) .show-area").show()
23
+ } else {
24
+ if ($(".new-" + form_name + "-form").length == 0) {
25
+ throw("ERROR: not found" + " .new-" + form_name + "-form")
26
+ }
27
+ var $form = $(event.currentTarget).closest(".new-" + form_name + "-form")
28
+ $form.slideUp()
29
+ $form.siblings(".new-" + form_name + "-button").fadeIn()
30
+ $form.find("i").remove()
31
+ }
32
+ })
33
+ })
34
+ });
35
+
36
+
37
+
@@ -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,69 @@
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
+
51
+ spec.post_install_message = <<~MSG
52
+ ---------------------------------------------
53
+ Welcome to Common Core
54
+
55
+ rails generate common_score:scaffold Thing
56
+
57
+ * Build plug-and-play scaffolding mixing HAML with jQuery-based Javascript
58
+ * Automatically Reads Your Models (make them before building your scaffolding!)
59
+ * Excellent for CRUD, lists with pagination, searching, sorting.
60
+ * Wonderful for prototyping.
61
+ * Plays nicely with Devise, Kaminari, Haml-Rails, Rspec.
62
+ * Create specs autoamatically along with the controllers.
63
+ * Nest your routes model-by-model for built-in poor man's authentication
64
+ * Throw the scaffolding away when your app is ready to graduate to its next phase.
65
+
66
+ see README for complete instructions.
67
+ ---------------------------------------------
68
+ MSG
69
+ end
@@ -1,5 +1,5 @@
1
1
  module CommonCoreJs
2
2
  class Engine < ::Rails::Engine
3
- isolate_namespace CommonCoreJs
3
+ # isolate_namespace CommonCoreJs
4
4
  end
5
5
  end
@@ -1,3 +1,3 @@
1
1
  module CommonCoreJs
2
- VERSION = '0.1.1'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -2,8 +2,6 @@ require 'rails/generators/erb/scaffold/scaffold_generator'
2
2
 
3
3
  module CommonCore
4
4
  class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
5
-
6
-
7
5
  hook_for :form_builder, :as => :scaffold
8
6
 
9
7
  source_root File.expand_path('templates', __dir__)
@@ -31,10 +29,6 @@ module CommonCore
31
29
  @singular = args[0].tableize.singularize # should be in form hello_world
32
30
 
33
31
 
34
-
35
-
36
-
37
-
38
32
  @plural = @singular + "s" # supply to override; leave blank to use default
39
33
  @singular_class = @singular.titleize.gsub(" ", "")
40
34
  @nest = nil
@@ -61,8 +55,6 @@ module CommonCore
61
55
  end
62
56
  end
63
57
 
64
-
65
-
66
58
  flags = meta_args[1]
67
59
  flags.each do |f|
68
60
  case (f)
@@ -70,10 +62,17 @@ module CommonCore
70
62
  @auth = nil
71
63
  when "--with-index"
72
64
  @with_index = true
65
+ when "--specs-only"
66
+ @specs_only = true
67
+ when "--no-specs"
68
+ @no_specs = true
73
69
  end
74
70
  end
75
71
 
76
-
72
+ if @specs_only && @no_specs
73
+ 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."
74
+ exit
75
+ end
77
76
 
78
77
  if @auth_identifier.nil? && !@auth.nil?
79
78
  @auth_identifier = @auth.gsub("current_", "")
@@ -86,7 +85,6 @@ module CommonCore
86
85
  @nested_args.each do |a|
87
86
  @nested_args_plural[a] = a + "s"
88
87
  end
89
-
90
88
  end
91
89
  end
92
90
 
@@ -99,20 +97,75 @@ module CommonCore
99
97
  end
100
98
 
101
99
  def copy_controller_and_spec_files
102
-
103
100
  @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
101
 
107
- end
102
+ unless @specs_only
103
+ template "controller.rb", File.join("app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
104
+ end
108
105
 
106
+ unless @no_specs
107
+ template "controller_spec.rb", File.join("spec/controllers#{namespace_with_dash}", "#{plural}_controller_spec.rb")
108
+ end
109
+ end
109
110
 
110
111
  def list_column_headings
111
112
  @columns.map(&:to_s).map{|col_name| ' %th{:scope => "col"} ' + col_name.humanize}.join("\r")
112
113
  end
113
114
 
115
+ def columns_spec_with_sample_data
116
+ @columns.map { |c|
117
+ if eval("#{singular_class}.columns_hash['#{c}']").nil?
118
+ byebug
119
+ end
120
+ type = eval("#{singular_class}.columns_hash['#{c}']").type
121
+ random_data = case type
122
+ when :integer
123
+ rand(1...1000)
124
+ when :string
125
+ FFaker::AnimalUS.common_name
126
+ when :text
127
+ FFaker::AnimalUS.common_name
128
+ when :datetime
129
+ Time.now + rand(1..5).days
130
+ end
131
+ c.to_s + ": '" + random_data.to_s + "'"
132
+ }.join(", ")
133
+ end
134
+
135
+ def object_parent_mapping_as_argument_for_specs
136
+ if @nested_args.any?
137
+ ", " + @nested_args.last + ": " + @nested_args.last
138
+ elsif @auth
139
+ ", #{@auth_identifier}: #{@auth}"
140
+ end
141
+ end
142
+
143
+ def objest_nest_factory_setup
144
+ res = ""
145
+ if @auth
146
+ last_parent = ", #{@auth_identifier}: #{@auth}"
147
+ end
148
+
149
+ @nested_args.each do |arg|
150
+ res << " let(:#{arg}) {create(:#{arg} #{last_parent} )}\n"
151
+ last_parent = ", #{arg}: #{arg}"
152
+ end
153
+ res
154
+ end
155
+
156
+
157
+ def objest_nest_params_by_id_for_specs
158
+ @nested_args.map{|arg|
159
+ "#{arg}_id: #{arg}.id"
160
+ }.join(",\n ")
161
+ end
162
+
163
+
114
164
  def controller_class_name
115
- plural.titleize.gsub(" ", "") + "Controller"
165
+ res = ""
166
+ res << @namespace.titleize + "::" if @namespace
167
+ res << plural.titleize.gsub(" ", "") + "Controller"
168
+ res
116
169
  end
117
170
 
118
171
  def singular_name
@@ -128,20 +181,26 @@ module CommonCore
128
181
  end
129
182
 
130
183
 
131
- def path_helper
184
+ def path_helper_singular
132
185
  "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{singular}_path"
133
186
  end
134
187
 
188
+ def path_helper_plural
189
+ "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{plural}_path"
190
+ end
135
191
 
136
192
  def path_arity
137
- (nested_objects_arity + ", " if @nested_args) + "@" + singular
193
+ res = ""
194
+ if @nested_args.any?
195
+ res << nested_objects_arity + ", "
196
+ end
197
+ res << "@" + singular
138
198
  end
139
199
 
140
200
  def line_path_partial
141
- "#{@namespace+"/" if @namespace}#{singular}/line"
201
+ "#{@namespace+"/" if @namespace}#{plural}/line"
142
202
  end
143
203
 
144
-
145
204
  def nested_assignments
146
205
  @nested_args.map{|a| "#{a}: @#{a}"}.join(", ") #metaprgramming into Ruby hash
147
206
  end
@@ -166,13 +225,26 @@ module CommonCore
166
225
  end
167
226
  end
168
227
 
228
+
229
+ def all_objects_root
230
+ if @auth
231
+ if @nested_args.none?
232
+ @auth + ".#{plural}"
233
+ else
234
+ "@" + @nested_args.last + ".#{plural}"
235
+ end
236
+ else
237
+ @singular_class + ".all"
238
+ end
239
+ end
240
+
169
241
  def any_nested?
170
242
  @nested_args.any?
171
243
  end
172
244
 
173
245
  def all_objects_variable
174
246
  # needs the authenticated root user
175
- "#{@auth}#{'.' + @nested_args.map{|a| "#{@nested_args_plural[a]}.find(@#{a})"}.join('.') + "." if @nested_args}#{plural}"
247
+ "#{@auth}.#{ @nested_args.map{|a| "#{@nested_args_plural[a]}.find(@#{a})"}.join('.') + "." if @nested_args.any?}#{plural}"
176
248
  end
177
249
 
178
250
  def auth_object
@@ -180,29 +252,49 @@ module CommonCore
180
252
  end
181
253
 
182
254
  def copy_view_files
255
+ return if @specs_only
183
256
  js_views.each do |view|
184
257
  formats.each do |format|
185
-
186
258
  filename = cc_filename_with_extensions(view, ["js","erb"])
187
- template filename, File.join("app/views", controller_file_path, filename)
259
+ template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
188
260
  end
189
261
  end
190
262
 
263
+
191
264
  haml_views.each do |view|
192
265
  formats.each do |format|
193
-
194
266
  filename = cc_filename_with_extensions(view, "haml")
195
- template filename, File.join("app/views", controller_file_path, filename)
267
+ template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
196
268
  end
197
269
  end
198
270
  end
199
271
 
272
+ def namespace_with_dash
273
+ if @namespace
274
+ "/#{@namespace}"
275
+ else
276
+ ""
277
+ end
278
+ end
279
+
280
+ def namespace_with_trailing_dash
281
+ if @namespace
282
+ "#{@namespace}/"
283
+ else
284
+ ""
285
+ end
286
+ end
287
+
200
288
  def js_views
201
289
  %w(index create destroy edit new update)
202
290
  end
203
291
 
204
292
  def haml_views
205
- %w(_edit _form _line _list _new)
293
+ res = %w(_edit _form _line _list _new)
294
+ if @with_index
295
+ res << 'all'
296
+ end
297
+ res
206
298
  end
207
299
 
208
300
 
@@ -214,11 +306,11 @@ module CommonCore
214
306
  def create_merge_params
215
307
  if @auth
216
308
  "#{@auth_identifier}: #{@auth}"
309
+ else
310
+ ""
217
311
  end
218
312
  end
219
313
 
220
-
221
-
222
314
  def model_has_strings?
223
315
  false
224
316
  end
@@ -228,6 +320,106 @@ module CommonCore
228
320
  []
229
321
  end
230
322
 
323
+ def all_form_fields
324
+ res = @columns.map { |col|
325
+ # if eval("#{singular_class}.columns_hash['#{col}']").nil?
326
+ # byebug
327
+ # end
328
+
329
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
330
+ limit = eval("#{singular_class}.columns_hash['#{col}']").limit
331
+ sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
332
+
333
+ case type
334
+ when :integer
335
+ # look for a belongs_to on this object
336
+ if col.to_s.ends_with?("_id")
337
+
338
+ assoc_name = col.to_s.gsub("_id","")
339
+ assoc = eval("#{singular_class}.reflect_on_association(':#{assoc_name}')")
340
+ ".row
341
+ .form-group.col-md-4
342
+ = f.collection_select(:#{col.to_s}, #{assoc_name.titleize}.all, :id, :to_label, {:prompt => true}, class: 'form-control')
343
+ %label.small.form-text.text-muted
344
+ #{col.to_s.humanize}"
345
+
346
+ else
347
+ ".row
348
+ .form-group.col-md-4
349
+ = f.text_field :#{col.to_s}, class: 'form-control', size: 4, type: 'number'
350
+ %label.form-text
351
+ #{col.to_s.humanize}\n"
352
+ end
353
+ when :string
354
+ width = (limit && limit < 40) ? limit : (40)
355
+ ".row
356
+ .form-group.col-md-4
357
+ = f.text_field :#{col.to_s}, size: #{width}, class: 'form-control'
358
+ %label.form-text
359
+ #{col.to_s.humanize}\n"
360
+ when :text
361
+ # width = (limit && limit < 40) ? limit : (40)
362
+ ".row
363
+ .form-group.col-md-4
364
+ = f.text_area :#{col.to_s}, rows: 4, cols: 40, class: 'form-control'
365
+ %label.form-text
366
+ #{col.humanize}\n"
367
+ when :datetime
368
+ ".row
369
+ .form-group.col-md-4
370
+ = f.text_field :#{col.to_s}, class: 'form-control', type: 'datetime-local'
371
+ %label.form-text
372
+ #{col.to_s.humanize}\n"
373
+ end
374
+ }.join("\n")
375
+ return res
376
+ end
377
+
378
+ def all_line_fields
379
+ res = "%tr{'data-id': #{singular}.id, 'data-edit': 'false'}\n"
380
+
381
+ res << @columns.map { |col|
382
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
383
+ limit = eval("#{singular_class}.columns_hash['#{col}']").limit
384
+ sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
385
+
386
+ case type
387
+ when :integer
388
+ # look for a belongs_to on this object
389
+ if col.to_s.ends_with?("_id")
390
+
391
+ assoc_name = col.to_s.gsub("_id","")
392
+
393
+
394
+ assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
395
+
396
+ if assoc.nil?
397
+ raise "can't find assocation for #{assoc_name}"
398
+ end
399
+
400
+ " %td
401
+ = #{singular}.#{assoc.name.to_s}.to_label"
402
+
403
+ else
404
+ " %td
405
+ = #{singular}.#{col}"
406
+ end
407
+ when :string
408
+ width = (limit && limit < 40) ? limit : (40)
409
+ " %td
410
+ = #{singular}.#{col}"
411
+ when :text
412
+ " %td
413
+ = #{singular}.#{col}"
414
+ when :datetime
415
+ " %td
416
+ = #{singular}.#{col}"
417
+ end
418
+ }.join("\n")
419
+ return res
420
+ end
421
+
422
+
231
423
 
232
424
  private # thor does something fancy like sending the class all of its own methods during some strange run sequence
233
425
  # does not like public methods