admin-panel 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +117 -0
  5. data/LICENSE +21 -0
  6. data/README.md +55 -0
  7. data/Rakefile +10 -0
  8. data/admin-panel.gemspec +29 -0
  9. data/lib/admin-panel/version.rb +3 -0
  10. data/lib/generators/admin_panel/install/install_generator.rb +69 -0
  11. data/lib/generators/admin_panel/install/templates/README +10 -0
  12. data/lib/generators/admin_panel/install/templates/assets/javascripts/admin.js +1 -0
  13. data/lib/generators/admin_panel/install/templates/assets/stylesheets/admin.css.scss +1 -0
  14. data/lib/generators/admin_panel/install/templates/controllers/admin/dashboard_controller.rb +3 -0
  15. data/lib/generators/admin_panel/install/templates/controllers/admin/passwords_controller.rb +4 -0
  16. data/lib/generators/admin_panel/install/templates/controllers/admin/sessions_controller.rb +4 -0
  17. data/lib/generators/admin_panel/install/templates/controllers/concerns/administrable.rb +9 -0
  18. data/lib/generators/admin_panel/install/templates/helpers/admin_helper.rb +19 -0
  19. data/lib/generators/admin_panel/install/templates/layouts/admin/_messages.html.erb +8 -0
  20. data/lib/generators/admin_panel/install/templates/layouts/admin/_navigation.html.erb +20 -0
  21. data/lib/generators/admin_panel/install/templates/layouts/admin/application.html.erb +22 -0
  22. data/lib/generators/admin_panel/install/templates/views/admin/dashboard/index.html.erb +1 -0
  23. data/lib/generators/admin_panel/install/templates/views/admin/passwords/edit.html.erb +17 -0
  24. data/lib/generators/admin_panel/install/templates/views/admin/passwords/new.html.erb +15 -0
  25. data/lib/generators/admin_panel/install/templates/views/admin/sessions/new.html.erb +17 -0
  26. data/lib/generators/admin_panel/scaffold/scaffold_generator.rb +168 -0
  27. data/lib/generators/admin_panel/scaffold/templates/controllers/controller.rb.erb +69 -0
  28. data/lib/generators/admin_panel/scaffold/templates/tests/test_unit/functional_test.rb.erb +51 -0
  29. data/lib/generators/admin_panel/scaffold/templates/views/erb/_form.html.erb.erb +13 -0
  30. data/lib/generators/admin_panel/scaffold/templates/views/erb/edit.html.erb.erb +12 -0
  31. data/lib/generators/admin_panel/scaffold/templates/views/erb/index.html.erb.erb +37 -0
  32. data/lib/generators/admin_panel/scaffold/templates/views/erb/new.html.erb.erb +14 -0
  33. data/lib/generators/admin_panel/scaffold/templates/views/erb/show.html.erb.erb +22 -0
  34. data/spec/dummy/Rakefile +7 -0
  35. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  36. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  37. data/spec/dummy/bin/rails +11 -0
  38. data/spec/dummy/config.ru +4 -0
  39. data/spec/dummy/config/application.rb +68 -0
  40. data/spec/dummy/config/boot.rb +6 -0
  41. data/spec/dummy/config/environment.rb +5 -0
  42. data/spec/dummy/config/environments/test.rb +39 -0
  43. data/spec/dummy/config/routes.rb +3 -0
  44. data/spec/dummy/db/seeds.rb +0 -0
  45. data/spec/generators/admin_panel/install/install_generator_spec.rb +79 -0
  46. data/spec/generators/admin_panel/scaffold/scaffold_generator_spec.rb +31 -0
  47. data/spec/spec_helper.rb +17 -0
  48. metadata +232 -0
