avo 0.2.3 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of avo might be problematic. Click here for more details.

Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +52 -48
  3. data/Gemfile.lock +26 -2
  4. data/README.md +30 -9
  5. data/app/controllers/avo/application_controller.rb +34 -1
  6. data/app/controllers/avo/filters_controller.rb +19 -0
  7. data/app/controllers/avo/relations_controller.rb +34 -0
  8. data/app/controllers/avo/resource_overview_controller.rb +15 -7
  9. data/app/controllers/avo/resources_controller.rb +71 -145
  10. data/app/controllers/avo/search_controller.rb +55 -0
  11. data/app/helpers/avo/application_helper.rb +6 -2
  12. data/app/views/layouts/avo/_javascript.html.erb +3 -0
  13. data/app/views/layouts/avo/_translations.html.erb +5 -0
  14. data/app/views/layouts/avo/application.html.erb +40 -18
  15. data/avo.gemspec +5 -2
  16. data/config/credentials.yml.enc +1 -0
  17. data/config/routes.rb +11 -7
  18. data/lib/avo.rb +4 -0
  19. data/lib/avo/app/action.rb +8 -5
  20. data/lib/avo/app/app.rb +35 -28
  21. data/lib/avo/app/fields/belongs_to.rb +2 -2
  22. data/lib/avo/app/fields/code_field.rb +2 -0
  23. data/lib/avo/app/fields/country_field.rb +1 -1
  24. data/lib/avo/app/fields/field.rb +3 -1
  25. data/lib/avo/app/fields/field_extensions/visible_in_different_views.rb +4 -0
  26. data/lib/avo/app/fields/has_and_belongs_to_many.rb +1 -0
  27. data/lib/avo/app/fields/has_many.rb +1 -0
  28. data/lib/avo/app/fields/has_one.rb +2 -2
  29. data/lib/avo/app/fields/id_field.rb +4 -4
  30. data/lib/avo/app/fields/markdown_field.rb +27 -0
  31. data/lib/avo/app/fields/password_field.rb +3 -1
  32. data/lib/avo/app/fields/select_field.rb +1 -1
  33. data/lib/avo/app/licensing/community_license.rb +4 -0
  34. data/lib/avo/app/licensing/hq.rb +86 -0
  35. data/lib/avo/app/licensing/license.rb +48 -0
  36. data/lib/avo/app/licensing/license_manager.rb +25 -0
  37. data/lib/avo/app/licensing/null_license.rb +12 -0
  38. data/lib/avo/app/licensing/pro_license.rb +9 -0
  39. data/lib/avo/app/resource.rb +49 -18
  40. data/lib/avo/app/services/authorization_service.rb +40 -0
  41. data/lib/avo/configuration.rb +28 -2
  42. data/lib/avo/engine.rb +7 -7
  43. data/lib/avo/version.rb +1 -1
  44. data/lib/generators/avo/install_generator.rb +2 -1
  45. data/lib/generators/avo/templates/{initializer.rb → initializer/avo.rb} +2 -0
  46. data/lib/generators/avo/templates/locales/avo.en.yml +60 -0
  47. data/lib/generators/avo/templates/views/_scripts.html.erb +0 -0
  48. data/public/avo-packs/css/application-2f609d81.css +3 -0
  49. data/public/avo-packs/css/application-2f609d81.css.br +0 -0
  50. data/public/avo-packs/css/application-2f609d81.css.gz +0 -0
  51. data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js +3 -0
  52. data/public/avo-packs/js/{application-9a0dde96ad9918852965.js.LICENSE.txt → application-84e2d573c3c15df1fb7b.js.LICENSE.txt} +0 -0
  53. data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.br +0 -0
  54. data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.gz +0 -0
  55. data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.map +1 -0
  56. data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.map.br +0 -0
  57. data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.map.gz +0 -0
  58. data/public/avo-packs/manifest.json +13 -6
  59. data/public/avo-packs/manifest.json.br +0 -0
  60. data/public/avo-packs/manifest.json.gz +0 -0
  61. data/public/avo-packs/media/font/fontello-068ca2b3.ttf +0 -0
  62. data/public/avo-packs/media/font/fontello-068ca2b3.ttf.br +0 -0
  63. data/public/avo-packs/media/font/fontello-068ca2b3.ttf.gz +0 -0
  64. data/public/avo-packs/media/font/fontello-8d4a4e6f.woff2 +0 -0
  65. data/public/avo-packs/media/font/fontello-9354499c.svg +72 -0
  66. data/public/avo-packs/media/font/fontello-9354499c.svg.br +0 -0
  67. data/public/avo-packs/media/font/fontello-9354499c.svg.gz +0 -0
  68. data/public/avo-packs/media/font/fontello-a782baa8.woff +0 -0
  69. data/public/avo-packs/media/font/fontello-e73a0647.eot +0 -0
  70. data/public/avo-packs/media/font/fontello-e73a0647.eot.br +0 -0
  71. data/public/avo-packs/media/font/fontello-e73a0647.eot.gz +0 -0
  72. data/public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg +1 -0
  73. data/public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg.br +0 -0
  74. data/public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg.gz +0 -0
  75. data/public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg +1 -0
  76. data/public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg.br +0 -0
  77. data/public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg.gz +0 -0
  78. metadata +90 -22
  79. data/public/avo-packs/css/application-5dc4dd78.css +0 -3
  80. data/public/avo-packs/css/application-5dc4dd78.css.br +0 -0
  81. data/public/avo-packs/css/application-5dc4dd78.css.gz +0 -0
  82. data/public/avo-packs/js/application-9a0dde96ad9918852965.js +0 -3
  83. data/public/avo-packs/js/application-9a0dde96ad9918852965.js.br +0 -0
  84. data/public/avo-packs/js/application-9a0dde96ad9918852965.js.gz +0 -0
  85. data/public/avo-packs/js/application-9a0dde96ad9918852965.js.map +0 -1
  86. data/public/avo-packs/js/application-9a0dde96ad9918852965.js.map.br +0 -0
  87. data/public/avo-packs/js/application-9a0dde96ad9918852965.js.map.gz +0 -0
