madmin 1.0.0.beta2 → 1.2.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.
- checksums.yaml +4 -4
- data/README.md +48 -1
- data/app/controllers/madmin/resource_controller.rb +4 -2
- data/app/helpers/madmin/sort_helper.rb +31 -0
- data/app/views/madmin/application/_javascript.html.erb +40 -5
- data/app/views/madmin/application/index.html.erb +1 -1
- data/app/views/madmin/fields/belongs_to/_index.html.erb +3 -2
- data/app/views/madmin/fields/belongs_to/_show.html.erb +3 -2
- data/app/views/madmin/fields/enum/_form.html.erb +1 -2
- data/app/views/madmin/fields/nested_has_many/_fields.html.erb +18 -0
- data/app/views/madmin/fields/nested_has_many/_form.html.erb +30 -0
- data/app/views/madmin/fields/nested_has_many/_index.html.erb +1 -0
- data/app/views/madmin/fields/nested_has_many/_show.html.erb +5 -0
- data/app/views/madmin/fields/password/_form.html.erb +2 -0
- data/app/views/madmin/fields/password/_index.html.erb +1 -0
- data/app/views/madmin/fields/password/_show.html.erb +1 -0
- data/lib/generators/madmin/resource/resource_generator.rb +14 -3
- data/lib/generators/madmin/resource/templates/resource.rb.tt +14 -0
- data/lib/generators/madmin/views/edit_generator.rb +16 -0
- data/lib/generators/madmin/views/form_generator.rb +15 -0
- data/lib/generators/madmin/views/index_generator.rb +15 -0
- data/lib/generators/madmin/views/javascript_generator.rb +15 -0
- data/lib/generators/madmin/views/layout_generator.rb +21 -0
- data/lib/generators/madmin/views/navigation_generator.rb +15 -0
- data/lib/generators/madmin/views/new_generator.rb +16 -0
- data/lib/generators/madmin/views/show_generator.rb +15 -0
- data/lib/generators/madmin/views/views_generator.rb +16 -0
- data/lib/madmin.rb +11 -9
- data/lib/madmin/fields/belongs_to.rb +3 -2
- data/lib/madmin/fields/enum.rb +3 -0
- data/lib/madmin/fields/has_many.rb +3 -2
- data/lib/madmin/fields/nested_has_many.rb +40 -0
- data/lib/madmin/fields/password.rb +6 -0
- data/lib/madmin/namespace.rb +35 -0
- data/lib/madmin/resource.rb +42 -9
- data/lib/madmin/version.rb +1 -1
- data/lib/madmin/view_generator.rb +42 -0
- metadata +25 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e868d17abd508729232e7ebeebd4b79a8e69545b853276a700c60e61e5d6348c
         | 
| 4 | 
            +
              data.tar.gz: b19043a0a2e7dd0ad6392f995b76812b434e54f73682eb163ca28e1aaeb4ad34
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: '09b7ec920a1c8ae8a1429db77cff71ca45574e379563db5a06648d5cd5434950597b99eed5b836f7834cdc5c71e9d68411f064cc78d363da848efde9a0ef1b1a'
         | 
| 7 | 
            +
              data.tar.gz: 51b2b25ddabe18e8777c9eab9e34dd1b8afd74a05aae5671f2f94c85cb404043bcde8423d996033a9dd4fa07ee672ad36240e65e195166586afabc02d756237a
         | 
    
        data/README.md
    CHANGED
    
    | @@ -7,9 +7,12 @@ | |
| 7 7 | 
             
            Why another Ruby on Rails admin? We wanted an admin that was:
         | 
| 8 8 |  | 
| 9 9 | 
             
            * Familiar and customizable like Rails scaffolds (less DSL)
         | 
| 10 | 
            -
            * Supports all the Rails features out of the box (ActionText, ActionMailbox, etc)
         | 
| 10 | 
            +
            * Supports all the Rails features out of the box (ActionText, ActionMailbox, has_secure_password, etc)
         | 
| 11 11 | 
             
            * Stimulus / Turbolinks / Hotwire ready
         | 
| 12 12 |  | 
| 13 | 
            +
            
         | 
| 14 | 
            +
            _We're still working on the design!_
         | 
| 15 | 
            +
             | 
| 13 16 | 
             
            ## Installation
         | 
| 14 17 | 
             
            Add `madmin` to your application's Gemfile:
         | 
| 15 18 |  | 
| @@ -37,6 +40,50 @@ To generate a resource for a model, you can run: | |
| 37 40 | 
             
            rails g madmin:resource ActionText::RichText
         | 
| 38 41 | 
             
            ```
         | 
| 39 42 |  | 
| 43 | 
            +
            ## Configuring Views
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            The views packaged within the gem are a great starting point, but inevitably people will need to be able to customize those views.
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            You can use the included generator to create the appropriate view files, which can then be customized.
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            For example, running the following will copy over all of the views into your application that will be used for every resource:
         | 
| 50 | 
            +
            ```bash
         | 
| 51 | 
            +
            rails generate madmin:views
         | 
| 52 | 
            +
            ```
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            The view files that are copied over in this case includes all of the standard Rails action views (index, new, edit, show, and _form), as well as:
         | 
| 55 | 
            +
            * `application.html.erb` (layout file)
         | 
| 56 | 
            +
            * `_javascript.html.erb` (default JavaScript setup)
         | 
| 57 | 
            +
            * `_navigation.html.erb` (renders the navigation/sidebar menu)
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            As with the other views, you can specifically run the views generator for only the navigation or application layout views:
         | 
| 60 | 
            +
            ```bash
         | 
| 61 | 
            +
            rails g madmin:views:navigation
         | 
