madmin 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 (96) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +102 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/config/madmin_manifest.js +2 -0
  6. data/app/assets/javascripts/madmin/application.js +15 -0
  7. data/app/assets/javascripts/madmin/dashboard.js +2 -0
  8. data/app/assets/javascripts/madmin/resources.js +36 -0
  9. data/app/assets/stylesheets/madmin/application.css +22 -0
  10. data/app/assets/stylesheets/madmin/dashboard.css +4 -0
  11. data/app/assets/stylesheets/madmin/resources.css +4 -0
  12. data/app/controllers/madmin/application_controller.rb +16 -0
  13. data/app/controllers/madmin/base_controller.rb +16 -0
  14. data/app/controllers/madmin/dashboard_controller.rb +8 -0
  15. data/app/controllers/madmin/resources_controller.rb +97 -0
  16. data/app/decorators/madmin/resource_decorator.rb +16 -0
  17. data/app/helpers/madmin/application_helper.rb +15 -0
  18. data/app/helpers/madmin/fields/polymorphic_helper.rb +25 -0
  19. data/app/jobs/madmin/application_job.rb +4 -0
  20. data/app/mailers/madmin/application_mailer.rb +6 -0
  21. data/app/models/madmin/application_record.rb +5 -0
  22. data/app/views/application/_navigation.html.erb +17 -0
  23. data/app/views/layouts/madmin/application.html.erb +30 -0
  24. data/app/views/madmin/dashboard/index.html.erb +6 -0
  25. data/app/views/madmin/fields/belongs_to/_form.html.erb +14 -0
  26. data/app/views/madmin/fields/belongs_to/_index.html.erb +7 -0
  27. data/app/views/madmin/fields/belongs_to/_show.html.erb +8 -0
  28. data/app/views/madmin/fields/check_box/_form.html.erb +4 -0
  29. data/app/views/madmin/fields/check_box/_index.html.erb +1 -0
  30. data/app/views/madmin/fields/check_box/_show.html.erb +8 -0
  31. data/app/views/madmin/fields/email/_form.html.erb +4 -0
  32. data/app/views/madmin/fields/email/_index.html.erb +1 -0
  33. data/app/views/madmin/fields/email/_show.html.erb +8 -0
  34. data/app/views/madmin/fields/has_many/_form.html.erb +0 -0
  35. data/app/views/madmin/fields/has_many/_show.html.erb +15 -0
  36. data/app/views/madmin/fields/has_one/_form.html.erb +0 -0
  37. data/app/views/madmin/fields/has_one/_show.html.erb +12 -0
  38. data/app/views/madmin/fields/number/_form.html.erb +4 -0
  39. data/app/views/madmin/fields/number/_index.html.erb +1 -0
  40. data/app/views/madmin/fields/number/_show.html.erb +8 -0
  41. data/app/views/madmin/fields/password/_form.html.erb +4 -0
  42. data/app/views/madmin/fields/password/_index.html.erb +1 -0
  43. data/app/views/madmin/fields/password/_show.html.erb +8 -0
  44. data/app/views/madmin/fields/polymorphic/_form.html.erb +32 -0
  45. data/app/views/madmin/fields/polymorphic/_index.html.erb +1 -0
  46. data/app/views/madmin/fields/polymorphic/_show.html.erb +14 -0
  47. data/app/views/madmin/fields/select/_form.html.erb +4 -0
  48. data/app/views/madmin/fields/select/_index.html.erb +1 -0
  49. data/app/views/madmin/fields/select/_show.html.erb +8 -0
  50. data/app/views/madmin/fields/text/_form.html.erb +4 -0
  51. data/app/views/madmin/fields/text/_index.html.erb +1 -0
  52. data/app/views/madmin/fields/text/_show.html.erb +8 -0
  53. data/app/views/madmin/fields/text_area/_form.html.erb +4 -0
  54. data/app/views/madmin/fields/text_area/_index.html.erb +1 -0
  55. data/app/views/madmin/fields/text_area/_show.html.erb +8 -0
  56. data/app/views/madmin/resources/_form.html.erb +15 -0
  57. data/app/views/madmin/resources/_scopes.html.erb +10 -0
  58. data/app/views/madmin/resources/edit.html.erb +2 -0
  59. data/app/views/madmin/resources/index.html.erb +13 -0
  60. data/app/views/madmin/resources/index/_content.html.erb +33 -0
  61. data/app/views/madmin/resources/new.html.erb +2 -0
  62. data/app/views/madmin/resources/show.html.erb +10 -0
  63. data/config/routes.rb +11 -0
  64. data/lib/generators/madmin/controller/USAGE +8 -0
  65. data/lib/generators/madmin/controller/controller_generator.rb +10 -0
  66. data/lib/generators/madmin/install/install_generator.rb +31 -0
  67. data/lib/generators/madmin/page/USAGE +8 -0
  68. data/lib/generators/madmin/page/page_generator.rb +20 -0
  69. data/lib/generators/madmin/page/templates/template.html.erb +2 -0
  70. data/lib/generators/madmin/page/templates/template.rb.erb +10 -0
  71. data/lib/generators/madmin/resource/resource_generator.rb +76 -0
  72. data/lib/generators/madmin/resource/templates/resource.rb.erb +11 -0
  73. data/lib/generators/madmin/views/views_generator.rb +15 -0
  74. data/lib/madmin.rb +30 -0
  75. data/lib/madmin/engine.rb +9 -0
  76. data/lib/madmin/field.rb +64 -0
  77. data/lib/madmin/field/associatable.rb +58 -0
  78. data/lib/madmin/field/belongs_to.rb +9 -0
  79. data/lib/madmin/field/check_box.rb +8 -0
  80. data/lib/madmin/field/date_time.rb +8 -0
  81. data/lib/madmin/field/email.rb +8 -0
  82. data/lib/madmin/field/has_many.rb +9 -0
  83. data/lib/madmin/field/has_one.rb +9 -0
  84. data/lib/madmin/field/number.rb +8 -0
  85. data/lib/madmin/field/password.rb +8 -0
  86. data/lib/madmin/field/polymorphic.rb +57 -0
  87. data/lib/madmin/field/select.rb +13 -0
  88. data/lib/madmin/field/text.rb +8 -0
  89. data/lib/madmin/field/text_area.rb +8 -0
  90. data/lib/madmin/generator_helpers.rb +13 -0
  91. data/lib/madmin/resourceable.rb +72 -0
  92. data/lib/madmin/resourceable/class_methods.rb +152 -0
  93. data/lib/madmin/resources.rb +13 -0
  94. data/lib/madmin/version.rb +3 -0
  95. data/lib/tasks/madmin_tasks.rake +4 -0
  96. metadata +197 -0
