headmin 0.3.2 → 0.3.3

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +27 -23
  5. data/app/assets/images/document.docx +0 -0
  6. data/app/assets/images/document.pdf +0 -0
  7. data/app/assets/images/image.jpg +0 -0
  8. data/app/assets/images/spreadsheet.xls +0 -0
  9. data/app/assets/images/video.mp4 +0 -0
  10. data/app/assets/javascripts/headmin/controllers/table_actions_controller.js +2 -2
  11. data/app/assets/javascripts/headmin/controllers/table_controller.js +28 -13
  12. data/app/assets/javascripts/headmin/index.js +0 -4
  13. data/app/assets/javascripts/headmin.js +33 -696
  14. data/app/assets/stylesheets/headmin/form.scss +4 -4
  15. data/app/assets/stylesheets/headmin/vendor/tom-select-bootstrap.css +1 -2
  16. data/app/assets/stylesheets/headmin.css +3 -3
  17. data/app/controllers/concerns/headmin/authentication.rb +1 -1
  18. data/app/controllers/concerns/headmin/searchable.rb +1 -1
  19. data/app/controllers/concerns/headmin/sortable.rb +7 -7
  20. data/app/helpers/headmin/admin_helper.rb +1 -1
  21. data/app/helpers/headmin/bootstrap_helper.rb +2 -24
  22. data/app/helpers/headmin/documentation_helper.rb +1 -1
  23. data/app/helpers/headmin/filter_helper.rb +1 -1
  24. data/app/helpers/headmin/form_helper.rb +3 -3
  25. data/app/helpers/headmin/notification_helper.rb +21 -21
  26. data/app/helpers/headmin/request_helper.rb +3 -3
  27. data/app/models/concerns/headmin/block.rb +1 -2
  28. data/app/models/concerns/headmin/blockable.rb +1 -1
  29. data/app/models/concerns/headmin/field.rb +1 -1
  30. data/app/models/concerns/headmin/fieldable.rb +8 -8
  31. data/app/models/headmin/documentation_renderer.rb +4 -4
  32. data/app/models/headmin/form/base.rb +1 -2
  33. data/app/models/headmin/form/text.rb +5 -7
  34. data/app/models/headmin/thumbnail.rb +61 -0
  35. data/app/services/block_service.rb +53 -53
  36. data/app/views/headmin/_thumbnail.html.erb +42 -40
  37. data/app/views/headmin/dropdown/_item.html.erb +1 -1
  38. data/app/views/headmin/forms/_checkbox.html.erb +1 -1
  39. data/app/views/headmin/forms/_file.html.erb +1 -1
  40. data/app/views/headmin/forms/_repeater.html.erb +1 -1
  41. data/app/views/headmin/forms/actions/_destroy.html.erb +3 -3
  42. data/app/views/headmin/forms/fields/_group.html.erb +1 -1
  43. data/app/views/headmin/nav/item/_devise.html.erb +1 -1
  44. data/app/views/headmin/table/_actions.html.erb +1 -1
  45. data/app/views/headmin/views/devise/registrations/_edit.html.erb +2 -2
  46. data/config/initializers/customize_input_error.rb +4 -4
  47. data/lib/generators/headmin/blocks_generator.rb +8 -8
  48. data/lib/generators/headmin/devise_generator.rb +4 -4
  49. data/lib/generators/headmin/fields_generator.rb +9 -9
  50. data/lib/generators/templates/controllers/auth/confirmations_controller.rb +1 -1
  51. data/lib/generators/templates/controllers/auth/omniauth_callbacks_controller.rb +1 -1
  52. data/lib/generators/templates/controllers/auth/passwords_controller.rb +1 -1
  53. data/lib/generators/templates/controllers/auth/registrations_controller.rb +1 -1
  54. data/lib/generators/templates/controllers/auth/sessions_controller.rb +1 -1
  55. data/lib/generators/templates/controllers/auth/unlocks_controller.rb +1 -1
  56. data/lib/generators/templates/models/block.rb +1 -1
  57. data/lib/headmin/engine.rb +6 -6
  58. data/lib/headmin/version.rb +1 -1
  59. data/package.json +0 -1
  60. data/yarn.lock +1 -258
  61. metadata +9 -4
  62. data/.rubocop.yml +0 -13