@@ -0,0 +1,55 @@
1
+ require_dependency 'avo/application_controller'
2
+
3
+ module Avo
4
+ class SearchController < ApplicationController
5
+ before_action :authorize_user
6
+
7
+ def index
8
+ resources = []
9
+
10
+ resources_to_search_through = App.get_resources
11
+ .select { |resource| resource.search.present? }
12
+ .select { |resource| AuthorizationService.authorize_action current_user, resource.model, 'index' }
13
+ .each do |resource_model|
14
+ found_resources = add_link_to_search_results(search_resource(resource_model), resource_model)
15
+ resources.push({
16
+ label: resource_model.name,
17
+ resources: found_resources
18
+ })
19
+ end
20
+
21
+ render json: {
22
+ resources: resources
23
+ }
24
+ end
25
+
26
+ def resource
27
+ render json: {
28
+ resources: add_link_to_search_results(search_resource(avo_resource), avo_resource)
29
+ }
30
+ end
31
+
32
+ private
33
+ def add_link_to_search_results(resources, avo_resource)
34
+ resources.map do |model|
35
+ {
36
+ id: model.id,
37
+ search_label: model.send(avo_resource.title),
38
+ link: "/resources/#{model.class.to_s.singularize.underscore}/#{model.id}",
39
+ }
40
+ end
41
+ end
42
+
43
+ def search_resource(avo_resource)
44
+ avo_resource.query_search(query: params[:q], via_resource_name: params[:via_resource_name], via_resource_id: params[:via_resource_id], user: current_user)
45
+ end
46
+
47
+ def authorize_user
48
+ return if params[:action] == 'index'
49
+
50
+ action = params[:action] == 'resource' ? :index : params[:action]
51
+
52
+ return render_unauthorized unless AuthorizationService::authorize_action current_user, avo_resource.model, action
53
+ end
54
+ end
55
+ end
@@ -10,12 +10,16 @@ module Avo
10
10
  render partial: 'vendor/avo/partials/logo' rescue render partial: 'partials/logo'
11
11
  end
12
12
 
13
+ def render_header
14
+ render partial: 'vendor/avo/partials/header' rescue render partial: 'partials/header'
15
+ end
16
+
13
17
  def render_footer
14
18
  render partial: 'vendor/avo/partials/footer' rescue render partial: 'partials/footer'