@@ -0,0 +1,4 @@
1
+ module Madmin
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Madmin
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ <nav class="nav bg-dark col-md-2 sidebar px-4 py-3 d-flex flex-column">
2
+ <h3><%= link_to 'Madmin', root_path %></h3>
3
+
4
+ <ul class="list-unstyled mt-3">
5
+ <% available_resources.each do |resource| %>
6
+ <% next unless resource.show_in_menu? %>
7
+ <li class="mb-1">
8
+ <%= link_to resource.friendly_name.pluralize, resources_path(resource.slug), class: "text-white" %>
9
+ </li>
10
+ <% end %>
11
+ <% pages.each do |page| %>
12
+ <li class="mb-1">
13
+ <%= link_to page, "#", class: "text-white"%>
14
+ </li>
15
+ <% end %>
16
+ </ul>
17
+ </nav>
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Madmin</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
9
+
10
+ <%= stylesheet_link_tag "madmin/application", media: "all" %>
11
+ </head>
12
+ <body>
13
+ <div class="container-fluid">
14
+ <div class="row">
15
+ <%= render 'application/navigation' %>
16
+ <div class="col-10 ml-sm-auto mt-4">
17
+ <div class="container">
18
+ <%= yield %>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </div>
23
+
24
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
25
+ <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
26
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
27
+ <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
28
+ <%= javascript_include_tag "madmin/application" %>
29
+ </body>
30
+ </html>
@@ -0,0 +1,6 @@
1
+ <h1>Administration</h1>
2
+ <% available_resources.each do |type| %>
3
+ <li>
4
+ <%= link_to type.friendly_name.pluralize, resources_path(type.slug) %>
5
+ </li>
6
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <div class="form-group">
2
+ <%= form.label field.key %>
3
+ <%=
4
+ form.select field.association_foreign_key,
5
+ options_from_collection_for_select(
6
+ field.association_collection,
7
+ :id,
8
+ field.association_display_value,
9
+ field.association_id_or_blank_for(resource)
10
+ ),
11
+ { include_blank: true },
12
+ class: 'form-control'
13
+ %>
14
+ </div>
@@ -0,0 +1,7 @@
1
+ <%=
2
+ link_to field.association_value_for(resource),
3
+ resource_path(
4
+ field.association_slug,
5
+ field.association_id_for(resource)
6
+ )
7
+ %>
@@ -0,0 +1,8 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%= field.association_value_for(resource) %>
7
+ </div>
8
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="form-group form-check">
2
+ <%= form.check_box field.key, class: "form-check-input" %>
3
+ <%= form.label field.key, field.label, class: "form-check-label" %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= field.value_for(resource) %>
@@ -0,0 +1,8 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%= field.value_for(resource) %>
7
+ </div>
8
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="form-group">
2
+ <%= form.label field.key, field.label %>
3
+ <%= form.email_field field.key, class: "form-control" %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= field.value_for(resource) %>
@@ -0,0 +1,8 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%= field.value_for(resource) %>
7
+ </div>
8
+ </div>
@@ -0,0 +1,15 @@
1
+ <div class="mt-3">
2
+ <div class="row">
3
+ <div class="col">
4
+ <h3><%= field.label %></h3>
5
+ <%= link_to "Add", new_resource_path(field.association_slug, field.association_param => { field.association_foreign_key => resource.id }) %>
6
+ <%=
7
+ render "madmin/resources/index/content",
8
+ headers: [],
9
+ collection: field.value_for(resource),
10
+ madmin_resource: madmin_resource_for(model: field.association_class),
11
+ show_new_button: false
12
+ %>
13
+ </div>
14
+ </div>
15
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="mt-3">
2
+ <div class="row">
3
+ <div class="col">
4
+ <h3><%= field.name %></h3>
5
+ <% if !field.value %>
6
+ <%= link_to "Add", new_resource_path(madmin_resource_for(model: field.foreign_class).slug, ActiveModel::Naming.param_key(field.foreign_class) => { field.foreign_key => field.resource.id }) %>
7
+ <% else %>
8
+ <%= render "madmin/resources/index/content", headers: [], collection: [Madmin::ResourceDecorator.new(field.value)], show_new_button: false %>
9
+ <% end %>
10
+ </div>
11
+ </div>
12
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="form-group">
2
+ <%= form.label field.key, field.label %>
3
+ <%= form.number_field field.key, class: "form-control" %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= link_to field.value_for(resource), resource_path(madmin_resource.slug, id: resource.id) %>
@@ -0,0 +1,8 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%= field.value_for(resource) %>
7
+ </div>
8
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="form-group">
2
+ <%= form.label field.key, field.label %>
3
+ <%= form.password_field field.key, class: "form-control", autocomplete: false %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= 'Password Encrypted' if field.value %>
@@ -0,0 +1,8 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%= 'Password Encrypted' if field.value_for(resource).present? %>
7
+ </div>
8
+ </div>
@@ -0,0 +1,32 @@
1
+ <div class="form-group">
2
+ <%= form.label field.key %>
3
+ <%=
4
+ form.select field.polymorphic_type_param,
5
+ polymorphic_models(field.key).map { |m| [m.name, m.name, { "data-slug" => madmin_resource_for(model: m).slug }] },
6
+ { include_blank: true },
7
+ id: field.polymorphic_type_param,
8
+ class: "form-control"
9
+ %>
10
+ <% if field.polymorphic_relationship_exists?(form.object) %>
11
+ <%=
12
+ form.select field.polymorphic_id_param,
13
+ polymorphic_options_for_selected_type(form: form, field: field),
14
+ {},
15
+ id: field.polymorphic_id_param,
16
+ class: "form-control"
17
+ %>
18
+ <% else %>
19
+ <%=
20
+ form.select field.polymorphic_id_param,
21
+ [],
22
+ {},
23
+ id: field.polymorphic_id_param,
24
+ class: "d-none form-control"
25
+ %>
26
+ <% end %>
27
+ </div>
28
+
29
+ <script>
30
+ window.polymorphicFields = window.polymorphicFields || [];
31
+ window.polymorphicFields.push('<%= field.key %>')
32
+ </script>
@@ -0,0 +1 @@
1
+ <%= link_to field.polymorphic_value_for(resource), resource_path(field.polymorphic_slug_for(resource), field.polymorphic_id_for(resource)) %>
@@ -0,0 +1,14 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%=
7
+ link_to field.polymorphic_value_for(resource),
8
+ resource_path(
9
+ field.polymorphic_slug_for(resource),
10
+ field.polymorphic_id_for(resource)
11
+ )
12
+ %>
13
+ </div>
14
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="form-group">
2
+ <%= form.label field.key, field.label %>
3
+ <%= form.select field.key, field.select_options, {}, class: "form-control" %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= field.value %>
@@ -0,0 +1,8 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%= field.value_for(resource) %>
7
+ </div>
8
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="form-group">
2
+ <%= form.label field.key, field.label %>
3
+ <%= form.text_field field.key, class: "form-control" %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= field.value_for(resource) %>
@@ -0,0 +1,8 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%= field.value_for(resource) %>
7
+ </div>
8
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="form-group">
2
+ <%= form.label field.key, field.label %>
3
+ <%= form.text_area field.key, class: "form-control" %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= field.value %>
@@ -0,0 +1,8 @@
1
+ <div class="row">
2
+ <div class="col-3">
3
+ <%= field.label %>
4
+ </div>
5
+ <div class="col-9">
6
+ <%= field.value_for(resource) %>
7
+ </div>
8
+ </div>
@@ -0,0 +1,15 @@
1
+ <%= form_for resource, url: url do |form| %>
2
+ <% if resource.errors.any? %>
3
+ <% resource.errors.full_messages.each do |message| %>
4
+ <li><%= message %></li>
5
+ <% end %>
6
+ <% end %>
7
+
8
+ <% madmin_resource.form_fields.each do |field| %>
9
+ <%= render "#{field.to_partial_path}/form", field: field, form: form, resource: resource %>
10
+ <% end %>
11
+
12
+ <div class="mt-4">
13
+ <%= form.submit class: "btn btn-primary" %>
14
+ </div>
15
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <div class="list-group">
2
+ <%= link_to resources_path(madmin_resource.slug), class: "list-group-item py-2 list-group-item-action #{'active' if params[:scope].blank?}" do %>
3
+ All
4
+ <% end %>
5
+ <% scopes.each do |scope| %>
6
+ <%= link_to resources_path(madmin_resource.slug, scope: scope.to_s), class: "list-group-item py-2 list-group-item-action #{'active' if params[:scope] == scope.to_s}" do %>
7
+ <%= scope.to_s.titleize %>
8
+ <% end %>
9
+ <% end %>
10
+ </div>
@@ -0,0 +1,2 @@
1
+ <h1><%= @resource.name %> <%= @resource.id %></h1>
2
+ <%= render 'form', resource: @resource, url: resource_path %>
@@ -0,0 +1,13 @@
1
+ <div class="row">
2
+ <div class="col">
3
+ <h1><%= madmin_resource.friendly_name.pluralize %></h1>
4
+ </div>
5
+ </div>
6
+ <div class="row">
7
+ <%= content_tag :div, class: @scopes.any? ? 'col-3' : 'd-none' do %>
8
+ <%= render 'scopes', scopes: @scopes %>
9
+ <% end %>
10
+ <%= content_tag :div, class: @scopes.any? ? 'col-9' : 'col-12' do %>
11
+ <%= render 'madmin/resources/index/content', headers: @headers, collection: @collection, show_new_button: true %>
12
+ <% end %>
13
+ </div>
@@ -0,0 +1,33 @@
1
+ <table class="table">
2
+ <thead>
3
+ <% headers.each do |header| %>
4
+ <th><%= header %></th>
5
+ <% end %>
6
+ </thead>
7
+ <% if collection.any? %>
8
+ <% collection.each do |resource| %>
9
+ <tr>
10
+ <% madmin_resource.index_fields.each do |field| %>
11
+ <td>
12
+ <%=
13
+ render "#{field.to_partial_path}/index",
14
+ field: field,
15
+ madmin_resource: madmin_resource,
16
+ resource: resource
17
+ %>
18
+ </td>
19
+ <% end %>
20
+ </tr>
21
+ <% end %>
22
+ <% else %>
23
+ <tr>
24
+ <td>No records found</td>
25
+ </tr>
26
+ <% end %>
27
+ </table>
28
+
29
+ <% if show_new_button %>
30
+ <div class="mt-4">
31
+ <%= link_to 'New', new_resource_path, class: "btn btn-primary" %>
32
+ </div>
33
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <h1>New <%= @resource.name %></h1>
2
+ <%= render 'form', resource: @resource, url: resources_path %>
@@ -0,0 +1,10 @@
1
+ <h1><%= @resource.name %> <%= @resource.id %></h1>
2
+
3
+ <% madmin_resource.show_fields.each do |field| %>
4
+ <%= render "#{field.to_partial_path}/show", field: field, resource: @resource %>
5
+ <% end %>
6
+
7
+ <div class="mt-4">
8
+ <%= link_to 'Edit', edit_resource_path(id: @resource.id), class: "btn btn-primary" %>
9
+ <%= link_to 'Delete', resource_path(id: @resource.id), method: :delete, class: "btn btn-danger" %>
10
+ </div>
@@ -0,0 +1,11 @@
1
+ Madmin::Engine.routes.draw do
2
+ root to: "dashboard#index"
3
+
4
+ get "/:resource", to: "resources#index", as: :resources
5
+ get "/:resource/new", to: "resources#new", as: :new_resource
6
+ post "/:resource", to: "resources#create"
7
+ get "/:resource/:id", to: "resources#show", as: :resource
8
+ get "/:resource/:id/edit", to: "resources#edit", as: :edit_resource
9
+ patch "/:resource/:id", to: "resources#update"
10
+ delete "/:resource/:id", to: "resources#destroy"
11
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Override certain Madmin controllers for fine-tuning
3
+
4
+ Example:
5
+ rails generate madmin:controller Application
6
+
7
+ This will create:
8
+ app/controllers/madmin/application_controller.rb