avo 2.13.2.pre.2 → 2.13.3.pre.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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +5 -1
  3. data/app/assets/stylesheets/avo.css +1 -1
  4. data/app/assets/stylesheets/css/fields/progress.css +3 -3
  5. data/app/assets/stylesheets/css/pagination.css +4 -0
  6. data/app/assets/stylesheets/css/search.css +1 -1
  7. data/app/assets/stylesheets/css/sidebar.css +1 -1
  8. data/app/assets/stylesheets/css/tags.css +0 -7
  9. data/app/assets/svgs/arrow-circle-right.svg +1 -1
  10. data/app/assets/svgs/arrow-down.svg +1 -1
  11. data/app/assets/svgs/arrow-up.svg +1 -1
  12. data/app/assets/svgs/bell.svg +1 -1
  13. data/app/assets/svgs/chevron-right.svg +1 -1
  14. data/app/assets/svgs/exclamation.svg +1 -1
  15. data/app/assets/svgs/failed_to_load.svg +5 -4
  16. data/app/assets/svgs/grid-empty-state.svg +11 -10
  17. data/app/assets/svgs/information-circle.svg +1 -1
  18. data/app/assets/svgs/logout.svg +1 -1
  19. data/app/assets/svgs/menu.svg +1 -1
  20. data/app/assets/svgs/play.svg +1 -1
  21. data/app/assets/svgs/switch-vertical.svg +1 -1
  22. data/app/assets/svgs/table-empty-state.svg +12 -11
  23. data/app/assets/svgs/user-circle.svg +1 -1
  24. data/app/assets/svgs/x.svg +1 -1
  25. data/app/components/avo/actions_component.html.erb +2 -2
  26. data/app/components/avo/actions_component.rb +1 -1
  27. data/app/components/avo/button_component.html.erb +1 -0
  28. data/app/components/avo/button_component.rb +3 -3
  29. data/app/components/avo/card_component.html.erb +12 -11
  30. data/app/components/avo/common_field_wrapper_component.html.erb +1 -1
  31. data/app/components/avo/fields/belongs_to_field/edit_component.rb +1 -1
  32. data/app/components/avo/fields/boolean_field/edit_component.html.erb +2 -2
  33. data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
  34. data/app/components/avo/fields/code_field/edit_component.html.erb +2 -2
  35. data/app/components/avo/fields/country_field/edit_component.html.erb +1 -1
  36. data/app/components/avo/fields/date_field/edit_component.html.erb +2 -2
  37. data/app/components/avo/fields/date_time_field/edit_component.html.erb +2 -2
  38. data/app/components/avo/fields/external_image_field/edit_component.html.erb +1 -1
  39. data/app/components/avo/fields/file_field/edit_component.html.erb +1 -1
  40. data/app/components/avo/fields/files_field/edit_component.html.erb +1 -1
  41. data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -1
  42. data/app/components/avo/fields/markdown_field/edit_component.html.erb +1 -1
  43. data/app/components/avo/fields/markdown_field/show_component.html.erb +1 -1
  44. data/app/components/avo/fields/number_field/edit_component.html.erb +1 -1
  45. data/app/components/avo/fields/password_field/edit_component.html.erb +1 -1
  46. data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -1
  47. data/app/components/avo/fields/progress_bar_field/index_component.html.erb +1 -1
  48. data/app/components/avo/fields/progress_bar_field/show_component.html.erb +1 -1
  49. data/app/components/avo/fields/select_field/edit_component.html.erb +1 -1
  50. data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
  51. data/app/components/avo/fields/tags_field/edit_component.html.erb +3 -3
  52. data/app/components/avo/fields/tags_field/show_component.rb +0 -2
  53. data/app/components/avo/fields/text_field/edit_component.html.erb +1 -1
  54. data/app/components/avo/fields/textarea_field/edit_component.html.erb +1 -1
  55. data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -1
  56. data/app/components/avo/profile_item_component.html.erb +1 -1
  57. data/app/components/avo/resource_component.rb +23 -0
  58. data/app/components/avo/tab_group_component.html.erb +1 -1
  59. data/app/components/avo/tab_switcher_component.rb +2 -2
  60. data/app/components/avo/views/resource_edit_component.html.erb +3 -1
  61. data/app/components/avo/views/resource_edit_component.rb +1 -1
  62. data/app/components/avo/views/resource_index_component.html.erb +2 -2
  63. data/app/components/avo/views/resource_index_component.rb +17 -23
  64. data/app/components/avo/views/resource_show_component.html.erb +7 -4
  65. data/app/components/avo/views/resource_show_component.rb +8 -0
  66. data/app/controllers/avo/base_controller.rb +87 -33
  67. data/app/controllers/avo/search_controller.rb +57 -20
  68. data/app/helpers/avo/actions_helper.rb +4 -0
  69. data/app/helpers/avo/application_helper.rb +16 -37
  70. data/app/helpers/avo/attachments_helper.rb +4 -0
  71. data/app/helpers/avo/resources_helper.rb +2 -2
  72. data/app/javascript/avo.js +1 -0
  73. data/app/javascript/js/controllers/fields/trix_field_controller.js +3 -4
  74. data/app/javascript/js/controllers/item_selector_controller.js +1 -1
  75. data/app/javascript/js/controllers/menu_controller.js +2 -2
  76. data/app/javascript/js/controllers/search_controller.js +42 -15
  77. data/app/views/avo/associations/new.html.erb +3 -2
  78. data/app/views/avo/base/_multiple_select_filter.html.erb +1 -1
  79. data/app/views/avo/base/_text_filter.html.erb +1 -1
  80. data/app/views/avo/partials/_header.html.erb +1 -1
  81. data/app/views/avo/partials/_logo.html.erb +2 -2
  82. data/app/views/avo/partials/_resource_search.html.erb +6 -0
  83. data/app/views/avo/private/_links_and_buttons.html.erb +1 -1
  84. data/app/views/avo/private/design.html.erb +3 -3
  85. data/app/views/kaminari/_first_page.html.erb +3 -0
  86. data/app/views/kaminari/_last_page.html.erb +3 -0
  87. data/app/views/kaminari/_next_page.html.erb +9 -0
  88. data/app/views/kaminari/_page.html.erb +12 -0
  89. data/app/views/kaminari/_prev_page.html.erb +9 -0
  90. data/app/views/layouts/avo/application.html.erb +0 -1
  91. data/avo.gemspec +1 -0
  92. data/lib/avo/concerns/has_editable_controls.rb +1 -1
  93. data/lib/avo/configuration.rb +0 -5
  94. data/lib/avo/dashboards/chartkick_card.rb +1 -1
  95. data/lib/avo/fields/base_field.rb +2 -1
  96. data/lib/avo/fields/concerns/is_readonly.rb +17 -0
  97. data/lib/avo/fields/has_base_field.rb +2 -0
  98. data/lib/avo/hosts/search_scope_host.rb +7 -0
  99. data/lib/avo/licensing/pro_license.rb +0 -1
  100. data/lib/avo/version.rb +1 -1
  101. data/lib/generators/avo/templates/field/components/edit_component.html.erb.tt +1 -1
  102. data/lib/generators/avo/templates/initializer/avo.tt +1 -15
  103. data/lib/generators/avo/templates/resource/resource.tt +1 -1
  104. data/public/avo-assets/avo.css +248 -286
  105. data/public/avo-assets/avo.js +47 -47
  106. data/public/avo-assets/avo.js.map +2 -2
  107. metadata +25 -3
  108. data/app/views/avo/partials/_branding.html.erb +0 -5
  109. data/lib/avo/configuration/branding.rb +0 -65
