avo 3.10.2 → 3.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e51595cfcbb3ba9850fd4c3fbc2e275885c1a15f02e08b9a753d0116b25d419e
4
- data.tar.gz: 0455fdbf83e642914f564e08b2ea0bd30e3f545a6b464b788819328122b475df
3
+ metadata.gz: 7afac36998d2f2e717c72503adfc0766ea5c58c3e0d26df00e7e33625cf1a77f
4
+ data.tar.gz: 912401e2bbcd7ad2977fa2f4372b168f8651b8ddbeb096ea7c6012e94954aabb
5
5
  SHA512:
6
- metadata.gz: 5f1ad37ee8e5d2593c31d7b2a35d6ab68337681e408067bbf6ca47bad885a5d3b843cd7a1e88a724253f68236743c58898b09c44dca8f55731af0489ac31f1dd
7
- data.tar.gz: c44b5d4065f29ee88af55a01ccb11b58366c679d6071d5169d8284237f6dd24671f7b3cd60a17b4f567d227f6705b21878de1a0017aa2a1419be535de1184c7c
6
+ metadata.gz: 828c4da677ed0de6d56a3a8747a538328e7269d22ab106c774f96df954653697bf2f08e689d9cb48e70e85d38e96751d80e128892a8d1b0f0451101261c7da70
7
+ data.tar.gz: 7709955ac1a64c6a6b32bf530290a2862de53dfdca746c07d9f222ae2b85dd87e9b261df30c456c82938dce17582b26cabe56a8e6d6fb8b84e299b792dfd8099
data/Gemfile CHANGED
@@ -121,8 +121,6 @@ end
121
121
 
122
122
  gem "zeitwerk"
123
123
 
124
- gem "httparty"
125
-
126
124
  gem "iso"
127
125
 
128
126
  gem "active_link_to"
data/Gemfile.lock CHANGED
@@ -17,7 +17,7 @@ GIT
17
17
 
18
18
  GIT
19
19
  remote: https://github.com/rails/rails.git
20
- revision: 4fa56814f18fd3da49c83931fa773caa727d8096
20
+ revision: 69d904e60f78300270ecbb01e4cf68e78074b30d
21
21
  branch: main
22
22
  specs:
23
23
  actioncable (8.0.0.alpha)
@@ -115,14 +115,13 @@ GIT
115
115
  PATH
116
116
  remote: .
117
117
  specs:
118
- avo (3.10.2)
118
+ avo (3.10.3)
119
119
  actionview (>= 6.1)
120
120
  active_link_to
121
121
  activerecord (>= 6.1)
122
122
  activesupport (>= 6.1)
123
123
  addressable
124
124
  docile
125
- httparty
126
125
  inline_svg
127
126
  literal (~> 0.2)
128
127
  meta-tags
@@ -167,8 +166,8 @@ GEM
167
166
  avo-record_link_field (0.0.1)
168
167
  awesome_print (1.9.2)
169
168
  aws-eventstream (1.3.0)
170
- aws-partitions (1.951.0)
171
- aws-sdk-core (3.201.0)
169
+ aws-partitions (1.955.0)
170
+ aws-sdk-core (3.201.1)
172
171
  aws-eventstream (~> 1, >= 1.3.0)
173
172
  aws-partitions (~> 1, >= 1.651.0)
174
173
  aws-sigv4 (~> 1.8)
@@ -333,10 +332,6 @@ GEM
333
332
  listen (>= 3.0.0)
334
333
  railties (>= 6.0.0)
335
334
  htmlbeautifier (1.4.3)
336
- httparty (0.22.0)
337
- csv
338
- mini_mime (>= 1.0.0)
339
- multi_xml (>= 0.5.2)
340
335
  i18n (1.14.5)
341
336
  concurrent-ruby (~> 1.0)
342
337
  i18n-tasks (1.0.14)
@@ -357,7 +352,7 @@ GEM
357
352
  activesupport (>= 3.0)
358
353
  nokogiri (>= 1.6)
359
354
  io-console (0.7.2)
