adminpanel 1.2.9 → 1.2.10
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.
- data/Gemfile +1 -0
- data/adminpanel.gemspec +1 -0
- data/app/controllers/adminpanel/analytics_controller.rb +1 -1
- data/app/controllers/adminpanel/application_controller.rb +6 -6
- data/app/controllers/adminpanel/categories_controller.rb +17 -8
- data/app/controllers/adminpanel/galleries_controller.rb +2 -0
- data/app/controllers/adminpanel/sections_controller.rb +2 -0
- data/app/controllers/adminpanel/sessions_controller.rb +2 -2
- data/app/controllers/adminpanel/users_controller.rb +2 -0
- data/app/helpers/adminpanel/custom_form_builder.rb +24 -0
- data/app/helpers/adminpanel/rest_actions_helper.rb +26 -9
- data/app/helpers/adminpanel/shared_pages_helper.rb +2 -1
- data/app/models/adminpanel/group.rb +6 -0
- data/app/models/adminpanel/user.rb +48 -5
- data/app/views/adminpanel/categories/_categories_table.html.erb +3 -2
- data/app/views/adminpanel/categories/_category_form.html.erb +4 -4
- data/app/views/adminpanel/categories/create.js.erb +2 -1
- data/app/views/adminpanel/categories/index.html.erb +1 -1
- data/app/views/adminpanel/categories/new.js.erb +2 -1
- data/app/views/layouts/_side_menu.html.erb +20 -18
- data/app/views/layouts/_top_bar.html.erb +1 -1
- data/app/views/shared/_form_fields.html.erb +57 -5
- data/app/views/shared/_modal.html.erb +8 -0
- data/app/views/shared/_remote_form_fields.html.erb +12 -0
- data/app/views/shared/create_belongs_to.js.erb +5 -0
- data/app/views/shared/create_has_many.js.erb +5 -0
- data/app/views/shared/edit.html.erb +1 -0
- data/app/views/shared/new.html.erb +15 -4
- data/app/views/shared/new.js.erb +2 -0
- data/config/locales/es.yml +5 -3
- data/lib/adminpanel.rb +1 -0
- data/lib/adminpanel/active_record/adminpanel_extension.rb +0 -4
- data/lib/adminpanel/version.rb +1 -1
- data/lib/generators/adminpanel/initialize/initialize_generator.rb +11 -0
- data/lib/generators/adminpanel/initialize/templates/ability.rb +31 -0
- data/lib/generators/adminpanel/initialize/templates/adminpanel_setup.rb +7 -7
- data/lib/generators/adminpanel/initialize/templates/create_adminpanel_tables.rb +9 -1
- data/lib/tasks/adminpanel/adminpanel.rake +2 -1
- data/spec/dummy/app/models/ability.rb +31 -0
- data/spec/dummy/app/models/adminpanel/category.rb +4 -1
- data/spec/features/authentication_pages_spec.rb +6 -5
- data/spec/features/galleries_pages_spec.rb +3 -1
- data/spec/features/section_pages_spec.rb +2 -1
- data/spec/features/shared_pages_spec.rb +66 -22
- data/spec/generators/gallery_generator_spec.rb +3 -3
- data/spec/generators/resource_generator_spec.rb +3 -3
- data/spec/models/gallery_spec.rb +3 -1
- data/spec/models/section_spec.rb +12 -11
- data/spec/models/user_spec.rb +6 -2
- data/spec/spec_helper.rb +5 -2
- data/spec/support/define_factory_models.rb +6 -0
- data/spec/support/helper_methods.rb +2 -1
- data/spec/support/test_database.rb +7 -0
- data/spec/tasks/adminpanel_rake_spec.rb +1 -0
- metadata +53 -32
- data/spec/dummy/app/controllers/adminpanel/categories_controller.rb +0 -4
- data/spec/models/product_spec.rb +0 -39
@@ -13,30 +13,82 @@
|
|
13
13
|
<% end %>
|
14
14
|
|
15
15
|
<% elsif properties["type"] == "adminpanel_file_field" %>
|
16
|
+
<% if !defined? remote_request %>
|
16
17
|
<%= f.fields_for(attribute) do |builder| %>
|
17
18
|
<%= render 'shared/image_fields', :f => builder %>
|
18
19
|
<% end -%>
|
19
20
|
<%= link_to_add_fields t("Add Image"), f, attribute %>
|
20
21
|
|
22
|
+
<% end %>
|
21
23
|
<% elsif properties["type"] == "belongs_to" %>
|
24
|
+
<% if !defined? remote_request %>
|
22
25
|
<% args = properties.except("type", "name", "model") %>
|
23
26
|
<% args.symbolize_keys! %>
|
24
27
|
<%= f.select(attribute, (@collections["#{properties["model"]}"].collect{|resource| [resource.name, resource.id]}), args) %>
|
25
28
|
|
26
|
-
|
27
|
-
|
29
|
+
|
30
|
+
<% if(properties['remote_resource'].nil? || properties['remote_resource']) %>
|
31
|
+
<!-- Button to create a new of this belongs_to resource -->
|
32
|
+
<% model_name = properties['model'].classify.constantize.model_name.demodulize.downcase %>
|
33
|
+
<%=
|
34
|
+
link_to(
|
35
|
+
I18n.t('other.add',
|
36
|
+
:model => properties['model'].classify.constantize.display_name
|
37
|
+
),
|
38
|
+
polymorphic_path(
|
39
|
+
[:new, :"#{model_name}"],
|
40
|
+
:model => @model.display_name,
|
41
|
+
:model_name => @model.name.demodulize.downcase,
|
42
|
+
:belongs_request => true
|
43
|
+
),
|
44
|
+
:class => 'btn btn-info',
|
45
|
+
:id => "#{model_name}-modal-link",
|
46
|
+
:'data-target' => "#new-modal",
|
47
|
+
:'data-toggle' => 'modal',
|
48
|
+
:remote => true
|
49
|
+
)
|
50
|
+
%>
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
|
54
|
+
<% end %>
|
55
|
+
<% elsif properties['type'] == 'has_many' %>
|
56
|
+
<% if !defined? remote_request %>
|
28
57
|
<div class="control-group">
|
29
58
|
<div class="control-label">
|
30
|
-
<%= I18n.t('other.choose', :model => pluralize_es(properties[
|
59
|
+
<%= I18n.t('other.choose', :model => pluralize_es(properties['model'].classify.constantize.display_name)) %>
|
31
60
|
</div>
|
32
61
|
<%= hidden_field_tag("#{class_name_downcase(f.object)}[#{relationship_ids(properties["model"])}][]", nil) %>
|
33
|
-
<div class="controls">
|
34
|
-
<% @collections["#{properties[
|
62
|
+
<div class="controls" id="<%= properties['model'].demodulize.downcase %>-relation">
|
63
|
+
<% @collections["#{properties['model']}"].each do |resource| %>
|
35
64
|
<%= f.checkbox(resource, class_name_downcase(f.object) ,relationship_ids(properties["model"])) %>
|
36
65
|
<% end %>
|
37
66
|
</div>
|
38
67
|
</div>
|
39
68
|
|
69
|
+
<% if properties['remote_resource'].nil? || propeties['remote_resource'] %>
|
70
|
+
<!-- Button to create a new of this has_many resource -->
|
71
|
+
<% model_name = properties['model'].classify.constantize.model_name.demodulize.downcase %>
|
72
|
+
<%=
|
73
|
+
link_to(
|
74
|
+
I18n.t('other.add',
|
75
|
+
:model => properties['model'].classify.constantize.display_name
|
76
|
+
),
|
77
|
+
polymorphic_path(
|
78
|
+
[:new, :"#{model_name}"],
|
79
|
+
:model => @model.display_name,
|
80
|
+
:model_name => @model.name.demodulize.downcase
|
81
|
+
),
|
82
|
+
:class => 'btn btn-info',
|
83
|
+
:id => "#{model_name}-modal-link",
|
84
|
+
:'data-target' => "#new-modal",
|
85
|
+
:'data-toggle' => 'modal',
|
86
|
+
:remote => true
|
87
|
+
)
|
88
|
+
%>
|
89
|
+
<% end %>
|
90
|
+
<% end %>
|
91
|
+
|
40
92
|
<% else %>
|
41
93
|
<% type = properties["type"] %>
|
42
94
|
<% args = properties.except("type", "name") %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div id="new-modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
2
|
+
<div class="modal-header" id="modal-header">
|
3
|
+
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
4
|
+
<h3 id="modal-title"></h3>
|
5
|
+
</div>
|
6
|
+
<div id="modal-container">
|
7
|
+
</div>
|
8
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= custom_form_for(resource, :url => {:action => :create, :model => params[:model], :model_name => params[:model_name], :belongs_request => params[:belongs_request] }, :remote => true, :html => {:class => "form-horizontal", :id => "new_resource"}) do |f| -%>
|
2
|
+
<div class="row-fluid">
|
3
|
+
<div class="modal-body">
|
4
|
+
<%= render 'shared/error_messages', :object => resource %>
|
5
|
+
<%= render 'shared/form_fields', :f => f, :remote_request => true %>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
<div class="modal-footer">
|
9
|
+
<button id="modal-button" class="btn" data-dismiss="modal" aria-hidden="true"><%= I18n.t('action.close') %></button>
|
10
|
+
<%= f.submit t("action.add") + " " + @model.display_name, :disable_with => t("action.submitting"), :id =>"new-resource-button" %>
|
11
|
+
</div>
|
12
|
+
<% end -%>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
var model_name = "<%= params[:model_name] %>";
|
2
|
+
var new_model = "<%= @model.name.demodulize.downcase %>";
|
3
|
+
var option = '<option value="<%= resource.id %>" selected="selected"><%= resource.name %></option>';
|
4
|
+
$("#" + model_name + "_" + new_model + "_id").append(option);
|
5
|
+
$("#new-modal").modal('toggle');
|
@@ -0,0 +1,5 @@
|
|
1
|
+
var model_name = "<%= params[:model_name] %>";
|
2
|
+
var new_model = "<%= @model.name.demodulize.downcase %>";
|
3
|
+
row = '<label class="checkbox"><input checked="checked" id="' + model_name + '_' + new_model + '_ids_" name="' + model_name + '[' + new_model + '_ids][]" type="checkbox" value="<%= resource.id %>"><%= resource.name %></label>';
|
4
|
+
$("#" + new_model + "-relation").append(row);
|
5
|
+
$("#new-modal").modal('toggle');
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% provide(:page_title, t("action.create") + " #{@model.display_name.capitalize}") -%>
|
2
2
|
<% breadcrumb_add(
|
3
|
-
@model.display_name.capitalize.pluralize,
|
3
|
+
@model.display_name.capitalize.pluralize,
|
4
4
|
{
|
5
5
|
:controller => params[:controller],
|
6
6
|
:action => "index"
|
@@ -15,14 +15,25 @@
|
|
15
15
|
</div>
|
16
16
|
<div class = "widget-body">
|
17
17
|
<div class = "widget-forms clearfix">
|
18
|
-
<%=
|
18
|
+
<%=
|
19
|
+
custom_form_for(
|
20
|
+
resource, :html => {
|
21
|
+
:class => "form-horizontal",
|
22
|
+
:id => "new_resource"
|
23
|
+
}
|
24
|
+
) do |f| -%>
|
19
25
|
<%= render 'shared/error_messages', :object => resource %>
|
20
26
|
<%= render 'shared/form_fields', :f => f %>
|
21
27
|
</div>
|
22
28
|
</div>
|
23
29
|
<div class = "widget-footer">
|
24
|
-
<%=
|
30
|
+
<%=
|
31
|
+
f.submit t("action.add") + " " + @model.display_name,
|
32
|
+
:disable_with => t("action.submitting"),
|
33
|
+
:id =>"new-#{@model.name.demodulize}-button"
|
34
|
+
%>
|
25
35
|
</div>
|
26
36
|
<% end -%>
|
27
37
|
</div>
|
28
|
-
</div>
|
38
|
+
</div>
|
39
|
+
<%= render 'shared/modal' %>
|
data/config/locales/es.yml
CHANGED
@@ -8,10 +8,10 @@ es:
|
|
8
8
|
brief: "Pequeña descripción"
|
9
9
|
category_id: "Categoría"
|
10
10
|
client_id: "Cliente"
|
11
|
-
adminproject_id: "Proyecto"
|
12
11
|
description: "Descripción"
|
13
12
|
email: "Correo electrónico"
|
14
13
|
file: "Imagen"
|
14
|
+
group_id: "Rol de usuario"
|
15
15
|
name: "Nombre"
|
16
16
|
password: "Contraseña"
|
17
17
|
password_confirmation: "Confirmar contraseña"
|
@@ -55,8 +55,9 @@ es:
|
|
55
55
|
delete confirmation: "Estás seguro que desea eliminar?"
|
56
56
|
authentication:
|
57
57
|
welcome: "Bienvenido! Inicia Sesión"
|
58
|
-
|
59
|
-
|
58
|
+
signin_error: "Correo y/o Contraseña incorrecta."
|
59
|
+
signin_success: "Bienvenido!"
|
60
|
+
not_authorized: 'No tienes permisos para acceder'
|
60
61
|
gallery:
|
61
62
|
new: "Agregar Imagen"
|
62
63
|
success: "La imagen ha sido guardada"
|
@@ -79,6 +80,7 @@ es:
|
|
79
80
|
password: "Contraseña"
|
80
81
|
email: "Correo electrónico"
|
81
82
|
other:
|
83
|
+
add : "Agregar %{model}"
|
82
84
|
choose: "Selecciona %{model} pertenecientes"
|
83
85
|
no description: "No tiene descripción aún"
|
84
86
|
key:
|
data/lib/adminpanel.rb
CHANGED
data/lib/adminpanel/version.rb
CHANGED
@@ -25,6 +25,11 @@ module Adminpanel
|
|
25
25
|
:aliases => '-p',
|
26
26
|
:default => false,
|
27
27
|
:desc => 'Skip setup if true'
|
28
|
+
class_option :'skip-setup',
|
29
|
+
:type => :boolean,
|
30
|
+
:aliases => '-y',
|
31
|
+
:default => false,
|
32
|
+
:desc => 'Skip cancan\'s ability.rb'
|
28
33
|
|
29
34
|
def create_initializers
|
30
35
|
if !options[:'skip-setup']
|
@@ -32,6 +37,12 @@ module Adminpanel
|
|
32
37
|
end
|
33
38
|
end
|
34
39
|
|
40
|
+
def create_ability
|
41
|
+
if !options[:'skip-ability']
|
42
|
+
copy_file 'ability.rb', 'app/models/ability.rb'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
35
46
|
def create_categories
|
36
47
|
if !options[:'skip-category']
|
37
48
|
# puts "including category files"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Ability
|
2
|
+
include CanCan::Ability
|
3
|
+
|
4
|
+
def initialize(user)
|
5
|
+
|
6
|
+
if user.group.name == "Admin"
|
7
|
+
can :manage, :all
|
8
|
+
else
|
9
|
+
# cannot :manage, Adminpanel::User
|
10
|
+
# can :manage, Adminpanel::Analytic
|
11
|
+
# can :manage, Adminpanel::Section
|
12
|
+
# can :manage, Adminpanel::Gallery
|
13
|
+
# can :manage, Adminpanel::Category
|
14
|
+
end
|
15
|
+
|
16
|
+
# The first argument to `can` is the action you are giving the user
|
17
|
+
# permission to do.
|
18
|
+
# If you pass :manage it will apply to every action. Other common actions
|
19
|
+
# here are :read, :create, :update and :destroy.
|
20
|
+
#
|
21
|
+
# The second argument is the resource the user can perform the action on.
|
22
|
+
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
|
23
|
+
# class of the resource.
|
24
|
+
#
|
25
|
+
# The third argument is an optional hash of conditions to further filter the
|
26
|
+
# objects.
|
27
|
+
# For example, here the user can only update published articles.
|
28
|
+
#
|
29
|
+
# can :update, Article, :published => true
|
30
|
+
end
|
31
|
+
end
|
@@ -11,11 +11,11 @@ Adminpanel.setup do |config|
|
|
11
11
|
# config.analytics_key_path = "config/analytics"
|
12
12
|
|
13
13
|
# # This are the modules that are going to be displayed and order that are going to be displayed
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
config.displayable_resources = [
|
15
|
+
:analytics,
|
16
|
+
:users,
|
17
|
+
:galleries,
|
18
|
+
:sections,
|
19
|
+
:categories
|
20
|
+
]
|
21
21
|
end
|
@@ -4,8 +4,11 @@ class CreateAdminpanelTables < ActiveRecord::Migration
|
|
4
4
|
# Create a default user
|
5
5
|
if direction == :up
|
6
6
|
if Rails.env.development?
|
7
|
-
Adminpanel::
|
7
|
+
group = Adminpanel::Group.new(:name => "Admin")
|
8
|
+
group.save
|
9
|
+
Adminpanel::User.new(:email => 'admin@admin.com', :name => "Admin", :password => 'password', :password_confirmation => 'password', :group_id => group.object_id).save
|
8
10
|
puts "The password for admin@admin.com is: password"
|
11
|
+
|
9
12
|
end
|
10
13
|
end
|
11
14
|
end
|
@@ -33,6 +36,11 @@ class CreateAdminpanelTables < ActiveRecord::Migration
|
|
33
36
|
t.timestamps
|
34
37
|
end
|
35
38
|
|
39
|
+
create_table :adminpanel_groups do |t|
|
40
|
+
t.string :name
|
41
|
+
t.timestamps
|
42
|
+
end
|
43
|
+
|
36
44
|
create_table :adminpanel_sections do |t|
|
37
45
|
t.string :name
|
38
46
|
t.boolean :has_description
|
@@ -45,7 +45,8 @@ namespace :adminpanel do
|
|
45
45
|
:email => 'admin@codn.com',
|
46
46
|
:name => 'CoDN',
|
47
47
|
:password => password,
|
48
|
-
:password_confirmation => password
|
48
|
+
:password_confirmation => password,
|
49
|
+
:group_id => Adminpanel::Group.find_by_name("Admin").object_id
|
49
50
|
).save
|
50
51
|
end
|
51
52
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Ability
|
2
|
+
include CanCan::Ability
|
3
|
+
|
4
|
+
def initialize(user)
|
5
|
+
|
6
|
+
if user.group.name == "Admin"
|
7
|
+
can :manage, :all
|
8
|
+
else
|
9
|
+
# cannot :manage, Adminpanel::User
|
10
|
+
# can :manage, Adminpanel::Analytic
|
11
|
+
# can :manage, Adminpanel::Section
|
12
|
+
# can :manage, Adminpanel::Gallery
|
13
|
+
# can :manage, Adminpanel::Category
|
14
|
+
end
|
15
|
+
|
16
|
+
# The first argument to `can` is the action you are giving the user
|
17
|
+
# permission to do.
|
18
|
+
# If you pass :manage it will apply to every action. Other common actions
|
19
|
+
# here are :read, :create, :update and :destroy.
|
20
|
+
#
|
21
|
+
# The second argument is the resource the user can perform the action on.
|
22
|
+
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
|
23
|
+
# class of the resource.
|
24
|
+
#
|
25
|
+
# The third argument is an optional hash of conditions to further filter the
|
26
|
+
# objects.
|
27
|
+
# For example, here the user can only update published articles.
|
28
|
+
#
|
29
|
+
# can :update, Article, :published => true
|
30
|
+
end
|
31
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Adminpanel
|
2
2
|
class Category < ActiveRecord::Base
|
3
|
-
attr_accessible :product_ids, :name
|
3
|
+
attr_accessible :product_ids, :name, :model
|
4
|
+
|
5
|
+
validates_presence_of :model
|
4
6
|
|
5
7
|
has_many :categorizations
|
6
8
|
has_many :products, :through => :categorizations, :dependent => :destroy
|
@@ -9,6 +11,7 @@ module Adminpanel
|
|
9
11
|
def self.form_attributes
|
10
12
|
[
|
11
13
|
{"name" => {"type" => "text_field", "name" => "name", "label" => "name", "placeholder" => "name"}},
|
14
|
+
# {'model' => {"type" => "text_field", "name" => "name", "label" => "name", "placeholder" => "name", 'show' => 'false'}},
|
12
15
|
{"product_ids" => {"type" => "has_many", "model" => "Adminpanel::Product", "name" => "product_ids"}},
|
13
16
|
]
|
14
17
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'support/test_database'
|
2
3
|
|
3
4
|
describe "Authentication" do
|
4
5
|
|
5
6
|
subject { page }
|
6
|
-
|
7
|
+
|
7
8
|
describe "sign in page" do
|
8
9
|
before { visit adminpanel.signin_path }
|
9
10
|
|
@@ -20,7 +21,7 @@ describe "Authentication" do
|
|
20
21
|
|
21
22
|
it { expect(page).to have_title(I18n.t("Panel title")) }
|
22
23
|
|
23
|
-
it { should have_selector('div.alert.alert-error', :text => I18n.t("authentication.
|
24
|
+
it { should have_selector('div.alert.alert-error', :text => I18n.t("authentication.signin_error")) }
|
24
25
|
end
|
25
26
|
|
26
27
|
describe "with valid information" do
|
@@ -29,7 +30,7 @@ describe "Authentication" do
|
|
29
30
|
valid_signin(user)
|
30
31
|
end
|
31
32
|
|
32
|
-
it { should have_selector('div.alert.alert-success', :text => I18n.t("authentication.
|
33
|
+
it { should have_selector('div.alert.alert-success', :text => I18n.t("authentication.signin_success")) }
|
33
34
|
it { should have_selector('i.icon-off') }
|
34
35
|
|
35
36
|
describe "signing out" do
|
@@ -37,8 +38,8 @@ describe "Authentication" do
|
|
37
38
|
|
38
39
|
it { current_path.should == adminpanel.signin_path }
|
39
40
|
it { expect(page).to have_title(I18n.t("Panel title")) }
|
40
|
-
|
41
|
+
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
44
|
-
end
|
45
|
+
end
|