15
19
  end
16
20
 
17
- def render_header
18
- render partial: 'vendor/avo/partials/header' rescue render partial: 'partials/header'
21
+ def render_scripts
22
+ render partial: 'vendor/avo/partials/scripts' rescue ''
19
23
  end
20
24
  end
21
25
  end
@@ -1,5 +1,8 @@
1
1
  <script>
2
2
  var rootPath = '<%= Avo.configuration.root_path %>';
3
3
  var timezone = '<%= Avo.configuration.timezone %>';
4
+ var locale = '<%= Avo.configuration.locale %>';
4
5
  var defaultViewType = '<%= Avo.configuration.default_view_type %>';
6
+ var license = <%= Avo::App.license.properties.to_json.html_safe %>;
7
+ var avoResources = <%= Avo::App.get_available_resources(current_user).as_json.html_safe %>;
5
8
  </script>
@@ -0,0 +1,5 @@
1
+ <script>
2
+ I18n.defaultLocale = 'en';
3
+ I18n.locale = "<%= Avo.configuration.language_code %>";
4
+ </script>
5
+ <%= javascript_include_tag 'translations', skip_pipeline: true %>
@@ -8,32 +8,54 @@
8
8
 
9
9
  <%= javascript_pack_tag 'application' %>
10
10
  <%= stylesheet_pack_tag 'application', media: 'all' %>
11
+ <%= render partial: 'layouts/avo/translations' %>
11
12
  <link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&display=swap" rel="stylesheet">
12
13
  </head>
14
+
13
15
  <body class="bg-gray-200">
14
16
 
15
17
  <div id="app" class="flex min-h-screen flex-row h-full">
16
- <application-sidebar :resources='<%= Avo::App.get_resources_navigation.as_json.html_safe %>'>
17
- <%= render_logo %>
18
- </application-sidebar>
19
-
20
- <div class="flex-1 h-full overflow-auto">
21
- <div class="relative bg-white p-2 shadow-md h-16 w-full flex items-center z-40">
22
- <div class="ml-6">
23
- <%= render_header %>
24
- </div>
25
- <div class="flex-1 flex justify-center">
26
- <div class="w-64">
27
- <resources-search :global="true">
18
+ <app-layout class="flex flex-1 w-full"
19
+ :router-key="routerKey"
20
+ :layout="layout"
21
+ inline-template
22
+ >
23
+ <div>
24
+ <application-sidebar v-if="layout !== 'blank'">
25
+ <template #logo>
26
+ <%= render_logo %>
27
+ </template>
28
+ <template #licensing>
29
+ <license-warnings></license-warnings>
30
+ </template>
31
+ </application-sidebar>
32
+
33
+ <div class="flex-1 h-full overflow-auto">
34
+ <div class="relative bg-white p-2 shadow-md h-16 w-full flex items-center z-50" v-if="layout !== 'blank'">
35
+ <div class="ml-6">
36
+ <%= render_header %>
37
+ </div>
38
+ <div class="flex-1 flex justify-center">
39
+ <div class="w-64">
40
+ <resources-search :global="true">
41
+ </div>
42
+ </div>
28
43
  </div>
29
- </div>
30
- </div>
31
44
 
32
- <div class="content p-8">
33
- <%= yield %>
34
- <%= render_footer %>
45
+ <div v-if="layout === 'blank'" class="h-full w-full flex justify-center items-center">
46
+ <%= yield %>
47
+ </div>
48
+
49
+ <div class="content p-8" v-else>
50
+ <%= yield %>
51
+ <%= render_footer %>
52
+ </div>
53
+ </div>
35
54
  </div>
36
- </div>
55
+ </app-layout>
37
56
  </div>
57
+
58
+ <%= render_scripts %>
59
+
38
60
  </body>
39
61
  </html>
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.name = 'avo'
9
9
  spec.version = Avo::VERSION
10
10
  spec.authors = ['Adrian Marin', 'Mihai Marin']
11
- spec.email = ['adrian@avohq.io']
11
+ spec.email = ['avo@avohq.io']
12
12
  spec.homepage = 'https://avohq.io'
13
13
  spec.summary = 'Configuration-based, no-maintenance, extendable Ruby on Rails admin.'