360
- irb (1.13.2)
355
+ irb (1.14.0)
361
356
  rdoc (>= 4.0.0)
362
357
  reline (>= 0.4.2)
363
358
  iso (0.4.0)
@@ -395,7 +390,7 @@ GEM
395
390
  meta-tags (2.2.0)
396
391
  actionpack (>= 3.2.0)
397
392
  method_source (1.1.0)
398
- mini_magick (4.13.1)
393
+ mini_magick (4.13.2)
399
394
  mini_mime (1.1.5)
400
395
  mini_portile2 (2.8.7)
401
396
  minitest (5.24.1)
@@ -409,8 +404,6 @@ GEM
409
404
  money (~> 6.13)
410
405
  railties (>= 3.0)
411
406
  msgpack (1.7.2)
412
- multi_xml (0.7.1)
413
- bigdecimal (~> 3.1)
414
407
  net-imap (0.4.14)
415
408
  date
416
409
  net-protocol
@@ -429,7 +422,7 @@ GEM
429
422
  orm_adapter (0.5.0)
430
423
  pagy (8.6.3)
431
424
  parallel (1.25.1)
432
- parser (3.3.3.0)
425
+ parser (3.3.4.0)
433
426
  ast (~> 2.4.1)
434
427
  racc
435
428
  path_expander (1.1.1)
@@ -444,7 +437,7 @@ GEM
444
437
  puma (6.4.2)
445
438
  nio4r (~> 2.0)
446
439
  racc (1.8.0)
447
- rack (3.1.6)
440
+ rack (3.1.7)
448
441
  rack-session (2.0.0)
449
442
  rack (>= 3.0.0)
450
443
  rack-test (2.1.0)
@@ -534,7 +527,7 @@ GEM
534
527
  ruby-progressbar (1.13.0)
535
528
  ruby-vips (2.2.1)
536
529
  ffi (~> 1.12)
537
- ruby_parser (3.21.0)
530
+ ruby_parser (3.21.1)
538
531
  racc (~> 1.5)
539
532
  sexp_processor (~> 4.16)
540
533
  rubycritic (4.9.0)
@@ -549,7 +542,7 @@ GEM
549
542
  simplecov (>= 0.22.0)
550
543
  tty-which (~> 0.5.0)
551
544
  virtus (~> 2.0)
552
- sexp_processor (4.17.1)
545
+ sexp_processor (4.17.2)
553
546
  simplecov (0.22.0)
554
547
  docile (~> 1.1)
555
548
  simplecov-html (~> 0.11)
@@ -696,7 +689,6 @@ DEPENDENCIES
696
689
  hightop
697
690
  hotwire-livereload (~> 1.3.0)
698
691
  htmlbeautifier
699
- httparty
700
692
  i18n-tasks (~> 1.0.12)
701
693
  image_processing (~> 1.12)
702
694
  iso