| 62 | 
            +
             # -> app/views/madmin/_navigation.html.erb
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            rails g madmin:views:layout  # Note the layout generator includes the layout, javascript, and navigation files.
         | 
| 65 | 
            +
             # -> app/views/madmin/application.html.erb
         | 
| 66 | 
            +
             # -> app/views/madmin/_javascript.html.erb
         | 
| 67 | 
            +
             # -> app/views/madmin/_navigation.html.erb
         | 
| 68 | 
            +
            ```
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            If you only need to customize specific views, you can restrict which views are copied by the generator:
         | 
| 71 | 
            +
            ```bash
         | 
| 72 | 
            +
            rails g madmin:views:index
         | 
| 73 | 
            +
             # -> app/views/madmin/application/index.html.erb
         | 
| 74 | 
            +
            ```
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            You can also scope the copied view(s) to a specific Resource/Model:
         | 
| 77 | 
            +
            ```bash
         | 
| 78 | 
            +
            rails generate madmin:views:index Book
         | 
| 79 | 
            +
             # -> app/views/madmin/books/index.html.erb
         | 
| 80 | 
            +
            ```
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            ## Authentication
         | 
| 83 | 
            +
             | 
| 84 | 
            +
            You can use a couple of strategies to authenticate users who are trying to
         | 
| 85 | 
            +
            access your madmin panel: [Authentication Docs](docs/authentication.md)
         | 
| 86 | 
            +
             | 
| 40 87 | 
             
            ## 🙏 Contributing
         | 
| 41 88 |  | 
| 42 89 | 
             
            This project uses Standard for formatting Ruby code. Please make sure to run standardrb before submitting pull requests.
         | 
| @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            module Madmin
         | 
| 2 2 | 
             
              class ResourceController < ApplicationController
         | 
| 3 | 
            +
                include SortHelper
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
                before_action :set_record, except: [:index, :new, :create]
         | 
| 4 6 |  | 
| 5 7 | 
             
                def index
         | 
| @@ -41,7 +43,7 @@ module Madmin | |
| 41 43 | 
             
                private
         | 
| 42 44 |  | 
| 43 45 | 
             
                def set_record
         | 
| 44 | 
            -
                  @record = resource. | 
| 46 | 
            +
                  @record = resource.model_find(params[:id])
         | 
| 45 47 | 
             
                end
         | 
| 46 48 |  | 
| 47 49 | 
             
                def resource
         | 
| @@ -54,7 +56,7 @@ module Madmin | |
| 54 56 | 
             
                end
         | 
| 55 57 |  | 
| 56 58 | 
             
                def scoped_resources
         | 
| 57 | 
            -
                  resource.model.send(valid_scope)
         | 
| 59 | 
            +
                  resource.model.send(valid_scope).order(sort_column => sort_direction)
         | 
| 58 60 | 
             
                end
         | 
| 59 61 |  | 
| 60 62 | 
             
                def valid_scope
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            module Madmin
         | 
| 2 | 
            +
              module SortHelper
         | 
| 3 | 
            +
                def sortable(column, title, options = {})
         | 
| 4 | 
            +
                  matching_column = (column.to_s == sort_column)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  link_to request.params.merge(sort: column, direction: sort_direction), options do
         | 
| 7 | 
            +
                    concat title
         | 
| 8 | 
            +
                    if matching_column
         | 
| 9 | 
            +
                      concat " "
         | 
| 10 | 
            +
                      concat tag.i(sort_direction == "asc" ? "▲" : "▼")
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def sort_column
         | 
| 16 | 
            +
                  resource.sortable_columns.include?(params[:sort]) ? params[:sort] : default_sort_column
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def sort_direction
         | 
| 20 | 
            +
                  ["asc", "desc"].include?(params[:direction]) ? params[:direction] : default_sort_direction
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def default_sort_column
         | 
| 24 | 
            +
                  resource.try(:default_sort_column) || "created_at"
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def default_sort_direction
         | 
| 28 | 
            +
                  resource.try(:default_sort_direction) || "desc"
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| @@ -1,9 +1,9 @@ | |
| 1 | 
            -
            <%= stylesheet_link_tag "https:// | 
| 2 | 
            -
            <%= stylesheet_link_tag "https:// | 
| 3 | 
            -
            <%= stylesheet_link_tag "https:// | 
| 1 | 
            +
            <%= stylesheet_link_tag "https://unpkg.com/flatpickr/dist/flatpickr.min.css", "data-turbo-track": "reload" %>
         | 
| 2 | 
            +
            <%= stylesheet_link_tag "https://unpkg.com/trix/dist/trix.css", "data-turbo-track": "reload" %>
         | 
| 3 | 
            +
            <%= stylesheet_link_tag "https://unpkg.com/slim-select@1.27.0/dist/slimselect.min.css", "data-turbo-track": "reload" %>
         | 
| 4 4 |  | 
| 5 5 | 
             
            <script type="module">
         | 
| 6 | 
            -
              import { Application } from 'https://cdn.skypack.dev/stimulus'
         | 
| 6 | 
            +
              import { Application, Controller } from 'https://cdn.skypack.dev/stimulus'
         | 
| 7 7 | 
             
              const application = Application.start()
         | 
| 8 8 |  | 
| 9 9 | 
             
              import stimulusFlatpickr from 'https://cdn.skypack.dev/stimulus-flatpickr'
         | 
| @@ -17,8 +17,43 @@ | |
| 17 17 | 
             
              import 'https://cdn.skypack.dev/trix'
         | 
| 18 18 | 
             
              import 'https://cdn.skypack.dev/@rails/actiontext@<%= npm_rails_version %>'
         | 
| 19 19 |  | 
| 20 | 
            -
              Rails.start()
         | 
| 20 | 
            +
              if (!window._rails_loaded) { Rails.start() }
         | 
| 21 21 | 
             
              ActiveStorage.start()
         | 
| 22 22 |  | 
| 23 23 | 
             
              import * as Turbo from "https://cdn.skypack.dev/@hotwired/turbo"
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              (() => {
         | 
| 26 | 
            +
                application.register('nested-form', class extends Controller {
         | 
| 27 | 
            +
                  static get targets() {
         | 
| 28 | 
            +
                    return [ "links", "template" ]
         | 
| 29 | 
            +
                  }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  connect() {
         | 
| 32 | 
            +
                    this.wrapperClass = this.data.get("wrapperClass") || "nested-fields"
         | 
| 33 | 
            +
                  }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  add_association(event) {
         | 
| 36 | 
            +
                    event.preventDefault()
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    var content = this.templateTarget.innerHTML.replace(/NEW_RECORD/g, new Date().getTime())
         | 
| 39 | 
            +
                    this.linksTarget.insertAdjacentHTML('beforebegin', content)
         | 
| 40 | 
            +
                  }
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  remove_association(event) {
         | 
| 43 | 
            +
                    event.preventDefault()
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    let wrapper = event.target.closest("." + this.wrapperClass)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    // New records are simply removed from the page
         | 
| 48 | 
            +
                    if (wrapper.dataset.newRecord == "true") {
         | 
| 49 | 
            +
                      wrapper.remove()
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    // Existing records are hidden and flagged for deletion
         | 
| 52 | 
            +
                    } else {
         | 
| 53 | 
            +
                      wrapper.querySelector("input[name*='_destroy']").value = 1
         | 
| 54 | 
            +
                      wrapper.style.display = 'none'
         | 
| 55 | 
            +
                    }
         | 
| 56 | 
            +
                  }
         | 
| 57 | 
            +
                })
         | 
| 58 | 
            +
              })()
         | 
| 24 59 | 
             
            </script>
         | 
| @@ -20,7 +20,7 @@ | |
| 20 20 | 
             
                    <% next if attribute[:field].nil? %>
         | 
| 21 21 | 
             
                    <% next unless attribute[:field].visible?(action_name) %>
         | 
| 22 22 |  | 
| 23 | 
            -
                    <th><%= attribute[:name].to_s.titleize %></th>
         | 
| 23 | 
            +
                    <th><%= sortable attribute[:name], attribute[:name].to_s.titleize %></th>
         | 
| 24 24 | 
             
                  <% end %>
         | 
| 25 25 | 
             
                  <th>Actions</th>
         | 
| 26 26 | 
             
                </tr>
         | 
| @@ -1,2 +1,3 @@ | |
| 1 | 
            -
            <% object = field.value(record) %>
         | 
| 2 | 
            -
            <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
         | 
| 1 | 
            +
            <% if (object = field.value(record)) %>
         | 
| 2 | 
            +
              <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
         | 
| 3 | 
            +
            <% end %>
         | 
| @@ -1,2 +1,3 @@ | |
| 1 | 
            -
            <% object = field.value(record) %>
         | 
| 2 | 
            -
            <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
         | 
| 1 | 
            +
            <% if (object = field.value(record)) %>
         | 
| 2 | 
            +
              <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
         | 
| 3 | 
            +
            <% end %>
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            <%= content_tag :div, class: "nested-fields bg-gray-100 rounded-t-xl p-5", data: { new_record: f.object.new_record? } do %>
         | 
| 2 | 
            +
              <% field.nested_attributes.each do |nested_attribute| %>
         | 
| 3 | 
            +
                <% next if nested_attribute[:field].nil? %>
         | 
| 4 | 
            +
                <% next unless nested_attribute[:field].visible?(action_name) %>
         | 
| 5 | 
            +
                <% next unless nested_attribute[:field].visible?(:form) %>
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                <% nested_field = nested_attribute[:field] %>
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                <div class="mb-4 flex">
         | 
| 10 | 
            +
                  <%= render partial: nested_field.to_partial_path("form"), locals: { field: nested_field, record: f.object, form: f, resource: field.resource } %>
         | 
| 11 | 
            +
                </div>
         | 
| 12 | 
            +
              <% end %>
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              <small><%= link_to "Remove", "#", data: { action: "click->nested-form#remove_association" } %></small>
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              <%= f.hidden_field :_destroy %>
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            <% end %>
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            <div class="container space-y-8" data-controller="nested-form">
         | 
| 4 | 
            +
              <template data-target="nested-form.template">
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                <%= form.fields_for field.attribute_name, field.to_model.new, child_index: 'NEW_RECORD' do |nested_form| %>
         | 
| 7 | 
            +
                  <%= render(
         | 
| 8 | 
            +
                    partial: field.to_partial_path('fields'),
         | 
| 9 | 
            +
                    locals: {
         | 
| 10 | 
            +
                      f: nested_form,
         | 
| 11 | 
            +
                      field: field
         | 
| 12 | 
            +
                    }
         | 
| 13 | 
            +
                  ) %>
         | 
| 14 | 
            +
              <% end %>
         | 
| 15 | 
            +
              </template>
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                <%= form.fields_for field.attribute_name do |nested_form| %>
         | 
| 18 | 
            +
                  <%= render(
         | 
| 19 | 
            +
                    partial: field.to_partial_path('fields'),
         | 
| 20 | 
            +
                    locals: {
         | 
| 21 | 
            +
                      f: nested_form,
         | 
| 22 | 
            +
                      field: field
         | 
| 23 | 
            +
                    }
         | 
| 24 | 
            +
                  ) %>
         | 
| 25 | 
            +
              <% end %>
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              <%= content_tag :div, class: '', data: { target:"nested-form.links" } do %>
         | 
| 28 | 
            +
                <%= link_to "+ Add new", "#",  data: { action: "click->nested-form#add_association" } %>
         | 
| 29 | 
            +
              <% end %>
         | 
| 30 | 
            +
            </div>
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            <%= pluralize field.value(record).count, field.attribute_name.to_s %>
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            <%= field.value(record) %>
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            <%= field.value(record) %>
         | 
| @@ -46,6 +46,10 @@ module Madmin | |
| 46 46 | 
             
                  def virtual_attributes
         | 
| 47 47 | 
             
                    virtual = []
         | 
| 48 48 |  | 
| 49 | 
            +
                    # has_secure_password columns
         | 
| 50 | 
            +
                    password_attributes = model.attribute_types.keys.select { |k| k.ends_with?("_digest") }.map { |k| k.delete_suffix("_digest") }
         | 
| 51 | 
            +
                    virtual += password_attributes.map { |attr| [attr, "#{attr}_confirmation"] }.flatten
         | 
| 52 | 
            +
             | 
| 49 53 | 
             
                    # Add virtual attributes for ActionText and ActiveStorage
         | 
| 50 54 | 
             
                    model.reflections.each do |name, association|
         | 
| 51 55 | 
             
                      if name.starts_with?("rich_text")
         | 
| @@ -63,6 +67,9 @@ module Madmin | |
| 63 67 | 
             
                  def redundant_attributes
         | 
| 64 68 | 
             
                    redundant = []
         | 
| 65 69 |  | 
| 70 | 
            +
                    # has_secure_password columns
         | 
| 71 | 
            +
                    redundant += model.attribute_types.keys.select { |k| k.ends_with?("_digest") }
         | 
| 72 | 
            +
             | 
| 66 73 | 
             
                    model.reflections.each do |name, association|
         | 
| 67 74 | 
             
                      if association.has_one?
         | 
| 68 75 | 
             
                        next
         | 
| @@ -98,13 +105,17 @@ module Madmin | |
| 98 105 | 
             
                    if %w[id created_at updated_at].include?(name)
         | 
| 99 106 | 
             
                      {form: false}
         | 
| 100 107 |  | 
| 101 | 
            -
                    #  | 
| 102 | 
            -
                    elsif  | 
| 103 | 
            -
                      {index: false}
         | 
| 108 | 
            +
                    # has_secure_passwords should only show on forms
         | 
| 109 | 
            +
                    elsif name.ends_with?("_confirmation") || virtual_attributes.include?("#{name}_confirmation")
         | 
| 110 | 
            +
                      {index: false, show: false}
         | 
| 104 111 |  | 
| 105 112 | 
             
                    # Counter cache columns are typically not editable
         | 
| 106 113 | 
             
                    elsif name.ends_with?("_count")
         | 
| 107 114 | 
             
                      {form: false}
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                    # Attributes without a database column
         | 
| 117 | 
            +
                    elsif !model.column_names.include?(name)
         | 
| 118 | 
            +
                      {index: false}
         | 
| 108 119 | 
             
                    end
         | 
| 109 120 | 
             
                  end
         | 
| 110 121 | 
             
                end
         | 
| @@ -8,4 +8,18 @@ class <%= class_name %>Resource < Madmin::Resource | |
| 8 8 | 
             
            <% associations.each do |association_name| -%>
         | 
| 9 9 | 
             
              attribute :<%= association_name %>
         | 
| 10 10 | 
             
            <% end -%>
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              # Uncomment this to customize the display name of records in the admin area.
         | 
| 13 | 
            +
              # def self.display_name(record)
         | 
| 14 | 
            +
              #   record.name
         | 
| 15 | 
            +
              # end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              # Uncomment this to customize the default sort column and direction.
         | 
| 18 | 
            +
              # def self.default_sort_column
         | 
| 19 | 
            +
              #   "created_at"
         | 
| 20 | 
            +
              # end
         | 
| 21 | 
            +
              #
         | 
| 22 | 
            +
              # def self.default_sort_direction
         | 
| 23 | 
            +
              #   "desc"
         | 
| 24 | 
            +
              # end
         | 
| 11 25 | 
             
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                module Views
         | 
| 6 | 
            +
                  class EditGenerator < Madmin::ViewGenerator
         | 
| 7 | 
            +
                    source_root template_source_path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def copy_edit
         | 
| 10 | 
            +
                      copy_resource_template("edit")
         | 
| 11 | 
            +
                      copy_resource_template("_form")
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                module Views
         | 
| 6 | 
            +
                  class FormGenerator < Madmin::ViewGenerator
         | 
| 7 | 
            +
                    source_root template_source_path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def copy_form
         | 
| 10 | 
            +
                      copy_resource_template("_form")
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                module Views
         | 
| 6 | 
            +
                  class IndexGenerator < Madmin::ViewGenerator
         | 
| 7 | 
            +
                    source_root template_source_path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def copy_template
         | 
| 10 | 
            +
                      copy_resource_template("index")
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                module Views
         | 
| 6 | 
            +
                  class JavascriptGenerator < Madmin::ViewGenerator
         | 
| 7 | 
            +
                    source_root template_source_path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def copy_navigation
         | 
| 10 | 
            +
                      copy_resource_template("_javascript")
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                module Views
         | 
| 6 | 
            +
                  class LayoutGenerator < Madmin::ViewGenerator
         | 
| 7 | 
            +
                    source_root template_source_path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def copy_template
         | 
| 10 | 
            +
                      copy_file(
         | 
| 11 | 
            +
                        "../../layouts/madmin/application.html.erb",
         | 
| 12 | 
            +
                        "app/views/layouts/madmin/application.html.erb"
         | 
| 13 | 
            +
                      )
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                      call_generator("madmin:views:navigation")
         | 
| 16 | 
            +
                      copy_resource_template("_javascript")
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                module Views
         | 
| 6 | 
            +
                  class NavigationGenerator < Madmin::ViewGenerator
         | 
| 7 | 
            +
                    source_root template_source_path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def copy_navigation
         | 
| 10 | 
            +
                      copy_resource_template("_navigation")
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                module Views
         | 
| 6 | 
            +
                  class NewGenerator < Madmin::ViewGenerator
         | 
| 7 | 
            +
                    source_root template_source_path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def copy_new
         | 
| 10 | 
            +
                      copy_resource_template("new")
         | 
| 11 | 
            +
                      copy_resource_template("_form")
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                module Views
         | 
| 6 | 
            +
                  class ShowGenerator < Madmin::ViewGenerator
         | 
| 7 | 
            +
                    source_root template_source_path
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def copy_template
         | 
| 10 | 
            +
                      copy_resource_template("show")
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require "madmin/view_generator"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Madmin
         | 
| 4 | 
            +
              module Generators
         | 
| 5 | 
            +
                class ViewsGenerator < Madmin::ViewGenerator
         | 
| 6 | 
            +
                  def copy_templates
         | 
| 7 | 
            +
                    # Some generators duplicate templates, so not everything is present here
         | 
| 8 | 
            +
                    call_generator("madmin:views:edit", resource_path, "--namespace", namespace)
         | 
| 9 | 
            +
                    call_generator("madmin:views:index", resource_path, "--namespace", namespace)
         | 
| 10 | 
            +
                    call_generator("madmin:views:layout", resource_path, "--namespace", namespace)
         | 
| 11 | 
            +
                    call_generator("madmin:views:new", resource_path, "--namespace", namespace)
         | 
| 12 | 
            +
                    call_generator("madmin:views:show", resource_path, "--namespace", namespace)
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
    
        data/lib/madmin.rb
    CHANGED
    
    | @@ -8,24 +8,26 @@ module Madmin | |
| 8 8 | 
             
              autoload :Resource, "madmin/resource"
         | 
| 9 9 |  | 
| 10 10 | 
             
              module Fields
         | 
| 11 | 
            +
                autoload :Attachment, "madmin/fields/attachment"
         | 
| 12 | 
            +
                autoload :Attachments, "madmin/fields/attachments"
         | 
| 13 | 
            +
                autoload :BelongsTo, "madmin/fields/belongs_to"
         | 
| 11 14 | 
             
                autoload :Boolean, "madmin/fields/boolean"
         | 
| 12 | 
            -
                autoload :Integer, "madmin/fields/integer"
         | 
| 13 | 
            -
                autoload :String, "madmin/fields/string"
         | 
| 14 | 
            -
                autoload :Text, "madmin/fields/text"
         | 
| 15 15 | 
             
                autoload :Date, "madmin/fields/date"
         | 
| 16 16 | 
             
                autoload :DateTime, "madmin/fields/date_time"
         | 
| 17 17 | 
             
                autoload :Decimal, "madmin/fields/decimal"
         | 
| 18 | 
            -
                autoload :Json, "madmin/fields/json"
         | 
| 19 18 | 
             
                autoload :Enum, "madmin/fields/enum"
         | 
| 20 19 | 
             
                autoload :Float, "madmin/fields/float"
         | 
| 21 | 
            -
                autoload :Time, "madmin/fields/time"
         | 
| 22 | 
            -
                autoload :BelongsTo, "madmin/fields/belongs_to"
         | 
| 23 | 
            -
                autoload :Polymorphic, "madmin/fields/polymorphic"
         | 
| 24 20 | 
             
                autoload :HasMany, "madmin/fields/has_many"
         | 
| 25 21 | 
             
                autoload :HasOne, "madmin/fields/has_one"
         | 
| 22 | 
            +
                autoload :Integer, "madmin/fields/integer"
         | 
| 23 | 
            +
                autoload :Json, "madmin/fields/json"
         | 
| 24 | 
            +
                autoload :NestedHasMany, "madmin/fields/nested_has_many"
         | 
| 25 | 
            +
                autoload :Password, "madmin/fields/password"
         | 
| 26 | 
            +
                autoload :Polymorphic, "madmin/fields/polymorphic"
         | 
| 26 27 | 
             
                autoload :RichText, "madmin/fields/rich_text"
         | 
| 27 | 
            -
                autoload : | 
| 28 | 
            -
                autoload : | 
| 28 | 
            +
                autoload :String, "madmin/fields/string"
         | 
| 29 | 
            +
                autoload :Text, "madmin/fields/text"
         | 
| 30 | 
            +
                autoload :Time, "madmin/fields/time"
         | 
| 29 31 | 
             
              end
         | 
| 30 32 |  | 
| 31 33 | 
             
              mattr_accessor :resources, default: []
         | 
| @@ -3,10 +3,11 @@ module Madmin | |
| 3 3 | 
             
                class BelongsTo < Field
         | 
| 4 4 | 
             
                  def options_for_select(record)
         | 
| 5 5 | 
             
                    association = record.class.reflect_on_association(attribute_name)
         | 
| 6 | 
            -
             | 
| 7 6 | 
             
                    klass = association.klass
         | 
| 7 | 
            +
                    resource = nil
         | 
| 8 8 | 
             
                    klass.all.map do |r|
         | 
| 9 | 
            -
                       | 
| 9 | 
            +
                      resource ||= Madmin.resource_for(r)
         | 
| 10 | 
            +
                      [resource.display_name(r), r.id]
         | 
| 10 11 | 
             
                    end
         | 
| 11 12 | 
             
                  end
         | 
| 12 13 |  | 
    
        data/lib/madmin/fields/enum.rb
    CHANGED
    
    
| @@ -3,10 +3,11 @@ module Madmin | |
| 3 3 | 
             
                class HasMany < Field
         | 
| 4 4 | 
             
                  def options_for_select(record)
         | 
| 5 5 | 
             
                    association = record.class.reflect_on_association(attribute_name)
         | 
| 6 | 
            -
             | 
| 7 6 | 
             
                    klass = association.klass
         | 
| 7 | 
            +
                    resource = nil
         | 
| 8 8 | 
             
                    klass.all.map do |r|
         | 
| 9 | 
            -
                       | 
| 9 | 
            +
                      resource ||= Madmin.resource_for(r)
         | 
| 10 | 
            +
                      [resource.display_name(r), r.id]
         | 
| 10 11 | 
             
                    end
         | 
| 11 12 | 
             
                  end
         | 
| 12 13 |  | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            module Madmin
         | 
| 2 | 
            +
              module Fields
         | 
| 3 | 
            +
                class NestedHasMany < Field
         | 
| 4 | 
            +
                  DEFAULT_ATTRIBUTES = %w[_destroy id].freeze
         | 
| 5 | 
            +
                  def nested_attributes
         | 
| 6 | 
            +
                    resource.attributes.reject { |i| skipped_fields.include?(i[:name]) }
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def resource
         | 
| 10 | 
            +
                    "#{to_model.name}Resource".constantize
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def to_param
         | 
| 14 | 
            +
                    {"#{attribute_name}_attributes": permitted_fields}
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def to_partial_path(name)
         | 
| 18 | 
            +
                    unless %w[index show form fields].include? name
         | 
| 19 | 
            +
                      raise ArgumentError, "`partial` must be 'index', 'show', 'form' or 'fields'"
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    "/madmin/fields/#{self.class.field_type}/#{name}"
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  def to_model
         | 
| 26 | 
            +
                    attribute_name.to_s.singularize.classify.constantize
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  private
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def permitted_fields
         | 
| 32 | 
            +
                    (resource.permitted_params - skipped_fields + DEFAULT_ATTRIBUTES).uniq
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def skipped_fields
         | 
| 36 | 
            +
                    options[:skip] || []
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            module Madmin
         | 
| 2 | 
            +
              class Namespace
         | 
| 3 | 
            +
                def initialize(namespace)
         | 
| 4 | 
            +
                  @namespace = namespace
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def resources
         | 
| 8 | 
            +
                  @resources ||= routes.map(&:first).uniq.map { |path|
         | 
| 9 | 
            +
                    Resource.new(namespace, path)
         | 
| 10 | 
            +
                  }
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def routes
         | 
| 14 | 
            +
                  @routes ||= all_routes.select { |controller, _action|
         | 
| 15 | 
            +
                    controller.starts_with?("#{namespace}/")
         | 
| 16 | 
            +
                  }.map { |controller, action|
         | 
| 17 | 
            +
                    [controller.gsub(/^#{namespace}\//, ""), action]
         | 
| 18 | 
            +
                  }
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def resources_with_index_route
         | 
| 22 | 
            +
                  routes.select { |_resource, route| route == "index" }.map(&:first).uniq
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                private
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                attr_reader :namespace
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def all_routes
         | 
| 30 | 
            +
                  Rails.application.routes.routes.map do |route|
         | 
| 31 | 
            +
                    route.defaults.values_at(:controller, :action).map(&:to_s)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
    
        data/lib/madmin/resource.rb
    CHANGED
    
    | @@ -18,6 +18,10 @@ module Madmin | |
| 18 18 | 
             
                    model_name.constantize
         | 
| 19 19 | 
             
                  end
         | 
| 20 20 |  | 
| 21 | 
            +
                  def model_find(id)
         | 
| 22 | 
            +
                    friendly_model? ? model.friendly.find(id) : model.find(id)
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 21 25 | 
             
                  def model_name
         | 
| 22 26 | 
             
                    to_s.chomp("Resource").classify
         | 
| 23 27 | 
             
                  end
         | 
| @@ -38,21 +42,27 @@ module Madmin | |
| 38 42 | 
             
                  end
         | 
| 39 43 |  | 
| 40 44 | 
             
                  def index_path(options = {})
         | 
| 41 | 
            -
                     | 
| 42 | 
            -
             | 
| 43 | 
            -
                     | 
| 45 | 
            +
                    route_name = "madmin_#{model.table_name}_path"
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    url_helpers.send(route_name, options)
         | 
| 44 48 | 
             
                  end
         | 
| 45 49 |  | 
| 46 50 | 
             
                  def new_path
         | 
| 47 | 
            -
                    " | 
| 51 | 
            +
                    route_name = "new_madmin_#{model.model_name.singular}_path"
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    url_helpers.send(route_name)
         | 
| 48 54 | 
             
                  end
         | 
| 49 55 |  | 
| 50 56 | 
             
                  def show_path(record)
         | 
| 51 | 
            -
                    " | 
| 57 | 
            +
                    route_name = "madmin_#{model.model_name.singular}_path"
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    url_helpers.send(route_name, record.to_param)
         | 
| 52 60 | 
             
                  end
         | 
| 53 61 |  | 
| 54 62 | 
             
                  def edit_path(record)
         | 
| 55 | 
            -
                    " | 
| 63 | 
            +
                    route_name = "edit_madmin_#{model.model_name.singular}_path"
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    url_helpers.send(route_name, record.to_param)
         | 
| 56 66 | 
             
                  end
         | 
| 57 67 |  | 
| 58 68 | 
             
                  def param_key
         | 
| @@ -60,13 +70,21 @@ module Madmin | |
| 60 70 | 
             
                  end
         | 
| 61 71 |  | 
| 62 72 | 
             
                  def permitted_params
         | 
| 63 | 
            -
                    attributes. | 
| 73 | 
            +
                    attributes.filter_map { |a| a[:field].to_param if a[:field].visible?(:form) }
         | 
| 64 74 | 
             
                  end
         | 
| 65 75 |  | 
| 66 76 | 
             
                  def display_name(record)
         | 
| 67 77 | 
             
                    "#{record.class} ##{record.id}"
         | 
| 68 78 | 
             
                  end
         | 
| 69 79 |  | 
| 80 | 
            +
                  def friendly_model?
         | 
| 81 | 
            +
                    model.respond_to? :friendly
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  def sortable_columns
         | 
| 85 | 
            +
                    model.column_names
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
             | 
| 70 88 | 
             
                  private
         | 
| 71 89 |  | 
| 72 90 | 
             
                  def field_for_type(name, type)
         | 
| @@ -90,6 +108,7 @@ module Madmin | |
| 90 108 | 
             
                      text: Fields::Text,
         | 
| 91 109 | 
             
                      time: Fields::Time,
         | 
| 92 110 | 
             
                      timestamp: Fields::Time,
         | 
| 111 | 
            +
                      password: Fields::Password,
         | 
| 93 112 |  | 
| 94 113 | 
             
                      # Postgres specific types
         | 
| 95 114 | 
             
                      bit: Fields::String,
         | 
| @@ -126,7 +145,8 @@ module Madmin | |
| 126 145 | 
             
                      polymorphic: Fields::Polymorphic,
         | 
| 127 146 | 
             
                      has_many: Fields::HasMany,
         | 
| 128 147 | 
             
                      has_one: Fields::HasOne,
         | 
| 129 | 
            -
                      rich_text: Fields::RichText
         | 
| 148 | 
            +
                      rich_text: Fields::RichText,
         | 
| 149 | 
            +
                      nested_has_many: Fields::NestedHasMany
         | 
| 130 150 | 
             
                    }.fetch(type)
         | 
| 131 151 | 
             
                  rescue
         | 
| 132 152 | 
             
                    raise ArgumentError, <<~MESSAGE
         | 
| @@ -143,7 +163,12 @@ module Madmin | |
| 143 163 | 
             
                    name_string = name.to_s
         | 
| 144 164 |  | 
| 145 165 | 
             
                    if model.attribute_types.include?(name_string)
         | 
| 146 | 
            -
                      model.attribute_types[name_string] | 
| 166 | 
            +
                      column_type = model.attribute_types[name_string]
         | 
| 167 | 
            +
                      if column_type.is_a? ActiveRecord::Enum::EnumType
         | 
| 168 | 
            +
                        :enum
         | 
| 169 | 
            +
                      else
         | 
| 170 | 
            +
                        column_type.type || :string
         | 
| 171 | 
            +
                      end
         | 
| 147 172 | 
             
                    elsif (association = model.reflect_on_association(name))
         | 
| 148 173 | 
             
                      type_for_association(association)
         | 
| 149 174 | 
             
                    elsif model.reflect_on_association(:"rich_text_#{name_string}")
         | 
| @@ -152,6 +177,10 @@ module Madmin | |
| 152 177 | 
             
                      :attachment
         | 
| 153 178 | 
             
                    elsif model.reflect_on_association(:"#{name_string}_attachments")
         | 
| 154 179 | 
             
                      :attachments
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                    # has_secure_password
         | 
| 182 | 
            +
                    elsif model.attribute_types.include?("#{name_string}_digest") || name_string.ends_with?("_confirmation")
         | 
| 183 | 
            +
                      :password
         | 
| 155 184 | 
             
                    end
         | 
| 156 185 | 
             
                  end
         | 
| 157 186 |  | 
| @@ -166,6 +195,10 @@ module Madmin | |
| 166 195 | 
             
                      :belongs_to
         | 
| 167 196 | 
             
                    end
         | 
| 168 197 | 
             
                  end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                  def url_helpers
         | 
| 200 | 
            +
                    @url_helpers ||= Rails.application.routes.url_helpers
         | 
| 201 | 
            +
                  end
         | 
| 169 202 | 
             
                end
         | 
| 170 203 | 
             
              end
         | 
| 171 204 | 
             
            end
         | 
    
        data/lib/madmin/version.rb
    CHANGED
    
    
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            require "rails/generators/base"
         | 
| 2 | 
            +
            require "madmin/generator_helpers"
         | 
| 3 | 
            +
            require "madmin/namespace"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Madmin
         | 
| 6 | 
            +
              class ViewGenerator < Rails::Generators::Base
         | 
| 7 | 
            +
                include Madmin::GeneratorHelpers
         | 
| 8 | 
            +
                class_option :namespace, type: :string, default: "madmin"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def self.template_source_path
         | 
| 11 | 
            +
                  File.expand_path(
         | 
| 12 | 
            +
                    "../../../app/views/madmin/application",
         | 
| 13 | 
            +
                    __FILE__
         | 
| 14 | 
            +
                  )
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                private
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def namespace
         | 
| 20 | 
            +
                  options[:namespace]
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def copy_resource_template(template_name)
         | 
| 24 | 
            +
                  template_file = "#{template_name}.html.erb"
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  copy_file(
         | 
| 27 | 
            +
                    template_file,
         | 
| 28 | 
            +
                    "app/views/#{namespace}/#{resource_path}/#{template_file}"
         | 
| 29 | 
            +
                  )
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def resource_path
         | 
| 33 | 
            +
                  args.first.try(:underscore).try(:pluralize) || BaseResourcePath.new
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                class BaseResourcePath
         | 
| 37 | 
            +
                  def to_s
         | 
| 38 | 
            +
                    "application"
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: madmin
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Chris Oliver
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire:
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2021- | 
| 12 | 
            +
            date: 2021-05-05 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: rails
         | 
| @@ -63,6 +63,7 @@ files: | |
| 63 63 | 
             
            - app/controllers/madmin/dashboard_controller.rb
         | 
| 64 64 | 
             
            - app/controllers/madmin/resource_controller.rb
         | 
| 65 65 | 
             
            - app/helpers/madmin/application_helper.rb
         | 
| 66 | 
            +
            - app/helpers/madmin/sort_helper.rb
         | 
| 66 67 | 
             
            - app/views/layouts/madmin/application.html.erb
         | 
| 67 68 | 
             
            - app/views/madmin/application/_form.html.erb
         | 
| 68 69 | 
             
            - app/views/madmin/application/_javascript.html.erb
         | 
| @@ -111,6 +112,13 @@ files: | |
| 111 112 | 
             
            - app/views/madmin/fields/json/_form.html.erb
         | 
| 112 113 | 
             
            - app/views/madmin/fields/json/_index.html.erb
         | 
| 113 114 | 
             
            - app/views/madmin/fields/json/_show.html.erb
         | 
| 115 | 
            +
            - app/views/madmin/fields/nested_has_many/_fields.html.erb
         | 
| 116 | 
            +
            - app/views/madmin/fields/nested_has_many/_form.html.erb
         | 
| 117 | 
            +
            - app/views/madmin/fields/nested_has_many/_index.html.erb
         | 
| 118 | 
            +
            - app/views/madmin/fields/nested_has_many/_show.html.erb
         | 
| 119 | 
            +
            - app/views/madmin/fields/password/_form.html.erb
         | 
| 120 | 
            +
            - app/views/madmin/fields/password/_index.html.erb
         | 
| 121 | 
            +
            - app/views/madmin/fields/password/_show.html.erb
         | 
| 114 122 | 
             
            - app/views/madmin/fields/polymorphic/_form.html.erb
         | 
| 115 123 | 
             
            - app/views/madmin/fields/polymorphic/_index.html.erb
         | 
| 116 124 | 
             
            - app/views/madmin/fields/polymorphic/_show.html.erb
         | 
| @@ -131,6 +139,15 @@ files: | |
| 131 139 | 
             
            - lib/generators/madmin/resource/resource_generator.rb
         | 
| 132 140 | 
             
            - lib/generators/madmin/resource/templates/controller.rb.tt
         | 
| 133 141 | 
             
            - lib/generators/madmin/resource/templates/resource.rb.tt
         | 
| 142 | 
            +
            - lib/generators/madmin/views/edit_generator.rb
         | 
| 143 | 
            +
            - lib/generators/madmin/views/form_generator.rb
         | 
| 144 | 
            +
            - lib/generators/madmin/views/index_generator.rb
         | 
| 145 | 
            +
            - lib/generators/madmin/views/javascript_generator.rb
         | 
| 146 | 
            +
            - lib/generators/madmin/views/layout_generator.rb
         | 
| 147 | 
            +
            - lib/generators/madmin/views/navigation_generator.rb
         | 
| 148 | 
            +
            - lib/generators/madmin/views/new_generator.rb
         | 
| 149 | 
            +
            - lib/generators/madmin/views/show_generator.rb
         | 
| 150 | 
            +
            - lib/generators/madmin/views/views_generator.rb
         | 
| 134 151 | 
             
            - lib/madmin.rb
         | 
| 135 152 | 
             
            - lib/madmin/engine.rb
         | 
| 136 153 | 
             
            - lib/madmin/field.rb
         | 
| @@ -147,14 +164,18 @@ files: | |
| 147 164 | 
             
            - lib/madmin/fields/has_one.rb
         | 
| 148 165 | 
             
            - lib/madmin/fields/integer.rb
         | 
| 149 166 | 
             
            - lib/madmin/fields/json.rb
         | 
| 167 | 
            +
            - lib/madmin/fields/nested_has_many.rb
         | 
| 168 | 
            +
            - lib/madmin/fields/password.rb
         | 
| 150 169 | 
             
            - lib/madmin/fields/polymorphic.rb
         | 
| 151 170 | 
             
            - lib/madmin/fields/rich_text.rb
         | 
| 152 171 | 
             
            - lib/madmin/fields/string.rb
         | 
| 153 172 | 
             
            - lib/madmin/fields/text.rb
         | 
| 154 173 | 
             
            - lib/madmin/fields/time.rb
         | 
| 155 174 | 
             
            - lib/madmin/generator_helpers.rb
         | 
| 175 | 
            +
            - lib/madmin/namespace.rb
         | 
| 156 176 | 
             
            - lib/madmin/resource.rb
         | 
| 157 177 | 
             
            - lib/madmin/version.rb
         | 
| 178 | 
            +
            - lib/madmin/view_generator.rb
         | 
| 158 179 | 
             
            - lib/tasks/madmin_tasks.rake
         | 
| 159 180 | 
             
            homepage: https://github.com/excid3/madmin
         | 
| 160 181 | 
             
            licenses:
         | 
| @@ -171,9 +192,9 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 171 192 | 
             
                  version: 2.5.0
         | 
| 172 193 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 173 194 | 
             
              requirements:
         | 
| 174 | 
            -
              - - " | 
| 195 | 
            +
              - - ">="
         | 
| 175 196 | 
             
                - !ruby/object:Gem::Version
         | 
| 176 | 
            -
                  version:  | 
| 197 | 
            +
                  version: '0'
         | 
| 177 198 | 
             
            requirements: []
         | 
| 178 199 | 
             
            rubygems_version: 3.2.3
         | 
| 179 200 | 
             
            signing_key:
         |