admin-panel 0.1.0

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.
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>