14
14
  spec.description = 'Avo is a beautiful next-generation framework that empowers you, the developer, to create fantastic admin panels for your Ruby on Rails apps with the flexibility to fit your needs as you grow.'
@@ -32,10 +32,13 @@ Gem::Specification.new do |spec|
32
32
  spec.files = Dir['{bin,app,config,db,lib,public}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.md', 'avo.gemspec', 'Gemfile', 'Gemfile.lock']
33
33
  .reject { |file| file.start_with? 'app/frontend' }
34
34
 
35
- spec.add_dependency 'rails', '~> 6.0.2', '>= 6.0.2.1'
35
+ spec.add_dependency 'rails', '>= 6.0'
36
36
  spec.add_dependency 'kaminari'
37
37
  spec.add_dependency 'zeitwerk'
38
38
  spec.add_dependency 'inline_svg'
39
39
  spec.add_dependency 'webpacker'
40
40
  spec.add_dependency 'countries'
41
+ spec.add_dependency 'pundit'
42
+ spec.add_dependency 'httparty'
43
+ spec.add_dependency 'i18n-js'
41
44
  end
@@ -0,0 +1 @@
1
+ u5m9Je6F3j/LCnOwcN7cXW37M63Bs0KNZC1fHRObWx4YQkV9DJl1k9H9+mlvV3irAC7NZB9H0BExhxquReVe2N0v6s3E3EvOWY8wfZhFONJpK8V0qerYJIhJvCOOPv0hfS/HQdcvUQx/i1faXEgr8QVR7nGVBHUzulwgab0lUBSAV0jjEbT6o+amTojFudelgtw0zmlZW9JL7OZ/IwZ7zxbi8/yoWB52lU4VKOxZV7AEWAVDzL/0ZogLRG12BsTSmqC0jS5ocdnOgV0X7oNeYL9HINqLLM5suBB+BOf3xL6vgngu7UDRAAQ/mN2TDGsvklF8bwVz0dDVQ0RuvdeQ9TWEeM75hhzGKG6wPKBjh4ebrKp7g9TT76F6omLe/hG30MbohGxaLVHIJjyJixfKlLlYwdNWeOjXwYsn--7CEWrUIlraWa8R0S--ia1zVj/2AXISMmbinw6S7g==
@@ -1,20 +1,24 @@
1
1
  Avo::Engine.routes.draw do
2
2
  root 'home#index'
3
3
 
4
- get '/avo-api/search', to: 'resources#search'
5
- get '/avo-api/:resource_name/search', to: 'resources#search'
6
- get '/avo-api/:resource_name', to: 'resources#index'
7
- get '/avo-api/:resource_name/filters', to: 'resources#filters'
4
+ get '/avo-api/:resource_name/filters', to: 'filters#index'
5
+
8
6
  get '/avo-api/:resource_name/actions', to: 'actions#index'
9
7
  post '/avo-api/:resource_name/actions', to: 'actions#handle'
8
+
9
+ get '/avo-api/search', to: 'search#index'
10
+ get '/avo-api/:resource_name/search', to: 'search#resource'
11
+
12
+ get '/avo-api/:resource_name', to: 'resources#index'
10
13
  post '/avo-api/:resource_name', to: 'resources#create'
11
- get '/avo-api/:resource_name/fields', to: 'resources#fields'
14
+ get '/avo-api/:resource_name/new', to: 'resources#new'
12
15
  get '/avo-api/:resource_name/:id', to: 'resources#show'
13
16
  get '/avo-api/:resource_name/:id/edit', to: 'resources#edit'
14
17
  put '/avo-api/:resource_name/:id', to: 'resources#update'
15
18
  delete '/avo-api/:resource_name/:id', to: 'resources#destroy'
16
- post '/avo-api/:resource_name/:id/attach/:attachment_name/:attachment_id', to: 'resources#attach'
17
- post '/avo-api/:resource_name/:id/detach/:attachment_name/:attachment_id', to: 'resources#detach'
19
+
20
+ post '/avo-api/:resource_name/:id/attach/:attachment_name/:attachment_id', to: 'relations#attach'
21
+ post '/avo-api/:resource_name/:id/detach/:attachment_name/:attachment_id', to: 'relations#detach'
18
22
 
19
23
  # Tools
