simple-admin 0.1.0.pre.alpha

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 (139) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +3 -0
  3. data/.gitattributes +1 -0
  4. data/.gitignore +17 -0
  5. data/.hound.yml +2 -0
  6. data/.inch.yml +4 -0
  7. data/.rspec +2 -0
  8. data/.rubocop.yml +68 -0
  9. data/.travis.yml +11 -0
  10. data/CODE_OF_CONDUCT.md +74 -0
  11. data/CONTRIBUTING.md +51 -0
  12. data/Gemfile +27 -0
  13. data/LICENSE.txt +21 -0
  14. data/README.md +87 -0
  15. data/Rakefile +20 -0
  16. data/app/assets/fonts/Simple-Line-Icons.woff +0 -0
  17. data/app/assets/javascripts/simple_admin/application.js +28 -0
  18. data/app/assets/stylesheets/simple_admin/application.scss +48 -0
  19. data/app/assets/stylesheets/simple_admin/global/buttons.css +473 -0
  20. data/app/assets/stylesheets/simple_admin/global/errors.css +12 -0
  21. data/app/assets/stylesheets/simple_admin/global/fontawesome-icons.css +3024 -0
  22. data/app/assets/stylesheets/simple_admin/global/fonts.css +560 -0
  23. data/app/assets/stylesheets/simple_admin/global/jquery.dataTables.css +169 -0
  24. data/app/assets/stylesheets/simple_admin/global/pagination.css +11 -0
  25. data/app/assets/stylesheets/simple_admin/global/reset.css +197 -0
  26. data/app/assets/stylesheets/simple_admin/global/simple-line-icons.css +672 -0
  27. data/app/assets/stylesheets/simple_admin/global/table.css +214 -0
  28. data/app/assets/stylesheets/simple_admin/global/tags.css +87 -0
  29. data/app/assets/stylesheets/simple_admin/page/aside.css +324 -0
  30. data/app/assets/stylesheets/simple_admin/page/header.css +332 -0
  31. data/app/assets/stylesheets/simple_admin/page/main-container.css +222 -0
  32. data/app/assets/stylesheets/simple_admin/page/sign_in.css +15 -0
  33. data/app/assets/stylesheets/simple_admin/tabs.css +26 -0
  34. data/app/controllers/simple_admin/admin/application_controller.rb +21 -0
  35. data/app/controllers/simple_admin/admin/search_controller.rb +29 -0
  36. data/app/controllers/simple_admin/admin/system/entities_controller.rb +37 -0
  37. data/app/controllers/simple_admin/admin/system/entity_field_types_controller.rb +31 -0
  38. data/app/controllers/simple_admin/admin/system/entity_fields_controller.rb +20 -0
  39. data/app/helpers/simple_admin_helper.rb +15 -0
  40. data/app/models/simple_admin/base.rb +14 -0
  41. data/app/models/simple_admin/entity.rb +50 -0
  42. data/app/models/simple_admin/entity_field.rb +77 -0
  43. data/app/models/simple_admin/entity_field_setting.rb +5 -0
  44. data/app/models/simple_admin/entity_field_type.rb +79 -0
  45. data/app/views/kaminari/_next_page.html.erb +5 -0
  46. data/app/views/kaminari/_page.html.erb +3 -0
  47. data/app/views/kaminari/_paginator.html.erb +26 -0
  48. data/app/views/kaminari/_prev_page.html.erb +5 -0
  49. data/app/views/layouts/devise.html.erb +11 -0
  50. data/app/views/layouts/simple_admin.html.erb +28 -0
  51. data/app/views/simple_admin/admin/resource/_form.html.erb +19 -0
  52. data/app/views/simple_admin/admin/resource/edit.html.erb +21 -0
  53. data/app/views/simple_admin/admin/resource/index.html.erb +13 -0
  54. data/app/views/simple_admin/admin/resource/new.html.erb +21 -0
  55. data/app/views/simple_admin/admin/search/index.html.erb +55 -0
  56. data/app/views/simple_admin/admin/shared/_aside.html.erb +46 -0
  57. data/app/views/simple_admin/admin/shared/_footer.html.erb +5 -0
  58. data/app/views/simple_admin/admin/shared/_header.html.erb +7 -0
  59. data/app/views/simple_admin/admin/shared/collection/_header.html.erb +12 -0
  60. data/app/views/simple_admin/admin/shared/collection/_table_body.html.erb +29 -0
  61. data/app/views/simple_admin/admin/shared/collection/_table_header.html.erb +11 -0
  62. data/app/views/simple_admin/admin/shared/components/_logout.html.erb +6 -0
  63. data/app/views/simple_admin/admin/shared/components/_search.html.erb +14 -0
  64. data/app/views/simple_admin/admin/shared/messages/_errors.html.erb +9 -0
  65. data/app/views/simple_admin/admin/shared/messages/_flash.html.erb +8 -0
  66. data/app/views/simple_admin/admin/system/entities/_form.html.erb +32 -0
  67. data/app/views/simple_admin/admin/system/entities/edit.html.erb +27 -0
  68. data/app/views/simple_admin/admin/system/entities/entity_fields/_form.html.erb +62 -0
  69. data/app/views/simple_admin/admin/system/entities/entity_fields/edit.html.erb +9 -0
  70. data/app/views/simple_admin/admin/system/entities/entity_fields/index.html.erb +39 -0
  71. data/app/views/simple_admin/admin/system/entities/entity_fields/new.html.erb +12 -0
  72. data/app/views/simple_admin/admin/system/entities/index.html.erb +59 -0
  73. data/app/views/simple_admin/admin/system/entities/new.html.erb +21 -0
  74. data/app/views/simple_admin/admin/system/entity_field_types/_form.html.erb +21 -0
  75. data/app/views/simple_admin/admin/system/entity_field_types/edit.html.erb +24 -0
  76. data/app/views/simple_admin/admin/system/entity_field_types/index.html.erb +55 -0
  77. data/app/views/simple_admin/admin/system/entity_field_types/new.html.erb +21 -0
  78. data/app/views/simple_admin/admin/system/entity_fields/create.js.erb +18 -0
  79. data/app/views/simple_admin/admin/system/entity_fields/destroy.js.erb +18 -0
  80. data/app/views/simple_admin/admin/system/entity_fields/update.js.erb +1 -0
  81. data/app/views/simple_admin/fields/boolean/_form.html.erb +6 -0
  82. data/app/views/simple_admin/fields/boolean/_index.html.erb +5 -0
  83. data/app/views/simple_admin/fields/image/_collection.html.erb +5 -0
  84. data/app/views/simple_admin/fields/image/_form.html.erb +6 -0
  85. data/app/views/simple_admin/fields/number/_collection.html.erb +5 -0
  86. data/app/views/simple_admin/fields/number/_form.html.erb +6 -0
  87. data/app/views/simple_admin/fields/password/_form.html.erb +6 -0
  88. data/app/views/simple_admin/fields/relation/_collection.html.erb +3 -0
  89. data/app/views/simple_admin/fields/relation/_form.html.erb +6 -0
  90. data/app/views/simple_admin/fields/select/_form.html.erb +8 -0
  91. data/app/views/simple_admin/fields/select/_index.html.erb +5 -0
  92. data/app/views/simple_admin/fields/string/_collection.html.erb +3 -0
  93. data/app/views/simple_admin/fields/string/_form.html.erb +6 -0
  94. data/app/views/simple_admin/fields/tags/_collection.html.erb +3 -0
  95. data/app/views/simple_admin/fields/tags/_form.html.erb +6 -0
  96. data/app/views/simple_admin/fields/text/_collection.html.erb +3 -0
  97. data/app/views/simple_admin/fields/text/_form.html.erb +6 -0
  98. data/bin/bundle +4 -0
  99. data/bin/rails +5 -0
  100. data/codecov.yml +21 -0
  101. data/config/locales/en.yml +23 -0
  102. data/config/locales/ru.yml +20 -0
  103. data/config/routes.rb +19 -0
  104. data/lib/generators/simple_admin/install_generator.rb +41 -0
  105. data/lib/generators/simple_admin/migration_generator.rb +24 -0
  106. data/lib/generators/templates/application_controller.rb +20 -0
  107. data/lib/generators/templates/initializers/simple_admin.rb.erb +3 -0
  108. data/lib/generators/templates/migrations/core_data_migration.rb +12 -0
  109. data/lib/generators/templates/migrations/core_migrations/entities_migration.rb +13 -0
  110. data/lib/generators/templates/migrations/core_migrations/entity_field_settings_migration.rb +12 -0
  111. data/lib/generators/templates/migrations/core_migrations/entity_field_types_migration.rb +12 -0
  112. data/lib/generators/templates/migrations/core_migrations/entity_fields_migration.rb +18 -0
  113. data/lib/generators/templates/user.rb +24 -0
  114. data/lib/generators/templates/views/devise/registrations/new.html.erb +46 -0
  115. data/lib/generators/templates/views/devise/sessions/new.html.erb +35 -0
  116. data/lib/generators/templates/views/devise/shared/_footer.html.erb +3 -0
  117. data/lib/simple_admin.rb +39 -0
  118. data/lib/simple_admin/config.rb +19 -0
  119. data/lib/simple_admin/engine.rb +15 -0
  120. data/lib/simple_admin/helpers/boolean_helper.rb +36 -0
  121. data/lib/simple_admin/helpers/url_helper.rb +29 -0
  122. data/lib/simple_admin/refinements/boolean.rb +36 -0
  123. data/lib/simple_admin/resource_controller/actions_builder.rb +40 -0
  124. data/lib/simple_admin/resource_controller/controller_builder.rb +31 -0
  125. data/lib/simple_admin/resource_controller/crudify.rb +111 -0
  126. data/lib/simple_admin/resource_controller/crudify_dynamic_resource.rb +55 -0
  127. data/lib/simple_admin/resource_controller/dynamic_fields.rb +53 -0
  128. data/lib/simple_admin/search.rb +23 -0
  129. data/lib/simple_admin/version.rb +3 -0
  130. data/simple_admin.gemspec +38 -0
  131. data/vendor/assets/fonts/Simple-Line-Icons.eot +0 -0
  132. data/vendor/assets/fonts/Simple-Line-Icons.ttf +0 -0
  133. data/vendor/assets/fonts/Simple-Line-Icons.woff +0 -0
  134. data/vendor/assets/fonts/fontawesome-webfont.eot +0 -0
  135. data/vendor/assets/fonts/fontawesome-webfont.svg +2671 -0
  136. data/vendor/assets/fonts/fontawesome-webfont.ttf +0 -0
  137. data/vendor/assets/fonts/fontawesome-webfont.woff +0 -0
  138. data/vendor/assets/fonts/fontawesome-webfont.woff2 +0 -0
  139. metadata +307 -0