data/README.md CHANGED
@@ -1,26 +1,49 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/avo.svg)](https://badge.fury.io/rb/avo)
2
- ![Tests](https://github.com/avo-hq/avo/workflows/Tests/badge.svg)
3
- ![reviewdog](https://github.com/avo-hq/avo/workflows/reviewdog/badge.svg)
2
+ [![System Tests](https://github.com/avo-hq/avo/actions/workflows/system-tests.yml/badge.svg)](https://github.com/avo-hq/avo/actions/workflows/system-tests.yml)
3
+ [![Feature Tests](https://github.com/avo-hq/avo/actions/workflows/feature-tests.yml/badge.svg)](https://github.com/avo-hq/avo/actions/workflows/feature-tests.yml)
4
+ [![Lint](https://github.com/avo-hq/avo/actions/workflows/lint.yml/badge.svg)](https://github.com/avo-hq/avo/actions/workflows/lint.yml)
5
+ <a href="https://github.com/avo-hq/avo/discussions" target="_blank">
6
+ <img alt="GitHub Discussions" src="https://img.shields.io/github/discussions/avo-hq/avo?color=168AFE&logo=github">
7
+ </a>
8
+ <a href="https://github.com/avo-hq/avo/issues" target="_blank">
9
+ <img alt="GitHub Issues or Pull Requests" src="https://img.shields.io/github/issues-closed/avo-hq/avo?style=flat&link=https%3A%2F%2Fgithub.com%2Favo-hq%2Favo%2Fissues&logo=github">
10
+ </a>
11
+ <a href="https://rubygems.org/gems/avo">
12
+ <img alt="GEM Downloads" src="https://img.shields.io/gem/dt/avo?color=168AFE&logo=ruby&logoColor=FE1616">
13
+ </a>
14
+ <a href="https://github.com/testdouble/standard">
15
+ <img alt="Ruby Style" src="https://img.shields.io/badge/style-standard-168AFE?logo=ruby&logoColor=FE1616" />
16
+ </a>
17
+ <a href="https://discord.com/invite/vuuwFe4Km3">
18
+ <img alt="Avo Rails Admin Discord Community" src="https://img.shields.io/discord/740892036978442260?color=8892F6&label=discord&logo=discord&logoColor=8892F6">
19
+ </a>
4
20
  [![codecov](https://codecov.io/gh/avo-hq/avo/branch/master/graph/badge.svg?token=Q2LMFE4989)](https://codecov.io/gh/avo-hq/avo)
5
21
  [![Maintainability](https://api.codeclimate.com/v1/badges/676a0afa2cc79f03aa29/maintainability)](https://codeclimate.com/github/avo-hq/avo/maintainability)
6
- [![Open Source Helpers](https://www.codetriage.com/avo-hq/avo/badges/users.svg)](https://www.codetriage.com/avo-hq/avo)
7
22
 
8
23
  ![](./public/avo-assets/logo-on-white.png)
9
24
 
10
- **Ruby on Rails application building framework.**
25
+ **<a href="https://avohq.io" title="Ruby on Rails Admin Panel Framework">Avo - Ruby on Rails Admin Panel Framework</a>**
11
26
 
12
- 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.
27
+ Avo is a very custom Admin Panel Framework, Content Management System, and Internal Tool Builder for Ruby on Rails that saves engineers and teams **months of development time**.
13
28
 
14
29
  ## Get started
15
30
 
16
- ⚡️ **Install**: [docs.avohq.io/3.0/installation](https://docs.avohq.io/3.0/installation.html)\
17
- ✨ **Website**: [avohq.io](https://avohq.io)\
18
- 📚 **Documentation**: [docs.avohq.io](https://docs.avohq.io)\
19
- 🗺 **Roadmap**: [GitHub Roadmap](https://github.com/orgs/avo-hq/projects/8)\
20
- 🎸 **Demo app**: [Avodemo](https://main.avodemo.com/)\
21
- 🐤 **Twitter**: [avo_hq](https://twitter.com/avo_hq)\
22
- 💬 **Community chat**: [discord](https://discord.gg/pkTF6y8)\
23
- 🔧 **Issue tracker**: [GitHub issues](http://github.com/avo-hq/avo/issues)\
31
+ ⚡️ **Install**: [docs.avohq.io/3.0/installation](https://docs.avohq.io/3.0/installation.html)
32
+ <br>
33
+ **Website**: [avohq.io](https://avohq.io)
34
+ <br>
35
+ 📚 **Documentation**: [docs.avohq.io](https://docs.avohq.io)
36
+ <br>
37
+ 🗺 **Roadmap**: [GitHub Roadmap](https://github.com/orgs/avo-hq/projects/14)
38
+ <br>
39
+ 🎸 **Demo app**: [Avodemo](https://main.avodemo.com/)
40
+ <br>
41
+ 🐤 **Twitter**: [avo_hq](https://twitter.com/avo_hq)
42
+ <br>
43
+ 💬 **Community chat**: [discord](https://discord.gg/pkTF6y8)
44
+ <br>
45
+ 🔧 **Issue tracker**: [GitHub issues](http://github.com/avo-hq/avo/issues)
46
+ <br>
24
47
  🎙 **Discussions and feature requests**: [GitHub issues](http://github.com/avo-hq/avo/discussions)
25
48
 
26
49
  ## Features
@@ -50,9 +73,9 @@ Avo is a beautiful next-generation framework that empowers you, the developer, t
50
73
 
51
74
  ## Some of the things we're going to focus on next
52
75
 
53
- Theming ⭐️ &nbsp;notifications ⭐️ &nbsp;Resource segmentation ⭐️ &nbsp;filterable fields ⭐️ &nbsp;inline editing ⭐️ &nbsp;multilingual records ⭐️ &nbsp;keyboard shortcuts ⭐️ &nbsp;track resource changes ⭐️ &nbsp;smart resource generation ⭐️ &nbsp;live resources ⭐️ &nbsp;columns view ⭐️ &nbsp;list view ⭐️ &nbsp;custom action items ⭐️ &nbsp;command bar ⭐️ &nbsp; use fields DSL in your custom views
76
+ Theming ⭐️ &nbsp;notifications ⭐️ &nbsp;Resource segmentation ⭐️ &nbsp;inline editing ⭐️ &nbsp;multilingual records ⭐️ &nbsp;keyboard shortcuts ⭐️ &nbsp;track resource changes ⭐️ &nbsp;live resources ⭐️ &nbsp;columns view ⭐️ &nbsp;list view ⭐️ &nbsp;custom action items ⭐️ &nbsp;command bar
54
77
 
55
- For more up-to-date info check out our 🗺 [Roadmap](https://github.com/orgs/avo-hq/projects/8).
78
+ For more up-to-date info check out our 🗺 [Roadmap](https://github.com/orgs/avo-hq/projects/14).
56
79
 
57
80
  # Installation
58
81
 
@@ -2,7 +2,7 @@
2
2
  <% if file.present? %>
3
3
  <div class="flex flex-col h-full">
4
4
  <% if file.representable? && is_image? %>
5
- <%= image_tag helpers.main_app.url_for(file), class: "rounded-lg max-w-full self-start #{@extra_classes}" %>
5
+ <%= image_tag helpers.main_app.url_for(file), class: "rounded-lg max-w-full self-start #{@extra_classes}", loading: :lazy, width: file.metadata["width"], height: file.metadata["height"] %>
6
6
  <% elsif is_audio? %>
7
7
  <%= audio_tag(helpers.main_app.url_for(file), controls: true, preload: false, class: 'w-full') %>
8
8
  <% elsif is_video? %>
@@ -17,7 +17,7 @@
17
17
  <%= sanitize @field.value.to_s %>
18
18
  <% end %>
19
19
  <%= @form.text_area @field.id,
20
- value: @field.value,
20
+ value: @field.value.try(:to_trix_html) || @field.value,
21
21
  class: classes("w-full hidden"),
22
22
  data: @field.get_html(:data, view: view, element: :input),
23
23
  disabled: disabled?,
@@ -1,3 +1,3 @@
1
1
  <div class="absolute bg-gray-50 w-full h-full">
2
- <%= image_tag Avo.configuration.branding.placeholder, class: 'relative transform -translate-x-1/2 -translate-y-1/2 h-20 text-gray-400 inset-auto top-1/2 left-1/2' %>
2
+ <%= image_tag Avo.configuration.branding.placeholder, class: "relative transform -translate-x-1/2 -translate-y-1/2 h-20 text-gray-400 inset-auto top-1/2 left-1/2", loading: :lazy %>
3
3
  </div>
@@ -48,7 +48,7 @@ class Avo::Index::GridItemComponent < Avo::BaseComponent
48
48
  def link_to_cover
49
49
  classes = "absolute h-full w-full object-cover"
50
50
 
51
- link_to image_tag(@card[:cover_url], class: classes), resource_view_path, class: classes, title: @card[:title]
51
+ link_to image_tag(@card[:cover_url], class: classes), resource_view_path, class: classes, title: @card[:title], loading: :lazy, width: "640", height: "480"
52
52
  end
53
53
 
54
54
  def render_title
@@ -64,7 +64,7 @@ module Avo
64
64
  # If we have no proc and no default location method, don't try to create markers
65
65
  return [] unless resource_mappable?
66
66
 
67
- resources
67
+ records_markers = resources
68
68
  .map do |resource|
69
69
  Avo::ExecutionContext.new(target: marker_proc, record: resource.record).handle
70
70
  end
@@ -72,6 +72,10 @@ module Avo
72
72
  .filter do |coordinates|
73
73
  coordinates[:latitude].present? && coordinates[:longitude].present?
74
74
  end
75
+
76
+ return records_markers if map_options[:extra_markers].nil?
77
+
78
+ records_markers + Avo::ExecutionContext.new(target: map_options[:extra_markers]).handle
75
79
  end
76
80
 
77
81
  def resource_mapkick_options
@@ -102,7 +106,7 @@ module Avo
102
106
  end
103
107
 
104
108
  def resource_mappable?
105
- map_options[:record_marker].present? || @resources.first.record.respond_to?(:coordinates)
109
+ map_options[:record_marker].present? || map_options[:extra_markers].present? || @resources.first.record.respond_to?(:coordinates)
106
110
  end
107
111
  end
108
112
  end
@@ -89,13 +89,13 @@ module Avo
89
89
 
90
90
  respond_to do |format|
91
91
  format.turbo_stream do
92
- case @response[:type]
92
+ turbo_response = case @response[:type]
93
93
  when :keep_modal_open
94
94
  # Only render the flash messages if the action keeps the modal open
95
- render turbo_stream: turbo_stream.flash_alerts
95
+ turbo_stream.flash_alerts
96
96
  when :download
97
97
  # Trigger download, removes modal and flash the messages
98
- render turbo_stream: [
98
+ [
99
99
  turbo_stream.download(content: Base64.encode64(@response[:path]), filename: @response[:filename]),
100
100
  turbo_stream.close_action_modal,
101
101
  turbo_stream.flash_alerts
@@ -104,16 +104,16 @@ module Avo
104
104
  frame_id = Avo::ACTIONS_TURBO_FRAME_ID
105
105
  src, _ = @response[:action].link_arguments(resource: @action.resource, **@response[:navigate_to_action_args])
106
106
 
107
- render turbo_stream: turbo_stream.turbo_frame_set_src(frame_id, src)
107
+ turbo_stream.turbo_frame_set_src(frame_id, src)
108
108
  when :redirect
109
- render turbo_stream: turbo_stream.redirect_to(
109
+ turbo_stream.redirect_to(
110
110
  Avo::ExecutionContext.new(target: @response[:path]).handle,
111
111
  turbo_frame: @response[:redirect_args][:turbo_frame],
112
112
  **@response[:redirect_args].except(:turbo_frame)
113
113
  )
114
114
  when :close_modal
115
115
  # Close the modal and flash the messages
116
- render turbo_stream: [
116
+ [
117
117
  turbo_stream.close_action_modal,
118
118
  turbo_stream.flash_alerts
119
119
  ]
@@ -121,8 +121,16 @@ module Avo
121
121
  # Reload the page
122
122
  back_path = request.referer || params[:referrer].presence || resources_path(resource: @resource)
123
123
 
124
- render turbo_stream: turbo_stream.redirect_to(back_path)
124
+ turbo_stream.redirect_to(back_path)
125
125
  end
126
+
127
+ responses = if @action.appended_turbo_streams.present?
128
+ Array(turbo_response) + Array(instance_exec(&@action.appended_turbo_streams))
129
+ else
130
+ Array(turbo_response)
131
+ end
132
+
133
+ render turbo_stream: responses
126
134
  end
127
135
  end
128
136
  end
@@ -34,6 +34,13 @@ module Avo
34
34
  @query = @query.includes(*@resource.includes)
35
35
  end
36
36
 
37
+ # Eager load attachments
38
+ if @resource.attachments.present?
39
+ @resource.attachments.each do |attachment|
40
+ @query = @query.send(:"with_attached_#{attachment}")
41
+ end
42
+ end
43
+
37
44
  apply_sorting
38
45
 
39
46
  # Apply filters to the current query
@@ -12,7 +12,7 @@ module Avo
12
12
  body = params[:body]
13
13
  body = {license_key: license_key, body: body, payload: Avo::Services::DebugService.debug_report(request).to_json}.to_json
14
14
 
15
- HTTParty.post url, body: body, headers: {"Content-Type": "application/json"}, timeout: timeout
15
+ Avo::Licensing::Request.post url, body:, timeout:
16
16
 
17
17
  render turbo_stream: turbo_stream.replace(:send_to_hq, plain: "Payload sent to Avo HQ.")
18
18
  end
@@ -53,7 +53,7 @@ module Avo
53
53
  results_count = query.reselect(resource.model_class.primary_key).count
54
54
 
55
55
  # Get the results
56
- query = query.limit(Avo.configuration.search_results_count)
56
+ query = query.limit(search_results_count(resource))
57
57
 
58
58
  results = apply_search_metadata(query, resource)
59
59
 
@@ -201,5 +201,16 @@ module Avo
201
201
  }
202
202
  }, status: 500
203
203
  end
204
+
205
+ def search_results_count(resource)
206
+ if resource.search_results_count
207
+ Avo::ExecutionContext.new(
208
+ target: resource.search_results_count,
209
+ params: params
210
+ ).handle
211
+ else
212
+ Avo.configuration.search_results_count
213
+ end
214
+ end
204
215
  end
205
216
  end
data/avo.gemspec CHANGED
@@ -39,7 +39,6 @@ Gem::Specification.new do |spec|
39
39
  spec.add_dependency "actionview", ">= 6.1"
40
40
  spec.add_dependency "pagy", ">= 7.0.0"
41
41
  spec.add_dependency "zeitwerk", ">= 2.6.12"
42
- spec.add_dependency "httparty"
43
42
  spec.add_dependency "active_link_to"
44
43
  spec.add_dependency "view_component", ">= 3.7.0"
45
44
  spec.add_dependency "turbo-rails", ">= 2.0.0"
@@ -21,6 +21,7 @@ module Avo
21
21
  attr_accessor :user
22
22
  attr_reader :arguments
23
23
  attr_reader :icon
24
+ attr_reader :appended_turbo_streams
24
25
 
25
26
  # TODO: find a differnet way to delegate this to the uninitialized Current variable
26
27
  delegate :context, to: Avo::Current
@@ -238,6 +239,8 @@ module Avo
238
239
  self
239
240
  end
240
241
 
242
+ alias_method :do_nothing, :close_modal
243
+
241
244
  # Add a placeholder silent message from when a user wants to do a redirect action or something similar
242
245
  def silent
243
246
  add_message nil, :silent
@@ -289,6 +292,10 @@ module Avo
289
292
  ).handle
290
293
  end
291
294
 
295
+ def append_to_response(turbo_stream)
296
+ @appended_turbo_streams = turbo_stream
297
+ end
298
+
292
299
  private
293
300
 
294
301
  def add_message(body, type = :info)
@@ -48,6 +48,9 @@ module Avo
48
48
  class_attribute :title
49
49
  class_attribute :search, default: {}
50
50
  class_attribute :includes, default: []
51
+ class_attribute :attachments, default: []
52
+ class_attribute :single_includes, default: []
53
+ class_attribute :single_attachments, default: []
51
54
  class_attribute :authorization_policy
52
55
  class_attribute :translation_key
53
56
  class_attribute :default_view_type, default: :table
@@ -150,11 +153,11 @@ module Avo
150
153
  # With uncountable models route key appends an _index suffix (Fish->fish_index)
151
154
  # Example: User->users, MediaItem->media_items, Fish->fish
152
155
  def model_key
153
- model_class.model_name.plural
156
+ @model_key ||= model_class.model_name.plural
154
157
  end
155
158
 
156
159
  def class_name
157
- to_s.demodulize
160
+ @class_name ||= to_s.demodulize
158
161
  end
159
162
 
160
163
  def route_key
@@ -170,7 +173,7 @@ module Avo
170
173
  end
171
174
 
172
175
  def name
173
- name_from_translation_key(count: 1, default: class_name.underscore.humanize)
176
+ @name ||= name_from_translation_key(count: 1, default: class_name.underscore.humanize)
174
177
  end
175
178
  alias_method :singular_name, :name
176
179
 
@@ -204,9 +207,21 @@ module Avo
204
207
  end
205
208
 
206
209
  def find_record(id, query: nil, params: nil)
210
+ query ||= find_scope # If no record is given we'll use the default
211
+
212
+ if single_includes.present?
213
+ query = query.includes(*single_includes)
214
+ end
215
+
216
+ if single_attachments.present?
217
+ single_attachments.each do |attachment|
218
+ query = query.send(:"with_attached_#{attachment}")
219
+ end
220
+ end
221
+
207
222
  Avo::ExecutionContext.new(
208
223
  target: find_record_method,
209
- query: query || find_scope, # If no record is given we'll use the default
224
+ query: query,
210
225
  id: id,
211
226
  params: params
212
227
  ).handle
@@ -216,6 +231,10 @@ module Avo
216
231
  search.dig(:query)
217
232
  end
218
233
 
234
+ def search_results_count
235
+ search.dig(:results_count)
236
+ end
237
+
219
238
  def fetch_search(key, record: nil)
220
239
  # self.class.fetch_search
221
240
  Avo::ExecutionContext.new(target: search[key], resource: self, record: record).handle
@@ -448,7 +467,6 @@ module Avo
448
467
  def file_hash
449
468
  content_to_be_hashed = ""
450
469
 
451
- file_name = self.class.underscore_name.tr(" ", "_")
452
470
  resource_path = Rails.root.join("app", "avo", "resources", "#{file_name}.rb").to_s
453
471
  if File.file? resource_path
454
472
  content_to_be_hashed += File.read(resource_path)
@@ -463,6 +481,10 @@ module Avo
463
481
  Digest::MD5.hexdigest(content_to_be_hashed)
464
482
  end
465
483
 
484
+ def file_name
485
+ @file_name ||= self.class.underscore_name.tr(" ", "_")
486
+ end
487
+
466
488
  def cache_hash(parent_record)
467
489
  result = [record, file_hash]
468
490
 
@@ -246,7 +246,7 @@ module Avo
246
246
  end
247
247
 
248
248
  def type
249
- self.class.name.demodulize.to_s.underscore.gsub("_field", "")
249
+ @type ||= self.class.name.demodulize.to_s.underscore.gsub("_field", "")
250
250
  end
251
251
 
252
252
  def custom?
@@ -94,8 +94,6 @@ module Avo
94
94
  cache_and_return_error "HTTP connection refused error.", exception.message
95
95
  rescue OpenSSL::SSL::SSLError => exception
96
96
  cache_and_return_error "OpenSSL error.", exception.message
97
- rescue HTTParty::Error => exception
98
- cache_and_return_error "HTTP client error.", exception.message
99
97
  rescue Net::OpenTimeout => exception
100
98
  cache_and_return_error "Request timeout.", exception.message
101
99
  rescue Net::ReadTimeout => exception
@@ -108,10 +106,11 @@ module Avo
108
106
  def perform_and_cache_request
109
107
  hq_response = perform_request
110
108
 
111
- return cache_and_return_error "Avo HQ Internal server error.", hq_response.body if hq_response.code == 500
112
-
113
- if hq_response.code == 200
114
- cache_response response: hq_response.parsed_response
109
+ case hq_response.code.to_i
110
+ when 500
111
+ cache_and_return_error "Avo HQ Internal server error.", hq_response.body if hq_response.code == 500
112
+ when 200
113
+ cache_response response: JSON.parse(hq_response.body)
115
114
  end
116
115
  end
117
116
 
@@ -148,9 +147,9 @@ module Avo
148
147
  Avo.logger.debug "Performing request to avohq.io API to check license availability." if Rails.env.development?
149
148
 
150
149
  if Rails.env.test?
151
- OpenStruct.new({code: 200, parsed_response: {id: "pro", valid: true}})
150
+ OpenStruct.new({code: 200, body: "{\"id\":\"pro\",\"valid\":true}"})
152
151
  else
153
- HTTParty.post ENDPOINT, body: payload.to_json, headers: {"Content-type": "application/json"}, timeout: REQUEST_TIMEOUT
152
+ Avo::Licensing::Request.post ENDPOINT, body: payload.to_json, timeout: REQUEST_TIMEOUT
154
153
  end
155
154
  end
156
155
 
@@ -0,0 +1,18 @@
1
+ module Avo
2
+ module Licensing
3
+ class Request
4
+ class << self
5
+ def post(endpoint, body:, timeout:)
6
+ uri = URI.parse(endpoint)
7
+ http = Net::HTTP.new(uri.host, uri.port)
8
+ http.use_ssl = (uri.scheme == "https")
9
+ http.read_timeout = timeout
10
+ http.open_timeout = timeout
11
+ request = Net::HTTP::Post.new(uri.request_uri, {'Content-Type' => 'application/json'})
12
+ request.body = body
13
+ http.request(request)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "3.10.2" unless const_defined?(:VERSION)
2
+ VERSION = "3.10.3" unless const_defined?(:VERSION)
3
3
  end
data/lib/avo.rb CHANGED
@@ -72,6 +72,7 @@ module Avo
72
72
  # Runs on each request
73
73
  def init
74
74
  Avo::Current.error_manager = Avo::ErrorManager.build
75
+ check_rails_version_issues
75
76
  Avo::Current.resource_manager = Avo::Resources::ResourceManager.build
76
77
  Avo::Current.tool_manager = Avo::Tools::ToolManager.build
77
78
 
@@ -142,6 +143,21 @@ module Avo
142
143
  def eager_load_actions
143
144
  Rails.autoloaders.main.eager_load_namespace(Avo::Actions) if defined?(Avo::Actions)
144
145
  end
146
+
147
+ def check_rails_version_issues
148
+ if Rails.version.start_with?("7.1") && Avo.configuration.license.in?(["pro", "advanced"])
149
+ Avo.error_manager.add({
150
+ url: "https://docs.avohq.io/3.0/upgrade.html#upgrade-from-3-7-4-to-3-9-1",
151
+ target: "_blank",
152
+ message: "Due to a Rails 7.1 bug the following features won't work:\n\r
153
+ - Dashboards\n\r
154
+ - Ordering\n\r
155
+ - Dynamic filters\n\r
156
+ We recommend you upgrade to Rails 7.2\n\r
157
+ Click banner for more information."
158
+ })
159
+ end
160
+ end
145
161
  end
146
162
  end
147
163
 
@@ -1,5 +1,6 @@
1
1
  class Avo::Resources::<%= resource_class %> < Avo::BaseResource
2
- self.includes = []<%= model_class_from_args %>
2
+ # self.includes = []
3
+ # self.attachments = []<%= model_class_from_args %>
3
4
  # self.search = {
4
5
  # query: -> { query.ransack(id_eq: params[:q], m: "or").result(distinct: false) }
5
6
  # }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avo
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.10.2
4
+ version: 3.10.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Marin
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-07-05 00:00:00.000000000 Z
13
+ date: 2024-07-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -82,20 +82,6 @@ dependencies:
82
82
  - - ">="
83
83
  - !ruby/object:Gem::Version
84
84
  version: 2.6.12
85
- - !ruby/object:Gem::Dependency
86
- name: httparty
87
- requirement: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- version: '0'
92
- type: :runtime
93
- prerelease: false
94
- version_requirements: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: '0'
99
85
  - !ruby/object:Gem::Dependency
100
86
  name: active_link_to
101
87
  requirement: !ruby/object:Gem::Requirement
@@ -2291,6 +2277,7 @@ files:
2291
2277
  - lib/avo/licensing/license_manager.rb
2292
2278
  - lib/avo/licensing/nil_license.rb
2293
2279
  - lib/avo/licensing/pro_license.rb
2280
+ - lib/avo/licensing/request.rb
2294
2281
  - lib/avo/loaders/actions_loader.rb
2295
2282
  - lib/avo/loaders/fields_loader.rb
2296
2283
  - lib/avo/loaders/filters_loader.rb