20
24
  get '/avo-tools/resource-overview', to: 'resource_overview#index'
data/lib/avo.rb CHANGED
@@ -11,8 +11,12 @@ require_relative 'avo/app/filters/select_filter'
11
11
 
12
12
  require_relative 'avo/app/resource'
13
13
 
14
+ require_relative 'avo/app/licensing/license_manager'
15
+
14
16
  module Avo
15
17
  ROOT_PATH = Pathname.new(File.join(__dir__, '..'))
18
+ IN_DEVELOPMENT = ENV['AVO_IN_DEVELOPMENT'] == '1'
19
+ PACKED = !IN_DEVELOPMENT
16
20
 
17
21
  class << self
18
22
  def webpacker
@@ -15,6 +15,7 @@ module Avo
15
15
  # filename: String
16
16
  # }
17
17
  attr_accessor :response
18
+ attr_accessor :no_confirmation
18
19
 
19
20
  @@default = nil
20
21
 
@@ -37,15 +38,16 @@ module Avo
37
38
 
38
39
  def initialize
39
40
  @name ||= name
40
- @message ||= 'Are you sure you want to run this action?'
41
+ @message ||= I18n.t('avo.are_you_sure_you_want_to_run_this_option')
41
42
  @default ||= ''
42
43
  @fields ||= []
43
- @confirm_text = 'Run'
44
- @cancel_text = 'Cancel'
44
+ @confirm_text = I18n.t('avo.run')
45
+ @cancel_text = I18n.t('avo.cancel')
45
46
  @response ||= {}
46
47
  @response[:message_type] ||= :success
47
- @response[:message] ||= 'Action ran successfully!'
48
+ @response[:message] ||= I18n.t('avo.action_ran_successfully')
48
49
  @theme ||= 'success'
50
+ @no_confirmation ||= false
49
51
  end
50
52
 
51
53
  def render_response(model, resource)
@@ -61,6 +63,7 @@ module Avo
61
63
  cancel_text: cancel_text,
62
64
  default: default,
63
65
  action_class: self.class.to_s,
66
+ no_confirmation: no_confirmation,
64
67
  }
65
68
  end
66
69
 
@@ -87,7 +90,7 @@ module Avo
87
90
  end
88
91
 
89
92
  def name
90
- self.class.name.demodulize.underscore.humanize
93
+ self.class.name.demodulize.underscore.humanize(keep_id_suffix: true)
91
94
  end
92
95
 
93
96
  def succeed(text)
@@ -4,37 +4,47 @@ require_relative 'filters/select_filter'
4
4
  require_relative 'filters/boolean_filter'
5
5
  require_relative 'resource'
6
6
  require_relative 'tool'
7
+ require_relative 'services/authorization_service'
7
8
 
8
9
  module Avo
9
10
  class App
10
11
  @@app = {
11
12
  root_path: '',
12
- tools: [],
13
- tool_classes: [],
14
13
  resources: [],
15
14
  field_names: {},
15
+ cache_store: nil
16
16
  }
17
+ @@license = nil
17
18
 
18
19
  class << self
19
- def init
20
+ def boot
20
21
  @@app[:root_path] = Pathname.new(File.join(__dir__, '..', '..'))
21
- # get_tools
22
- # init_tools
23
22
  init_fields
23
+ I18n.locale = Avo.configuration.language_code
24
+
25
+ if Rails.cache.class == ActiveSupport::Cache::NullStore
26
+ @@app[:cache_store] ||= ActiveSupport::Cache::MemoryStore.new
27
+ else
28
+ @@app[:cache_store] = Rails.cache
29
+ end
30
+ end
31
+
32
+ def init(current_request = nil)
24
33
  init_resources
34
+ @@license = LicenseManager.new(HQ.new(current_request).response).license
25
35
  end
26
36
 
27
37
  def app
28
38
  @@app
29
39
  end
30
40
 
31
- # def tools
32
- # @@app[:tools]
33
- # end
41
+ def license
42
+ @@license
43
+ end
34
44
 
35
- # def get_tools
36
- # @@app[:tool_classes] = ToolsManager.get_tools
37
- # end
45
+ def cache_store
46
+ @@app[:cache_store]
47
+ end
38
48
 
39
49
  # This method will take all fields available in the Avo::Fields namespace and create a method for them.