@@ -64,51 +64,30 @@ module Avo
64
64
  classes
65
65
  end
66
66
 
67
+ # I takes a filename or a path and tries to find the asset in this order:
68
+ # - file inside the parent app's `app/assets/svgs` path
69
+ # - full path in the parent app
70
+ # - file inside the Avo's app/assets/svgs path
71
+ # - full path in Avo's assets
67
72
  def svg(file_name, **args)
68
73
  return if file_name.nil?
69
74
 
70
- options = {}
71
- options[:class] = args[:class].present? ? args[:class] : ""
72
- options[:class] += args[:extra_class].present? ? " #{args[:extra_class]}" : ""
75
+ file_name = "#{file_name}.svg" unless file_name.end_with? ".svg"
73
76
 
74
- if args[:'data-target'].present?
75
- options[:'data-target'] = args[:'data-target']
76
- end
77
- if args[:'data-tippy'].present?
78
- options[:'data-tippy'] = args[:'data-tippy']
79
- end
80
- if args[:title].present?
81
- options[:title] = args[:title]
82
- end
83
-
84
- # Create the path to the svgs directory
85
- file_path = "#{Avo::Engine.root}/app/assets/svgs/#{file_name}"
86
- file_path = "#{file_path}.svg" unless file_path.end_with? ".svg"
87
-
88
- # Create a cache hash
89
- hash = Digest::MD5.hexdigest "#{file_path.underscore}_#{options}"
77
+ paths = [
78
+ Rails.root.join("app", "assets", "svgs", file_name).to_s,
79
+ Rails.root.join(file_name).to_s,
80
+ Avo::Engine.root.join("app", "assets", "svgs", file_name).to_s,
81
+ Avo::Engine.root.join(file_name).to_s,
82
+ ]
90
83
 