@@ -27,16 +27,16 @@ input[type="search"] {
27
27
  .repeater-row {
28
28
  position: relative;
29
29
 
30
- :hover {
31
- & > .repeater-row-remove {
30
+ &:hover {
31
+ .repeater-row-remove {
32
32
  visibility: visible;
33
33
  }
34
34
 
35
- & > .repeater-row-add {
35
+ .repeater-row-add {
36
36
  visibility: visible;
37
37
  }
38
38
 
39
- & > .repeater-row-handle {
39
+ .repeater-row-handle {
40
40
  visibility: visible;
41
41
  }
42
42
  }
@@ -533,5 +533,4 @@
533
533
  .input-group > .ts-wrapper:not(:last-child) > .ts-control {
534
534
  border-top-right-radius: 0;
535
535
  border-bottom-right-radius: 0;
536
- }
537
- /*# sourceMappingURL=tom-select.bootstrap5.css.map */
536
+ }
@@ -12937,13 +12937,13 @@ input[type=search] {
12937
12937
  .repeater-row {
12938
12938
  position: relative;
12939
12939
  }
12940
- .repeater-row :hover > .repeater-row-remove {
12940
+ .repeater-row:hover .repeater-row-remove {
12941
12941
  visibility: visible;
12942
12942
  }
12943
- .repeater-row :hover > .repeater-row-add {
12943
+ .repeater-row:hover .repeater-row-add {
12944
12944
  visibility: visible;
12945
12945
  }
12946
- .repeater-row :hover > .repeater-row-handle {
12946
+ .repeater-row:hover .repeater-row-handle {
12947
12947
  visibility: visible;
12948
12948
  }
12949
12949
  .repeater-row-remove {
@@ -6,4 +6,4 @@ module Headmin
6
6
  before_action :authenticate_admin!
7
7
  end
8
8
  end
9
- end
9
+ end
@@ -9,7 +9,7 @@ module Headmin
9
9
  end
10
10
 
11
11
  def search_params
12
- @search_params ||= params[:search] && params[:search].to_s
12
+ @search_params ||= params[:search]&.to_s
13
13
  end
14
14
  end
15
15
  end
@@ -12,8 +12,8 @@ module Headmin
12
12
 
13
13
  def sort_by_params(collection)
14
14
  sort_params.each do |key, value|
15
- next unless %w(asc desc).include?(value)
16
- attribute = key.gsub('sort_', '')
15
+ next unless %w[asc desc].include?(value)
16
+ attribute = key.gsub("sort_", "")
17
17
 
18
18
  # Sort on model columns first, then check for translation columns
19
19
  if collection.attribute_names.include?(attribute.to_s)
@@ -26,19 +26,19 @@ module Headmin
26
26
 
27
27
  order_scope = "order_by_#{attribute}".to_sym
28
28
  sort_scope = "sort_by_#{attribute}".to_sym
29
- if collection.respond_to?(order_scope)
30
- collection = collection.send(order_scope, value)
29
+ collection = if collection.respond_to?(order_scope)
30
+ collection.send(order_scope, value)
31
31
  elsif collection.respond_to?(sort_scope)
32
- collection = collection.send(sort_scope, value)
32
+ collection.send(sort_scope, value)
33
33
  else
34
- collection = collection.order(column.send(value))
34
+ collection.order(column.send(value))
35
35
  end
36
36
  end
37
37
  collection
38
38
  end
39
39
 
40
40
  def sort_params
41
- params.permit!.select { |p| p.to_s.include?('sort_') }
41
+ params.permit!.select { |p| p.to_s.include?("sort_") }
42
42
  end
43
43
  end
44
44
  end
@@ -7,4 +7,4 @@ module Headmin
7
7
  include Headmin::RequestHelper
8
8
  include Headmin::DocumentationHelper
9
9
  end
10
- end
10
+ end
@@ -2,30 +2,8 @@ module Headmin
2
2
  module BootstrapHelper
3
3
  def bootstrap_icon(icon, options = {})
4
4
  tag_name = options.extract!(:tag_name).fetch(:tag_name, :i)
5
- options[:class] = ['bi', "bi-#{icon}", options.dig(:class)].compact.join(' ')
5
+ options[:class] = ["bi", "bi-#{icon}", options.dig(:class)].compact.join(" ")
6
6
  content_tag(tag_name, options) {}
7
7
  end
8
-
9
- # References
10
- # https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
11
- def bootstrap_icon_for_mime_type(mime_type, options = {})
12
- type_map = {
13
- image: %w[image/bmp image/gif image/vnd.microsoft.icon image/jpeg image/png image/svg+xml image/tiff image/webp],
14
- play: %w[video/mp4 video/mpeg video/ogg video/mp2t video/webm video/3gpp video/3gpp2],
15
- music: %w[audio/aac audio/midi audio/x-midi audio/mpeg audio/ogg audio/opus audio/wav audio/webm audio/3gpp audio/3gpp2],
16
- word: %w[application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document],
17
- ppt: %w[application/vnd.ms-powerpoint application/vnd.openxmlformats-officedocument.presentationml.presentation],
18
- excel: %w[application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet],
19
- slides: %w[application/vnd.oasis.opendocument.presentation],
20
- spreadsheet: %w[application/vnd.oasis.opendocument.spreadsheet],
21
- richtext: %w[application/vnd.oasis.opendocument.text],
22
- zip: %w[application/zip application/x-7z-compressed application/x-bzip application/x-bzip2 application/gzip application/vnd.rar],
23
- pdf: %w[application/pdf],
24
- }
25
- icon_name = type_map.find{|key, mime_types| mime_types.include?(mime_type)}.first
26
-
27
- icon = ['file', 'earmark', icon_name].compact.join('-')
28
- bootstrap_icon(icon, options)
29
- end
30
8
  end
31
- end
9
+ end
@@ -7,7 +7,7 @@ module Headmin
7
7
  between = text[/#{starts_with}(.*?)#{ends_with}/m, 1]
8
8
 
9
9
  # Remove leading whitespaces from each line
10
- between.lines.map { |line| line.sub(' ', '') }.join
10
+ between.lines.map { |line| line.sub(" ", "") }.join
11
11
  end
12
12
 
13
13
  def markdown_to_html(text)
@@ -13,4 +13,4 @@ module Headmin
13
13
  end
14
14
  end
15
15
  end
16
- end
16
+ end
@@ -5,12 +5,12 @@ module Headmin
5
5
  end
6
6
 
7
7
  def form_field_validation_id(form, name)
8
- [form.object_name, name.to_s, 'validation'].join('_').parameterize.underscore
8
+ [form.object_name, name.to_s, "validation"].join("_").parameterize.underscore
9
9
  end
10
10
 
11
11
  def form_field_validation_class(form, name)
12
12
  return nil if request.get?
13
- form.object.errors.has_key?(name) ? 'is-invalid' : 'is-valid'
13
+ form.object.errors.has_key?(name) ? "is-invalid" : "is-valid"
14
14
  end
15
15
 
16
16
  def human_attribute_name(attribute)
@@ -37,4 +37,4 @@ module Headmin
37
37
  test.join.html_safe
38
38
  end
39
39
  end
40
- end
40
+ end
@@ -2,30 +2,30 @@ module Headmin
2
2
  module NotificationHelper
3
3
  def notification_color(name)
4
4
  color = {
5
- notice: {
6
- background: 'bg-success',
7
- text: 'text-white'
8
- },
9
- error: {
10
- text: 'text-dark',
11
- background: 'bg-danger'
12
- },
13
- alert: {
14
- text: 'text-dark',
15
- background: 'bg-warning'
16
- },
17
- timedout: {
18
- text: 'text-dark',
19
- background: 'bg-warning'
20
- },
21
- fallback: {
22
- text: 'text-light',
23
- background: 'bg-info',
24
- }
5
+ notice: {
6
+ background: "bg-success",
7
+ text: "text-white"
8
+ },
9
+ error: {
10
+ text: "text-dark",
11
+ background: "bg-danger"
12
+ },
13
+ alert: {
14
+ text: "text-dark",
15
+ background: "bg-warning"
16
+ },
17
+ timedout: {
18
+ text: "text-dark",
19
+ background: "bg-warning"
20
+ },
21
+ fallback: {
22
+ text: "text-light",
23
+ background: "bg-info"
24
+ }
25
25
  }
26
26
 
27
27
  name = name.to_sym
28
28
  color.key?(name) ? color[name] : color[:fallback]
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -3,7 +3,7 @@ module Headmin
3
3
  def current_url?(url)
4
4
  uri = URI(url)
5
5
  path = uri.path
6
- query_string = uri.query || ''
6
+ query_string = uri.query || ""
7
7
  matches_path = request.path.include?(path)
8
8
  matches_query = request.query_string.include?(query_string)
9
9
  matches_path && matches_query
@@ -28,7 +28,7 @@ module Headmin
28
28
  end
29
29
 
30
30
  def is_sort_param_key?(key)
31
- key.to_s.include?('sort_')
31
+ key.to_s.include?("sort_")
32
32
  end
33
33
  end
34
- end
34
+ end
@@ -3,9 +3,8 @@ module Headmin
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
-
7
6
  # Associations
8
7
  belongs_to :blockable, polymorphic: true, optional: true, touch: true
9
8
  end
10
9
  end
11
- end
10
+ end
@@ -7,4 +7,4 @@ module Headmin
7
7
  accepts_nested_attributes_for :blocks, allow_destroy: true
8
8
  end
9
9
  end
10
- end
10
+ end
@@ -14,4 +14,4 @@ module Headmin
14
14
  has_one_attached :file
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -24,27 +24,27 @@ module Headmin
24
24
  when Hash
25
25
  fields.build(
26
26
  name: key,
27
- field_type: 'group',
27
+ field_type: "group",
28
28
  fields: parse_fields_hash(value)
29
29
  )
30
30
  when Array
31
31
  fields.build(
32
32
  name: key,
33
- field_type: 'list',
33
+ field_type: "list",
34
34
  fields: value.map do |item|
35
- fields.new(name: 'item', field_type: 'group', fields: parse_fields_hash(item))
35
+ fields.new(name: "item", field_type: "group", fields: parse_fields_hash(item))
36
36
  end
37
37
  )
38
38
  when String
39
39
  fields.build(
40
40
  name: key,
41
- field_type: 'text',
41
+ field_type: "text",
42
42
  value: value
43
43
  )
44
44
  else
45
45
  fields.build(
46
46
  name: key,
47
- field_type: 'file',
47
+ field_type: "file",
48
48
  file: value
49
49
  )
50
50
  end
@@ -52,7 +52,7 @@ module Headmin
52
52
  end
53
53
 
54
54
  def parse_hash_tree(hash_tree)
55
- Hash[hash_tree.map do |field, children|
55
+ hash_tree.map do |field, children|
56
56
  case field.field_type.to_sym
57
57
  when :group
58
58
  children = children.any? ? children : field.hash_tree
@@ -67,8 +67,8 @@ module Headmin
67
67
  else
68
68
  [field.name, field.value]
69
69
  end
70
- end]
70
+ end.to_h
71
71
  end
72
72
  end
73
73
  end
74
- end
74
+ end
@@ -2,7 +2,7 @@ module Headmin
2
2
  class DocumentationRenderer < Redcarpet::Render::HTML
3
3
  def block_code(code, language)
4
4
  if language == "erbx"
5
- "<div class=\"card mb-3\"><div class=\"card-body\">#{render_code(code)}</div><div class=\"card-footer\"><pre><code class=\"h-syntax\">#{highlight_syntax(code, 'erb')}</code></pre></div></div>"
5
+ "<div class=\"card mb-3\"><div class=\"card-body\">#{render_code(code)}</div><div class=\"card-footer\"><pre><code class=\"h-syntax\">#{highlight_syntax(code, "erb")}</code></pre></div></div>"
6
6
  else
7
7
  "<pre><code class=\"h-syntax\">#{highlight_syntax(code, language)}</code></pre></div>"
8
8
  end
@@ -22,9 +22,9 @@ module Headmin
22
22
 
23
23
  def render_code(code)
24
24
  ApplicationController.renderer.new(
25
- 'action_dispatch.request.path_parameters' => {
26
- controller: 'main',
27
- action: 'index'
25
+ "action_dispatch.request.path_parameters" => {
26
+ controller: "main",
27
+ action: "index"
28
28
  }
29
29
  ).render(inline: code)
30
30
  end
@@ -60,7 +60,6 @@ module Headmin
60
60
 
61
61
  def append
62
62
  @local_assigns[:append]
63
-
64
63
  end
65
64
 
66
65
  def prepend
@@ -76,4 +75,4 @@ module Headmin
76
75
  end
77
76
  end
78
77
  end
79
- end
78
+ end
@@ -19,18 +19,16 @@ module Headmin
19
19
  end
20
20
 
21
21
  def options
22
- option_keys = %i(aria autocomplete autofocus data disabled id maxlength minlength list pattern placeholder readonly required spellcheck size value)
22
+ option_keys = %i[aria autocomplete autofocus data disabled id maxlength minlength list pattern placeholder readonly required spellcheck size value]
23
23
  @local_assigns.slice(*option_keys).merge(
24
- aria: { describedby: form_field_validation_id(form, attribute) },
24
+ aria: {describedby: form_field_validation_id(form, attribute)},
25
25
  class: ["form-control", form_field_validation_class(form, attribute)].join(" "),
26
26
  list: @local_assigns[:list] ? "#{attribute}_list" : nil,
27
27
  placeholder: placeholder
28
28
  )
29
29
  end
30
30
 
31
- def local_assigns
32
- @local_assigns
33
- end
31
+ attr_reader :local_assigns
34
32
 
35
33
  def form_field_valid?(form, name)
36
34
  return unless form.object
@@ -46,8 +44,8 @@ module Headmin
46
44
 
47
45
  def form_field_validation_class(form, name)
48
46
  return nil if @request.get?
49
- form.object.errors.has_key?(name) ? 'is-invalid' : 'is-valid'
47
+ form.object.errors.has_key?(name) ? "is-invalid" : "is-valid"
50
48
  end
51
49
  end
52
50
  end
53
- end
51
+ end
@@ -0,0 +1,61 @@
1
+ module Headmin
2
+ class Thumbnail
3
+ def initialize(local_assigns)
4
+ @local_assigns = local_assigns
5
+ end
6
+
7
+ def class_names
8
+ class_names = [@local_assigns[:class]]
9
+ class_names << "img-thumbnail h-thumbnail"
10
+ class_names.join(" ")
11
+ end
12
+
13
+ def width
14
+ @local_assigns[:width] || 150
15
+ end
16
+
17
+ def height
18
+ @local_assigns[:height] || 150
19
+ end
20
+
21
+ def src
22
+ @local_assigns[:src]
23
+ end
24
+
25
+ def mime_type
26
+ if src
27
+ stripped_path = URI.parse(src).path
28
+ extension = File.extname(stripped_path)
29
+ Rack::Mime.mime_type(extension)
30
+ end
31
+ end
32
+
33
+ def image?
34
+ mime_type&.match?(/^image/)
35
+ end
36
+
37
+ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
38
+ def icon_name
39
+ type_map = {
40
+ image: %w[image/bmp image/gif image/vnd.microsoft.icon image/jpeg image/png image/svg+xml image/tiff image/webp],
41
+ play: %w[video/mp4 video/mpeg video/ogg video/mp2t video/webm video/3gpp video/3gpp2],
42
+ music: %w[audio/aac audio/midi audio/x-midi audio/mpeg audio/ogg audio/opus audio/wav audio/webm audio/3gpp audio/3gpp2],
43
+ word: %w[application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document],
44
+ ppt: %w[application/vnd.ms-powerpoint application/vnd.openxmlformats-officedocument.presentationml.presentation],
45
+ excel: %w[application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet],
46
+ slides: %w[application/vnd.oasis.opendocument.presentation],
47
+ spreadsheet: %w[application/vnd.oasis.opendocument.spreadsheet],
48
+ richtext: %w[application/vnd.oasis.opendocument.text],
49
+ zip: %w[application/zip application/x-7z-compressed application/x-bzip application/x-bzip2 application/gzip application/vnd.rar],
50
+ pdf: %w[application/pdf]
51
+ }
52
+
53
+ type = type_map.find { |key, mime_types| mime_types.include?(mime_type) }
54
+ if type
55
+ ["file", "earmark", type.first].compact.join("-")
56
+ else
57
+ "question"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,72 +1,72 @@
1
1
  class BlockService
2
- def self.block_names(path:)
3
- form_views(path: path).map do |view|
4
- view_name(view)
2
+ class << self
3
+ def block_names(path:)
4
+ form_views(path: path).map do |view|
5
+ view_name(view)
6
+ end
5
7
  end
6
- end
7
8
 
8
- def self.form_view(name, path:)
9
- view_by_name(name, form_view_paths(path))
10
- end
9
+ def form_view(name, path:)
10
+ view_by_name(name, form_view_paths(path))
11
+ end
11
12
 
12
- def self.frontend_view(name, path:)
13
- view_by_name(name, frontend_view_paths(path))
14
- end
13
+ def frontend_view(name, path:)
14
+ view_by_name(name, frontend_view_paths(path))
15
+ end
15
16
 
16
- def self.frontend_views(path:)
17
- views(frontend_view_paths(path))
18
- end
17
+ def frontend_views(path:)
18
+ views(frontend_view_paths(path))
19
+ end
19
20
 
20
- def self.form_views(path:)
21
- views(form_view_paths(path))
22
- end
21
+ def form_views(path:)
22
+ views(form_view_paths(path))
23
+ end
23
24
 
24
- def self.view_name(view)
25
- filename = File.basename(view.split('.')[0])
25
+ def view_name(view)
26
+ filename = File.basename(view.split(".")[0])
26
27
 
27
- # Removes leading _ if exists
28
- filename.sub(/^_/, '')
29
- end
28
+ # Removes leading _ if exists
29
+ filename.sub(/^_/, "")
30
+ end
30
31
 
31
- private
32
+ # Looks for a block view by its name.
33
+ #
34
+ # It will first search in a specified path and will fallback to the default path
35
+ # An exception will be raised if the view is nowhere to be found
36
+ def view_by_name(name, paths)
37
+ views = views(paths)
38
+ view = views.find { |view| view.include?("/_#{name}.html.erb") }
32
39
 
33
- # Looks for a block view by its name.
34
- #
35
- # It will first search in a specified path and will fallback to the default path
36
- # An exception will be raised if the view is nowhere to be found
37
- def self.view_by_name(name, paths)
38
- views = views(paths)
39
- view = views.find { |view| view.include?("/_#{name}.html.erb") }
40
+ unless view
41
+ prefixes = paths.map { |path| path.split("app/views/").last }
42
+ raise ActionView::MissingTemplate.new(paths, name, prefixes, true, "headmin") unless view
43
+ end
40
44
 
41
- unless view
42
- prefixes = paths.map { |path| path.split('app/views/').last }
43
- raise ActionView::MissingTemplate.new(paths, name, prefixes, true, "headmin") unless view
45
+ view
44
46
  end
45
47
 
46
- view
47
- end
48
-
49
- def self.form_view_paths(path)
50
- [app_view_path(path), app_view_path('admin/blocks')].uniq
51
- end
48
+ def form_view_paths(path)
49
+ [app_view_path(path), app_view_path("admin/blocks")].uniq
50
+ end
52
51
 
53
- def self.frontend_view_paths(path)
54
- [app_view_path(path), app_view_path('website/blocks')].uniq
55
- end
52
+ def frontend_view_paths(path)
53
+ [app_view_path(path), app_view_path("website/blocks")].uniq
54
+ end
56
55
 
57
- def self.app_view_path(path)
58
- base_path = 'app/views'
59
- [base_path, path].join('/')
60
- end
56
+ def app_view_path(path)
57
+ base_path = "app/views"
58
+ [base_path, path].join("/")
59
+ end
61
60
 
62
- def self.views(paths)
63
- paths.map { |path| views_in_path(path) }.flatten
64
- end
61
+ def views(paths)
62
+ paths.map { |path| views_in_path(path) }.flatten
63
+ end
65
64
 
66
- def self.views_in_path(path)
67
- files = Dir.glob("#{path}/*")
68
- files.map do |file|
69
- file.split('app/views/').last
65
+ def views_in_path(path)
66
+ files = Dir.glob("#{path}/*")
67
+ files.map do |file|
68
+ file.split("app/views/").last
69
+ end
70
70
  end
71
71
  end
72
- end
72
+ end