40
50
  #
@@ -129,23 +139,20 @@ module Avo
129
139
  name.to_s.camelize.singularize
130
140
  end
131
141
 
132
- # def init_tools
133
- # @@app[:tool_classes].each do |tool_class|
134
- # @@app[:tools].push tool_class.new
135
- # end
136
- # end
137
-
138
- # def render_navigation
139
- # navigation = []
140
- # @@app[:tools].each do |tool|
141
- # navigation.push(tool.render_navigation) if tool.class.method_defined?(:render_navigation)
142
- # end
143
-
144
- # navigation.join('')
145
- # end
146
-
147
- def get_resources_navigation
148
- App.get_resources.map { |resource| { label: resource.resource_name_plural.humanize, resource_name: resource.url.pluralize } }.to_json.to_s.html_safe
142
+ def get_available_resources(user)
143
+ App.get_resources
144
+ .select { |resource| AuthorizationService::authorize user, resource.model, Avo.configuration.authorization_methods.stringify_keys['index'] }
145
+ .map do |resource|
146
+ {
147
+ label: resource.plural_name.humanize(keep_id_suffix: true),
148
+ resource_name: resource.url.pluralize,
149
+ translation_key: resource.translation_key
150
+ }
151
+ end
152
+ .reject { |i| i.blank? }
153
+ .to_json
154
+ .to_s
155
+ .html_safe
149
156
  end
150
157
  end
151
158
  end
@@ -7,7 +7,7 @@ module Avo
7
7
  def initialize(name, **args, &block)
8
8
  @defaults = {
9
9
  component: 'belongs-to-field',
10
- placeholder: "Choose #{name.downcase}",
10
+ placeholder: I18n.t('avo.choose_an_option')
11
11
  }
12
12
 
13
13
  @searchable = args[:searchable] == true ? true : false
@@ -49,7 +49,7 @@ module Avo
49
49
  end
50
50
  end
51
51
 
52
- fields[:resource_name_plural] = target_resource.resource_name_plural
52
+ fields[:plural_name] = target_resource.plural_name
53
53
 
54
54
  fields
55
55
  end
@@ -12,12 +12,14 @@ module Avo
12
12
 
13
13
  @language = args[:language].present? ? args[:language].to_s : 'javascript'
14
14
  @theme = args[:theme].present? ? args[:theme].to_s : 'material-darker'
15
+ @height = args[:height].present? ? args[:height].to_s : 'auto'
15
16
  end
16
17
 
17
18
  def hydrate_field(fields, model, resource, view)
18
19
  {
19
20
  language: @language,
20
21
  theme: @theme,
22
+ height: @height,
21
23
  }
22
24
  end
23
25
  end
@@ -5,7 +5,7 @@ module Avo
5
5
  @defaults = {
6
6
  sortable: true,
7
7
  component: 'country-field',
8
- placeholder: 'Choose a country',
8
+ placeholder: I18n.t('avo.choose_a_country'),
9
9
  }
10
10
 
11
11
  super(name, **args, &block)
@@ -9,6 +9,7 @@ module Avo
9
9
 
10
10
  attr_accessor :id
11
11
  attr_accessor :name
12
+ attr_accessor :translation_key
12
13
  attr_accessor :component
13
14
  attr_accessor :updatable
14
15
  attr_accessor :sortable
@@ -35,7 +36,8 @@ module Avo
35
36
  # The field properties as a hash {property: default_value}
36
37
  @field_properties = {
37
38
  id: id,
38
- name: id.to_s.humanize,
39
+ name: id.to_s.humanize(keep_id_suffix: true),
40
+ translation_key: nil,
39
41
  block: block,
40
42
  component: 'field',
41
43
  required: false,
@@ -15,12 +15,16 @@ module Avo
15
15
  end
16
16
 
17
17
  def show_on(*where)
18
+ return show_on_all if where.include? :all
19
+
18
20
  normalize_views(where).flatten.each do |view|
19
21
  show_on_view view
20
22
  end
21
23
  end
22
24
 
23
25
  def hide_on(*where)
26
+ return hide_on_all if where.include? :all
27
+
24
28
  normalize_views(where).flatten.each do |view|
25
29
  hide_on_view view
26
30
  end