@@ -0,0 +1,17 @@
1
+ <h2>Change your password</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <%= f.input :reset_password_token, as: :hidden %>
7
+ <%= f.full_error :reset_password_token %>
8
+
9
+ <div class="form-inputs">
10
+ <%= f.input :password, label: "New password", required: true, autofocus: true %>
11
+ <%= f.input :password_confirmation, label: "Confirm your new password", required: true %>
12
+ </div>
13
+
14
+ <div class="form-actions">
15
+ <%= f.button :submit, "Change my password" %>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <h2>Forgot your password?</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="form-inputs">
7
+ <%= f.input :email, required: true, autofocus: true %>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%= f.button :submit, "Send me reset password instructions" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,17 @@
1
+ <h2>Sign in</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
4
+ <div class="form-inputs">
5
+ <%= f.input :email, required: false, autofocus: true %>
6
+ <%= f.input :password, required: false %>
7
+ <%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%= f.button :submit, "Sign in" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%- if devise_mapping.recoverable? %>
16
+ <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
17
+ <% end -%>
@@ -0,0 +1,168 @@
1
+ require 'rubygems/specification'
2
+ require 'rails/generators/named_base'
3
+ require 'rails/generators/resource_helpers'
4
+
5
+ module AdminPanel
6
+ module Generators
7
+ class ScaffoldGenerator < Rails::Generators::NamedBase
8
+ include Rails::Generators::ResourceHelpers
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ class_option :template_engine, desc: 'Template engine to be invoked (erb or haml).'
13
+
14
+ check_class_collision suffix: "Controller"
15
+ check_class_collision suffix: "ControllerTest"
16
+ check_class_collision suffix: "Helper"
17
+
18
+ class_option :orm, banner: "NAME", type: :string, required: true,
19
+ desc: "ORM to generate the controller for"
20
+
21
+ class_option :parent_controller, banner: "admin", type: :string, default: "application",
22
+ desc: "Define the parent controller"
23
+
24
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
25
+
26
+ def initialize(args, *options) #:nodoc:
27
+ super
28
+ end
29
+
30
+ hook_for :resource_route, in: :rails do |resource_route|
31
+ invoke resource_route, [prefixed_class_name]
32
+ end
33
+
34
+ def create_model
35
+ # There is no sane way of converting Rails::Generators::GeneratedAttribute back to string
36
+ attributes_string = attributes.map do |attr|
37
+ index = (attr.instance_variable_get("@has_uniq_index") && ':uniq') ||
38
+ (attr.instance_variable_get("@has_index") && ':index') ||
39
+ ''
40
+ "#{attr.name}:#{attr.type}#{index}"
41
+ end
42
+ generate 'model', class_name, *attributes_string
43
+ end
44
+
45
+ def create_controller_files
46
+ template "controllers/controller.rb.erb", File.join('app/controllers', prefix, class_path, "#{controller_file_name}_controller.rb")
47
+ end
48
+
49
+ def create_test_files
50
+ template "tests/test_unit/functional_test.rb.erb", File.join("test/controllers", prefix, controller_class_path, "#{controller_file_name}_controller_test.rb")
51
+ end
52
+
53
+ hook_for :helper, in: :rails do |helper|
54
+ invoke helper, [prefixed_controller_class_name]
55
+ end
56
+
57
+ def create_root_folder
58
+ empty_directory File.join("app/views", prefix, controller_file_path)
59
+ end
60
+
61
+ def copy_view_files
62
+ available_views.each do |view|
63
+ filename = filename_with_extensions(view)
64
+ template "views/#{handler}/#{filename}.erb", File.join("app/views", prefix, controller_file_path, filename)
65
+ end
66
+ end
67
+
68
+ hook_for :assets, in: :rails do |assets|
69
+ invoke assets, [prefixed_class_name]
70
+ end
71
+
72
+ protected
73
+
74
+ def prefix
75
+ 'admin'
76
+ end
77
+
78
+ def prefixed_class_name
79
+ "#{prefix.capitalize}::#{class_name}"
80
+ end
81
+
82
+ def prefixed_controller_class_name
83
+ "#{prefix.capitalize}::#{controller_class_name}"
84
+ end
85
+
86
+ def parent_controller_class_name
87
+ options[:parent_controller].capitalize
88
+ end
89
+
90
+ def prefixed_route_url
91
+ "/#{prefix}#{route_url}"
92
+ end
93
+
94
+ def prefixed_plain_model_url
95
+ "#{prefix}_#{singular_table_name}"
96
+ end
97
+
98
+ def prefixed_index_helper
99
+ "#{prefix}_#{index_helper}"
100
+ end
101
+
102
+ def available_views
103
+ %w(index edit show new _form)
104
+ end
105
+
106
+ def format
107
+ :html
108
+ end
109
+
110
+ def handler
111
+ options[:template_engine]
112
+ end
113
+
114
+ def filename_with_extensions(name)
115
+ [name, format, handler].compact.join(".")
116
+ end
117
+
118
+ # Add a class collisions name to be checked on class initialization. You
119
+ # can supply a hash with a :prefix or :suffix to be tested.
120
+ #
121
+ # ==== Examples
122
+ #
123
+ # check_class_collision suffix: "Decorator"
124
+ #
125
+ # If the generator is invoked with class name Admin, it will check for
126
+ # the presence of "AdminDecorator".
127
+ #
128
+ def self.check_class_collision(options={})
129
+ define_method :check_class_collision do
130
+ name = if self.respond_to?(:prefixed_controller_class_name) # for ScaffoldBase
131
+ prefixed_controller_class_name
132
+ elsif self.respond_to?(:prefixed_controller_class_name) # for ScaffoldBase
133
+ controller_class_name
134
+ else
135
+ class_name
136
+ end
137
+
138
+ class_collisions "#{options[:prefix]}#{name}#{options[:suffix]}"
139
+ end
140
+ end
141
+
142
+ def attributes_hash
143
+ return if attributes_names.empty?
144
+
145
+ attributes_names.map do |name|
146
+ if %w(password password_confirmation).include?(name) && attributes.any?(&:password_digest?)
147
+ "#{name}: 'secret'"
148
+ else
149
+ "#{name}: @#{singular_table_name}.#{name}"
150
+ end
151
+ end.sort.join(', ')
152
+ end
153
+
154
+ def attributes_list_with_timestamps
155
+ attributes_list(attributes_names + %w(created_at updated_at))
156
+ end
157
+
158
+ def attributes_list(attributes = attributes_names)
159
+ if self.attributes.any? { |attr| attr.name == 'password' && attr.type == :digest }
160
+ attributes = attributes.reject { |name| %w(password password_confirmation).include? name }
161
+ end
162
+
163
+ attributes.map { |a| ":#{a}" } * ', '
164
+ end
165
+
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,69 @@
1
+ <% if namespaced? -%>
2
+ require_dependency "<%= namespaced_file_path %>/application_controller"
3
+
4
+ <% end -%>
5
+ <% module_namespacing do -%>
6
+ class <%= prefixed_controller_class_name %>Controller < <%= parent_controller_class_name %>Controller
7
+ include Administrable
8
+ before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy]
9
+
10
+ # GET <%= prefixed_route_url %>
11
+ def index
12
+ @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
13
+ end
14
+
15
+ # GET <%= prefixed_route_url %>/1
16
+ def show
17
+ end
18
+
19
+ # GET <%= prefixed_route_url %>/new
20
+ def new
21
+ @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
22
+ end
23
+
24
+ # GET <%= prefixed_route_url %>/1/edit
25
+ def edit
26
+ end
27
+
28
+ # POST <%= prefixed_route_url %>
29
+ def create
30
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
31
+
32
+ if @<%= orm_instance.save %>
33
+ redirect_to <%= "[:#{prefix}, @#{singular_table_name}]" %>, notice: <%= "'#{human_name} was successfully created.'" %>
34
+ else
35
+ render action: 'new'
36
+ end
37
+ end
38
+
39
+ # PATCH/PUT <%= prefixed_route_url %>/1
40
+ def update
41
+ if @<%= orm_instance.update("#{singular_table_name}_params") %>
42
+ redirect_to <%= "[:#{prefix}, @#{singular_table_name}]" %>, notice: <%= "'#{human_name} was successfully updated.'" %>
43
+ else
44
+ render action: 'edit'
45
+ end
46
+ end
47
+
48
+ # DELETE <%= prefixed_route_url %>/1
49
+ def destroy
50
+ @<%= orm_instance.destroy %>
51
+ redirect_to <%= prefixed_index_helper %>_url, notice: <%= "'#{human_name} was successfully destroyed.'" %>
52
+ end
53
+
54
+ private
55
+ # Use callbacks to share common setup or constraints between actions.
56
+ def set_<%= singular_table_name %>
57
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
58
+ end
59
+
60
+ # Only allow a trusted parameter "white list" through.
61
+ def <%= "#{singular_table_name}_params" %>
62
+ <%- if attributes_names.empty? -%>
63
+ params[<%= ":#{singular_table_name}" %>]
64
+ <%- else -%>
65
+ params.require(<%= ":#{singular_table_name}" %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
66
+ <%- end -%>
67
+ end
68
+ end
69
+ <% end -%>
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= prefixed_controller_class_name %>ControllerTest < ActionController::TestCase
5
+ setup do
6
+ @<%= singular_table_name %> = <%= table_name %>(:one)
7
+ end
8
+
9
+ test "should get index" do
10
+ get :index
11
+ assert_response :success
12
+ assert_not_nil assigns(:<%= table_name %>)
13
+ end
14
+
15
+ test "should get new" do
16
+ get :new
17
+ assert_response :success
18
+ end
19
+
20
+ test "should create <%= singular_table_name %>" do
21
+ assert_difference('<%= class_name %>.count') do
22
+ post :create, <%= "#{singular_table_name}: { #{attributes_hash} }" %>
23
+ end
24
+
25
+ assert_redirected_to <%= prefixed_plain_model_url %>_path(assigns(:<%= singular_table_name %>))
26
+ end
27
+
28
+ test "should show <%= singular_table_name %>" do
29
+ get :show, id: <%= "@#{singular_table_name}" %>
30
+ assert_response :success
31
+ end
32
+
33
+ test "should get edit" do
34
+ get :edit, id: <%= "@#{singular_table_name}" %>
35
+ assert_response :success
36
+ end
37
+
38
+ test "should update <%= singular_table_name %>" do
39
+ patch :update, id: <%= "@#{singular_table_name}" %>, <%= "#{singular_table_name}: { #{attributes_hash} }" %>
40
+ assert_redirected_to <%= prefixed_plain_model_url %>_path(assigns(:<%= singular_table_name %>))
41
+ end
42
+
43
+ test "should destroy <%= singular_table_name %>" do
44
+ assert_difference('<%= class_name %>.count', -1) do
45
+ delete :destroy, id: <%= "@#{singular_table_name}" %>
46
+ end
47
+
48
+ assert_redirected_to <%= prefixed_index_helper %>_path
49
+ end
50
+ end
51
+ <% end -%>
@@ -0,0 +1,13 @@
1
+ <%%= simple_form_for(<%= "[:#{prefix}, @#{singular_table_name}]" %>) do |f| %>
2
+ <%%= f.error_notification %>
3
+
4
+ <div class="form-inputs">
5
+ <%- attributes.each do |attribute| -%>
6
+ <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
7
+ <%- end -%>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%%= f.button :submit %>
12
+ </div>
13
+ <%% end %>
@@ -0,0 +1,12 @@
1
+ <div class="page-header">
2
+ <div class="row">
3
+ <div class="col-md-8">
4
+ <h2>Editing <%= singular_table_name %></h2>
5
+ </div>
6
+ <div class="col-md-4 text-right">
7
+ <%%= link_to 'Back', <%= prefixed_index_helper %>_path, class: 'btn btn-default' %>
8
+ </div>
9
+ </div>
10
+ </div>
11
+
12
+ <%%= render 'form' %>
@@ -0,0 +1,37 @@
1
+ <div class="page-header">
2
+ <div class="row">
3
+ <div class="col-md-8">
4
+ <h2>Listing <%= plural_table_name %></h2>
5
+ </div>
6
+ <div class="col-md-4 text-right">
7
+ <%%= link_to 'New <%= human_name %>', new_<%= prefixed_plain_model_url %>_path, class: 'btn btn-success'%>
8
+ </div>
9
+ </div>
10
+ </div>
11
+
12
+ <table class="table table-striped">
13
+ <thead>
14
+ <tr>
15
+ <% attributes.reject(&:password_digest?).each do |attribute| -%>
16
+ <th><%= attribute.human_name %></th>
17
+ <% end -%>
18
+ <th class="text-right">Actions</th>
19
+ </tr>
20
+ </thead>
21
+
22
+ <tbody>
23
+ <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
24
+ <tr>
25
+ <% attributes.reject(&:password_digest?).each do |attribute| -%>
26
+ <td><%%= link_to <%= singular_table_name %>.<%= attribute.name %>, <%= "[:#{prefix}, #{singular_table_name}]" %> %></td>
27
+ <% end -%>
28
+ <td class="text-right">
29
+ <%%= link_to 'Show', <%= "[:#{prefix}, #{singular_table_name}]" %>, class: 'btn btn-default' %>
30
+ <%%= link_to 'Edit', edit_<%= prefixed_plain_model_url %>_path(<%= singular_table_name %>), class: 'btn btn-primary' %>
31
+ <%%= link_to 'Destroy', <%= "[:#{prefix}, #{singular_table_name}]" %>, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' %>
32
+ </td>
33
+ </tr>
34
+ <%% end %>
35
+ </tbody>
36
+ </table>
37
+
@@ -0,0 +1,14 @@
1
+ <div class="page-header">
2
+ <div class="row">
3
+ <div class="col-md-8">
4
+ <h2>New <%= singular_table_name %></h2>
5
+ </div>
6
+ <div class="col-md-4 text-right">
7
+ <%%= link_to 'Back', <%= prefixed_index_helper %>_path, class: 'btn btn-default' %>
8
+ </div>
9
+ </div>
10
+ </div>
11
+
12
+
13
+ <%%= render 'form' %>
14
+
@@ -0,0 +1,22 @@
1
+ <p id="notice"><%%= notice %></p>
2
+
3
+ <table class="table table-striped">
4
+ <tbody>
5
+ <% attributes.reject(&:password_digest?).each do |attribute| -%>
6
+ <tr>
7
+ <td><strong><%= attribute.human_name %>:</strong></td>
8
+ <td><%%= @<%= singular_table_name %>.<%= attribute.name %> %></td>
9
+ </tr>
10
+ <% end -%>
11
+ </tbody>
12
+ </table>
13
+
14
+ <div class="row">
15
+ <div class="col-md-6">
16
+ <%%= link_to 'Back', <%= prefixed_index_helper %>_path, class: 'btn btn-default' %>
17
+ </div
18
+ <div class="col-md-6 text-right">
19
+ <%%= link_to 'Edit', edit_<%= prefixed_plain_model_url %>_path(@<%= singular_table_name %>), class: 'btn btn-primary' %>
20
+ <%%= link_to 'Destroy', <%= "[:#{prefix}, @#{singular_table_name}]" %>, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' %>
21
+ </div>
22
+ </div>