padrino-admin 0.6.3 → 0.6.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +16 -0
- data/VERSION +1 -1
- data/lib/padrino-admin.rb +24 -5
- data/lib/padrino-admin/access_control.rb +75 -29
- data/lib/padrino-admin/{ext_js/column_store.rb → column_store.rb} +31 -15
- data/lib/padrino-admin/config.rb +36 -0
- data/lib/padrino-admin/generators/actions.rb +62 -7
- data/lib/padrino-admin/generators/admin_app.rb +27 -26
- data/lib/padrino-admin/generators/admin_page.rb +20 -18
- data/lib/padrino-admin/generators/admin_uploader.rb +83 -0
- data/lib/padrino-admin/generators/app/app.rb.tt +1 -3
- data/lib/padrino-admin/generators/app/controllers/accounts.rb +1 -1
- data/lib/padrino-admin/generators/app/public/flash/swfupload.swf +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/back.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/background.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/bg-content.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/bg-hd-slate.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/bg-hd.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/bg-intro.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/bg-login.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/bg-menu-slate.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/bg-menu.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/bg.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/btn-login.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/admin/cancel.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/categories.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/admin/close.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/admin/close.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/delete.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/download.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/duplicate.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/edit.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/export.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/hd-bg.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/image.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/loader.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/logo-loader.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/logo-small.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/new.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/no-image.png +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/preview.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/print.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/save.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/{backend → admin}/support.gif +0 -0
- data/lib/padrino-admin/generators/app/public/images/admin/up.gif +0 -0
- data/lib/padrino-admin/generators/app/public/javascripts/ext.js +4 -1
- data/lib/padrino-admin/generators/app/public/javascripts/swfupload.js +4 -0
- data/lib/padrino-admin/generators/app/public/stylesheets/admin.css +25 -43
- data/lib/padrino-admin/generators/app/public/stylesheets/login.css +3 -3
- data/lib/padrino-admin/generators/app/public/stylesheets/standard.css +53 -52
- data/lib/padrino-admin/generators/app/views/accounts/_form.haml +1 -0
- data/lib/padrino-admin/generators/app/views/base/index.haml +5 -7
- data/lib/padrino-admin/generators/app/views/javascripts/admin.js.erb +217 -297
- data/lib/padrino-admin/generators/app/views/sessions/new.haml +1 -1
- data/lib/padrino-admin/generators/templates/{controller.rb.tt → page/controller.rb.tt} +1 -1
- data/lib/padrino-admin/generators/templates/{db → page/db}/seeds.rb.tt +0 -0
- data/lib/padrino-admin/generators/templates/{views → page/views}/_form.haml.tt +0 -0
- data/lib/padrino-admin/generators/templates/{views → page/views}/edit.haml.tt +0 -0
- data/lib/padrino-admin/generators/templates/{views → page/views}/grid.js.erb.tt +1 -1
- data/lib/padrino-admin/generators/templates/{views → page/views}/new.haml.tt +0 -0
- data/lib/padrino-admin/generators/templates/{views → page/views}/store.jml.tt +0 -0
- data/lib/padrino-admin/generators/templates/uploader/controller.rb +24 -0
- data/lib/padrino-admin/generators/templates/uploader/lib/uploader.rb +54 -0
- data/lib/padrino-admin/generators/templates/uploader/views/grid.js.erb +56 -0
- data/lib/padrino-admin/generators/templates/uploader/views/store.jml +10 -0
- data/lib/padrino-admin/helpers/authentication.rb +30 -19
- data/lib/padrino-admin/helpers/view.rb +172 -35
- data/lib/padrino-admin/locale/admin/en.yml +1 -0
- data/lib/padrino-admin/middleware/flash_middleware.rb +36 -0
- data/lib/padrino-admin/orm.rb +33 -0
- data/lib/padrino-admin/orm/abstract.rb +94 -0
- data/lib/padrino-admin/{adapters/ar.rb → orm/activerecord.rb} +69 -36
- data/lib/padrino-admin/orm/datamapper.rb +214 -0
- data/lib/padrino-admin/{adapters/mm.rb → orm/mongomapper.rb} +36 -20
- data/lib/padrino-admin/utils/literal.rb +1 -1
- data/padrino-admin.gemspec +62 -51
- data/test/fixtures/active_record.rb +14 -2
- data/test/fixtures/data_mapper.rb +2 -1
- data/test/fixtures/mongo_mapper.rb +1 -1
- data/test/fixtures/test_column_store.jml +1 -0
- data/test/helper.rb +3 -2
- data/test/test_access_control.rb +1 -1
- data/test/test_active_record.rb +56 -1
- data/test/test_column_store.rb +56 -10
- data/test/test_data_mapper.rb +67 -1
- metadata +58 -47
- data/lib/padrino-admin/adapters.rb +0 -108
- data/lib/padrino-admin/adapters/dm.rb +0 -147
- data/lib/padrino-admin/ext_js/config.rb +0 -186
- data/test/fixtures/test_generic.jml +0 -7
- data/test/fixtures/test_javascript.jml +0 -81
@@ -17,7 +17,7 @@
|
|
17
17
|
.ln=password_field_tag :password, :value => params[:password], :style => "width:250px"
|
18
18
|
.padding-top.bottom
|
19
19
|
.left=flash[:notice]
|
20
|
-
.right=image_submit_tag("../images/
|
20
|
+
.right=image_submit_tag("../images/admin/btn-login.png", :style => "padding:none;border:none;width:72px;height:25px")
|
21
21
|
.clear
|
22
22
|
#copyright
|
23
23
|
Powered by
|
@@ -32,6 +32,6 @@ Admin.controllers :<%= @model_plural %> do
|
|
32
32
|
delete :destroy, :respond_to => :json do
|
33
33
|
<%= @model_plural %> = <%= @model_name %>.all(:conditions => { :id => params[:ids].split(",") })
|
34
34
|
errors = <%= @model_plural %>.map { |<%= @model_singular %>| I18n.t("admin.general.cantDelete", :record => <%= @model_singular %>.id) unless <%= @model_singular %>.destroy }.compact
|
35
|
-
|
35
|
+
render :success => errors.empty?, :msg => errors.join("<br />")
|
36
36
|
end
|
37
37
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Admin.controllers :uploads do
|
2
|
+
|
3
|
+
get :index, :respond_to => [:js, :json] do
|
4
|
+
@store = Upload.column_store(options.views, "uploads/store")
|
5
|
+
@session_id = options.session_id
|
6
|
+
case content_type
|
7
|
+
when :js then render 'uploads/grid.js'
|
8
|
+
when :json then @store.store_data(params)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
post :create do
|
13
|
+
@upload = Upload.new
|
14
|
+
@upload.file = params[:file]
|
15
|
+
@upload.save
|
16
|
+
render :success => true
|
17
|
+
end
|
18
|
+
|
19
|
+
delete :destroy, :respond_to => :json do
|
20
|
+
uploads = Upload.all(:conditions => { :id => params[:ids].split(",") })
|
21
|
+
errors = uploads.map { |upload| I18n.t("admin.general.cantDelete", :record => upload.id) unless upload.destroy }.compact
|
22
|
+
render :success => errors.empty?, :msg => errors.join("<br />")
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Uploader < CarrierWave::Uploader::Base
|
2
|
+
|
3
|
+
# Include RMagick or ImageScience support
|
4
|
+
# include CarrierWave::RMagick
|
5
|
+
# include CarrierWave::ImageScience
|
6
|
+
include CarrierWave::MiniMagick
|
7
|
+
|
8
|
+
# Choose what kind of storage to use for this uploader
|
9
|
+
storage :file
|
10
|
+
# storage :s3
|
11
|
+
|
12
|
+
# Override the directory where uploaded files will be stored
|
13
|
+
# This is a sensible default for uploaders that are meant to be mounted:
|
14
|
+
|
15
|
+
def root
|
16
|
+
"shared/public"
|
17
|
+
end
|
18
|
+
|
19
|
+
def store_dir
|
20
|
+
"uploads"
|
21
|
+
end
|
22
|
+
|
23
|
+
def cache_dir
|
24
|
+
"tmp"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Provide a default URL as a default if there hasn't been a file uploaded
|
28
|
+
# def default_url
|
29
|
+
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
|
30
|
+
# end
|
31
|
+
# Process files as they are uploaded.
|
32
|
+
process :resize_to_fit => [640, 480]
|
33
|
+
#
|
34
|
+
# def scale(width, height)
|
35
|
+
# # do something
|
36
|
+
# end
|
37
|
+
|
38
|
+
# Create different versions of your uploaded files
|
39
|
+
version :thumb do
|
40
|
+
process :resize_to_fit => [128, 128]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Add a white list of extensions which are allowed to be uploaded,
|
44
|
+
# for images you might use something like this:
|
45
|
+
# def extension_white_list
|
46
|
+
# %w(jpg jpeg gif png)
|
47
|
+
# end
|
48
|
+
|
49
|
+
# Override the filename of the uploaded files
|
50
|
+
# def filename
|
51
|
+
# "something.jpg" if original_filename
|
52
|
+
# end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
var grid = new Admin.grid({
|
2
|
+
id: 'grid-uploads',
|
3
|
+
title: 'List Upload',
|
4
|
+
baseUrl: '/admin/uploads',
|
5
|
+
buttons: ['remove'],
|
6
|
+
column_fields: <%= @store.column_fields %>,
|
7
|
+
store_fields: <%= @store.store_fields %>
|
8
|
+
});
|
9
|
+
|
10
|
+
grid.on('dblclick', function(r){
|
11
|
+
var sel = grid.getSelectionModel().getSelected();
|
12
|
+
if (!sel) return;
|
13
|
+
Admin.app.mask();
|
14
|
+
var image = new Image();
|
15
|
+
image.src = sel.data['uploads.file'];
|
16
|
+
image.onerror = function(){ Admin.app.unmask() };
|
17
|
+
image.onload = function(){
|
18
|
+
if (image.width == 0 || image.height == 0) return;
|
19
|
+
var win = new Ext.Window({
|
20
|
+
resizable: false,
|
21
|
+
title: sel.data['uploads.file'],
|
22
|
+
html: '<img src="'+sel.data['uploads.file']+'" height="'+image.height+'" width="'+image.width+'" />'
|
23
|
+
});
|
24
|
+
Admin.app.unmask();
|
25
|
+
win.show();
|
26
|
+
}
|
27
|
+
});
|
28
|
+
|
29
|
+
var upload = new Ext.SwfUploadPanel({
|
30
|
+
id: 'grid-upload',
|
31
|
+
title: 'Upload a new file',
|
32
|
+
region: 'south',
|
33
|
+
collapsible: true,
|
34
|
+
collapseMode:'mini',
|
35
|
+
split: true,
|
36
|
+
single_select: this.single_select,
|
37
|
+
file_types: "*.*", // Default allow all file types
|
38
|
+
file_types_description: "All Files", // A text description that is displayed to the user in the File Browser dialog.
|
39
|
+
file_size_limit: "1MB", // Default size limit 1MB
|
40
|
+
file_upload_limit: "0", // Default no upload limit
|
41
|
+
file_queue_limit: "0", // Default no queue limit
|
42
|
+
upload_url: '/admin/uploads/create',
|
43
|
+
post_params: { '<%= @session_id %>': '<%= session[@session_id] %>' },
|
44
|
+
flash_url: '<%= uri_root_path("flash/swfupload.swf") %>',
|
45
|
+
labelWidth: 110,
|
46
|
+
height: 300
|
47
|
+
});
|
48
|
+
|
49
|
+
upload.on('fileUploadComplete', function(){ grid.store.reload() });
|
50
|
+
|
51
|
+
var panel = new Ext.Panel({
|
52
|
+
layout: 'border',
|
53
|
+
items: [grid, upload]
|
54
|
+
});
|
55
|
+
|
56
|
+
Admin.app.addItem(panel, '<%= params[:small] %>');
|
@@ -1,56 +1,71 @@
|
|
1
1
|
module Padrino
|
2
2
|
module Admin
|
3
3
|
module Helpers
|
4
|
-
|
4
|
+
##
|
5
|
+
# Returns true if +current_account+ is logged and active.
|
6
|
+
#
|
5
7
|
def logged_in?
|
6
8
|
!current_account.nil?
|
7
9
|
end
|
8
10
|
|
11
|
+
##
|
9
12
|
# Returns the current_account, it's an instance of <tt>Account</tt> model
|
13
|
+
#
|
10
14
|
def current_account
|
11
15
|
@current_account ||= login_from_session
|
12
16
|
end
|
13
17
|
|
14
|
-
|
18
|
+
##
|
19
|
+
# Return the admin menu
|
20
|
+
#
|
15
21
|
def admin_menu
|
16
22
|
return "[]" unless current_account
|
17
23
|
access_control.auths(current_account).project_modules.collect(&:config).to_json
|
18
24
|
end
|
19
25
|
|
26
|
+
##
|
20
27
|
# Ovverride the current_account, you must provide an instance of Account Model
|
21
28
|
#
|
22
29
|
# Examples:
|
23
30
|
#
|
24
31
|
# current_account = Account.last
|
25
32
|
#
|
26
|
-
def set_current_account(account)
|
27
|
-
session[
|
28
|
-
@current_account
|
33
|
+
def set_current_account(account=nil)
|
34
|
+
session[options.session_id] = account ? account.id : nil
|
35
|
+
@current_account = account
|
29
36
|
end
|
30
37
|
|
31
|
-
|
38
|
+
##
|
39
|
+
# Returns true if the +current_account+ is allowed to see the requested path
|
40
|
+
#
|
41
|
+
# For configure this role please refer to: +Padrino::AccessControl::Base+
|
32
42
|
#
|
33
|
-
# For configure this role please refer to: <tt>Padrino::AccessControl::Base</tt>
|
34
43
|
def allowed?
|
35
44
|
access_control.auths(current_account).can?(request.path_info)
|
36
45
|
end
|
37
46
|
|
38
|
-
|
39
|
-
#
|
47
|
+
##
|
48
|
+
# Returns a helper to pass in a +before_filter+ for check if
|
49
|
+
# an account are: +logged_in?+ and +allowed?+
|
40
50
|
#
|
41
51
|
# By default this method is used in BackendController so is not necessary
|
52
|
+
#
|
42
53
|
def login_required
|
43
54
|
store_location! if store_location
|
44
55
|
return access_denied unless allowed?
|
45
56
|
end
|
46
57
|
|
58
|
+
##
|
47
59
|
# Store in session[:return_to] the request.fullpath
|
60
|
+
#
|
48
61
|
def store_location!
|
49
62
|
session[:return_to] = request.fullpath
|
50
63
|
end
|
51
64
|
|
65
|
+
##
|
52
66
|
# Redirect the account to the page that requested an authentication or
|
53
67
|
# if the account is not allowed/logged return it to a default page
|
68
|
+
#
|
54
69
|
def redirect_back_or_default(default)
|
55
70
|
redirect_to(session[:return_to] || default)
|
56
71
|
session[:return_to] = nil
|
@@ -72,20 +87,16 @@ module Padrino
|
|
72
87
|
end
|
73
88
|
|
74
89
|
def login_page
|
75
|
-
options.login_page rescue nil #
|
90
|
+
options.login_page rescue nil # on sinatra 9.4.x respond_to?(:login_page) didn't work
|
76
91
|
end
|
77
92
|
|
78
93
|
def store_location
|
79
94
|
options.store_location rescue false
|
80
95
|
end
|
81
96
|
|
82
|
-
def
|
83
|
-
options.
|
84
|
-
end
|
85
|
-
|
86
|
-
def login_from_session #:nodoc:
|
87
|
-
Account.first(:conditions => { :id => session[session_name] }) if defined?(Account)
|
97
|
+
def login_from_session
|
98
|
+
Account.first(:conditions => { :id => session[options.session_id] }) if defined?(Account)
|
88
99
|
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
100
|
+
end # Helpers
|
101
|
+
end # Admin
|
102
|
+
end # Padrino
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Padrino
|
2
2
|
module Admin
|
3
3
|
module Helpers
|
4
|
+
##
|
4
5
|
# Set the title of the page.
|
5
6
|
#
|
6
7
|
# An interesting thing wose that this helper
|
@@ -11,13 +12,17 @@ module Padrino
|
|
11
12
|
#
|
12
13
|
def title(title)
|
13
14
|
title = I18n.t("admin.titles.#{title}", :default => title.to_s) if title.is_a?(Symbol)
|
14
|
-
|
15
|
+
tag(:span, :title => title)
|
15
16
|
end
|
16
17
|
|
18
|
+
##
|
17
19
|
# This method work like error_message_for but use an Ext.Message.show({..})
|
20
|
+
#
|
18
21
|
def show_messages_for(*objects)
|
19
|
-
options
|
20
|
-
count
|
22
|
+
options = objects.extract_options!.symbolize_keys
|
23
|
+
count = objects.inject(0) {|sum, object| sum + object.errors.count }
|
24
|
+
error_cleaner = objects.map{|object| object.class.properties.map{|k| "if ($('#{object.class.to_s.downcase}_#{k.name}')) $('#{object.class.to_s.downcase}_#{k.name}').removeClassName('x-form-invalid');" } }.join("\n")
|
25
|
+
|
21
26
|
unless count.zero?
|
22
27
|
html = {}
|
23
28
|
options[:object_name] ||= objects.first.class
|
@@ -33,13 +38,12 @@ module Padrino
|
|
33
38
|
message = escape_javascript(options.include?(:message) ? options[:message] : locale.t(:body))
|
34
39
|
error_messages = objects.map {|object| object.errors.full_messages.map {|msg| content_tag(:li, escape_javascript(msg)) } }.join
|
35
40
|
error_highlighter = objects.map {|object| object.errors_keys.map{ |k| "$('#{object.class.to_s.downcase}_#{k}').addClassName('x-form-invalid');" } }.join("\n")
|
36
|
-
|
37
41
|
contents = ''
|
38
42
|
contents << content_tag(:p, message) if message.present?
|
39
43
|
contents << content_tag(:ul, error_messages, :class => :list)
|
40
44
|
|
41
45
|
(<<-JAVASCRIPT).gsub(/ {14}/, '')
|
42
|
-
|
46
|
+
#{error_cleaner}
|
43
47
|
Ext.Msg.show({
|
44
48
|
title: '#{header_message}',
|
45
49
|
msg: '<ul>#{contents}</ul>',
|
@@ -51,12 +55,13 @@ module Padrino
|
|
51
55
|
end
|
52
56
|
else
|
53
57
|
(<<-JAVASCRIPT).gsub(/ {12}/, '')
|
54
|
-
|
58
|
+
#{error_cleaner}
|
55
59
|
Ext.Msg.alert(Admin.locale.messages.compliments.title, Admin.locale.messages.compliments.message);
|
56
60
|
JAVASCRIPT
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
64
|
+
##
|
60
65
|
# This method add tab for in your view.
|
61
66
|
#
|
62
67
|
# First argument is the name and title of the tab, an interesting thing wose that this helper
|
@@ -70,8 +75,8 @@ module Padrino
|
|
70
75
|
#
|
71
76
|
# Third argument is an hash that accepts:
|
72
77
|
#
|
73
|
-
#
|
74
|
-
#
|
78
|
+
# :id:: The id of the tab
|
79
|
+
# :style:: Custom style of the tab
|
75
80
|
#
|
76
81
|
def tab(name, padding=true, options={}, &block)
|
77
82
|
options[:id] ||= name.to_s.downcase.gsub(/[^a-z0-9]+/, '_').gsub(/-+$/, '').gsub(/^-+$/, '')
|
@@ -83,6 +88,7 @@ module Padrino
|
|
83
88
|
concat_content content_tag(:div, container, options)
|
84
89
|
end
|
85
90
|
|
91
|
+
##
|
86
92
|
# This method generates a new ExtJs BoxComponent.
|
87
93
|
#
|
88
94
|
# Examples:
|
@@ -96,43 +102,174 @@ module Padrino
|
|
96
102
|
# * :collapsible => false
|
97
103
|
# * :start => :close
|
98
104
|
#
|
99
|
-
def box(title=nil,
|
105
|
+
def box(title=nil, options={}, &block)
|
100
106
|
title = I18n.t("admin.boxs.#{title.to_s.downcase}", :default => title.to_s.humanize) if title.is_a?(Symbol)
|
107
|
+
subtitle = options.delete(:subtitle)
|
101
108
|
options[:style] ||= "width:100%;"
|
102
109
|
options[:start] ||= :open
|
103
|
-
concat_content <<-HTML
|
104
|
-
<div class="
|
105
|
-
<div class="x-box
|
106
|
-
<div class="x-box-
|
107
|
-
<div class="x-box-
|
110
|
+
concat_content (<<-HTML).gsub(/ {10}/, '')
|
111
|
+
<div class="#{options[:class]}" style="options[:margin]">
|
112
|
+
<div class="x-box">
|
113
|
+
<div class="x-box-tl">
|
114
|
+
<div class="x-box-tr">
|
115
|
+
<div class="x-box-tc"> </div>
|
116
|
+
</div>
|
108
117
|
</div>
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
118
|
+
<div class="x-box-ml">
|
119
|
+
<div class="x-box-mr">
|
120
|
+
<div class="x-box-mc">
|
121
|
+
<div id="x-body-title" style="#{"cursor:pointer" if options[:collapsible]}" onclick="#{"Backend.app.collapseBoxes(this);" if options[:collapsible]}">
|
122
|
+
#{"<h3 style=\"margin-bottom:0px;padding-bottom:0px;float:left;\">"+title+"</h3>" if title.present?}
|
123
|
+
#{"<div style=\"float:right\"><em>"+subtitle+"</em></div>" if subtitle.present?}
|
124
|
+
#{"<br class=\"clear\" />" if title.present? || subtitle.present?}
|
125
|
+
#{"<div style=\"font-size:0px\"> </div>" if title.present? || subtitle.present?}
|
126
|
+
</div>
|
127
|
+
<div class="#{"x-box-collapsible" if options[:collapsible]}" style="width:99%;#{"display:none" if options[:collapsible] && options[:start] == :close}">
|
128
|
+
#{"<div style=\"font-size:10px\"> </div>" if title.present? || subtitle.present?}
|
129
|
+
#{capture_html(&block)}
|
130
|
+
#{"<div style=\"text-align:right;margin-top:10px\">#{submit_tag(I18n.t("lipsiadmin.buttons.save"), :onclick=>"Backend.app.submitForm()")}</div>" if options[:submit]}
|
131
|
+
</div>
|
123
132
|
</div>
|
124
133
|
</div>
|
125
134
|
</div>
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
135
|
+
<div class="x-box-bl">
|
136
|
+
<div class="x-box-br">
|
137
|
+
<div class="x-box-bc"> </div>
|
138
|
+
</div>
|
130
139
|
</div>
|
131
140
|
</div>
|
132
141
|
</div>
|
133
142
|
HTML
|
134
143
|
end
|
135
144
|
|
136
|
-
|
137
|
-
|
138
|
-
|
145
|
+
##
|
146
|
+
# Open a Standard window that can contain a grid. Works like a select_tag.
|
147
|
+
#
|
148
|
+
# Options can be:
|
149
|
+
#
|
150
|
+
# :with:: name of the association. Ex: :images.
|
151
|
+
# :url:: the url of the gird, by default we autogenerate them using +:with+ ex: url(:images_index, :format => :js)
|
152
|
+
# :show:: value to display, if it's a symbol we tranform them using +with+ ex: :name, will be: data["images.name"]
|
153
|
+
# :get:: value to store in our db, Default: +:id+
|
154
|
+
# :grid:: the name of the var of Admin.grid. Default :grid
|
155
|
+
# :item:: the name of container. This necessary in cases where our grid it's in another container.
|
156
|
+
# :update:: javascript function to handle when the user close grid with some selections. Default autogenerated.
|
157
|
+
# :prompt:: text or html tag to prompt. Default is autogenerated.
|
158
|
+
# :prompt_destroy:: text or html tag to prompt for clear current selections. Default is autogenerated.
|
159
|
+
# :function:: name of the function. Default is autogenerated.
|
160
|
+
# :multiple:: if true returns a collections of +:value+. Default false.
|
161
|
+
#
|
162
|
+
# Example multiple values:
|
163
|
+
# # Generate:
|
164
|
+
# # <script type="text/javascript">
|
165
|
+
# # function showAccountImages(){
|
166
|
+
# # Ext.Ajax.request({
|
167
|
+
# # url: '/admin/images.js',
|
168
|
+
# # scripts: false,
|
169
|
+
# # success: function(response){
|
170
|
+
# # try { eval(response.responseText) } catch(e) { Admin.app.error(e) };
|
171
|
+
# # var win = new Admin.window({ grid: grid, width: 800, height: 600 });
|
172
|
+
# # win.on('selected', function(win, selections){ ... });
|
173
|
+
# # win.show();
|
174
|
+
# # }
|
175
|
+
# # });
|
176
|
+
# # }
|
177
|
+
# # </script>
|
178
|
+
# # <ul id="account_images">
|
179
|
+
# # <li>
|
180
|
+
# # <span id="display">Foo</span>
|
181
|
+
# # <input type="hidden" name="account[image_ids][]" value = "1" />
|
182
|
+
# # <a href="#" onclick="this.up('li').destroy(); return false">Remove</a>
|
183
|
+
# # </li>
|
184
|
+
# # <li>
|
185
|
+
# # <span id="display">Bar</span>
|
186
|
+
# # <input type="hidden" name="account[image_ids][]" value = "2" />
|
187
|
+
# # <a href="#" onclick="this.up('li').destroy(); return false">Remove</a>
|
188
|
+
# # </li>
|
189
|
+
# # </ul>
|
190
|
+
# # <a href="#" onclick="showAccountImages(); return false">Show Images</a>
|
191
|
+
# open_grid :account, :image_ids, :with => :images, :show => :name, :get => :id, :multiple => true
|
192
|
+
#
|
193
|
+
def open_window_grid(object_name, method, options={})
|
194
|
+
|
195
|
+
# We need plural version of our association
|
196
|
+
controller = options[:multiple] ? options[:with] : "#{options[:with].to_s.pluralize}".to_sym
|
197
|
+
|
198
|
+
# Now we need our association
|
199
|
+
association = instance_variable_get("@#{object_name}").send(options[:with])
|
200
|
+
|
201
|
+
# Parsing not mandatory options
|
202
|
+
options[:url] ||= url("#{controller}_index".to_sym, :format => :js, :small => true)
|
203
|
+
options[:grid] ||= :grid
|
204
|
+
options[:item] ||= :undefined
|
205
|
+
options[:get] ||= :id
|
206
|
+
options[:prompt] ||= image_tag("admin/new.gif", :style => "vertical-align:bottom;padding:2px")
|
207
|
+
options[:function] ||= "show#{object_name.to_s.capitalize}#{options[:with].to_s.capitalize}"
|
208
|
+
|
209
|
+
# Here we build our html template
|
210
|
+
input_name = "#{object_name}[#{method}]"
|
211
|
+
input_name += "[]" if options[:multiple]
|
212
|
+
|
213
|
+
template = (<<-HTML).gsub(/ {10}/, "")
|
214
|
+
<li>
|
215
|
+
<span class="display">{0}</span>
|
216
|
+
<input type="hidden" name="#{input_name}" value="{1}">
|
217
|
+
<a href="#" onclick="this.up(\\'li\\').remove(); return false" class="closebutton"> </a>
|
218
|
+
</li>
|
219
|
+
HTML
|
220
|
+
|
221
|
+
# We create a collection of <li>
|
222
|
+
collection = Array(association).map do |item|
|
223
|
+
template.gsub("{0}", item.send(options[:show]).to_s).
|
224
|
+
gsub("{1}", item.send(options[:get]).to_s)
|
225
|
+
end
|
226
|
+
|
227
|
+
# And we add our link for add new records
|
228
|
+
collection << content_tag(:li, link_to(options[:prompt], "#", :onclick => "#{options[:function]}(); return false;"), :class => :clean)
|
229
|
+
|
230
|
+
# Now we have the final container
|
231
|
+
container = content_tag(:ul, collection.join.gsub("\\",""), :id => "#{object_name}_#{method}", :class => "open-window-grid")
|
232
|
+
|
233
|
+
# We need to refactor some values
|
234
|
+
show = "data['#{controller}.#{options[:show]}']" if options[:show].is_a?(Symbol)
|
235
|
+
get = options[:get].is_a?(Symbol) && options[:get] != :id ? "data['#{controller}.#{options[:get]}']" : options[:get]
|
236
|
+
|
237
|
+
update_function = if options[:multiple]
|
238
|
+
(<<-JAVASCRIPT).gsub(/ {12}/, "")
|
239
|
+
Ext.each(selections, function(selection){
|
240
|
+
var template = String.format('#{template.gsub(/\n/,"")}', selection.#{show}, selection.#{get});
|
241
|
+
Ext.fly('#{object_name}_#{method}').insertHtml('afterBegin', template);
|
242
|
+
});
|
243
|
+
JAVASCRIPT
|
244
|
+
else
|
245
|
+
(<<-JAVASCRIPT).gsub(/ {12}/, "")
|
246
|
+
var selection = selections.first();
|
247
|
+
var template = String.format('#{template.gsub(/\n/,"")}', selection.#{show}, selection.#{get});
|
248
|
+
Ext.fly('#{object_name}_#{method}').update(template);
|
249
|
+
JAVASCRIPT
|
250
|
+
end
|
251
|
+
|
252
|
+
# Now we build the update function (if not present)
|
253
|
+
javascript = (<<-JAVASCRIPT).gsub(/ {10}/, '')
|
254
|
+
function #{options[:function]}(){
|
255
|
+
Ext.Ajax.request({
|
256
|
+
url: '#{options[:url]}',
|
257
|
+
scripts: false,
|
258
|
+
success: function(response){
|
259
|
+
try { eval(response.responseText) } catch(e) { Admin.app.error(e) };
|
260
|
+
var win = new Admin.window({ grid: #{options[:grid]}, item: #{options[:item]}, width: 800, height: 600 });
|
261
|
+
win.on('selected', function(win, selections){
|
262
|
+
#{update_function}
|
263
|
+
});
|
264
|
+
win.show();
|
265
|
+
}
|
266
|
+
});
|
267
|
+
}
|
268
|
+
JAVASCRIPT
|
269
|
+
|
270
|
+
# Now we return our html code
|
271
|
+
[content_tag(:script, javascript, :type => 'text/javascript'), container, tag(:div, :class => :clear)].join("\n")
|
272
|
+
end
|
273
|
+
end # Helpers
|
274
|
+
end # Admin
|
275
|
+
end # Padrino
|