91
- svg_content = Avo::App.cache_store.fetch "svg_file_#{hash}", expires_in: 1.week, cache_nils: false do
92
- if File.exist?(file_path)
93
- file = File.read(file_path)
94
-
95
- # parse svg
96
- doc = Nokogiri::HTML::DocumentFragment.parse file
97
- svg = doc.at_css "svg"
98
-
99
- # attach options
100
- options.each do |attr, value|
101
- svg[attr.to_s] = value
102
- end
103
-
104
- # cast to html
105
- doc.to_html.html_safe
106
- end
84
+ path = paths.find do |path|
85
+ File.exist? path
107
86
  end
108
87
 
109
- return "(not found)" if svg_content.to_s.blank?
88
+ return if path.nil?
110
89
 
111
- svg_content
90
+ inline_svg_tag path, **args
112
91
  end
113
92
 
114
93
  def input_classes(extra_classes = "", has_error: false)
@@ -0,0 +1,4 @@
1
+ module Avo
2
+ module AttachmentsHelper
3
+ end
4
+ end
@@ -47,7 +47,7 @@ module Avo
47
47
 
48
48
  def item_selector_input(floating: false, size: :md)
49
49
  "<input type='checkbox'
50
- class='mx-3 rounded checked:bg-primary-400 focus:checked:!bg-primary-400 #{"absolute inset-auto left-0 mt-2 z-10 hidden group-hover:block checked:block" if floating} #{size.to_sym == :lg ? "w-5 h-5" : "w-4 h-4"}'
50
+ class='mx-3 rounded #{"absolute inset-auto left-0 mt-2 z-10 hidden group-hover:block checked:block" if floating} #{size.to_sym == :lg ? "w-5 h-5" : "w-4 h-4"}'
51
51
  data-action='input->item-selector#toggle input->item-select-all#update'
52
52
  data-item-select-all-target='itemCheckbox'
53
53
  name='#{t "avo.select_item"}'
@@ -58,7 +58,7 @@ module Avo
58
58
 
59
59
  def item_select_all_input
60
60
  "<input type='checkbox'
61
- class='mx-3 rounded w-4 h-4 checked:bg-primary-400 focus:checked:!bg-primary-400'
61
+ class='mx-3 rounded w-4 h-4'
62
62
  data-action='input->item-select-all#toggle'
