admin_assistant 2.0.0.pre1 → 2.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +7 -5
- data/VERSION +1 -1
- data/admin_assistant.gemspec +11 -7
- data/config/routes.rb +16 -0
- data/lib/admin_assistant/belongs_to_column.rb +1 -1
- data/lib/admin_assistant/column.rb +9 -18
- data/lib/admin_assistant/date_time_range_end_point_selector.rb +3 -2
- data/lib/admin_assistant/form_view.rb +18 -9
- data/lib/admin_assistant/index.rb +4 -7
- data/lib/admin_assistant/init.rb +14 -0
- data/lib/admin_assistant/model.rb +72 -0
- data/lib/admin_assistant/request/base.rb +2 -2
- data/lib/admin_assistant/route.rb +50 -0
- data/lib/admin_assistant/virtual_column.rb +3 -3
- data/lib/admin_assistant.rb +23 -101
- data/lib/stylesheets/default.css +1 -1
- data/lib/views/_polymorphic_field_search.html.erb +3 -3
- data/lib/views/_token_input.html.erb +1 -1
- data/lib/views/form.html.erb +2 -2
- data/lib/views/index.html.erb +11 -9
- data/lib/views/multi_form.html.erb +2 -2
- metadata +24 -7
- data/init.rb +0 -1
- data/install.rb +0 -21
- data/lib/admin_assistant/file_column_column.rb +0 -73
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require 'rake/rdoctask'
|
|
5
5
|
require 'spec/rake/spectask'
|
6
6
|
|
7
7
|
desc 'Default: run all specs across all supported Rails gem versions.'
|
8
|
-
task :default => :
|
8
|
+
task :default => :test
|
9
9
|
|
10
10
|
# run with rake publish
|
11
11
|
Grancher::Task.new do |g|
|
@@ -25,8 +25,8 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
25
25
|
end
|
26
26
|
|
27
27
|
desc 'Run all specs across all supported Rails gem versions.'
|
28
|
-
task :
|
29
|
-
supported_versions = %w(
|
28
|
+
task :test do
|
29
|
+
supported_versions = %w(3.0.6)
|
30
30
|
locally_installed_versions =
|
31
31
|
`gem list --local rails`.split(/\n/).
|
32
32
|
detect { |l| l=~ /^rails / }.strip.
|
@@ -35,7 +35,7 @@ task :spec do
|
|
35
35
|
if !missing.empty?
|
36
36
|
puts "Missing Rails versions #{missing.join(',')}; please install and then re-run tests"
|
37
37
|
else
|
38
|
-
cmd = "cd
|
38
|
+
cmd = "cd rails_3_test && " + (
|
39
39
|
supported_versions.map { |version|
|
40
40
|
"echo '===== Testing #{version} =====' && RAILS_GEM_VERSION=#{version} rake"
|
41
41
|
}.join(" && ")
|
@@ -54,8 +54,10 @@ begin
|
|
54
54
|
gem.email = "sera@fhwang.net"
|
55
55
|
gem.homepage = "http://github.com/fhwang/admin_assistant"
|
56
56
|
gem.authors = ["Francis Hwang"]
|
57
|
-
gem.add_dependency "will_paginate"
|
57
|
+
gem.add_dependency "will_paginate", "~> 3.0.pre2"
|
58
|
+
gem.add_dependency "dynamic_form"
|
58
59
|
gem.files.exclude "rails_2_test"
|
60
|
+
gem.files.exclude "rails_3_test"
|
59
61
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
60
62
|
end
|
61
63
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.0.
|
1
|
+
2.0.0.pre2
|
data/admin_assistant.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{admin_assistant}
|
8
|
-
s.version = "2.0.0.
|
8
|
+
s.version = "2.0.0.pre2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Francis Hwang"]
|
@@ -21,9 +21,8 @@ Gem::Specification.new do |s|
|
|
21
21
|
"Rakefile",
|
22
22
|
"VERSION",
|
23
23
|
"admin_assistant.gemspec",
|
24
|
+
"config/routes.rb",
|
24
25
|
"doc/img/blog_posts-index.png",
|
25
|
-
"init.rb",
|
26
|
-
"install.rb",
|
27
26
|
"lib/admin_assistant.rb",
|
28
27
|
"lib/admin_assistant/active_record_column.rb",
|
29
28
|
"lib/admin_assistant/association_target.rb",
|
@@ -32,11 +31,12 @@ Gem::Specification.new do |s|
|
|
32
31
|
"lib/admin_assistant/column.rb",
|
33
32
|
"lib/admin_assistant/date_time_range_end_point_selector.rb",
|
34
33
|
"lib/admin_assistant/default_search_column.rb",
|
35
|
-
"lib/admin_assistant/file_column_column.rb",
|
36
34
|
"lib/admin_assistant/form_view.rb",
|
37
35
|
"lib/admin_assistant/has_many_column.rb",
|
38
36
|
"lib/admin_assistant/helper.rb",
|
39
37
|
"lib/admin_assistant/index.rb",
|
38
|
+
"lib/admin_assistant/init.rb",
|
39
|
+
"lib/admin_assistant/model.rb",
|
40
40
|
"lib/admin_assistant/paperclip_column.rb",
|
41
41
|
"lib/admin_assistant/polymorphic_belongs_to_column.rb",
|
42
42
|
"lib/admin_assistant/request/autocomplete.rb",
|
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
|
|
48
48
|
"lib/admin_assistant/request/new.rb",
|
49
49
|
"lib/admin_assistant/request/show.rb",
|
50
50
|
"lib/admin_assistant/request/update.rb",
|
51
|
+
"lib/admin_assistant/route.rb",
|
51
52
|
"lib/admin_assistant/search.rb",
|
52
53
|
"lib/admin_assistant/show_view.rb",
|
53
54
|
"lib/admin_assistant/virtual_column.rb",
|
@@ -144,12 +145,15 @@ Gem::Specification.new do |s|
|
|
144
145
|
s.specification_version = 3
|
145
146
|
|
146
147
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
147
|
-
s.add_runtime_dependency(%q<will_paginate>, ["
|
148
|
+
s.add_runtime_dependency(%q<will_paginate>, ["~> 3.0.pre2"])
|
149
|
+
s.add_runtime_dependency(%q<dynamic_form>, [">= 0"])
|
148
150
|
else
|
149
|
-
s.add_dependency(%q<will_paginate>, ["
|
151
|
+
s.add_dependency(%q<will_paginate>, ["~> 3.0.pre2"])
|
152
|
+
s.add_dependency(%q<dynamic_form>, [">= 0"])
|
150
153
|
end
|
151
154
|
else
|
152
|
-
s.add_dependency(%q<will_paginate>, ["
|
155
|
+
s.add_dependency(%q<will_paginate>, ["~> 3.0.pre2"])
|
156
|
+
s.add_dependency(%q<dynamic_form>, [">= 0"])
|
153
157
|
end
|
154
158
|
end
|
155
159
|
|
data/config/routes.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# In development mode, we need to ensure that all controllers are loaded,
|
2
|
+
# because that's how AdminAssistant knows what routes to create
|
3
|
+
unless Rails.configuration.cache_classes
|
4
|
+
Find.find("#{Rails.root}/app/controllers") do |path|
|
5
|
+
if path =~ /\.rb$/
|
6
|
+
require path
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Rails.application.routes.draw do
|
12
|
+
AdminAssistant.routes.each do |route|
|
13
|
+
route.add(binding)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -37,7 +37,9 @@ class AdminAssistant
|
|
37
37
|
else
|
38
38
|
helper_method = "after_#{name}_input"
|
39
39
|
if @action_view.respond_to?(helper_method)
|
40
|
-
@action_view.
|
40
|
+
@action_view.raw(
|
41
|
+
@action_view.send(helper_method, rails_form.object)
|
42
|
+
)
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
@@ -47,7 +49,7 @@ class AdminAssistant
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def errors(record)
|
50
|
-
record.errors
|
52
|
+
record.errors[name]
|
51
53
|
end
|
52
54
|
|
53
55
|
def html(rails_form)
|
@@ -218,7 +220,7 @@ class AdminAssistant
|
|
218
220
|
opt << ">#{text}</option>"
|
219
221
|
}.join("\n")
|
220
222
|
@action_view.select_tag(
|
221
|
-
"search[#{name}(comparator)]", option_tags
|
223
|
+
"search[#{name}(comparator)]", @action_view.raw(option_tags)
|
222
224
|
)
|
223
225
|
end
|
224
226
|
|
@@ -338,15 +340,8 @@ class AdminAssistant
|
|
338
340
|
end
|
339
341
|
|
340
342
|
def check_box_and_hidden_tags(input_name, value)
|
341
|
-
|
342
|
-
|
343
|
-
if RAILS_GEM_VERSION =~ /^2.3/
|
344
|
-
@action_view.send(:hidden_field_tag, input_name, '0', :id => "#{input_name}_hidden") +
|
345
|
-
@action_view.send(:check_box_tag, input_name, '1', value)
|
346
|
-
else
|
347
|
-
@action_view.send(:check_box_tag, input_name, '1', value) +
|
348
|
-
@action_view.send(:hidden_field_tag, input_name, '0', :id => "#{input_name}_hidden")
|
349
|
-
end
|
343
|
+
@action_view.send(:hidden_field_tag, input_name, '0', :id => "#{input_name}_hidden") +
|
344
|
+
@action_view.send(:check_box_tag, input_name, '1', value)
|
350
345
|
end
|
351
346
|
|
352
347
|
def controller
|
@@ -355,17 +350,13 @@ class AdminAssistant
|
|
355
350
|
|
356
351
|
def custom_template_file_path(slug)
|
357
352
|
File.join(
|
358
|
-
|
353
|
+
Rails.root, 'app/views', controller.controller_path,
|
359
354
|
"#{slug}.html.erb"
|
360
355
|
)
|
361
356
|
end
|
362
357
|
|
363
358
|
def file_option_for_custom_template_render(slug)
|
364
|
-
|
365
|
-
File.join(controller.controller_path, "#{slug}.html.erb")
|
366
|
-
else
|
367
|
-
custom_template_file_path slug
|
368
|
-
end
|
359
|
+
custom_template_file_path slug
|
369
360
|
end
|
370
361
|
|
371
362
|
def label
|
@@ -2,8 +2,9 @@ class AdminAssistant
|
|
2
2
|
# Copied (and then streamlined) from Rails 2.3.5 in an effort to provide
|
3
3
|
# consistent functionality all the way back to Rails 2.1.0
|
4
4
|
class DateTimeRangeEndPointSelector
|
5
|
+
include ActionView::Helpers::RawOutputHelper
|
5
6
|
include ActionView::Helpers::TagHelper
|
6
|
-
|
7
|
+
|
7
8
|
DEFAULT_PREFIX = 'date'.freeze unless const_defined?('DEFAULT_PREFIX')
|
8
9
|
POSITION = {
|
9
10
|
:year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6
|
@@ -259,7 +260,7 @@ class AdminAssistant
|
|
259
260
|
select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
|
260
261
|
select_html << select_options_as_html.to_s
|
261
262
|
|
262
|
-
content_tag(:select, select_html, select_options) + "\n"
|
263
|
+
content_tag(:select, raw(select_html), select_options) + "\n"
|
263
264
|
end
|
264
265
|
|
265
266
|
# Builds a prompt option tag with supplied options or from default options
|
@@ -43,8 +43,7 @@ class AdminAssistant
|
|
43
43
|
|
44
44
|
def form_for_args
|
45
45
|
args = {:url => {:action => action, :id => @record.id}}
|
46
|
-
|
47
|
-
@admin_assistant.file_columns.empty?
|
46
|
+
if !@admin_assistant.paperclip_attachments.empty?
|
48
47
|
args[:html] = {:multipart => true}
|
49
48
|
end
|
50
49
|
args
|
@@ -87,14 +86,13 @@ class AdminAssistant
|
|
87
86
|
end
|
88
87
|
|
89
88
|
def form_for_args
|
89
|
+
opts = {
|
90
|
+
:builder => AdminAssistant::MultiFormView::Builder,
|
91
|
+
:sub_form_views => @sub_form_views, :url => {:action => action}
|
92
|
+
}
|
90
93
|
[
|
91
|
-
@records
|
92
|
-
@records
|
93
|
-
{
|
94
|
-
:url => {:action => action},
|
95
|
-
:builder => AdminAssistant::MultiFormView::Builder,
|
96
|
-
:sub_form_views => @sub_form_views
|
97
|
-
}
|
94
|
+
RecordsForForm.new(@records),
|
95
|
+
opts.merge(:as => @records.first.class.name.underscore.to_sym)
|
98
96
|
]
|
99
97
|
end
|
100
98
|
|
@@ -163,5 +161,16 @@ class AdminAssistant
|
|
163
161
|
end
|
164
162
|
end
|
165
163
|
end
|
164
|
+
|
165
|
+
# Passing an array as the object to form_for confuses it, so we hide that
|
166
|
+
# this is an array with a DelegateClass.
|
167
|
+
class RecordsForForm < DelegateClass(Array)
|
168
|
+
def initialize(records)
|
169
|
+
super(records)
|
170
|
+
end
|
171
|
+
|
172
|
+
def id
|
173
|
+
end
|
174
|
+
end
|
166
175
|
end
|
167
176
|
end
|
@@ -193,12 +193,7 @@ class AdminAssistant
|
|
193
193
|
slug = "_after_index_header.html.erb"
|
194
194
|
abs_template_file = File.join( Rails.root, 'app/views', @admin_assistant.controller_class.controller_path, slug )
|
195
195
|
if File.exist?(abs_template_file)
|
196
|
-
|
197
|
-
File.join(@admin_assistant.controller_class.controller_path, slug)
|
198
|
-
else
|
199
|
-
abs_template_file
|
200
|
-
end
|
201
|
-
@action_view.render :file => template
|
196
|
+
@action_view.render :file => abs_template_file
|
202
197
|
end
|
203
198
|
end
|
204
199
|
|
@@ -260,7 +255,9 @@ class AdminAssistant
|
|
260
255
|
else
|
261
256
|
"New #{@admin_assistant.model_class_name}"
|
262
257
|
end
|
263
|
-
@action_view.link_to
|
258
|
+
@action_view.link_to(
|
259
|
+
new_link_name, @admin_assistant.url_params(:new)
|
260
|
+
)
|
264
261
|
end
|
265
262
|
|
266
263
|
def right_column?
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
class AdminAssistant
|
5
|
+
def self.init
|
6
|
+
gem_root = File.dirname(__FILE__) + "/../.."
|
7
|
+
%w(stylesheets javascripts images).each do |asset_type|
|
8
|
+
asset_dir = "#{Rails.root}/public/#{asset_type}/admin_assistant"
|
9
|
+
FileUtils.mkdir(asset_dir) unless File.exist?(asset_dir)
|
10
|
+
FileUtils.cp_r(Dir.glob("#{gem_root}/lib/#{asset_type}/*"), asset_dir)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class AdminAssistant
|
2
|
+
class Model
|
3
|
+
def initialize(ar_model)
|
4
|
+
@ar_model = ar_model
|
5
|
+
end
|
6
|
+
|
7
|
+
def accessors
|
8
|
+
@ar_model.instance_methods.
|
9
|
+
select { |m| m =~ /=$/ }.
|
10
|
+
map { |m| m.gsub(/=/, '')}.
|
11
|
+
select { |m| @ar_model.instance_methods.include?(m) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def belongs_to_associations
|
15
|
+
@ar_model.reflect_on_all_associations.select { |assoc|
|
16
|
+
assoc.macro == :belongs_to
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def belongs_to_assoc(association_name)
|
21
|
+
belongs_to_associations.detect { |assoc|
|
22
|
+
assoc.name.to_s == association_name.to_s
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def belongs_to_assoc_by_foreign_key(foreign_key)
|
27
|
+
belongs_to_associations.detect { |assoc|
|
28
|
+
assoc.association_foreign_key == foreign_key
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def belongs_to_assoc_by_polymorphic_type(name)
|
33
|
+
if name =~ /^(.*)_type/
|
34
|
+
belongs_to_associations.detect { |assoc|
|
35
|
+
assoc.options[:polymorphic] && $1 == assoc.name.to_s
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_column_names
|
41
|
+
@ar_model.columns.reject { |ar_column|
|
42
|
+
%w(id created_at updated_at).include?(ar_column.name)
|
43
|
+
}.map { |ar_column| ar_column.name }
|
44
|
+
end
|
45
|
+
|
46
|
+
def has_many_assoc(association_name)
|
47
|
+
@ar_model.reflect_on_all_associations.select { |assoc|
|
48
|
+
assoc.macro == :has_many
|
49
|
+
}.detect { |assoc|
|
50
|
+
assoc.name.to_s == association_name.to_s
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def paperclip_attachments
|
55
|
+
pa = []
|
56
|
+
if @ar_model.respond_to?(:attachment_definitions)
|
57
|
+
if @ar_model.attachment_definitions
|
58
|
+
pa = @ar_model.attachment_definitions.map { |name, definition|
|
59
|
+
name
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
pa
|
64
|
+
end
|
65
|
+
|
66
|
+
def searchable_columns
|
67
|
+
@ar_model.columns.select { |column|
|
68
|
+
[:string, :text].include?(column.type)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -24,14 +24,14 @@ class AdminAssistant
|
|
24
24
|
|
25
25
|
def after_template_file(template_name)
|
26
26
|
File.join(
|
27
|
-
|
27
|
+
Rails.root, 'app/views/', @controller.controller_path,
|
28
28
|
"_after_#{template_name}.html.erb"
|
29
29
|
)
|
30
30
|
end
|
31
31
|
|
32
32
|
def before_template_file(template_name)
|
33
33
|
File.join(
|
34
|
-
|
34
|
+
Rails.root, 'app/views/', @controller.controller_path,
|
35
35
|
"_before_#{template_name}.html.erb"
|
36
36
|
)
|
37
37
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class AdminAssistant
|
2
|
+
class Route
|
3
|
+
attr_reader :admin_assistant
|
4
|
+
|
5
|
+
def initialize(admin_assistant)
|
6
|
+
@admin_assistant = admin_assistant
|
7
|
+
end
|
8
|
+
|
9
|
+
def add(binding)
|
10
|
+
route_str = "resources(:#{resource})"
|
11
|
+
unless autocomplete_actions.empty?
|
12
|
+
route_str << " do "
|
13
|
+
autocomplete_actions.each do |action|
|
14
|
+
route_str << " get :#{action}, :on => :collection;"
|
15
|
+
end
|
16
|
+
route_str << " end "
|
17
|
+
end
|
18
|
+
if namespace
|
19
|
+
route_str = "namespace(:#{namespace}) do " + route_str + " end"
|
20
|
+
end
|
21
|
+
eval(route_str, binding)
|
22
|
+
end
|
23
|
+
|
24
|
+
def autocomplete_actions
|
25
|
+
admin_assistant.autocomplete_actions
|
26
|
+
end
|
27
|
+
|
28
|
+
def controller
|
29
|
+
admin_assistant.controller_class
|
30
|
+
end
|
31
|
+
|
32
|
+
def namespace
|
33
|
+
name = controller.name.gsub(/Controller$/, '').underscore
|
34
|
+
if name =~ %r|(.*)/(.*)|
|
35
|
+
$1.to_sym
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def resource
|
40
|
+
name = controller.name.gsub(/Controller$/, '').underscore
|
41
|
+
if name =~ %r|(.*)/(.*)|
|
42
|
+
$2.to_sym
|
43
|
+
else
|
44
|
+
name.to_sym
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
@@ -51,14 +51,14 @@ class AdminAssistant
|
|
51
51
|
@action_view.send("#{input}_tag", input_name, string(object))
|
52
52
|
end
|
53
53
|
if has_matching_errors?(object)
|
54
|
-
html = "<div class=\"
|
54
|
+
html = "<div class=\"field_with_errors\">#{html}</div>"
|
55
55
|
end
|
56
56
|
html
|
57
57
|
end
|
58
58
|
|
59
59
|
def has_matching_errors?(record)
|
60
|
-
record.respond_to?(:errors) && record.errors.respond_to?(:
|
61
|
-
record.errors
|
60
|
+
record.respond_to?(:errors) && record.errors.respond_to?(:[]) &&
|
61
|
+
record.errors[name]
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
data/lib/admin_assistant.rb
CHANGED
@@ -1,17 +1,24 @@
|
|
1
1
|
$: << File.join(File.dirname(__FILE__), '../vendor/ar_query/lib')
|
2
|
+
require 'dynamic_form'
|
3
|
+
require 'will_paginate'
|
4
|
+
|
2
5
|
require 'find'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
files = %w(
|
7
|
+
column virtual_column active_record_column association_target
|
8
|
+
belongs_to_column builder date_time_range_end_point_selector
|
9
|
+
default_search_column form_view has_many_column helper index init model
|
10
|
+
paperclip_column polymorphic_belongs_to_column request/base
|
11
|
+
request/autocomplete request/create request/destroy request/edit
|
12
|
+
request/index request/new request/show request/update route search show_view
|
13
|
+
)
|
14
|
+
files.each do |file|
|
15
|
+
require "#{File.dirname(__FILE__)}/admin_assistant/#{file}"
|
9
16
|
end
|
10
|
-
require 'will_paginate'
|
11
17
|
|
12
18
|
class AdminAssistant
|
13
|
-
cattr_accessor :request_start_time
|
14
|
-
|
19
|
+
cattr_accessor :request_start_time, :routes
|
20
|
+
self.routes = []
|
21
|
+
|
15
22
|
def self.profile(msg)
|
16
23
|
if self.request_start_time
|
17
24
|
Rails.logger.info "#{msg}: #{Time.now - self.request_start_time}"
|
@@ -81,9 +88,7 @@ class AdminAssistant
|
|
81
88
|
end
|
82
89
|
|
83
90
|
def column(name)
|
84
|
-
if @model.
|
85
|
-
FileColumnColumn.new name
|
86
|
-
elsif @model.paperclip_attachments.include?(name)
|
91
|
+
if @model.paperclip_attachments.include?(name)
|
87
92
|
PaperclipColumn.new name
|
88
93
|
elsif (belongs_to_assoc = @model.belongs_to_assoc(name) or
|
89
94
|
belongs_to_assoc = @model.belongs_to_assoc_by_foreign_key(name))
|
@@ -136,10 +141,6 @@ class AdminAssistant
|
|
136
141
|
@model.default_column_names
|
137
142
|
end
|
138
143
|
|
139
|
-
def file_columns
|
140
|
-
@model.file_columns
|
141
|
-
end
|
142
|
-
|
143
144
|
def method_missing(meth, *args)
|
144
145
|
if crudful_request_methods.include?(meth) and args.size == 1
|
145
146
|
self.class.request_start_time = Time.now if ENV['PROFILE_LOGGING']
|
@@ -200,98 +201,19 @@ class AdminAssistant
|
|
200
201
|
self.class.admin_assistant.send(action, self)
|
201
202
|
end
|
202
203
|
end
|
204
|
+
AdminAssistant.routes << Route.new(self.admin_assistant)
|
203
205
|
rescue ActiveRecord::StatementInvalid
|
204
206
|
Rails.logger.info "Skipping admin_assistant_for for #{self.name} because the table doesn't exist in the DB. Hopefully that's because you're deploying with a migration."
|
205
207
|
end
|
206
208
|
end
|
207
209
|
end
|
208
|
-
|
209
|
-
class
|
210
|
-
|
211
|
-
|
212
|
-
end
|
213
|
-
|
214
|
-
def accessors
|
215
|
-
@ar_model.instance_methods.
|
216
|
-
select { |m| m =~ /=$/ }.
|
217
|
-
map { |m| m.gsub(/=/, '')}.
|
218
|
-
select { |m| @ar_model.instance_methods.include?(m) }
|
219
|
-
end
|
220
|
-
|
221
|
-
def belongs_to_associations
|
222
|
-
@ar_model.reflect_on_all_associations.select { |assoc|
|
223
|
-
assoc.macro == :belongs_to
|
224
|
-
}
|
225
|
-
end
|
226
|
-
|
227
|
-
def belongs_to_assoc(association_name)
|
228
|
-
belongs_to_associations.detect { |assoc|
|
229
|
-
assoc.name.to_s == association_name.to_s
|
230
|
-
}
|
231
|
-
end
|
232
|
-
|
233
|
-
def belongs_to_assoc_by_foreign_key(foreign_key)
|
234
|
-
belongs_to_associations.detect { |assoc|
|
235
|
-
assoc.association_foreign_key == foreign_key
|
236
|
-
}
|
237
|
-
end
|
238
|
-
|
239
|
-
def belongs_to_assoc_by_polymorphic_type(name)
|
240
|
-
if name =~ /^(.*)_type/
|
241
|
-
belongs_to_associations.detect { |assoc|
|
242
|
-
assoc.options[:polymorphic] && $1 == assoc.name.to_s
|
243
|
-
}
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
def default_column_names
|
248
|
-
@ar_model.columns.reject { |ar_column|
|
249
|
-
%w(id created_at updated_at).include?(ar_column.name)
|
250
|
-
}.map { |ar_column| ar_column.name }
|
251
|
-
end
|
252
|
-
|
253
|
-
def file_columns
|
254
|
-
unless @file_columns
|
255
|
-
@file_columns = []
|
256
|
-
if @ar_model.respond_to?(:file_column)
|
257
|
-
names_to_check = @ar_model.columns.map(&:name).concat(accessors).uniq
|
258
|
-
@file_columns = names_to_check.select { |name|
|
259
|
-
%w( relative_path dir relative_dir temp ).all? { |suffix|
|
260
|
-
@ar_model.method_defined? "#{name}_#{suffix}".to_sym
|
261
|
-
}
|
262
|
-
}
|
263
|
-
end
|
264
|
-
end
|
265
|
-
@file_columns
|
266
|
-
end
|
267
|
-
|
268
|
-
def has_many_assoc(association_name)
|
269
|
-
@ar_model.reflect_on_all_associations.select { |assoc|
|
270
|
-
assoc.macro == :has_many
|
271
|
-
}.detect { |assoc|
|
272
|
-
assoc.name.to_s == association_name.to_s
|
273
|
-
}
|
274
|
-
end
|
275
|
-
|
276
|
-
def paperclip_attachments
|
277
|
-
pa = []
|
278
|
-
if @ar_model.respond_to?(:attachment_definitions)
|
279
|
-
if @ar_model.attachment_definitions
|
280
|
-
pa = @ar_model.attachment_definitions.map { |name, definition|
|
281
|
-
name
|
282
|
-
}
|
283
|
-
end
|
284
|
-
end
|
285
|
-
pa
|
286
|
-
end
|
287
|
-
|
288
|
-
def searchable_columns
|
289
|
-
@ar_model.columns.select { |column|
|
290
|
-
[:string, :text].include?(column.type)
|
291
|
-
}
|
210
|
+
|
211
|
+
class Engine < ::Rails::Engine
|
212
|
+
initializer "admin_assistant.init" do
|
213
|
+
AdminAssistant.init
|
292
214
|
end
|
293
215
|
end
|
294
216
|
end
|
295
|
-
|
217
|
+
|
296
218
|
ActionController::Base.send :include, AdminAssistant::ControllerMethods
|
297
219
|
|
data/lib/stylesheets/default.css
CHANGED
@@ -49,12 +49,12 @@ end
|
|
49
49
|
<%
|
50
50
|
option_tags = "<option value=''></option>"
|
51
51
|
option_tags << options_for_select(
|
52
|
-
|
53
|
-
|
52
|
+
association_target.options_for_select,
|
53
|
+
(associated.id if associated.class == polymorphic_type)
|
54
54
|
)
|
55
55
|
%>
|
56
56
|
<%= select_tag(
|
57
|
-
"#{column.name}_#{name}_id", option_tags,
|
57
|
+
"#{column.name}_#{name}_id", raw(option_tags),
|
58
58
|
'data-behavior' => 'select',
|
59
59
|
'data-value-type' => polymorphic_type.name
|
60
60
|
) %>
|
@@ -19,7 +19,7 @@ end
|
|
19
19
|
<script type="text/javascript">
|
20
20
|
$(document).ready(function() {
|
21
21
|
$("#<%= text_field_id %>").tokenInput(
|
22
|
-
"<%= token_url %>", <%= token_input_options.to_json %>
|
22
|
+
"<%= raw(token_url) %>", <%= raw(token_input_options.to_json) %>
|
23
23
|
);
|
24
24
|
});
|
25
25
|
</script>
|
data/lib/views/form.html.erb
CHANGED
@@ -14,7 +14,7 @@ form_view = AdminAssistant::FormView.new(@record, @admin_assistant, self)
|
|
14
14
|
<% if !@record.errors.empty? %>
|
15
15
|
<%= error_messages_for 'record' %>
|
16
16
|
<% end %>
|
17
|
-
|
17
|
+
<%= form_for(@record, form_view.form_for_args) do |rails_form| %>
|
18
18
|
<% if @origin %>
|
19
19
|
<%= hidden_field_tag 'origin', @origin %>
|
20
20
|
<% end %>
|
@@ -25,7 +25,7 @@ form_view = AdminAssistant::FormView.new(@record, @admin_assistant, self)
|
|
25
25
|
<% if column.description %>
|
26
26
|
<p class="description"><%= h(column.description) %></p>
|
27
27
|
<% end %>
|
28
|
-
<%= column.html(rails_form) %>
|
28
|
+
<%= raw(column.html(rails_form)) %>
|
29
29
|
</div>
|
30
30
|
<% end %>
|
31
31
|
<div>
|
data/lib/views/index.html.erb
CHANGED
@@ -18,9 +18,9 @@
|
|
18
18
|
<%= index_view.render_after_index_header %>
|
19
19
|
</div>
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
:url => {:action => 'index'},
|
21
|
+
<%= form_for(
|
22
|
+
@index.search,
|
23
|
+
:as => :search, :url => {:action => 'index'},
|
24
24
|
:html => {:id => 'search_form', :style => 'display:none', :method => 'get'}
|
25
25
|
) do |form| %>
|
26
26
|
<% @index.hidden_fields_for_search_form.each do |name, value| -%>
|
@@ -37,7 +37,7 @@
|
|
37
37
|
) %>
|
38
38
|
<% end %>
|
39
39
|
<% column_views.each do |column_view| %>
|
40
|
-
<%= column_view.html(form) %>
|
40
|
+
<%= raw(column_view.html(form)) %>
|
41
41
|
<% end %>
|
42
42
|
<%= submit_tag('Search') %>
|
43
43
|
<%=
|
@@ -59,7 +59,7 @@
|
|
59
59
|
<tr>
|
60
60
|
<% index_view.columns.each do |column| %>
|
61
61
|
<% th_class = column.header_css_class %>
|
62
|
-
<th<%= " class=\"#{th_class}\"" if th_class %>><%=
|
62
|
+
<th<%= raw(" class=\"#{th_class}\"") if th_class %>><%=
|
63
63
|
if column.sort_possible?(@index.records.total_entries)
|
64
64
|
link_to(h(column.label), column.next_sort_params)
|
65
65
|
else
|
@@ -77,12 +77,14 @@
|
|
77
77
|
%>_<%= record.id %>">
|
78
78
|
<% index_view.columns.each do |column| %>
|
79
79
|
<% td_class = column.td_css_classes(column, record) %>
|
80
|
-
<td<%= " class=\"#{td_class}\"" unless td_class.blank? %>><%=
|
81
|
-
column.html(record)
|
80
|
+
<td<%= raw(" class=\"#{td_class}\"") unless td_class.blank? %>><%=
|
81
|
+
raw(column.html(record))
|
82
82
|
%></td>
|
83
83
|
<% end %>
|
84
84
|
<% if index_view.right_column? %>
|
85
|
-
<td class="actions"
|
85
|
+
<td class="actions">
|
86
|
+
<%= raw(index_view.right_column_links(record)) %>
|
87
|
+
</td>
|
86
88
|
<% end %>
|
87
89
|
</tr>
|
88
90
|
<% end %>
|
@@ -95,7 +97,7 @@
|
|
95
97
|
<%= will_paginate @index.records, :container => false %>
|
96
98
|
</div>
|
97
99
|
<% if @index.records.total_pages > 10 %>
|
98
|
-
|
100
|
+
<%= form_tag({:action => 'index'}, :method => 'get') do %>
|
99
101
|
<%= text_field_tag('page', nil, :size => 2) %>
|
100
102
|
<%= submit_tag('Jump') %>
|
101
103
|
<% end %>
|
@@ -12,7 +12,7 @@ multi_form_view = AdminAssistant::MultiFormView.new(
|
|
12
12
|
<%= link_to('Back to index', :action => 'index') %>
|
13
13
|
</div>
|
14
14
|
</div>
|
15
|
-
|
15
|
+
<%= form_for(*multi_form_view.form_for_args) do |rails_form| %>
|
16
16
|
<% if @origin %>
|
17
17
|
<%= hidden_field_tag 'origin', @origin %>
|
18
18
|
<% end %>
|
@@ -53,7 +53,7 @@ multi_form_view = AdminAssistant::MultiFormView.new(
|
|
53
53
|
<% end %>
|
54
54
|
<tr>
|
55
55
|
<% sub_form_view.columns.each do |column| %>
|
56
|
-
<td<%= " class='
|
56
|
+
<td<%= " class='field_with_errors'" if column.errors(record) %>>
|
57
57
|
<%= column.html(rails_sub_form) %>
|
58
58
|
</td>
|
59
59
|
<% end %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: admin_assistant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: -
|
4
|
+
hash: -1876988223
|
5
5
|
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 0
|
9
9
|
- 0
|
10
|
-
-
|
11
|
-
version: 2.0.0.
|
10
|
+
- pre2
|
11
|
+
version: 2.0.0.pre2
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Francis Hwang
|
@@ -23,6 +23,22 @@ dependencies:
|
|
23
23
|
name: will_paginate
|
24
24
|
prerelease: false
|
25
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: -1876988247
|
31
|
+
segments:
|
32
|
+
- 3
|
33
|
+
- 0
|
34
|
+
- pre2
|
35
|
+
version: 3.0.pre2
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: dynamic_form
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
26
42
|
none: false
|
27
43
|
requirements:
|
28
44
|
- - ">="
|
@@ -32,7 +48,7 @@ dependencies:
|
|
32
48
|
- 0
|
33
49
|
version: "0"
|
34
50
|
type: :runtime
|
35
|
-
version_requirements: *
|
51
|
+
version_requirements: *id002
|
36
52
|
description: admin_assistant is a Rails plugin that automates a lot of features typically needed in admin interfaces.
|
37
53
|
email: sera@fhwang.net
|
38
54
|
executables: []
|
@@ -47,9 +63,8 @@ files:
|
|
47
63
|
- Rakefile
|
48
64
|
- VERSION
|
49
65
|
- admin_assistant.gemspec
|
66
|
+
- config/routes.rb
|
50
67
|
- doc/img/blog_posts-index.png
|
51
|
-
- init.rb
|
52
|
-
- install.rb
|
53
68
|
- lib/admin_assistant.rb
|
54
69
|
- lib/admin_assistant/active_record_column.rb
|
55
70
|
- lib/admin_assistant/association_target.rb
|
@@ -58,11 +73,12 @@ files:
|
|
58
73
|
- lib/admin_assistant/column.rb
|
59
74
|
- lib/admin_assistant/date_time_range_end_point_selector.rb
|
60
75
|
- lib/admin_assistant/default_search_column.rb
|
61
|
-
- lib/admin_assistant/file_column_column.rb
|
62
76
|
- lib/admin_assistant/form_view.rb
|
63
77
|
- lib/admin_assistant/has_many_column.rb
|
64
78
|
- lib/admin_assistant/helper.rb
|
65
79
|
- lib/admin_assistant/index.rb
|
80
|
+
- lib/admin_assistant/init.rb
|
81
|
+
- lib/admin_assistant/model.rb
|
66
82
|
- lib/admin_assistant/paperclip_column.rb
|
67
83
|
- lib/admin_assistant/polymorphic_belongs_to_column.rb
|
68
84
|
- lib/admin_assistant/request/autocomplete.rb
|
@@ -74,6 +90,7 @@ files:
|
|
74
90
|
- lib/admin_assistant/request/new.rb
|
75
91
|
- lib/admin_assistant/request/show.rb
|
76
92
|
- lib/admin_assistant/request/update.rb
|
93
|
+
- lib/admin_assistant/route.rb
|
77
94
|
- lib/admin_assistant/search.rb
|
78
95
|
- lib/admin_assistant/show_view.rb
|
79
96
|
- lib/admin_assistant/virtual_column.rb
|
data/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "#{File.dirname(__FILE__)}/lib/admin_assistant"
|
data/install.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'pathname'
|
3
|
-
|
4
|
-
outer = File.dirname(__FILE__)
|
5
|
-
|
6
|
-
# Delete rails_2_test and various doc directories, unless you're actually
|
7
|
-
# developing admin_assistant itself
|
8
|
-
test_rails_app = Pathname.new("#{outer}/rails_2_test").realpath.to_s
|
9
|
-
unless RAILS_ROOT == test_rails_app
|
10
|
-
%w(doc rails_2_test website).each do |dir|
|
11
|
-
FileUtils.rm_rf "#{outer}/#{dir}"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# Copy over static assets
|
16
|
-
%w(stylesheets javascripts images).each do |asset_type|
|
17
|
-
asset_dir = "#{Rails.root}/public/#{asset_type}/admin_assistant"
|
18
|
-
FileUtils.mkdir(asset_dir) unless File.exist?(asset_dir)
|
19
|
-
FileUtils.cp_r(Dir.glob("#{outer}/lib/#{asset_type}/*"), asset_dir)
|
20
|
-
end
|
21
|
-
|
@@ -1,73 +0,0 @@
|
|
1
|
-
class AdminAssistant
|
2
|
-
class FileColumnColumn < Column
|
3
|
-
attr_reader :name
|
4
|
-
|
5
|
-
def initialize(name)
|
6
|
-
@name = name.to_s
|
7
|
-
end
|
8
|
-
|
9
|
-
def contains?(column_name)
|
10
|
-
column_name.to_s == @name
|
11
|
-
end
|
12
|
-
|
13
|
-
class View < AdminAssistant::Column::View
|
14
|
-
def file_exists?(record)
|
15
|
-
if @file_exists_method
|
16
|
-
@file_exists_method.call record
|
17
|
-
else
|
18
|
-
!source_for_image_tag(record).nil?
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def image_html(record)
|
23
|
-
@action_view.image_tag(
|
24
|
-
source_for_image_tag(record), :size => @image_size
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
def source_for_image_tag(record)
|
29
|
-
if @file_url_method
|
30
|
-
@file_url_method.call record
|
31
|
-
else
|
32
|
-
@action_view.instance_variable_set :@record, record
|
33
|
-
@action_view.url_for_file_column 'record', @column.name
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class FormView < View
|
39
|
-
include AdminAssistant::Column::FormViewMethods
|
40
|
-
|
41
|
-
def default_html(form)
|
42
|
-
if file_exists?(form.object)
|
43
|
-
check_box_tag = @action_view.check_box_tag(
|
44
|
-
"#{form.object.class.name.underscore}[#{name}(destroy)]"
|
45
|
-
)
|
46
|
-
<<-HTML
|
47
|
-
<p>Current image:<br />#{image_html(form.object)}</p>
|
48
|
-
<p>Remove: #{check_box_tag}</p>
|
49
|
-
<p>Update: #{form.file_field(name)}</p>
|
50
|
-
HTML
|
51
|
-
else
|
52
|
-
"<p>Add: #{form.file_field(name)}</p>"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class IndexView < View
|
58
|
-
include AdminAssistant::Column::IndexViewMethods
|
59
|
-
|
60
|
-
def unconfigured_html(record)
|
61
|
-
image_html(record) if file_exists?(record)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class ShowView < View
|
66
|
-
include AdminAssistant::Column::ShowViewMethods
|
67
|
-
|
68
|
-
def html(record)
|
69
|
-
image_html(record) if file_exists?(record)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|