@@ -0,0 +1,15 @@
1
+ .content.content-boxed {
2
+ max-width: 1280px;
3
+ }
4
+
5
+ .pulldown {
6
+ position: relative;
7
+ top: 50px;
8
+ }
9
+
10
+ @media screen and (min-width: 992px) {
11
+ /* line 9052, /Users/dmitriy/Projects/exampleapp/gemfiles/simple_admin/app/assets/stylesheets/simple_admin/core.scss */
12
+ .pulldown {
13
+ top: 150px;
14
+ }
15
+ }
@@ -0,0 +1,26 @@
1
+ .block > .nav-tabs {
2
+ background-color: #f9f9f9;
3
+ border-bottom: none;
4
+ }
5
+
6
+ .block > .nav-tabs > li.ui-tabs-active > a, .block > .nav-tabs > li.ui-tabs-active > a:hover, .block > .nav-tabs > li.ui-tabs-active > a:focus {
7
+ color: #646464;
8
+ background-color: #fff;
9
+ border-color: transparent;
10
+ }
11
+
12
+ .block > .nav-tabs > li > a {
13
+ margin-right: 0;
14
+ padding-top: 12px;
15
+ padding-bottom: 12px;
16
+ color: #646464;
17
+ font-weight: 600;
18
+ border: 1px solid transparent;
19
+ border-radius: 0;
20
+ }
21
+
22
+ .nav {
23
+ margin-bottom: 0!important;
24
+ padding-left: 0!important;
25
+ list-style: none;
26
+ }
@@ -0,0 +1,21 @@
1
+ module SimpleAdmin
2
+ module Admin
3
+ class ApplicationController < ActionController::Base
4
+ layout 'simple_admin'
5
+
6
+ before_action :authenticate_user!
7
+
8
+ def current_user
9
+ # TODO: Add authenticated user here
10
+ raise NotImplementedError
11
+ end
12
+
13
+ private
14
+
15
+ def authenticate_user!
16
+ # TODO: Add authentication logic here
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ module SimpleAdmin
2
+ module Admin
3
+ class SearchController < SimpleAdmin::Admin::ApplicationController
4
+ PER_PAGE = 10
5
+
6
+ before_action :initialize_fields_entities!
7
+
8
+ def index
9
+ @resources = SimpleAdmin::Search.new(params[:query], params[:resource_klass].constantize).process
10
+ @resources = @resources.page(params[:page]).per(PER_PAGE) if @resources.present?
11
+
12
+ @resource_name = @entity.model_klass.model_name.element.capitalize
13
+ end
14
+
15
+ def initialize_fields_entities!
16
+ raise ActiveRecord::RecordNotFound if search_params_blank?
17
+
18
+ @entity = SimpleAdmin::Entity.find_by(model_klass_name: params[:resource_klass])
19
+ @entity_fields = @entity.entity_fields.collection
20
+ end
21
+
22
+ private
23
+
24
+ def search_params_blank?
25
+ params[:resource_klass].blank? || params[:query].blank?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ module SimpleAdmin
2
+ module Admin
3
+ module System
4
+ class EntitiesController < SimpleAdmin::Admin::ApplicationController
5
+ include ResourceController::Crudify
6
+
7
+ before_action :reload_models!, only: %i[new edit]
8
+
9
+ def model_klass
10
+ SimpleAdmin::Entity
11
+ end
12
+
13
+ def after_create_path
14
+ edit_admin_system_entity_path(@resource)
15
+ end
16
+
17
+ def after_update_path
18
+ admin_system_entities_path
19
+ end
20
+
21
+ def after_destroy_path
22
+ admin_system_entities_path
23
+ end
24
+
25
+ private
26
+
27
+ def resource_params
28
+ params.require(:simple_admin_entity).permit(:model_klass_name, :label, :status)
29
+ end
30
+
31
+ def reload_models!
32
+ Rails.application.eager_load!
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ module SimpleAdmin
2
+ module Admin
3
+ module System
4
+ class EntityFieldTypesController < SimpleAdmin::Admin::ApplicationController
5
+ include ResourceController::Crudify
6
+
7
+ def model_klass
8
+ SimpleAdmin::EntityFieldType
9
+ end
10
+
11
+ def after_create_path
12
+ admin_system_entity_field_types_path
13
+ end
14
+
15
+ def after_update_path
16
+ admin_system_entity_field_types_path
17
+ end
18
+
19
+ def after_destroy_path
20
+ admin_system_entity_field_types_path
21
+ end
22
+
23
+ private
24
+
25
+ def resource_params
26
+ params.require(:simple_admin_entity_field_type).permit(:name, :template)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ module SimpleAdmin
2
+ module Admin
3
+ module System
4
+ class EntityFieldsController < SimpleAdmin::Admin::ApplicationController
5
+ include ResourceController::CrudifyDynamicResource
6
+
7
+ def model_klass
8
+ SimpleAdmin::EntityField
9
+ end
10
+
11
+ private
12
+
13
+ def resource_params
14
+ params.require(:simple_admin_entity_field).permit(:name, :label, :entity_field_type_id, :entity_id, :presentation,
15
+ :search_indexable, entity_field_setting_attributes: [:value])
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module SimpleAdminHelper
2
+ include SimpleAdmin::Helpers::UrlHelper
3
+
4
+ def resources_pagination_start(per_page, current_page)
5
+ (per_page * current_page.to_i) - (per_page - 1)
6
+ end
7
+
8
+ def resources_pagination_end(per_page, current_page)
9
+ (per_page * current_page.to_i) + 1
10
+ end
11
+
12
+ def resource_index_path(resource_name, prefix=:admin_system, postfix=:path)
13
+ public_send("#{prefix}_#{resource_name}_#{postfix}")
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module SimpleAdmin
2
+ class Base < ApplicationRecord
3
+ self.abstract_class = true
4
+ self.table_name_prefix = 'simple_admin_'
5
+
6
+ class << self
7
+ def custom_model_names(namespace='SimpleAdmin')
8
+ ApplicationRecord.descendants.map do |model|
9
+ [model.name, model.name] unless model.name.include?(namespace)
10
+ end.compact
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,50 @@
1
+ module SimpleAdmin
2
+ class Entity < Base
3
+ include Helpers::BooleanHelper
4
+
5
+ boolean_fields :status
6
+
7
+ has_many :entity_fields
8
+
9
+ scope :enabled, -> { where(status: true) }
10
+
11
+ validates :model_klass_name, presence: true
12
+
13
+ before_save :label_default_value!
14
+ after_create :create_default_fields!
15
+
16
+ after_save :reload_routes! unless Rails.env.test?
17
+
18
+ class << self
19
+ def form_attributes(model_klass)
20
+ find_by(model_klass_name: model_klass.to_s).entity_fields.form.pluck(:name)
21
+ end
22
+
23
+ def resource_attributes
24
+ enabled.map do |entity|
25
+ [entity.model_klass.model_name.collection, entity.model_klass_name]
26
+ end
27
+ end
28
+ end
29
+
30
+ def model_klass
31
+ model_klass_name.constantize
32
+ end
33
+
34
+ private
35
+
36
+ def reload_routes!
37
+ Rails.application.routes_reloader.reload!
38
+ end
39
+
40
+ def label_default_value!
41
+ return if label.present?
42
+ self.label = model_klass.model_name.human.pluralize
43
+ end
44
+
45
+ def create_default_fields!
46
+ SimpleAdmin::EntityFieldType.reload_helper_methods!
47
+ SimpleAdmin::EntityField.create_number_field(name: :id, label: '#', entity: self, presentation: :collection)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,77 @@
1
+ module SimpleAdmin
2
+ class EntityField < Base
3
+ enum presentation: %i[collection form]
4
+
5
+ belongs_to :entity
6
+
7
+ has_one :entity_field_type, primary_key: :entity_field_type_id, foreign_key: :id
8
+ has_one :entity_field_setting, dependent: :destroy
9
+
10
+ accepts_nested_attributes_for :entity_field_setting, update_only: true
11
+ delegate :value, to: :entity_field_setting, allow_nil: true
12
+
13
+ validate :name_presentation_uniqueness, on: :create
14
+
15
+ scope :latest, -> { order(created_at: :asc) }
16
+ scope :labels, -> { latest.pluck(:label) }
17
+
18
+ scope :search_indexable_columns, -> { collection.where(search_indexable: true).pluck(:name) }
19
+
20
+ before_save :label_default_value!
21
+
22
+ def id_field?
23
+ name == 'id'
24
+ end
25
+
26
+ # Entity association class for field
27
+ # @example SimpleAdmin::Post
28
+ # module SimpleAdmin
29
+ # class Post < Base
30
+ # belongs_to :category, optional: true
31
+ # end
32
+ # end
33
+ #
34
+ # entity = SimpleAdmin::Entity.create(model_klass_name: SimpleAdmin::Post.to_s)
35
+ # entity_field_type = SimpleAdmin::EntityFieldType.create(name: :relation, template: 'simple_admin/fields/relation')
36
+ #
37
+ # entity_field = SimpleAdmin::EntityField.new(name: :category_id, label: 'Category',
38
+ # entity_field_type: entity_field_type, entity: entity)
39
+ # entity_field.association_klass
40
+ #
41
+ # SimpleAdmin::Category
42
+ #
43
+ # @return [ActiveRecord Class]
44
+ #
45
+ # @since 0.1.0
46
+ def association_klass
47
+ model_instance = entity.model_klass.new
48
+ association_name = name.remove('_id')
49
+
50
+ model_instance.public_send("build_#{association_name}").class
51
+ end
52
+
53
+ # Template path for field
54
+ #
55
+ # @return [String]
56
+ #
57
+ # @since 0.1.0
58
+ def template_path
59
+ "#{entity_field_type.template}/#{presentation}"
60
+ end
61
+
62
+ def already_exists?
63
+ self.class.where(name: name, presentation: presentation, entity: entity).any?
64
+ end
65
+
66
+ private
67
+
68
+ def label_default_value!
69
+ return if id_field? || label.present?
70
+ self.label = name.camelize
71
+ end
72
+
73
+ def name_presentation_uniqueness
74
+ errors.add(:name, 'already exists') if already_exists?
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,5 @@
1
+ module SimpleAdmin
2
+ class EntityFieldSetting < Base
3
+ belongs_to :entity_field
4
+ end
5
+ end
@@ -0,0 +1,79 @@
1
+ module SimpleAdmin
2
+ class EntityFieldType < Base
3
+ include Helpers::BooleanHelper
4
+
5
+ boolean_fields :inbuilt
6
+
7
+ belongs_to :entity_field, optional: true
8
+
9
+ validate :view_templates_presence, unless: :inbuilt?
10
+
11
+ after_create :initialize_helper_methods!
12
+
13
+ class << self
14
+ # Define entity fields model methods to simplify creation.
15
+ # You not need to define entity_field_type directly
16
+ # Use:
17
+ # SimpleAdmin::EntityField.create_string_field(name: :title, entity: entity, presentation: :collection)
18
+ # SimpleAdmin::EntityField.create_number_field(name: :id, entity: entity, presentation: :collection)
19
+ #
20
+ # @since 0.1.0
21
+ def build_helper_methods!
22
+ pluck(:name).each do |field_type_name|
23
+ SimpleAdmin::EntityField.define_singleton_method("create_#{field_type_name}_field") do |params|
24
+ params[:entity_field_type_id] = SimpleAdmin::EntityFieldType.find_by(name: field_type_name).to_param
25
+
26
+ create(params)
27
+ end
28
+ end
29
+ end
30
+
31
+ def reload_helper_methods!
32
+ build_helper_methods!
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def initialize_helper_methods!
39
+ self.class.build_helper_methods!
40
+ end
41
+
42
+ def view_templates_presence
43
+ validate_collection_template!
44
+ validate_form_template!
45
+ end
46
+
47
+ def validate_collection_template!
48
+ collection_template_path =
49
+ if Rails.env.test?
50
+ "spec/example_app/app/views/#{template}/_collection.*"
51
+ else
52
+ "app/views/#{template}/_collection.*"
53
+ end
54
+
55
+ unless template_exists?(collection_template_path)
56
+ errors.add(:base, 'Collection template missing')
57
+ end
58
+ end
59
+
60
+ def validate_form_template!
61
+ form_template_path =
62
+ if Rails.env.test?
63
+ "spec/example_app/app/views/#{template}/_form.*"
64
+ else
65
+ "app/views/#{template}/_form.*"
66
+ end
67
+
68
+ errors.add(:base, 'Form template missing') unless template_exists?(form_template_path)
69
+ end
70
+
71
+ def template_exists?(template_path)
72
+ !Dir.glob(template_path).empty? || !Dir.glob("#{core_path}/#{template_path}").empty?
73
+ end
74
+
75
+ def core_path
76
+ Gem.loaded_specs['simple_admin'].full_gem_path
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,5 @@
1
+ <li class="paginate_button next <%= 'disabled' if current_page.last? %>" aria-controls="DataTables_Table_1" tabindex="0" id="DataTables_Table_1_next">
2
+ <%= link_to url, remote: remote do %>
3
+ <i class="fa fa-angle-right"></i>
4
+ <% end %>
5
+ </li>
@@ -0,0 +1,3 @@
1
+ <li class="paginate_button <%= 'active' if page.current? %>" aria-controls="DataTables_Table_1" tabindex="0">
2
+ <%= link_to page, url, { remote: remote, rel: page.rel } %>
3
+ </li>