63
63
  data-item-select-all-target='checkbox'
64
64
  name='#{t "avo.select_all"}'
@@ -10,6 +10,7 @@ import tippy from 'tippy.js'
10
10
 
11
11
  import 'chartkick/chart.js/chart.esm'
12
12
 
13
+ // Toastr alerts
13
14
  import './js/active-storage'
14
15
  import './js/controllers'
15
16
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-alert */
2
1
  import 'trix'
3
2
  import { Controller } from '@hotwired/stimulus'
4
3
  import { castBoolean } from '../../helpers/cast_boolean'
@@ -49,7 +48,7 @@ export default class extends Controller {
49
48
  // Prevent file uploads for fields that have attachments disabled.
50
49
  if (this.attachmentsDisabled) {
51
50
  event.preventDefault()
52
- alert('This field has attachments disabled.')
51
+ window.toastr.warning('This field has attachments disabled.')
53
52
 
54
53
  return
55
54
  }
@@ -57,7 +56,7 @@ export default class extends Controller {
57
56
  // Prevent file uploads for resources that haven't been saved yet.
58
57
  if (this.resourceId === '') {
59
58
  event.preventDefault()
60
- alert("You can't upload files into the Trix editor until you save the resource.")
59
+ window.toastr.warning("You can't upload files into the Trix editor until you save the resource.")
61
60
 
62
61
  return
63
62
  }
@@ -65,7 +64,7 @@ export default class extends Controller {
65
64
  // Prevent file uploads for fields without an attachment key.
66
65
  if (this.attachmentKey === '') {
67
66
  event.preventDefault()
68
- alert("You haven't set an `attachment_key` to this Trix field.")
67
+ window.toastr.warning("You haven't set an <a href='https://google.com' class='!text-blue-700 underline'>attachment_key</a> to this Trix field.")
69
68
  }
70
69
  }
71
70
  })
