adminable 0.0.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +91 -0
- data/Rakefile +22 -0
- data/app/assets/javascripts/adminable/application.js +18 -0
- data/app/assets/javascripts/adminable/scripts.js +20 -0
- data/app/assets/stylesheets/adminable/application.scss +3 -0
- data/app/controllers/adminable/application_controller.rb +7 -0
- data/app/controllers/adminable/resources_controller.rb +93 -0
- data/app/helpers/adminable/application_helper.rb +4 -0
- data/app/views/adminable/kaminari/_first_page.html.haml +2 -0
- data/app/views/adminable/kaminari/_last_page.html.haml +2 -0
- data/app/views/adminable/kaminari/_next_page.html.haml +2 -0
- data/app/views/adminable/kaminari/_page.html.haml +6 -0
- data/app/views/adminable/kaminari/_paginator.html.haml +10 -0
- data/app/views/adminable/kaminari/_prev_page.html.haml +2 -0
- data/app/views/adminable/resources/_form.html.haml +14 -0
- data/app/views/adminable/resources/_search.html.haml +9 -0
- data/app/views/adminable/resources/edit.html.haml +5 -0
- data/app/views/adminable/resources/form/_belongs_to.html.haml +3 -0
- data/app/views/adminable/resources/form/_boolean.html.haml +3 -0
- data/app/views/adminable/resources/form/_datetime.html.haml +2 -0
- data/app/views/adminable/resources/form/_decimal.html.haml +2 -0
- data/app/views/adminable/resources/form/_float.html.haml +2 -0
- data/app/views/adminable/resources/form/_has_many.html.haml +9 -0
- data/app/views/adminable/resources/form/_integer.html.haml +2 -0
- data/app/views/adminable/resources/form/_string.html.haml +2 -0
- data/app/views/adminable/resources/form/_text.html.haml +2 -0
- data/app/views/adminable/resources/index.html.haml +35 -0
- data/app/views/adminable/resources/index/_belongs_to.html.haml +5 -0
- data/app/views/adminable/resources/index/_boolean.html.haml +2 -0
- data/app/views/adminable/resources/index/_datetime.html.haml +2 -0
- data/app/views/adminable/resources/index/_decimal.html.haml +1 -0
- data/app/views/adminable/resources/index/_float.html.haml +1 -0
- data/app/views/adminable/resources/index/_has_many.html.haml +3 -0
- data/app/views/adminable/resources/index/_integer.html.haml +1 -0
- data/app/views/adminable/resources/index/_string.html.haml +1 -0
- data/app/views/adminable/resources/index/_text.html.haml +1 -0
- data/app/views/adminable/resources/new.html.haml +5 -0
- data/app/views/adminable/shared/_alert.html.haml +4 -0
- data/app/views/adminable/shared/_label.html.haml +5 -0
- data/app/views/layouts/adminable/application.html.haml +40 -0
- data/config/initializers/haml.rb +3 -0
- data/config/locales/adminable.en.yml +18 -0
- data/config/routes.rb +7 -0
- data/lib/adminable.rb +33 -0
- data/lib/adminable/attributes/association.rb +21 -0
- data/lib/adminable/attributes/base.rb +42 -0
- data/lib/adminable/attributes/collection.rb +77 -0
- data/lib/adminable/attributes/types/belongs_to.rb +13 -0
- data/lib/adminable/attributes/types/boolean.rb +8 -0
- data/lib/adminable/attributes/types/datetime.rb +8 -0
- data/lib/adminable/attributes/types/decimal.rb +8 -0
- data/lib/adminable/attributes/types/float.rb +8 -0
- data/lib/adminable/attributes/types/has_many.rb +21 -0
- data/lib/adminable/attributes/types/integer.rb +8 -0
- data/lib/adminable/attributes/types/string.rb +8 -0
- data/lib/adminable/attributes/types/text.rb +8 -0
- data/lib/adminable/configuration.rb +19 -0
- data/lib/adminable/engine.rb +9 -0
- data/lib/adminable/extensions/devise.rb +24 -0
- data/lib/adminable/resource.rb +37 -0
- data/lib/adminable/version.rb +3 -0
- data/lib/generators/cms/resource/templates/resource_controller.rb.erb +2 -0
- data/lib/generators/cms/resource_generator.rb +28 -0
- metadata +381 -0
@@ -0,0 +1 @@
|
|
1
|
+
= value
|
@@ -0,0 +1 @@
|
|
1
|
+
= value
|
@@ -0,0 +1 @@
|
|
1
|
+
= value
|
@@ -0,0 +1 @@
|
|
1
|
+
= value
|
@@ -0,0 +1 @@
|
|
1
|
+
= strip_tags(value.truncate(100)).squish
|
@@ -0,0 +1,40 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title Adminable
|
5
|
+
%link{ :href => 'https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css', :rel => 'stylesheet' }/
|
6
|
+
%link{ :href => '//oss.maxcdn.com/clusterize.js/0.16.0/clusterize.css', :rel => 'stylesheet' }/
|
7
|
+
%script{ :src => '//oss.maxcdn.com/clusterize.js/0.16.0/clusterize.min.js' }
|
8
|
+
%script{ :src => '//cdn.tinymce.com/4/tinymce.min.js' }
|
9
|
+
%meta{ :content => 'width=device-width, initial-scale=1, shrink-to-fit=no', :name => 'viewport' }/
|
10
|
+
%meta{ :content => 'ie=edge', 'http-equiv' => 'x-ua-compatible' }/
|
11
|
+
= stylesheet_link_tag 'adminable/application', media: 'all'
|
12
|
+
= javascript_include_tag 'adminable/application'
|
13
|
+
= csrf_meta_tags
|
14
|
+
%body
|
15
|
+
#collapsing-nav.collapse.p-y-1
|
16
|
+
- Adminable::Configuration.resources.each do |resource|
|
17
|
+
= link_to resource.model.model_name.human.pluralize,
|
18
|
+
polymorphic_path(resource.route), class: 'btn btn-link btn-block'
|
19
|
+
.navbar.navbar-full.navbar-dark.bg-primary.m-b-3
|
20
|
+
.hidden-md-up
|
21
|
+
%button.navbar-toggler{ 'data-target' => '#collapsing-nav', 'data-toggle' => :collapse, :type => :button }
|
22
|
+
\☰
|
23
|
+
.container.hidden-sm-down
|
24
|
+
%ul.nav.navbar-nav
|
25
|
+
%li.nav-item
|
26
|
+
= link_to main_app.root_path, class: 'nav-link' do
|
27
|
+
%i.fa.fa-home
|
28
|
+
- Adminable::Configuration.resources.each do |resource|
|
29
|
+
%li.nav-item{ :class => ('active' if current_page?(File.join('/adminable/', resource.name))) }
|
30
|
+
= link_to resource.model.model_name.human.pluralize,
|
31
|
+
polymorphic_path(resource.route), class: 'nav-link'
|
32
|
+
.container.p-b-3
|
33
|
+
- if flash[:alert] || notice.present?
|
34
|
+
.p-b-2
|
35
|
+
- if flash[:alert]
|
36
|
+
- flash[:alert].each do |alert|
|
37
|
+
= render 'adminable/shared/alert', message: alert, type: 'danger'
|
38
|
+
- if notice.present?
|
39
|
+
= render 'adminable/shared/alert', message: notice, type: 'success'
|
40
|
+
= yield
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
adminable:
|
4
|
+
ui:
|
5
|
+
confirm: Are you sure?
|
6
|
+
not_selected: Not selected
|
7
|
+
buttons:
|
8
|
+
submit: Submit
|
9
|
+
back: Back
|
10
|
+
edit: Edit
|
11
|
+
new: New %{resource}
|
12
|
+
titles:
|
13
|
+
edit: Edit %{resource}
|
14
|
+
new: New %{resource}
|
15
|
+
resources:
|
16
|
+
created: "%{resource} has been successfully created."
|
17
|
+
updated: "%{resource} has been successfully updated."
|
18
|
+
deleted: "%{resource} has been successfully deleted."
|
data/config/routes.rb
ADDED
data/lib/adminable.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'adminable/engine'
|
2
|
+
require 'adminable/configuration'
|
3
|
+
|
4
|
+
require 'adminable/extensions/devise'
|
5
|
+
|
6
|
+
require 'adminable/resource'
|
7
|
+
|
8
|
+
require 'adminable/attributes/collection'
|
9
|
+
require 'adminable/attributes/association'
|
10
|
+
|
11
|
+
require 'adminable/attributes/base'
|
12
|
+
|
13
|
+
require 'adminable/attributes/types/belongs_to'
|
14
|
+
require 'adminable/attributes/types/boolean'
|
15
|
+
require 'adminable/attributes/types/datetime'
|
16
|
+
require 'adminable/attributes/types/decimal'
|
17
|
+
require 'adminable/attributes/types/float'
|
18
|
+
require 'adminable/attributes/types/has_many'
|
19
|
+
require 'adminable/attributes/types/integer'
|
20
|
+
require 'adminable/attributes/types/string'
|
21
|
+
require 'adminable/attributes/types/text'
|
22
|
+
|
23
|
+
require 'haml-rails'
|
24
|
+
require 'sass-rails'
|
25
|
+
require 'coffee-rails'
|
26
|
+
require 'jquery-rails'
|
27
|
+
require 'bootstrap'
|
28
|
+
require 'rails-assets-tether'
|
29
|
+
require 'babosa'
|
30
|
+
require 'kaminari'
|
31
|
+
|
32
|
+
module Adminable
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Adminable
|
2
|
+
module Attributes
|
3
|
+
module Association
|
4
|
+
attr_reader :options_for_select, :association
|
5
|
+
|
6
|
+
def options_for_select(entry)
|
7
|
+
@association.klass.all.reject { |e| e == entry }.collect do |e|
|
8
|
+
[association_option_name(e), e.id]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def association_option_name(entry)
|
15
|
+
%i(email login name title id).each do |a|
|
16
|
+
return entry.try(a) unless entry.try(a).nil?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Adminable
|
2
|
+
module Attributes
|
3
|
+
class Base
|
4
|
+
attr_accessor :name, :required, :show, :center, :wysiwyg
|
5
|
+
attr_reader :key, :ransack_name
|
6
|
+
|
7
|
+
def initialize(name, options = {})
|
8
|
+
raise 'Base class cannot be initialized' if self.class == Base
|
9
|
+
|
10
|
+
@name = name
|
11
|
+
@key = options[:key] || @name
|
12
|
+
@ransack_name = "#{@name}_cont"
|
13
|
+
@association = options[:association]
|
14
|
+
@required = options[:required] || false
|
15
|
+
@show = true
|
16
|
+
@center = %w(integer boolean float decimal).include?(type)
|
17
|
+
@wysiwyg = %w(text).include?(type)
|
18
|
+
end
|
19
|
+
|
20
|
+
alias required? required
|
21
|
+
alias show? show
|
22
|
+
alias center? center
|
23
|
+
alias wysiwyg? wysiwyg
|
24
|
+
|
25
|
+
def type
|
26
|
+
self.class.name.demodulize.underscore
|
27
|
+
end
|
28
|
+
|
29
|
+
def strong_parameter
|
30
|
+
key
|
31
|
+
end
|
32
|
+
|
33
|
+
def index_partial_path
|
34
|
+
"index/#{type}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def form_partial_path
|
38
|
+
"adminable/resources/form/#{type}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Adminable
|
2
|
+
module Attributes
|
3
|
+
class Collection
|
4
|
+
attr_reader :model
|
5
|
+
attr_writer :index, :form
|
6
|
+
|
7
|
+
def initialize(model)
|
8
|
+
@model = model
|
9
|
+
end
|
10
|
+
|
11
|
+
def index
|
12
|
+
@index ||= all.except(:created_at, :updated_at)
|
13
|
+
end
|
14
|
+
|
15
|
+
def form
|
16
|
+
@form ||= all.except(:id, :created_at, :updated_at)
|
17
|
+
end
|
18
|
+
|
19
|
+
def ransack
|
20
|
+
@ransack ||= columns.except(:id, :created_at, :updated_at)
|
21
|
+
.select { |k, v| %w(string text).include?(v.type) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def all
|
25
|
+
[columns, belongs_to, has_many].inject(&:merge)
|
26
|
+
end
|
27
|
+
|
28
|
+
def association
|
29
|
+
[belongs_to, has_many].inject(&:merge)
|
30
|
+
end
|
31
|
+
|
32
|
+
def columns
|
33
|
+
@columns ||= {}.tap do |attribute|
|
34
|
+
@model.columns.reject { |a| a.name.match(/_id$/) }.each do |column|
|
35
|
+
attribute[column.name] = "adminable/attributes/types/#{column.type}"
|
36
|
+
.classify.constantize.new(
|
37
|
+
column.name,
|
38
|
+
required: attribute_required?(column.name)
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end.symbolize_keys
|
42
|
+
end
|
43
|
+
|
44
|
+
def belongs_to
|
45
|
+
@belongs_to ||= {}.tap do |attribute|
|
46
|
+
@model.reflect_on_all_associations(:belongs_to).each do |association|
|
47
|
+
attribute[association.name] = Adminable::Attributes::Types::BelongsTo.new(
|
48
|
+
association.name,
|
49
|
+
required: attribute_required?(association.name),
|
50
|
+
association: association
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end.symbolize_keys
|
54
|
+
end
|
55
|
+
|
56
|
+
def has_many
|
57
|
+
@has_many ||= {}.tap do |attribute|
|
58
|
+
@model.reflect_on_all_associations(:has_many).each do |association|
|
59
|
+
attribute[association.name] = Adminable::Attributes::Types::HasMany.new(
|
60
|
+
association.name,
|
61
|
+
required: attribute_required?(association.name),
|
62
|
+
association: association
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end.symbolize_keys
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def attribute_required?(name)
|
71
|
+
@model.validators_on(name).any? do |validator|
|
72
|
+
validator.class == ActiveRecord::Validations::PresenceValidator
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Adminable
|
2
|
+
module Attributes
|
3
|
+
module Types
|
4
|
+
class HasMany < Base
|
5
|
+
include Adminable::Attributes::Association
|
6
|
+
|
7
|
+
def key
|
8
|
+
@key = "#{@name.to_s.singularize}_ids"
|
9
|
+
end
|
10
|
+
|
11
|
+
def strong_parameter
|
12
|
+
{ key => [] }
|
13
|
+
end
|
14
|
+
|
15
|
+
def show?
|
16
|
+
@association.klass.any?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Adminable
|
2
|
+
module Configuration
|
3
|
+
def self.resources
|
4
|
+
@resources ||= resources_paths.map do |resource_path|
|
5
|
+
Adminable::Resource.new(
|
6
|
+
resource_path.to_s.split('adminable/').last.sub(/_controller\.rb$/, '')
|
7
|
+
)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.find_resource(name)
|
12
|
+
resources.find { |resource| resource.name == name }
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.resources_paths
|
16
|
+
Dir[Rails.root.join('app/controllers/adminable/**/*_controller.rb')]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|