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.
- checksums.yaml +4 -4
- data/.generators +8 -0
- data/.gitignore +16 -0
- data/.rakeTasks +7 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +175 -0
- data/LICENSE +2 -2
- data/README.md +147 -34
- data/app/assets/images/common_core_js/.keep +0 -0
- data/app/assets/stylesheets/common_core_js/common_core.scss +43 -0
- data/app/helpers/common_core_js/application_helper.rb +76 -0
- data/app/views/common/_common_create.js.erb +1 -1
- data/bin/rails +14 -0
- data/common_core_js.gemspec +70 -0
- data/lib/common_core_js.rb +20 -0
- data/lib/common_core_js/engine.rb +3 -1
- data/lib/common_core_js/version.rb +1 -1
- data/lib/generators/common_core/USAGE +2 -4
- data/lib/generators/common_core/install_generator.rb +22 -0
- data/lib/generators/common_core/scaffold_generator.rb +329 -30
- data/lib/generators/common_core/templates/_edit.haml +1 -1
- data/lib/generators/common_core/templates/_errors.haml +5 -0
- data/lib/generators/common_core/templates/_flash_notices.haml +7 -0
- data/lib/generators/common_core/templates/_form.haml +1 -0
- data/lib/generators/common_core/templates/_line.haml +5 -0
- data/lib/generators/common_core/templates/_list.haml +1 -1
- data/lib/generators/common_core/templates/_new.haml +1 -1
- data/lib/generators/common_core/templates/all.haml +5 -0
- data/lib/generators/common_core/templates/common_core.js +52 -0
- data/lib/generators/common_core/templates/common_core.scss +5 -0
- data/lib/generators/common_core/templates/controller.rb +6 -7
- data/lib/generators/common_core/templates/controller_spec.rb +110 -0
- data/lib/generators/common_core/templates/edit.js.erb +1 -1
- data/lib/generators/common_core/templates/update.js.erb +1 -1
- data/lib/tasks/common_core_js_tasks.rake +7 -4
- 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(
|
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();
|
data/bin/rails
ADDED
@@ -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
|
data/lib/common_core_js.rb
CHANGED
@@ -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
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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}#{
|
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}
|
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
|