@@ -5,7 +5,7 @@ export default class extends Controller {
5
5
 
6
6
  checkbox = {};
7
7
 
8
- enabledClasses = ['text-black']
8
+ enabledClasses = ['text-black', 'hover:bg-blue-500', 'hover:text-white']
9
9
 
10
10
  disabledClasses = ['text-gray-500']
11
11
 
@@ -22,8 +22,8 @@ export default class extends Controller {
22
22
  }
23
23
 
24
24
  get initiallyCollapsed() {
25
- if (this.defaultState === 'collapsed') {
26
- return this.userState === 'collapsed'
25
+ if (!this.userState) {
26
+ return this.defaultState === 'collapsed'
27
27
  }
28
28
 
29
29
  return this.userState === 'collapsed'
@@ -48,6 +48,10 @@ export default class extends Controller {
48
48
  return this.dataset.viaAssociation === 'belongs_to'
49
49
  }
50
50
 
51
+ get isHasManySearch() {
52
+ return this.dataset.viaAssociation === 'has_many'
53
+ }
54
+
51
55
  get isGlobalSearch() {
52
56
  return this.dataset.searchResource === 'global'
53
57
  }
@@ -83,27 +87,50 @@ export default class extends Controller {
83
87
  params.global = true
84
88
  }
85
89
 
86
- if (this.isBelongsToSearch) {
87
- params = {
88
- ...params,
89
- // eslint-disable-next-line camelcase
90
- via_association_id: this.dataset.viaAssociationId,
91
- // eslint-disable-next-line camelcase
92
- via_reflection_class: this.dataset.viaReflectionClass,
93
- // eslint-disable-next-line camelcase
94
- via_reflection_id: this.dataset.viaReflectionId,
95
- // eslint-disable-next-line camelcase
96
- via_parent_resource_id: this.dataset.viaParentResourceId,
97
- // eslint-disable-next-line camelcase
98
- via_parent_resource_class: this.dataset.viaParentResourceClass,
99
- // eslint-disable-next-line camelcase
100
- via_relation: this.dataset.viaRelation,
90
+ if (this.isBelongsToSearch || this.isHasManySearch) {
91
+ params = this.addAssociationParams(params)
92
+ params = this.addReflectionParams(params)
93
+
94
+ if (this.isBelongsToSearch) {
95
+ params = {
96
+ ...params,
97
+ // eslint-disable-next-line camelcase
98
+ via_parent_resource_id: this.dataset.viaParentResourceId,
99
+ // eslint-disable-next-line camelcase
100
+ via_parent_resource_class: this.dataset.viaParentResourceClass,
101
+ // eslint-disable-next-line camelcase
102
+ via_relation: this.dataset.viaRelation,
103
+ }
101
104
  }
102
105
  }
103
106
 
104
107
  return params
105
108
  }
106
109
 
110
+ addAssociationParams(params) {
111
+ params = {
112
+ ...params,
113
+ // eslint-disable-next-line camelcase
114
+ via_association: this.dataset.viaAssociation,
115
+ // eslint-disable-next-line camelcase
116
+ via_association_id: this.dataset.viaAssociationId,
117
+ }
118
+
119
+ return params
120
+ }
121
+
122
+ addReflectionParams(params) {
123
+ params = {
124
+ ...params,
125
+ // eslint-disable-next-line camelcase
126
+ via_reflection_class: this.dataset.viaReflectionClass,
127
+ // eslint-disable-next-line camelcase
128
+ via_reflection_id: this.dataset.viaReflectionId,
129
+ }
130
+
131
+ return params
132
+ }
133
+
107
134
  handleOnSelect({ item }) {
108
135
  if (this.isBelongsToSearch) {
109
136
  this.updateFieldAttribute(this.hiddenIdTarget, 'value', item._id)
@@ -13,6 +13,7 @@
13
13
  <div class="flex-1 flex items-center justify-center px-0 lg:px-8 text-lg mt-8 mb-12">
14
14
  <% if @field.searchable %>
15
15
  <%= render Avo::Fields::BelongsToField::AutocompleteComponent.new form: form,
16
+ classes: input_classes("w-full"),
16
17
  field: @field,
17
18
  model_key: @field.target_resource&.model_key,
18
19
  foreign_key: 'related_id',
@@ -34,10 +35,10 @@
34
35
  </div>
35
36
 
36
37
  <% c.controls do %>
37
- <%= a_button 'data-action': 'click->modal#close', size: :sm, style: :outline, color: :primary do %>
38
+ <%= a_button 'data-action': 'click->modal#close', size: :sm do %>
38
39
  <%= t('avo.cancel') %>
39
40
  <% end %>
40
- <%= a_button type: :submit, style: :primary, color: :primary, size: :sm do %>
41
+ <%= a_button type: :submit, color: :green, size: :sm do %>
41
42
  <%= t('avo.attach') %>
42
43
  <% end %>
43
44
  <% end %>
@@ -12,7 +12,7 @@
12
12
  'data-multiple-select-filter-target': 'selector'
13
13
  %>
14
14
  <div class="flex justify-end">
15
- <%= a_button class: 'mt-4', color: :primary, size: :xs, data: { action: "multiple-select-filter#changeFilter" } do %>
15
+ <%= a_button class: 'mt-4', color: :blue, size: :xs, data: { action: "multiple-select-filter#changeFilter" } do %>
16
16
  Filter by <%=filter.name %>
17
17
  <% end %>
18
18
  </div>
@@ -13,7 +13,7 @@
13
13
  'data-action': 'keypress->text-filter#tryToSubmit'
14
14
  %>
15
15
  <div class="flex justify-end">
16
- <%= a_button class: 'mt-4', color: :primary, data: { action: "text-filter#changeFilter" }, size: :xs do %>
16
+ <%= a_button class: 'mt-4', color: :blue, data: { action: "text-filter#changeFilter" }, size: :xs do %>
17
17
  <%= filter.button_label || "Filter by #{filter.name}" %>
18
18
  <% end %>
19
19
  </div>
@@ -1 +1 @@
1
- <%= link_to Avo.configuration.app_name, '/', class: 'text-primary-500 font-semibold', target: :_blank %>
1
+ <%= link_to Avo.configuration.app_name, '/', class: 'text-blue-500 font-semibold', target: :_blank %>
@@ -1,4 +1,4 @@
1
1
  <%= link_to root_path, class: 'logo-placeholder h-full w-full flex justify-start' do %>
2
- <%= image_tag Avo.configuration.branding.logo, class: 'hidden sm:block object-contain', title: 'Avo' %>
3
- <%= image_tag Avo.configuration.branding.logomark, class: 'sm:hidden object-contain', title: 'Avo' %>
2
+ <%= image_tag '/avo-assets/logo.png', class: 'hidden sm:block object-contain', title: 'Avo' %>
3
+ <%= image_tag '/avo-assets/logomark.png', class: 'sm:hidden object-contain', title: 'Avo' %>
4
4
  <% end %>
@@ -3,6 +3,12 @@
3
3
  data-search-target="autocomplete"
4
4
  data-search-resource="<%= resource %>"
5
5
  data-translation-keys='{"no_item_found": "<%= I18n.translate 'avo.no_item_found' %>"}'
6
+ <% if via_reflection.present? %>
7
+ data-via-association="<%= via_reflection[:association] %>"
8
+ data-via-association-id="<%= via_reflection[:association_id] %>"
9
+ data-via-reflection-class="<%= via_reflection[:class] %>"
10
+ data-via-reflection-id="<%= via_reflection[:id] %>"
11
+ <% end %>
6
12
  >
7
13
  </div>
8
14
  <div class="hidden relative inline-flex text-gray-400 text-sm border border-gray-300 rounded cursor-pointer" data-search-target="button"></div>
@@ -2,7 +2,7 @@
2
2
  entities = [:button, :link]
3
3
  sizes = [:xl, :lg, :md, :sm, :xs].reverse
4
4
  styles = [:primary, :outline, :text]
5
- colors = [:primary, :blue, :gray, :red, :orange, :green]
5
+ colors = [:primary, :gray, :red, :orange, :green]
6
6
  states = [:regular, :hover, :disabled, :active]
7
7
  %>
8
8
  <div class="px-6 space-y-4">
@@ -6,15 +6,15 @@
6
6
  <% end %>
7
7
 
8
8
  <%= a_link('/admin', icon: 'arrow-left', style: :outline, is_link: true) do %>
9
- Outline
9
+ Secondary
10
10
  <% end %>
11
11
 
12
12
  <%= a_link('/admin', icon: 'arrow-left', style: :outline, color: :red, is_link: true) do %>
13
13
  Red
14
14
  <% end %>
15
15
 
16
- <%= a_link('/admin', icon: 'arrow-left', style: :text, color: :orange, is_link: true) do %>
17
- Text
16
+ <%= a_link('/admin', icon: 'arrow-left', style: :outline, color: :orange, is_link: true) do %>
17
+ Red
18
18
  <% end %>
19
19
  <% end %>
20
20
 
@@ -0,0 +1,3 @@
1
+ <span class="first">
2
+ <%= link_to_unless current_page.first?, t('views.pagination.first').html_safe, url, remote: remote, class: 'relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150' %>
3
+ </span>
@@ -0,0 +1,3 @@
1
+ <span class="last">
2
+ <%= link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, remote: remote, class: 'ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150' %>
3
+ </span>
@@ -0,0 +1,9 @@
1
+ <% if !current_page.last? %>
2
+ <%= link_to url, :id => 'pnnext',:remote => remote do %>
3
+ <button type="button" class="-ml-px relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-500 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150">
4
+ <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
5
+ <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
6
+ </svg>
7
+ </button>
8
+ <% end %>
9
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <% url = resources_path(resource: @resource, page: page, keep_query_params: true) %>
2
+ <% if page.current? %>
3
+ <button type="button" class="hidden md:inline-flex -ml-px relative items-center px-4 py-2 border bg-gray-100 text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 z-10 outline-none border-primary-300 active:bg-gray-100 transition ease-in-out duration-150">
4
+ <%= page %>
5
+ </button>
6
+ <% else %>
7
+ <%= link_to url, :remote => remote do %>
8
+ <button type="button" class="hidden md:inline-flex -ml-px relative items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
9
+ <%= page %>
10
+ </button>
11
+ <% end %>
12
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <% if !current_page.first? %>
2
+ <%= link_to url, :id => 'pnprev', :remote => remote do %>
3
+ <button type="button" class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-500 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150">
4
+ <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
5
+ <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/>
6
+ </svg>
7
+ </button>
8
+ <% end %>
9
+ <% end %>
@@ -7,7 +7,6 @@
7
7
  <%= csp_meta_tag %>
8
8
  <%= render partial: 'avo/partials/javascript' %>
9
9
  <%= render partial: 'avo/partials/head' %>
10
- <%= render partial: 'avo/partials/branding' %>
11
10
  <% if Avo::PACKED %>
12
11
  <%= javascript_include_tag "/avo-assets/avo", "data-turbo-track": "reload", defer: true %>
13
12
  <%= stylesheet_link_tag "/avo-assets/avo", "data-turbo-track": "reload", defer: true %>
data/avo.gemspec CHANGED
@@ -48,4 +48,5 @@ Gem::Specification.new do |spec|
48
48
  spec.add_dependency "chartkick"
49
49
  spec.add_dependency "dry-initializer"
50
50
  spec.add_dependency "docile"
51
+ spec.add_dependency "inline_svg"
51
52
  end
@@ -24,7 +24,7 @@ module Avo
24
24
  resource: self,
25
25
  record: model,
26
26
  view: view
27
- ).handle.items
27
+ ).handle&.items || []
28
28
  else
29
29
  []
30
30
  end
@@ -34,7 +34,6 @@ module Avo
34
34
  attr_accessor :buttons_on_form_footers
35
35
  attr_accessor :main_menu
36
36
  attr_accessor :profile_menu
37
- attr_writer :branding
38
37
 
39
38
  def initialize
40
39
  @root_path = "/avo"
@@ -122,10 +121,6 @@ module Avo
122
121
  def feature_enabled?(feature)
123
122
  !@disabled_features.map(&:to_sym).include?(feature.to_sym)
124
123
  end
125
-
126
- def branding
127
- Avo::Configuration::Branding.new(**@branding || {})
128
- end
129
124
  end
130
125
 
131
126
  def self.configuration
@@ -29,7 +29,7 @@ module Avo
29
29
  default = {
30
30
  # figure our the available height for the chart
31
31
  height: "#{(rows * card_height) - card_heading}px",
32
- colors: ::Avo.configuration.branding.chart_colors,
32
+ colors: %w[#0B8AE2 #34C683 #2AB1EE #34C6A8],
33
33
  library: {
34
34
  discrete: false,
35
35
  points: false,
@@ -13,6 +13,7 @@ module Avo
13
13
  include Avo::Concerns::HandlesFieldArgs
14
14
  include Avo::Concerns::HasHTMLAttributes
15
15
  include Avo::Fields::Concerns::IsRequired
16
+ include Avo::Fields::Concerns::IsReadonly
16
17
 
17
18
  delegate :view_context, to: ::Avo::App
18
19
  delegate :simple_format, :content_tag, to: :view_context
@@ -160,7 +161,7 @@ module Avo
160
161
  final_value = @model.send(property) if (model_or_class(@model) == "model") && @model.respond_to?(property)
161
162
 
162
163
  # On new views and actions modals we need to prefill the fields
163
- if (@view === :new) || @action.present?
164
+ if @view.in?([:new, :create]) || @action.present?
164
165
  if default.present?
165
166
  final_value = if default.respond_to?(:call)
166
167
  default.call
@@ -0,0 +1,17 @@
1
+ module Avo
2
+ module Fields
3
+ module Concerns
4
+ module IsReadonly
5
+ extend ActiveSupport::Concern
6
+
7
+ def is_readonly?
8
+ if readonly.respond_to? :call
9
+ Avo::Hosts::ViewRecordHost.new(block: readonly, record: model, view: view).handle
10
+ else
11
+ readonly
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,7 @@ module Avo
6
6
  attr_accessor :attach_scope
7
7
  attr_accessor :description
8
8
  attr_accessor :discreet_pagination
9
+ attr_accessor :hide_search_input
9
10
 
10
11
  def initialize(id, **args, &block)
11
12
  super(id, **args, &block)
@@ -14,6 +15,7 @@ module Avo
14
15
  @attach_scope = args[:attach_scope].present? ? args[:attach_scope] : nil
15
16
  @display = args[:display].present? ? args[:display] : :show
16
17
  @searchable = args[:searchable] == true
18
+ @hide_search_input = args[:hide_search_input] || false
17
19
  @description = args[:description]
18
20
  @use_resource = args[:use_resource] || nil
19
21
  @discreet_pagination = args[:discreet_pagination] || false
@@ -0,0 +1,7 @@
1
+ module Avo
2
+ module Hosts
3
+ class SearchScopeHost < BaseHost
4
+ option :scope
5
+ end
6
+ end
7
+ end
@@ -16,7 +16,6 @@ module Avo
16
16
  :menu_editor,
17
17
  :stimulus_js_integration,
18
18
  :resource_show_controls,
19
- :branding,
20
19
  :advanced_fields
21
20
  ]
22
21
  end
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.13.2.pre.2" unless const_defined?(:VERSION)
2
+ VERSION = "2.13.3.pre.1" unless const_defined?(:VERSION)
3
3
  end
@@ -2,5 +2,5 @@
2
2
  <%%= @form.text_field @field.id,
3
3
  class: classes("w-full"),
4
4
  placeholder: @field.placeholder,
5
- disabled: @field.readonly %>
5
+ disabled: @field.is_readonly? %>
6
6
  <%% end %>
@@ -1,4 +1,4 @@
1
- # For more information regaring these settings check out our docs https://docs.avohq.io
1
+ # For more information regarding these settings check out our docs https://docs.avohq.io
2
2
  Avo.configure do |config|
3
3
  ## == Routing ==
4
4
  config.root_path = '/<%= options[:path] %>'
@@ -52,20 +52,6 @@ Avo.configure do |config|
52
52
  # config.display_license_request_timeout_error = true
53
53
  # config.disabled_features = []
54
54
  # config.resource_controls = :right
55
- # config.buttons_on_form_footers = true
56
-
57
- ## == Branding ==
58
- # config.branding = {
59
- # colors: {
60
- # 100 => "#CEE7F8",
61
- # 400 => "#399EE5",
62
- # 500 => "#0886DE",
63
- # 600 => "#066BB2",
64
- # },
65
- # chart_colors: ["#0B8AE2", "#34C683", "#2AB1EE", "#34C6A8"],
66
- # logo: "/avo-assets/logo.png"
67
- # logomark: "/avo-assets/logomark.png",
68
- # }
69
55
 
70
56
 
71
57
  ## == Breadcrumbs ==
@@ -1,7 +1,7 @@
1
1
  class <%= resource_class %> < Avo::BaseResource
2
2
  self.title = :id
3
3
  self.includes = []
4
- # self.search_query = ->(params:) do
4
+ # self.search_query = -> do
5
5
  # scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
6
6
  # end
7
7